Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qhc 848 support iq modulation for r&s sgs100 a #872

Open
wants to merge 23 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
329ffdb
raise an error if qdac input values are outside of the range
flavie-lebars Jan 8, 2025
b2673d8
added two other ways to prevent the out of bound values and unit tests
flavie-lebars Jan 8, 2025
0d08589
change log
flavie-lebars Jan 8, 2025
fb85ac7
unit test to cover all the tested code and added bounds as private class
flavie-lebars Jan 9, 2025
eea30f8
code format
flavie-lebars Jan 9, 2025
8ca9e91
Merge branch 'main' into QHC-840-Limit-QDAC-and-SPI-ramping-rate
flavie-lebars Jan 9, 2025
0c54472
renamed variable, removed comments and unused imports
flavie-lebars Jan 10, 2025
5d64236
Code to enable the IQ mixer feature already part of qcode in qililab
flavie-lebars Jan 15, 2025
7fdf2fe
document the change
flavie-lebars Jan 15, 2025
5a3c4a4
included the IQ state in the runcard
flavie-lebars Jan 15, 2025
9aa870c
Updated the chanhelog
flavie-lebars Jan 15, 2025
389b012
updated change log
flavie-lebars Jan 15, 2025
e9ff014
Merge branch 'main' into QHC-848-Support-IQ-modulation-for-R&S-SGS100A
flavie-lebars Jan 15, 2025
21c20bd
removed IQ state from a runcard
flavie-lebars Jan 15, 2025
b32b5da
Merge branch 'QHC-848-Support-IQ-modulation-for-R&S-SGS100A' of https…
flavie-lebars Jan 15, 2025
dee0a06
added IQ state to runcards
flavie-lebars Jan 16, 2025
833e917
added iq state to runcards
flavie-lebars Jan 16, 2025
4079b22
added iq state to fix the code coverage
flavie-lebars Jan 16, 2025
c16eb28
changed variable name from iq state to hardare_modulation for more co…
flavie-lebars Jan 16, 2025
c348bca
Fixed a typo in a runcard
flavie-lebars Jan 16, 2025
2ae8d74
Merge branch 'main' into QHC-848-Support-IQ-modulation-for-R&S-SGS100A
flavie-lebars Jan 16, 2025
043f8b6
debugged the code following failed physical tests
flavie-lebars Feb 4, 2025
9941995
Merge branch 'main' into QHC-848-Support-IQ-modulation-for-R&S-SGS100A
flavie-lebars Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/releases/changelog-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@
Each chunk duration is restricted to the range (\[100, 500\]) ns, ensuring that chunks are neither too small (leading to excessive repetitions) nor too large (risking out-of-memory issues). If no duration within (\[100, 500\]) ns meets these remainder constraints, the compiler defaults to using the original waveform in its entirety.
[#861](https://github.com/qilimanjaro-tech/qililab/pull/861)

-Raises an error when the inputed value for the QDAC is outside of the bounds provided by QM. Done in 3 ways, runcard, set_parameter RAMPING_ENABLED and set_parameter RAMPING_RATE.
- Raises an error when the inputed value for the QDAC is outside of the bounds provided by QM. Done in 3 ways, runcard, set_parameter RAMPING_ENABLED and set_parameter RAMPING_RATE.
[#865](https://github.com/qilimanjaro-tech/qililab/pull/865)

- Code to enable the IQ mixer feature already part of qcode in qililab for the rohde and schwarz SGS100a
[#872](https://github.com/qilimanjaro-tech/qililab/pull/872)


### Improvements

Expand Down
19 changes: 19 additions & 0 deletions src/qililab/instruments/rohde_schwarz/sgs100a.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class SGS100ASettings(Instrument.InstrumentSettings):
power: float
frequency: float
rf_on: bool
hardware_modulation: bool

settings: SGS100ASettings
device: RohdeSchwarzSGS100A
Expand Down Expand Up @@ -78,6 +79,15 @@ def rf_on(self):
"""
return self.settings.rf_on

@property
def hardware_modulation(self):
"""SignalGenerator 'IQ state' property.

Returns:
bool: settings.hardware_modulation.
"""
return self.settings.hardware_modulation

def to_dict(self):
"""Return a dict representation of the SignalGenerator class."""
return dict(super().to_dict().items())
Expand Down Expand Up @@ -106,6 +116,12 @@ def set_parameter(self, parameter: Parameter, value: ParameterValue, channel_id:
else:
self.turn_off()
return
if parameter == Parameter.HARDWARE_MODULATION:
value = bool(value)
self.settings.hardware_modulation = value
if self.is_device_active():
self.device.IQ_state(value)
return
raise ParameterNotFound(self, parameter)

def get_parameter(self, parameter: Parameter, channel_id: ChannelID | None = None) -> ParameterValue:
Expand All @@ -115,13 +131,16 @@ def get_parameter(self, parameter: Parameter, channel_id: ChannelID | None = Non
return self.settings.frequency
if parameter == Parameter.RF_ON:
return self.settings.rf_on
if parameter == Parameter.HARDWARE_MODULATION:
return self.settings.hardware_modulation
raise ParameterNotFound(self, parameter)

@check_device_initialized
def initial_setup(self):
"""performs an initial setup"""
self.device.power(self.power)
self.device.frequency(self.frequency)
self.device.hardware_modulation(self.hardware_modulation)
if self.rf_on:
self.device.on()
else:
Expand Down
1 change: 1 addition & 0 deletions tests/calibration/galadriel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ instruments:
power: 16
frequency: 8.0726e+09
rf_on: true
hardware_modulation: true
- name: mini_circuits
alias: attenuator
attenuation: 32
Expand Down
6 changes: 6 additions & 0 deletions tests/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class Galadriel:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 7.24730e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

rohde_schwarz_controller_1: dict[str, Any] = {
Expand All @@ -478,6 +479,7 @@ class Galadriel:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 3.351e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

attenuator_controller_0: dict[str, Any] = {
Expand Down Expand Up @@ -621,6 +623,7 @@ class SauronYokogawa:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 7.24730e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

yokogawa_gs200_current_controller = {
Expand Down Expand Up @@ -709,6 +712,7 @@ class SauronSpiRack:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 7.24730e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

spi_rack_controller_usb = {
Expand Down Expand Up @@ -779,6 +783,7 @@ class SauronQDevil:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 7.24730e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

qdevil_qdac2_controller_ip = {
Expand Down Expand Up @@ -1276,6 +1281,7 @@ class SauronQuantumMachines:
Parameter.POWER.value: 15,
Parameter.LO_FREQUENCY.value: 7.24730e09,
Parameter.RF_ON.value: True,
Parameter.HARDWARE_MODULATION.value: True,
}

qmm_controller_wrong_module = {
Expand Down
1 change: 1 addition & 0 deletions tests/instrument_controllers/qblox/qblox_runcard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ instruments:
power: 15
frequency: 7e9
rf_on: True
hardware_modulation: True

instrument_controllers:
- name: qblox_cluster
Expand Down
27 changes: 24 additions & 3 deletions tests/instruments/rohde_schwarz/test_rohde_schwarz_sgs100a.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from qililab.instruments import SGS100A, ParameterNotFound
from qililab.typings.enums import Parameter


@pytest.fixture(name="sdg100a")
def fixture_sdg100a() -> SGS100A:
"""Fixture that returns an instance of a dummy QDAC-II."""
Expand All @@ -14,18 +15,36 @@ def fixture_sdg100a() -> SGS100A:
"alias": "qdac",
"power": 100,
"frequency": 1e6,
"rf_on": True
"rf_on": True,
"hardware_modulation": True
}
)
sdg100a.device = MagicMock()
return sdg100a


@pytest.fixture(name="sdg100a_iq")
def fixture_sdg100a_iq() -> SGS100A:
"""Fixture that returns an instance of a dummy QDAC-II."""
sdg100a_iq = SGS100A(
{
"alias": "qdac",
"power": 100,
"frequency": 1e6,
"rf_on": True,
"hardware_modulation": True
}
)
sdg100a_iq.device = MagicMock()
return sdg100a_iq


class TestSGS100A:
"""Unit tests checking the SGS100A attributes and methods"""

@pytest.mark.parametrize(
"parameter, value",
[(Parameter.POWER, 0.01), (Parameter.LO_FREQUENCY, 6.0e09), (Parameter.RF_ON, True), (Parameter.RF_ON, False)],
[(Parameter.POWER, 0.01), (Parameter.LO_FREQUENCY, 6.0e09), (Parameter.RF_ON, True), (Parameter.RF_ON, False), (Parameter.HARDWARE_MODULATION, True), (Parameter.HARDWARE_MODULATION, False)],
)
def test_set_parameter_method(
self, sdg100a: SGS100A, parameter: Parameter, value: float,
Expand All @@ -38,6 +57,8 @@ def test_set_parameter_method(
assert sdg100a.settings.frequency == value
if parameter == Parameter.RF_ON:
assert sdg100a.settings.rf_on == value
if parameter == Parameter.HARDWARE_MODULATION:
assert sdg100a.settings.hardware_modulation == value

def test_set_parameter_method_raises_error(self, sdg100a: SGS100A):
"""Test setup method"""
Expand All @@ -46,7 +67,7 @@ def test_set_parameter_method_raises_error(self, sdg100a: SGS100A):

@pytest.mark.parametrize(
"parameter, expected_value",
[(Parameter.POWER, 100), (Parameter.LO_FREQUENCY, 1e6), (Parameter.RF_ON, True)],
[(Parameter.POWER, 100), (Parameter.LO_FREQUENCY, 1e6), (Parameter.RF_ON, True), (Parameter.HARDWARE_MODULATION, True)],
)
def test_get_parameter_method(
self, sdg100a: SGS100A, parameter: Parameter, expected_value: float,
Expand Down
Loading