Ejemplo n.º 1
0
def Ramsey(device,
           qubit_id,
           transition='01',
           *extra_sweep_args,
           channel_amplitudes1=None,
           channel_amplitudes2=None,
           lengths=None,
           target_freq_offset=None,
           readout_delay=0,
           delay_seq_generator=None,
           measurement_type='Ramsey',
           additional_references={},
           additional_metadata={}):
    from .readout_pulse import get_uncalibrated_measurer
    if type(lengths) is type(None):
        lengths = np.arange(
            0,
            float(
                device.get_qubit_constant(qubit_id=qubit_id,
                                          name='Ramsey_length')),
            float(
                device.get_qubit_constant(qubit_id=qubit_id,
                                          name='Ramsey_step')))

    #readout_pulse = get_qubit_readout_pulse(device, qubit_id)
    readout_pulse, measurer = get_uncalibrated_measurer(
        device, qubit_id, transition)
    ex_pulse1 = excitation_pulse.get_excitation_pulse(
        device,
        qubit_id,
        np.pi / 2.,
        channel_amplitudes_override=channel_amplitudes1)
    ex_pulse2 = excitation_pulse.get_excitation_pulse(
        device,
        qubit_id,
        np.pi / 2.,
        channel_amplitudes_override=channel_amplitudes2)

    def set_delay(length):
        #ex_pulse_seq = [device.pg.pmulti(length+2*tail_length, *tuple(channel_pulses))]
        if delay_seq_generator is None:
            delay_seq = [device.pg.pmulti(length)]
        else:
            delay_seq = delay_seq_generator(length)
        readout_delay_seq = [device.pg.pmulti(readout_delay)]
        readout_trigger_seq = device.trigger_readout_seq
        readout_pulse_seq = readout_pulse.pulse_sequence

        device.pg.set_seq(device.pre_pulses + ex_pulse1.get_pulse_sequence(0) +
                          delay_seq +
                          ex_pulse2.get_pulse_sequence(length *
                                                       target_freq_offset * 2 *
                                                       np.pi) +
                          readout_delay_seq + readout_trigger_seq +
                          readout_pulse_seq)

    references = {
        'ex_pulse1':
        ex_pulse1.id,
        'ex_pulse2':
        ex_pulse2.id,
        'frequency_controls':
        device.get_frequency_control_measurement_id(qubit_id=qubit_id),
        'readout_pulse':
        readout_pulse.id
    }
    references.update(additional_references)

    if hasattr(measurer, 'references'):
        references.update(measurer.references)

    fitter_arguments = ('iq' + qubit_id, exp_sin_fitter(), -1,
                        np.arange(len(extra_sweep_args)))

    metadata = {
        'qubit_id': qubit_id,
        'transition': transition,
        'extra_sweep_args': str(len(extra_sweep_args)),
        'target_offset_freq': str(target_freq_offset),
        'readout_delay': str(readout_delay)
    }
    metadata.update(additional_metadata)

    measurement = device.sweeper.sweep_fit_dataset_1d_onfly(
        measurer,
        *extra_sweep_args, (lengths, set_delay, 'Delay', 's'),
        fitter_arguments=fitter_arguments,
        measurement_type=measurement_type,
        metadata=metadata,
        references=references)

    return measurement
Ejemplo n.º 2
0
def Ramsey_crosstalk(device,
                     target_qubit_id,
                     control_qubit_id,
                     *extra_sweep_args,
                     channel_amplitudes_control=None,
                     channel_amplitudes1=None,
                     channel_amplitudes2=None,
                     lengths=None,
                     target_freq_offset=None,
                     readout_delay=0,
                     delay_seq_generator=None,
                     measurement_type='Ramsey_crosstalk',
                     additional_references={}):

    #if type(lengths) is type(None):
    #	lengths = np.arange(0,
    #						float(device.get_qubit_constant(qubit_id=qubit_id, name='Ramsey_length')),
    #						float(device.get_qubit_constant(qubit_id=qubit_id, name='Ramsey_step')))

    # if we don't have a ramsey coherence scan, get one
    from .readout_pulse import get_uncalibrated_measurer
    try:
        deexcited_measurement = device.exdir_db.select_measurement_by_id(
            get_Ramsey_coherence_measurement(
                device, target_qubit_id).references['fit_source'])
    except:
        deexcited_measurement = None

    if lengths is None:
        lengths = deexcited_measurement.datasets[
            'iq' + target_qubit_id].parameters[-1].values
    if target_freq_offset is None:  ###TODO: make sure we don't skip oscillations due to decoherence
        ##(improbable but possible if the qubits are very coherent even at high crosstalks AHAHAHA)
        target_freq_offset = float(
            deexcited_measurement.metadata['target_offset_freq'])

    #readout_pulse = get_qubit_readout_pulse(device, target_qubit_id)
    readout_pulse, measurer = get_uncalibrated_measurer(
        device, target_qubit_id)  #, readout_pulse)
    ex_control_pulse = excitation_pulse.get_excitation_pulse(
        device,
        control_qubit_id,
        np.pi,
        channel_amplitudes_override=channel_amplitudes_control)
    ex_pulse1 = excitation_pulse.get_excitation_pulse(
        device,
        target_qubit_id,
        np.pi / 2.,
        channel_amplitudes_override=channel_amplitudes1)
    ex_pulse2 = excitation_pulse.get_excitation_pulse(
        device,
        target_qubit_id,
        np.pi / 2.,
        channel_amplitudes_override=channel_amplitudes2)

    def set_delay(length):
        #ex_pulse_seq = [device.pg.pmulti(length+2*tail_length, *tuple(channel_pulses))]
        if delay_seq_generator is None:
            delay_seq = [device.pg.pmulti(length)]
        else:
            delay_seq = delay_seq_generator(length)
        readout_delay_seq = [device.pg.pmulti(readout_delay)]
        readout_trigger_seq = device.trigger_readout_seq
        readout_pulse_seq = readout_pulse.pulse_sequence

        device.pg.set_seq(device.pre_pulses+\
                          ex_control_pulse.get_pulse_sequence(0)+\
                          ex_pulse1.get_pulse_sequence(0)+\
                          delay_seq+\
                          ex_pulse2.get_pulse_sequence(length*target_freq_offset*2*np.pi)+\
                          readout_delay_seq+\
                          readout_trigger_seq+\
                          readout_pulse_seq)

    references = {
        'ex_control_pulse':
        ex_control_pulse.id,
        'ex_pulse1':
        ex_pulse1.id,
        'ex_pulse2':
        ex_pulse2.id,
        'frequency_controls':
        device.get_frequency_control_measurement_id(qubit_id=target_qubit_id),
    }
    if deexcited_measurement is not None:
        references['deexcited_measurement'] = deexcited_measurement.id

    if hasattr(measurer, 'references'):
        references.update(measurer.references)

    fitter_arguments = ('iq' + target_qubit_id, exp_sin_fitter(), -1,
                        np.arange(len(extra_sweep_args)))

    metadata = {
        'target_qubit_id': target_qubit_id,
        'control_qubit_id': control_qubit_id,
        'extra_sweep_args': str(len(extra_sweep_args)),
        'target_offset_freq': str(target_freq_offset),
        'readout_delay': str(readout_delay)
    }

    references.update(additional_references)

    measurement = device.sweeper.sweep_fit_dataset_1d_onfly(
        measurer,
        *extra_sweep_args, (lengths, set_delay, 'Delay', 's'),
        fitter_arguments=fitter_arguments,
        measurement_type=measurement_type,
        metadata=metadata,
        references=references)

    return measurement
Ejemplo n.º 3
0
def Rabi_rect(device, qubit_id, channel_amplitudes, transition='01', lengths=None, *extra_sweep_args, tail_length=0, readout_delay=0,
              pre_pulses=tuple(), repeats=1, measurement_type='Rabi_rect', samples=False, additional_metadata={}):
    from .readout_pulse2 import get_uncalibrated_measurer
    from .calibrated_readout import get_calibrated_measurer

    if type(qubit_id) is not list and type(qubit_id) is not tuple:  # if we are working with a single qubit, use uncalibrated measurer
        readout_pulse, measurer = get_uncalibrated_measurer(device, qubit_id, transition=transition, samples=samples)
        measurement_name = 'iq'+qubit_id
        qubit_id = [qubit_id]
        exp_sin_fitter_mode = 'unsync'
        exitation_channel = [i for i in device.get_qubit_excitation_channel_list(qubit_id[0]).keys()][0]
    else: # otherwise use calibrated measurer
        readout_pulse, measurer = get_calibrated_measurer(device, qubit_id)
        measurement_name = 'resultnumbers'
        exp_sin_fitter_mode = 'unsync'
        exitation_channel = [i for i in device.get_qubit_excitation_channel_list(qubit_id).keys()][0]

    #pre_pulse_sequences = []
    #for pulse in pre_pulses:
    #    if hasattr(pulse, 'get_pulse_sequence'):
    #        pre_pulse_sequences += pulse.get_pulse_sequence(0.0)
    #    else:
    #        pre_pulse_sequences += pulse

    #pre_pulse_sequences = [p for pulse in pre_pulses for p in pulse.get_pulse_sequence(0)]
    # Exitation sequencer
    # Nado zagrusit pre rulse vo vse sequencery
    #print(qubit_id)

    ex_channel = device.awg_channels[exitation_channel]
    if ex_channel.is_iq():
        control_seq_id = ex_channel.parent.sequencer_id
    else:
        control_seq_id = ex_channel.channel//2
    ex_sequencers = []

    # Pulse definition
    for a, c in channel_amplitudes.items():
        if a == exitation_channel:
            exitation_amplitude = np.abs(c)
    def_frag, play_frag = device.pg.rect_cos(channel=exitation_channel,
                                             length=0, amp=exitation_amplitude,
                                             length_tail=tail_length, fast_control=True)

    for seq_id in device.pre_pulses.seq_in_use:
        if seq_id != control_seq_id:
            ex_seq = zi_scripts.SIMPLESequence(sequencer_id=seq_id, awg=device.modem.awg,
                                               awg_amp=1, use_modulation=True, pre_pulses = [])
        else:
            ex_seq = zi_scripts.SIMPLESequence(sequencer_id=seq_id, awg=device.modem.awg,
                                               awg_amp=1, use_modulation=True, pre_pulses=[], control=True)
            control_sequence = ex_seq
            ex_seq.add_definition_fragment(def_frag)
            ex_seq.add_play_fragment(play_frag*repeats)

        ex_sequencers.append(ex_seq)
    control_sequence.set_frequency(np.abs(ex_channel.get_frequency()))
    for sequence in ex_sequencers:
        sequence.stop()
        device.pre_pulses.set_seq_offsets(sequence)
        device.pre_pulses.set_seq_prepulses(sequence)
        device.modem.awg.set_sequence(sequence.params['sequencer_id'], sequence)
        sequence.start()

    '''#There is no more special delay_seq and special readout_trigger_seq due to the new pulse generation structure
    #Now delay_seq and special readout_trigger_seq replace with new sequencer READSequence

    #delay_seq = [device.pg.pmulti(readout_delay)]
    #readout_trigger_seq = device.trigger_readout_seq

    # There is no more special sequence for readout. We need only readout_channel, frequency, length, amplitude
    #readout_pulse_seq = readout_pulse.pulse_sequence

    # There is no more set_seq
    #device.pg.set_seq(device.pre_pulses+pre_pulse_sequences+delay_seq+ex_pulse_seq+delay_seq+readout_trigger_seq+readout_pulse_seq)'''

    re_sequence = sequence_control.define_readout_control_seq(device, readout_pulse)
    re_sequence.start()

    def set_ex_length(length, ex_sequence = control_sequence):
        ex_sequence.set_length(length)
        #time.sleep(0.05)

    times = np.zeros(len(lengths))
    for _i in range(len(lengths)):
        times[_i] = int(round(lengths[_i] * control_sequence.clock))
    lengths = times / control_sequence.clock

    #def set_coil_offset(coil_name,x, ex_sequence=ex_sequence):
    #    ex_sequence.set_offset(device.awg_channels[coil_name].channel, x)

    references = {('frequency_controls', qubit_id_): device.get_frequency_control_measurement_id(qubit_id=qubit_id_) for qubit_id_ in qubit_id}
    references['channel_amplitudes'] = channel_amplitudes.id
    references['readout_pulse'] = readout_pulse.id

    if hasattr(measurer, 'references'):
        references.update(measurer.references)

    for pre_pulse_id, pre_pulse in enumerate(pre_pulses):
        if hasattr(pre_pulse, 'id'):
            references.update({('pre_pulse', str(pre_pulse_id)): pre_pulse.id})

    if len(qubit_id)>1:
        arg_id = -2 # the last parameter is resultnumbers, so the time-like argument is -2
    else:
        arg_id = -1
    fitter_arguments = (measurement_name, exp_sin_fitter(mode=exp_sin_fitter_mode), arg_id, np.arange(len(extra_sweep_args)))

    metadata = {'qubit_id': ','.join(qubit_id),
                'extra_sweep_args': str(len(extra_sweep_args)),
                'tail_length': str(tail_length),
                'readout_delay': str(readout_delay),
                'repeats': str(repeats),
                'transition':transition}
    metadata.update(additional_metadata)

    measurement = device.sweeper.sweep_fit_dataset_1d_onfly(measurer,
                                                            *extra_sweep_args,
                                                            (lengths, set_ex_length, 'Excitation length', 's'),
                                                            fitter_arguments=fitter_arguments,
                                                            measurement_type=measurement_type,
                                                            metadata=metadata,
                                                            references=references,
                                                            on_update_divider=5)

    return measurement
Ejemplo n.º 4
0
def Ramsey(device, qubit_id, transition='01', *extra_sweep_args, channel_amplitudes1=None, channel_amplitudes2=None, lengths=None,
           target_freq_offset=None, readout_delay=0, delay_seq_generator=None, measurement_type='Ramsey',
           additional_references = {}, additional_metadata = {}):
    from .readout_pulse2 import get_uncalibrated_measurer
    if type(lengths) is type(None):
        lengths = np.arange(0,
                            float(device.get_qubit_constant(qubit_id=qubit_id, name='Ramsey_length')),
                            float(device.get_qubit_constant(qubit_id=qubit_id, name='Ramsey_step')))
    #readout_pulse = get_qubit_readout_pulse(device, qubit_id)
    readout_pulse, measurer = get_uncalibrated_measurer(device, qubit_id, transition)
    ex_pulse1 = excitation_pulse.get_excitation_pulse(device, qubit_id, np.pi/2., channel_amplitudes_override=channel_amplitudes1)
    ex_pulse2 = excitation_pulse.get_excitation_pulse(device, qubit_id, np.pi/2., channel_amplitudes_override=channel_amplitudes2)


    exitation_channel = [i for i in device.get_qubit_excitation_channel_list(qubit_id).keys()][0]
    ex_channel = device.awg_channels[exitation_channel]
    if ex_channel.is_iq():
        control_seq_id = ex_channel.parent.sequencer_id
    else:
        control_seq_id = ex_channel.channel//2
    ex_sequencers = []

    for seq_id in device.pre_pulses.seq_in_use:
        if seq_id != control_seq_id:
            ex_seq = zi_scripts.SIMPLESequence(sequencer_id=seq_id, awg=device.modem.awg,
                                               awg_amp=1, use_modulation=True, pre_pulses = [])
        else:
            ex_seq = zi_scripts.SIMPLESequence(sequencer_id=seq_id, awg=device.modem.awg,
                                               awg_amp=1, use_modulation=True, pre_pulses=[], control=True)
            control_sequence = ex_seq
        device.pre_pulses.set_seq_offsets(ex_seq)
        device.pre_pulses.set_seq_prepulses(ex_seq)
        #device.modem.awg.set_sequence(ex_seq.params['sequencer_id'], ex_seq)
        ex_seq.start()
        ex_sequencers.append(ex_seq)
    readout_sequencer = sequence_control.define_readout_control_seq(device, readout_pulse)
    readout_sequencer.start()

    class ParameterSetter:
        def __init__(self):
            self.ex_sequencers=ex_sequencers
            self.prepare_seq = []
            self.readout_sequencer = readout_sequencer
            self.delay_seq_generator = delay_seq_generator
            self.lengths = lengths
            self.control_sequence = control_sequence
            # Create preparation sequence
            self.prepare_seq.extend(ex_pulse1.get_pulse_sequence(0))
            if self.delay_seq_generator is None:
                self.prepare_seq.extend([device.pg.pmulti(device, 0)])
                self.prepare_seq.extend([device.pg.pmulti(device, self.lengths)])
                self.prepare_seq.extend([device.pg.pmulti(device, 0)])
            else:
                self.pre_pause, self.delay_sequence, self.post_pause = self.delay_seq_generator(self.lengths)
                self.prepare_seq.extend(self.pre_pause)
                self.prepare_seq.extend(self.delay_sequence)
                self.prepare_seq.extend(self.post_pause)
            self.prepare_seq.extend(excitation_pulse.get_s(device, qubit_id,
                                                           phase=(64/self.control_sequence.clock)*target_freq_offset*360 % 360,
                                                           fast_control='quasi-binary'))
            self.prepare_seq.extend(ex_pulse2.get_pulse_sequence(0))
            # Set preparation sequence
            sequence_control.set_preparation_sequence(device, self.ex_sequencers, self.prepare_seq)
            self.readout_sequencer.start()

        def set_delay(self, length):
            phase = int(np.round((length+140e-9)*self.control_sequence.clock)+64)/self.control_sequence.clock*target_freq_offset*360 % 360
            #print ('length: ', length, ', phase: ', phase, ', phase register: ', int(phase/360*(2**6)))

            if self.delay_seq_generator is None:
                for ex_seq in self.ex_sequencers:
                    ex_seq.set_length(length)
                self.control_sequence.set_phase(int(phase/360*(2**8)))
            else:
                if length == self.lengths[0]:
                    self.readout_sequencer.awg.stop_seq(self.readout_sequencer.params['sequencer_id'])
                    self.pre_pause, self.delay_sequence, self.post_pause = self.delay_seq_generator(self.lengths)
                    self.prepare_seq[-4] = self.delay_sequence[0]
                    #sequence_control.set_preparation_sequence(device, self.ex_sequencers, self.prepare_seq,
                                                              #self.control_sequence)
                    sequence_control.set_preparation_sequence(device, self.ex_sequencers, self.prepare_seq)

                    for ex_seq in self.ex_sequencers:
                        ex_seq.set_length(length)
                    self.control_sequence.set_phase(int(phase/360*(2**8)))
                    self.readout_sequencer.awg.start_seq(self.readout_sequencer.params['sequencer_id'])

                else:
                    for ex_seq in self.ex_sequencers:
                        ex_seq.set_length(length)
                    self.control_sequence.set_phase(int(phase/360*(2**8)))

        def set_delay1(self, length):
            self.prepare_seq[-2] = excitation_pulse.get_s(device, qubit_id,
                                        phase=(int(np.round(length*self.control_sequence.clock)+64)/self.control_sequence.clock)*target_freq_offset*360)

            if self.delay_seq_generator is None:
                self.readout_sequencer.awg.stop_seq(self.readout_sequencer.params['sequencer_id'])
                for ex_seq in self.ex_sequencers:
                    ex_seq.set_length(length)
                    if ex_seq.params['sequencer_id'] == self.control_sequence.params['sequencer_id']:
                        ex_seq.awg.stop_seq(ex_seq.params['sequencer_id'])
                        ex_seq.clear_pulse_sequence()
                        for prep_seq in self.prepare_seq:
                            for seq_id, single_sequence in prep_seq[0].items():
                                if seq_id == ex_seq.params['sequencer_id']:
                                    ex_seq.add_definition_fragment(single_sequence[0])
                                    ex_seq.add_play_fragment(single_sequence[1])
                        device.modem.awg.set_sequence(ex_seq.params['sequencer_id'], ex_seq)
                        ex_seq.awg.start_seq(ex_seq.params['sequencer_id'])
                self.readout_sequencer.awg.start_seq(self.readout_sequencer.params['sequencer_id'])

            else:
                if length == self.lengths[0]:
                    self.readout_sequencer.awg.stop_seq(self.readout_sequencer.params['sequencer_id'])
                    self.pre_pause, self.delay_sequence, self.post_pause = self.delay_seq_generator(self.lengths)
                    self.prepare_seq[-4] = self.delay_sequence
                    sequence_control.set_preparation_sequence(device, self.ex_sequencers, self.prepare_seq)
                    for ex_seq in self.ex_sequencers:
                        ex_seq.set_length(length)
                    self.readout_sequencer.awg.start_seq(self.readout_sequencer.params['sequencer_id'])
                else:
                    self.readout_sequencer.awg.stop_seq(self.readout_sequencer.params['sequencer_id'])
                    for ex_seq in self.ex_sequencers:
                        ex_seq.set_length(length)
                        if ex_seq.params['sequencer_id'] == self.control_sequence.params['sequencer_id']:
                            ex_seq.awg.stop_seq(ex_seq.params['sequencer_id'])
                            ex_seq.clear_pulse_sequence()
                            for prep_seq in self.prepare_seq:
                                for seq_id, single_sequence in prep_seq[0].items():
                                    if seq_id == ex_seq.params['sequencer_id']:
                                        ex_seq.add_definition_fragment(single_sequence[0])
                                        ex_seq.add_play_fragment(single_sequence[1])
                            device.modem.awg.set_sequence(ex_seq.params['sequencer_id'], ex_seq)
                            ex_seq.awg.start_seq(ex_seq.params['sequencer_id'])
                    self.readout_sequencer.awg.start_seq(self.readout_sequencer.params['sequencer_id'])

    setter = ParameterSetter()

    references = {'ex_pulse1':ex_pulse1.id,
                  'ex_pulse2':ex_pulse2.id,
                  'frequency_controls':device.get_frequency_control_measurement_id(qubit_id=qubit_id),
                  'readout_pulse':readout_pulse.id }
    references.update(additional_references)

    if hasattr(measurer, 'references'):
        references.update(measurer.references)

    fitter_arguments = ('iq'+qubit_id, exp_sin_fitter(), -1, np.arange(len(extra_sweep_args)))

    metadata = {'qubit_id': qubit_id,
                'transition': transition,
              'extra_sweep_args':str(len(extra_sweep_args)),
              'target_offset_freq': str(target_freq_offset),
              'readout_delay':str(readout_delay)}
    metadata.update(additional_metadata)

    measurement = device.sweeper.sweep_fit_dataset_1d_onfly(measurer,
                                              *extra_sweep_args,
                                              (lengths, setter.set_delay, 'Delay','s'),
                                              fitter_arguments = fitter_arguments,
                                              measurement_type=measurement_type,
                                              metadata=metadata,
                                              references=references,
                                              on_update_divider=10)

    for ex_seq in ex_sequencers:
        ex_seq.stop()
    readout_sequencer.stop()
    return measurement
Ejemplo n.º 5
0
def Rabi_rect(device,
              qubit_id,
              channel_amplitudes,
              transition='01',
              lengths=None,
              *extra_sweep_args,
              tail_length=0,
              readout_delay=0,
              pre_pulses=tuple(),
              repeats=1,
              measurement_type='Rabi_rect',
              samples=False,
              additional_metadata={}):
    from .readout_pulse import get_uncalibrated_measurer
    from .calibrated_readout import get_calibrated_measurer
    if type(qubit_id) is not list and type(
            qubit_id
    ) is not tuple:  # if we are working with a single qubit, use uncalibrated measurer
        readout_pulse, measurer = get_uncalibrated_measurer(
            device, qubit_id, transition=transition, samples=samples)
        measurement_name = 'iq' + qubit_id
        qubit_id = [qubit_id]
        exp_sin_fitter_mode = 'unsync'
    else:  # otherwise use calibrated measurer
        readout_pulse, measurer = get_calibrated_measurer(device, qubit_id)
        measurement_name = 'resultnumbers'
        exp_sin_fitter_mode = 'unsync'

    def set_ex_length(length):
        pre_pulse_sequences = []
        for pulse in pre_pulses:
            if hasattr(pulse, 'get_pulse_sequence'):
                pre_pulse_sequences += pulse.get_pulse_sequence(0.0)
            else:
                pre_pulse_sequences += pulse
        #pre_pulse_sequences = [p for pulse in pre_pulses for p in pulse.get_pulse_sequence(0)]
        ex_pulse_seq = excitation_pulse.get_rect_cos_pulse_sequence(
            device, channel_amplitudes, tail_length, length,
            phase=0.) * repeats
        delay_seq = [device.pg.pmulti(readout_delay)]
        readout_trigger_seq = device.trigger_readout_seq
        readout_pulse_seq = readout_pulse.pulse_sequence

        device.pg.set_seq(device.pre_pulses + pre_pulse_sequences + delay_seq +
                          ex_pulse_seq + delay_seq + readout_trigger_seq +
                          readout_pulse_seq)

    references = {
        ('frequency_controls', qubit_id_):
        device.get_frequency_control_measurement_id(qubit_id=qubit_id_)
        for qubit_id_ in qubit_id
    }
    references['channel_amplitudes'] = channel_amplitudes.id
    references['readout_pulse'] = readout_pulse.id

    if hasattr(measurer, 'references'):
        references.update(measurer.references)

    for pre_pulse_id, pre_pulse in enumerate(pre_pulses):
        if hasattr(pre_pulse, 'id'):
            references.update({('pre_pulse', str(pre_pulse_id)): pre_pulse.id})

    if len(qubit_id) > 1:
        arg_id = -2  # the last parameter is resultnumbers, so the time-like argument is -2
    else:
        arg_id = -1
    fitter_arguments = (measurement_name,
                        exp_sin_fitter(mode=exp_sin_fitter_mode), arg_id,
                        np.arange(len(extra_sweep_args)))

    metadata = {
        'qubit_id': ','.join(qubit_id),
        'extra_sweep_args': str(len(extra_sweep_args)),
        'tail_length': str(tail_length),
        'readout_delay': str(readout_delay),
        'repeats': str(repeats),
        'transition': transition
    }
    metadata.update(additional_metadata)

    measurement = device.sweeper.sweep_fit_dataset_1d_onfly(
        measurer,
        *extra_sweep_args, (lengths, set_ex_length, 'Excitation length', 's'),
        fitter_arguments=fitter_arguments,
        measurement_type=measurement_type,
        metadata=metadata,
        references=references)

    return measurement