sqil-core 0.0.2__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. {sqil_core-0.0.2 → sqil_core-1.0.0}/PKG-INFO +40 -7
  2. {sqil_core-0.0.2 → sqil_core-1.0.0}/README.md +27 -3
  3. {sqil_core-0.0.2 → sqil_core-1.0.0}/pyproject.toml +15 -5
  4. sqil_core-1.0.0/sqil_core/__init__.py +7 -0
  5. sqil_core-1.0.0/sqil_core/config.py +13 -0
  6. sqil_core-1.0.0/sqil_core/config_log.py +42 -0
  7. sqil_core-1.0.0/sqil_core/experiment/__init__.py +11 -0
  8. sqil_core-1.0.0/sqil_core/experiment/_analysis.py +95 -0
  9. sqil_core-1.0.0/sqil_core/experiment/_events.py +25 -0
  10. sqil_core-1.0.0/sqil_core/experiment/_experiment.py +553 -0
  11. sqil_core-1.0.0/sqil_core/experiment/data/plottr.py +778 -0
  12. sqil_core-1.0.0/sqil_core/experiment/helpers/_function_override_handler.py +111 -0
  13. sqil_core-1.0.0/sqil_core/experiment/helpers/_labone_wrappers.py +12 -0
  14. sqil_core-1.0.0/sqil_core/experiment/instruments/__init__.py +2 -0
  15. sqil_core-1.0.0/sqil_core/experiment/instruments/_instrument.py +190 -0
  16. sqil_core-1.0.0/sqil_core/experiment/instruments/drivers/SignalCore_SC5511A.py +515 -0
  17. sqil_core-1.0.0/sqil_core/experiment/instruments/local_oscillator.py +205 -0
  18. sqil_core-1.0.0/sqil_core/experiment/instruments/server.py +175 -0
  19. sqil_core-1.0.0/sqil_core/experiment/instruments/setup.yaml +21 -0
  20. sqil_core-1.0.0/sqil_core/experiment/instruments/zurich_instruments.py +55 -0
  21. sqil_core-1.0.0/sqil_core/fit/__init__.py +38 -0
  22. sqil_core-1.0.0/sqil_core/fit/_core.py +1084 -0
  23. sqil_core-1.0.0/sqil_core/fit/_fit.py +1191 -0
  24. sqil_core-1.0.0/sqil_core/fit/_guess.py +232 -0
  25. sqil_core-1.0.0/sqil_core/fit/_models.py +127 -0
  26. sqil_core-1.0.0/sqil_core/fit/_quality.py +266 -0
  27. sqil_core-1.0.0/sqil_core/resonator/__init__.py +13 -0
  28. sqil_core-1.0.0/sqil_core/resonator/_resonator.py +989 -0
  29. sqil_core-1.0.0/sqil_core/utils/__init__.py +86 -0
  30. sqil_core-1.0.0/sqil_core/utils/_analysis.py +415 -0
  31. sqil_core-1.0.0/sqil_core/utils/_const.py +105 -0
  32. sqil_core-1.0.0/sqil_core/utils/_formatter.py +259 -0
  33. sqil_core-1.0.0/sqil_core/utils/_plot.py +373 -0
  34. sqil_core-1.0.0/sqil_core/utils/_read.py +262 -0
  35. sqil_core-1.0.0/sqil_core/utils/_utils.py +164 -0
  36. sqil_core-0.0.2/sqil_core/__init__.py +0 -3
  37. sqil_core-0.0.2/sqil_core/utils/__init__.py +0 -6
  38. sqil_core-0.0.2/sqil_core/utils/analysis.py +0 -68
  39. sqil_core-0.0.2/sqil_core/utils/const.py +0 -38
  40. sqil_core-0.0.2/sqil_core/utils/formatter.py +0 -134
  41. sqil_core-0.0.2/sqil_core/utils/read.py +0 -156
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: sqil-core
3
- Version: 0.0.2
3
+ Version: 1.0.0
4
4
  Summary: The codebase of the SQIL group in EPFL
5
5
  Author: Andrea Duina
6
6
  Requires-Python: >=3.10,<4.0
@@ -9,12 +9,21 @@ Classifier: Programming Language :: Python :: 3.10
9
9
  Classifier: Programming Language :: Python :: 3.11
10
10
  Classifier: Programming Language :: Python :: 3.12
11
11
  Classifier: Programming Language :: Python :: 3.13
12
+ Requires-Dist: blinker (>=1.9.0,<2.0.0)
12
13
  Requires-Dist: h5py (>=3.12.1,<4.0.0)
13
14
  Requires-Dist: isort (==5.9.3)
15
+ Requires-Dist: laboneq (>=2.54.0,<3.0.0)
16
+ Requires-Dist: laboneq-applications (>=2.4.0,<3.0.0)
17
+ Requires-Dist: lmfit (>=1.3.2,<2.0.0)
14
18
  Requires-Dist: matplotlib (>=3.9.3,<4.0.0)
15
- Requires-Dist: numpy (>=2.2.0,<3.0.0)
19
+ Requires-Dist: mpld3 (>=0.5.10,<0.6.0)
20
+ Requires-Dist: numpy (>=2.2.3,<3.0.0)
21
+ Requires-Dist: plottr (>=0.14.0,<0.15.0)
22
+ Requires-Dist: pyro5 (>=5.15,<6.0)
23
+ Requires-Dist: qcodes (>=0.51.0,<0.52.0)
24
+ Requires-Dist: qcodes-contrib-drivers (>=0.23.0,<0.24.0)
16
25
  Requires-Dist: scipy (>=1.14.1,<2.0.0)
17
- Requires-Dist: seaborn (>=0.13.2,<0.14.0)
26
+ Requires-Dist: tabulate (>=0.9.0,<0.10.0)
18
27
  Description-Content-Type: text/markdown
19
28
 
20
29
  # For users
@@ -38,34 +47,44 @@ path = 'path to your data folder'
38
47
  mag, phase, freq = sqil.extract_h5_data(path, ['mag_dB', 'phase', 'ro_freq'])
39
48
  ```
40
49
 
50
+ ## Documentation
51
+ You can find the documentation for this package [here](https://sqil-epfl.github.io/sqil-core/)
52
+
41
53
  # For developers
42
54
 
43
55
  ## Development
44
56
 
45
57
  1. **Install poetry if you haven't already**
58
+
46
59
  ```bash
47
60
  $ pip install poetry
61
+ $ pip install poetry-plugin-shell
48
62
  ```
49
63
 
50
64
  2. **Install the required packages using poetry**
65
+
51
66
  ```bash
52
67
  $ poetry install
53
68
  ```
54
69
 
55
70
  3. **Install the pre-commit hooks**
56
- If you are on windows you need to install git ([https://git-scm.com/downloads](here)) and add it to your windows PATH.
57
- After the installation open a new terminal.
71
+ If you are on windows you need to install git ([https://git-scm.com/downloads](here)) and add it to your windows PATH.
72
+ After the installation open a new terminal.
73
+
58
74
  ```bash
59
75
  $ poetry run pre-commit install
60
76
  ```
77
+
61
78
  This will check if your python files are formatted correctly when you try to commit.
62
79
  If that's not the case the commit will be canceled and the files will be automatically formatted.
63
80
  Then you'll have to add and commit again the new files.
64
81
 
65
82
  4. **Start the virtual environment**
83
+
66
84
  ```bash
67
85
  $ poetry shell
68
86
  ```
87
+
69
88
  To exit the virtual environment just use `exit`
70
89
 
71
90
  #### Test your changes
@@ -91,7 +110,11 @@ $ poetry run build
91
110
  $ pip install PATH_TO_SQIL_CORE_FOLDER/dist/SQIL_CORE-VERSION.whl
92
111
  ```
93
112
 
94
- If you're using a jupyter notebook remember to restart the kernel
113
+ If you're testing a new function remember to import it in the folder's `__init__.py` file.
114
+
115
+
116
+ If you're using a jupyter notebook remember to restart the kernel.
117
+
95
118
 
96
119
  ## Build
97
120
 
@@ -99,6 +122,16 @@ If you're using a jupyter notebook remember to restart the kernel
99
122
  $ poetry run build
100
123
  ```
101
124
 
125
+ ## Publish
126
+
127
+ To publish version X.X.X run the commands below. This will trigger a GitHub action that deploys to release to PyPi (pip) and GitHub.
128
+ Remember also to change the version number in the `pyproject.toml` file.
129
+
130
+ ```bash
131
+ $ git tag vX.X.X
132
+ $ git push origin vX.X.X
133
+ ```
134
+
102
135
  ## Docs
103
136
 
104
137
  Serve docs
@@ -19,34 +19,44 @@ path = 'path to your data folder'
19
19
  mag, phase, freq = sqil.extract_h5_data(path, ['mag_dB', 'phase', 'ro_freq'])
20
20
  ```
21
21
 
22
+ ## Documentation
23
+ You can find the documentation for this package [here](https://sqil-epfl.github.io/sqil-core/)
24
+
22
25
  # For developers
23
26
 
24
27
  ## Development
25
28
 
26
29
  1. **Install poetry if you haven't already**
30
+
27
31
  ```bash
28
32
  $ pip install poetry
33
+ $ pip install poetry-plugin-shell
29
34
  ```
30
35
 
31
36
  2. **Install the required packages using poetry**
37
+
32
38
  ```bash
33
39
  $ poetry install
34
40
  ```
35
41
 
36
42
  3. **Install the pre-commit hooks**
37
- If you are on windows you need to install git ([https://git-scm.com/downloads](here)) and add it to your windows PATH.
38
- After the installation open a new terminal.
43
+ If you are on windows you need to install git ([https://git-scm.com/downloads](here)) and add it to your windows PATH.
44
+ After the installation open a new terminal.
45
+
39
46
  ```bash
40
47
  $ poetry run pre-commit install
41
48
  ```
49
+
42
50
  This will check if your python files are formatted correctly when you try to commit.
43
51
  If that's not the case the commit will be canceled and the files will be automatically formatted.
44
52
  Then you'll have to add and commit again the new files.
45
53
 
46
54
  4. **Start the virtual environment**
55
+
47
56
  ```bash
48
57
  $ poetry shell
49
58
  ```
59
+
50
60
  To exit the virtual environment just use `exit`
51
61
 
52
62
  #### Test your changes
@@ -72,7 +82,11 @@ $ poetry run build
72
82
  $ pip install PATH_TO_SQIL_CORE_FOLDER/dist/SQIL_CORE-VERSION.whl
73
83
  ```
74
84
 
75
- If you're using a jupyter notebook remember to restart the kernel
85
+ If you're testing a new function remember to import it in the folder's `__init__.py` file.
86
+
87
+
88
+ If you're using a jupyter notebook remember to restart the kernel.
89
+
76
90
 
77
91
  ## Build
78
92
 
@@ -80,6 +94,16 @@ If you're using a jupyter notebook remember to restart the kernel
80
94
  $ poetry run build
81
95
  ```
82
96
 
97
+ ## Publish
98
+
99
+ To publish version X.X.X run the commands below. This will trigger a GitHub action that deploys to release to PyPi (pip) and GitHub.
100
+ Remember also to change the version number in the `pyproject.toml` file.
101
+
102
+ ```bash
103
+ $ git tag vX.X.X
104
+ $ git push origin vX.X.X
105
+ ```
106
+
83
107
  ## Docs
84
108
 
85
109
  Serve docs
@@ -1,23 +1,32 @@
1
1
  [tool.poetry]
2
2
  name = "sqil-core"
3
- version = "v0.0.2"
3
+ version = "v1.0.0"
4
4
  description = "The codebase of the SQIL group in EPFL"
5
5
  authors = ["Andrea Duina"]
6
6
  readme = "README.md"
7
7
 
8
8
  [tool.poetry.scripts]
9
9
  build = "scripts:build"
10
- docs-serve = "scripts:docs_serve"
10
+ docs-dev = "scripts:docs_dev"
11
11
  docs-build = "scripts:docs_build"
12
12
 
13
13
  [tool.poetry.dependencies]
14
- python = "^3.10"
15
- numpy = "^2.2.0"
14
+ python = ">=3.10,<4.0"
16
15
  scipy = "^1.14.1"
17
16
  h5py = "^3.12.1"
18
17
  matplotlib = "^3.9.3"
19
- seaborn = "^0.13.2"
20
18
  isort = "5.9.3"
19
+ tabulate = "^0.9.0"
20
+ numpy = "^2.2.3"
21
+ lmfit = "^1.3.2"
22
+ pyro5 = "^5.15"
23
+ qcodes = "^0.51.0"
24
+ qcodes-contrib-drivers = "^0.23.0"
25
+ blinker = "^1.9.0"
26
+ laboneq-applications = "^2.4.0"
27
+ plottr = "^0.14.0"
28
+ laboneq = "^2.54.0"
29
+ mpld3 = "^0.5.10"
21
30
 
22
31
 
23
32
  [tool.poetry.group.dev.dependencies]
@@ -27,6 +36,7 @@ mkdocs = "^1.6.1"
27
36
  mkdocs-material = "^9.5.48"
28
37
  mkdocstrings-python = "^1.12.2"
29
38
  pytest = "^8.3.4"
39
+ mkdocs-jupyter = "^0.25.1"
30
40
 
31
41
  [build-system]
32
42
  requires = ["poetry-core"]
@@ -0,0 +1,7 @@
1
+ import sqil_core.experiment as experiment
2
+ import sqil_core.fit as fit
3
+ import sqil_core.resonator as resonator
4
+ import sqil_core.utils as utils
5
+ from sqil_core.utils import *
6
+
7
+ __all__ = utils.__all__ + ["utils", "fit", "resonator"]
@@ -0,0 +1,13 @@
1
+ _EXCLUDED_PACKAGES = [
2
+ "os",
3
+ "sys",
4
+ "inspect",
5
+ "np",
6
+ "spopt",
7
+ "lmfit",
8
+ "h5py",
9
+ "json",
10
+ "tabulate",
11
+ "matplotlib",
12
+ "plt",
13
+ ]
@@ -0,0 +1,42 @@
1
+ import logging
2
+
3
+ from colorama import Fore, Style, init
4
+
5
+ # Initialize Colorama
6
+ init(autoreset=True, strip=False, convert=False)
7
+
8
+
9
+ class SqilFormatter(logging.Formatter):
10
+ FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
11
+
12
+ COLOR_MAP = {
13
+ "DEBUG": Fore.BLUE,
14
+ "INFO": Fore.GREEN,
15
+ "WARNING": Fore.YELLOW,
16
+ "ERROR": Fore.RED,
17
+ "CRITICAL": Fore.RED + Style.BRIGHT,
18
+ }
19
+
20
+ def format(self, record):
21
+ log_color = self.COLOR_MAP.get(record.levelname, "")
22
+ record.levelname = f"{log_color}{record.levelname}{Style.RESET_ALL}"
23
+ return super().format(record)
24
+
25
+
26
+ class SqilLogger(logging.Logger):
27
+ # By default show the stack trace when errors are logged
28
+ def error(self, msg, *args, exc_info=True, **kwargs):
29
+ super().error(msg, *args, exc_info=exc_info, **kwargs)
30
+
31
+
32
+ logging.setLoggerClass(SqilLogger)
33
+ logger = logging.getLogger("sqil_logger")
34
+ logger.setLevel(logging.DEBUG)
35
+
36
+ console_handler = logging.StreamHandler()
37
+ console_handler.setLevel(logging.DEBUG)
38
+ console_handler.setFormatter(SqilFormatter(SqilFormatter.FORMAT))
39
+
40
+ # Avoid adding multiple handlers if the logger is reused
41
+ if not logger.hasHandlers():
42
+ logger.addHandler(console_handler)
@@ -0,0 +1,11 @@
1
+ from ._analysis import AnalysisResult
2
+ from ._events import after_experiment, before_experiment
3
+ from ._experiment import ExperimentHandler
4
+ from .instruments._instrument import Instrument
5
+ from .instruments.local_oscillator import LocalOscillator
6
+ from .instruments.server import (
7
+ InstrumentServer,
8
+ link_instrument_server,
9
+ start_instrument_server,
10
+ unlink_instrument_server,
11
+ )
@@ -0,0 +1,95 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+
7
+ import h5py
8
+ import mpld3
9
+ import numpy as np
10
+
11
+ from sqil_core.utils import get_measurement_id
12
+
13
+ if TYPE_CHECKING:
14
+ from matplotlib.figure import Figure
15
+
16
+ from sqil_core.fit import FitResult
17
+
18
+
19
+ class AnalysisResult:
20
+ updated_params: dict[str, dict] = {}
21
+ figures: dict[str, Figure] = {}
22
+ fits: dict[str, FitResult] = {}
23
+ extra_data: dict[str, np.ndarray] = {}
24
+
25
+ def __init__(
26
+ self,
27
+ updated_params: dict[str, dict] = {},
28
+ figures: dict[str, Figure] = {},
29
+ fits: dict[str, FitResult] = {},
30
+ extra_data: dict[str, np.ndarray] = {},
31
+ ):
32
+ self.updated_params = updated_params or {}
33
+ self.figures = figures or {}
34
+ self.fits = fits or {}
35
+ self.extra_data = extra_data or {}
36
+
37
+ def add_exp_info_to_figures(self, dir_path: str):
38
+ if not self.figures:
39
+ return
40
+ id = get_measurement_id(dir_path)
41
+ cooldown_name = Path(dir_path).parts[-3]
42
+ for _, fig in self.figures.items():
43
+ # Add dummy text to infer font size
44
+ dummy_text = fig.text(0, 0, "dummy", visible=False)
45
+ font_size = dummy_text.get_fontsize()
46
+ dummy_text.remove()
47
+ fig.text(
48
+ 0.98,
49
+ 0.98,
50
+ f"{cooldown_name}\n{id} | {dir_path[-16:]}",
51
+ ha="right",
52
+ va="top",
53
+ color="gray",
54
+ fontsize=font_size * 0.8,
55
+ )
56
+
57
+ def save_figures(self, dir_path: str):
58
+ """Saves figures both as png and interactive html."""
59
+ for key, fig in self.figures.items():
60
+ path = os.path.join(dir_path, key)
61
+ fig.savefig(os.path.join(f"{path}.png"), bbox_inches="tight", dpi=300)
62
+ html = mpld3.fig_to_html(fig)
63
+ with open(f"{path}.html", "w") as f:
64
+ f.write(html)
65
+
66
+ def aggregate_fit_summaries(self):
67
+ """Aggreate all the fit summaries and include model name."""
68
+ result = ""
69
+ for key, fit in self.fits.items():
70
+ summary = fit.summary(no_print=True)
71
+ result += f"{key}\nModel: {fit.model_name}\n{summary}\n"
72
+ return result
73
+
74
+ def save_fits(self, dir_path: str):
75
+ if not self.fits:
76
+ return
77
+ with open(os.path.join(dir_path, "fit.mono.md"), "w", encoding="utf-8") as f:
78
+ f.write(self.aggregate_fit_summaries())
79
+
80
+ def save_extra_data(self, dir_path: str):
81
+ if not self.extra_data:
82
+ return
83
+ with h5py.File(os.path.join(dir_path, "extra.ddh5"), "a") as f:
84
+ grp = f.require_group("data")
85
+ for key, array in self.extra_data.items():
86
+ # Overwrite if already exists
87
+ if key in grp:
88
+ del grp[key]
89
+ grp.create_dataset(key, data=array)
90
+
91
+ def save_all(self, dir_path: str):
92
+ self.add_exp_info_to_figures(dir_path)
93
+ self.save_figures(dir_path)
94
+ self.save_fits(dir_path)
95
+ self.save_extra_data(dir_path)
@@ -0,0 +1,25 @@
1
+ from blinker import NamedSignal
2
+
3
+ before_experiment = NamedSignal("before_experiment")
4
+ after_experiment = NamedSignal("after_experiment")
5
+
6
+ before_sequence = NamedSignal("before_sequence")
7
+ after_sequence = NamedSignal("after_sequence")
8
+
9
+
10
+ def clear_signal(signal):
11
+ """Removes all listeners (receivers) from an event (signal)."""
12
+ receivers = list(signal.receivers.values())
13
+ for receiver in receivers:
14
+ signal.disconnect(receiver)
15
+
16
+
17
+ def one_time_listener(signal, func):
18
+ """Listens for an event only once."""
19
+
20
+ def wrapper(*args, **kwargs):
21
+ signal.disconnect(wrapper)
22
+ return func(*args, **kwargs)
23
+
24
+ signal.connect(wrapper, weak=False)
25
+ return wrapper