simcats 1.1.0__py3-none-any.whl → 2.0.0__py3-none-any.whl

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 (42) hide show
  1. simcats/__init__.py +4 -3
  2. simcats/_default_configs.py +129 -13
  3. simcats/_simulation.py +451 -69
  4. simcats/config_samplers/_GaAs_v1_random_variations_v3_config_sampler.py +1059 -0
  5. simcats/config_samplers/__init__.py +9 -0
  6. simcats/distortions/_distortion_interfaces.py +1 -1
  7. simcats/distortions/_dot_jumps.py +8 -6
  8. simcats/distortions/_random_telegraph_noise.py +4 -4
  9. simcats/distortions/_transition_blurring.py +5 -5
  10. simcats/distortions/_white_noise.py +2 -2
  11. simcats/ideal_csd/geometric/_generate_lead_transition_mask.py +3 -3
  12. simcats/ideal_csd/geometric/_get_electron_occupation.py +5 -5
  13. simcats/ideal_csd/geometric/_ideal_csd_geometric.py +5 -5
  14. simcats/ideal_csd/geometric/_ideal_csd_geometric_class.py +9 -9
  15. simcats/ideal_csd/geometric/_tct_bezier.py +5 -5
  16. simcats/sensor/__init__.py +10 -6
  17. simcats/sensor/{_generic_sensor.py → _sensor_generic.py} +1 -1
  18. simcats/sensor/_sensor_interface.py +164 -11
  19. simcats/sensor/_sensor_rise_glf.py +229 -0
  20. simcats/sensor/_sensor_scan_sensor_generic.py +929 -0
  21. simcats/sensor/barrier_function/__init__.py +9 -0
  22. simcats/sensor/barrier_function/_barrier_function_glf.py +280 -0
  23. simcats/sensor/barrier_function/_barrier_function_interface.py +43 -0
  24. simcats/sensor/barrier_function/_barrier_function_multi_glf.py +157 -0
  25. simcats/sensor/deformation/__init__.py +9 -0
  26. simcats/sensor/deformation/_sensor_peak_deformation_circle.py +109 -0
  27. simcats/sensor/deformation/_sensor_peak_deformation_interface.py +65 -0
  28. simcats/sensor/deformation/_sensor_peak_deformation_linear.py +77 -0
  29. simcats/support_functions/__init__.py +11 -3
  30. simcats/support_functions/_generalized_logistic_function.py +146 -0
  31. simcats/support_functions/_linear_algebra.py +171 -0
  32. simcats/support_functions/_parameter_sampling.py +108 -19
  33. simcats/support_functions/_pixel_volt_transformation.py +24 -0
  34. simcats/support_functions/_reset_offset_mu_sens.py +43 -0
  35. {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/METADATA +93 -29
  36. simcats-2.0.0.dist-info/RECORD +53 -0
  37. {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/WHEEL +1 -1
  38. simcats-1.1.0.dist-info/RECORD +0 -37
  39. /simcats/sensor/{_gaussian_sensor_peak.py → _sensor_peak_gaussian.py} +0 -0
  40. /simcats/sensor/{_lorentzian_sensor_peak.py → _sensor_peak_lorentzian.py} +0 -0
  41. {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info/licenses}/LICENSE +0 -0
  42. {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/top_level.txt +0 -0
@@ -7,12 +7,10 @@ The contained functions can be used for example for the parameter sampling in th
7
7
 
8
8
  import warnings
9
9
  from abc import ABC, abstractmethod
10
- from typing import Tuple, Union
10
+ from typing import Tuple, Optional
11
11
 
12
12
  import numpy as np
13
13
 
14
- __all__ = []
15
-
16
14
 
17
15
  class ParameterSamplingInterface(ABC):
18
16
  """Interface for parameter sampling.
@@ -47,8 +45,9 @@ class NormalSamplingRange(ParameterSamplingInterface):
47
45
  self,
48
46
  total_range: Tuple,
49
47
  std: float,
50
- sampling_range: Union[float, None] = None,
51
- rng: Union[np.random.Generator, None] = None,
48
+ mean: Optional[float] = None,
49
+ sampling_range: Optional[float] = None,
50
+ rng: Optional[np.random.Generator] = None,
52
51
  ) -> None:
53
52
  """This class can be used to generate randomly normal sampled parameters within a given range.
54
53
 
@@ -60,7 +59,9 @@ class NormalSamplingRange(ParameterSamplingInterface):
60
59
  range, a new sample is drawn until a sample inside the sampling_range/total_range was generated,
61
60
  leading to a truncated normal distribution.
62
61
  std (float): The standard deviation of the sampled elements, which is used in the normal distribution.
63
- sampling_range (Union[float, None]): The maximum range in which the parameter is allowed to change during
62
+ mean (Optional[float]): The mean to be used for the normal distribution. If None, the center of the
63
+ total range will be used. Defaults to None.
64
+ sampling_range (Optional[float]): The maximum range in which the parameter is allowed to change during
64
65
  the simulation. The explicit range is set up during the initialization, narrowing down the
65
66
  supplied total_range. Default is None, which leads to no narrowing of the given total_range.
66
67
  rng (np.random.Generator): random number generator used for the sampling of random numbers. If None, the
@@ -86,13 +87,17 @@ class NormalSamplingRange(ParameterSamplingInterface):
86
87
  )
87
88
  self.__range = (sampled - 0.5 * sampling_range, sampled + 0.5 * sampling_range)
88
89
  self.__std = std
90
+ if mean is not None:
91
+ self.__mean = mean
92
+ else:
93
+ self.__mean = np.mean(self.__range)
89
94
  self.__last_sample = None
90
95
 
91
96
  def sample_parameter(self):
92
- sampled = self.__rng.normal(loc=np.mean(self.__range), scale=self.__std)
97
+ sampled = self.__rng.normal(loc=self.__mean, scale=self.__std)
93
98
  # repeat sampling until the sampled value is in self.__range
94
99
  while sampled < self.__range[0] or sampled > self.__range[1]:
95
- sampled = self.__rng.normal(loc=np.mean(self.__range), scale=self.__std)
100
+ sampled = self.__rng.normal(loc=self.__mean, scale=self.__std)
96
101
  self.__last_sample = sampled
97
102
  return sampled
98
103
 
@@ -102,7 +107,7 @@ class NormalSamplingRange(ParameterSamplingInterface):
102
107
  def __repr__(self) -> str:
103
108
  return (
104
109
  self.__class__.__name__
105
- + f"(last_sample={self.last_sample()}, range={self.__range}, std={self.__std}, rng={self.__rng})"
110
+ + f"(last_sample={self.last_sample()}, range={self.__range}, mean={self.__mean}, std={self.__std}, rng={self.__rng})"
106
111
  )
107
112
 
108
113
 
@@ -111,8 +116,8 @@ class UniformSamplingRange(ParameterSamplingInterface):
111
116
  def __init__(
112
117
  self,
113
118
  total_range: Tuple,
114
- sampling_range: Union[float, None] = None,
115
- rng: Union[np.random.Generator, None] = None,
119
+ sampling_range: Optional[float] = None,
120
+ rng: Optional[np.random.Generator] = None,
116
121
  ) -> None:
117
122
  """This class can be used to generate randomly uniform sampled parameters within a given range.
118
123
 
@@ -121,11 +126,11 @@ class UniformSamplingRange(ParameterSamplingInterface):
121
126
  Args:
122
127
  total_range (Tuple): The total range in which the parameters can be sampled. This can be narrowed down
123
128
  randomly with the help of sampling_range.
124
- sampling_range (Union[float, None]): The maximum range in which the parameter is allowed to change during
129
+ sampling_range (Optional[float]): The maximum range in which the parameter is allowed to change during
125
130
  the simulation. The explicit range is set up during the initialization, narrowing down the supplied
126
131
  total_range. Default is None, which leads to no narrowing of the given total_range.
127
- rng (np.random.Generator): random number generator used for the sampling of random numbers. If None, the
128
- default generator of numpy (np.random.default_rng()) is used. Default is None.
132
+ rng (Optional[np.random.Generator]): Random number generator used for the sampling of random numbers. If
133
+ None, the default generator of numpy (np.random.default_rng()) is used. Default is None.
129
134
  """
130
135
  if rng:
131
136
  self.__rng = rng
@@ -165,8 +170,8 @@ class LogNormalSamplingRange(ParameterSamplingInterface):
165
170
  def __init__(
166
171
  self,
167
172
  total_range: Tuple,
168
- sampling_range: Union[float, None] = None,
169
- rng: Union[np.random.Generator, None] = None,
173
+ sampling_range: Optional[float] = None,
174
+ rng: Optional[np.random.Generator] = None,
170
175
  mean: float = 0,
171
176
  sigma: float = 1,
172
177
  ) -> None:
@@ -179,11 +184,11 @@ class LogNormalSamplingRange(ParameterSamplingInterface):
179
184
  randomly with the help of sampling_range. If the log-normal distribution generates a sample outside this
180
185
  range, a new sample is drawn until a sample inside the sampling_range/total_range was generated, leading
181
186
  toa truncated log-normal distribution.
182
- sampling_range (Union[float, None]): The maximum range in which the parameter is allowed to change during
187
+ sampling_range (Optional[float]): The maximum range in which the parameter is allowed to change during
183
188
  the simulation. The explicit range is set up during the initialization, narrowing down the supplied
184
189
  total_range. Default is None, which leads to no narrowing of the given total_range.
185
- rng (np.random.Generator): random number generator used for the sampling of random numbers. If None, the
186
- default generator of numpy (np.random.default_rng()) is used. Default is None.
190
+ rng (Optional[np.random.Generator]): Random number generator used for the sampling of random numbers. If
191
+ None, the default generator of numpy (np.random.default_rng()) is used. Default is None.
187
192
  mean (float): Mean value of the underlying normal distribution. Default is 0.
188
193
  sigma (float): Standard deviation of the underlying normal distribution. Must be non-negative. Default is 1.
189
194
  """
@@ -231,3 +236,87 @@ class LogNormalSamplingRange(ParameterSamplingInterface):
231
236
  + f"(last_sample={self.last_sample()}, range={self.__range}, mean={self.__mean}, sigma={self.__sigma}"
232
237
  + f", rng={self.__rng})"
233
238
  )
239
+
240
+
241
+ class ExponentialSamplingRange(ParameterSamplingInterface):
242
+ """Exponential distribution sampling range implementation of ParameterSamplingInterface."""
243
+
244
+ def __init__(
245
+ self,
246
+ total_range: Tuple,
247
+ scale: float,
248
+ sampling_range: Optional[float] = None,
249
+ rng: Optional[np.random.Generator] = None,
250
+ ) -> None:
251
+ """This class can be used to generate randomly sampled parameters from an exponential distribution within a given range.
252
+
253
+ The samples are calculated as follows:\n
254
+ min(sampling_range) + exponential_distribution_sample * (max(sampling_range) - min(Sampling_range))
255
+
256
+ To select the correct scale factor (1 / λ), take the following into consideration:\n
257
+ To have the p percent quantile at position q, the following must be valid:\n
258
+ q = ln( 1 / (1-p) ) / λ \n
259
+ with 1 / λ = scale \n
260
+ So in general the scale is calculated as: \n
261
+ scale = q / ln( 1 / (1-p) ) \n
262
+ For example: If it is desired to have 90% of the values in 50% of the sampling range, we get:\n
263
+ scale = 0.5 / ln( 1 / (1-0.9) ) = 0.21715
264
+
265
+ Further reading: https://en.wikipedia.org/wiki/Exponential_distribution#properties
266
+
267
+ Used for example for the distortions during the simulation of CSDs.
268
+
269
+ Args:
270
+ total_range (Tuple): The total range in which the parameters can be sampled. This can be narrowed down
271
+ randomly with the help of the parameter sampling_range. If the exponential distribution generates a
272
+ sample outside this range, a new sample is drawn until a sample inside the sampling_range/total_range
273
+ was generated, leading to a truncated exponential distribution.
274
+ scale (float): The scale of the exponential distribution. See __init__ docstring for more detailed
275
+ information.
276
+ sampling_range (Optional[float]): The maximum range in which the parameter is allowed to change during
277
+ the simulation. The explicit range is set up during the initialization, narrowing down the
278
+ supplied total_range. Default is None, which leads to no narrowing of the given total_range.
279
+ rng (Optional[np.random.Generator]): Random number generator used for the sampling of random numbers. If
280
+ None, the default generator of numpy (np.random.default_rng()) is used. Default is None.
281
+ """
282
+ if rng:
283
+ self.__rng = rng
284
+ else:
285
+ self.__rng = np.random.default_rng()
286
+ if sampling_range is None:
287
+ self.__range = total_range
288
+ else:
289
+ if np.greater_equal(sampling_range, np.max(total_range) - np.min(total_range)):
290
+ warnings.warn(
291
+ "The given reduced sampling range is equal or larger than the given total range. As "
292
+ "default the given total sampling range is taken.",
293
+ stacklevel=2,
294
+ )
295
+ self.__range = total_range
296
+ else:
297
+ sampled = self.__rng.uniform(
298
+ np.min(total_range) + 0.5 * sampling_range, np.max(total_range) - 0.5 * sampling_range
299
+ )
300
+ if total_range[0] < total_range[1]:
301
+ self.__range = (sampled - 0.5 * sampling_range, sampled + 0.5 * sampling_range)
302
+ else:
303
+ self.__range = (sampled + 0.5 * sampling_range, sampled - 0.5 * sampling_range)
304
+ self.__scale = scale
305
+ self.__last_sample = None
306
+
307
+ def sample_parameter(self):
308
+ sampled = self.__range[0] + self.__rng.exponential(scale=self.__scale) * (self.__range[1] - self.__range[0])
309
+ # repeat sampling until the sampled value is in self.__range
310
+ while sampled < np.min(self.__range) or sampled > np.max(self.__range):
311
+ sampled = self.__range[0] + self.__rng.exponential(scale=self.__scale) * (self.__range[1] - self.__range[0])
312
+ self.__last_sample = sampled
313
+ return sampled
314
+
315
+ def last_sample(self):
316
+ return self.__last_sample
317
+
318
+ def __repr__(self) -> str:
319
+ return (
320
+ self.__class__.__name__
321
+ + f"(last_sample={self.last_sample()}, range={self.__range}, scale={self.__scale}, rng={self.__rng})"
322
+ )
@@ -0,0 +1,24 @@
1
+ """This module contains functions for transforming pixel coordinates into voltages
2
+
3
+ @author: b.papajewski
4
+ """
5
+
6
+ import numpy as np
7
+
8
+
9
+ def pixel_to_volt_1d(pixel: int, pixel_num: int, volt_limits: np.ndarray) -> np.ndarray:
10
+ """Method that maps a pixel index to a voltage value within specified voltage limits.
11
+
12
+ This function linearly maps a pixel position within a span of `pixel_num` pixels to a corresponding voltage value.
13
+ The voltage values of the pixel span change uniformly between the two values in `volt_limits`.
14
+
15
+ Args:
16
+ pixel (int): The pixel index starting at 0.
17
+ pixel_num (int): Total number of pixels in the span.
18
+ volt_limits (np.ndarray): A 1D array of shape (2,) containing the start and end voltage values. The start value
19
+ is the first of the two values and the end value is the last one.
20
+
21
+ Returns:
22
+ np.ndarray: The voltage value corresponding to the given pixel index.
23
+ """
24
+ return volt_limits[0] + (volt_limits[1] - volt_limits[0]) * (pixel / pixel_num)
@@ -0,0 +1,43 @@
1
+ """This module contains functions for resetting the sensor to a fixed position.
2
+
3
+ @author: f.hader
4
+ """
5
+
6
+ import numpy as np
7
+
8
+ __all__ = []
9
+
10
+
11
+ def reset_offset_mu_sens(dqd_sim: "Simulation",
12
+ target_mu_sens: float,
13
+ sweep_range_g1: np.ndarray,
14
+ sweep_range_g2: np.ndarray, ):
15
+ """
16
+ Helper function to reset the sensor offset mu sens before measuring a CSD.
17
+
18
+ Can be used to reset the sensor to the steepest point before each CSD measurement. For example, this applies to
19
+ configs generated by sample_random_variations_v3_config with the set_sensor_potential_offset_to_steepest_point
20
+ option, which creates a configuration where the offset corresponds to the steepest point when no voltages are
21
+ applied.
22
+
23
+ **Warning**: This alters the provided Simulation object! Make sure to store the previous sensor offset if you want
24
+ to re-use it later to reset the sensor to this point again.
25
+
26
+ Args:
27
+ dqd_sim (Simulation): SimCATS Simulation object, of which the offset_mu_sens should be adjusted, so that the
28
+ sensor has the specified target_mu_sens at the initial sweep voltages.
29
+ target_mu_sens: The target mu sens to be reached at the initial sweep voltages.
30
+ sweep_range_g1 (np.ndarray): Voltage sweep range of (plunger) gate 1 (second-/x-axis). \n
31
+ Example: \n
32
+ [min_V1, max_V1]
33
+ sweep_range_g2 (np.ndarray): Voltage sweep range of (plunger) gate 2 (first-/y-axis). \n
34
+ Example: \n
35
+ [min_V2, max_V2]
36
+ """
37
+ # calculate potential to reset offset_mu_sens
38
+ occupations, _ = dqd_sim.ideal_csd_config.get_csd_data(volt_limits_g1=sweep_range_g1,
39
+ volt_limits_g2=sweep_range_g2,
40
+ resolution=2)
41
+ potentials = dqd_sim.sensor.sensor_potential(occupations, sweep_range_g1, sweep_range_g2)
42
+ # the new offset is calculated as follows: target_offset - (potentials[0] - current_offset)
43
+ dqd_sim.sensor.offset_mu_sens = target_mu_sens - (potentials[0] - dqd_sim.sensor.offset_mu_sens)
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: simcats
3
- Version: 1.1.0
3
+ Version: 2.0.0
4
4
  Summary: SimCATS is a python framework for simulating charge stability diagrams (CSDs) typically measured during the tuning process of qubits.
5
- Author-email: Fabian Hader <f.hader@fz-juelich.de>, Sarah Fleitmann <s.fleitmann@fz-juelich.de>, Fabian Fuchs <f.fuchs@fz-juelich.de>
6
- License: CC BY-NC-SA 4.0
5
+ Author-email: Fabian Hader <f.hader@fz-juelich.de>, Sarah Fleitmann <s.fleitmann@fz-juelich.de>, Benjamin Papajewski <b.papajewski@fz-juelich.de>, Fabian Fuchs <f.fuchs@fz-juelich.de>, Karin Havemann <k.havemann@fz-juelich.de>, Jan Vogelbruch <j.vogelbruch@fz-juelich.de>
6
+ License-Expression: CC-BY-NC-SA-4.0
7
7
  Project-URL: homepage, https://github.com/f-hader/SimCATS
8
8
  Project-URL: documentation, https://simcats.readthedocs.io
9
9
  Project-URL: source, https://github.com/f-hader/SimCATS
@@ -30,11 +30,37 @@ Requires-Dist: numpy
30
30
  Requires-Dist: opencv-python
31
31
  Requires-Dist: scipy
32
32
  Requires-Dist: sympy
33
+ Dynamic: license-file
34
+
35
+ <h1 align="center">
36
+ <img src="https://raw.githubusercontent.com/f-hader/SimCATS/main/SimCATS_symbol.svg" alt="SimCATS logo">
37
+ <br>
38
+ </h1>
39
+
40
+ <div align="center">
41
+ <a href="https://github.com/f-hader/SimCATS/blob/main/LICENSE">
42
+ <img src="https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg" alt="License: CC BY-NC-SA 4.0"/>
43
+ </a>
44
+ <a href="https://pypi.org/project/simcats/">
45
+ <img src="https://img.shields.io/pypi/v/simcats.svg" alt="PyPi Latest Release"/>
46
+ </a>
47
+ <a href="https://simcats.readthedocs.io/en/latest/">
48
+ <img src="https://img.shields.io/readthedocs/simcats" alt="Read the Docs"/>
49
+ </a>
50
+ <a href="https://doi.org/10.1109/TQE.2024.3445967">
51
+ <img src="https://img.shields.io/badge/DOI (Paper)-10.1109/TQE.2024.3445967-007ec6.svg" alt="DOI Paper"/>
52
+ </a>
53
+ <a href="https://doi.org/10.5281/zenodo.13805205">
54
+ <img src="https://img.shields.io/badge/DOI (Code)-10.5281/zenodo.13805205-007ec6.svg" alt="DOI Code"/>
55
+ </a>
56
+ </div>
33
57
 
34
58
  # SimCATS
35
59
 
36
60
  Simulation of CSDs for Automated Tuning Solutions (`SimCATS`) is a Python framework for simulating charge stability
37
- diagrams (CSDs) typically measured during the tuning process of qubits.
61
+ diagrams (CSDs) typically measured during the tuning process of qubits. <br>
62
+ Starting with version 2.0, the framework additionally allows simulating sensor scans. This enables to simulate the
63
+ (re)configuration of the sensor dot before measuring a CSD.
38
64
 
39
65
  ## Installation
40
66
 
@@ -56,9 +82,10 @@ For the installation in development/editable mode, use the option `-e`.
56
82
  After installing the package, a good starting point is a look into the Jupyter Notebook
57
83
  `example_SimCATS_simulation_class.ipynb`, which provides an overview of the usage of the simulation class offered by
58
84
  the framework.
59
- For more detailed examples and explanations of the geometric ideal CSD simulation using Total Charge Transitions (TCTs), look at the Jupyter Notebook `example_SimCATS_IdealCSDGeometric.ipynb`. This notebook also includes a hint
60
- regarding the generation of required labels for training algorithms that might need line labels defined as start and
61
- end points or require semantic information about particular transitions.
85
+ For more detailed examples and explanations of the geometric ideal CSD simulation using Total Charge Transitions (TCTs),
86
+ look at the Jupyter Notebook `example_SimCATS_IdealCSDGeometric.ipynb`. This notebook also includes a hint regarding the
87
+ generation of required labels for training algorithms that might need line labels defined as start and end points or
88
+ require semantic information about particular transitions.
62
89
 
63
90
  ## Tests
64
91
 
@@ -78,7 +105,8 @@ pytest --cov=simcats -n auto --dist loadfile .\tests\
78
105
 
79
106
  The argument
80
107
  - `--cov=simcats` enables a coverage summary of the `SimCATS` package,
81
- - `-n auto` enables the test to run with multiple threads (auto will choose as many threads as possible, but can be replaced with a specific number of threads to use), and
108
+ - `-n auto` enables the test to run with multiple threads (auto will choose as many threads as possible, but can be
109
+ replaced with a specific number of threads to use), and
82
110
  - `--dist loadfile` specifies that each file should be executed only by one thread.
83
111
 
84
112
  <!-- start sec:documentation -->
@@ -105,8 +133,8 @@ To view the generated HTML documentation, open the file `docs\build\html\index.h
105
133
  The primary user interface for `SimCATS` is the class `Simulation`, which combines all the necessary functionalities to
106
134
  measure (simulate) a CSD and adjust the parameters for the simulated measurement. The class `Simulation` and default
107
135
  configurations for the simulation (`default_configs`) can be imported directly from `simcats`. Aside from that,
108
- `SimCATS` contains the subpackages `ideal_csd`, `sensor`, `distortions`, and `support_functions`, described in
109
- the following sections.
136
+ `SimCATS` contains the subpackages `ideal_csd`, `sensor`, `distortions`, and `support_functions`, described in the
137
+ following sections.
110
138
 
111
139
  ### Module `simulation`
112
140
 
@@ -115,21 +143,24 @@ An instance of the simulation class requires
115
143
  - an implementation of the `IdealCSDInterface` for the simulation of ideal CSD data,
116
144
  - an implementation of the `SensorInterface` for the simulation of the sensor (dot) reaction based on the ideal CSD
117
145
  data, and
118
- - (optionally) implementations of the desired types of distortions, which can be implementations from `OccupationDistortionInterface`, `SensorPotentialDistortionInterface`, or `SensorResponseDistortionInterface`.
146
+ - (optionally) implementations of the desired types of distortions, which can be implementations from
147
+ `OccupationDistortionInterface`, `SensorPotentialDistortionInterface`, or `SensorResponseDistortionInterface`.
119
148
 
120
149
  With an initialized instance of the `Simulation` class, it is possible to run simulations using the `measure` function
121
150
  (see `example_SimCATS_simulation_class.ipynb`).
122
151
 
123
152
  ### Subpackage `ideal_csd`
124
153
 
125
- This subpackage contains the `IdealCSDInterface` used by the `Simulation` class and an implementation of
126
- the `IdealCSDInterface` (`IdealCSDGeometric`) based on our geometric simulation approach.
154
+ This subpackage contains the `IdealCSDInterface` used by the `Simulation` class and an implementation of the
155
+ `IdealCSDInterface` (`IdealCSDGeometric`) based on our geometric simulation approach. Please have a look at the notebook
156
+ `example_SimCATS_IdealCSDGeometric.ipynb` and the `SimCATS` paper for detailed explanations regarding the geometric
157
+ approach.
127
158
  Additionally, it contains in the subpackage `geometric` the functions used by `IdealCSDGeometric`, including the
128
159
  implementation of the total charge transition (TCT) definition and functions for calculating the occupations using TCTs.
129
160
 
130
161
  ### Subpackage `distortions`
131
162
 
132
- The distortions subpackage contains the `DistortionInterface` from which the `OccupationDistortionInterface`, the
163
+ The `distortions` subpackage contains the `DistortionInterface` from which the `OccupationDistortionInterface`, the
133
164
  `SensorPotentialDistortionInterface`, and the `SensorResponseDistortionInterface` are derived. Distortion functions used
134
165
  in the `Simulation` class have to implement these specific interfaces. Implemented distortions included in the
135
166
  subpackage are:
@@ -140,22 +171,41 @@ subpackage are:
140
171
  - dot jumps, simulated using the algorithm described in ["Toward Robust Autotuning of Noisy Quantum Dot Devices" by Ziegler et al.](https://doi.org/10.1103/PhysRevApplied.17.024069) (In the `Simulation` class, this is applied to a whole block of rows or columns, but there is also a function for applying it linewise.), and
141
172
  - lead transition blurring, simulated using Gaussian or Fermi-Dirac blurring.
142
173
 
143
- The implementations also offer the option to set ratios (parameter `ratio`) for the occurrence of the distortion (e.g. dot jumps may only happen sometimes and not in every measurement). Moreover, it is also possible to sample the
144
- noise parameters from a given sampling range using an object of type `ParameterSamplingInterface`.
145
- Classes for randomly sampling from a normal distribution or a uniform distribution within a given range are available in
146
- the subpackage `support_functions`.
147
- In this case, the strength is randomly chosen from the given range for every measurement.
148
- Additionally, it is possible to specify that this range should be a smaller subrange of the provided range.
149
- This allows restricting distortion fluctuations during a simulation while enabling a large variety of different strengths
150
- for the initialization of the objects. <br>
151
- RTN, dot jumps, and lead transition blurring are applied in the pixel domain. However, the jump length or the blurring strength should be consistent in the voltage domain even if the resolution changes. Therefore, the parameters
152
- are given in the voltage domain and adjusted according to the resolution in terms of pixel per voltage. <br>
153
- For a simulated measurement with a continuous voltage sweep involving an averaging for each pixel, the noise strength of the
154
- white and pink noise should be adjusted if the resolution (volt per pixel) changes, due to smoothing out the noise. This smoothing depends on the type of averaging used and is not incorporated in the default implementation.
174
+ The implementations also offer the option to set ratios (parameter `ratio`) for the occurrence of the distortion (e.g.
175
+ dot jumps may only happen sometimes and not in every measurement). Moreover, it is also possible to sample the noise
176
+ parameters from a given sampling range using an object of type `ParameterSamplingInterface`. Classes for randomly
177
+ sampling from a normal distribution or a uniform distribution within a given range are available in the subpackage
178
+ `support_functions`. In this case, the strength is randomly chosen from the given range for every measurement.
179
+ Additionally, it is possible to specify that this range should be a smaller subrange of the provided range. This allows
180
+ restricting distortion fluctuations during a simulation while enabling a large variety of different strengths for the
181
+ initialization of the objects. <br>
182
+ RTN, dot jumps, and lead transition blurring are applied in the pixel domain. However, the jump length or the blurring
183
+ strength should be consistent in the voltage domain even if the resolution changes. Therefore, the parameters are given
184
+ in the voltage domain and adjusted according to the resolution in terms of pixel per voltage. <br>
185
+ For a simulated measurement with a continuous voltage sweep involving an averaging for each pixel, the noise strength of
186
+ the white and pink noise should be adjusted if the resolution (volt per pixel) changes, due to smoothing out the noise.
187
+ This smoothing depends on the type of averaging used and is not incorporated in the default implementation.
155
188
 
156
189
  ### Subpackage `sensor`
157
190
 
158
- This subpackage contains the `SensorInterface` that defines how a sensor simulation must be implemented to be used by the `Simulation` class. The `SensorPeakInterface` provides the desired representation for the definition of the Coulomb peaks the sensor uses. `SensorGeneric` implements the `SensorInterface` and offers functions for simulating the sensor response and potential. It offers the possibility to simulate with a single peak or multiple sensor peaks. Current implementations of the `SensorPeakInterface` are `SensorPeakGaussian` and `SensorPeakLorentzian`.
191
+ This subpackage contains the `SensorInterface` that defines how a sensor simulation must be implemented to be used by
192
+ the `Simulation` class. The `SensorPeakInterface` provides the desired representation for the definition of the Coulomb
193
+ peaks the sensor uses. `SensorGeneric` implements the `SensorInterface` and offers functions for simulating the sensor
194
+ response and potential. It offers the possibility to simulate with a single peak or multiple sensor peaks. Current
195
+ implementations of the `SensorPeakInterface` are `SensorPeakGaussian` and `SensorPeakLorentzian`. <br>
196
+ Starting with version 2.0, an extension of the `SensorInterface` called `SensorScanSensorInterface` is available.
197
+ Implementations of this interface allow simulating sensor scans in addition to CSDs. This enables to simulate the
198
+ (re)configuration of the sensor dot before measuring a CSD. `SensorScanSensorGeneric` implements the
199
+ `SensorScanSensorInterface`, modeling the sensor dot as three resistors in series (barrier, dot, barrier). The function
200
+ describing the dot is similar to the function in the `SensorGeneric`, but has an additional final rise of the signal
201
+ after the last Coulomb peak (an implementation of the `SensorRiseInterface`). A new interface called
202
+ `BarrierFunctionInterface` defines how the barrier functions must be implemented. These functions, which basically model
203
+ the shape of a pinch-off measurement, are currently implemented using generalized logistic functions
204
+ (`BarrierFunctionGLF`, `BarrierFunctionMultiGLF`). The potentials for both barriers and the dot itself are calculated
205
+ from the applied voltages and provided lever-arms. Then, the barrier and dot functions are applied to calculate the
206
+ individual conductances. Finally, these conductances are combined to retrieve the sensor signal (proportional to the
207
+ total conductance across the sensor dot).
208
+
159
209
 
160
210
  ### Subpackage `support_functions`
161
211
 
@@ -166,6 +216,20 @@ This subpackage contains support functions, which are used by the end user and b
166
216
  - `ParameterSamplingInterface` defines an interface for randomly sampled (fluctuated) strengths of distortions.
167
217
  - `NormalSamplingRange` and `UniformSamplingRange` are implementations of the `ParameterSamplingInterface`.
168
218
 
219
+ ## Citations
220
+
221
+ ```bibtex
222
+ @article{hader2024simcats,
223
+ author={Hader, Fabian and Fleitmann, Sarah and Vogelbruch, Jan and Geck, Lotte and Waasen, Stefan van},
224
+ journal={IEEE Transactions on Quantum Engineering},
225
+ title={Simulation of Charge Stability Diagrams for Automated Tuning Solutions (SimCATS)},
226
+ year={2024},
227
+ volume={5},
228
+ pages={1-14},
229
+ doi={10.1109/TQE.2024.3445967}
230
+ }
231
+ ```
232
+
169
233
  ## License, CLA, and Copyright
170
234
 
171
235
  [![CC BY-NC-SA 4.0][cc-by-nc-sa-shield]][cc-by-nc-sa]
@@ -181,4 +245,4 @@ This work is licensed under a
181
245
 
182
246
  Contributions must follow the Contributor License Agreement. For more information, see the CONTRIBUTING.md file at the top of the GitHub repository.
183
247
 
184
- Copyright © 2023 Forschungszentrum Jülich GmbH - Central Institute of Engineering, Electronics and Analytics (ZEA) - Electronic Systems (ZEA-2)
248
+ Copyright © 2026 Peter Grünberg Institute - Integrated Computing Architectures (ICA / PGI-4), Forschungszentrum Jülich GmbH
@@ -0,0 +1,53 @@
1
+ simcats/__init__.py,sha256=BCQvUsAPnS3939FRFakyDF1xwem2JXaWr2qxOrUDr70,316
2
+ simcats/_default_configs.py,sha256=_Q8LWGeplNaKRTexNrN4rOVQAOrF-rFMvWtci1-0w18,16061
3
+ simcats/_simulation.py,sha256=2Ti-aZpD9rqKe_iDTgKn-ttH3tqEbzXbxtPWm8gepjY,45747
4
+ simcats/config_samplers/_GaAs_v1_random_variations_v3_config_sampler.py,sha256=dKswkcEFWGPFDlh2uUtA2psiugZHQFJbcc6dN7bWqrI,53839
5
+ simcats/config_samplers/__init__.py,sha256=2zcXSBoP7FZP88INUQluBPqZr1_RwE5U0B71rrUE_ew,281
6
+ simcats/distortions/__init__.py,sha256=3oXqKm1rkznDKhWeitZxYJyb1wFMdan6CBfBw673J7A,1368
7
+ simcats/distortions/_distortion_interfaces.py,sha256=fHQsgyFNfLdKwWj24_5DvF5GwLFZIDeLwQ424s-P6J0,6714
8
+ simcats/distortions/_dot_jumps.py,sha256=-fCC_FOYFhqFQQYSIcvrjd9H0cQHiOfR87YhENbSTPQ,38469
9
+ simcats/distortions/_pink_noise.py,sha256=2-ZvNAvtsypNHqLXN_FfGR-iWnAGgXWZxTS7LKk73pQ,5233
10
+ simcats/distortions/_random_telegraph_noise.py,sha256=sY8iK_3LElICujBa98xZjoi-to_Z0pySCCibLQ8q5mQ,16844
11
+ simcats/distortions/_transition_blurring.py,sha256=RsBA_wZkL1_vux8wu2aNI0s7uI36Z3szCIOa6P_gIw4,13629
12
+ simcats/distortions/_white_noise.py,sha256=4yr5UhQ1sQftj1jVspGsUaSoYob334DBKoQeB3k63oE,4420
13
+ simcats/ideal_csd/__init__.py,sha256=jxQkBf_z1xIclUcqeur6OVzrFJhd9eAXFF9PJdb091I,316
14
+ simcats/ideal_csd/_ideal_csd_interface.py,sha256=3PjLgv_MjIlN2YqbpLwrJysukntftZSBCrBBPwe0HSA,2334
15
+ simcats/ideal_csd/geometric/__init__.py,sha256=uXqR4qGbBcTQ8WdIO56ZxHWXqbn85yvuVlm5zJV7iVc,927
16
+ simcats/ideal_csd/geometric/_calculate_all_bezier_anchors.py,sha256=AvSsOsiu5H3HKoJwwZ1797T3yHoRc6Rj2YT-JJujaIY,6491
17
+ simcats/ideal_csd/geometric/_generate_lead_transition_mask.py,sha256=Q5lqfn8OuBW6HjYCWmJIb0dyvISz6ftnDrQIRFuiT3I,6313
18
+ simcats/ideal_csd/geometric/_get_electron_occupation.py,sha256=A3srfb700sX8v0SRG4rhVMA7XxvyottO5_8fR7VlzrY,13452
19
+ simcats/ideal_csd/geometric/_ideal_csd_geometric.py,sha256=nPrIFMuO3YD38jWn8yXw0b6exWAv8OWcO6aPryprrLQ,10075
20
+ simcats/ideal_csd/geometric/_ideal_csd_geometric_class.py,sha256=xMzzVW85NoqOnAM30Er0YlsWvB8l1a1lqAMYLCdItrA,7467
21
+ simcats/ideal_csd/geometric/_initialize_tct_functions.py,sha256=z1rCkKLM68e97xQkdwnUq5DGuCkHiOADRfwiDb2I3kE,3161
22
+ simcats/ideal_csd/geometric/_tct_bezier.py,sha256=3eUn6LFVOYXXI6-srV0MPUDMK2fddq1afUY6FDSGmCk,12065
23
+ simcats/sensor/__init__.py,sha256=KAn5mv7AJI-Np8no9FHdYOvQUCRGUB1M6FLNuMvvml8,913
24
+ simcats/sensor/_sensor_generic.py,sha256=HIzIcWw8AvFBKAvDNNssluWEOySx9GvrtmopsaC4bjA,10453
25
+ simcats/sensor/_sensor_interface.py,sha256=URtfjqhVCKw-VCKi4sE1Hb-9Xj-RqORJCqJOekwCcgg,15009
26
+ simcats/sensor/_sensor_peak_gaussian.py,sha256=7xrSfl505MygBJ7Nu3V3RJpNq8q-mjukVDcrL-ezEuA,4039
27
+ simcats/sensor/_sensor_peak_lorentzian.py,sha256=Rj3Tpk6dksZGfOAHhdSGQR-wJo3ehdmXnumXyGuaNC4,3952
28
+ simcats/sensor/_sensor_rise_glf.py,sha256=CXXLNijyID1k2p3YgLJRm7YT5ehmYGtf15Ru7wX4XUE,11470
29
+ simcats/sensor/_sensor_scan_sensor_generic.py,sha256=DLxZ29WVH4f441T72qe5Tx34fkO8e5qnKowBMvJwlqE,55927
30
+ simcats/sensor/barrier_function/__init__.py,sha256=BI5RFhG3gYwT2h77TMkjwhBlc4MMk-xWmed0Jt5d0zg,487
31
+ simcats/sensor/barrier_function/_barrier_function_glf.py,sha256=RjpVc1jbVSSOuKEAP0S1ir8Vt28DpFWf7RQkUl5i8sQ,14296
32
+ simcats/sensor/barrier_function/_barrier_function_interface.py,sha256=LR6MX9zQQm0SDhoglXcaLLgAIIFXtQOJAMgZ5NJ6buo,1269
33
+ simcats/sensor/barrier_function/_barrier_function_multi_glf.py,sha256=BC93k3h1b7KaiTDsCd2YuqqdgKptUznFmA6JkqnG07w,9101
34
+ simcats/sensor/deformation/__init__.py,sha256=6LZVjyRc1LVcIpBzIX4iI3zwo84NvfBqOiaHE-dq1JU,538
35
+ simcats/sensor/deformation/_sensor_peak_deformation_circle.py,sha256=Q4hsYaZWu2xKB1buMwotPqW2RFe7ddqbN7PDzkiICIw,5264
36
+ simcats/sensor/deformation/_sensor_peak_deformation_interface.py,sha256=48kqIaqCKP358l78viqthMQh0ldvkGyiXW0bUxjB3UU,2450
37
+ simcats/sensor/deformation/_sensor_peak_deformation_linear.py,sha256=3sznbTlpw5Ii0IodczHyeSkQ0gKZLRrPInOdetJmNDg,3199
38
+ simcats/support_functions/__init__.py,sha256=bmc7WrjS-TucMmPq-hk15fZdMWrnRLD7rnk1UZRZ5fI,1762
39
+ simcats/support_functions/_cumulative_distribution_functions.py,sha256=pE01RoSL2VwtkBP7xYivd-vcd6krSJrb4xb8MCfyRBA,3366
40
+ simcats/support_functions/_fermi_filter1d.py,sha256=F4GrdLt0bOXidRdg0P-163Op-bxKvgHte3ENI39qYAk,3706
41
+ simcats/support_functions/_generalized_logistic_function.py,sha256=XG8IbO3KMP9KhXpyMs1mFoO6wzd68LOBrf9yIo_4ncA,10229
42
+ simcats/support_functions/_linear_algebra.py,sha256=xV6Eup1DmZBm7fiwPc6qUD0ayIAC2yJQMeq0XnCmWTc,6927
43
+ simcats/support_functions/_parameter_sampling.py,sha256=Dsy_CF143vNEriKNWgZjo06Rfastc-2jKmt96yrDjhc,15304
44
+ simcats/support_functions/_pixel_volt_transformation.py,sha256=qDXK1fRSQrwcpf0b6xA9IC9ott6DdZMeiuQZ3-QSFoA,1060
45
+ simcats/support_functions/_plotting.py,sha256=xc050m4W6RZm8XdOdqruc-6IYyhzW9UFvNlJEgkJRi8,9070
46
+ simcats/support_functions/_reset_offset_mu_sens.py,sha256=YR4Eed3FQIpIjOXrMcaLQJR6eJknKIKQd1OKwpgJGEg,2218
47
+ simcats/support_functions/_rotate_points.py,sha256=4tgzE4a4uykBVw2pSK55DzGe-5n9N38nsBYhfA38Qgs,778
48
+ simcats/support_functions/_signed_dist_points_line.py,sha256=dMnDoBARY7C48xCHFp8mNFNCkPk7YUiaWaRqAsindsE,908
49
+ simcats-2.0.0.dist-info/licenses/LICENSE,sha256=aZs_e2FTt6geKaC1hd9FpoxERpb5YHhxJ608urp4nig,21294
50
+ simcats-2.0.0.dist-info/METADATA,sha256=3lpZyrw5nGv9GqjAluWLm4rNa2aquH6lnAfbaTkvqxA,13908
51
+ simcats-2.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
52
+ simcats-2.0.0.dist-info/top_level.txt,sha256=M-ExkkJ_NLsuuJiDo3iM2qPPPsEX29E2MQUmegBZ8Wk,8
53
+ simcats-2.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.42.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,37 +0,0 @@
1
- simcats/__init__.py,sha256=v8TOUudnx9Q6cNwoVjZkvmHv3VmZCTqEfR7D5sDbUA0,300
2
- simcats/_default_configs.py,sha256=wHWa4wyTVtZf9J37WdcMlvM7XeI_OZhl8NB7lrBi-yI,6980
3
- simcats/_simulation.py,sha256=xvKLnOzwc8uGGLfXvBZPaLYYPHBaXcwwtlYmJ3zTkUU,24795
4
- simcats/distortions/__init__.py,sha256=3oXqKm1rkznDKhWeitZxYJyb1wFMdan6CBfBw673J7A,1368
5
- simcats/distortions/_distortion_interfaces.py,sha256=8twWE8FX8fqiLlxrcSOBaMZCc3boDbE6n_b4587-ra4,6717
6
- simcats/distortions/_dot_jumps.py,sha256=6segzH8VWaUlRPMcWjkDacwyCcN8bPhfWyrYQD8UaoA,38162
7
- simcats/distortions/_pink_noise.py,sha256=2-ZvNAvtsypNHqLXN_FfGR-iWnAGgXWZxTS7LKk73pQ,5233
8
- simcats/distortions/_random_telegraph_noise.py,sha256=psRV-tosDXHC0xBSZyrKZAgRBMQoxSeeDTRIpUsJ9hg,16785
9
- simcats/distortions/_transition_blurring.py,sha256=3kryfx3VEnJpAgPfoJF-Z4leoSFrzGUwf-5mb8bXD3o,13631
10
- simcats/distortions/_white_noise.py,sha256=toxal_V2aPxxqoxpsJz3-lH7rtNjzsz5aoTbgNhiWxU,4413
11
- simcats/ideal_csd/__init__.py,sha256=jxQkBf_z1xIclUcqeur6OVzrFJhd9eAXFF9PJdb091I,316
12
- simcats/ideal_csd/_ideal_csd_interface.py,sha256=3PjLgv_MjIlN2YqbpLwrJysukntftZSBCrBBPwe0HSA,2334
13
- simcats/ideal_csd/geometric/__init__.py,sha256=uXqR4qGbBcTQ8WdIO56ZxHWXqbn85yvuVlm5zJV7iVc,927
14
- simcats/ideal_csd/geometric/_calculate_all_bezier_anchors.py,sha256=AvSsOsiu5H3HKoJwwZ1797T3yHoRc6Rj2YT-JJujaIY,6491
15
- simcats/ideal_csd/geometric/_generate_lead_transition_mask.py,sha256=QOYSNSy5IHiNefmC37KsuM3484xJfsl8yNeo4o5Xdws,6316
16
- simcats/ideal_csd/geometric/_get_electron_occupation.py,sha256=rEW9guTxM4pTGy9vtQ34NP4zxRaMNk-LQstfCkq4OEw,13461
17
- simcats/ideal_csd/geometric/_ideal_csd_geometric.py,sha256=gpYVgRx_rRB46FyaKntg9CWIpGSP4uroJGeyeufmoKE,10077
18
- simcats/ideal_csd/geometric/_ideal_csd_geometric_class.py,sha256=Qx1IQy4NX4gtkFQGBaQRxjW46urv95mMQI_enWRUl4M,7481
19
- simcats/ideal_csd/geometric/_initialize_tct_functions.py,sha256=z1rCkKLM68e97xQkdwnUq5DGuCkHiOADRfwiDb2I3kE,3161
20
- simcats/ideal_csd/geometric/_tct_bezier.py,sha256=xDBlEylwYvnX-xOdUt-N7P7k9i0yzTce9b3dXZa_Zx4,12067
21
- simcats/sensor/__init__.py,sha256=v9aG6_WGYF5Dq_OFHHn2NQxZx2X2HGg0nkglz5wSoHw,611
22
- simcats/sensor/_gaussian_sensor_peak.py,sha256=7xrSfl505MygBJ7Nu3V3RJpNq8q-mjukVDcrL-ezEuA,4039
23
- simcats/sensor/_generic_sensor.py,sha256=88E6xP3r5GZCBKaR7TKtqrWovR4XW-mm6YUwL96L_AQ,10441
24
- simcats/sensor/_lorentzian_sensor_peak.py,sha256=Rj3Tpk6dksZGfOAHhdSGQR-wJo3ehdmXnumXyGuaNC4,3952
25
- simcats/sensor/_sensor_interface.py,sha256=mn5L9WbAIMun_ou0AHgOV6XiBeykYPugndLAeufadTo,5064
26
- simcats/support_functions/__init__.py,sha256=cSJXeCLuquzZFoY_dLY4B2nTT08Ngpch1FMfYDzkiSg,1032
27
- simcats/support_functions/_cumulative_distribution_functions.py,sha256=pE01RoSL2VwtkBP7xYivd-vcd6krSJrb4xb8MCfyRBA,3366
28
- simcats/support_functions/_fermi_filter1d.py,sha256=F4GrdLt0bOXidRdg0P-163Op-bxKvgHte3ENI39qYAk,3706
29
- simcats/support_functions/_parameter_sampling.py,sha256=0TYceyE3ejLtZZ-ofCJ3icTKFpUvHf1xZycVIbHWxfE,10555
30
- simcats/support_functions/_plotting.py,sha256=xc050m4W6RZm8XdOdqruc-6IYyhzW9UFvNlJEgkJRi8,9070
31
- simcats/support_functions/_rotate_points.py,sha256=4tgzE4a4uykBVw2pSK55DzGe-5n9N38nsBYhfA38Qgs,778
32
- simcats/support_functions/_signed_dist_points_line.py,sha256=dMnDoBARY7C48xCHFp8mNFNCkPk7YUiaWaRqAsindsE,908
33
- simcats-1.1.0.dist-info/LICENSE,sha256=aZs_e2FTt6geKaC1hd9FpoxERpb5YHhxJ608urp4nig,21294
34
- simcats-1.1.0.dist-info/METADATA,sha256=u-ZTqGo-9AKHdgQTs7pv_zvqhklIXHlBMja7vK3x0hs,10680
35
- simcats-1.1.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
36
- simcats-1.1.0.dist-info/top_level.txt,sha256=M-ExkkJ_NLsuuJiDo3iM2qPPPsEX29E2MQUmegBZ8Wk,8
37
- simcats-1.1.0.dist-info/RECORD,,