iqm-pulse 11.0.0__tar.gz → 11.1.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 (82) hide show
  1. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/CHANGELOG.rst +8 -0
  2. {iqm_pulse-11.0.0/src/iqm_pulse.egg-info → iqm_pulse-11.1.0}/PKG-INFO +1 -1
  3. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/builder.py +82 -70
  4. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/measure.py +15 -3
  5. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/instructions.py +4 -0
  6. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0/src/iqm_pulse.egg-info}/PKG-INFO +1 -1
  7. iqm_pulse-11.1.0/version.txt +1 -0
  8. iqm_pulse-11.0.0/version.txt +0 -1
  9. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/LICENSE.txt +0 -0
  10. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/MANIFEST.in +0 -0
  11. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/README.rst +0 -0
  12. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/API.rst +0 -0
  13. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/Makefile +0 -0
  14. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/.gitignore +0 -0
  15. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/css/custom.css +0 -0
  16. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/favicon.ico +0 -0
  17. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/feedback_timing.svg +0 -0
  18. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/logo.png +0 -0
  19. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/playlist_breakdown.svg +0 -0
  20. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/pulse_timing.svg +0 -0
  21. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_static/images/readout_timing.svg +0 -0
  22. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_templates/autosummary-class-template.rst +0 -0
  23. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/_templates/autosummary-module-template.rst +0 -0
  24. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/changelog.rst +0 -0
  25. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/concepts.rst +0 -0
  26. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/conf.py +0 -0
  27. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/custom_gates.rst +0 -0
  28. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/index.rst +0 -0
  29. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/license.rst +0 -0
  30. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/pulse_timing.rst +0 -0
  31. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/references.bib +0 -0
  32. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/references.rst +0 -0
  33. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/docs/using_builder.rst +0 -0
  34. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/pyproject.toml +0 -0
  35. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/requirements/base.in +0 -0
  36. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/requirements/base.txt +0 -0
  37. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/setup.cfg +0 -0
  38. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/setup.py +0 -0
  39. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/__init__.py +0 -0
  40. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/base_utils.py +0 -0
  41. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/circuit_operations.py +0 -0
  42. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gate_implementation.py +0 -0
  43. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/__init__.py +0 -0
  44. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/barrier.py +0 -0
  45. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/conditional.py +0 -0
  46. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/cz.py +0 -0
  47. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/default_gates.py +0 -0
  48. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/delay.py +0 -0
  49. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/enums.py +0 -0
  50. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/flux_multiplexer.py +0 -0
  51. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/move.py +0 -0
  52. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/prx.py +0 -0
  53. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/reset.py +0 -0
  54. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/rz.py +0 -0
  55. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/sx.py +0 -0
  56. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/gates/u.py +0 -0
  57. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/__init__.py +0 -0
  58. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/channel.py +0 -0
  59. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/fast_drag.py +0 -0
  60. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/hd_drag.py +0 -0
  61. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/playlist.py +0 -0
  62. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/schedule.py +0 -0
  63. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/__init__.py +0 -0
  64. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/base.py +0 -0
  65. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/templates/playlist_inspection.jinja2 +0 -0
  66. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/templates/static/logo.png +0 -0
  67. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/templates/static/moment.min.js +0 -0
  68. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/templates/static/vis-timeline-graph2d.min.css +0 -0
  69. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/visualisation/templates/static/vis-timeline-graph2d.min.js +0 -0
  70. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/playlist/waveforms.py +0 -0
  71. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/py.typed +0 -0
  72. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/quantum_ops.py +0 -0
  73. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/scheduler.py +0 -0
  74. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/timebox.py +0 -0
  75. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/utils.py +0 -0
  76. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm/pulse/validation.py +0 -0
  77. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm_pulse.egg-info/SOURCES.txt +0 -0
  78. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm_pulse.egg-info/dependency_links.txt +0 -0
  79. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm_pulse.egg-info/requires.txt +0 -0
  80. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/src/iqm_pulse.egg-info/top_level.txt +0 -0
  81. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/tests/.pylintrc +0 -0
  82. {iqm_pulse-11.0.0 → iqm_pulse-11.1.0}/tests/__init__.py +0 -0
@@ -2,6 +2,14 @@
2
2
  Changelog
3
3
  =========
4
4
 
5
+ Version 11.1.0 (2025-09-08)
6
+ ===========================
7
+
8
+ Features
9
+ --------
10
+
11
+ - ScheduleBuilder.timeboxes_to_front_padded_playlist now returns also the used measure implementations per readout label
12
+
5
13
  Version 11.0.0 (2025-09-08)
6
14
  ===========================
7
15
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulse
3
- Version: 11.0.0
3
+ Version: 11.1.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
@@ -15,6 +15,7 @@
15
15
 
16
16
  from __future__ import annotations
17
17
 
18
+ from collections import defaultdict
18
19
  from collections.abc import Iterable
19
20
  import copy
20
21
  from dataclasses import dataclass, field, replace
@@ -983,7 +984,9 @@ class ScheduleBuilder:
983
984
  boxes.append(factory(**op.args))
984
985
  return TimeBox.composite(boxes, label=name, scheduling_algorithm=scheduling_algorithm)
985
986
 
986
- def timeboxes_to_front_padded_playlist(self, boxes: Iterable[TimeBox], *, neighborhood: int = 0) -> Playlist:
987
+ def timeboxes_to_front_padded_playlist(
988
+ self, boxes: Iterable[TimeBox], *, neighborhood: int = 0
989
+ ) -> tuple[Playlist, dict[str, set[str]]]:
987
990
  """Temporary helper function, for converting a sequence of TimeBoxes to a Playlist.
988
991
 
989
992
  Each individual TimeBox in ``boxes`` is resolved into a Schedule, and then
@@ -1002,7 +1005,8 @@ class ScheduleBuilder:
1002
1005
  blocks only the defined locus components and any other components which have occupied channels.
1003
1006
 
1004
1007
  Returns:
1005
- playlist that implements ``boxes``
1008
+ playlist that implements ``boxes`` and the mapping from readout labels to the set of used measurement
1009
+ implementations (of the format ``<QuantumOp name>.<impl name>``).
1006
1010
 
1007
1011
  """
1008
1012
  schedules = [self.resolve_timebox(box, neighborhood=neighborhood).cleanup() for box in boxes]
@@ -1046,7 +1050,7 @@ class ScheduleBuilder:
1046
1050
  playlist that implements ``boxes``
1047
1051
 
1048
1052
  """
1049
- return self.build_playlist(self.timebox_to_schedule(box, neighborhood=neighborhood) for box in boxes)
1053
+ return self.build_playlist(self.timebox_to_schedule(box, neighborhood=neighborhood) for box in boxes)[0]
1050
1054
 
1051
1055
  def timebox_to_schedule(
1052
1056
  self,
@@ -1396,7 +1400,9 @@ class ScheduleBuilder:
1396
1400
  if not schedule[ch]:
1397
1401
  schedule.append(ch, Block(T))
1398
1402
 
1399
- def build_playlist(self, schedules: Iterable[Schedule], finish_schedules: bool = True) -> Playlist:
1403
+ def build_playlist( # noqa: PLR0915
1404
+ self, schedules: Iterable[Schedule], finish_schedules: bool = True
1405
+ ) -> tuple[Playlist, dict[str, set[str]]]:
1400
1406
  """Build a playlist from a number of instruction schedules.
1401
1407
 
1402
1408
  This involves compressing the schedules so that no duplicate information
@@ -1410,7 +1416,8 @@ class ScheduleBuilder:
1410
1416
  unless some process has already finalised them before calling this function.
1411
1417
 
1412
1418
  Returns:
1413
- playlist containing the schedules
1419
+ playlist containing the schedules and the mapping from readout labels to the set of used measurement
1420
+ implementations (of the format ``<QuantumOp name>.<impl name>``).
1414
1421
 
1415
1422
  Raises:
1416
1423
  ValueError: if the schedules contain channels with non-uniform sampling rates
@@ -1458,6 +1465,75 @@ class ScheduleBuilder:
1458
1465
 
1459
1466
  # add the schedules in the playlist
1460
1467
 
1468
+ label_to_implementation: dict[str, set[str]] = defaultdict(set)
1469
+
1470
+ def _map_instruction(inst: Instruction) -> sc_instructions.Instruction:
1471
+ """TODO only necessary until SC has been updated to use the iqm.pulse Instruction class."""
1472
+ operation: Any
1473
+
1474
+ def _map_acquisition(acq: AcquisitionMethod) -> sc_instructions.AcquisitionMethod:
1475
+ if acq.implementation is not None:
1476
+ label_to_implementation[acq.label].add(acq.implementation)
1477
+ if isinstance(acq, ThresholdStateDiscrimination):
1478
+ return sc_instructions.ThresholdStateDiscrimination(
1479
+ label=acq.label,
1480
+ delay_samples=acq.delay_samples,
1481
+ weights=_map_instruction(acq.weights).operation,
1482
+ threshold=acq.threshold,
1483
+ feedback_signal_label=acq.feedback_signal_label,
1484
+ )
1485
+ if isinstance(acq, ComplexIntegration):
1486
+ return sc_instructions.ComplexIntegration(
1487
+ label=acq.label,
1488
+ delay_samples=acq.delay_samples,
1489
+ weights=_map_instruction(acq.weights).operation,
1490
+ )
1491
+ if isinstance(acq, TimeTrace):
1492
+ return sc_instructions.TimeTrace(
1493
+ label=acq.label, delay_samples=acq.delay_samples, duration_samples=acq.duration_samples
1494
+ )
1495
+ raise ValueError(f"Unknown AcquisitionMethod {acq}")
1496
+
1497
+ if isinstance(inst, Wait):
1498
+ operation = sc_instructions.Wait()
1499
+ elif isinstance(inst, VirtualRZ):
1500
+ operation = sc_instructions.VirtualRZ(inst.phase_increment)
1501
+ elif isinstance(inst, RealPulse):
1502
+ operation = sc_instructions.RealPulse(
1503
+ wave=to_canonical(inst.wave),
1504
+ scale=inst.scale,
1505
+ )
1506
+ elif isinstance(inst, IQPulse):
1507
+ operation = sc_instructions.IQPulse(
1508
+ wave_i=to_canonical(inst.wave_i),
1509
+ wave_q=to_canonical(inst.wave_q),
1510
+ scale_i=inst.scale_i,
1511
+ scale_q=inst.scale_q,
1512
+ phase=inst.phase,
1513
+ modulation_frequency=inst.modulation_frequency,
1514
+ phase_increment=inst.phase_increment,
1515
+ )
1516
+ elif isinstance(inst, ConditionalInstruction):
1517
+ if len(inst.outcomes) != 2:
1518
+ raise ValueError("ConditionalInstruction requires exactly two outcomes.")
1519
+ operation = sc_instructions.ConditionalInstruction(
1520
+ condition=inst.condition,
1521
+ if_true=_map_instruction(inst.outcomes[1]),
1522
+ if_false=_map_instruction(inst.outcomes[0]),
1523
+ )
1524
+ elif isinstance(inst, MultiplexedIQPulse):
1525
+ sc_entries = tuple((_map_instruction(p), d) for p, d in inst.entries)
1526
+ operation = sc_instructions.MultiplexedIQPulse(sc_entries)
1527
+ elif isinstance(inst, ReadoutTrigger):
1528
+ sc_acquisitions = tuple(_map_acquisition(a) for a in inst.acquisitions)
1529
+ operation = sc_instructions.ReadoutTrigger(
1530
+ probe_pulse=_map_instruction(inst.probe_pulse),
1531
+ acquisitions=sc_acquisitions,
1532
+ )
1533
+ else:
1534
+ raise ValueError(f"{inst} not supported.")
1535
+ return sc_instructions.Instruction(duration_samples=int(inst.duration), operation=operation)
1536
+
1461
1537
  # NOTE that there is no implicit right-alignment or equal duration for schedules, unlike in old-style playlists!
1462
1538
  for schedule in schedules:
1463
1539
  finished_schedule = self._finish_schedule(schedule) if finish_schedules else schedule
@@ -1486,7 +1562,7 @@ class ScheduleBuilder:
1486
1562
  if prev_wait:
1487
1563
  _append_to_schedule(sc_schedule, channel_name, prev_wait)
1488
1564
  pl.segments.append(sc_schedule)
1489
- return pl
1565
+ return pl, label_to_implementation
1490
1566
 
1491
1567
  def _set_gate_implementation_shortcut(self, op_name: str) -> None:
1492
1568
  """Create shortcut for `self.get_implementation(<op_name>, ...)` as `self.<op_name>(...)`.
@@ -1522,67 +1598,3 @@ class ScheduleBuilder:
1522
1598
  f"a class attribute ``ScheduleBuilder.{op_name}``."
1523
1599
  )
1524
1600
  self._logger.warning(warning_msg)
1525
-
1526
-
1527
- def _map_instruction(inst: Instruction) -> sc_instructions.Instruction:
1528
- """TODO only necessary until SC has been updated to use the iqm.pulse Instruction class."""
1529
- operation: Any
1530
-
1531
- def _map_acquisition(acq: AcquisitionMethod) -> sc_instructions.AcquisitionMethod:
1532
- if isinstance(acq, ThresholdStateDiscrimination):
1533
- return sc_instructions.ThresholdStateDiscrimination(
1534
- label=acq.label,
1535
- delay_samples=acq.delay_samples,
1536
- weights=_map_instruction(acq.weights).operation,
1537
- threshold=acq.threshold,
1538
- feedback_signal_label=acq.feedback_signal_label,
1539
- )
1540
- if isinstance(acq, ComplexIntegration):
1541
- return sc_instructions.ComplexIntegration(
1542
- label=acq.label, delay_samples=acq.delay_samples, weights=_map_instruction(acq.weights).operation
1543
- )
1544
- if isinstance(acq, TimeTrace):
1545
- return sc_instructions.TimeTrace(
1546
- label=acq.label, delay_samples=acq.delay_samples, duration_samples=acq.duration_samples
1547
- )
1548
- raise ValueError(f"Unknown AcquisitionMethod {acq}")
1549
-
1550
- if isinstance(inst, Wait):
1551
- operation = sc_instructions.Wait()
1552
- elif isinstance(inst, VirtualRZ):
1553
- operation = sc_instructions.VirtualRZ(inst.phase_increment)
1554
- elif isinstance(inst, RealPulse):
1555
- operation = sc_instructions.RealPulse(
1556
- wave=to_canonical(inst.wave),
1557
- scale=inst.scale,
1558
- )
1559
- elif isinstance(inst, IQPulse):
1560
- operation = sc_instructions.IQPulse(
1561
- wave_i=to_canonical(inst.wave_i),
1562
- wave_q=to_canonical(inst.wave_q),
1563
- scale_i=inst.scale_i,
1564
- scale_q=inst.scale_q,
1565
- phase=inst.phase,
1566
- modulation_frequency=inst.modulation_frequency,
1567
- phase_increment=inst.phase_increment,
1568
- )
1569
- elif isinstance(inst, ConditionalInstruction):
1570
- if len(inst.outcomes) != 2:
1571
- raise ValueError("ConditionalInstruction requires exactly two outcomes.")
1572
- operation = sc_instructions.ConditionalInstruction(
1573
- condition=inst.condition,
1574
- if_true=_map_instruction(inst.outcomes[1]),
1575
- if_false=_map_instruction(inst.outcomes[0]),
1576
- )
1577
- elif isinstance(inst, MultiplexedIQPulse):
1578
- sc_entries = tuple((_map_instruction(p), d) for p, d in inst.entries)
1579
- operation = sc_instructions.MultiplexedIQPulse(sc_entries)
1580
- elif isinstance(inst, ReadoutTrigger):
1581
- sc_acquisitions = tuple(_map_acquisition(a) for a in inst.acquisitions)
1582
- operation = sc_instructions.ReadoutTrigger(
1583
- probe_pulse=_map_instruction(inst.probe_pulse),
1584
- acquisitions=sc_acquisitions,
1585
- )
1586
- else:
1587
- raise ValueError(f"{inst} not supported.")
1588
- return sc_instructions.Instruction(duration_samples=int(inst.duration), operation=operation)
@@ -199,9 +199,13 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
199
199
 
200
200
  acquisition_type = root_params.get("acquisition_type", self.root_parameters["acquisition_type"].value) # type: ignore[union-attr]
201
201
  acquisition_label = "TO_BE_REPLACED"
202
+ op_and_implementation = f"{self.parent.name}.{self.name}"
202
203
  if acquisition_type == "complex":
203
204
  acquisition_method = ComplexIntegration(
204
- label=acquisition_label, delay_samples=root_params["acquisition_delay"], weights=weights
205
+ label=acquisition_label,
206
+ delay_samples=root_params["acquisition_delay"],
207
+ weights=weights,
208
+ implementation=op_and_implementation,
205
209
  )
206
210
  elif acquisition_type == "threshold":
207
211
  acquisition_method = ThresholdStateDiscrimination(
@@ -209,6 +213,7 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
209
213
  delay_samples=root_params["acquisition_delay"],
210
214
  weights=weights,
211
215
  threshold=root_params["integration_threshold"],
216
+ implementation=op_and_implementation,
212
217
  )
213
218
  else:
214
219
  raise ValueError(f"Unknown acquisition type {acquisition_type}")
@@ -407,6 +412,7 @@ class Measure_CustomWaveforms(CustomIQWaveforms):
407
412
  label=f"{probe_name}__{label_key}",
408
413
  delay_samples=delay_samples,
409
414
  duration_samples=duration_samples,
415
+ implementation=f"{self.parent.name}.{self.name}",
410
416
  )
411
417
  trigger_with_trace = replace(readout_trigger, acquisitions=readout_trigger.acquisitions + (time_trace,))
412
418
  segment._instructions[0] = trigger_with_trace
@@ -520,7 +526,10 @@ class ProbePulse_CustomWaveforms(CustomIQWaveforms):
520
526
  acquisition_delay = round(self._probe_line.duration_to_samples(root_params["acquisition_delay"]))
521
527
  time_trace_label = "TO_BE_REPLACED"
522
528
  time_trace_acquisition = TimeTrace(
523
- label=time_trace_label, delay_samples=acquisition_delay, duration_samples=integration_length
529
+ label=time_trace_label,
530
+ delay_samples=acquisition_delay,
531
+ duration_samples=integration_length,
532
+ implementation=f"{self.parent.name}.{self.name}",
524
533
  )
525
534
 
526
535
  # TODO: due to device limitations, we need to integrate always, even though it does not make much sense here
@@ -536,7 +545,10 @@ class ProbePulse_CustomWaveforms(CustomIQWaveforms):
536
545
  )
537
546
  integration_label = "dummy__integration"
538
547
  integration_acquisition = ComplexIntegration(
539
- label=integration_label, delay_samples=acquisition_delay, weights=weights
548
+ label=integration_label,
549
+ delay_samples=acquisition_delay,
550
+ weights=weights,
551
+ implementation=f"{self.parent.name}.{self.name}",
540
552
  )
541
553
  return probe_pulse, (integration_acquisition, time_trace_acquisition)
542
554
 
@@ -210,6 +210,10 @@ class AcquisitionMethod:
210
210
  """Identifier for the returned data, like ``QB1__readout.time_trace``."""
211
211
  delay_samples: int
212
212
  """Delay from beginning of probe pulse to beginning of acquisition window, in samples."""
213
+ implementation: str | None
214
+ """Measure operation and implementation that created this AcquisitionMethod, in the format
215
+ ``<operation name>.<implementation name>``. If the acquisition is not originated from a
216
+ gate implementation, this should be ``None``."""
213
217
 
214
218
 
215
219
  @dataclass(frozen=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-pulse
3
- Version: 11.0.0
3
+ Version: 11.1.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
+ 11.1.0
@@ -1 +0,0 @@
1
- 11.0.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