iqm-pulse 9.12.0__tar.gz → 9.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/CHANGELOG.rst +9 -0
  2. {iqm_pulse-9.12.0/src/iqm_pulse.egg-info → iqm_pulse-9.13.0}/PKG-INFO +1 -1
  3. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/__init__.py +2 -1
  4. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/default_gates.py +6 -2
  5. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/measure.py +70 -3
  6. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0/src/iqm_pulse.egg-info}/PKG-INFO +1 -1
  7. iqm_pulse-9.13.0/version.txt +1 -0
  8. iqm_pulse-9.12.0/version.txt +0 -1
  9. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/LICENSE.txt +0 -0
  10. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/MANIFEST.in +0 -0
  11. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/README.rst +0 -0
  12. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/API.rst +0 -0
  13. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/Makefile +0 -0
  14. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/.gitignore +0 -0
  15. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/css/custom.css +0 -0
  16. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/favicon.ico +0 -0
  17. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/feedback_timing.svg +0 -0
  18. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/logo.png +0 -0
  19. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/playlist_breakdown.svg +0 -0
  20. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/pulse_timing.svg +0 -0
  21. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_static/images/readout_timing.svg +0 -0
  22. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_templates/autosummary-class-template.rst +0 -0
  23. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/_templates/autosummary-module-template.rst +0 -0
  24. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/changelog.rst +0 -0
  25. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/concepts.rst +0 -0
  26. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/conf.py +0 -0
  27. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/custom_gates.rst +0 -0
  28. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/index.rst +0 -0
  29. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/license.rst +0 -0
  30. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/pulse_timing.rst +0 -0
  31. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/references.bib +0 -0
  32. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/references.rst +0 -0
  33. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/docs/using_builder.rst +0 -0
  34. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/pyproject.toml +0 -0
  35. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/requirements/base.in +0 -0
  36. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/requirements/base.txt +0 -0
  37. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/setup.cfg +0 -0
  38. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/setup.py +0 -0
  39. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/__init__.py +0 -0
  40. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/base_utils.py +0 -0
  41. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/builder.py +0 -0
  42. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/circuit_operations.py +0 -0
  43. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gate_implementation.py +0 -0
  44. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/barrier.py +0 -0
  45. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/conditional.py +0 -0
  46. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/cz.py +0 -0
  47. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/delay.py +0 -0
  48. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/enums.py +0 -0
  49. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/flux_multiplexer.py +0 -0
  50. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/move.py +0 -0
  51. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/prx.py +0 -0
  52. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/reset.py +0 -0
  53. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/rz.py +0 -0
  54. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/sx.py +0 -0
  55. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/gates/u.py +0 -0
  56. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/__init__.py +0 -0
  57. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/channel.py +0 -0
  58. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/fast_drag.py +0 -0
  59. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/hd_drag.py +0 -0
  60. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/instructions.py +0 -0
  61. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/playlist.py +0 -0
  62. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/schedule.py +0 -0
  63. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/__init__.py +0 -0
  64. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/base.py +0 -0
  65. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/templates/playlist_inspection.jinja2 +0 -0
  66. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/templates/static/logo.png +0 -0
  67. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/templates/static/moment.min.js +0 -0
  68. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/templates/static/vis-timeline-graph2d.min.css +0 -0
  69. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/visualisation/templates/static/vis-timeline-graph2d.min.js +0 -0
  70. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/playlist/waveforms.py +0 -0
  71. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/quantum_ops.py +0 -0
  72. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/scheduler.py +0 -0
  73. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/timebox.py +0 -0
  74. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/utils.py +0 -0
  75. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm/pulse/validation.py +0 -0
  76. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm_pulse.egg-info/SOURCES.txt +0 -0
  77. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm_pulse.egg-info/dependency_links.txt +0 -0
  78. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm_pulse.egg-info/requires.txt +0 -0
  79. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/src/iqm_pulse.egg-info/top_level.txt +0 -0
  80. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/tests/.pylintrc +0 -0
  81. {iqm_pulse-9.12.0 → iqm_pulse-9.13.0}/tests/__init__.py +0 -0
@@ -2,6 +2,15 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ Version 9.13.0 (2025-06-11)
6
+ ===========================
7
+
8
+ Features
9
+ --------
10
+
11
+ - Add a base class for shelved readout :class:`Shelved_Measure_CustomWaveforms` and an implementation of shelved readout
12
+ :class:`Shelved_Measure_Constant`. This implementations consist of ``prx_12`` + ``measure`` + ``prx_12`` gates.
13
+
5
14
  Version 9.12.0 (2025-05-30)
6
15
  ===========================
7
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulse
3
- Version: 9.12.0
3
+ Version: 9.13.0
4
4
  Summary: A Python-based project for providing interface and implementations for control pulses.
5
5
  Author-email: IQM Finland Oy <info@meetiqm.com>
6
6
  License: Apache License
@@ -47,7 +47,7 @@ from iqm.pulse.gates.cz import (
47
47
  from iqm.pulse.gates.default_gates import _quantum_ops_library
48
48
  from iqm.pulse.gates.delay import Delay
49
49
  from iqm.pulse.gates.flux_multiplexer import FluxMultiplexer_SampleLinear
50
- from iqm.pulse.gates.measure import Measure_Constant, Measure_Constant_Qnd
50
+ from iqm.pulse.gates.measure import Measure_Constant, Measure_Constant_Qnd, Shelved_Measure_Constant
51
51
  from iqm.pulse.gates.move import MOVE_CRF_CRF, MOVE_TGSS_CRF
52
52
  from iqm.pulse.gates.prx import (
53
53
  Constant_PRX_with_smooth_rise_fall,
@@ -102,6 +102,7 @@ _exposed_implementations: dict[str, type[GateImplementation]] = {
102
102
  FluxPulseGate_CRF_CRF,
103
103
  Measure_Constant,
104
104
  Measure_Constant_Qnd,
105
+ Shelved_Measure_Constant,
105
106
  PRX_ModulatedDRAGCosineRiseFall,
106
107
  MOVE_CRF_CRF,
107
108
  MOVE_TGSS_CRF,
@@ -34,7 +34,7 @@ from iqm.pulse.gates.cz import (
34
34
  )
35
35
  from iqm.pulse.gates.delay import Delay
36
36
  from iqm.pulse.gates.flux_multiplexer import FluxMultiplexer_SampleLinear
37
- from iqm.pulse.gates.measure import Measure_Constant
37
+ from iqm.pulse.gates.measure import Measure_Constant, Shelved_Measure_Constant
38
38
  from iqm.pulse.gates.move import MOVE_CRF_CRF, MOVE_TGSS_CRF
39
39
  from iqm.pulse.gates.prx import (
40
40
  PRX_DRAGCosineRiseFall,
@@ -60,7 +60,11 @@ for different gates."""
60
60
  _default_implementations = {
61
61
  "barrier": {"": Barrier},
62
62
  "delay": {"wait": Delay},
63
- "measure": {"constant": Measure_Constant, "constant_qnd": Measure_Constant},
63
+ "measure": {
64
+ "constant": Measure_Constant,
65
+ "constant_qnd": Measure_Constant,
66
+ "shelved_constant": Shelved_Measure_Constant,
67
+ },
64
68
  "prx": {
65
69
  "drag_gaussian": PRX_DRAGGaussian,
66
70
  "drag_crf": PRX_DRAGCosineRiseFall,
@@ -214,7 +214,7 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
214
214
  return probe_pulse, acquisition_method
215
215
 
216
216
  def probe_timebox(
217
- self, key: str = "", feedback_key: str = "", do_acquisition: bool = True
217
+ self, key: str = "", feedback_key: str = "", do_acquisition: bool = True, **kwargs
218
218
  ) -> MultiplexedProbeTimeBox:
219
219
  """Returns a "naked" probe timebox that supports convenient multiplexing through
220
220
  ``MultiplexedProbeTimeBox.__add__``.
@@ -286,10 +286,12 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
286
286
  label=f"{self.__class__.__name__} on {self.locus}",
287
287
  )
288
288
  else:
289
+ # _skip_override used for child classes build on `Measure_CustomWaveforms` to not call `.probe_timebox`
290
+ # from the parent class, but from this class instead.
289
291
  probe_timeboxes = [
290
292
  self.builder.get_implementation(
291
293
  self.parent.name, (c,), impl_name=self.name, priority_calibration=self._prio_calibration
292
- ).probe_timebox(key, feedback_key, do_acquisition)
294
+ ).probe_timebox(key, feedback_key, do_acquisition, _skip_override=True)
293
295
  for c in self.locus
294
296
  ]
295
297
  probe_timebox = functools.reduce(lambda x, y: x + y, probe_timeboxes)
@@ -377,7 +379,7 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
377
379
  args = (key, acquisition_delay, acquisition_duration, feedback_key)
378
380
  # additional caching for time traces since the acquisitions differ from the ones in _call
379
381
  if args not in self._time_traces:
380
- probe_timebox = deepcopy(self.probe_timebox(key=key, feedback_key=feedback_key))
382
+ probe_timebox = deepcopy(self.probe_timebox(key=key, feedback_key=feedback_key, _skip_override=True))
381
383
  for probe_channel, segment in probe_timebox.atom.items():
382
384
  readout_trigger = segment[0]
383
385
  # TODO instead of editing the probe_timebox output contents, we should make the function itself do this
@@ -785,3 +787,68 @@ class Probe_Constant(ProbePulse_CustomWaveforms_noIntegration, wave_i=Constant,
785
787
 
786
788
  Uses a constant probe pulse.
787
789
  """
790
+
791
+
792
+ class Shelved_Measure_CustomWaveforms(Measure_CustomWaveforms):
793
+ """Base class for shelved readout.
794
+
795
+ Shelved readout applies a ``prx_12(pi)`` gate before and after a standard dispersive readout on each qubit measured.
796
+ The first ``prx_12(pi)`` swaps the amplitudes of the |1> and |2> states, and the second one swaps them back after
797
+ the measurement has (roughtly) collapsed the state. If the discriminator of the readout is calibrated such that
798
+ the |0> state is on one side and the |1> and |2> states are on the other, the end result is equivalent to the
799
+ standard readout operation but with the advantage that the population in the |2> state is less susceptible to
800
+ :math:`T_1` decay during the readout than the population in the |1> state.
801
+
802
+ .. note:: Mixed implementation multiplexing is not supported.
803
+ """
804
+
805
+ # Copied from `CompositeGate` to refresh caching after any calibration changes (in particular for the `prx_12`
806
+ # calibration)
807
+ def __call__(self, *args, **kwargs):
808
+ default_cache_key = tuple(args) + tuple(kwargs.items())
809
+ try:
810
+ hash(default_cache_key)
811
+ key_is_hashable = True
812
+ except TypeError:
813
+ key_is_hashable = False
814
+ if key_is_hashable:
815
+ if box := self.builder.composite_cache.get(self, default_cache_key):
816
+ return box
817
+ box = self._call(*args, **kwargs)
818
+ if key_is_hashable:
819
+ self.builder.composite_cache.set(self, default_cache_key, box)
820
+ return box
821
+
822
+ # `probe_timebox` is needed for making certain experiments work (e.g. `MeasurementQNDness`), since they call this
823
+ # function explicitly. However, the main functionality of this method will not work: Enabling mixed
824
+ # implementation multiplexing. This is because the method has to return time boxes due to the `prx_12` pulses,
825
+ # instead of `MultiplexedProbeTimeBox`
826
+ # TODO: Enable mixed implementation multiplexing for shelved readout
827
+ def probe_timebox(
828
+ self, key: str = "", feedback_key: str = "", do_acquisition: bool = True, _skip_override: bool = False
829
+ ) -> TimeBox:
830
+ # type: ignore[override]
831
+ if _skip_override:
832
+ return super().probe_timebox(key, feedback_key, do_acquisition)
833
+ multiplexed_timeboxes = super().probe_timebox(key, feedback_key)
834
+ prx_12_impl = [self.builder.get_implementation("prx_12", [q])(np.pi) for q in self.locus]
835
+
836
+ boxes = prx_12_impl + multiplexed_timeboxes + prx_12_impl
837
+ return boxes
838
+
839
+ def _call(self, key: str = "", feedback_key: str = "") -> TimeBox: # type: ignore[override]
840
+ shelved_measure_box = TimeBox.composite(
841
+ self.probe_timebox(key=key, feedback_key=feedback_key), label=f"Readout on {self.locus}"
842
+ )
843
+ shelved_measure_box.neighborhood_components[0] = shelved_measure_box.children[
844
+ len(self.locus)
845
+ ].neighborhood_components[0]
846
+
847
+ return shelved_measure_box
848
+
849
+
850
+ class Shelved_Measure_Constant(Shelved_Measure_CustomWaveforms, wave_i=Constant, wave_q=Constant):
851
+ """Implementation of a shelved readout.
852
+
853
+ A measure gate implemented as a constant waveform is surrounded by two `prx_12` gates.
854
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulse
3
- Version: 9.12.0
3
+ Version: 9.13.0
4
4
  Summary: A Python-based project for providing interface and implementations for control pulses.
5
5
  Author-email: IQM Finland Oy <info@meetiqm.com>
6
6
  License: Apache License
@@ -0,0 +1 @@
1
+ 9.13.0
@@ -1 +0,0 @@
1
- 9.12.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes