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

Feature/instruments initial setup #519

Open
wants to merge 60 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
759a7d0
work in progress
jjmartinezQT Aug 14, 2023
a788b61
Merge branch 'main' into feature/TAS-247
jjmartinezQT Aug 17, 2023
32f7fb3
fixing init
jjmartinezQT Aug 17, 2023
c169709
work in progress using the flag
jjmartinezQT Aug 18, 2023
ff464c3
Merge branch 'main' into feature/TAS-247
jjmartinezQT Aug 18, 2023
fe1d716
wip
jjmartinezQT Aug 21, 2023
00491d3
wip
jjmartinezQT Aug 21, 2023
746cd0e
changes needed in pulsar and data
jjmartinezQT Aug 22, 2023
316a415
new runcard class for new instruments and buses
jjmartinezQT Aug 22, 2023
a2c4381
checking for flag to be active in connection methods
jjmartinezQT Aug 22, 2023
0183a8a
changes in instrument and platform
jjmartinezQT Aug 22, 2023
7a59699
Merge branch 'main' into feature/TAS-247
jjmartinezQT Aug 22, 2023
c90d7df
sequencers arg
jjmartinezQT Aug 23, 2023
f09069b
initial setup
jjmartinezQT Aug 23, 2023
af3f663
changes in instruments
jjmartinezQT Aug 23, 2023
38ae6d4
Update src/qililab/drivers/instruments/instruments.py
jjmartinezQT Aug 23, 2023
36077d7
changes from PR
jjmartinezQT Aug 23, 2023
37718c7
Merge branch 'feature/instruments_initial_setup' of https://github.co…
jjmartinezQT Aug 23, 2023
bd35267
typo
jjmartinezQT Aug 23, 2023
80d9e33
removing casting
jjmartinezQT Aug 23, 2023
360dd64
redefinition typo
jjmartinezQT Aug 23, 2023
d6a3470
whitespace
jjmartinezQT Aug 23, 2023
6ff3b2c
moved docstrings
jjmartinezQT Aug 23, 2023
389c86d
documentation
jjmartinezQT Aug 23, 2023
74b1907
removing saved params
jjmartinezQT Aug 23, 2023
84d917f
cluster submodules and submodules params
jjmartinezQT Aug 23, 2023
531ca55
adding sequencers retrieval in cluster
jjmartinezQT Aug 23, 2023
ab08c6f
dynamic sequencers adding from list from runcard
jjmartinezQT Aug 23, 2023
0514070
format
jjmartinezQT Aug 23, 2023
05cc858
fix unittest for pulsar
jjmartinezQT Aug 23, 2023
3674e9e
fix for cluster using none
jjmartinezQT Aug 23, 2023
32944bc
fixing docstring
jjmartinezQT Aug 23, 2023
a31d461
fixing unittest for cluster
jjmartinezQT Aug 23, 2023
13d0714
fixing qcm_qrm unittests
jjmartinezQT Aug 23, 2023
267521b
removing new galadriel
jjmartinezQT Aug 23, 2023
c4c0410
Merge branch 'main' into feature/instruments_initial_setup
jjmartinezQT Aug 23, 2023
5992876
isort plus platform from main
jjmartinezQT Aug 23, 2023
54ce432
isort
jjmartinezQT Aug 23, 2023
2d635be
black formatting
jjmartinezQT Aug 23, 2023
60690c9
black formatting
jjmartinezQT Aug 23, 2023
ff6cda8
removing new runcard unittests
jjmartinezQT Aug 23, 2023
49c11a0
changes for pylint
jjmartinezQT Aug 23, 2023
f67822f
deleting new runcard
jjmartinezQT Aug 23, 2023
d02d6a7
formatting
jjmartinezQT Aug 23, 2023
62d5cda
pylint changes
jjmartinezQT Aug 23, 2023
06fafc1
pylint changes
jjmartinezQT Aug 23, 2023
af4391c
pylint changes
jjmartinezQT Aug 23, 2023
856058b
black formatting
jjmartinezQT Aug 23, 2023
9148282
increasing codecoverage
jjmartinezQT Aug 24, 2023
099cf08
formatting
jjmartinezQT Aug 24, 2023
aac5e08
removing file to move it to another PR
jjmartinezQT Aug 24, 2023
45c69a8
remove unused imports
jjmartinezQT Aug 24, 2023
7f6c4bc
adding instrument representations
jjmartinezQT Aug 25, 2023
590560f
instrument representations
jjmartinezQT Aug 25, 2023
6900446
moving internal logic for instrument representation
jjmartinezQT Aug 25, 2023
1c8996e
isort
jjmartinezQT Aug 25, 2023
437511a
isort
jjmartinezQT Aug 25, 2023
07c44a7
isort
jjmartinezQT Aug 25, 2023
c66423e
black formatting
jjmartinezQT Aug 25, 2023
c0acf85
removing prints
jjmartinezQT Aug 25, 2023
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
1 change: 1 addition & 0 deletions src/qililab/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class RUNCARD:
"""YAML constants."""

NAME = "name"
TYPE = "type"
DEVICE_ID = "device_id"
ALIAS = "alias"
INSTRUMENT = "instrument"
Expand Down
3 changes: 2 additions & 1 deletion src/qililab/drivers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@
~VoltageSource
~Attenuator
"""
from .instruments import GS200, Cluster, ERASynthPlus, Keithley2600, Pulsar, RhodeSchwarzSGS100A, SpiRack
from .instruments import GS200, Cluster, ERASynthPlus, Instruments, InstrumentDriverFactory, Keithley2600, Pulsar, RhodeSchwarzSGS100A, SpiRack
from .interfaces import BaseInstrument
1 change: 1 addition & 0 deletions src/qililab/drivers/instruments/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""__init__.py"""
from .era_synth import ERASynthPlus
from .instruments import Instruments
from .instrument_factory import InstrumentDriverFactory
from .keithley import Keithley2600
from .qblox import Cluster, Pulsar, SpiRack
Expand Down
32 changes: 32 additions & 0 deletions src/qililab/drivers/instruments/instruments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Instruments class"""
from dataclasses import dataclass

import yaml

from qililab.drivers.interfaces import BaseInstrument


@dataclass
class Instruments:
"""Instruments class."""
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved

elements: list[BaseInstrument]

def get_instrument(self, alias: str | None = None):
"""Get element given an alias."""
return next((element for element in self.elements if element.alias == alias), None)

def to_dict(self):
"""Return a dict representation of the Instruments class."""
return [instrument.to_dict() for instrument in self.elements]

def __str__(self) -> str:
"""
Returns:
str: String representation of the Instruments class.
"""
return str(yaml.dump(self._short_dict(), sort_keys=False))

def _short_dict(self):
"""Return a dict representation of the Instruments class discarding all static elements."""
return [instrument.short_dict() for instrument in self.elements]
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 1 addition & 1 deletion src/qililab/drivers/instruments/qblox/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def alias(self):
class QcmQrm(QcodesQcmQrm, BaseInstrument):
"""Qililab's driver for QBlox-instruments QcmQrm"""

def __init__(self, parent: Instrument, name: str, slot_idx: int):
def __init__(self, parent: Instrument, name: str, slot_idx: int, **kwargs):
"""Initialise the instrument.

Args:
Expand Down
33 changes: 26 additions & 7 deletions src/qililab/drivers/instruments/qblox/pulsar.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Driver for the Qblox Pulsar class."""
from typing import Any
from qblox_instruments.qcodes_drivers import Pulsar as QcodesPulsar
from qcodes.instrument.channel import ChannelTuple, InstrumentModule

Expand All @@ -13,25 +14,33 @@
class Pulsar(QcodesPulsar, BaseInstrument): # pylint: disable=abstract-method
"""Qililab's driver for QBlox-instruments Pulsar"""

def __init__(self, name: str, address: str | None = None, **kwargs):
def __init__(self, alias: str, address: str | None = None, sequencers: list[str] | None = None, **kwargs):
"""Initialise the instrument.

Args:
name (str): Sequencer name
alias (str): Pulsar name
address (str): Instrument address
"""
super().__init__(name, identifier=address, **kwargs)
self.address = address
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
self.port = kwargs.get('port', None)
self.debug = kwargs.get('debug', None)
self.dummy_type = kwargs.get('dummy_type', None)
super().__init__(name=alias, identifier=address, port=self.port, debug=self.debug, dummy_type=self.dummy_type)
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved

# Add sequencers
self.submodules: dict[str, SequencerQCM | SequencerQRM] = {} # resetting superclass submodules
self.instrument_modules: dict[str, InstrumentModule] = {} # resetting superclass instrument modules
self._channel_lists: dict[str, ChannelTuple] = {} # resetting superclass channel lists

sequencer_class = SequencerQCM if self.is_qcm_type else SequencerQRM
for seq_idx in range(6):
seq = sequencer_class(parent=self, name=f"sequencer{seq_idx}", seq_idx=seq_idx) # type: ignore
self.add_submodule(f"sequencer{seq_idx}", seq)

if sequencers is not None:
for seq_idx, seq_name in enumerate(sequencers):
seq = sequencer_class(parent=self, name=seq_name, seq_idx=seq_idx, map_dict=sequencers[seq_name]) # type: ignore
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
self.add_submodule(seq_name, seq)
else:
for seq_idx in range(6):
seq = sequencer_class(parent=self, name=f"sequencer{seq_idx}", seq_idx=seq_idx) # type: ignore
self.add_submodule(f"sequencer{seq_idx}", seq)
@property
def params(self):
"""return the parameters of the instrument"""
Expand All @@ -41,3 +50,13 @@ def params(self):
def alias(self):
"""return the alias of the instrument, which corresponds to the QCodes name attribute"""
return self.name

def initial_setup(self, params: dict[str, Any] | None = None):
"""Initializes the parameters of the instrument and of the submodules.

Args:
setup_dict (dict[str, Any]): Dictionary representation.
"""
if params:
for param_name, value in params.items():
self.set(param_name=param_name, value=value)
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
19 changes: 16 additions & 3 deletions src/qililab/drivers/instruments/qblox/sequencer_qcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ class SequencerQCM(Sequencer, AWG):

_MIN_WAIT_TIME: int = 4

def __init__(self, parent: Instrument, name: str, seq_idx: int):
def __init__(self, parent: Instrument, name: str, seq_idx: int, **kwargs):
"""Initialise the instrument.

Args:
parent (Instrument): Parent for the sequencer instance.
name (str): Sequencer name
seq_idx (int): sequencer identifier index
map_dict (dict): mappings parameters
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
"""
super().__init__(parent=parent, name=name, seq_idx=seq_idx)
self.add_parameter(name="swap_paths", set_cmd=None, vals=vals.Bool(), initial_value=False)
Expand All @@ -46,6 +47,16 @@ def alias(self):
"""return the alias of the instrument, which corresponds to the QCodes name attribute"""
return self.name

def initial_setup(self, params: dict[str, Any] | None = None):
"""Initializes the parameters of the instrument and of the submodules.

Args:
setup_dict (dict[str, Any]): Dictionary representation.
"""
if params:
for param_name, value in params.items():
self.set(param_name=param_name, value=value)

def set(self, param_name: str, value: Any):
"""Sets a parameter value checking if is an output mapping.

Expand All @@ -58,20 +69,22 @@ def set(self, param_name: str, value: Any):
else:
super().set(param_name, value)

def _map_outputs(self, param_name: str, param_value: Any):
def _map_outputs(self, param_name: str, param_value: str | int):
"""Map sequencer paths with output channels and set the swapping.

Args:
param_name (str): Parameter name
param_value (Any): Parameter value
"""
if isinstance(param_value, str):
param_value = int(param_value)
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
allowed_conf = {("path0", 0), ("path0", 2), ("path1", 1), ("path1", 3)}
swappable_conf = {("path0", 1), ("path0", 3), ("path1", 0), ("path1", 2)}
if (param_name, param_value) in allowed_conf:
self.set(f"channel_map_{param_name}_out{param_value}_en", True)
elif (param_name, param_value) in swappable_conf:
self.set("swap_paths", True)
self.set(f"channel_map_{param_name}_out{1 - param_value}_en", True)
self.set(f"channel_map_{param_name}_out{abs(1 - param_value)}_en", True)
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
else:
raise ValueError(
f"Impossible path configuration detected. {param_name} cannot be mapped to output {param_value}."
Expand Down
4 changes: 2 additions & 2 deletions src/qililab/drivers/instruments/qblox/sequencer_qrm.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class SequencerQRM(SequencerQCM, Digitiser):
"""Qililab's driver for QBlox-instruments digitiser Sequencer"""

def __init__(self, parent: Instrument, name: str, seq_idx: int):
def __init__(self, parent: Instrument, name: str, seq_idx: int, map_dict: dict[str, str] | None = None):
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
"""Initialise the instrument.

Args:
Expand All @@ -28,7 +28,7 @@ def __init__(self, parent: Instrument, name: str, seq_idx: int):
sequence_timeout (int): timeout to retrieve sequencer state in minutes
acquisition_timeout (int): timeout to retrieve acquisition state in minutes
"""
super().__init__(parent=parent, name=name, seq_idx=seq_idx)
super().__init__(parent=parent, name=name, seq_idx=seq_idx, map_dict=map_dict)
self.add_parameter(name="sequence_timeout", vals=vals.Ints(), set_cmd=None, initial_value=1)
self.add_parameter(name="acquisition_timeout", vals=vals.Ints(), set_cmd=None, initial_value=1)
self.add_parameter(name="weights_i", vals=vals.Lists(), set_cmd=None, initial_value=[])
Expand Down
8 changes: 8 additions & 0 deletions src/qililab/drivers/interfaces/base_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,11 @@ def get(self, param_name: str) -> Any:
Returns:
Any: Current value of the parameter.
"""

@abstractmethod
jjmartinezQT marked this conversation as resolved.
Show resolved Hide resolved
def initial_setup(self, params: dict[str, Any] | None = None):
"""Initializes the parameters of the instrument and of the submodules.

Args:
setup_dict (dict[str, Any]): Dictionary representation.
"""
Loading