def add_dose_time_to_mtz(hklin, hklout, doses, times=None):
    """Add doses and times from dictionaries doses, times (optional)
    to hklin to produce hklout. The dictionaries are indexed by the
    BATCH column in hklin. Will raise exception if no BATCH column."""
    from iotbx import mtz
    from cctbx.array_family import flex
    mtz_obj = mtz.object(file_name=hklin)
    batch_column = None
    batch_dataset = None
    for crystal in mtz_obj.crystals():
        for dataset in crystal.datasets():
            for column in dataset.columns():
                if column.label() == 'BATCH':
                    batch_column = column
                    batch_dataset = dataset
    if not batch_column:
        raise RuntimeError('no BATCH column found in %s' % hklin)
    batch_column_values = batch_column.extract_values(not_a_number_substitute
        =-1)
    dose_column = batch_dataset.add_column(label='DOSE', type='R')
    dose_column_values = flex.float()
    if times:
        time_column = batch_dataset.add_column(label='TIME', type='R')
        time_column_values = flex.float()
    valid = flex.bool()
    for b in batch_column_values:
        valid.append(True)
        dose_column_values.append(doses.get(b, -1.0))
        if times:
            time_column_values.append(times.get(b, -1.0))
    dose_column.set_values(values=dose_column_values, selection_valid=valid)
    if times:
        time_column.set_values(values=time_column_values, selection_valid=valid
            )
    mtz_obj.write(file_name=hklout)
