Ejemplo n.º 1
0
    def _internal_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) -> None:
        """Parameter constraints are validated in build_waveform because build_waveform is guaranteed to be called
        during sequencing"""
        ### current behavior (same as previously): only adds EXEC Loop and measurements if a waveform exists.
        ### measurements are directly added to parent_loop (to reflect behavior of Sequencer + MultiChannelProgram)
        assert not scope.get_volatile_parameters().keys(
        ) & self.parameter_names, "AtomicPT cannot be volatile"

        waveform = self.build_waveform(parameters=scope,
                                       channel_mapping=channel_mapping)
        if waveform:
            measurements = self.get_measurement_windows(
                parameters=scope, measurement_mapping=measurement_mapping)

            if global_transformation:
                waveform = TransformingWaveform(waveform,
                                                global_transformation)

            parent_loop.add_measurements(measurements=measurements)
            parent_loop.append_child(waveform=waveform)
Ejemplo n.º 2
0
    def _internal_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) -> None:
        """Parameter constraints are validated in build_waveform because build_waveform is guaranteed to be called
        during sequencing"""
        ### current behavior (same as previously): only adds EXEC Loop and measurements if a waveform exists.
        ### measurements are directly added to parent_loop (to reflect behavior of Sequencer + MultiChannelProgram)
        # todo (2018-08-08): could move measurements into own Loop object?

        # todo (2018-07-05): why are parameter constraints not validated here?
        try:
            parameters = {parameter_name: parameters[parameter_name].get_value()
                          for parameter_name in self.parameter_names}
        except KeyError as e:
            raise ParameterNotProvidedException(str(e)) from e

        waveform = self.build_waveform(parameters=parameters,
                                       channel_mapping=channel_mapping)
        if waveform:
            measurements = self.get_measurement_windows(parameters=parameters,
                                                        measurement_mapping=measurement_mapping)

            if global_transformation:
                waveform = TransformingWaveform(waveform, global_transformation)

            parent_loop.add_measurements(measurements=measurements)
            parent_loop.append_child(waveform=waveform)
Ejemplo n.º 3
0
    def _internal_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) -> None:
        self.validate_parameter_constraints(parameters=parameters)
        relevant_params = set(self._repetition_count.variables).union(self.measurement_parameters)
        try:
            real_parameters = {v: parameters[v].get_value() for v in relevant_params}
        except KeyError as e:
            raise ParameterNotProvidedException(str(e)) from e

        repetition_count = max(0, self.get_repetition_count_value(real_parameters))

        # todo (2018-07-19): could in some circumstances possibly just multiply subprogram repetition count?
        # could be tricky if any repetition count is volatile ? check later and optimize if necessary
        if repetition_count > 0:
            repj_loop = Loop(repetition_count=repetition_count)
            self.body._create_program(parameters=parameters,
                                      measurement_mapping=measurement_mapping,
                                      channel_mapping=channel_mapping,
                                      global_transformation=global_transformation,
                                      to_single_waveform=to_single_waveform,
                                      parent_loop=repj_loop)
            if repj_loop.waveform is not None or len(repj_loop.children) > 0:
                measurements = self.get_measurement_windows(real_parameters, measurement_mapping)
                if measurements:
                    parent_loop.add_measurements(measurements)

                parent_loop.append_child(loop=repj_loop)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 def _internal_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) -> None:
     measurements = self.get_measurement_windows(parameters, measurement_mapping)
     self.create_program_calls.append((parameters, measurement_mapping, channel_mapping, parent_loop))
     if self._program:
         parent_loop.add_measurements(measurements)
         parent_loop.append_child(waveform=self._program.waveform, children=self._program.children)
     elif self.waveform:
         parent_loop.add_measurements(measurements)
         parent_loop.append_child(waveform=self.waveform)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    def _internal_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) -> None:
        self.validate_scope(scope)

        repetition_count = max(0, self.get_repetition_count_value(scope))

        # todo (2018-07-19): could in some circumstances possibly just multiply subprogram repetition count?
        # could be tricky if any repetition count is volatile ? check later and optimize if necessary
        if repetition_count > 0:
            if scope.get_volatile_parameters().keys(
            ) & self.repetition_count.variables:
                repetition_definition = VolatileRepetitionCount(
                    self.repetition_count, scope)
                assert int(repetition_definition) == repetition_count
            else:
                repetition_definition = repetition_count

            repj_loop = Loop(repetition_count=repetition_definition)
            self.body._create_program(
                scope=scope,
                measurement_mapping=measurement_mapping,
                channel_mapping=channel_mapping,
                global_transformation=global_transformation,
                to_single_waveform=to_single_waveform,
                parent_loop=repj_loop)
            if repj_loop.waveform is not None or len(repj_loop.children) > 0:
                measurements = self.get_measurement_windows(
                    scope, measurement_mapping)
                if measurements:
                    parent_loop.add_measurements(measurements)

                parent_loop.append_child(loop=repj_loop)
Ejemplo n.º 8
0
def complex_program_as_loop(unique_wfs, wf_same):
    root = Loop(repetition_count=12)

    for wf_unique in unique_wfs:
        root.append_child(children=[
            Loop(repetition_count=42, waveform=wf_unique),
            Loop(repetition_count=98, waveform=wf_same)
        ],
                          repetition_count=10)

    root.append_child(waveform=unique_wfs[0], repetition_count=21)
    root.append_child(waveform=wf_same, repetition_count=23)

    volatile_repetition = VolatileRepetitionCount(
        ExpressionScalar('n + 4'), DictScope.from_kwargs(n=3, volatile={'n'}))
    root.append_child(waveform=wf_same, repetition_count=volatile_repetition)

    return root
Ejemplo n.º 9
0
def complex_program_as_loop(unique_wfs, wf_same):
    root = Loop(repetition_count=12)

    for wf_unique in unique_wfs:
        root.append_child(children=[
            Loop(repetition_count=42, waveform=wf_unique),
            Loop(repetition_count=98, waveform=wf_same)
        ],
                          repetition_count=10)

    root.append_child(waveform=unique_wfs[0], repetition_count=21)
    root.append_child(waveform=wf_same, repetition_count=23)

    return root
Ejemplo n.º 10
0
 def internal_create_program(*, scope, parent_loop: Loop, **_):
     if always_append or 'append_a_child' in scope:
         if measurements is not None:
             parent_loop.add_measurements(measurements=measurements)
         parent_loop.append_child(waveform=waveform)