From 0dae7469b93235a5f15948ba4e7299c872219c7d Mon Sep 17 00:00:00 2001 From: Serwan Asaad Date: Tue, 2 Jul 2024 07:41:20 +0200 Subject: [PATCH] fully working tests --- quam/components/channels.py | 5 ++- quam/components/ports/analog_inputs.py | 2 + quam/components/ports/analog_outputs.py | 3 ++ quam/components/ports/base_ports.py | 15 +++++-- .../channels/test_in_out_IQ_channel.py | 18 ++++----- .../channels/test_in_out_single_channel.py | 5 +-- .../channels/test_in_single_channel.py | 4 +- .../channels/test_in_single_out_IQ_channel.py | 8 ++-- .../channels/test_single_channel.py | 19 +++++---- .../ports/test_lf_fem_analog_ports.py | 6 ++- .../ports/test_mw_fem_analog_ports.py | 2 + .../superconducting_qubits/test_transmon.py | 39 ++++++++++++++----- 12 files changed, 81 insertions(+), 45 deletions(-) diff --git a/quam/components/channels.py b/quam/components/channels.py index 671f1a74..aff44088 100644 --- a/quam/components/channels.py +++ b/quam/components/channels.py @@ -1018,7 +1018,8 @@ def apply_to_config(self, config: dict): opx_port = LFFEMAnalogOutputPort(*opx_output, offset=offset) opx_port.apply_to_config(config) - element_cfg["mixInputs"][I_or_Q] = opx_port.port_tuple + if "mixInputs" in element_cfg: + element_cfg["mixInputs"][I_or_Q] = opx_port.port_tuple @quam_dataclass @@ -1054,7 +1055,7 @@ class InIQChannel(Channel): opx_input_offset_I: float = None opx_input_offset_Q: float = None - input_gain: Optional[float] = None + input_gain: Optional[int] = None frequency_converter_down: BaseFrequencyConverter = None diff --git a/quam/components/ports/analog_inputs.py b/quam/components/ports/analog_inputs.py index b7d1675a..10999928 100644 --- a/quam/components/ports/analog_inputs.py +++ b/quam/components/ports/analog_inputs.py @@ -15,6 +15,7 @@ @quam_dataclass class LFAnalogInputPort(BasePort, ABC): + fem_type: ClassVar[str] = "LF" port_type: ClassVar[str] = "analog_input" offset: Optional[float] = None @@ -48,6 +49,7 @@ def get_port_properties(self) -> Dict[str, Any]: @quam_dataclass class MWFEMAnalogInputPort(FEMPort): + fem_type: ClassVar[str] = "MW" port_type: ClassVar[str] = "analog_input" band: int diff --git a/quam/components/ports/analog_outputs.py b/quam/components/ports/analog_outputs.py index f0c4c584..4d1954ee 100644 --- a/quam/components/ports/analog_outputs.py +++ b/quam/components/ports/analog_outputs.py @@ -15,6 +15,7 @@ @quam_dataclass class LFAnalogOutputPort(BasePort, ABC): + fem_type: ClassVar[str] = "LF" port_type: ClassVar[str] = "analog_output" offset: Optional[float] = None @@ -47,6 +48,7 @@ class OPXPlusAnalogOutputPort(LFAnalogOutputPort, OPXPlusPort): @quam_dataclass class LFFEMAnalogOutputPort(LFAnalogOutputPort, FEMPort): + fem_type: ClassVar[str] = "LF" sampling_rate: float = 1e9 # Either 1e9 or 2e9 upsampling_mode: Literal["mw", "pulse"] = "mw" output_mode: Literal["direct", "amplified"] = "direct" @@ -61,6 +63,7 @@ def get_port_properties(self) -> Dict[str, Any]: @quam_dataclass class MWFEMAnalogOutputPort(FEMPort): + fem_type: ClassVar[str] = "MW" port_type: ClassVar[str] = "analog_output" band: int diff --git a/quam/components/ports/base_ports.py b/quam/components/ports/base_ports.py index cef03c05..f9756d9e 100644 --- a/quam/components/ports/base_ports.py +++ b/quam/components/ports/base_ports.py @@ -33,9 +33,9 @@ def _update_port_config(self, port_config, port_properties): if key in port_config and value != port_config[key]: warnings.warn( f"Error generating QUA config: Controller {self.port_type} " - f"port {self.port_tuple} already has entry for {key}. This likely " - f"means that the port is being configured multiple times. " - f"Overwriting {port_config['key']} → {value}." + f"port {self.port_tuple} already has entry for {key}. This " + f"likely means that the port is being configured multiple " + f"times. Overwriting {port_config[key]} → {value}." ) except Exception: pass @@ -80,6 +80,7 @@ def get_port_config( @quam_dataclass class FEMPort(BasePort, ABC): + fem_type: ClassVar[str] controller_id: Union[str, int] fem_id: int port_id: int @@ -113,6 +114,14 @@ def get_port_config( controller_cfg = config["controllers"].setdefault(self.controller_id, {}) fems_cfg = controller_cfg.setdefault("fems", {}) fem_cfg = fems_cfg.setdefault(self.fem_id, {}) + if hasattr(self, "fem_type"): + if fem_cfg.get("type", self.fem_type) != self.fem_type: + raise ValueError( + f"Error generating config: FEM {self.fem_id} is not of type " + f"{self.fem_type}" + ) + fem_cfg["type"] = self.fem_type + ports_cfg = fem_cfg.setdefault(f"{self.port_type}s", {}) port_cfg = ports_cfg.setdefault(self.port_id, {}) return port_cfg diff --git a/tests/components/channels/test_in_out_IQ_channel.py b/tests/components/channels/test_in_out_IQ_channel.py index 65caa52f..54088de9 100644 --- a/tests/components/channels/test_in_out_IQ_channel.py +++ b/tests/components/channels/test_in_out_IQ_channel.py @@ -64,14 +64,13 @@ def test_empty_in_out_IQ_channel(): "controllers": { "con1": { "analog_inputs": { - 3: {}, - 4: {}, + 3: {"gain_db": 0, "shareable": False}, + 4: {"gain_db": 0, "shareable": False}, }, "analog_outputs": { - 1: {}, - 2: {}, + 1: {"delay": 0, "shareable": False}, + 2: {"delay": 0, "shareable": False}, }, - "digital_outputs": {}, } }, "elements": { @@ -159,14 +158,13 @@ def test_readout_resonator_with_readout(): "controllers": { "con1": { "analog_inputs": { - 3: {}, - 4: {}, + 3: {"gain_db": 0, "shareable": False}, + 4: {"gain_db": 0, "shareable": False}, }, "analog_outputs": { - 1: {}, - 2: {}, + 1: {"delay": 0, "shareable": False}, + 2: {"delay": 0, "shareable": False}, }, - "digital_outputs": {}, } }, "elements": { diff --git a/tests/components/channels/test_in_out_single_channel.py b/tests/components/channels/test_in_out_single_channel.py index cff1eb0b..5b88d730 100644 --- a/tests/components/channels/test_in_out_single_channel.py +++ b/tests/components/channels/test_in_out_single_channel.py @@ -30,9 +30,8 @@ def test_in_out_single_channel(): expected_cfg = { "controllers": { "con1": { - "analog_inputs": {2: {}}, - "analog_outputs": {1: {}}, - "digital_outputs": {}, + "analog_inputs": {2: {"gain_db": 0, "shareable": False}}, + "analog_outputs": {1: {"delay": 0, "shareable": False}}, } }, "elements": { diff --git a/tests/components/channels/test_in_single_channel.py b/tests/components/channels/test_in_single_channel.py index b7b48b50..c0c3854e 100644 --- a/tests/components/channels/test_in_single_channel.py +++ b/tests/components/channels/test_in_single_channel.py @@ -23,10 +23,8 @@ def test_generate_config(qua_config): assert qua_config["controllers"] == { "con1": { "analog_inputs": { - 1: {}, + 1: {"gain_db": 0, "shareable": False}, }, - "analog_outputs": {}, - "digital_outputs": {}, } } diff --git a/tests/components/channels/test_in_single_out_IQ_channel.py b/tests/components/channels/test_in_single_out_IQ_channel.py index b0ac736c..13df4390 100644 --- a/tests/components/channels/test_in_single_out_IQ_channel.py +++ b/tests/components/channels/test_in_single_out_IQ_channel.py @@ -39,10 +39,12 @@ def test_generate_config(qua_config): assert qua_config["controllers"] == { "con1": { "analog_inputs": { - 1: {}, + 1: {"gain_db": 0, "shareable": False}, + }, + "analog_outputs": { + 1: {"delay": 0, "shareable": False}, + 2: {"delay": 0, "shareable": False}, }, - "analog_outputs": {1: {}, 2: {}}, - "digital_outputs": {}, } } diff --git a/tests/components/channels/test_single_channel.py b/tests/components/channels/test_single_channel.py index a9f9433a..f3caccf7 100644 --- a/tests/components/channels/test_single_channel.py +++ b/tests/components/channels/test_single_channel.py @@ -33,9 +33,7 @@ def test_single_channel_offset(bare_cfg): expected_cfg = { "controllers": { "con1": { - "analog_inputs": {}, - "digital_outputs": {}, - "analog_outputs": {1: {}}, + "analog_outputs": {1: {"delay": 0, "shareable": False}}, } }, "elements": { @@ -61,21 +59,24 @@ def test_single_channel_differing_offsets(bare_cfg): cfg = deepcopy(bare_cfg) channel1.apply_to_config(cfg) channel2.apply_to_config(cfg) - assert cfg["controllers"]["con1"]["analog_outputs"][1] == {} + assert cfg["controllers"]["con1"]["analog_outputs"][1] == { + "delay": 0, + "shareable": False, + } channel1.opx_output_offset = 0.1 cfg = deepcopy(bare_cfg) channel1.apply_to_config(cfg) channel2.apply_to_config(cfg) - assert cfg["controllers"]["con1"]["analog_outputs"][1] == {"offset": 0.1} + assert cfg["controllers"]["con1"]["analog_outputs"][1]["offset"] == 0.1 channel2.opx_output_offset = 0.1 cfg = deepcopy(bare_cfg) channel1.apply_to_config(cfg) channel2.apply_to_config(cfg) - assert cfg["controllers"]["con1"]["analog_outputs"][1] == {"offset": 0.1} + assert cfg["controllers"]["con1"]["analog_outputs"][1]["offset"] == 0.1 channel2.opx_output_offset = 0.2 @@ -88,7 +89,7 @@ def test_single_channel_differing_offsets(bare_cfg): channel1.apply_to_config(cfg) channel2.opx_output_offset = 0.1 + 0.5e-4 channel2.apply_to_config(cfg) - assert cfg["controllers"]["con1"]["analog_outputs"][1] == {"offset": 0.1 + 0.5e-4} + assert cfg["controllers"]["con1"]["analog_outputs"][1]["offset"] == 0.1 + 0.5e-4 def test_single_channel_offset_quam(qua_config): @@ -103,9 +104,7 @@ class QuamTest(QuamRoot): qua_config["controllers"] = { "con1": { - "analog_inputs": {}, - "digital_outputs": {}, - "analog_outputs": {1: {"offset": 0.0}}, + "analog_outputs": {1: {"delay": 0, "shareable": False, "offset": 0.0}}, } } qua_config["elements"] = { diff --git a/tests/components/ports/test_lf_fem_analog_ports.py b/tests/components/ports/test_lf_fem_analog_ports.py index 193ddb76..8d9cbfad 100644 --- a/tests/components/ports/test_lf_fem_analog_ports.py +++ b/tests/components/ports/test_lf_fem_analog_ports.py @@ -46,6 +46,7 @@ def test_lf_fem_analog_output_port(): "con1": { "fems": { 1: { + "type": "LF", "analog_outputs": { 2: { "delay": 0, @@ -54,7 +55,7 @@ def test_lf_fem_analog_output_port(): "sampling_rate": 1e9, "upsampling_mode": "mw", } - } + }, } } } @@ -108,13 +109,14 @@ def test_lf_fem_analog_input_port(): "con1": { "fems": { 1: { + "type": "LF", "analog_inputs": { 2: { "gain_db": 0, "shareable": False, "sampling_rate": 1e9, } - } + }, } } } diff --git a/tests/components/ports/test_mw_fem_analog_ports.py b/tests/components/ports/test_mw_fem_analog_ports.py index aae30a92..46043843 100644 --- a/tests/components/ports/test_mw_fem_analog_ports.py +++ b/tests/components/ports/test_mw_fem_analog_ports.py @@ -53,6 +53,7 @@ def test_mw_fem_analog_output_port(): "con1": { "fems": { 1: { + "type": "MW", "analog_outputs": { 2: { "band": 1, @@ -112,6 +113,7 @@ def test_mw_fem_analog_input_ports(): "con1": { "fems": { 1: { + "type": "MW", "analog_inputs": { 2: { "band": 1, diff --git a/tests/examples/superconducting_qubits/test_transmon.py b/tests/examples/superconducting_qubits/test_transmon.py index 26e3cf70..4689935c 100644 --- a/tests/examples/superconducting_qubits/test_transmon.py +++ b/tests/examples/superconducting_qubits/test_transmon.py @@ -63,9 +63,10 @@ def test_transmon_xy(): }, "controllers": { "con1": { - "analog_outputs": {1: {}, 2: {}}, - "digital_outputs": {}, - "analog_inputs": {}, + "analog_outputs": { + 1: {"delay": 0, "shareable": False}, + 2: {"delay": 0, "shareable": False}, + }, } }, } @@ -121,9 +122,22 @@ def test_transmon_xy_opx1000(): "fems": { 2: { "type": "LF", - "analog_outputs": {1: {}, 2: {}}, - "digital_outputs": {}, - "analog_inputs": {}, + "analog_outputs": { + 1: { + "delay": 0, + "shareable": False, + "sampling_rate": 1e9, + "upsampling_mode": "mw", + "output_mode": "direct", + }, + 2: { + "delay": 0, + "shareable": False, + "sampling_rate": 1e9, + "upsampling_mode": "mw", + "output_mode": "direct", + }, + }, } } } @@ -182,9 +196,16 @@ def test_transmon_add_pulse(): assert config == { "controllers": { "con1": { - "analog_outputs": {1: {}, 2: {}}, - "digital_outputs": {}, - "analog_inputs": {}, + "analog_outputs": { + 1: { + "delay": 0, + "shareable": False, + }, + 2: { + "delay": 0, + "shareable": False, + }, + }, } }, "elements": {