def test_internal_create_program_one_child_no_duration(self) -> None: sub1 = DummyPulseTemplate(duration=0, waveform=None, measurements=[('b', 1, 2)], defined_channels={'A'}) sub2 = DummyPulseTemplate(duration=2, waveform=DummyWaveform(duration=2), parameter_names={'foo'}, defined_channels={'A'}) scope = DictScope.from_kwargs() measurement_mapping = {'a': 'a', 'b': 'b'} channel_mapping = dict() seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)]) loop = Loop() seq._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=set(), parent_loop=loop) self.assertEqual(1, loop.repetition_count) self.assertIsNone(loop.waveform) self.assertEqual([Loop(repetition_count=1, waveform=sub2.waveform)], list(loop.children)) self.assert_measurement_windows_equal({'a': ([0], [1])}, loop.get_measurement_windows()) # MultiChannelProgram calls cleanup loop.cleanup() self.assert_measurement_windows_equal({'a': ([0], [1])}, loop.get_measurement_windows()) ### test again with inverted sequence seq = SequencePulseTemplate(sub2, sub1, measurements=[('a', 0, 1)]) loop = Loop() seq._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=set(), parent_loop=loop) self.assertEqual(1, loop.repetition_count) self.assertIsNone(loop.waveform) self.assertEqual([Loop(repetition_count=1, waveform=sub2.waveform)], list(loop.children)) self.assert_measurement_windows_equal({'a': ([0], [1])}, loop.get_measurement_windows()) # MultiChannelProgram calls cleanup loop.cleanup() self.assert_measurement_windows_equal({'a': ([0], [1])}, loop.get_measurement_windows())
def test_create_program_internal(self) -> None: sub1 = DummyPulseTemplate(duration=3, waveform=DummyWaveform(duration=3), measurements=[('b', 1, 2)], defined_channels={'A'}) sub2 = DummyPulseTemplate(duration=2, waveform=DummyWaveform(duration=2), parameter_names={'foo'}, defined_channels={'A'}) parameters = {'foo': DummyNoValueParameter()} measurement_mapping = {'a': 'a', 'b': 'b'} channel_mapping = dict() seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)]) loop = Loop() seq._internal_create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=set(), parent_loop=loop) self.assertEqual(1, loop.repetition_count) self.assertIsNone(loop.waveform) self.assertEqual([Loop(repetition_count=1, waveform=sub1.waveform), Loop(repetition_count=1, waveform=sub2.waveform)], loop.children) self.assert_measurement_windows_equal({'a': ([0], [1]), 'b': ([1], [2])}, loop.get_measurement_windows()) # ensure same result as from Sequencer sequencer = Sequencer() sequencer.push(seq, parameters=parameters, conditions={}, window_mapping=measurement_mapping, channel_mapping=channel_mapping) block = sequencer.build() old_program = MultiChannelProgram(block, channels={'A'}) self.assertEqual(old_program.programs[frozenset({'A'})], loop) ### test again with inverted sequence seq = SequencePulseTemplate(sub2, sub1, measurements=[('a', 0, 1)]) loop = Loop() seq._internal_create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=set(), parent_loop=loop) self.assertEqual(1, loop.repetition_count) self.assertIsNone(loop.waveform) self.assertEqual([Loop(repetition_count=1, waveform=sub2.waveform), Loop(repetition_count=1, waveform=sub1.waveform)], loop.children) self.assert_measurement_windows_equal({'a': ([0], [1]), 'b': ([3], [2])}, loop.get_measurement_windows()) # ensure same result as from Sequencer sequencer = Sequencer() sequencer.push(seq, parameters=parameters, conditions={}, window_mapping=measurement_mapping, channel_mapping=channel_mapping) block = sequencer.build() old_program = MultiChannelProgram(block, channels={'A'}) self.assertEqual(old_program.programs[frozenset({'A'})], loop)
def test_create_program_declaration_success(self) -> None: repetitions = "foo" body = DummyPulseTemplate(duration=2.0, waveform=DummyWaveform( duration=2, defined_channels={'A'})) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9']) scope = DictScope.from_kwargs(foo=3) measurement_mapping = dict(moth='fire') channel_mapping = dict(asd='f') program = Loop() t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertEqual(1, program.repetition_count) self.assertEqual(1, len(program.children)) internal_loop = program.children[0] # type: Loop self.assertEqual(scope[repetitions], internal_loop.repetition_count) self.assertEqual(1, len(internal_loop)) self.assertEqual( (scope, measurement_mapping, channel_mapping, internal_loop), body.create_program_calls[-1]) self.assertEqual(body.waveform, internal_loop[0].waveform) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_internal_create_program_no_measurement_mapping(self) -> None: sub1 = DummyPulseTemplate(duration=3, waveform=DummyWaveform(duration=3), measurements=[('b', 1, 2)]) sub2 = DummyPulseTemplate(duration=2, waveform=DummyWaveform(duration=2), parameter_names={'foo'}) parameters = {'foo': DummyNoValueParameter()} seq = SequencePulseTemplate(sub1, sub2, measurements=[('a', 0, 1)]) children = [Loop(waveform=DummyWaveform())] loop = Loop(measurements=[], children=children) with self.assertRaises(KeyError): seq._internal_create_program(parameters=parameters, measurement_mapping=dict(), channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop) self.assertFalse(sub1.create_program_calls) self.assertFalse(sub2.create_program_calls) self.assertEqual(children, loop.children) self.assertEqual(1, loop.repetition_count) self.assertIsNone(loop.waveform) self.assert_measurement_windows_equal({}, loop.get_measurement_windows()) # test for child level measurements (does not guarantee to leave parent_loop unchanged in this case) with self.assertRaises(KeyError): seq._internal_create_program(parameters=parameters, measurement_mapping=dict(a='a'), channel_mapping=dict(), global_transformation=None, to_single_waveform=set(), parent_loop=loop)
def test_create_program_invalid_params(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration=4, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) invalid_scope = DictScope.from_kwargs(a=0, b=2, c=1) measurement_mapping = dict(A='B') channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) with self.assertRaises(ParameterConstraintViolation): flt._internal_create_program( scope=invalid_scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, list(program.children)) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_create_program_declaration_parameter_value_not_whole( self) -> None: repetitions = "foo" body = DummyPulseTemplate(duration=2.0, waveform=DummyWaveform(duration=2.0)) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9']) scope = DictScope.from_kwargs(foo=(3.3)) measurement_mapping = dict(moth='fire') channel_mapping = dict(asd='f') children = [Loop(waveform=DummyWaveform(duration=0))] program = Loop(children=children) with self.assertRaises(ParameterNotIntegerException): t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertFalse(body.create_program_calls) self.assertEqual(1, program.repetition_count) self.assertEqual(children, list(program.children)) self.assertIsNone(program.waveform) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def test_create_program_constraint_on_loop_var_exception(self): """This test is to assure the status-quo behavior of ForLoopPT handling parameter constraints affecting the loop index variable. Please see https://github.com/qutech/qupulse/issues/232 .""" with self.assertWarnsRegex(UserWarning, "constraint on a variable shadowing the loop index", msg="ForLoopPT did not issue a warning when constraining the loop index"): flt = ForLoopPulseTemplate(body=DummyPulseTemplate(parameter_names={'k', 'i'}), loop_index='i', loop_range=('a', 'b', 'c',), parameter_constraints=['k<=f', 'k>i']) # loop index showing up in parameter_names because it appears in consraints self.assertEqual(flt.parameter_names, {'f', 'k', 'a', 'b', 'c', 'i'}) scope = DictScope.from_kwargs(k=1, a=0, b=2, c=1, f=2) # loop index not accessible in current build_sequence -> Exception children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) with self.assertRaises(ParameterNotProvidedException): flt._internal_create_program(scope=scope, measurement_mapping=dict(), channel_mapping=dict(), parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, list(program.children)) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal({}, program.get_measurement_windows())
def test_create_program_constant_success_measurements(self) -> None: repetitions = 3 body = DummyPulseTemplate(duration=2.0, waveform=DummyWaveform( duration=2, defined_channels={'A'}), measurements=[('b', 0, 1)]) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9'], measurements=[('my', 2, 2)]) scope = DictScope.from_mapping({'foo': 8}) measurement_mapping = {'my': 'thy', 'b': 'b'} channel_mapping = {} program = Loop() t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertEqual(1, len(program.children)) internal_loop = program[0] # type: Loop self.assertEqual(repetitions, internal_loop.repetition_count) self.assertEqual(1, len(internal_loop)) self.assertEqual( (scope, measurement_mapping, channel_mapping, internal_loop), body.create_program_calls[-1]) self.assertEqual(body.waveform, internal_loop[0].waveform) self.assert_measurement_windows_equal( { 'b': ([0, 2, 4], [1, 1, 1]), 'thy': ([2], [2]) }, program.get_measurement_windows()) # done in MultiChannelProgram program.cleanup() self.assert_measurement_windows_equal( { 'b': ([0, 2, 4], [1, 1, 1]), 'thy': ([2], [2]) }, program.get_measurement_windows())
def _create_program(self, *, scope: Scope, measurement_mapping: Dict[str, Optional[str]], channel_mapping: Dict[ChannelID, Optional[ChannelID]], global_transformation: Optional[Transformation], to_single_waveform: Set[Union[str, 'PulseTemplate']], parent_loop: Loop): """Generic part of create program. This method handles to_single_waveform and the configuration of the transformer.""" if self.identifier in to_single_waveform or self in to_single_waveform: root = Loop() if not scope.get_volatile_parameters().keys().isdisjoint( self.parameter_names): raise NotImplementedError( 'A pulse template that has volatile parameters cannot be transformed into a ' 'single waveform yet.') self._internal_create_program( scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=to_single_waveform, parent_loop=root) waveform = to_waveform(root) if global_transformation: waveform = TransformingWaveform(waveform, global_transformation) # convert the nicely formatted measurement windows back into the old format again :( measurements = root.get_measurement_windows() measurement_window_list = [] for measurement_name, (begins, lengths) in measurements.items(): measurement_window_list.extend( zip(itertools.repeat(measurement_name), begins, lengths)) parent_loop.add_measurements(measurement_window_list) parent_loop.append_child(waveform=waveform) else: self._internal_create_program( scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=to_single_waveform, global_transformation=global_transformation, parent_loop=parent_loop)
def test_create_program_invalid_measurement_mapping(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration=4, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) invalid_parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2) } measurement_mapping = dict() channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) with self.assertRaises(KeyError): flt._internal_create_program( parameters=invalid_parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, program.children) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal( {}, program.get_measurement_windows()) # test for broken mapping on child level. no guarantee that parent_loop is not changed, only check for exception measurement_mapping = dict(A='B') with self.assertRaises(KeyError): flt._internal_create_program( parameters=invalid_parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None)
def test_create_program_declaration_success_appended_measurements( self) -> None: repetitions = "foo" body = DummyPulseTemplate(duration=2.0, waveform=DummyWaveform(duration=2), measurements=[('b', 0, 1)]) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9'], measurements=[('moth', 0, 'meas_end')]) scope = DictScope.from_kwargs(foo=3, meas_end=7.1) measurement_mapping = dict(moth='fire', b='b') channel_mapping = dict(asd='f') children = [Loop(waveform=DummyWaveform(duration=0))] program = Loop(children=children, measurements=[('a', [0], [1])], repetition_count=2) t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertEqual(2, program.repetition_count) self.assertEqual(2, len(program.children)) self.assertIs(program.children[0], children[0]) internal_loop = program.children[1] # type: Loop self.assertEqual(scope[repetitions], internal_loop.repetition_count) self.assertEqual(1, len(internal_loop)) self.assertEqual( (scope, measurement_mapping, channel_mapping, internal_loop), body.create_program_calls[-1]) self.assertEqual(body.waveform, internal_loop[0].waveform) self.assert_measurement_windows_equal( { 'fire': ([0, 6], [7.1, 7.1]), 'b': ([0, 2, 4, 6, 8, 10], [1, 1, 1, 1, 1, 1]), 'a': ([0], [1]) }, program.get_measurement_windows())
def _render_loop( loop: Loop, render_measurements: bool, ) -> Tuple[Waveform, List[MeasurementWindow]]: """Transform program into single waveform and measurement windows. The specific implementation of render for Loop arguments.""" waveform = to_waveform(loop) if render_measurements: measurement_dict = loop.get_measurement_windows() measurement_list = [] for name, (begins, lengths) in measurement_dict.items(): measurement_list.extend( zip(itertools.repeat(name), begins, lengths)) measurements = sorted(measurement_list, key=operator.itemgetter(1)) else: measurements = [] return waveform, measurements
def _create_program(self, *, parameters: Dict[str, Parameter], measurement_mapping: Dict[str, Optional[str]], channel_mapping: Dict[ChannelID, Optional[ChannelID]], global_transformation: Optional[Transformation], to_single_waveform: Set[Union[str, 'PulseTemplate']], parent_loop: Loop): """Generic part of create program. This method handles to_single_waveform and the configuration of the transformer.""" if self.identifier in to_single_waveform or self in to_single_waveform: root = Loop() self._internal_create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, global_transformation=None, to_single_waveform=to_single_waveform, parent_loop=root) waveform = to_waveform(root) if global_transformation: waveform = TransformingWaveform(waveform, global_transformation) # convert the nicely formatted measurement windows back into the old format again :( measurements = root.get_measurement_windows() measurement_window_list = [] for measurement_name, (begins, lengths) in measurements.items(): measurement_window_list.extend( zip(itertools.repeat(measurement_name), begins, lengths)) parent_loop.add_measurements(measurement_window_list) parent_loop.append_child(waveform=waveform) else: self._internal_create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=to_single_waveform, global_transformation=global_transformation, parent_loop=parent_loop)
def _render_loop( loop: Loop, sample_rate: Real, render_measurements: bool, time_slice: Tuple[Real, Real] = None ) -> Union[Tuple[np.ndarray, Dict[ChannelID, np.ndarray]], Tuple[ np.ndarray, Dict[ChannelID, np.ndarray], List[MeasurementWindow]]]: """The specific implementation of render for Loop arguments.""" waveform = to_waveform(loop) channels = waveform.defined_channels if time_slice is None: time_slice = (0, waveform.duration) elif time_slice[1] < time_slice[0] or time_slice[0] < 0 or time_slice[ 1] < 0: raise ValueError("time_slice is not valid.") sample_count = (time_slice[1] - time_slice[0]) * sample_rate + 1 times = np.linspace(float(time_slice[0]), float(time_slice[1]), num=int(sample_count), dtype=float) times[-1] = np.nextafter(times[-1], times[-2]) voltages = {} for ch in channels: voltages[ch] = waveform.get_sampled(ch, times) if render_measurements: measurement_dict = loop.get_measurement_windows() measurement_list = [] for name, (begins, lengths) in measurement_dict.items(): measurement_list.extend( m for m in zip(itertools.repeat(name), begins, lengths) if m[1] + m[2] > time_slice[0] and m[1] < time_slice[1]) measurements = sorted(measurement_list, key=operator.itemgetter(1)) else: measurements = [] return times, voltages, measurements
def test_create_program_append(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration=4, measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 0, 1)], parameter_constraints=['c > 1']) parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2) } measurement_mapping = dict(A='B', b='b') channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) flt._internal_create_program(parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(3, len(program.children)) self.assertIs(children[0], program.children[0]) self.assertEqual(dt.waveform, program.children[1].waveform) self.assertEqual(dt.waveform, program.children[2].waveform) self.assertEqual(1, program.children[1].repetition_count) self.assertEqual(1, program.children[2].repetition_count) self.assertEqual(1, program.repetition_count) self.assert_measurement_windows_equal( { 'b': ([4, 8], [1, 1]), 'B': ([2], [1]) }, program.get_measurement_windows())
def test_create_program_constant_measurement_mapping_failure(self) -> None: repetitions = "foo" body = DummyPulseTemplate(duration=2.0, waveform=DummyWaveform(duration=2.0), measurements=[('b', 0, 1)]) t = RepetitionPulseTemplate(body, repetitions, parameter_constraints=['foo<9'], measurements=[('a', 0, 1)]) scope = DictScope.from_kwargs(foo=3) measurement_mapping = dict() channel_mapping = dict(asd='f') children = [Loop(waveform=DummyWaveform(duration=0))] program = Loop(children=children) with self.assertRaises(KeyError): t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) # test for failure on child level measurement_mapping = dict(a='a') with self.assertRaises(KeyError): t._internal_create_program(scope=scope, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, to_single_waveform=set(), global_transformation=None, parent_loop=program) self.assertFalse(body.create_program_calls) self.assertEqual(1, program.repetition_count) self.assertEqual(children, list(program.children)) self.assertIsNone(program.waveform) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())
def register_program(self, name: str, program: Loop, run_callback=lambda: None, update=False) -> None: if not callable(run_callback): raise TypeError('The provided run_callback is not callable') channels = next( program.get_depth_first_iterator()).waveform.defined_channels if channels - set(self._channel_map.keys()): raise KeyError( 'The following channels are unknown to the HardwareSetup: {}'. format(channels - set(self._channel_map.keys()))) temp_measurement_windows = defaultdict(list) for mw_name, begins_lengths in program.get_measurement_windows().items( ): temp_measurement_windows[mw_name].append(begins_lengths) if set(temp_measurement_windows.keys()) - set( self._measurement_map.keys()): raise KeyError( 'The following measurements are not registered: {}\nUse set_measurement for that.' .format( set(temp_measurement_windows.keys()) - set(self._measurement_map.keys()))) measurement_windows = dict() while temp_measurement_windows: mw_name, begins_lengths_deque = temp_measurement_windows.popitem() begins, lengths = zip(*begins_lengths_deque) measurement_windows[mw_name] = (np.concatenate(begins), np.concatenate(lengths)) affected_dacs = defaultdict(dict) for measurement_name, begins_lengths in measurement_windows.items(): for dac, mask_name in self._measurement_map[measurement_name]: affected_dacs[dac][mask_name] = begins_lengths handled_awgs = set() awgs_to_channel_info = dict() def get_default_info(awg): return ([None] * awg.num_channels, [None] * awg.num_channels, [None] * awg.num_markers) for channel_id in channels: for single_channel in self._channel_map[channel_id]: playback_ids, voltage_trafos, marker_ids = \ awgs_to_channel_info.setdefault(single_channel.awg, get_default_info(single_channel.awg)) if isinstance(single_channel, PlaybackChannel): playback_ids[single_channel.channel_on_awg] = channel_id voltage_trafos[ single_channel. channel_on_awg] = single_channel.voltage_transformation elif isinstance(single_channel, MarkerChannel): marker_ids[single_channel.channel_on_awg] = channel_id for awg, (playback_ids, voltage_trafos, marker_ids) in awgs_to_channel_info.items(): if awg in handled_awgs: raise ValueError('AWG has two programs') else: handled_awgs.add(awg) awg.upload(name, program=program, channels=tuple(playback_ids), markers=tuple(marker_ids), force=update, voltage_transformation=tuple(voltage_trafos)) for dac, dac_windows in affected_dacs.items(): dac.register_measurement_windows(name, dac_windows) self._registered_programs[name] = RegisteredProgram( program=program, measurement_windows=measurement_windows, run_callback=run_callback, awgs_to_upload_to=handled_awgs, dacs_to_arm=set(affected_dacs.keys()))
def test_create_program_missing_params(self) -> None: dt = DummyPulseTemplate(parameter_names={'i'}, waveform=DummyWaveform(duration=4.0), duration='t', measurements=[('b', 2, 1)]) flt = ForLoopPulseTemplate(body=dt, loop_index='i', loop_range=('a', 'b', 'c'), measurements=[('A', 'alph', 1)], parameter_constraints=['c > 1']) parameters = {'a': ConstantParameter(1), 'b': ConstantParameter(4)} measurement_mapping = dict(A='B') channel_mapping = dict(C='D') children = [Loop(waveform=DummyWaveform(duration=2.0))] program = Loop(children=children) # test parameter in constraints with self.assertRaises(ParameterNotProvidedException): flt._internal_create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) # test parameter in measurement mappings parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2) } with self.assertRaises(ParameterNotProvidedException): flt._internal_create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) # test parameter in duration parameters = { 'a': ConstantParameter(1), 'b': ConstantParameter(4), 'c': ConstantParameter(2), 'alph': ConstantParameter(0) } with self.assertRaises(ParameterNotProvidedException): flt._internal_create_program( parameters=parameters, measurement_mapping=measurement_mapping, channel_mapping=channel_mapping, parent_loop=program, to_single_waveform=set(), global_transformation=None) self.assertEqual(children, program.children) self.assertEqual(1, program.repetition_count) self.assertIsNone(program._measurements) self.assert_measurement_windows_equal( {}, program.get_measurement_windows())