Skip to content

QuAM Hardware API

BaseFrequencyConverter

Bases: QuamComponent

Base class for frequency converters.

Source code in quam/components/hardware.py
110
111
112
113
114
@quam_dataclass
class BaseFrequencyConverter(QuamComponent):
    """Base class for frequency converters."""

    pass

FrequencyConverter

Bases: BaseFrequencyConverter

Frequency up/down converter component.

This component encapsulates the local oscillator and mixer used to upconvert or downconvert an RF signal.

The FrequencyConverter component is attached to IQ channels through

  • IQChannel.frequency_converter_up
  • InOutIQChannel.frequency_converter_down

Parameters:

Name Type Description Default
local_oscillator LocalOscillator

The local oscillator for the frequency converter.

required
mixer Mixer

The mixer for the frequency converter.

required
gain float

The gain of the frequency converter.

required
Source code in quam/components/hardware.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
@quam_dataclass
class FrequencyConverter(BaseFrequencyConverter):
    """Frequency up/down converter component.

    This component encapsulates the local oscillator and mixer used to upconvert or
    downconvert an RF signal.

    The FrequencyConverter component is attached to IQ channels through

    - `IQChannel.frequency_converter_up`
    - `InOutIQChannel.frequency_converter_down`

    Args:
        local_oscillator (LocalOscillator): The local oscillator for the frequency converter.
        mixer (Mixer): The mixer for the frequency converter.
        gain (float): The gain of the frequency converter.
    """

    local_oscillator: LocalOscillator = None
    mixer: Mixer = None
    gain: float = None

    @property
    def LO_frequency(self):
        return self.local_oscillator.frequency

    def configure(self):
        if self.local_oscillator is not None:
            self.local_oscillator.configure()

LocalOscillator

Bases: QuamComponent

QuAM component for a local oscillator.

Parameters:

Name Type Description Default
frequency float

The frequency of the local oscillator. Used by the mixer to determine the intermediate frequency.

required
power float

The power of the local oscillator. Not used for the QUA configuration

required
Source code in quam/components/hardware.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@quam_dataclass
class LocalOscillator(QuamComponent):
    """QuAM component for a local oscillator.

    Args:
        frequency (float): The frequency of the local oscillator.
            Used by the mixer to determine the intermediate frequency.
        power (float, optional): The power of the local oscillator.
            Not used for the QUA configuration
    """

    frequency: float = None
    power: float = None

    def configure(self): ...

Mixer

Bases: QuamComponent

QuAM component for a mixer.

All properties are optional, so it can be instantiated as Mixer(). For the default values, it is assumed that the mixer parent is an IQChannel that has a LocalOscillator.

Parameters:

Name Type Description Default
local_oscillator_frequency float

The frequency of the local oscillator. Default is #../local_oscillator/frequency, meaning that the frequency is extracted from the the local_oscillator of the parent.

required
intermediate_frequency float

The intermediate frequency of the mixer. Default is #../intermediate_frequency, meaning that the frequency references the intermediate_frequency of the parent.

required
correction_gain float

The gain imbalance of the mixer. Default is 0, see Mixer.IQ_imbalance for details.

required
correction_phase float

The phase imbalance of the mixer in radians.

required
Source code in quam/components/hardware.py
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@quam_dataclass
class Mixer(QuamComponent):
    """QuAM component for a mixer.

    All properties are optional, so it can be instantiated as `Mixer()`.
    For the default values, it is assumed that the mixer parent is an `IQChannel`
    that has a `LocalOscillator`.

    Args:
        local_oscillator_frequency (float, optional): The frequency of the local
            oscillator. Default is `#../local_oscillator/frequency`, meaning that
            the frequency is extracted from the the local_oscillator of the parent.
        intermediate_frequency (float, optional): The intermediate frequency of the
            mixer. Default is `#../intermediate_frequency`, meaning that the frequency
            references the intermediate_frequency of the parent.
        correction_gain (float, optional): The gain imbalance of the mixer.
            Default is 0, see `Mixer.IQ_imbalance` for details.
        correction_phase (float, optional): The phase imbalance of the mixer in radians.
    """

    local_oscillator_frequency: float = "#../local_oscillator/frequency"
    intermediate_frequency: float = "#../../intermediate_frequency"

    correction_gain: float = 0
    correction_phase: float = 0

    @property
    def name(self):
        frequency_converter = getattr(self, "parent", None)
        if frequency_converter is None:
            raise AttributeError(
                f"Mixer.parent must be a frequency converter for {self}"
            )

        channel = getattr(frequency_converter, "parent", None)
        channel_name = getattr(channel, "name", None)
        if channel is None or channel_name is None:
            raise AttributeError(f"Mixer.parent.parent must be a channel for {self}")

        return f"{channel_name}{str_ref.DELIMITER}mixer"

    def apply_to_config(self, config: dict):
        """Adds this mixer to the QUA configuration.

        See [`QuamComponent.apply_to_config`][quam.core.quam_classes.QuamComponent.apply_to_config]
        for details.
        """
        correction_matrix = self.IQ_imbalance(
            self.correction_gain, self.correction_phase
        )

        config["mixers"][self.name] = [
            {
                "intermediate_frequency": self.intermediate_frequency,
                "lo_frequency": self.local_oscillator_frequency,
                "correction": correction_matrix,
            }
        ]

    @staticmethod
    def IQ_imbalance(g: float, phi: float) -> List[float]:
        """
        Creates the correction matrix for the mixer imbalance caused by the gain and
        phase imbalances, more information can be seen here:
        https://docs.qualang.io/libs/examples/mixer-calibration/#non-ideal-mixer
        :param g: relative gain imbalance between the I & Q ports. (unit-less),
            set to 0 for no gain imbalance.
        :param phi: relative phase imbalance between the I & Q ports (radians),
            set to 0 for no phase imbalance.
        """
        c = np.cos(phi)
        s = np.sin(phi)
        N = 1 / ((1 - g**2) * (2 * c**2 - 1))
        return [
            float(N * x) for x in [(1 - g) * c, (1 + g) * s, (1 - g) * s, (1 + g) * c]
        ]

IQ_imbalance(g, phi) staticmethod

Creates the correction matrix for the mixer imbalance caused by the gain and phase imbalances, more information can be seen here: https://docs.qualang.io/libs/examples/mixer-calibration/#non-ideal-mixer :param g: relative gain imbalance between the I & Q ports. (unit-less), set to 0 for no gain imbalance. :param phi: relative phase imbalance between the I & Q ports (radians), set to 0 for no phase imbalance.

Source code in quam/components/hardware.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@staticmethod
def IQ_imbalance(g: float, phi: float) -> List[float]:
    """
    Creates the correction matrix for the mixer imbalance caused by the gain and
    phase imbalances, more information can be seen here:
    https://docs.qualang.io/libs/examples/mixer-calibration/#non-ideal-mixer
    :param g: relative gain imbalance between the I & Q ports. (unit-less),
        set to 0 for no gain imbalance.
    :param phi: relative phase imbalance between the I & Q ports (radians),
        set to 0 for no phase imbalance.
    """
    c = np.cos(phi)
    s = np.sin(phi)
    N = 1 / ((1 - g**2) * (2 * c**2 - 1))
    return [
        float(N * x) for x in [(1 - g) * c, (1 + g) * s, (1 - g) * s, (1 + g) * c]
    ]

apply_to_config(config)

Adds this mixer to the QUA configuration.

See QuamComponent.apply_to_config for details.

Source code in quam/components/hardware.py
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def apply_to_config(self, config: dict):
    """Adds this mixer to the QUA configuration.

    See [`QuamComponent.apply_to_config`][quam.core.quam_classes.QuamComponent.apply_to_config]
    for details.
    """
    correction_matrix = self.IQ_imbalance(
        self.correction_gain, self.correction_phase
    )

    config["mixers"][self.name] = [
        {
            "intermediate_frequency": self.intermediate_frequency,
            "lo_frequency": self.local_oscillator_frequency,
            "correction": correction_matrix,
        }
    ]