def test_add_entry_for_interpolation(self) -> None: table = TablePulseTemplate() strategies = ["linear","hold","jump","hold"] for i,strategy in enumerate(strategies): table.add_entry(2*(i+1), i+1, strategy) self.assertRaises(ValueError, table.add_entry, 1,2, "bar")
def test_add_entry_empty_time_is_str(self) -> None: table = TablePulseTemplate() table.add_entry('t', 0) decl = ParameterDeclaration('t', min=0) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (decl, 0, HoldInterpolationStrategy())], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def generate_TablePulseTemplates(self,number_of_entries,max_dist=RANGE): while 1: x = TablePulseTemplate() name = "TablePulseTemplate_{}".format(self.__TablePulseTemplateOffset) self.__TablePulseTemplateOffset +=1 if bool(random.getrandbits(1)): x.identifier = name previous_min = 0 previous_max = 0 parameter_names = [] for i in range(number_of_entries): dict_ = {} for j in ["time","voltage"]: a = random.choice(["float","str","ParameterDeclaration"]) if a == "float": if j == "time": dict_[j] = random.uniform(previous_max,previous_max+max_dist) previous_min = dict_[j] previous_max = dict_[j] else: dict_[j] = random.uniform(-RANGE,RANGE) elif a == "str": dict_[j] = "_".join([name,"str",str(i),str(j)]) parameter_names.append(dict_[j]) elif a == "ParameterDeclaration": if j == "time": dict_[j] = self.generate_ParameterDeclaration(previous_min, previous_min+max_dist, name, previous_max).__next__() previous_min = dict_[j].min_value previous_max = dict_[j].max_value else: dict_[j] = self.generate_ParameterDeclaration().__next__() parameter_names.append(dict_[j].name) x.add_entry(time=dict_["time"],voltage=dict_["voltage"],interpolation=random.choice(INTERPOLATION_STRATEGIES)) yield x
def test_add_entry_empty_time_is_0_voltage_is_parameter(self) -> None: table = TablePulseTemplate() table.add_entry(0, 'foo') decl = ParameterDeclaration('foo') self.assertEqual([(0, decl, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_no_measurement_windows(self) -> None: pulse = TablePulseTemplate(measurement=False) pulse.add_entry(1, 1) pulse.add_entry(3, 0) pulse.add_entry(5, 0) windows = pulse.get_measurement_windows() self.assertEqual([], windows)
def test_add_entry_empty_time_is_declaration(self) -> None: table = TablePulseTemplate() decl = ParameterDeclaration('foo') table.add_entry(decl, 0) decl.min_value = 0 self.assertEqual([(0, 0, HoldInterpolationStrategy()), (decl, 0, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_add_entry_time_float_after_declaration_smaller_bound(self) -> None: table = TablePulseTemplate() decl = ParameterDeclaration('t', min=1.0, max=1.3) table.add_entry(decl, 7.1) table.add_entry(2.1, 5.5) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (decl, 7.1, HoldInterpolationStrategy()), (2.1, 5.5, HoldInterpolationStrategy())], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_add_entry_known_interpolation_strategies(self) -> None: table = TablePulseTemplate() strategies = ["linear", "hold", "jump"] for i,strategy in enumerate(strategies): table.add_entry(i, i, strategy) manual = [(0,0,LinearInterpolationStrategy()), (1,1,HoldInterpolationStrategy()), (2,2,JumpInterpolationStrategy())] self.assertEqual(manual, table.entries)
def test_add_entry_time_declaration_higher_min_after_float(self) -> None: table = TablePulseTemplate() table.add_entry(3.2, 92.1) decl = ParameterDeclaration('t', min=4.5) table.add_entry(decl, 1.2) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (3.2, 92.1, HoldInterpolationStrategy()), (decl, 1.2, HoldInterpolationStrategy())], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_add_entry_voltage_declaration_in_use_as_time(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=0, max=2) table.add_entry(foo_decl, 0) self.assertRaises(ValueError, table.add_entry, 4, foo_decl) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (foo_decl, 0, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({foo_decl}, table.parameter_declarations)
def test_add_entry_time_declaration_lower_min_after_float(self) -> None: table = TablePulseTemplate() table.add_entry(3.2, 92.1) decl = ParameterDeclaration('t', min=0.1) self.assertRaises(ValueError, table.add_entry, decl, 1.2) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (3.2, 92.1, HoldInterpolationStrategy())], table.entries) self.assertFalse(table.parameter_names) self.assertFalse(table.parameter_declarations)
def test_get_entries_instantiated_two_entries_invalid_parameters(self) -> None: table = TablePulseTemplate() table.add_entry(0, 'v1') t_decl = ParameterDeclaration('t', min=1, max=2) v2_decl = ParameterDeclaration('v2', min=10, max=30) table.add_entry(t_decl, v2_decl) self.assertRaises(ParameterValueIllegalException, table.get_entries_instantiated, {'v1': -5, 't': 0, 'v2': 20}) self.assertRaises(ParameterValueIllegalException, table.get_entries_instantiated, {'v1': -5, 't': 1, 'v2': -20})
def test_add_entry_time_float_after_declaration_smaller_than_min_bound(self) -> None: table = TablePulseTemplate() decl = ParameterDeclaration('t', min=1.2, max=83456.2) table.add_entry(decl, 2.2) with self.assertRaises(ValueError): table.add_entry(1.1, -6.3) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (decl, 2.2, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_add_entry_time_float_after_declaration_greater_bound(self) -> None: table = TablePulseTemplate() decl = ParameterDeclaration('t', max=3.4) table.add_entry(decl, 7.1) decl.min_value = 0 self.assertRaises(ValueError, table.add_entry, 2.1, 5.5) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (decl, 7.1, HoldInterpolationStrategy())], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({decl}, table.parameter_declarations)
def test_add_entry_time_declaration_lower_bound_upper_bound_too_small_after_declaration(self) -> None: table = TablePulseTemplate() bar_decl = ParameterDeclaration('bar', min=1, max=2) foo_decl = ParameterDeclaration('foo', min=1, max=1.5) table.add_entry(bar_decl, -3) self.assertRaises(ValueError, table.add_entry, foo_decl, 0.1) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (bar_decl, -3, HoldInterpolationStrategy())], table.entries) self.assertEqual({'bar'}, table.parameter_names) self.assertEqual({bar_decl}, table.parameter_declarations)
def test_add_entry_time_declaration_lower_bound_after_declaration_upper_bound(self) -> None: table = TablePulseTemplate() bar_decl = ParameterDeclaration('bar', min=1, max=2) foo_decl = ParameterDeclaration('foo', min=1) table.add_entry(bar_decl, -3) table.add_entry(foo_decl, 0.1) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (bar_decl, -3, HoldInterpolationStrategy()), (foo_decl, 0.1, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo', 'bar'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl}, table.parameter_declarations)
def test_get_entries_instantiated_unlinked_time_declarations(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1, max=2) bar_decl = ParameterDeclaration('bar', min=1.5, max=4) table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') instantiated_entries = table.get_entries_instantiated({'v': 2.3, 'foo': 1, 'bar': 4}) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (1, 2.3, LinearInterpolationStrategy()), (4, 0, JumpInterpolationStrategy())], instantiated_entries) self.assertRaises(Exception, table.get_entries_instantiated, {'v': 2.3, 'foo': 2, 'bar': 1.5})
def test_add_entry_time_float_after_declaration_greater_bound(self) -> None: table = TablePulseTemplate() decl = ParameterDeclaration('t', max=3.4) table.add_entry(decl, 7.1) table.add_entry(2.1, 5.5) expected_decl = ParameterDeclaration('t', min=0, max=2.1) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (expected_decl, 7.1, HoldInterpolationStrategy()), (2.1, 5.5, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'t'}, table.parameter_names) self.assertEqual({expected_decl}, table.parameter_declarations)
def test_add_entry_time_parmeter_name_in_use_as_time(self) -> None: table = TablePulseTemplate() table.add_entry('foo', 'bar') foo_decl = ParameterDeclaration('foo', min=0) bar_decl = ParameterDeclaration('bar') self.assertRaises(ValueError, table.add_entry, ParameterDeclaration('foo'), 3.4) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (foo_decl, bar_decl, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo', 'bar'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl}, table.parameter_declarations)
class SequencePulseTemplateSerializationTests(unittest.TestCase): def setUp(self) -> None: self.serializer = DummySerializer() self.table_foo = TablePulseTemplate(identifier='foo') self.table_foo.add_entry('hugo', 2) self.table_foo.add_entry(ParameterDeclaration('albert', max=9.1), 'voltage') self.table = TablePulseTemplate(measurement=True) self.foo_mappings = dict(hugo='ilse', albert='albert', voltage='voltage') def test_get_serialization_data(self) -> None: sequence = SequencePulseTemplate([(self.table_foo, self.foo_mappings), (self.table, {})], ['ilse', 'albert', 'voltage'], identifier='foo') expected_data = dict( type=self.serializer.get_type_identifier(sequence), external_parameters=['albert', 'ilse', 'voltage'], is_interruptable=True, subtemplates = [ dict(template=str(id(self.table_foo)), mappings=self.foo_mappings), dict(template=str(id(self.table)), mappings=dict()) ] ) data = sequence.get_serialization_data(self.serializer) self.assertEqual(expected_data, data) def test_deserialize(self) -> None: data = dict( external_parameters={'ilse', 'albert', 'voltage'}, is_interruptable=True, subtemplates = [ dict(template=str(id(self.table_foo)), mappings=self.foo_mappings), dict(template=str(id(self.table)), mappings=dict()) ], identifier='foo' ) # prepare dependencies for deserialization self.serializer.subelements[str(id(self.table_foo))] = self.table_foo self.serializer.subelements[str(id(self.table))] = self.table # deserialize sequence = SequencePulseTemplate.deserialize(self.serializer, **data) # compare! self.assertEqual(data['external_parameters'], sequence.parameter_names) self.assertEqual({ParameterDeclaration('ilse'), ParameterDeclaration('albert'), ParameterDeclaration('voltage')}, sequence.parameter_declarations) self.assertIs(self.table_foo, sequence.subtemplates[0][0]) self.assertIs(self.table, sequence.subtemplates[1][0]) self.assertEqual(self.foo_mappings, {k: m.string for k,m in sequence.subtemplates[0][1].items()}) self.assertEqual(dict(), sequence.subtemplates[1][1]) self.assertEqual(data['identifier'], sequence.identifier)
def test_add_entry_time_declaration_after_declaration_upper_bound(self) -> None: table = TablePulseTemplate() bar_decl = ParameterDeclaration('bar', min=1, max=2) foo_decl = ParameterDeclaration('foo') table.add_entry(bar_decl, -3) table.add_entry(foo_decl, 0.1) foo_decl.min_value = bar_decl self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (bar_decl, -3, HoldInterpolationStrategy()), (foo_decl, 0.1, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'foo', 'bar'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl}, table.parameter_declarations)
def test_add_entry_time_declaration_after_declaration_no_upper_bound(self) -> None: table = TablePulseTemplate() table.add_entry('bar', 72.14) table.add_entry('foo', 0) bar_decl = ParameterDeclaration('bar', min=0) foo_decl = ParameterDeclaration('foo') foo_decl.min_value = bar_decl self.assertEqual([(0, 0, HoldInterpolationStrategy()), (bar_decl, 72.14, HoldInterpolationStrategy()), (foo_decl, 0, HoldInterpolationStrategy())], table.entries) self.assertEqual({'bar', 'foo'}, table.parameter_names) self.assertEqual({bar_decl, foo_decl}, table.parameter_declarations)
def test_add_entry_time_declaration_lower_bound_upper_bound_too_small_after_declaration(self) -> None: table = TablePulseTemplate() bar_decl = ParameterDeclaration('bar', min=1, max=2) foo_decl = ParameterDeclaration('foo', min=1, max=1.5) table.add_entry(bar_decl, -3) with self.assertRaises(ValueError): table.add_entry(foo_decl, 0.1) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (bar_decl, -3, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'bar'}, table.parameter_names) self.assertEqual({bar_decl}, table.parameter_declarations)
def test_add_entry_time_parmeter_name_in_use_as_time(self) -> None: table = TablePulseTemplate() table.add_entry('foo', 'bar') foo_decl = ParameterDeclaration('foo', min=0) bar_decl = ParameterDeclaration('bar') with self.assertRaises(ValueError): table.add_entry(ParameterDeclaration('foo'), 3.4) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (foo_decl, bar_decl, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'foo', 'bar'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl}, table.parameter_declarations)
def test_add_entry_time_declaration_after_declaration_no_upper_bound(self) -> None: table = TablePulseTemplate() table.add_entry('bar', 72.14) table.add_entry('foo', 0) bar_decl = ParameterDeclaration('bar', min=0) foo_decl = ParameterDeclaration('foo') foo_decl.min_value = bar_decl self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (bar_decl, 72.14, HoldInterpolationStrategy()), (foo_decl, 0, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'bar', 'foo'}, table.parameter_names) self.assertEqual({bar_decl, foo_decl}, table.parameter_declarations)
def test_add_entry_time_parameter_name_in_use_as_voltage(self) -> None: table = TablePulseTemplate() table.add_entry(0, 'foo') foo_decl = ParameterDeclaration('foo') self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({foo_decl}, table.parameter_declarations) self.assertRaises(ValueError, table.add_entry, 'foo', 4.3) self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({foo_decl}, table.parameter_declarations) self.assertEqual([(0, foo_decl, HoldInterpolationStrategy())], table.entries)
def test_get_entries_instantiated_unlinked_time_declarations(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1, max=2) bar_decl = ParameterDeclaration('bar', min=1.5, max=4) table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') instantiated_entries = table.get_entries_instantiated({'v': 2.3, 'foo': 1, 'bar': 4}) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (1, 2.3, LinearInterpolationStrategy()), (4, 0, JumpInterpolationStrategy())]], instantiated_entries) with self.assertRaises(Exception): table.get_entries_instantiated({'v': 2.3, 'foo': 2, 'bar': 1.5})
def test_get_entries_instantiated_two_entries_invalid_parameters(self) -> None: table = TablePulseTemplate() table.add_entry(0, 'v1') t_decl = ParameterDeclaration('t', min=1, max=2) v2_decl = ParameterDeclaration('v2', min=10, max=30) table.add_entry(t_decl, v2_decl) with self.assertRaises(ParameterValueIllegalException): table.get_entries_instantiated({'v1': -5, 't': 0, 'v2': 20}) with self.assertRaises(ParameterValueIllegalException): table.get_entries_instantiated({'v1': -5, 't': 1, 'v2': -20})
def test_concatenation_sequence_table_pulse_double_parameter(self): a = TablePulseTemplate() a.add_entry('t', 'a') b = TablePulseTemplate() b.add_entry('t', 'a') subtemplates = [(b, {'t': 't', 'a': 'a'})] seq = SequencePulseTemplate(subtemplates, ['t', 'a']) with self.assertRaises(DoubleParameterNameException) as e: concat = seq @ a
def test_add_entry_time_parameter_name_in_use_as_voltage(self) -> None: table = TablePulseTemplate() table.add_entry(0, 'foo') foo_decl = ParameterDeclaration('foo') self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({foo_decl}, table.parameter_declarations) with self.assertRaises(ValueError): table.add_entry('foo', 4.3) self.assertEqual({'foo'}, table.parameter_names) self.assertEqual({foo_decl}, table.parameter_declarations) self.assertEqual([[(0, foo_decl, HoldInterpolationStrategy())]], table.entries)
def test_add_entry_time_float_after_float(self) -> None: table = TablePulseTemplate() table.add_entry(1.2, -3.8) # expect ValueError if next float is smaller or equal than previous self.assertRaises(ValueError, table.add_entry, 0.423, 0) self.assertRaises(ValueError, table.add_entry, 1.2, 0) # adding a higher value as next entry should work table.add_entry(3.7, 1.34875) self.assertEqual([(0, 0, HoldInterpolationStrategy()), (1.2, -3.8, HoldInterpolationStrategy()), (3.7, 1.34875, HoldInterpolationStrategy())], table.entries) self.assertFalse(table.parameter_names) self.assertFalse(table.parameter_declarations)
def test_add_entry_time_declaration_invalid_bounds(self) -> None: table = TablePulseTemplate() bar_decl = ParameterDeclaration('bar') foo_decl = ParameterDeclaration('foo') foo_decl.min_value = bar_decl with self.assertRaises(ValueError): table.add_entry(foo_decl, 23857.23) with self.assertRaises(ValueError): table.add_entry(bar_decl, -4967.1) self.assertEquals([[TableEntry(0, 0, HoldInterpolationStrategy())]], table.entries) self.assertFalse(table.parameter_names) self.assertFalse(table.parameter_declarations)
def test_get_entries_instantiated_two_equal_entries(self) -> None: table = TablePulseTemplate() table.add_entry(0, 0) table.add_entry(1, 5) table.add_entry(3, 5) table.add_entry(5, 1) entries = table.get_entries_instantiated({}) expected = [[ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(1, 5, HoldInterpolationStrategy()), TableEntry(3, 5, HoldInterpolationStrategy()), TableEntry(5, 1, HoldInterpolationStrategy()) ]] self.assertEqual(expected, entries)
def test_get_entries_instantiated_two_equal_entries(self) -> None: table = TablePulseTemplate() table.add_entry(0, 0) table.add_entry(1, 5) table.add_entry(3, 5) table.add_entry(5, 1) entries = table.get_entries_instantiated({}) expected = [ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(1, 5, HoldInterpolationStrategy()), TableEntry(3, 5, HoldInterpolationStrategy()), TableEntry(5, 1, HoldInterpolationStrategy()) ] self.assertEqual(expected, entries)
def test_table_sequence_sequencer_integration(self) -> None: t1 = TablePulseTemplate() t1.add_entry(2, 'foo') t1.add_entry(5, 0) t2 = TablePulseTemplate() t2.add_entry(4, 0) t2.add_entry(4.5, 'bar', 'linear') t2.add_entry(5, 0) seqt = SequencePulseTemplate([(t1, {'foo': 'foo'}), (t2, {'bar': '2 * hugo'})], {'foo', 'hugo'}) with self.assertRaises(ParameterNotProvidedException): t1.requires_stop(dict(), dict()) with self.assertRaises(ParameterNotProvidedException): t2.requires_stop(dict(), dict()) self.assertFalse(seqt.requires_stop({}, {})) foo = DummyNoValueParameter() bar = DummyNoValueParameter() sequencer = Sequencer() sequencer.push(seqt, {'foo': foo, 'hugo': bar}) instructions = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(1, len(instructions)) foo = DummyParameter(value=1.1) bar = DummyNoValueParameter() sequencer = Sequencer() sequencer.push(seqt, {'foo': foo, 'hugo': bar}) instructions = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(2, len(instructions)) foo = DummyParameter(value=1.1) bar = DummyNoValueParameter() sequencer = Sequencer() sequencer.push(seqt, {'foo': bar, 'hugo': foo}) instructions = sequencer.build() self.assertFalse(sequencer.has_finished()) self.assertEqual(1, len(instructions)) foo = DummyParameter(value=1.1) bar = DummyParameter(value=-0.2) sequencer = Sequencer() sequencer.push(seqt, {'foo': foo, 'hugo': bar}) instructions = sequencer.build() self.assertTrue(sequencer.has_finished()) self.assertEqual(3, len(instructions))
class TablePulseTemplateSerializationTests(unittest.TestCase): def setUp(self) -> None: self.serializer = DummySerializer(lambda x: dict(name=x.name), lambda x: x.name, lambda x: x['name']) self.template = TablePulseTemplate(measurement=True, identifier='foo') self.expected_data = dict(type=self.serializer.get_type_identifier(self.template)) def test_get_serialization_data(self) -> None: self.template.add_entry('foo', 2) self.template.add_entry('hugo', 'ilse', interpolation='linear') self.expected_data['is_measurement_pulse'] = True self.expected_data['time_parameter_declarations'] = [dict(name='foo'), dict(name='hugo')] self.expected_data['voltage_parameter_declarations'] = [dict(name='ilse')] self.expected_data['entries'] = [[(0, 0, 'hold'), ('foo', 2, 'hold'), ('hugo', 'ilse', 'linear')]] data = self.template.get_serialization_data(self.serializer) self.assertEqual(self.expected_data, data) def test_deserialize(self) -> None: data = dict(is_measurement_pulse=True, time_parameter_declarations=[dict(name='hugo'), dict(name='foo')], voltage_parameter_declarations=[dict(name='ilse')], entries=[[(0, 0, 'hold'), ('foo', 2, 'hold'), ('hugo', 'ilse', 'linear')]], identifier='foo') # prepare dependencies for deserialization self.serializer.subelements['foo'] = ParameterDeclaration('foo') self.serializer.subelements['hugo'] = ParameterDeclaration('hugo') self.serializer.subelements['ilse'] = ParameterDeclaration('ilse') # deserialize template = TablePulseTemplate.deserialize(self.serializer, **data) # prepare expected parameter declarations self.serializer.subelements['foo'].min_value = 0 self.serializer.subelements['foo'].max_value = self.serializer.subelements['hugo'] all_declarations = set(self.serializer.subelements.values()) # prepare expected entries entries = [[(0, 0, HoldInterpolationStrategy()), (self.serializer.subelements['foo'], 2, HoldInterpolationStrategy()), (self.serializer.subelements['hugo'], self.serializer.subelements['ilse'], LinearInterpolationStrategy())]] # compare! self.assertEqual(all_declarations, template.parameter_declarations) self.assertEqual({'foo', 'hugo', 'ilse'}, template.parameter_names) self.assertEqual(entries, template.entries) self.assertEqual('foo', template.identifier)
def test_requires_stop(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1) bar_decl = ParameterDeclaration('bar') table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') test_sets = [(False, {'foo': DummyParameter(0, False), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, False)}, {'foo': DummyCondition(False)}), (False, {'foo': DummyParameter(0, False), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, False)}, {'foo': DummyCondition(True)}), (True, {'foo': DummyParameter(0, True), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, False)}, {'foo': DummyCondition(False)}), (True, {'foo': DummyParameter(0, True), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, False)}, {'foo': DummyCondition(True)}), (True, {'foo': DummyParameter(0, False), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, True)}, {'foo': DummyCondition(False)}), (True, {'foo': DummyParameter(0, False), 'bar': DummyParameter(0, False), 'v': DummyParameter(0, True)}, {'foo': DummyCondition(True)}), (True, {'foo': DummyParameter(0, True), 'bar': DummyParameter(0, True), 'v': DummyParameter(0, True)}, {'foo': DummyCondition(False)}), (True, {'foo': DummyParameter(0, True), 'bar': DummyParameter(0, True), 'v': DummyParameter(0, True)}, {'foo': DummyCondition(True)})] for expected_result, parameter_set, condition_set in test_sets: self.assertEqual(expected_result, table.requires_stop(parameter_set, condition_set))
def test_build_sequence(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1) bar_decl = ParameterDeclaration('bar') table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') parameters = {'v': 2.3, 'foo': 1, 'bar': 4} instantiated_entries = tuple(table.get_entries_instantiated(parameters)) sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, parameters, {}, instruction_block) waveform = TableWaveform(instantiated_entries) self.assertEqual(1, len(instruction_block.instructions)) instruction = instruction_block.instructions[0] self.assertIsInstance(instruction, EXECInstruction) self.assertEqual(waveform, instruction.waveform)
class TablePulseTemplateSerializationTests(unittest.TestCase): def setUp(self) -> None: self.serializer = DummySerializer(lambda x: dict(name=x.name), lambda x: x.name, lambda x: x['name']) self.template = TablePulseTemplate(measurement=True, identifier='foo') self.expected_data = dict(type=self.serializer.get_type_identifier(self.template)) def test_get_serialization_data(self) -> None: self.template.add_entry('foo', 2) self.template.add_entry('hugo', 'ilse', interpolation='linear') self.expected_data['is_measurement_pulse'] = True self.expected_data['time_parameter_declarations'] = [dict(name='foo'), dict(name='hugo')] self.expected_data['voltage_parameter_declarations'] = [dict(name='ilse')] self.expected_data['entries'] = [(0, 0, 'hold'), ('foo', 2, 'hold'), ('hugo', 'ilse', 'linear')] self.assertEqual(self.expected_data, self.template.get_serialization_data(self.serializer)) def test_deserialize(self) -> None: data = dict(is_measurement_pulse=True, time_parameter_declarations=[dict(name='hugo'), dict(name='foo')], voltage_parameter_declarations=[dict(name='ilse')], entries=[(0, 0, 'hold'), ('foo', 2, 'hold'), ('hugo', 'ilse', 'linear')], identifier='foo') # prepare dependencies for deserialization self.serializer.subelements['foo'] = ParameterDeclaration('foo') self.serializer.subelements['hugo'] = ParameterDeclaration('hugo') self.serializer.subelements['ilse'] = ParameterDeclaration('ilse') # deserialize template = TablePulseTemplate.deserialize(self.serializer, **data) # prepare expected parameter declarations self.serializer.subelements['foo'].min_value = 0 self.serializer.subelements['foo'].max_value = self.serializer.subelements['hugo'] all_declarations = set(self.serializer.subelements.values()) # prepare expected entries entries = [(0, 0, HoldInterpolationStrategy()), (self.serializer.subelements['foo'], 2, HoldInterpolationStrategy()), (self.serializer.subelements['hugo'], self.serializer.subelements['ilse'], LinearInterpolationStrategy())] # compare! self.assertEqual(all_declarations, template.parameter_declarations) self.assertEqual({'foo', 'hugo', 'ilse'}, template.parameter_names) self.assertEqual(entries, template.entries) self.assertEqual('foo', template.identifier)
class SequencePulseTemplateTest(unittest.TestCase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Setup test data self.square = TablePulseTemplate() self.square.add_entry('up', 'v', 'hold') self.square.add_entry('down', 0, 'hold') self.square.add_entry('length', 0) self.mapping1 = { 'up': 'uptime', 'down': 'uptime + length', 'v': 'voltage', 'length': '0.5 * pulse_length' } self.outer_parameters = ['uptime', 'length', 'pulse_length', 'voltage'] self.parameters = {} self.parameters['uptime'] = ConstantParameter(5) self.parameters['length'] = ConstantParameter(10) self.parameters['pulse_length'] = ConstantParameter(100) self.parameters['voltage'] = ConstantParameter(10) self.sequence = SequencePulseTemplate([(self.square, self.mapping1)], self.outer_parameters) def test_missing_mapping(self): mapping = self.mapping1 mapping.pop('v') subtemplates = [(self.square, mapping)] with self.assertRaises(MissingMappingException): SequencePulseTemplate(subtemplates, self.outer_parameters) def test_unnecessary_mapping(self): mapping = self.mapping1 mapping['unnecessary'] = 'voltage' subtemplates = [(self.square, mapping)] with self.assertRaises(UnnecessaryMappingException): SequencePulseTemplate(subtemplates, self.outer_parameters) def test_identifier(self): identifier = 'some name' pulse = SequencePulseTemplate([], [], identifier=identifier) self.assertEqual(identifier, pulse.identifier)
def test_build_sequence_multi_one_channel_empty(self) -> None: table = TablePulseTemplate(channels=2) table.add_entry('foo', 4) parameters = {'foo': 3} instantiated_entries = table.get_entries_instantiated(parameters) sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, parameters, {}, instruction_block) expected_waveform = TableWaveform(instantiated_entries) self.assertEqual(1, len(instruction_block.instructions)) instruction = instruction_block.instructions[0] self.assertIsInstance(instruction, EXECInstruction) self.assertEqual(expected_waveform, instruction.waveform) waveform = table.build_waveform(parameters) self.assertEqual(expected_waveform, waveform)
def test_build_sequence(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=1) bar_decl = ParameterDeclaration('bar') table.add_entry(foo_decl, 'v', 'linear') table.add_entry(bar_decl, 0, 'jump') parameters = {'v': 2.3, 'foo': 1, 'bar': 4} instantiated_entries = tuple(table.get_entries_instantiated(parameters)) waveform = table.build_waveform(parameters) sequencer = DummySequencer() instruction_block = DummyInstructionBlock() table.build_sequence(sequencer, parameters, {}, instruction_block) expected_waveform = TableWaveform(instantiated_entries) self.assertEqual(1, len(instruction_block.instructions)) instruction = instruction_block.instructions[0] self.assertIsInstance(instruction, EXECInstruction) self.assertEqual(expected_waveform, instruction.waveform) self.assertEqual(expected_waveform, waveform)
def test_measurement_windows_multi(self) -> None: pulse = TablePulseTemplate(measurement=True, channels=2) pulse.add_entry(1, 1) pulse.add_entry(3, 0) pulse.add_entry(5, 0) pulse.add_entry(1, 1, channel=1) pulse.add_entry(3, 0, channel=1) pulse.add_entry(10, 0, channel=1) windows = pulse.get_measurement_windows() self.assertEqual([(0,10)], windows)
def test_get_entries_instantiated_two_channels_one_empty(self) -> None: table = TablePulseTemplate(channels=2) table.add_entry('foo', 4) parameters = {'foo': 10} entries = table.get_entries_instantiated(parameters) expected = [ [ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(10, 4, HoldInterpolationStrategy()), ], [ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(10, 0, HoldInterpolationStrategy()) ] ] self.assertEqual(expected, entries)
def test_add_entry_time_float_after_float(self) -> None: table = TablePulseTemplate() table.add_entry(1.2, -3.8) # expect ValueError if next float is smaller than previous with self.assertRaises(ValueError): table.add_entry(0.423, 0) # adding a higher value or equal value as last entry should work table.add_entry(1.2, 2.5252) table.add_entry(3.7, 1.34875) self.assertEqual([[(0, 0, HoldInterpolationStrategy()), (1.2, 2.5252, HoldInterpolationStrategy()), (3.7, 1.34875, HoldInterpolationStrategy())]], table.entries) self.assertFalse(table.parameter_names) self.assertFalse(table.parameter_declarations)
def integrated_test_with_sequencer_and_pulse_templates(self) -> None: # Setup test data square = TablePulseTemplate() square.add_entry('up', 'v', 'hold') square.add_entry('down', 0, 'hold') square.add_entry('length', 0) mapping1 = { 'up': 'uptime', 'down': 'uptime + length', 'v': 'voltage', 'length': '0.5 * pulse_length' } outer_parameters = ['uptime', 'length', 'pulse_length', 'voltage'] parameters = {} parameters['uptime'] = 5 parameters['length'] = 10 parameters['pulse_length'] = 100 parameters['voltage'] = 10 sequence = SequencePulseTemplate([(square, mapping1), (square, mapping1)], outer_parameters) # run the sequencer and render the plot sample_rate = 20 plotter = Plotter(sample_rate=sample_rate) sequencer = Sequencer(plotter) sequencer.push(sequence, parameters) block = sequencer.build() times, voltages = plotter.render(block) # compute expected values expected_times = numpy.linspace(0, 100, sample_rate) expected_voltages = numpy.zeros_like(expected_times) expected_voltages[100:300] = numpy.ones(200) * parameters['voltage'] # compare self.assertEqual(expected_times, times) self.assertEqual(expected_voltages, voltages)
def test_add_entry_voltage_declaration_reuse(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=0, max=3.3) bar_decl = ParameterDeclaration('bar', min=-3.3, max=1.15) table.add_entry(0, foo_decl) table.add_entry(1.51, bar_decl) table.add_entry(3, 'foo') table.add_entry('t', foo_decl) t_decl = ParameterDeclaration('t', min=3) self.assertEqual([(0, foo_decl, HoldInterpolationStrategy()), (1.51, bar_decl, HoldInterpolationStrategy()), (3, foo_decl, HoldInterpolationStrategy()), (t_decl, foo_decl, HoldInterpolationStrategy())], table.entries) self.assertEqual({'foo', 'bar', 't'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl, t_decl}, table.parameter_declarations)
def test_add_entry_voltage_declaration_reuse(self) -> None: table = TablePulseTemplate() foo_decl = ParameterDeclaration('foo', min=0, max=3.3) bar_decl = ParameterDeclaration('bar', min=-3.3, max=1.15) table.add_entry(0, foo_decl) table.add_entry(1.51, bar_decl) table.add_entry(3, 'foo') table.add_entry('t', foo_decl) t_decl = ParameterDeclaration('t', min=3) self.assertEqual([[(0, foo_decl, HoldInterpolationStrategy()), (1.51, bar_decl, HoldInterpolationStrategy()), (3, foo_decl, HoldInterpolationStrategy()), (t_decl, foo_decl, HoldInterpolationStrategy())]], table.entries) self.assertEqual({'foo', 'bar', 't'}, table.parameter_names) self.assertEqual({foo_decl, bar_decl, t_decl}, table.parameter_declarations)
def test_serialization_and_deserialization_combined(self) -> None: table_foo = TablePulseTemplate(identifier='foo') table_foo.add_entry('hugo', 2) table_foo.add_entry(ParameterDeclaration('albert', max=9.1), 'voltage') table = TablePulseTemplate(measurement=True) foo_mappings = dict(hugo='ilse', albert='albert', voltage='voltage') sequence = SequencePulseTemplate([(table_foo, foo_mappings), (table, {})], ['ilse', 'albert', 'voltage'], identifier=None) storage = DummyStorageBackend() serializer = Serializer(storage) serializer.serialize(sequence) serialized_foo = storage.stored_items['foo'] serialized_sequence = storage.stored_items['main'] deserialized_sequence = serializer.deserialize('main') storage.stored_items = dict() serializer.serialize(deserialized_sequence) self.assertEqual(serialized_foo, storage.stored_items['foo']) self.assertEqual(serialized_sequence, storage.stored_items['main'])
def test_concatenation_sequence_table_pulse(self): a = TablePulseTemplate() a.add_entry('t', 'a') b = TablePulseTemplate() b.add_entry('t', 'a') subtemplates = [(b, {'t': 't_ext', 'a': 'a_ext'})] seq = SequencePulseTemplate(subtemplates, ['t_ext', 'a_ext']) concat = seq @ a subtemplates2 = [(seq, { 't_ext': 't_ext', 'a_ext': 'a_ext' }), (a, { 't': 't', 'a': 'a' })] seq2 = SequencePulseTemplate(subtemplates2, ['a', 'a_ext', 't', 't_ext']) self.assertEqual(concat.parameter_names, seq2.parameter_names) self.assertEqual(concat.subtemplates, seq2.subtemplates)
def test_get_instaniated_entries_multi_one_empty_channel(self) -> None: table = TablePulseTemplate(channels=2) table.add_entry(1, 3, channel=1) table.add_entry('foo', 'bar', 'linear', channel=1) parameters = {'foo': 5.2, 'bar': -83.8} entries = table.get_entries_instantiated(parameters) expected = [ [ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(5.2, 0, HoldInterpolationStrategy()) ], [ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(1, 3, HoldInterpolationStrategy()), TableEntry(5.2, -83.8, LinearInterpolationStrategy()) ] ] self.assertEqual(expected, entries)
def test_get_entries_instantiated_removal_for_three_subsequent_equal_entries_does_not_destroy_linear_interpolation(self) -> None: table = TablePulseTemplate() table.add_entry(0, 5) table.add_entry(2, 5, 'linear') table.add_entry(5, 5) table.add_entry(10, 0, 'linear') entries = table.get_entries_instantiated({}) expected = [ TableEntry(0, 5, HoldInterpolationStrategy()), TableEntry(5, 5, HoldInterpolationStrategy()), TableEntry(10, 0, LinearInterpolationStrategy()) ] self.assertEqual(expected, entries) result_sampled = TableWaveform(entries).sample(numpy.linspace(0, 10, 11), 0) self.assertEqual([5, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0], result_sampled.tolist())
def test_get_entries_instantiated_removal_for_three_subsequent_equal_entries_does_not_destroy_linear_interpolation(self) -> None: table = TablePulseTemplate() table.add_entry(0, 5) table.add_entry(2, 5, 'linear') table.add_entry(5, 5) table.add_entry(10, 0, 'linear') entries = table.get_entries_instantiated({}) expected = [[ TableEntry(0, 5, HoldInterpolationStrategy()), TableEntry(5, 5, HoldInterpolationStrategy()), TableEntry(10, 0, LinearInterpolationStrategy()) ]] self.assertEqual(expected, entries) result_sampled = TableWaveform(entries).sample(numpy.linspace(0, 10, 11), 0) numbers = [5, 5, 5, 5, 5, 5, 4, 3, 2, 1, 0] expected = [[float(x) for x in numbers]] self.assertEqual(expected, result_sampled.tolist())
def test_get_entries_instantiated_removal_for_three_subsequent_equal_entries(self) -> None: table = TablePulseTemplate() table.add_entry(1, 5) table.add_entry(1.5, 5) table.add_entry(2, 5) table.add_entry(3, 0) entries = table.get_entries_instantiated({}) expected = [[ TableEntry(0, 0, HoldInterpolationStrategy()), TableEntry(1, 5, HoldInterpolationStrategy()), TableEntry(2, 5, HoldInterpolationStrategy()), TableEntry(3, 0, HoldInterpolationStrategy()) ]] self.assertEqual(expected, entries)
def test_crash(self) -> None: table = TablePulseTemplate(identifier='foo') table.add_entry('ta', 'va', interpolation='hold') table.add_entry('tb', 'vb', interpolation='linear') table.add_entry('tend', 0, interpolation='jump') external_parameters = ['ta', 'tb', 'tc', 'td', 'va', 'vb', 'tend'] first_mapping = { 'ta': 'ta', 'tb': 'tb', 'va': 'va', 'vb': 'vb', 'tend': 'tend' } second_mapping = { 'ta': 'tc', 'tb': 'td', 'va': 'vb', 'vb': 'va + vb', 'tend': '2 * tend' } sequence = SequencePulseTemplate([(table, first_mapping), (table, second_mapping)], external_parameters) parameters = { 'ta': ConstantParameter(2), 'va': ConstantParameter(2), 'tb': ConstantParameter(4), 'vb': ConstantParameter(3), 'tc': ConstantParameter(5), 'td': ConstantParameter(11), 'tend': ConstantParameter(6) } sequencer = DummySequencer() block = DummyInstructionBlock() self.assertFalse(sequence.requires_stop(parameters, {})) sequence.build_sequence(sequencer, parameters, {}, block) from qctoolkit.pulses.sequencing import Sequencer s = Sequencer() s.push(sequence, parameters) s.build()
# | | # | | # | | # a--------| ------------------d # # Point: Tuple # a: (0,0) # b: ('t_up', 'value1') # c: ('t_down', 'value2') # d: ('end', 0) # t_down should not be given by the user, instead give the time between c and b as 'length' squarePulse = TablePulseTemplate() # Prepare new empty Pulse # Then add pulses sequentially squarePulse.add_entry( 't_up', 'value1', interpolation='hold') # hold is the standard interpolation value squarePulse.add_entry('t_down', 'value2', interpolation='linear') squarePulse.add_entry('end', 0, interpolation='jump') # We can just plug in values for the parameters to get an actual pulse: parameters = { 't_up': 200, 't_down': 2000, 'end': 4000, 'value1': 2.2, 'value2': 3.0 } # with these parameters, we can plot the pulse: plot(squarePulse, parameters)
class SequencePulseTemplateSerializationTests(unittest.TestCase): def setUp(self) -> None: self.serializer = DummySerializer() self.table_foo = TablePulseTemplate(identifier='foo') self.table_foo.add_entry('hugo', 2) self.table_foo.add_entry(ParameterDeclaration('albert', max=9.1), 'voltage') self.table = TablePulseTemplate(measurement=True) self.foo_mappings = dict(hugo='ilse', albert='albert', voltage='voltage') def test_get_serialization_data(self) -> None: serializer = DummySerializer(serialize_callback=lambda x: str(x)) foo_mappings = {k: Expression(v) for k, v in self.foo_mappings.items()} sequence = SequencePulseTemplate([(self.table_foo, self.foo_mappings), (self.table, {})], ['ilse', 'albert', 'voltage'], identifier='foo') expected_data = dict( type=serializer.get_type_identifier(sequence), external_parameters=['albert', 'ilse', 'voltage'], is_interruptable=True, subtemplates=[ dict(template=str(self.table_foo), mappings={k: str(v) for k, v in foo_mappings.items()}), dict(template=str(self.table), mappings=dict()) ]) data = sequence.get_serialization_data(serializer) self.assertEqual(expected_data, data) def test_deserialize(self) -> None: foo_mappings = {k: Expression(v) for k, v in self.foo_mappings.items()} data = dict( external_parameters={'ilse', 'albert', 'voltage'}, is_interruptable=True, subtemplates=[ dict(template=str(id(self.table_foo)), mappings={k: str(id(v)) for k, v in foo_mappings.items()}), dict(template=str(id(self.table)), mappings=dict()) ], identifier='foo') # prepare dependencies for deserialization self.serializer.subelements[str(id(self.table_foo))] = self.table_foo self.serializer.subelements[str(id(self.table))] = self.table for v in foo_mappings.values(): self.serializer.subelements[str(id(v))] = v # deserialize sequence = SequencePulseTemplate.deserialize(self.serializer, **data) # compare! self.assertEqual(data['external_parameters'], sequence.parameter_names) self.assertEqual( { ParameterDeclaration('ilse'), ParameterDeclaration('albert'), ParameterDeclaration('voltage') }, sequence.parameter_declarations) self.assertIs(self.table_foo, sequence.subtemplates[0][0]) self.assertIs(self.table, sequence.subtemplates[1][0]) #self.assertEqual(self.foo_mappings, {k: m.string for k,m in sequence.subtemplates[0][1].items()}) self.assertEqual(foo_mappings, sequence.subtemplates[0][1]) self.assertEqual(dict(), sequence.subtemplates[1][1]) self.assertEqual(data['identifier'], sequence.identifier)