pyvale 2025.5.3__cp311-cp311-macosx_14_0_arm64.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.

Potentially problematic release.


This version of pyvale might be problematic. Click here for more details.

Files changed (175) hide show
  1. pyvale/.dylibs/libomp.dylib +0 -0
  2. pyvale/__init__.py +89 -0
  3. pyvale/analyticmeshgen.py +102 -0
  4. pyvale/analyticsimdatafactory.py +91 -0
  5. pyvale/analyticsimdatagenerator.py +323 -0
  6. pyvale/blendercalibrationdata.py +15 -0
  7. pyvale/blenderlightdata.py +26 -0
  8. pyvale/blendermaterialdata.py +15 -0
  9. pyvale/blenderrenderdata.py +30 -0
  10. pyvale/blenderscene.py +488 -0
  11. pyvale/blendertools.py +420 -0
  12. pyvale/camera.py +146 -0
  13. pyvale/cameradata.py +69 -0
  14. pyvale/cameradata2d.py +84 -0
  15. pyvale/camerastereo.py +217 -0
  16. pyvale/cameratools.py +522 -0
  17. pyvale/cython/rastercyth.c +32211 -0
  18. pyvale/cython/rastercyth.cpython-311-darwin.so +0 -0
  19. pyvale/cython/rastercyth.py +640 -0
  20. pyvale/data/__init__.py +5 -0
  21. pyvale/data/cal_target.tiff +0 -0
  22. pyvale/data/case00_HEX20_out.e +0 -0
  23. pyvale/data/case00_HEX27_out.e +0 -0
  24. pyvale/data/case00_HEX8_out.e +0 -0
  25. pyvale/data/case00_TET10_out.e +0 -0
  26. pyvale/data/case00_TET14_out.e +0 -0
  27. pyvale/data/case00_TET4_out.e +0 -0
  28. pyvale/data/case13_out.e +0 -0
  29. pyvale/data/case16_out.e +0 -0
  30. pyvale/data/case17_out.e +0 -0
  31. pyvale/data/case18_1_out.e +0 -0
  32. pyvale/data/case18_2_out.e +0 -0
  33. pyvale/data/case18_3_out.e +0 -0
  34. pyvale/data/case25_out.e +0 -0
  35. pyvale/data/case26_out.e +0 -0
  36. pyvale/data/optspeckle_2464x2056px_spec5px_8bit_gblur1px.tiff +0 -0
  37. pyvale/dataset.py +325 -0
  38. pyvale/errorcalculator.py +109 -0
  39. pyvale/errordriftcalc.py +146 -0
  40. pyvale/errorintegrator.py +336 -0
  41. pyvale/errorrand.py +607 -0
  42. pyvale/errorsyscalib.py +134 -0
  43. pyvale/errorsysdep.py +327 -0
  44. pyvale/errorsysfield.py +414 -0
  45. pyvale/errorsysindep.py +808 -0
  46. pyvale/examples/__init__.py +5 -0
  47. pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +131 -0
  48. pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +158 -0
  49. pyvale/examples/basics/ex1_3_customsens_therm3d.py +216 -0
  50. pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +153 -0
  51. pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +168 -0
  52. pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +133 -0
  53. pyvale/examples/basics/ex1_7_spatavg_therm2d.py +123 -0
  54. pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +112 -0
  55. pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +111 -0
  56. pyvale/examples/basics/ex2_3_sensangle_disp2d.py +139 -0
  57. pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +196 -0
  58. pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +109 -0
  59. pyvale/examples/basics/ex3_1_basictensors_strain2d.py +114 -0
  60. pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +111 -0
  61. pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +182 -0
  62. pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +171 -0
  63. pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +252 -0
  64. pyvale/examples/genanalyticdata/ex1_1_scalarvisualisation.py +35 -0
  65. pyvale/examples/genanalyticdata/ex1_2_scalarcasebuild.py +43 -0
  66. pyvale/examples/genanalyticdata/ex2_1_analyticsensors.py +80 -0
  67. pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +79 -0
  68. pyvale/examples/renderblender/ex1_1_blenderscene.py +121 -0
  69. pyvale/examples/renderblender/ex1_2_blenderdeformed.py +119 -0
  70. pyvale/examples/renderblender/ex2_1_stereoscene.py +128 -0
  71. pyvale/examples/renderblender/ex2_2_stereodeformed.py +131 -0
  72. pyvale/examples/renderblender/ex3_1_blendercalibration.py +120 -0
  73. pyvale/examples/renderrasterisation/ex_rastenp.py +153 -0
  74. pyvale/examples/renderrasterisation/ex_rastercyth_oneframe.py +218 -0
  75. pyvale/examples/renderrasterisation/ex_rastercyth_static_cypara.py +187 -0
  76. pyvale/examples/renderrasterisation/ex_rastercyth_static_pypara.py +190 -0
  77. pyvale/examples/visualisation/ex1_1_plot_traces.py +102 -0
  78. pyvale/examples/visualisation/ex2_1_animate_sim.py +89 -0
  79. pyvale/experimentsimulator.py +175 -0
  80. pyvale/field.py +128 -0
  81. pyvale/fieldconverter.py +351 -0
  82. pyvale/fieldsampler.py +111 -0
  83. pyvale/fieldscalar.py +166 -0
  84. pyvale/fieldtensor.py +218 -0
  85. pyvale/fieldtransform.py +388 -0
  86. pyvale/fieldvector.py +213 -0
  87. pyvale/generatorsrandom.py +505 -0
  88. pyvale/imagedef2d.py +569 -0
  89. pyvale/integratorfactory.py +240 -0
  90. pyvale/integratorquadrature.py +217 -0
  91. pyvale/integratorrectangle.py +165 -0
  92. pyvale/integratorspatial.py +89 -0
  93. pyvale/integratortype.py +43 -0
  94. pyvale/output.py +17 -0
  95. pyvale/pyvaleexceptions.py +11 -0
  96. pyvale/raster.py +31 -0
  97. pyvale/rastercy.py +77 -0
  98. pyvale/rasternp.py +603 -0
  99. pyvale/rendermesh.py +147 -0
  100. pyvale/sensorarray.py +178 -0
  101. pyvale/sensorarrayfactory.py +196 -0
  102. pyvale/sensorarraypoint.py +278 -0
  103. pyvale/sensordata.py +71 -0
  104. pyvale/sensordescriptor.py +213 -0
  105. pyvale/sensortools.py +142 -0
  106. pyvale/simcases/case00_HEX20.i +242 -0
  107. pyvale/simcases/case00_HEX27.i +242 -0
  108. pyvale/simcases/case00_HEX8.i +242 -0
  109. pyvale/simcases/case00_TET10.i +242 -0
  110. pyvale/simcases/case00_TET14.i +242 -0
  111. pyvale/simcases/case00_TET4.i +242 -0
  112. pyvale/simcases/case01.i +101 -0
  113. pyvale/simcases/case02.i +156 -0
  114. pyvale/simcases/case03.i +136 -0
  115. pyvale/simcases/case04.i +181 -0
  116. pyvale/simcases/case05.i +234 -0
  117. pyvale/simcases/case06.i +305 -0
  118. pyvale/simcases/case07.geo +135 -0
  119. pyvale/simcases/case07.i +87 -0
  120. pyvale/simcases/case08.geo +144 -0
  121. pyvale/simcases/case08.i +153 -0
  122. pyvale/simcases/case09.geo +204 -0
  123. pyvale/simcases/case09.i +87 -0
  124. pyvale/simcases/case10.geo +204 -0
  125. pyvale/simcases/case10.i +257 -0
  126. pyvale/simcases/case11.geo +337 -0
  127. pyvale/simcases/case11.i +147 -0
  128. pyvale/simcases/case12.geo +388 -0
  129. pyvale/simcases/case12.i +329 -0
  130. pyvale/simcases/case13.i +140 -0
  131. pyvale/simcases/case14.i +159 -0
  132. pyvale/simcases/case15.geo +337 -0
  133. pyvale/simcases/case15.i +150 -0
  134. pyvale/simcases/case16.geo +391 -0
  135. pyvale/simcases/case16.i +357 -0
  136. pyvale/simcases/case17.geo +135 -0
  137. pyvale/simcases/case17.i +144 -0
  138. pyvale/simcases/case18.i +254 -0
  139. pyvale/simcases/case18_1.i +254 -0
  140. pyvale/simcases/case18_2.i +254 -0
  141. pyvale/simcases/case18_3.i +254 -0
  142. pyvale/simcases/case19.geo +252 -0
  143. pyvale/simcases/case19.i +99 -0
  144. pyvale/simcases/case20.geo +252 -0
  145. pyvale/simcases/case20.i +250 -0
  146. pyvale/simcases/case21.geo +74 -0
  147. pyvale/simcases/case21.i +155 -0
  148. pyvale/simcases/case22.geo +82 -0
  149. pyvale/simcases/case22.i +140 -0
  150. pyvale/simcases/case23.geo +164 -0
  151. pyvale/simcases/case23.i +140 -0
  152. pyvale/simcases/case24.geo +79 -0
  153. pyvale/simcases/case24.i +123 -0
  154. pyvale/simcases/case25.geo +82 -0
  155. pyvale/simcases/case25.i +140 -0
  156. pyvale/simcases/case26.geo +166 -0
  157. pyvale/simcases/case26.i +140 -0
  158. pyvale/simcases/run_1case.py +61 -0
  159. pyvale/simcases/run_all_cases.py +69 -0
  160. pyvale/simcases/run_build_case.py +64 -0
  161. pyvale/simcases/run_example_cases.py +69 -0
  162. pyvale/simtools.py +67 -0
  163. pyvale/visualexpplotter.py +191 -0
  164. pyvale/visualimagedef.py +74 -0
  165. pyvale/visualimages.py +76 -0
  166. pyvale/visualopts.py +493 -0
  167. pyvale/visualsimanimator.py +111 -0
  168. pyvale/visualsimsensors.py +318 -0
  169. pyvale/visualtools.py +136 -0
  170. pyvale/visualtraceplotter.py +142 -0
  171. pyvale-2025.5.3.dist-info/METADATA +144 -0
  172. pyvale-2025.5.3.dist-info/RECORD +175 -0
  173. pyvale-2025.5.3.dist-info/WHEEL +6 -0
  174. pyvale-2025.5.3.dist-info/licenses/LICENSE +21 -0
  175. pyvale-2025.5.3.dist-info/top_level.txt +1 -0
pyvale/errorrand.py ADDED
@@ -0,0 +1,607 @@
1
+ # ==============================================================================
2
+ # pyvale: the python validation engine
3
+ # License: MIT
4
+ # Copyright (C) 2025 The Computer Aided Validation Team
5
+ # ==============================================================================
6
+
7
+ import numpy as np
8
+ from pyvale.sensordata import SensorData
9
+ from pyvale.errorcalculator import (IErrCalculator,
10
+ EErrType,
11
+ EErrDep)
12
+ from pyvale.generatorsrandom import IGenRandom
13
+
14
+
15
+ class ErrRandUnif(IErrCalculator):
16
+ """Random error calculator based on uniform sampling of an interval
17
+ specified by its upper and lower bound.
18
+
19
+ Implements the `IErrCalculator` interface.
20
+ """
21
+ __slots__ = ("low","high","rng","err_dep")
22
+
23
+ def __init__(self,
24
+ low: float,
25
+ high: float,
26
+ err_dep: EErrDep = EErrDep.INDEPENDENT,
27
+ seed: int | None = None) -> None:
28
+ """
29
+ Parameters
30
+ ----------
31
+ low : float
32
+ Lower bound of the uniform random generator.
33
+ high : float
34
+ Upper bound of the uniform random generator.
35
+ err_dep : EErrDependence, optional
36
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
37
+ seed : int | None, optional
38
+ Optional seed for the random generator to allow for replicable
39
+ behaviour, by default None.
40
+
41
+ Raises
42
+ ------
43
+ ValueError
44
+ Raised if the user specified a lower bound that is higher than the
45
+ upper bound.
46
+ """
47
+
48
+ if low > high:
49
+ raise ValueError("The upper bound must be higher than the lower "
50
+ + "bound for this error.")
51
+ self.low = low
52
+ self.high = high
53
+ self.rng = np.random.default_rng(seed)
54
+ self.err_dep = err_dep
55
+
56
+ def get_error_dep(self) -> EErrDep:
57
+ """Gets the error dependence state for this error calculator. An
58
+ independent error is calculated based on the input truth values as the
59
+ error basis. A dependent error is calculated based on the accumulated
60
+ sensor reading from all preceeding errors in the chain.
61
+
62
+ For this class errors are calculated independently regardless.
63
+
64
+ Returns
65
+ -------
66
+ EErrDependence
67
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
68
+ """
69
+ return self.err_dep
70
+
71
+ def set_error_dep(self, dependence: EErrDep) -> None:
72
+ """Sets the error dependence state for this error calculator. An
73
+ independent error is calculated based on the input truth values as the
74
+ error basis. A dependent error is calculated based on the accumulated
75
+ sensor reading from all preceeding errors in the chain.
76
+
77
+ For this class errors are calculated independently regardless.
78
+
79
+ Parameters
80
+ ----------
81
+ dependence : EErrDependence
82
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
83
+ """
84
+ self.err_dep = dependence
85
+
86
+ def get_error_type(self) -> EErrType:
87
+ """Gets the error type.
88
+
89
+ Returns
90
+ -------
91
+ EErrType
92
+ Enumeration definining RANDOM or SYSTEMATIC error types.
93
+ """
94
+ return EErrType.RANDOM
95
+
96
+ def calc_errs(self,
97
+ err_basis: np.ndarray,
98
+ sens_data: SensorData,
99
+ ) -> tuple[np.ndarray, SensorData]:
100
+ """Calculates the error array based on the size of the input.
101
+
102
+ Parameters
103
+ ----------
104
+ err_basis : np.ndarray
105
+ Array of values with the same dimensions as the sensor measurement
106
+ matrix.
107
+ sens_data : SensorData
108
+ The accumulated sensor state data for all errors prior to this one.
109
+
110
+ Returns
111
+ -------
112
+ tuple[np.ndarray, SensorData]
113
+ Tuple containing the calculated error array and pass through of the
114
+ sensor data object as it is not modified by this class. The returned
115
+ error array has the same shape as the input error basis.
116
+ """
117
+ rand_errs = self.rng.uniform(low=self.low,
118
+ high=self.high,
119
+ size=err_basis.shape)
120
+
121
+ return (rand_errs,sens_data)
122
+
123
+
124
+ class ErrRandUnifPercent(IErrCalculator):
125
+ """Random error calculator based on a percentage error based on sampling
126
+ from a uniform probability distribution specified by its upper and lower
127
+ bound (in percent).
128
+
129
+ The percentage error is calculated based on the ground truth if the error
130
+ dependence is `INDEPENDENT` or based on the accumulated sensor measurement
131
+ if the dependence is `DEPENDENT`.
132
+
133
+ Implements the `IErrCalculator` interface.
134
+ """
135
+ __slots__ = ("low","high","rng","err_dep")
136
+
137
+ def __init__(self,
138
+ low_percent: float,
139
+ high_percent: float,
140
+ err_dep: EErrDep = EErrDep.INDEPENDENT,
141
+ seed: int | None = None) -> None:
142
+ """
143
+ Parameters
144
+ ----------
145
+ low_percent : float
146
+ Lower percentage bound of the uniform random generator.
147
+ high_percent : float
148
+ Upper percentage bound of the uniform random generator.
149
+ err_dep : EErrDependence, optional
150
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
151
+ seed : int | None, optional
152
+ Optional seed for the random generator to allow for replicable
153
+ behaviour, by default None.
154
+
155
+ Raises
156
+ ------
157
+ ValueError
158
+ Raised if the user specified a lower bound that is higher than the
159
+ upper bound.
160
+ """
161
+
162
+ if low_percent > high_percent:
163
+ raise ValueError("The upper percentage bound must be higher than "
164
+ + "the lower percentage bound for this error.")
165
+
166
+ self.low = low_percent/100
167
+ self.high = high_percent/100
168
+ self.rng = np.random.default_rng(seed)
169
+ self.err_dep = err_dep
170
+
171
+ def get_error_dep(self) -> EErrDep:
172
+ """Gets the error dependence state for this error calculator. An
173
+ independent error is calculated based on the input truth values as the
174
+ error basis. A dependent error is calculated based on the accumulated
175
+ sensor reading from all preceeding errors in the chain.
176
+
177
+ Returns
178
+ -------
179
+ EErrDependence
180
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
181
+ """
182
+ return self.err_dep
183
+
184
+ def set_error_dep(self, dependence: EErrDep) -> None:
185
+ """Sets the error dependence state for this error calculator. An
186
+ independent error is calculated based on the input truth values as the
187
+ error basis. A dependent error is calculated based on the accumulated
188
+ sensor reading from all preceeding errors in the chain.
189
+
190
+ Parameters
191
+ ----------
192
+ dependence : EErrDependence
193
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
194
+ """
195
+ self.err_dep = dependence
196
+
197
+ def get_error_type(self) -> EErrType:
198
+ """Gets the error type.
199
+
200
+ Returns
201
+ -------
202
+ EErrType
203
+ Enumeration definining RANDOM or SYSTEMATIC error types.
204
+ """
205
+ return EErrType.RANDOM
206
+
207
+ def calc_errs(self,
208
+ err_basis: np.ndarray,
209
+ sens_data: SensorData,
210
+ ) -> tuple[np.ndarray, SensorData]:
211
+ """Calculates the error array based on the size of the input.
212
+
213
+ Parameters
214
+ ----------
215
+ err_basis : np.ndarray
216
+ Array of values with the same dimensions as the sensor measurement
217
+ matrix.
218
+ sens_data : SensorData
219
+ The accumulated sensor state data for all errors prior to this one.
220
+
221
+ Returns
222
+ -------
223
+ tuple[np.ndarray, SensorData]
224
+ Tuple containing the calculated error array and pass through of the
225
+ sensor data object as it is not modified by this class. The returned
226
+ error array has the same shape as the input error basis.
227
+ """
228
+ norm_rand = self.rng.uniform(low=self.low,
229
+ high=self.high,
230
+ size=err_basis.shape)
231
+
232
+ return (err_basis*norm_rand,sens_data)
233
+
234
+
235
+ class ErrRandNorm(IErrCalculator):
236
+ """Random error calculator based on sampling of a normal (Gaussian)
237
+ distribution specified using the standard deviation with an assumed zero
238
+ mean. A non-zero mean is a systematic error and should be specified using
239
+ `ErrSysOffset`.
240
+
241
+ Implements the `IErrCalculator` interface.
242
+ """
243
+ __slots__ = ("std","rng","err_dep")
244
+
245
+ def __init__(self,
246
+ std: float,
247
+ err_dep: EErrDep = EErrDep.INDEPENDENT,
248
+ seed: int | None = None) -> None:
249
+ """
250
+ Parameters
251
+ ----------
252
+ std : float
253
+ Standard deviation of the normal distribution to sample from.
254
+ err_dep : EErrDependence, optional
255
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
256
+ seed : int | None, optional
257
+ Optional seed for the random generator to allow for replicable
258
+ behaviour, by default None.
259
+ """
260
+ self.std = np.abs(std)
261
+ self.rng = np.random.default_rng(seed)
262
+ self.err_dep = err_dep
263
+
264
+ def get_error_dep(self) -> EErrDep:
265
+ """Gets the error dependence state for this error calculator. An
266
+ independent error is calculated based on the input truth values as the
267
+ error basis. A dependent error is calculated based on the accumulated
268
+ sensor reading from all preceeding errors in the chain.
269
+
270
+ For this class errors are calculated independently regardless.
271
+
272
+ Returns
273
+ -------
274
+ EErrDependence
275
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
276
+ """
277
+ return self.err_dep
278
+
279
+ def set_error_dep(self, dependence: EErrDep) -> None:
280
+ """Sets the error dependence state for this error calculator. An
281
+ independent error is calculated based on the input truth values as the
282
+ error basis. A dependent error is calculated based on the accumulated
283
+ sensor reading from all preceeding errors in the chain.
284
+
285
+ For this class errors are calculated independently regardless.
286
+
287
+ Parameters
288
+ ----------
289
+ dependence : EErrDependence
290
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
291
+ """
292
+ self.err_dep = dependence
293
+
294
+ def get_error_type(self) -> EErrType:
295
+ """Gets the error type.
296
+
297
+ Returns
298
+ -------
299
+ EErrType
300
+ Enumeration definining RANDOM or SYSTEMATIC error types.
301
+ """
302
+ return EErrType.RANDOM
303
+
304
+ def calc_errs(self,
305
+ err_basis: np.ndarray,
306
+ sens_data: SensorData,
307
+ ) -> tuple[np.ndarray, SensorData]:
308
+ """Calculates the error array based on the size of the input.
309
+
310
+ Parameters
311
+ ----------
312
+ err_basis : np.ndarray
313
+ Array of values with the same dimensions as the sensor measurement
314
+ matrix.
315
+ sens_data : SensorData
316
+ The accumulated sensor state data for all errors prior to this one.
317
+
318
+ Returns
319
+ -------
320
+ tuple[np.ndarray, SensorData]
321
+ Tuple containing the calculated error array and pass through of the
322
+ sensor data object as it is not modified by this class. The returned
323
+ error array has the same shape as the input error basis.
324
+ """
325
+ rand_errs = self.rng.normal(loc=0.0,
326
+ scale=self.std,
327
+ size=err_basis.shape)
328
+
329
+ return (rand_errs,sens_data)
330
+
331
+
332
+ class ErrRandNormPercent(IErrCalculator):
333
+ """Sensor random error calculator based on sampling of a normal (Gaussian)
334
+ distribution specified using the standard deviation with an assumed zero
335
+ mean. This error is calculated as a percentage of the input error basis.
336
+ Note that a non-zero mean is a systematic error and should be specified
337
+ using `ErrSysOffset`.
338
+
339
+ The percentage error is calculated based on the ground truth if the error
340
+ dependence is `INDEPENDENT` or based on the accumulated sensor measurement
341
+ if the dependence is `DEPENDENT`.
342
+
343
+ Implements the `IErrCalculator` interface.
344
+ """
345
+ __slots__ = ("_std","_rng","_err_dep")
346
+
347
+ def __init__(self,
348
+ std_percent: float,
349
+ err_dep: EErrDep = EErrDep.INDEPENDENT,
350
+ seed: int | None = None) -> None:
351
+ """
352
+ Parameters
353
+ ----------
354
+ std_percent : float
355
+ Standard deviation of the normal distribution to sample as a
356
+ percentage.
357
+ err_dep : EErrDependence, optional
358
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
359
+ seed : int | None, optional
360
+ Optional seed for the random generator to allow for replicable
361
+ behaviour, by default None.
362
+ """
363
+ self._std = np.abs(std_percent)/100
364
+ self._rng = np.random.default_rng(seed)
365
+ self._err_dep = err_dep
366
+
367
+ def get_error_dep(self) -> EErrDep:
368
+ """Gets the error dependence state for this error calculator. An
369
+ independent error is calculated based on the input truth values as the
370
+ error basis. A dependent error is calculated based on the accumulated
371
+ sensor reading from all preceeding errors in the chain.
372
+
373
+ Returns
374
+ -------
375
+ EErrDependence
376
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
377
+ """
378
+ return self._err_dep
379
+
380
+ def set_error_dep(self, dependence: EErrDep) -> None:
381
+ """Sets the error dependence state for this error calculator. An
382
+ independent error is calculated based on the input truth values as the
383
+ error basis. A dependent error is calculated based on the accumulated
384
+ sensor reading from all preceeding errors in the chain.
385
+
386
+ Parameters
387
+ ----------
388
+ dependence : EErrDependence
389
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
390
+ """
391
+ self._err_dep = dependence
392
+
393
+ def get_error_type(self) -> EErrType:
394
+ """Gets the error type.
395
+
396
+ Returns
397
+ -------
398
+ EErrType
399
+ Enumeration definining RANDOM or SYSTEMATIC error types.
400
+ """
401
+ return EErrType.RANDOM
402
+
403
+ def calc_errs(self,
404
+ err_basis: np.ndarray,
405
+ sens_data: SensorData,
406
+ ) -> tuple[np.ndarray, SensorData]:
407
+ """Calculates the error array based on the size of the input.
408
+
409
+ Parameters
410
+ ----------
411
+ err_basis : np.ndarray
412
+ Array of values with the same dimensions as the sensor measurement
413
+ matrix.
414
+ sens_data : SensorData
415
+ The accumulated sensor state data for all errors prior to this one.
416
+
417
+ Returns
418
+ -------
419
+ tuple[np.ndarray, SensorData]
420
+ Tuple containing the calculated error array and pass through of the
421
+ sensor data object as it is not modified by this class. The returned
422
+ error array has the same shape as the input error basis.
423
+ """
424
+ norm_rand = self._rng.normal(loc=0.0,
425
+ scale=1.0,
426
+ size=err_basis.shape)
427
+
428
+ return (err_basis*self._std*norm_rand,sens_data)
429
+
430
+
431
+ class ErrRandGenerator(IErrCalculator):
432
+ """Sensor random error calculator based on sampling a user specified random
433
+ number generator implementing the `IGeneratorRandom` interface.
434
+
435
+ Implements the `IErrCalculator` interface.
436
+ """
437
+ __slots__ = ("_generator","_err_dep")
438
+
439
+ def __init__(self,
440
+ generator: IGenRandom,
441
+ err_dep: EErrDep = EErrDep.INDEPENDENT) -> None:
442
+ """
443
+ Parameters
444
+ ----------
445
+ generator : IGeneratorRandom
446
+ Interface for a user specified random number generator.
447
+ err_dep : EErrDependence, optional
448
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
449
+ """
450
+ self._generator = generator
451
+ self._err_dep = err_dep
452
+
453
+ def get_error_dep(self) -> EErrDep:
454
+ """Gets the error dependence state for this error calculator. An
455
+ independent error is calculated based on the input truth values as the
456
+ error basis. A dependent error is calculated based on the accumulated
457
+ sensor reading from all preceeding errors in the chain.
458
+
459
+ For this class errors are calculated independently regardless.
460
+
461
+ Returns
462
+ -------
463
+ EErrDependence
464
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
465
+ """
466
+ return self._err_dep
467
+
468
+ def set_error_dep(self, dependence: EErrDep) -> None:
469
+ """Sets the error dependence state for this error calculator. An
470
+ independent error is calculated based on the input truth values as the
471
+ error basis. A dependent error is calculated based on the accumulated
472
+ sensor reading from all preceeding errors in the chain.
473
+
474
+ For this class errors are calculated independently regardless.
475
+
476
+ Parameters
477
+ ----------
478
+ dependence : EErrDependence
479
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
480
+ """
481
+ self._err_dep = dependence
482
+
483
+ def get_error_type(self) -> EErrType:
484
+ """Gets the error type.
485
+
486
+ Returns
487
+ -------
488
+ EErrType
489
+ Enumeration definining RANDOM or SYSTEMATIC error types.
490
+ """
491
+ return EErrType.RANDOM
492
+
493
+ def calc_errs(self,
494
+ err_basis: np.ndarray,
495
+ sens_data: SensorData,
496
+ ) -> tuple[np.ndarray, SensorData]:
497
+ """Calculates the error array based on the size of the input.
498
+
499
+ Parameters
500
+ ----------
501
+ err_basis : np.ndarray
502
+ Array of values with the same dimensions as the sensor measurement
503
+ matrix.
504
+ sens_data : SensorData
505
+ The accumulated sensor state data for all errors prior to this one.
506
+
507
+ Returns
508
+ -------
509
+ tuple[np.ndarray, SensorData]
510
+ Tuple containing the calculated error array and pass through of the
511
+ sensor data object as it is not modified by this class. The returned
512
+ error array has the same shape as the input error basis.
513
+ """
514
+ rand_errs = self._generator.generate(shape=err_basis.shape)
515
+
516
+ return (rand_errs,sens_data)
517
+
518
+
519
+ class ErrRandGenPercent(IErrCalculator):
520
+ """Random error calculator based on sampling a user specified random
521
+ number generator implementing the `IGeneratorRandom` interface. This class
522
+ assumes the random generator is for a percentage error based on the input
523
+ error basis and therefore it supports error dependence.
524
+
525
+ The percentage error is calculated based on the ground truth if the error
526
+ dependence is `INDEPENDENT` or based on the accumulated sensor measurement
527
+ if the dependence is `DEPENDENT`.
528
+
529
+ Implements the `IErrCalculator` interface.
530
+ """
531
+ __slots__ = ("_generator","_err_dep")
532
+
533
+ def __init__(self,
534
+ generator: IGenRandom,
535
+ err_dep: EErrDep = EErrDep.INDEPENDENT) -> None:
536
+ """
537
+ Parameters
538
+ ----------
539
+ generator : IGeneratorRandom
540
+ Interface for a user specified random number generator.
541
+ err_dep : EErrDependence, optional
542
+ Error calculation dependence, by default EErrDependence.INDEPENDENT.
543
+ """
544
+ self._generator = generator
545
+ self._err_dep = err_dep
546
+
547
+ def get_error_dep(self) -> EErrDep:
548
+ """Gets the error dependence state for this error calculator. An
549
+ independent error is calculated based on the input truth values as the
550
+ error basis. A dependent error is calculated based on the accumulated
551
+ sensor reading from all preceeding errors in the chain.
552
+
553
+ Returns
554
+ -------
555
+ EErrDependence
556
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
557
+ """
558
+ return self._err_dep
559
+
560
+ def set_error_dep(self, dependence: EErrDep) -> None:
561
+ """Sets the error dependence state for this error calculator. An
562
+ independent error is calculated based on the input truth values as the
563
+ error basis. A dependent error is calculated based on the accumulated
564
+ sensor reading from all preceeding errors in the chain.
565
+
566
+ Parameters
567
+ ----------
568
+ dependence : EErrDependence
569
+ Enumeration defining INDEPENDENT or DEPENDENT behaviour.
570
+ """
571
+ self._err_dep = dependence
572
+
573
+ def get_error_type(self) -> EErrType:
574
+ """Gets the error type.
575
+
576
+ Returns
577
+ -------
578
+ EErrType
579
+ Enumeration definining RANDOM or SYSTEMATIC error types.
580
+ """
581
+ return EErrType.RANDOM
582
+
583
+ def calc_errs(self,
584
+ err_basis: np.ndarray,
585
+ sens_data: SensorData,
586
+ ) -> tuple[np.ndarray, SensorData]:
587
+ """Calculates the error array based on the size of the input.
588
+
589
+ Parameters
590
+ ----------
591
+ err_basis : np.ndarray
592
+ Array of values with the same dimensions as the sensor measurement
593
+ matrix.
594
+ sens_data : SensorData
595
+ The accumulated sensor state data for all errors prior to this one.
596
+
597
+ Returns
598
+ -------
599
+ tuple[np.ndarray, SensorData]
600
+ Tuple containing the calculated error array and pass through of the
601
+ sensor data object as it is not modified by this class. The returned
602
+ error array has the same shape as the input error basis.
603
+ """
604
+ rand_errs = err_basis \
605
+ * self._generator.generate(shape=err_basis.shape)/100.0
606
+
607
+ return (rand_errs,sens_data)