def test_map_parameters(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping={
                                      'foo': 't*k',
                                      'bar': 't*l'
                                  })

        parameters = {
            't': ConstantParameter(3),
            'k': ConstantParameter(2),
            'l': ConstantParameter(7)
        }
        values = {'foo': 6, 'bar': 21}
        for k, v in st.map_parameters(parameters).items():
            self.assertEqual(v.get_value(), values[k])
        parameters.popitem()
        with self.assertRaises(ParameterNotProvidedException):
            st.map_parameters(parameters)

        parameters = dict(t=3, k=2, l=7)
        values = {'foo': 6, 'bar': 21}
        for k, v in st.map_parameters(parameters).items():
            self.assertEqual(v, values[k])

        with self.assertRaisesRegex(ValueError, "type of return value"):
            st.map_parameters({})

        parameters = dict(t=3, k=2, l=ConstantParameter(7))
        with self.assertRaisesRegex(TypeError,
                                    "neither all Parameter nor Real"):
            st.map_parameters(parameters)
Exemple #2
0
    def test_as_expression(self):
        from sympy.abc import f, k, b
        duration = 5
        dummy = DummyPulseTemplate(defined_channels={'A', 'B', 'C'},
                                   parameter_names={'k', 'f', 'b'},
                                   integrals={
                                       'A': Expression(2 * k),
                                       'B': Expression(-3.2 * f + b),
                                       'C': Expression(1)
                                   },
                                   duration=duration)
        t = DummyPulseTemplate._AS_EXPRESSION_TIME
        dummy_expr = {
            ch: i * t / duration
            for ch, i in dummy._integrals.items()
        }
        pulse = MappingPulseTemplate(dummy,
                                     parameter_mapping={
                                         'k': 'f',
                                         'b': 2.3
                                     },
                                     channel_mapping={
                                         'A': 'a',
                                         'C': None
                                     },
                                     allow_partial_parameter_mapping=True)

        expected = {
            'a': Expression(2 * f * t / duration),
            'B': Expression((-3.2 * f + 2.3) * t / duration),
        }
        self.assertEqual(expected, pulse._as_expression())
Exemple #3
0
    def test_create_program_invalid_measurement_mapping(self) -> None:
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}
        channel_mapping = {'B': 'default'}

        template = DummyPulseTemplate(measurements=[('meas1', 0, 1)], measurement_names={'meas1'},
                                      defined_channels={'B'},
                                      waveform=DummyWaveform(duration=2.0),
                                      duration=2,
                                      parameter_names={'t'})
        st = MappingPulseTemplate(template, parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping, channel_mapping=channel_mapping)

        pre_scope = DictScope.from_kwargs(k=5)
        pre_measurement_mapping = {}
        pre_channel_mapping = {'default': 'A'}

        program = Loop()
        with self.assertRaises(KeyError):
            st._internal_create_program(scope=pre_scope,
                                        measurement_mapping=pre_measurement_mapping,
                                        channel_mapping=pre_channel_mapping,
                                        to_single_waveform=set(),
                                        global_transformation=None,
                                        parent_loop=program)
    def test_create_program_parameter_constraint_violation(self) -> None:
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}
        channel_mapping = {'B': 'default'}

        template = DummyPulseTemplate(measurements=[('meas1', 0, 1)],
                                      measurement_names={'meas1'},
                                      defined_channels={'B'},
                                      waveform=DummyWaveform(duration=2.0),
                                      duration=2,
                                      parameter_names={'t'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping,
                                  channel_mapping=channel_mapping,
                                  parameter_constraints={'k > 6'})

        pre_parameters = {'k': ConstantParameter(5)}
        pre_measurement_mapping = {'meas2': 'meas3'}
        pre_channel_mapping = {'default': 'A'}

        program = Loop()
        with self.assertRaises(ParameterConstraintViolation):
            st._internal_create_program(
                parameters=pre_parameters,
                measurement_mapping=pre_measurement_mapping,
                channel_mapping=pre_channel_mapping,
                to_single_waveform=set(),
                global_transformation=None,
                parent_loop=program)
Exemple #5
0
 def test_get_serialization_data(self) -> None:
     # test for deprecated version during transition period, remove after final switch
     with self.assertWarnsRegex(DeprecationWarning, "deprecated",
                                msg="SequencePT does not issue warning for old serialization routines."):
         dummy_pt = DummyPulseTemplate(defined_channels={'foo'},
                                       measurement_names={'meas'},
                                       parameter_names={'hugo', 'herbert', 'ilse'})
         mpt = MappingPulseTemplate(
             template=dummy_pt,
             parameter_mapping={'hugo': Expression('2*k+c'), 'herbert': Expression('c-1.5'), 'ilse': Expression('ilse')},
             measurement_mapping={'meas': 'seam'},
             channel_mapping={'foo': 'default_channel'},
             parameter_constraints=[str(ParameterConstraint('c > 0'))]
         )
         serializer = DummySerializer()
         expected_data = {
             'template': serializer.dictify(dummy_pt),
             'parameter_mapping': {'hugo': str(Expression('2*k+c')), 'herbert': str(Expression('c-1.5')),
                                   'ilse': str(Expression('ilse'))},
             'measurement_mapping': {'meas': 'seam'},
             'channel_mapping': {'foo': 'default_channel'},
             'parameter_constraints': [str(ParameterConstraint('c > 0'))]
         }
         data = mpt.get_serialization_data(serializer=serializer)
         self.assertEqual(expected_data, data)
    def test_nested_mapping_avoidance(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
        st_1 = MappingPulseTemplate(template,
                                    parameter_mapping={'foo': 't*k'},
                                    allow_partial_parameter_mapping=True)
        st_2 = MappingPulseTemplate(st_1,
                                    parameter_mapping={'bar': 't*l'},
                                    allow_partial_parameter_mapping=True)

        self.assertIs(st_2.template, template)
        self.assertEqual(st_2.parameter_mapping, {'foo': 't*k', 'bar': 't*l'})

        st_3 = MappingPulseTemplate(template,
                                    parameter_mapping={'foo': 't*k'},
                                    allow_partial_parameter_mapping=True,
                                    identifier='käse')
        st_4 = MappingPulseTemplate(st_3,
                                    parameter_mapping={'bar': 't*l'},
                                    allow_partial_parameter_mapping=True)
        self.assertIs(st_4.template, st_3)
        self.assertEqual(st_4.parameter_mapping, {
            't': 't',
            'k': 'k',
            'bar': 't*l'
        })
Exemple #7
0
 def test_get_updated_measurement_mapping(self):
     template = DummyPulseTemplate(measurement_names={'foo', 'bar'})
     st = MappingPulseTemplate(template, measurement_mapping={'bar': 'kneipe'})
     with self.assertRaises(KeyError):
         st.get_updated_measurement_mapping(dict())
     self.assertEqual(st.get_updated_measurement_mapping({'kneipe': 'meas1', 'foo': 'meas2', 'troet': 'meas3'}),
                      {'foo': 'meas2', 'bar': 'meas1'})
Exemple #8
0
    def test_plot_with_parameter_value_being_expression_string(self) -> None:
        """This is currently not supported but probably should be?"""
        sine_measurements = [('M', 't_duration/2', 't_duration')]
        sine = FunctionPulseTemplate('a*sin(omega*t)',
                                     't_duration',
                                     measurements=sine_measurements)
        sine_channel_mapping = dict(default='sin_channel')
        sine_measurement_mapping = dict(M='M_sin')
        remapped_sine = MappingPulseTemplate(
            sine,
            measurement_mapping=sine_measurement_mapping,
            channel_mapping=sine_channel_mapping)
        cos_measurements = [('M', 0, 't_duration/2')]
        cos = FunctionPulseTemplate('a*cos(omega*t)',
                                    't_duration',
                                    measurements=cos_measurements)
        cos_channel_mapping = dict(default='cos_channel')
        cos_measurement_mapping = dict(M='M_cos')
        remapped_cos = MappingPulseTemplate(
            cos,
            channel_mapping=cos_channel_mapping,
            measurement_mapping=cos_measurement_mapping)
        both = AtomicMultiChannelPulseTemplate(remapped_sine, remapped_cos)

        parameter_values = dict(omega=1.0, a=1.0, t_duration="2*pi")

        _ = plot(both, parameters=parameter_values, sample_rate=100)
Exemple #9
0
    def test_constrained(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
        st = MappingPulseTemplate(template, parameter_mapping={'foo': 't*k', 'bar': 't*l'}, parameter_constraints=['t < m'])
        external_params = {'t', 'l', 'k', 'm'}
        self.assertEqual(st.parameter_names, external_params)

        with self.assertRaises(ParameterConstraintViolation):
            st.map_parameters(dict(t=1, l=2, k=3, m=0))
Exemple #10
0
 def test_get_updated_channel_mapping(self):
     template = DummyPulseTemplate(defined_channels={'foo', 'bar', 'brotzeit'})
     st = MappingPulseTemplate(template, channel_mapping={'bar': 'kneipe', 'brotzeit': None})
     with self.assertRaises(KeyError):
         st.get_updated_channel_mapping(dict())
     self.assertEqual(st.get_updated_channel_mapping({'kneipe': 'meas1',
                                                      'foo': 'meas2',
                                                      'troet': 'meas3'}),
                      {'foo': 'meas2',
                       'bar': 'meas1',
                       'brotzeit': None})
    def test_init_exceptions(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'},
                                      defined_channels={'A'},
                                      measurement_names={'B'})
        parameter_mapping = {'foo': 't*k', 'bar': 't*l'}

        with self.assertRaises(MissingMappingException):
            MappingPulseTemplate(template,
                                 parameter_mapping={},
                                 allow_partial_parameter_mapping=False)
        with self.assertRaises(MissingMappingException):
            MappingPulseTemplate(template,
                                 parameter_mapping={'bar': 'kneipe'},
                                 allow_partial_parameter_mapping=False)
        with self.assertRaises(UnnecessaryMappingException):
            MappingPulseTemplate(template,
                                 parameter_mapping=dict(**parameter_mapping,
                                                        foobar='asd'))

        with self.assertRaises(UnnecessaryMappingException):
            MappingPulseTemplate(template,
                                 parameter_mapping=parameter_mapping,
                                 measurement_mapping=dict(a='b'))
        with self.assertRaises(UnnecessaryMappingException):
            MappingPulseTemplate(template,
                                 parameter_mapping=parameter_mapping,
                                 channel_mapping=dict(a='b'))

        with self.assertRaises(TypeError):
            MappingPulseTemplate(template, parameter_mapping)

        MappingPulseTemplate(template, parameter_mapping={'bar': 'kneipe'})
        MappingPulseTemplate(template, parameter_mapping=parameter_mapping)
Exemple #12
0
        def test_mapping_permutations(template: DummyPulseTemplate,
                         pmap, mmap, cmap):
            direct = MappingPulseTemplate(template,
                                          parameter_mapping=pmap,
                                          measurement_mapping=mmap,
                                          channel_mapping=cmap)

            mappings = [m for m in [pmap, mmap, cmap] if m is not None]

            for current_mapping_order in itertools.permutations(mappings):
                mapper = MappingPulseTemplate.from_tuple((template, *current_mapping_order))
                self.assertEqual(mapper.measurement_mapping, direct.measurement_mapping)
                self.assertEqual(mapper.channel_mapping, direct.channel_mapping)
                self.assertEqual(mapper.parameter_mapping, direct.parameter_mapping)
Exemple #13
0
    def __init__(self,
                 *subtemplates: Union[AtomicPulseTemplate, MappingTuple, MappingPulseTemplate],
                 identifier: Optional[str] = None,
                 parameter_constraints: Optional[List] = None,
                 measurements: Optional[List[MeasurementDeclaration]] = None,
                 registry: PulseRegistryType = None,
                 duration: Optional[ExpressionLike] = None) -> None:
        """Parallels multiple AtomicPulseTemplates of the same duration. If the duration keyword argument is given
        it is enforced that the instantiated pulse template has this duration. If duration is None the duration of the
        PT is the duration of the first subtemplate. There are probably changes to this behaviour in the future.

        Args:
            *subtemplates: Positional arguments are subtemplates to combine.
            identifier: Forwarded to AtomicPulseTemplate.__init__
            parameter_constraints: Forwarded to ParameterConstrainer.__init__
            measurements: Forwarded to AtomicPulseTemplate.__init__
            duration: Enforced duration of the pulse template on instantiation. build_waveform checks all sub-waveforms
            have this duration. If True the equality of durations is only checked durtin instantiation not construction.
        """
        AtomicPulseTemplate.__init__(self, identifier=identifier, measurements=measurements)
        ParameterConstrainer.__init__(self, parameter_constraints=parameter_constraints)

        self._subtemplates = [st if isinstance(st, PulseTemplate) else MappingPulseTemplate.from_tuple(st) for st in
                              subtemplates]

        if duration in (True, False):
            warnings.warn("Boolean duration is deprecated since qupulse 0.6 and interpreted as None",
                          category=DeprecationWarning, stacklevel=2)
            duration = None

        for subtemplate in self._subtemplates:
            if isinstance(subtemplate, AtomicPulseTemplate):
                continue
            elif isinstance(subtemplate, MappingPulseTemplate):
                if isinstance(subtemplate.template, AtomicPulseTemplate):
                    continue
                else:
                    raise TypeError('Non atomic subtemplate of MappingPulseTemplate: {}'.format(subtemplate.template))
            else:
                raise TypeError('Non atomic subtemplate: {}'.format(subtemplate))

        if not self._subtemplates:
            raise ValueError('Cannot create empty MultiChannelPulseTemplate')

        defined_channels = [st.defined_channels for st in self._subtemplates]

        # check there are no intersections between channels
        for i, channels_i in enumerate(defined_channels):
            for j, channels_j in enumerate(defined_channels[i + 1:]):
                if channels_i & channels_j:
                    raise ChannelMappingException('subtemplate {}'.format(i + 1),
                                                  'subtemplate {}'.format(i + 2 + j),
                                                  (channels_i & channels_j).pop())

        if duration is None:
            self._duration = None
        else:
            self._duration = ExpressionScalar(duration)

        self._register(registry=registry)
Exemple #14
0
 def test_drop_channel(self):
     dummy = DummyPulseTemplate(defined_channels={'A', 'B', 'C', 'D'},
                                parameter_names={'k', 'f', 'b'})
     pulse = MappingPulseTemplate(dummy, parameter_mapping={'k': 'f', 'b': 2.3}, channel_mapping={'A': 'a',
                                                                                                  'C': None,
                                                                                                  'D': None})
     self.assertEqual({'a', 'B'}, pulse.defined_channels)
Exemple #15
0
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)

        # Setup test data
        self.square = TablePulseTemplate(
            {
                'default': [(0, 0), ('up', 'v', 'hold'), ('down', 0, 'hold'),
                            ('length', 0)]
            },
            measurements=[('mw1', 'up', 'length-up')])
        self.mapping1 = {
            'up': 'uptime',
            'down': 'uptime + length',
            'v': 'voltage',
            'length': '0.5 * pulse_length'
        }

        self.window_name_mapping = {'mw1': 'test_window'}

        self.outer_parameters = {'uptime', 'length', 'pulse_length', 'voltage'}

        self.parameters = dict()
        self.parameters['uptime'] = ConstantParameter(5)
        self.parameters['length'] = ConstantParameter(10)
        self.parameters['pulse_length'] = ConstantParameter(100)
        self.parameters['voltage'] = ConstantParameter(10)

        self.sequence = SequencePulseTemplate(
            MappingPulseTemplate(self.square,
                                 parameter_mapping=self.mapping1,
                                 measurement_mapping=self.window_name_mapping))
    def test_same_channel_error(self):

        dpt = DummyPulseTemplate(defined_channels={'A', 'B'})

        with self.assertRaisesRegex(ValueError,
                                    'multiple channels to the same target'):
            MappingPulseTemplate(dpt, channel_mapping={'A': 'X', 'B': 'X'})
    def test_partial_parameter_mapping(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping={'foo': 't*k'},
                                  allow_partial_parameter_mapping=True)

        self.assertEqual(st.parameter_mapping, {'foo': 't*k', 'bar': 'bar'})
 def test_measurement_names(self):
     template = DummyPulseTemplate(measurement_names={'foo', 'bar'})
     st = MappingPulseTemplate(template,
                               measurement_mapping={
                                   'foo': 'froop',
                                   'bar': 'kneipe'
                               })
     self.assertEqual(st.measurement_names, {'froop', 'kneipe'})
 def test_parameter_names(self) -> None:
     template = DummyPulseTemplate(parameter_names={'foo'},
                                   measurement_names={'meas1'})
     mt = MappingPulseTemplate(template,
                               parameter_mapping={'foo': 't*k'},
                               parameter_constraints={'t >= m'},
                               measurement_mapping={'meas1': 'meas2'})
     self.assertEqual({'t', 'k', 'm'}, mt.parameter_names)
Exemple #20
0
    def test_duration(self):
        seconds2ns = 1e9
        pulse_duration = 1.0765001496284785e-07

        dpt = DummyPulseTemplate(duration=Expression('duration'), parameter_names={'duration'},
                                   defined_channels={'A'})
        mpt = MappingPulseTemplate(dpt, parameter_mapping={'duration': seconds2ns * pulse_duration})
        self.assertEqual(seconds2ns * pulse_duration, mpt.duration)
    def test_build_sequence(self):
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}

        template = DummyPulseTemplate(
            measurement_names=set(measurement_mapping.keys()),
            parameter_names=set(parameter_mapping.keys()))
        st = MappingPulseTemplate(template,
                                  parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping)
        sequencer = DummySequencer()
        block = DummyInstructionBlock()
        pre_parameters = {'k': ConstantParameter(5)}
        pre_measurement_mapping = {'meas2': 'meas3'}
        pre_channel_mapping = {'default': 'A'}
        conditions = dict(a=True)
        st.build_sequence(sequencer, pre_parameters, conditions,
                          pre_measurement_mapping, pre_channel_mapping, block)

        self.assertEqual(template.build_sequence_calls, 1)
        forwarded_args = template.build_sequence_arguments[0]
        self.assertEqual(forwarded_args[0], sequencer)
        self.assertEqual(forwarded_args[1], st.map_parameters(pre_parameters))
        self.assertEqual(forwarded_args[2], conditions)
        self.assertEqual(
            forwarded_args[3],
            st.get_updated_measurement_mapping(pre_measurement_mapping))
        self.assertEqual(forwarded_args[4],
                         st.get_updated_channel_mapping(pre_channel_mapping))
        self.assertEqual(forwarded_args[5], block)
 def test_external_params(self):
     template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
     st = MappingPulseTemplate(template,
                               parameter_mapping={
                                   'foo': 't*k',
                                   'bar': 't*l'
                               })
     external_params = {'t', 'l', 'k'}
     self.assertEqual(st.parameter_names, external_params)
Exemple #23
0
    def test_integral(self) -> None:
        dummy = DummyPulseTemplate(defined_channels={'A', 'B', 'C'},
                                   parameter_names={'k', 'f', 'b'},
                                   integrals={'A': Expression('2*k'),
                                              'B': Expression('-3.2*f+b'),
                                              'C': Expression(1)})
        pulse = MappingPulseTemplate(dummy, parameter_mapping={'k': 'f', 'b': 2.3}, channel_mapping={'A': 'a',
                                                                                                     'C': None},
                                     allow_partial_parameter_mapping=True)

        self.assertEqual({'a': Expression('2*f'), 'B': Expression('-3.2*f+2.3')}, pulse.integral)
Exemple #24
0
    def __init__(self,
                 *subtemplates: Union[PulseTemplate, MappingTuple],
                 external_parameters: Optional[Union[Iterable[str],
                                                     Set[str]]] = None,
                 identifier: Optional[str] = None,
                 parameter_constraints: Optional[List[Union[
                     str, Expression]]] = None,
                 measurements: Optional[List[MeasurementDeclaration]] = None,
                 registry: PulseRegistryType = None) -> None:
        """Create a new SequencePulseTemplate instance.

        Requires a (correctly ordered) list of subtemplates in the form
        (PulseTemplate, Dict(str -> str)) where the dictionary is a mapping between the external
        parameters exposed by this SequencePulseTemplate to the parameters declared by the
        subtemplates, specifying how the latter are derived from the former, i.e., the mapping is
        subtemplate_parameter_name -> mapping_expression (as str) where the free variables in the
        mapping_expression are parameters declared by this SequencePulseTemplate.

        The following requirements must be satisfied:
            - for each parameter declared by a subtemplate, a mapping expression must be provided
            - each free variable in a mapping expression must be declared as an external parameter
                of this SequencePulseTemplate

        Args:
            subtemplates (List(Subtemplate)): The list of subtemplates of this
                SequencePulseTemplate as tuples of the form (PulseTemplate, Dict(str -> str)).
            external_parameters (List(str)): A set of names for external parameters of this
                SequencePulseTemplate. Deprecated.
            identifier (str): A unique identifier for use in serialization. (optional)
        """
        PulseTemplate.__init__(self, identifier=identifier)
        ParameterConstrainer.__init__(
            self, parameter_constraints=parameter_constraints)
        MeasurementDefiner.__init__(self, measurements=measurements)

        self.__subtemplates = [
            MappingPulseTemplate.from_tuple(st)
            if isinstance(st, tuple) else st for st in subtemplates
        ]

        # check that all subtemplates live on the same channels
        defined_channels = self.__subtemplates[0].defined_channels
        for subtemplate in self.__subtemplates[1:]:
            if subtemplate.defined_channels != defined_channels:
                raise ValueError(
                    'The subtemplates are defined for different channels')

        if external_parameters:
            warnings.warn(
                "external_parameters is an obsolete argument and will be removed in the future.",
                category=DeprecationWarning)

        self._register(registry=registry)
    def test_create_program_subtemplate_none(self) -> None:
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}
        channel_mapping = {'B': 'default'}

        template = DummyPulseTemplate(measurements=[('meas1', 0, 1)],
                                      measurement_names={'meas1'},
                                      defined_channels={'B'},
                                      waveform=None,
                                      duration=0,
                                      parameter_names={'t'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping,
                                  channel_mapping=channel_mapping)

        pre_parameters = {'k': ConstantParameter(5)}
        pre_measurement_mapping = {'meas2': 'meas3'}
        pre_channel_mapping = {'default': 'A'}

        program = Loop()
        st._internal_create_program(
            parameters=pre_parameters,
            measurement_mapping=pre_measurement_mapping,
            channel_mapping=pre_channel_mapping,
            to_single_waveform=set(),
            global_transformation=None,
            parent_loop=program)

        self.assertEqual(1, len(template.create_program_calls))
        self.assertEqual(
            (st.map_parameters(pre_parameters),
             st.get_updated_measurement_mapping(pre_measurement_mapping),
             st.get_updated_channel_mapping(pre_channel_mapping), program),
            template.create_program_calls[-1])

        self.assertEqual(1, program.repetition_count)
        self.assertEqual(0, len(program.children))
        self.assertIsNone(program._measurements)

        # ensure same result as from Sequencer
        sequencer = Sequencer()
        sequencer.push(st,
                       parameters=pre_parameters,
                       conditions={},
                       window_mapping=pre_measurement_mapping,
                       channel_mapping=pre_channel_mapping)
        block = sequencer.build()
        program_old = MultiChannelProgram(
            block, channels={'A'}).programs[frozenset({'A'})]
        self.assertEqual(program_old, program)
    def test_create_program(self) -> None:
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}
        channel_mapping = {'B': 'default'}
        global_transformation = TransformationStub()
        to_single_waveform = {'tom', 'jerry'}

        template = DummyPulseTemplate(measurements=[('meas1', 0, 1)],
                                      measurement_names={'meas1'},
                                      defined_channels={'B'},
                                      waveform=DummyWaveform(duration=2.0),
                                      duration=2,
                                      parameter_names={'t'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping,
                                  channel_mapping=channel_mapping)

        pre_parameters = {'k': ConstantParameter(5)}
        pre_measurement_mapping = {'meas2': 'meas3'}
        pre_channel_mapping = {'default': 'A'}

        program = Loop()
        expected_inner_args = dict(
            parameters=st.map_parameters(pre_parameters),
            measurement_mapping=st.get_updated_measurement_mapping(
                pre_measurement_mapping),
            channel_mapping=st.get_updated_channel_mapping(
                pre_channel_mapping),
            to_single_waveform=to_single_waveform,
            global_transformation=global_transformation,
            parent_loop=program)

        with mock.patch.object(template,
                               '_create_program') as inner_create_program:
            st._internal_create_program(
                parameters=pre_parameters,
                measurement_mapping=pre_measurement_mapping,
                channel_mapping=pre_channel_mapping,
                to_single_waveform=to_single_waveform,
                global_transformation=global_transformation,
                parent_loop=program)
            inner_create_program.assert_called_once_with(**expected_inner_args)

        # as we mock the inner function there shouldnt be any changes
        self.assertEqual(program, Loop())
    def test_deserialize(self) -> None:
        # test for deprecated version during transition period, remove after final switch
        with self.assertWarnsRegex(
                DeprecationWarning,
                "deprecated",
                msg=
                "SequencePT does not issue warning for old serialization routines."
        ):
            dummy_pt = DummyPulseTemplate(
                defined_channels={'foo'},
                measurement_names={'meas'},
                parameter_names={'hugo', 'herbert', 'ilse'})
            serializer = DummySerializer()
            data = {
                'template': serializer.dictify(dummy_pt),
                'parameter_mapping': {
                    'hugo': str(Expression('2*k+c')),
                    'herbert': str(Expression('c-1.5')),
                    'ilse': str(Expression('ilse'))
                },
                'measurement_mapping': {
                    'meas': 'seam'
                },
                'channel_mapping': {
                    'foo': 'default_channel'
                },
                'parameter_constraints': [str(ParameterConstraint('c > 0'))]
            }
            deserialized = MappingPulseTemplate.deserialize(
                serializer=serializer, **data)

            self.assertIsInstance(deserialized, MappingPulseTemplate)
            self.assertEqual(data['parameter_mapping'],
                             deserialized.parameter_mapping)
            self.assertEqual(data['channel_mapping'],
                             deserialized.channel_mapping)
            self.assertEqual(data['measurement_mapping'],
                             deserialized.measurement_mapping)
            self.assertEqual(
                data['parameter_constraints'],
                [str(pc) for pc in deserialized.parameter_constraints])
            self.assertIs(deserialized.template, dummy_pt)
Exemple #28
0
    def test_create_program_subtemplate_none(self) -> None:
        measurement_mapping = {'meas1': 'meas2'}
        parameter_mapping = {'t': 'k'}
        channel_mapping = {'B': 'default'}
        volatile = {'t'}

        template = DummyPulseTemplate(measurements=[('meas1', 0, 1)],
                                      measurement_names={'meas1'},
                                      defined_channels={'B'},
                                      waveform=None,
                                      duration=0,
                                      parameter_names={'t'})
        st = MappingPulseTemplate(template,
                                  parameter_mapping=parameter_mapping,
                                  measurement_mapping=measurement_mapping,
                                  channel_mapping=channel_mapping)

        pre_scope = DictScope.from_kwargs(k=5, volatile=volatile)
        pre_measurement_mapping = {'meas2': 'meas3'}
        pre_channel_mapping = {'default': 'A'}

        program = Loop()
        st._internal_create_program(
            scope=pre_scope,
            measurement_mapping=pre_measurement_mapping,
            channel_mapping=pre_channel_mapping,
            to_single_waveform=set(),
            global_transformation=None,
            parent_loop=program)

        self.assertEqual(1, len(template.create_program_calls))
        self.assertEqual(
            (st.map_scope(pre_scope),
             st.get_updated_measurement_mapping(pre_measurement_mapping),
             st.get_updated_channel_mapping(pre_channel_mapping), program),
            template.create_program_calls[-1])

        self.assertEqual(1, program.repetition_count)
        self.assertEqual(0, len(program.children))
        self.assertIsNone(program._measurements)
    def __init__(self,
                 *subtemplates: Union[AtomicPulseTemplate, MappingTuple,
                                      MappingPulseTemplate],
                 external_parameters: Optional[Set[str]] = None,
                 identifier: Optional[str] = None,
                 parameter_constraints: Optional[List] = None,
                 measurements: Optional[List[MeasurementDeclaration]] = None,
                 registry: PulseRegistryType = None,
                 duration: Union[str, Expression, bool] = False) -> None:
        """Parallels multiple AtomicPulseTemplates of the same duration. The duration equality check is performed on
        construction by default. If the duration keyword argument is given the check is performed on instantiation
        (when build_waveform is called). duration can be a Expression to enforce a certain duration or True for an
        unspecified duration.

        Args:
            *subtemplates: Positional arguments are subtemplates to combine.
            identifier: Forwarded to AtomicPulseTemplate.__init__
            parameter_constraints: Forwarded to ParameterConstrainer.__init__
            measurements: Forwarded to AtomicPulseTemplate.__init__
            duration: Enforced duration of the pulse template on instantiation. build_waveform checks all sub-waveforms
            have this duration. If True the equality of durations is only checked durtin instantiation not construction.
            external_parameters: No functionality. (Deprecated)
        """
        AtomicPulseTemplate.__init__(self,
                                     identifier=identifier,
                                     measurements=measurements)
        ParameterConstrainer.__init__(
            self, parameter_constraints=parameter_constraints)

        self._subtemplates = [
            st if isinstance(st, PulseTemplate) else
            MappingPulseTemplate.from_tuple(st) for st in subtemplates
        ]

        for subtemplate in self._subtemplates:
            if isinstance(subtemplate, AtomicPulseTemplate):
                continue
            elif isinstance(subtemplate, MappingPulseTemplate):
                if isinstance(subtemplate.template, AtomicPulseTemplate):
                    continue
                else:
                    raise TypeError(
                        'Non atomic subtemplate of MappingPulseTemplate: {}'.
                        format(subtemplate.template))
            else:
                raise TypeError(
                    'Non atomic subtemplate: {}'.format(subtemplate))

        if not self._subtemplates:
            raise ValueError('Cannot create empty MultiChannelPulseTemplate')

        defined_channels = [st.defined_channels for st in self._subtemplates]

        # check there are no intersections between channels
        for i, channels_i in enumerate(defined_channels):
            for j, channels_j in enumerate(defined_channels[i + 1:]):
                if channels_i & channels_j:
                    raise ChannelMappingException(
                        'subtemplate {}'.format(i + 1),
                        'subtemplate {}'.format(i + 2 + j),
                        (channels_i | channels_j).pop())

        if external_parameters is not None:
            warnings.warn(
                "external_parameters is an obsolete argument and will be removed in the future.",
                category=DeprecationWarning)

        if not duration:
            duration = self._subtemplates[0].duration
            for subtemplate in self._subtemplates[1:]:
                if almost_equal(duration.sympified_expression,
                                subtemplate.duration.sympified_expression):
                    continue
                else:
                    raise ValueError(
                        'Could not assert duration equality of {} and {}'.
                        format(duration, subtemplate.duration))
            self._duration = None
        elif duration is True:
            self._duration = None
        else:
            self._duration = ExpressionScalar(duration)

        self._register(registry=registry)
    def test_from_tuple_exceptions(self):
        template = DummyPulseTemplate(parameter_names={'foo', 'bar'},
                                      measurement_names={'foo', 'foobar'},
                                      defined_channels={'bar', 'foobar'})

        with self.assertRaises(ValueError):
            MappingPulseTemplate.from_tuple((template, {'A': 'B'}))
        with self.assertRaises(AmbiguousMappingException):
            MappingPulseTemplate.from_tuple((template, {'foo': 'foo'}))
        with self.assertRaises(AmbiguousMappingException):
            MappingPulseTemplate.from_tuple((template, {'bar': 'bar'}))
        with self.assertRaises(AmbiguousMappingException):
            MappingPulseTemplate.from_tuple((template, {'foobar': 'foobar'}))

        template = DummyPulseTemplate(parameter_names={'foo', 'bar'})
        with self.assertRaises(MappingCollisionException):
            MappingPulseTemplate.from_tuple((template, {
                'foo': '1',
                'bar': 2
            }, {
                'foo': '1',
                'bar': 4
            }))

        template = DummyPulseTemplate(defined_channels={'A'})
        with self.assertRaises(MappingCollisionException):
            MappingPulseTemplate.from_tuple((template, {'A': 'N'}, {'A': 'C'}))

        template = DummyPulseTemplate(measurement_names={'M'})
        with self.assertRaises(MappingCollisionException):
            MappingPulseTemplate.from_tuple((template, {'M': 'N'}, {'M': 'N'}))