From f93e02ff97df3893bf1c34bba2c65a2d246e87ae Mon Sep 17 00:00:00 2001 From: Selene Lab Date: Thu, 19 Dec 2024 14:12:04 +0100 Subject: [PATCH] simon's reversed loopbuilder --- qupulse/program/__init__.py | 3 +++ qupulse/program/loop.py | 11 ++++++++++- qupulse/program/waveforms.py | 2 +- qupulse/pulses/time_reversal_pulse_template.py | 16 ++++------------ 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/qupulse/program/__init__.py b/qupulse/program/__init__.py index 46df1bef..6f0064cb 100644 --- a/qupulse/program/__init__.py +++ b/qupulse/program/__init__.py @@ -74,6 +74,9 @@ def with_iteration(self, index_name: str, rng: range, def evaluate_nested_stepping(self, scope: Scope, parameter_names: set[str]) -> bool: return False + def time_reversed(self) -> ContextManager['ProgramBuilder']: + pass + def to_program(self, defined_channels: Set[ChannelID]) -> Optional[Program]: """Further addition of new elements might fail after finalizing the program.""" diff --git a/qupulse/program/loop.py b/qupulse/program/loop.py index 5dc9261f..5ef8124c 100644 --- a/qupulse/program/loop.py +++ b/qupulse/program/loop.py @@ -817,7 +817,16 @@ def with_iteration(self, index_name: str, rng: range, for value in rng: top_frame.iterating = (index_name, value) yield self - + + @contextmanager + def time_reversed(self) -> ContextManager['LoopBuilder']: + inner_builder = LoopBuilder() + yield inner_builder + inner_program = inner_builder.to_program() + if inner_program: + inner_program.reverse_inplace() + self._try_append(inner_program, None) + @contextmanager def with_sequence(self, measurements: Optional[Sequence[MeasurementWindow]] = None) -> ContextManager['ProgramBuilder']: top_frame = StackFrame(LoopGuard(self._top, measurements), None) diff --git a/qupulse/program/waveforms.py b/qupulse/program/waveforms.py index 01b4cfc6..a99b3b91 100644 --- a/qupulse/program/waveforms.py +++ b/qupulse/program/waveforms.py @@ -1270,7 +1270,7 @@ def unsafe_sample(self, channel: ChannelID, sample_times: np.ndarray, else: inner_output_array = output_array[::-1] inner_output_array = self._inner.unsafe_sample(channel, inner_sample_times, output_array=inner_output_array) - if inner_output_array.base not in (output_array, output_array.base): + if id(inner_output_array.base) not in (id(output_array), id(output_array.base)): # TODO: is there a guarantee by numpy we never end up here? output_array[:] = inner_output_array[::-1] return output_array diff --git a/qupulse/pulses/time_reversal_pulse_template.py b/qupulse/pulses/time_reversal_pulse_template.py index 8fcb4f88..e753e568 100644 --- a/qupulse/pulses/time_reversal_pulse_template.py +++ b/qupulse/pulses/time_reversal_pulse_template.py @@ -88,7 +88,6 @@ class TimeReversalPulseTemplate(PulseTemplate): def __init__(self, inner: PulseTemplate, identifier: Optional[str] = None, registry: PulseRegistryType = None): - raise NotImplementedError("Not yet adapted to ProgramBuilder formalism") super(TimeReversalPulseTemplate, self).__init__(identifier=identifier) self._inner = inner self._register(registry=registry) @@ -120,17 +119,10 @@ def defined_channels(self) -> Set['ChannelID']: def integral(self) -> Dict[ChannelID, ExpressionScalar]: return self._inner.integral - def _internal_create_program(self, *, parent_loop: Loop, **kwargs) -> None: - - raise NotImplementedError("Not yet adapted to ProgramBuilder formalism") - - # inner_loop = Loop() - # self._inner._internal_create_program(parent_loop=inner_loop, **kwargs) - # inner_loop.reverse_inplace() - - # parent_loop.append_child(inner_loop) - - + def _internal_create_program(self, *, program_builder: ProgramBuilder, **kwargs) -> None: + with program_builder.time_reversed() as reversed_builder: + self._inner._internal_create_program(program_builder=reversed_builder, **kwargs) + def build_waveform(self, *args, **kwargs) -> Optional[Waveform]: wf = self._inner.build_waveform(*args, **kwargs)