Skip to content

Commit b1c55b4

Browse files
committed
pad all atomic subtemplates
1 parent feafac0 commit b1c55b4

8 files changed

+92
-27
lines changed

qupulse/pulses/arithmetic_pulse_template.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import sympy
88

9-
from qupulse.expressions import ExpressionScalar, ExpressionLike
9+
from qupulse.expressions import ExpressionScalar, ExpressionLike, Expression
1010
from qupulse.serialization import Serializer, PulseRegistryType
1111
from qupulse.parameter_scope import Scope
1212

@@ -538,7 +538,12 @@ def get_measurement_windows(self,
538538

539539
def _is_atomic(self):
540540
return self._pulse_template._is_atomic()
541-
541+
542+
def pad_all_atomic_subtemplates_to(self,
543+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
544+
545+
self._pulse_template = self._pulse_template.pad_all_atomic_subtemplates_to(to_new_duration)
546+
542547

543548
def try_operation(lhs: Union[PulseTemplate, ExpressionLike, Mapping[ChannelID, ExpressionLike]],
544549
op: str,

qupulse/pulses/loop_pulse_template.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import functools
55
import itertools
66
from abc import ABC
7-
from typing import Dict, Set, Optional, Any, Union, Tuple, Iterator, Sequence, cast, Mapping
7+
from typing import Dict, Set, Optional, Any, Union, Tuple, Iterator, Sequence, cast, Mapping, Callable
88
import warnings
99
from numbers import Number
1010

@@ -16,7 +16,7 @@
1616

1717
from qupulse.program import ProgramBuilder
1818

19-
from qupulse.expressions import ExpressionScalar, ExpressionVariableMissingException, Expression
19+
from qupulse.expressions import ExpressionScalar, ExpressionVariableMissingException, Expression, ExpressionLike
2020
from qupulse.utils import checked_int_cast, cached_property
2121
from qupulse.pulses.parameters import InvalidParameterNameException, ParameterConstrainer, ParameterNotProvidedException
2222
from qupulse.pulses.pulse_template import PulseTemplate, ChannelID, AtomicPulseTemplate
@@ -241,7 +241,13 @@ def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
241241
for ch, value in values.items():
242242
values[ch] = ExpressionScalar(value.underlying_expression.subs(self._loop_index, final_idx))
243243
return values
244-
244+
245+
def pad_all_atomic_subtemplates_to(self,
246+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'ForLoopPulseTemplate':
247+
self.__body = self.body.pad_all_atomic_subtemplates_to(to_new_duration)
248+
self.__dict__.pop('duration', None)
249+
return self
250+
245251

246252
class LoopIndexNotUsedException(Exception):
247253
def __init__(self, loop_index: str, body_parameter_names: Set[str]):

qupulse/pulses/mapping_pulse_template.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from typing import Optional, Set, Dict, Union, List, Any, Tuple, Mapping
1+
from typing import Optional, Set, Dict, Union, List, Any, Tuple, Mapping, Callable
22
import itertools
33
import numbers
44
import collections
55

66
from qupulse.utils.types import ChannelID, FrozenDict, FrozenMapping
7-
from qupulse.expressions import Expression, ExpressionScalar
7+
from qupulse.expressions import Expression, ExpressionScalar, ExpressionLike
88
from qupulse.parameter_scope import Scope, MappedScope
99
from qupulse.pulses.pulse_template import PulseTemplate, MappingTuple
1010
from qupulse.pulses.parameters import ParameterNotProvidedException, ParameterConstrainer
@@ -352,7 +352,12 @@ def initial_values(self) -> Dict[ChannelID, ExpressionScalar]:
352352
@property
353353
def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
354354
return self._apply_mapping_to_inner_channel_dict(self.__template.final_values)
355-
355+
356+
def pad_all_atomic_subtemplates_to(self,
357+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
358+
359+
self.__template = self.template.pad_all_atomic_subtemplates_to(to_new_duration)
360+
return self
356361

357362
class MissingMappingException(Exception):
358363
"""Indicates that no mapping was specified for some parameter declaration of a

qupulse/pulses/multi_channel_pulse_template.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- ParallelChannelPulseTemplate: A pulse template to add channels to an existing pulse template.
88
"""
99

10-
from typing import Dict, List, Optional, Any, AbstractSet, Union, Set, Sequence, Mapping
10+
from typing import Dict, List, Optional, Any, AbstractSet, Union, Set, Sequence, Mapping, Callable
1111
import numbers
1212
import warnings
1313

@@ -215,7 +215,14 @@ def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
215215
for subtemplate in self._subtemplates:
216216
values.update(subtemplate.final_values)
217217
return values
218-
218+
219+
def pad_all_atomic_subtemplates_to(self,
220+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
221+
222+
for i,subtemplate in enumerate(self._subtemplates):
223+
self._subtemplates[i] = subtemplate.pad_all_atomic_subtemplates_to(to_new_duration)
224+
return self
225+
219226

220227
class ParallelChannelPulseTemplate(PulseTemplate):
221228
def __init__(self,
@@ -352,7 +359,13 @@ def with_parallel_channels(self, values: Mapping[ChannelID, ExpressionLike]) ->
352359

353360
def _is_atomic(self) -> bool:
354361
return self._template._is_atomic()
355-
362+
363+
def pad_all_atomic_subtemplates_to(self,
364+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
365+
366+
self._template = self.template.pad_all_atomic_subtemplates_to(to_new_duration)
367+
return self
368+
356369

357370
ParallelConstantChannelPulseTemplate = ParallelChannelPulseTemplate
358371

qupulse/pulses/pulse_template.py

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ def with_appended(self, *appended: 'PulseTemplate'):
376376
return self
377377

378378
def pad_to(self, to_new_duration: Union[ExpressionLike, Callable[[Expression], ExpressionLike]],
379-
as_single_wf: bool = True,
379+
as_single_wf: bool = False,
380380
pt_kwargs: Mapping[str, Any] = {}) -> 'PulseTemplate':
381381
"""Pad this pulse template to the given duration.
382382
The target duration can be numeric, symbolic or a callable that returns a new duration from the current
@@ -405,7 +405,7 @@ def pad_to(self, to_new_duration: Union[ExpressionLike, Callable[[Expression], E
405405
406406
Returns:
407407
A pulse template that has the duration given by ``to_new_duration``.
408-
self if ConstantPT,
408+
XXX# self if ConstantPT,
409409
else SingleWFTimeExtensionPulseTemplate if as_single_wf,
410410
else SequencePT
411411
"""
@@ -418,12 +418,13 @@ def pad_to(self, to_new_duration: Union[ExpressionLike, Callable[[Expression], E
418418
new_duration = ExpressionScalar(to_new_duration)
419419
pad_duration = new_duration - current_duration
420420

421-
#shortcut
422-
if isinstance(self,ConstantPT):
423-
if pt_kwargs:
424-
raise NotImplementedError()
425-
self._duration = new_duration
426-
return self
421+
#maybe leads to inconsistencies if self may be returned
422+
# #shortcut
423+
# if isinstance(self,ConstantPT):
424+
# if pt_kwargs:
425+
# raise NotImplementedError()
426+
# self._duration = new_duration
427+
# return self
427428

428429
if as_single_wf:
429430
return SingleWFTimeExtensionPulseTemplate(self, new_duration, **pt_kwargs)
@@ -436,7 +437,16 @@ def pad_to(self, to_new_duration: Union[ExpressionLike, Callable[[Expression], E
436437
return SequencePT(self, pad_pt, **pt_kwargs)
437438
else:
438439
return self @ pad_pt
439-
440+
441+
# @abstractmethod
442+
def pad_all_atomic_subtemplates_to(self,
443+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
444+
"""pad ll atomic subtemplates to a new duration determiend from callable
445+
to_new_duration, e.g. from qupulse.utils.to_next_multiple for waveform
446+
granularity.
447+
"""
448+
raise NotImplementedError()
449+
440450
def __format__(self, format_spec: str):
441451
if format_spec == '':
442452
format_spec = self._DEFAULT_FORMAT_SPEC
@@ -611,7 +621,15 @@ def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
611621
for ch, value in values.items():
612622
values[ch] = value.evaluate_symbolic({self._AS_EXPRESSION_TIME: self.duration})
613623
return values
614-
624+
625+
def pad_to(self, to_new_duration: Union[ExpressionLike, Callable[[Expression], ExpressionLike]],
626+
pt_kwargs: Mapping[str, Any] = {}) -> 'PulseTemplate':
627+
return super().pad_to(to_new_duration,as_single_wf=True,pt_kwargs=pt_kwargs)
628+
629+
def pad_all_atomic_subtemplates_to(self,
630+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
631+
return self.pad_to(to_new_duration)
632+
615633

616634
class DoubleParameterNameException(Exception):
617635

qupulse/pulses/repetition_pulse_template.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""This module defines RepetitionPulseTemplate, a higher-order hierarchical pulse template that
22
represents the n-times repetition of another PulseTemplate."""
33

4-
from typing import Dict, List, AbstractSet, Optional, Union, Any, Mapping, cast
4+
from typing import Dict, List, AbstractSet, Optional, Union, Any, Mapping, cast, Callable
55
from numbers import Real
66
from warnings import warn
77

@@ -13,7 +13,7 @@
1313
from qupulse.parameter_scope import Scope
1414

1515
from qupulse.utils.types import ChannelID
16-
from qupulse.expressions import ExpressionScalar
16+
from qupulse.expressions import ExpressionScalar, Expression, ExpressionLike
1717
from qupulse.utils import checked_int_cast
1818
from qupulse.pulses.pulse_template import PulseTemplate
1919
from qupulse.pulses.loop_pulse_template import LoopPulseTemplate
@@ -180,7 +180,13 @@ def initial_values(self) -> Dict[ChannelID, ExpressionScalar]:
180180
@property
181181
def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
182182
return self.body.final_values
183-
183+
184+
def pad_all_atomic_subtemplates_to(self,
185+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
186+
187+
self.__body = self.body.pad_all_atomic_subtemplates_to(to_new_duration)
188+
return self
189+
184190

185191
class ParameterNotIntegerException(Exception):
186192
"""Indicates that the value of the parameter given as repetition count was not an integer."""

qupulse/pulses/sequence_pulse_template.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from qupulse.pulses.mapping_pulse_template import MappingPulseTemplate, MappingTuple
1818
from qupulse.program.waveforms import SequenceWaveform
1919
from qupulse.pulses.measurement import MeasurementDeclaration, MeasurementDefiner
20-
from qupulse.expressions import Expression, ExpressionScalar
20+
from qupulse.expressions import Expression, ExpressionScalar, ExpressionLike
2121

2222
__all__ = ["SequencePulseTemplate"]
2323

@@ -194,3 +194,9 @@ def initial_values(self) -> Dict[ChannelID, ExpressionScalar]:
194194
def final_values(self) -> Dict[ChannelID, ExpressionScalar]:
195195
return self.__subtemplates[-1].final_values
196196

197+
def pad_all_atomic_subtemplates_to(self,
198+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
199+
200+
for i,sub in enumerate(self.__subtemplates):
201+
self.__subtemplates[i] = sub.pad_all_atomic_subtemplates_to(to_new_duration)
202+
return self

qupulse/pulses/time_reversal_pulse_template.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from typing import Optional, Set, Dict, Union
1+
from typing import Optional, Set, Dict, Union, Callable
22

33
from qupulse import ChannelID
44
from qupulse.program.loop import Loop
55
from qupulse.program.waveforms import Waveform
66
from qupulse.serialization import PulseRegistryType
7-
from qupulse.expressions import ExpressionScalar
7+
from qupulse.expressions import ExpressionScalar, Expression, ExpressionLike
88

99
from qupulse.pulses.pulse_template import PulseTemplate
1010

@@ -68,3 +68,9 @@ def get_serialization_data(self, serializer=None):
6868

6969
def _is_atomic(self) -> bool:
7070
return self._inner._is_atomic()
71+
72+
def pad_all_atomic_subtemplates_to(self,
73+
to_new_duration: Callable[[Expression], ExpressionLike]) -> 'PulseTemplate':
74+
self._inner = self._inner.pad_all_atomic_subtemplates_to(to_new_duration)
75+
return self
76+

0 commit comments

Comments
 (0)