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.
- simcats/__init__.py +4 -3
- simcats/_default_configs.py +129 -13
- simcats/_simulation.py +451 -69
- simcats/config_samplers/_GaAs_v1_random_variations_v3_config_sampler.py +1059 -0
- simcats/config_samplers/__init__.py +9 -0
- simcats/distortions/_distortion_interfaces.py +1 -1
- simcats/distortions/_dot_jumps.py +8 -6
- simcats/distortions/_random_telegraph_noise.py +4 -4
- simcats/distortions/_transition_blurring.py +5 -5
- simcats/distortions/_white_noise.py +2 -2
- simcats/ideal_csd/geometric/_generate_lead_transition_mask.py +3 -3
- simcats/ideal_csd/geometric/_get_electron_occupation.py +5 -5
- simcats/ideal_csd/geometric/_ideal_csd_geometric.py +5 -5
- simcats/ideal_csd/geometric/_ideal_csd_geometric_class.py +9 -9
- simcats/ideal_csd/geometric/_tct_bezier.py +5 -5
- simcats/sensor/__init__.py +10 -6
- simcats/sensor/{_generic_sensor.py → _sensor_generic.py} +1 -1
- simcats/sensor/_sensor_interface.py +164 -11
- simcats/sensor/_sensor_rise_glf.py +229 -0
- simcats/sensor/_sensor_scan_sensor_generic.py +929 -0
- simcats/sensor/barrier_function/__init__.py +9 -0
- simcats/sensor/barrier_function/_barrier_function_glf.py +280 -0
- simcats/sensor/barrier_function/_barrier_function_interface.py +43 -0
- simcats/sensor/barrier_function/_barrier_function_multi_glf.py +157 -0
- simcats/sensor/deformation/__init__.py +9 -0
- simcats/sensor/deformation/_sensor_peak_deformation_circle.py +109 -0
- simcats/sensor/deformation/_sensor_peak_deformation_interface.py +65 -0
- simcats/sensor/deformation/_sensor_peak_deformation_linear.py +77 -0
- simcats/support_functions/__init__.py +11 -3
- simcats/support_functions/_generalized_logistic_function.py +146 -0
- simcats/support_functions/_linear_algebra.py +171 -0
- simcats/support_functions/_parameter_sampling.py +108 -19
- simcats/support_functions/_pixel_volt_transformation.py +24 -0
- simcats/support_functions/_reset_offset_mu_sens.py +43 -0
- {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/METADATA +93 -29
- simcats-2.0.0.dist-info/RECORD +53 -0
- {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/WHEEL +1 -1
- simcats-1.1.0.dist-info/RECORD +0 -37
- /simcats/sensor/{_gaussian_sensor_peak.py → _sensor_peak_gaussian.py} +0 -0
- /simcats/sensor/{_lorentzian_sensor_peak.py → _sensor_peak_lorentzian.py} +0 -0
- {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {simcats-1.1.0.dist-info → simcats-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SimCATS subpackage of the sensor package containing all functionalities related to barrier functions.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from simcats.sensor.barrier_function._barrier_function_interface import BarrierFunctionInterface
|
|
6
|
+
from simcats.sensor.barrier_function._barrier_function_glf import BarrierFunctionGLF
|
|
7
|
+
from simcats.sensor.barrier_function._barrier_function_multi_glf import BarrierFunctionMultiGLF
|
|
8
|
+
|
|
9
|
+
__all__ = ['BarrierFunctionInterface', 'BarrierFunctionGLF', 'BarrierFunctionMultiGLF']
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"""This module contains a class that models the conductivity of a barrier using the generalized logistic function (GLF).
|
|
2
|
+
|
|
3
|
+
@author: b.papajewski
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Union
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from simcats.sensor.barrier_function import BarrierFunctionInterface
|
|
11
|
+
from simcats.support_functions import glf, inverse_glf
|
|
12
|
+
|
|
13
|
+
__all__ = []
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BarrierFunctionGLF(BarrierFunctionInterface):
|
|
17
|
+
"""Implementation of the BarrierFunctionInterface that models a conductivity off of a barrier using a generalized logistic function (GLF).
|
|
18
|
+
|
|
19
|
+
For further information see: https://en.wikipedia.org/wiki/Generalised_logistic_function
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, pinch_off_percentage: float, fully_conductive_percentage: float, asymptote_left: float,
|
|
23
|
+
asymptote_right: float, growth_rate: float, asymmetry: float, shape_factor: float,
|
|
24
|
+
denominator_offset: float = 1, offset: float = 0):
|
|
25
|
+
"""
|
|
26
|
+
Initializes an object of the class to represent the barrier function using the generalized logistic function.
|
|
27
|
+
For further information see: https://en.wikipedia.org/wiki/Generalised_logistic_function
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
pinch_off_percentage (float): Percentage of the GLF height before which the barrier response is
|
|
31
|
+
considered non-conductive. The height is defined as the absolute difference between the two asymptotes.
|
|
32
|
+
fully_conductive_percentage (float): Percentage of the GLF height after which the barrier response is
|
|
33
|
+
considered fully conductive. The height is defined as the absolute difference between the two
|
|
34
|
+
asymptotes.
|
|
35
|
+
asymptote_left (float): Originally called A. This parameter is the left horizontal asymptote of the
|
|
36
|
+
function. Any rational number can be used as the left asymptote. This parameter may take any rational
|
|
37
|
+
number.
|
|
38
|
+
asymptote_right (float): Originally called K. Specifies the right horizontal asymptote of the function
|
|
39
|
+
when denominator_offset=1. If asymptote_left=0 and denominator_offset=1 then this parameter is also
|
|
40
|
+
called the carrying capacity. This parameter may take any rational number.
|
|
41
|
+
growth_rate (float): Originally called B. The growth rate of the function. The value must be a float and can
|
|
42
|
+
be any rational number. Be careful with negative values, because the function is mirrored on a vertical
|
|
43
|
+
straight line for these. This line passes through the point where the potential equals `offset`.
|
|
44
|
+
asymmetry (float): Originally called nu. This parameter introduces skew and affects symmetry. It also
|
|
45
|
+
affects near which asymptote maximum growth occurs. The value of asymmetry must be a rational number
|
|
46
|
+
greater than zero. \n
|
|
47
|
+
- `asymmetry > 1`: the curve rises more gradually before the midpoint and more sharply after. \n
|
|
48
|
+
- `asymmetry < 1`: the curve rises quickly early on and levels off more slowly.
|
|
49
|
+
shape_factor (float): Originally called Q. is related to the value Y(0) and adjusts the curve's value at the
|
|
50
|
+
y-intercept. Thereby it changes the shape of the function without changing the asymptotes. The shape
|
|
51
|
+
factor can be any rational number.
|
|
52
|
+
denominator_offset (float): Originally called C. A constant added to the denominator inside the power.
|
|
53
|
+
Controls the initial level of the denominator.This parameter must be a rational number. It typically
|
|
54
|
+
takes a value of 1. Otherwise, the upper asymptote is \n
|
|
55
|
+
asymptote_left + (asymptote_right-asymptote_left)/(denominator_offset^(1/asymmetry)).
|
|
56
|
+
offset (float): Potential offset that shifts the GLF starting from the zero point. If the offset is
|
|
57
|
+
positive, the function is shifted to the right and if it is negative, it is shifted to the left. Default
|
|
58
|
+
is 0.
|
|
59
|
+
"""
|
|
60
|
+
self.pinch_off_percentage = pinch_off_percentage
|
|
61
|
+
self.fully_conductive_percentage = fully_conductive_percentage
|
|
62
|
+
self.asymptote_left = asymptote_left
|
|
63
|
+
self.asymptote_right = asymptote_right
|
|
64
|
+
self.growth_rate = growth_rate
|
|
65
|
+
self.asymmetry = asymmetry
|
|
66
|
+
self.shape_factor = shape_factor
|
|
67
|
+
self.denominator_offset = denominator_offset
|
|
68
|
+
self.offset = offset
|
|
69
|
+
|
|
70
|
+
def get_value(self, potential: Union[float, np.ndarray]) -> float:
|
|
71
|
+
"""Returns the value of the barrier function for a given potential.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
potential (Union[float, np.ndarray]): Potential for which the conductance of the barrier function is to be
|
|
75
|
+
calculated.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Union[float, np.ndarray]: Value of the barrier function for a given potential.
|
|
79
|
+
"""
|
|
80
|
+
return glf(potential=potential, asymptote_left=self.asymptote_left, asymptote_right=self.asymptote_right,
|
|
81
|
+
growth_rate=self.growth_rate, asymmetry=self.asymmetry, shape_factor=self.shape_factor,
|
|
82
|
+
denominator_offset=self.denominator_offset, offset=self.offset)
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def pinch_off(self) -> float:
|
|
86
|
+
"""Potential value of the pinch off."""
|
|
87
|
+
return inverse_glf(
|
|
88
|
+
value=np.abs(self.asymptote_right - self.asymptote_left) * self.pinch_off_percentage + np.min(
|
|
89
|
+
[self.asymptote_left, self.asymptote_right]),
|
|
90
|
+
asymptote_left=self.asymptote_left,
|
|
91
|
+
asymptote_right=self.asymptote_right,
|
|
92
|
+
growth_rate=self.growth_rate,
|
|
93
|
+
asymmetry=self.asymmetry,
|
|
94
|
+
shape_factor=self.shape_factor,
|
|
95
|
+
denominator_offset=self.denominator_offset,
|
|
96
|
+
offset=self.offset
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def pinch_off_percentage(self) -> float:
|
|
101
|
+
"""Percentage of the GLF height before which the barrier response is considered non-conductive. The height is
|
|
102
|
+
defined as the absolute difference between the two asymptotes."""
|
|
103
|
+
return self.__pinch_off_percentage
|
|
104
|
+
|
|
105
|
+
@pinch_off_percentage.setter
|
|
106
|
+
def pinch_off_percentage(self, pinch_off_percentage: float) -> None:
|
|
107
|
+
"""Updates the pinch of percentage.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
pinch_off_percentage (float): Potential value of the pinch off
|
|
111
|
+
"""
|
|
112
|
+
self.__pinch_off_percentage = pinch_off_percentage
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def fully_conductive(self) -> float:
|
|
116
|
+
"""Potential value of the point from which on the barrier vanishes and becomes fully conductive."""
|
|
117
|
+
return inverse_glf(
|
|
118
|
+
value=np.abs(self.asymptote_right - self.asymptote_left) * self.fully_conductive_percentage + np.min(
|
|
119
|
+
[self.asymptote_left, self.asymptote_right]),
|
|
120
|
+
asymptote_left=self.asymptote_left,
|
|
121
|
+
asymptote_right=self.asymptote_right,
|
|
122
|
+
growth_rate=self.growth_rate,
|
|
123
|
+
asymmetry=self.asymmetry,
|
|
124
|
+
shape_factor=self.shape_factor,
|
|
125
|
+
denominator_offset=self.denominator_offset,
|
|
126
|
+
offset=self.offset
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def fully_conductive_percentage(self) -> float:
|
|
131
|
+
"""Percentage of the GLF height after which the barrier response is considered fully conductive. The height is
|
|
132
|
+
defined as the absolute difference between the two asymptotes."""
|
|
133
|
+
return self.__fully_conductive_percentage
|
|
134
|
+
|
|
135
|
+
@fully_conductive_percentage.setter
|
|
136
|
+
def fully_conductive_percentage(self, fully_conductive_percentage: float) -> None:
|
|
137
|
+
"""Updates the fully conductive percentage.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
fully_conductive_percentage (float): Potential value of the fully conductive point.
|
|
141
|
+
"""
|
|
142
|
+
self.__fully_conductive_percentage = fully_conductive_percentage
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def asymptote_left(self):
|
|
146
|
+
"""Originally called A. This parameter is the left horizontal asymptote of the function. Any rational number can
|
|
147
|
+
be used as the left asymptote. This parameter may take any rational number.
|
|
148
|
+
"""
|
|
149
|
+
return self.__asymptote_left
|
|
150
|
+
|
|
151
|
+
@asymptote_left.setter
|
|
152
|
+
def asymptote_left(self, asymptote_left: float) -> None:
|
|
153
|
+
"""Updates the left horizontal asymptote of the GLF.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
asymptote_left (float): Left horizontal asymptote of the GLF. The value must be a float and can be any
|
|
157
|
+
rational number.
|
|
158
|
+
"""
|
|
159
|
+
self.__asymptote_left = asymptote_left
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def asymptote_right(self):
|
|
163
|
+
"""Originally called K. Specifies the right horizontal asymptote of the function when denominator_offset=1. If
|
|
164
|
+
asymptote_left=0 and denominator_offset=1 then this parameter is also called the carrying capacity. This
|
|
165
|
+
parameter may take any rational number.
|
|
166
|
+
"""
|
|
167
|
+
return self.__asymptote_right
|
|
168
|
+
|
|
169
|
+
@asymptote_right.setter
|
|
170
|
+
def asymptote_right(self, asymptote_right: float) -> None:
|
|
171
|
+
"""Updates the right horizontal asymptote of the GLF.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
asymptote_right (float): Right horizontal asymptote of the GLF. The value must be a float and can be any
|
|
175
|
+
rational number.
|
|
176
|
+
"""
|
|
177
|
+
self.__asymptote_right = asymptote_right
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def growth_rate(self):
|
|
181
|
+
"""Originally called B. The growth rate of the function. The value must be a float and can´be any rational
|
|
182
|
+
number. Be careful with negative values, because the function is mirrored on a vertical straight line for these.
|
|
183
|
+
This line passes through the point where the potential equals `offset`.
|
|
184
|
+
"""
|
|
185
|
+
return self.__growth_rate
|
|
186
|
+
|
|
187
|
+
@growth_rate.setter
|
|
188
|
+
def growth_rate(self, growth_rate: float) -> None:
|
|
189
|
+
"""Updates the growth rate of the GLF.
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
growth_rate (float): Growth rate of the GLF. The value must be a float and can be any rational number.
|
|
193
|
+
"""
|
|
194
|
+
self.__growth_rate = growth_rate
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def asymmetry(self):
|
|
198
|
+
"""Originally called nu. This parameter introduces skew and affects symmetry. It also affects near which
|
|
199
|
+
asymptote maximum growth occurs. The value of asymmetry must be a rational number greater than zero. \n
|
|
200
|
+
- If `asymmetry > 1`: the curve rises more gradually before the midpoint and more sharply after. \n
|
|
201
|
+
- If `asymmetry < 1`: the curve rises quickly early on and levels off more slowly.
|
|
202
|
+
"""
|
|
203
|
+
return self.__asymmetry
|
|
204
|
+
|
|
205
|
+
@asymmetry.setter
|
|
206
|
+
def asymmetry(self, asymmetry: float) -> None:
|
|
207
|
+
"""Updates asymmetry, which affects near which asymptote maximum growth occurs. The value of asymmetry must be
|
|
208
|
+
a rational number greater than zero.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
asymmetry (float): Asymmetry of the GLF. The value must be a float and can be any rational number greater
|
|
212
|
+
than zero.
|
|
213
|
+
"""
|
|
214
|
+
if asymmetry <= 0:
|
|
215
|
+
raise ValueError(f"asymmetry should be positive, but was {asymmetry}")
|
|
216
|
+
self.__asymmetry = asymmetry
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def shape_factor(self):
|
|
220
|
+
"""Originally called Q. is related to the value Y(0) and adjusts the curve’s value at the y-intercept. Thereby
|
|
221
|
+
it changes the shape of the function without changing the asymptotes. The shape factor can be any rational
|
|
222
|
+
number."""
|
|
223
|
+
return self.__shape_factor
|
|
224
|
+
|
|
225
|
+
@shape_factor.setter
|
|
226
|
+
def shape_factor(self, shape_factor: float) -> None:
|
|
227
|
+
"""Updates shape_factor, which is related the value Y(0). The value can be any rational number.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
shape_factor (float): Shape factor of the GLF. The value must be a float and can be any rational number.
|
|
231
|
+
"""
|
|
232
|
+
self.__shape_factor = shape_factor
|
|
233
|
+
|
|
234
|
+
@property
|
|
235
|
+
def denominator_offset(self) -> float:
|
|
236
|
+
"""Originally called C. A constant added to the denominator inside the power. Controls the initial level of the
|
|
237
|
+
denominator.This parameter must be a rational number. It typically takes a value of 1. Otherwise, the upper
|
|
238
|
+
asymptote is \n
|
|
239
|
+
asymptote_left + (asymptote_right-asymptote_left)/(denominator_offset^(1/asymmetry)).
|
|
240
|
+
"""
|
|
241
|
+
return self.__denominator_offset
|
|
242
|
+
|
|
243
|
+
@denominator_offset.setter
|
|
244
|
+
def denominator_offset(self, denominator_offset: float) -> None:
|
|
245
|
+
"""Originally called C. A constant added to the denominator inside the power. Controls the initial level of the
|
|
246
|
+
denominator.This parameter must be a rational number. It typically takes a value of 1. Otherwise, the upper
|
|
247
|
+
asymptote is \n
|
|
248
|
+
asymptote_left + (asymptote_right-asymptote_left)/(denominator_offset^(1/asymmetry)).
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
denominator_offset (float): Denominator offset of the GLF. The value must be a float and can be any rational
|
|
252
|
+
number.
|
|
253
|
+
"""
|
|
254
|
+
self.__denominator_offset = denominator_offset
|
|
255
|
+
|
|
256
|
+
@property
|
|
257
|
+
def offset(self) -> float:
|
|
258
|
+
"""Attribute that shifts the GLF starting from the zero point. If the offset is positive, the function is
|
|
259
|
+
shifted to the right and if it is negative, it is shifted to the left. Default is 0.
|
|
260
|
+
"""
|
|
261
|
+
return self.__offset
|
|
262
|
+
|
|
263
|
+
@offset.setter
|
|
264
|
+
def offset(self, offset: float) -> None:
|
|
265
|
+
"""Updates the potential offset of the GLF. This value shifts the GLF in relation to the zero point.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
offset (float): Potential offset of the GLF. The value must be a float and can be any rational number.
|
|
269
|
+
"""
|
|
270
|
+
self.__offset = offset
|
|
271
|
+
|
|
272
|
+
def __repr__(self):
|
|
273
|
+
return (
|
|
274
|
+
self.__class__.__name__
|
|
275
|
+
+ f"(pinch_off_percentage={self.pinch_off_percentage}, "
|
|
276
|
+
f"fully_conductive_percentage={self.fully_conductive_percentage}, "
|
|
277
|
+
f"asymptote_left={self.asymptote_left}, asymptote_right={self.asymptote_right}, "
|
|
278
|
+
f"growth_rate={self.growth_rate}, asymmetry={self.asymmetry}, shape_factor={self.shape_factor}, "
|
|
279
|
+
f"denominator_offset={self.denominator_offset}, offset={self.offset})"
|
|
280
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""This module contains an interface that models the conductivity of a sensor dot barrier.
|
|
2
|
+
|
|
3
|
+
@author: b.papajewski
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
from abc import ABC, abstractmethod
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
import numpy as np
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BarrierFunctionInterface(ABC):
|
|
15
|
+
"""
|
|
16
|
+
Interface that models the conductivity (similar to a pinch-off measurement) of a barrier.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
@abstractmethod
|
|
20
|
+
def get_value(self, potential: Union[float, np.ndarray]) -> float:
|
|
21
|
+
"""
|
|
22
|
+
Returns the value of the barrier function for a given potential.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
potential (Union[float, np.ndarray]): Potential for which the conductance of the barrier function is to be
|
|
26
|
+
calculated.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Union[float, np.ndarray]: Value of the barrier function for a given potential.
|
|
30
|
+
"""
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def pinch_off(self) -> float:
|
|
36
|
+
"""Potential value of the pinch off."""
|
|
37
|
+
raise NotImplementedError
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
@abstractmethod
|
|
41
|
+
def fully_conductive(self) -> float:
|
|
42
|
+
"""Potential value of the point from which on the barrier vanishes and becomes fully conductive."""
|
|
43
|
+
raise NotImplementedError
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""This module contains a class that models the conductivity of a barrier using multiple generalized logistic functions (GLFs).
|
|
2
|
+
|
|
3
|
+
@author: b.papajewski
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Union, Tuple
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from simcats.sensor.barrier_function import BarrierFunctionInterface
|
|
11
|
+
from simcats.support_functions import multi_glf
|
|
12
|
+
|
|
13
|
+
__all__ = []
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BarrierFunctionMultiGLF(BarrierFunctionInterface):
|
|
17
|
+
"""
|
|
18
|
+
Implementation of the BarrierFunctionInterface that models a conductivity off of a barrier using a combination of
|
|
19
|
+
multiple generalized logistic functions (GLFs).
|
|
20
|
+
For further information see: https://en.wikipedia.org/wiki/Generalised_logistic_function
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, pinch_off: float, fully_conductive: float, *params: float):
|
|
24
|
+
"""Initializes an object of the class to represent the barrier function using several generalized logistic functions.
|
|
25
|
+
|
|
26
|
+
For further information see: https://en.wikipedia.org/wiki/Generalised_logistic_function
|
|
27
|
+
|
|
28
|
+
The number of GLFs is specified by the number of parameters. To do this, the parameter count must be
|
|
29
|
+
divisible by seven and a GLF is added for every seven other parameters.
|
|
30
|
+
|
|
31
|
+
Each GLF has the following parameters: \n
|
|
32
|
+
- asymptote_left (float): Originally called A. This parameter is the left horizontal asymptote of the function.
|
|
33
|
+
Any rational number can be used as the left asymptote.
|
|
34
|
+
- asymptote_right (float): Originally called K. Specifies the right horizontal asymptote of the function when
|
|
35
|
+
denominator_offset=1. If asymptote_left=0 and denominator_offset=1 then this parameter is also called the
|
|
36
|
+
carrying capacity. This parameter may take any rational number.
|
|
37
|
+
- growth_rate (float): Originally called B. The growth rate of the function. The value must be a float and can
|
|
38
|
+
be any rational number. Be careful with negative values, because the function is mirrored on a vertical
|
|
39
|
+
straight line for these. This line passes through the point where the potential equals `offset`.
|
|
40
|
+
- asymmetry (float): Originally called nu. This parameter introduces skew and affects symmetry. It also affects
|
|
41
|
+
near which asymptote maximum growth occurs. The value of asymmetry must be a rational number greater than
|
|
42
|
+
zero. \n
|
|
43
|
+
- If `asymmetry > 1`: the curve rises more gradually before the midpoint and more sharply after. \n
|
|
44
|
+
- If `asymmetry < 1`: the curve rises quickly early on and levels off more slowly.
|
|
45
|
+
- shape_factor (float): Originally called Q. is related to the value Y(0) and adjusts the curve’s value at the
|
|
46
|
+
y-intercept. Thereby it changes the shape of the function without changing the asymptotes. The shape
|
|
47
|
+
factor can be any rational number.
|
|
48
|
+
- denominator_offset (float): Originally called C. A constant added to the denominator inside the power.
|
|
49
|
+
Controls the initial level of the denominator.This parameter must be a rational number. It typically takes a
|
|
50
|
+
value of 1. Otherwise, the upper asymptote is \n
|
|
51
|
+
asymptote_left + (asymptote_right - asymptote_left) / (denominator_offset^(1 / asymmetry)).
|
|
52
|
+
- offset (float): Potential offset, that shifts the function starting from the zero point. If the offset is
|
|
53
|
+
positive, the function is shifted to the right and if it is negative, it is shifted to the left.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
pinch_off (float): Potential at which the pinch-off of the barrier is located.
|
|
57
|
+
fully_conductive (float): Potential of the point from which on the barrier function is fully conductive.
|
|
58
|
+
*params: Additional positional arguments representing the GLF parameters. The number of additional
|
|
59
|
+
parameters must be divisible by seven and determines the number of GLFs that are used for the Multi-GLF.
|
|
60
|
+
All parameters consist of sequential groups of seven floats that each represent a single GLF. All
|
|
61
|
+
individual parameters are described above and are in the same order as they are described.
|
|
62
|
+
"""
|
|
63
|
+
self.pinch_off = pinch_off
|
|
64
|
+
self.fully_conductive = fully_conductive
|
|
65
|
+
self.params = params
|
|
66
|
+
|
|
67
|
+
def get_value(self, potential: Union[float, np.ndarray]) -> float:
|
|
68
|
+
"""Returns the value of the barrier function for a given potential.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
potential (Union[float, np.ndarray]): Potential for which the conductance of the barrier function is to be
|
|
72
|
+
calculated.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Union[float, np.ndarray]: Value of the barrier function for a given potential.
|
|
76
|
+
"""
|
|
77
|
+
return multi_glf(potential, *self.__params)
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def pinch_off(self) -> float:
|
|
81
|
+
"""Potential value of the pinch off."""
|
|
82
|
+
return self.__pinch_off
|
|
83
|
+
|
|
84
|
+
@pinch_off.setter
|
|
85
|
+
def pinch_off(self, pinch_off: float) -> None:
|
|
86
|
+
"""Updates the potential value of the pinch off.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
pinch_off (float): Potential value of the pinch off
|
|
90
|
+
"""
|
|
91
|
+
self.__pinch_off = pinch_off
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def fully_conductive(self) -> float:
|
|
95
|
+
"""Potential value of the point from which on the barrier vanishes and becomes fully conductive."""
|
|
96
|
+
return self.__fully_conductive
|
|
97
|
+
|
|
98
|
+
@fully_conductive.setter
|
|
99
|
+
def fully_conductive(self, fully_conductive: float) -> None:
|
|
100
|
+
"""Updates the fully conductive point, the potential value at which the barrier vanishes.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
fully_conductive (float): Potential value of the fully conductive point.
|
|
104
|
+
"""
|
|
105
|
+
self.__fully_conductive = fully_conductive
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def params(self) -> Tuple[float]:
|
|
109
|
+
"""Parameters of the multiple GLFs.
|
|
110
|
+
The number of GLFs is specified by the number of parameters. To do this, the parameter count must be divisible
|
|
111
|
+
by seven and a GLF is added for every seven other parameters.
|
|
112
|
+
|
|
113
|
+
Each GLF has the following parameters: \n
|
|
114
|
+
- asymptote_left (float): Originally called A. This parameter is the left horizontal asymptote of the function.
|
|
115
|
+
Any rational number can be used as the left asymptote.
|
|
116
|
+
- asymptote_right (float): Originally called K. Specifies the right horizontal asymptote of the function when
|
|
117
|
+
denominator_offset=1. If asymptote_left=0 and denominator_offset=1 then this parameter is also called the
|
|
118
|
+
carrying capacity. This parameter may take any rational number.
|
|
119
|
+
- growth_rate (float): Originally called B. The growth rate of the function. The value must be a float and can
|
|
120
|
+
be any rational number. Be careful with negative values, because the function is mirrored on a vertical
|
|
121
|
+
straight line for these. This line passes through the point where the potential equals `offset`.
|
|
122
|
+
- asymmetry (float): Originally called nu. This parameter introduces skew and affects symmetry. It also affects
|
|
123
|
+
near which asymptote maximum growth occurs. The value of asymmetry must be a rational number greater than
|
|
124
|
+
zero. \n
|
|
125
|
+
- If `asymmetry > 1`: the curve rises more gradually before the midpoint and more sharply after. \n
|
|
126
|
+
- If `asymmetry < 1`: the curve rises quickly early on and levels off more slowly.
|
|
127
|
+
- shape_factor (float): Originally called Q. is related to the value Y(0) and adjusts the curve’s value at the
|
|
128
|
+
y-intercept. Thereby it changes the shape of the function without changing the asymptotes. The shape factor can
|
|
129
|
+
be any rational number.
|
|
130
|
+
- denominator_offset (float): Originally called C. A constant added to the denominator inside the power.
|
|
131
|
+
Controls the initial level of the denominator. This parameter must be a rational number. It typically takes a
|
|
132
|
+
value of 1. Otherwise, the upper asymptote is \n
|
|
133
|
+
asymptote_left + (asymptote_right - asymptote_left) / (denominator_offset^(1 / asymmetry)).
|
|
134
|
+
- offset (float): Potential offset, that shifts the function starting from the zero point. If the offset is
|
|
135
|
+
positive, the function is shifted to the right and if it is negative, it is shifted to the left.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
The parameters of the multiple GLFs as described above.
|
|
139
|
+
"""
|
|
140
|
+
return self.__params
|
|
141
|
+
|
|
142
|
+
@params.setter
|
|
143
|
+
def params(self, params: Tuple[float]) -> None:
|
|
144
|
+
"""Updates the parameter list of a multi GLF. A more detailed description of every parameter can be found above.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
params (Tuple[float]): Parameters of the multiple GLFs as described above.
|
|
148
|
+
"""
|
|
149
|
+
if len(params) % 7 != 0:
|
|
150
|
+
raise ValueError("The parameter list must be divisible by 7")
|
|
151
|
+
self.__params = params
|
|
152
|
+
|
|
153
|
+
def __repr__(self):
|
|
154
|
+
return (
|
|
155
|
+
self.__class__.__name__
|
|
156
|
+
+ f"(pinch_off={self.pinch_off}, fully_conductive={self.fully_conductive}, *params={self.__params}"
|
|
157
|
+
)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SimCATS subpackage of the sensor package containing all functionalities related to sensor peak deformations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from simcats.sensor.deformation._sensor_peak_deformation_interface import SensorPeakDeformationInterface
|
|
6
|
+
from simcats.sensor.deformation._sensor_peak_deformation_circle import SensorPeakDeformationCircle
|
|
7
|
+
from simcats.sensor.deformation._sensor_peak_deformation_linear import SensorPeakDeformationLinear
|
|
8
|
+
|
|
9
|
+
__all__ = ['SensorPeakDeformationInterface', 'SensorPeakDeformationCircle', 'SensorPeakDeformationLinear']
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""This module contains the class for simulating a circular deformation of sensor peaks in a scan.
|
|
2
|
+
|
|
3
|
+
@author: b.papajewski
|
|
4
|
+
"""
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from simcats.sensor.deformation import SensorPeakDeformationInterface
|
|
10
|
+
|
|
11
|
+
__all__ = []
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class SensorPeakDeformationCircle(SensorPeakDeformationInterface):
|
|
15
|
+
"""Circular deformation implementation of the SensorPeakDeformationInterface."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, radius: float) -> None:
|
|
18
|
+
"""Initialization of an object of the class CircleSensorPeakDeformation.
|
|
19
|
+
This kind of deformation uses a single circle for the deformation of a sensor peak.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
radius (float): Radius of the circle that is used for the deformation. The radius can the positive or
|
|
23
|
+
negative. If the radius is positive the center of the circle is below mu0 and if it is negative the
|
|
24
|
+
center is above mu0.
|
|
25
|
+
"""
|
|
26
|
+
super().__init__()
|
|
27
|
+
|
|
28
|
+
self.__radius = radius
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def radius(self) -> float:
|
|
32
|
+
"""Returns the radius used for this deformation.
|
|
33
|
+
Radius is specified in potential values.
|
|
34
|
+
The radius can the positive or negative. If the radius is positive the center of the circle is below mu0 and if
|
|
35
|
+
it is negative the center is above mu0.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
float: Radius of the circular deformation. The wavefront is deformed according to this circle.
|
|
39
|
+
"""
|
|
40
|
+
return self.__radius
|
|
41
|
+
|
|
42
|
+
@radius.setter
|
|
43
|
+
def radius(self, radius: float) -> None:
|
|
44
|
+
"""Sets the radius of the circular deformation.
|
|
45
|
+
Radius is specified in potential values.
|
|
46
|
+
The radius can the positive or negative. If the radius is positive the center of the circle is below mu0 and if
|
|
47
|
+
it is negative the center is above mu0.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
radius (float): Radius of the circular deformation. The wavefront is deformed according to this circle.
|
|
51
|
+
"""
|
|
52
|
+
self.__radius = radius
|
|
53
|
+
|
|
54
|
+
def calc_mu(self, dist: Union[float, np.ndarray], mu0: float) -> Union[float, np.ndarray]:
|
|
55
|
+
"""
|
|
56
|
+
Method that calculates the deformed potential value for mu0 of a sensor peak that is moved based on the
|
|
57
|
+
distance (dist) to a middle line, from which the deformation originates, using a circle. The middle line follows
|
|
58
|
+
the direction of the sensor peaks (i.e., the sensor dot potential) and is perpendicular to the wavefronts
|
|
59
|
+
defined by the peaks.
|
|
60
|
+
|
|
61
|
+
The center of the circle is either above or below the sensor peak and lies on the middle line. However, it is
|
|
62
|
+
chosen so that the mu0 value lies on the edge of the circle. To determine the deformation, one of the points of
|
|
63
|
+
the circle with the given distance to the middle line is used. The deformed mu0 value is the potential value of
|
|
64
|
+
the point whose potential value is closest to the original mu0 value. If there is no point of the circle that
|
|
65
|
+
has the given distance (dist) to the middle line, the potential of the point of the circle with the greatest
|
|
66
|
+
distance to the middle straight line is used.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
dist (Union[float, np.ndarray]): Distance from the middle line, from which the deformation originates. If a
|
|
70
|
+
point is above the middle line the distance is positive and if it is below, the distance is negative.
|
|
71
|
+
The parameter can either be a np.ndarray that contains multiple distances or a single distance as a
|
|
72
|
+
float.
|
|
73
|
+
mu0 (float): Potential offset for calculation of the deformed potential. Usually this should be the
|
|
74
|
+
potential offset of the sensor peak, that should be deformed.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Union[float, np.ndarray]: Deformed potential value mu0 of a sensor peak. The same type as the type of
|
|
78
|
+
`dist` is returned.
|
|
79
|
+
"""
|
|
80
|
+
# Here only positive distances are used as the deformation with a single circle is symmetrical
|
|
81
|
+
dist = np.abs(dist)
|
|
82
|
+
# Conversion of the raidus from potential values to voltage values
|
|
83
|
+
radius_volt = self.__radius / np.linalg.norm(self.sensor.alpha_sensor_gate[0])
|
|
84
|
+
|
|
85
|
+
radius_abs = np.abs(radius_volt)
|
|
86
|
+
sign_radius = np.sign(self.__radius)
|
|
87
|
+
|
|
88
|
+
# Prevents division by zero if radius_abs is zero
|
|
89
|
+
with np.errstate(divide='ignore', invalid='ignore'):
|
|
90
|
+
angle = np.arcsin(np.clip(dist / radius_abs, -1, 1))
|
|
91
|
+
cos_angle = np.cos(angle)
|
|
92
|
+
|
|
93
|
+
# Calculation of both possible points of the circle that have the distance dist to the middle line
|
|
94
|
+
temp1 = mu0 - (radius_abs - cos_angle * radius_abs) * sign_radius
|
|
95
|
+
temp2 = mu0 - radius_volt * np.sign(radius_volt)
|
|
96
|
+
|
|
97
|
+
# Selection of the result that is closer to the output mu0
|
|
98
|
+
result = np.where(dist <= radius_abs, temp1, temp2)
|
|
99
|
+
|
|
100
|
+
# If the result is an array with only one element, you can convert it to a scalar
|
|
101
|
+
if np.isscalar(dist):
|
|
102
|
+
return result.item()
|
|
103
|
+
else:
|
|
104
|
+
return result
|
|
105
|
+
|
|
106
|
+
def __repr__(self):
|
|
107
|
+
return (
|
|
108
|
+
self.__class__.__name__ + f"(radius={self.radius})"
|
|
109
|
+
)
|