Skip to content

Commit

Permalink
Added channel tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nulinspiratie committed Jul 2, 2024
1 parent 0dae746 commit d280572
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Explore detailed documentation and get started with QuAM here: [QuAM Documentati
- **State Management**: Features robust tools for saving and loading your quantum states, promoting reproducibility and consistency.

## Installation
To install QuAM, first ensure you have Python 3.8 installed on your system.
To install QuAM, first ensure you have 3.8 ≤ Python 3.11 installed on your system.
Then run the following command:

```bash
Expand Down
67 changes: 67 additions & 0 deletions tests/components/channels/test_IQ_channel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
from quam.components import IQChannel
from quam.components.ports.analog_outputs import OPXPlusAnalogOutputPort


def test_IQ_channel_set_dc_offset(mocker):
Expand Down Expand Up @@ -88,3 +89,69 @@ def test_IQ_channel_inferred_LO_frequency():
channel.intermediate_frequency = None
with pytest.raises(AttributeError):
channel.inferred_LO_frequency


def test_generate_config(qua_config):
channel = IQChannel(
id="out_channel",
opx_output_I=("con1", 1),
opx_output_Q=("con1", 2),
frequency_converter_up=None,
)

channel.apply_to_config(qua_config)
channel.opx_output_I.apply_to_config(qua_config)
channel.opx_output_Q.apply_to_config(qua_config)

assert qua_config["controllers"] == {
"con1": {
"analog_outputs": {
1: {"delay": 0, "shareable": False},
2: {"delay": 0, "shareable": False},
},
}
}

assert qua_config["elements"] == {
"out_channel": {
"intermediate_frequency": 0.0,
"mixInputs": {
"I": ("con1", 1),
"Q": ("con1", 2),
},
"operations": {},
}
}


def test_generate_config_ports(qua_config):
channel = IQChannel(
id="out_channel",
opx_output_I=OPXPlusAnalogOutputPort("con1", 1),
opx_output_Q=OPXPlusAnalogOutputPort("con1", 2),
frequency_converter_up=None,
)

channel.apply_to_config(qua_config)
channel.opx_output_I.apply_to_config(qua_config)
channel.opx_output_Q.apply_to_config(qua_config)

assert qua_config["controllers"] == {
"con1": {
"analog_outputs": {
1: {"delay": 0, "shareable": False},
2: {"delay": 0, "shareable": False},
},
}
}

assert qua_config["elements"] == {
"out_channel": {
"intermediate_frequency": 0.0,
"mixInputs": {
"I": ("con1", 1),
"Q": ("con1", 2),
},
"operations": {},
}
}
31 changes: 30 additions & 1 deletion tests/components/channels/test_digital_channel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from copy import deepcopy
from quam.components import Channel, DigitalOutputChannel, pulses
from quam.components.ports.digital_outputs import OPXPlusDigitalOutputPort
from quam.core import QuamRoot, quam_dataclass
from quam.core.quam_instantiation import instantiate_quam_class

Expand All @@ -18,14 +19,42 @@ def test_digital_only_channel(qua_config):
quam = QuamTest(channel=channel)
cfg = quam.generate_config()

qua_config["controllers"] = {"con1": {"digital_outputs": {1: {"inverted": False, "shareable": False}}}}
qua_config["controllers"] = {
"con1": {"digital_outputs": {1: {"inverted": False, "shareable": False}}}
}
qua_config["elements"] = {
"channel": {"digitalInputs": {"1": {"port": ("con1", 1)}}, "operations": {}}
}

assert cfg == qua_config


def test_digital_only_channel_with_port(qua_config):

channel = Channel(
id="channel",
digital_outputs={
"1": DigitalOutputChannel(
opx_output=OPXPlusDigitalOutputPort(
"con1", 2, inverted=True, shareable=True
)
)
},
)

quam = QuamTest(channel=channel)
cfg = quam.generate_config()

qua_config["controllers"] = {
"con1": {"digital_outputs": {2: {"inverted": True, "shareable": True}}}
}
qua_config["elements"] = {
"channel": {"digitalInputs": {"1": {"port": ("con1", 2)}}, "operations": {}}
}

assert cfg == qua_config


def test_digital_only_pulse(qua_config):
channel = Channel(
id="channel",
Expand Down
37 changes: 37 additions & 0 deletions tests/components/channels/test_in_IQ_out_single_channel.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from quam.components.channels import InIQOutSingleChannel
from quam.components.ports.analog_inputs import OPXPlusAnalogInputPort
from quam.components.ports.analog_outputs import OPXPlusAnalogOutputPort
from quam.utils.dataclass import get_dataclass_attr_annotations


Expand Down Expand Up @@ -56,3 +58,38 @@ def test_generate_config(qua_config):
"time_of_flight": 24,
}
}


def test_generate_config_ports(qua_config):
channel = InIQOutSingleChannel(
id="in_out_channel",
opx_output=OPXPlusAnalogOutputPort("con1", 1),
opx_input_I=OPXPlusAnalogInputPort("con1", 1),
opx_input_Q=OPXPlusAnalogInputPort("con1", 2),
frequency_converter_down=None,
)

channel.apply_to_config(qua_config)
channel.opx_output.apply_to_config(qua_config)
channel.opx_input_I.apply_to_config(qua_config)
channel.opx_input_Q.apply_to_config(qua_config)

assert qua_config["controllers"] == {
"con1": {
"analog_inputs": {
1: {"gain_db": 0, "shareable": False},
2: {"gain_db": 0, "shareable": False},
},
"analog_outputs": {1: {"delay": 0, "shareable": False}},
}
}

assert qua_config["elements"] == {
"in_out_channel": {
"operations": {},
"outputs": {"out1": ("con1", 1), "out2": ("con1", 2)},
"singleInput": {"port": ("con1", 1)},
"smearing": 0,
"time_of_flight": 24,
}
}
128 changes: 128 additions & 0 deletions tests/components/channels/test_in_out_IQ_channel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
from quam.components import *
from quam.components.ports.analog_inputs import OPXPlusAnalogInputPort
from quam.components.ports.analog_outputs import OPXPlusAnalogOutputPort


def test_empty_in_out_IQ_channel():
Expand Down Expand Up @@ -254,3 +256,129 @@ def test_channel_measure(mocker):
mocker.patch("quam.components.channels.measure", return_value=1)
result = readout_resonator.measure("readout")
assert result == (1, 1)


def test_empty_in_out_IQ_channel_ports():
readout_resonator = InOutIQChannel(
frequency_converter_up=FrequencyConverter(
mixer=Mixer(), local_oscillator=LocalOscillator()
),
opx_output_I=OPXPlusAnalogOutputPort("con1", 1),
opx_output_Q=OPXPlusAnalogOutputPort("con1", 2),
opx_input_I=OPXPlusAnalogInputPort("con1", 3),
opx_input_Q=OPXPlusAnalogInputPort("con1", 4),
intermediate_frequency=100e6,
)

assert isinstance(readout_resonator.frequency_converter_up.mixer, Mixer)

assert isinstance(readout_resonator.local_oscillator, LocalOscillator)
assert (
readout_resonator.frequency_converter_up.local_oscillator
is readout_resonator.local_oscillator
)

mixer = readout_resonator.frequency_converter_up.mixer
assert mixer.intermediate_frequency == 100e6

assert mixer.local_oscillator_frequency is None
readout_resonator.local_oscillator.frequency = 5e9
assert mixer.local_oscillator_frequency == 5e9

with pytest.raises(AttributeError):
mixer.name
assert readout_resonator.id is None
with pytest.raises(AttributeError):
readout_resonator.name

readout_resonator.id = 1

d = readout_resonator.to_dict()
assert d == {
"frequency_converter_up": {
"__class__": "quam.components.hardware.FrequencyConverter",
"mixer": {},
"local_oscillator": {"frequency": 5000000000.0},
},
"opx_output_I": {
"controller_id": "con1",
"port_id": 1,
"__class__": "quam.components.ports.analog_outputs.OPXPlusAnalogOutputPort",
},
"opx_output_Q": {
"controller_id": "con1",
"port_id": 2,
"__class__": "quam.components.ports.analog_outputs.OPXPlusAnalogOutputPort",
},
"opx_input_I": {
"controller_id": "con1",
"port_id": 3,
"__class__": "quam.components.ports.analog_inputs.OPXPlusAnalogInputPort",
},
"opx_input_Q": {
"controller_id": "con1",
"port_id": 4,
"__class__": "quam.components.ports.analog_inputs.OPXPlusAnalogInputPort",
},
"intermediate_frequency": 100000000.0,
"id": 1,
}

bare_cfg = {
"controllers": {},
"elements": {},
"pulses": {},
"waveforms": {},
"integration_weights": {},
}
cfg = bare_cfg.copy()
expected_cfg = {
"controllers": {
"con1": {
"analog_inputs": {
3: {"gain_db": 0, "shareable": False},
4: {"gain_db": 0, "shareable": False},
},
"analog_outputs": {
1: {"delay": 0, "shareable": False},
2: {"delay": 0, "shareable": False},
},
}
},
"elements": {
"IQ1": {
"intermediate_frequency": 100000000.0,
"mixInputs": {
"I": ("con1", 1),
"Q": ("con1", 2),
"lo_frequency": 5000000000.0,
"mixer": "IQ1.mixer",
},
"operations": {},
"outputs": {"out1": ("con1", 3), "out2": ("con1", 4)},
"smearing": 0,
"time_of_flight": 24,
}
},
"pulses": {},
"waveforms": {},
"integration_weights": {},
}
readout_resonator.apply_to_config(cfg)
readout_resonator.opx_output_I.apply_to_config(cfg)
readout_resonator.opx_output_Q.apply_to_config(cfg)
readout_resonator.opx_input_I.apply_to_config(cfg)
readout_resonator.opx_input_Q.apply_to_config(cfg)
assert cfg == expected_cfg

cfg = bare_cfg.copy()
readout_resonator._default_label = "res"
readout_resonator.apply_to_config(cfg)
expected_cfg["elements"]["res1"] = expected_cfg["elements"].pop("IQ1")
expected_cfg["elements"]["res1"]["mixInputs"]["mixer"] = "IQ1.mixer"

cfg = bare_cfg.copy()
readout_resonator.id = "resonator_1"
readout_resonator.apply_to_config(cfg)
expected_cfg["elements"]["resonator_1"] = expected_cfg["elements"].pop("res1")
expected_cfg["elements"]["resonator_1"]["mixInputs"]["mixer"] = "resonator_1.mixer"
36 changes: 36 additions & 0 deletions tests/components/channels/test_in_out_single_channel.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
from quam.components import *
from quam.components.ports.analog_inputs import OPXPlusAnalogInputPort
from quam.components.ports.analog_outputs import OPXPlusAnalogOutputPort


def test_in_out_single_channel_empty_error():
Expand Down Expand Up @@ -46,3 +48,37 @@ def test_in_out_single_channel():
}

assert cfg == expected_cfg


def test_in_out_single_channel_ports():
channel = InOutSingleChannel(
id=1,
opx_output=OPXPlusAnalogOutputPort("con1", 1),
opx_input=OPXPlusAnalogInputPort("con1", 2),
)

cfg = {"controllers": {}, "elements": {}}

channel.apply_to_config(cfg)
channel.opx_output.apply_to_config(cfg)
channel.opx_input.apply_to_config(cfg)

expected_cfg = {
"controllers": {
"con1": {
"analog_inputs": {2: {"gain_db": 0, "shareable": False}},
"analog_outputs": {1: {"delay": 0, "shareable": False}},
}
},
"elements": {
"ch1": {
"operations": {},
"outputs": {"out1": ("con1", 2)},
"singleInput": {"port": ("con1", 1)},
"smearing": 0,
"time_of_flight": 24,
}
},
}

assert cfg == expected_cfg
Loading

0 comments on commit d280572

Please sign in to comment.