diff --git a/CHANGELOG.md b/CHANGELOG.md index 60063f57..7831b436 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Channel offsets (e.g. `SingleChannel.opx_output_offset`) is None by default (see note in Fixed) - Move `quam.components.superconducting_qubits` to `quam.examples.superconducting_qubits` - Replaced `InOutIQChannel.measure` kwargs `I_var` and `Q_var` by `qua_vars` tuple +- `Pulse.id` is now an instance variable instead of a class variable ### Fixed - Don't raise instantiation error when required_type is not a class diff --git a/quam/components/channels.py b/quam/components/channels.py index bed48209..617bb099 100644 --- a/quam/components/channels.py +++ b/quam/components/channels.py @@ -17,9 +17,16 @@ fixed, demod, dual_demod, + frame_rotation, +) +from qm.qua._dsl import ( + _PulseAmp, + AmpValuesType, + QuaNumberType, + QuaExpressionType, + ChirpType, + StreamType, ) -from qm.qua._type_hinting import * -from qm.qua._dsl import _PulseAmp __all__ = [ @@ -273,6 +280,33 @@ def align(self, *other_elements): ] align(self.name, *other_elements_str) + def frame_rotation(self, angle: QuaNumberType): + r"""Shift the phase of the channel element's oscillator by the given angle. + + This is typically used for virtual z-rotations. + + Note: + The fixed point format of QUA variables of type fixed is 4.28, meaning the + phase must be between $-8$ and $8-2^{28}$. Otherwise the phase value will be + invalid. It is therefore better to use `frame_rotation_2pi()` which avoids + this issue. + + Note: + The phase is accumulated with a resolution of 16 bit. + Therefore, *N* changes to the phase can result in a phase (and amplitude) + inaccuracy of about :math:`N \cdot 2^{-16}`. To null out this accumulated + error, it is recommended to use `reset_frame(el)` from time to time. + + Args: + angle (Union[float, QUA variable of type fixed]): The angle to + add to the current phase (in radians) + *elements (str): a single element whose oscillator's phase will + be shifted. multiple elements can be given, in which case + all of their oscillators' phases will be shifted + + """ + frame_rotation(angle, self.name) + def _config_add_controller( self, config: Dict[str, dict], controller_name: str ) -> Dict[str, dict]: diff --git a/quam/components/octave.py b/quam/components/octave.py index f8be6b10..af0cefd1 100644 --- a/quam/components/octave.py +++ b/quam/components/octave.py @@ -6,8 +6,8 @@ from quam.components.hardware import FrequencyConverter from quam.components.channels import InOutIQChannel -from qm.QuantumMachinesManager import QuantumMachinesManager -from qm.QuantumMachine import QuantumMachine +from qm import QuantumMachinesManager +from qm import QuantumMachine from qm.octave.qm_octave import QmOctave from octave_sdk import RFInputLOSource diff --git a/quam/components/pulses.py b/quam/components/pulses.py index 4d5eb5c5..2a32f702 100644 --- a/quam/components/pulses.py +++ b/quam/components/pulses.py @@ -52,10 +52,9 @@ class Pulse(QuamComponent): The digital marker label is defined as `"{channel_name}.{pulse_name}.dm"`. """ - - id: ClassVar[str] = None operation: ClassVar[str] = "control" length: int + id: str = None digital_marker: Union[str, List[Tuple[int, int]]] = None diff --git a/tests/components/pulses/test_pulses.py b/tests/components/pulses/test_pulses.py index 50712d4f..eb86dd74 100644 --- a/tests/components/pulses/test_pulses.py +++ b/tests/components/pulses/test_pulses.py @@ -14,6 +14,7 @@ def test_drag_pulse(): assert drag_pulse.operation == "control" assert drag_pulse.length == 20 assert drag_pulse.get_attrs() == { + "id": None, "length": 20, "axis_angle": 0.0, "digital_marker": None,