pyvale 2025.4.1__py3-none-any.whl → 2025.5.1__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.
Potentially problematic release.
This version of pyvale might be problematic. Click here for more details.
- pyvale/__init__.py +18 -3
- pyvale/analyticmeshgen.py +1 -0
- pyvale/analyticsimdatafactory.py +18 -13
- pyvale/analyticsimdatagenerator.py +105 -72
- pyvale/blendercalibrationdata.py +15 -0
- pyvale/blenderlightdata.py +26 -0
- pyvale/blendermaterialdata.py +15 -0
- pyvale/blenderrenderdata.py +30 -0
- pyvale/blenderscene.py +488 -0
- pyvale/blendertools.py +420 -0
- pyvale/camera.py +6 -5
- pyvale/cameradata.py +25 -7
- pyvale/cameradata2d.py +6 -4
- pyvale/camerastereo.py +217 -0
- pyvale/cameratools.py +206 -11
- pyvale/cython/rastercyth.py +6 -2
- pyvale/data/cal_target.tiff +0 -0
- pyvale/dataset.py +73 -14
- pyvale/errorcalculator.py +8 -10
- pyvale/errordriftcalc.py +10 -9
- pyvale/errorintegrator.py +19 -21
- pyvale/errorrand.py +33 -39
- pyvale/errorsyscalib.py +134 -0
- pyvale/errorsysdep.py +19 -22
- pyvale/errorsysfield.py +49 -41
- pyvale/errorsysindep.py +79 -175
- pyvale/examples/basics/ex1_1_basicscalars_therm2d.py +131 -0
- pyvale/examples/basics/ex1_2_sensormodel_therm2d.py +158 -0
- pyvale/examples/basics/ex1_3_customsens_therm3d.py +216 -0
- pyvale/examples/basics/ex1_4_basicerrors_therm3d.py +153 -0
- pyvale/examples/basics/ex1_5_fielderrs_therm3d.py +168 -0
- pyvale/examples/basics/ex1_6_caliberrs_therm2d.py +133 -0
- pyvale/examples/basics/ex1_7_spatavg_therm2d.py +123 -0
- pyvale/examples/basics/ex2_1_basicvectors_disp2d.py +112 -0
- pyvale/examples/basics/ex2_2_vectorsens_disp2d.py +111 -0
- pyvale/examples/basics/ex2_3_sensangle_disp2d.py +139 -0
- pyvale/examples/basics/ex2_4_chainfielderrs_disp2d.py +196 -0
- pyvale/examples/basics/ex2_5_vectorfields3d_disp3d.py +109 -0
- pyvale/examples/basics/ex3_1_basictensors_strain2d.py +114 -0
- pyvale/examples/basics/ex3_2_tensorsens2d_strain2d.py +111 -0
- pyvale/examples/basics/ex3_3_tensorsens3d_strain3d.py +182 -0
- pyvale/examples/basics/ex4_1_expsim2d_thermmech2d.py +171 -0
- pyvale/examples/basics/ex4_2_expsim3d_thermmech3d.py +252 -0
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_1_scalarvisualisation.py +6 -9
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex1_2_scalarcasebuild.py +8 -11
- pyvale/examples/{analyticdatagen → genanalyticdata}/ex2_1_analyticsensors.py +9 -12
- pyvale/examples/imagedef2d/ex_imagedef2d_todisk.py +8 -15
- pyvale/examples/renderblender/ex1_1_blenderscene.py +121 -0
- pyvale/examples/renderblender/ex1_2_blenderdeformed.py +119 -0
- pyvale/examples/renderblender/ex2_1_stereoscene.py +128 -0
- pyvale/examples/renderblender/ex2_2_stereodeformed.py +131 -0
- pyvale/examples/renderblender/ex3_1_blendercalibration.py +120 -0
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastenp.py +3 -2
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_oneframe.py +2 -2
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_cypara.py +3 -8
- pyvale/examples/{rasterisation → renderrasterisation}/ex_rastercyth_static_pypara.py +6 -7
- pyvale/examples/{ex1_4_thermal2d.py → visualisation/ex1_1_plot_traces.py} +32 -16
- pyvale/examples/{features/ex_animation_tools_3dmonoblock.py → visualisation/ex2_1_animate_sim.py} +37 -31
- pyvale/experimentsimulator.py +107 -30
- pyvale/field.py +2 -9
- pyvale/fieldconverter.py +98 -22
- pyvale/fieldsampler.py +2 -2
- pyvale/fieldscalar.py +10 -10
- pyvale/fieldtensor.py +15 -17
- pyvale/fieldtransform.py +7 -2
- pyvale/fieldvector.py +6 -7
- pyvale/generatorsrandom.py +25 -47
- pyvale/imagedef2d.py +6 -2
- pyvale/integratorfactory.py +2 -2
- pyvale/integratorquadrature.py +50 -24
- pyvale/integratorrectangle.py +85 -7
- pyvale/integratorspatial.py +4 -4
- pyvale/integratortype.py +3 -3
- pyvale/output.py +17 -0
- pyvale/pyvaleexceptions.py +11 -0
- pyvale/raster.py +6 -5
- pyvale/rastercy.py +6 -4
- pyvale/rasternp.py +6 -4
- pyvale/rendermesh.py +6 -2
- pyvale/sensorarray.py +2 -2
- pyvale/sensorarrayfactory.py +52 -65
- pyvale/sensorarraypoint.py +29 -30
- pyvale/sensordata.py +2 -2
- pyvale/sensordescriptor.py +138 -25
- pyvale/sensortools.py +3 -3
- pyvale/simtools.py +67 -0
- pyvale/visualexpplotter.py +99 -57
- pyvale/visualimagedef.py +11 -7
- pyvale/visualimages.py +6 -4
- pyvale/visualopts.py +372 -58
- pyvale/visualsimanimator.py +42 -13
- pyvale/visualsimsensors.py +318 -0
- pyvale/visualtools.py +69 -13
- pyvale/visualtraceplotter.py +52 -165
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/METADATA +17 -14
- pyvale-2025.5.1.dist-info/RECORD +172 -0
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/WHEEL +1 -1
- pyvale/examples/analyticdatagen/__init__.py +0 -5
- pyvale/examples/ex1_1_thermal2d.py +0 -86
- pyvale/examples/ex1_2_thermal2d.py +0 -108
- pyvale/examples/ex1_3_thermal2d.py +0 -110
- pyvale/examples/ex1_5_thermal2d.py +0 -102
- pyvale/examples/ex2_1_thermal3d .py +0 -84
- pyvale/examples/ex2_2_thermal3d.py +0 -51
- pyvale/examples/ex2_3_thermal3d.py +0 -106
- pyvale/examples/ex3_1_displacement2d.py +0 -44
- pyvale/examples/ex3_2_displacement2d.py +0 -76
- pyvale/examples/ex3_3_displacement2d.py +0 -101
- pyvale/examples/ex3_4_displacement2d.py +0 -102
- pyvale/examples/ex4_1_strain2d.py +0 -54
- pyvale/examples/ex4_2_strain2d.py +0 -76
- pyvale/examples/ex4_3_strain2d.py +0 -97
- pyvale/examples/ex5_1_multiphysics2d.py +0 -75
- pyvale/examples/ex6_1_multiphysics2d_expsim.py +0 -115
- pyvale/examples/ex6_2_multiphysics3d_expsim.py +0 -160
- pyvale/examples/features/__init__.py +0 -5
- pyvale/examples/features/ex_area_avg.py +0 -89
- pyvale/examples/features/ex_calibration_error.py +0 -108
- pyvale/examples/features/ex_chain_field_errs.py +0 -141
- pyvale/examples/features/ex_field_errs.py +0 -78
- pyvale/examples/features/ex_sensor_single_angle_batch.py +0 -110
- pyvale/optimcheckfuncs.py +0 -153
- pyvale/visualsimplotter.py +0 -182
- pyvale-2025.4.1.dist-info/RECORD +0 -163
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/licenses/LICENSE +0 -0
- {pyvale-2025.4.1.dist-info → pyvale-2025.5.1.dist-info}/top_level.txt +0 -0
pyvale/errorsysdep.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import enum
|
|
8
8
|
from typing import Callable
|
|
@@ -10,7 +10,7 @@ import numpy as np
|
|
|
10
10
|
from pyvale.sensordata import SensorData
|
|
11
11
|
from pyvale.errorcalculator import (IErrCalculator,
|
|
12
12
|
EErrType,
|
|
13
|
-
|
|
13
|
+
EErrDep)
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class ERoundMethod(enum.Enum):
|
|
@@ -53,9 +53,8 @@ class ErrSysRoundOff(IErrCalculator):
|
|
|
53
53
|
def __init__(self,
|
|
54
54
|
method: ERoundMethod = ERoundMethod.ROUND,
|
|
55
55
|
base: float = 1.0,
|
|
56
|
-
err_dep:
|
|
57
|
-
"""
|
|
58
|
-
|
|
56
|
+
err_dep: EErrDep = EErrDep.DEPENDENT) -> None:
|
|
57
|
+
"""
|
|
59
58
|
Parameters
|
|
60
59
|
----------
|
|
61
60
|
method : ERoundMethod, optional
|
|
@@ -70,7 +69,7 @@ class ErrSysRoundOff(IErrCalculator):
|
|
|
70
69
|
self._method = _select_round_method(method)
|
|
71
70
|
self._err_dep = err_dep
|
|
72
71
|
|
|
73
|
-
def get_error_dep(self) ->
|
|
72
|
+
def get_error_dep(self) -> EErrDep:
|
|
74
73
|
"""Gets the error dependence state for this error calculator. An
|
|
75
74
|
independent error is calculated based on the input truth values as the
|
|
76
75
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -83,7 +82,7 @@ class ErrSysRoundOff(IErrCalculator):
|
|
|
83
82
|
"""
|
|
84
83
|
return self._err_dep
|
|
85
84
|
|
|
86
|
-
def set_error_dep(self, dependence:
|
|
85
|
+
def set_error_dep(self, dependence: EErrDep) -> None:
|
|
87
86
|
"""Sets the error dependence state for this error calculator. An
|
|
88
87
|
independent error is calculated based on the input truth values as the
|
|
89
88
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -142,9 +141,8 @@ class ErrSysDigitisation(IErrCalculator):
|
|
|
142
141
|
def __init__(self,
|
|
143
142
|
bits_per_unit: float,
|
|
144
143
|
method: ERoundMethod = ERoundMethod.ROUND,
|
|
145
|
-
err_dep:
|
|
146
|
-
"""
|
|
147
|
-
|
|
144
|
+
err_dep: EErrDep = EErrDep.DEPENDENT) -> None:
|
|
145
|
+
"""
|
|
148
146
|
Parameters
|
|
149
147
|
----------
|
|
150
148
|
bits_per_unit : float
|
|
@@ -159,7 +157,7 @@ class ErrSysDigitisation(IErrCalculator):
|
|
|
159
157
|
self._method = _select_round_method(method)
|
|
160
158
|
self._err_dep = err_dep
|
|
161
159
|
|
|
162
|
-
def get_error_dep(self) ->
|
|
160
|
+
def get_error_dep(self) -> EErrDep:
|
|
163
161
|
"""Gets the error dependence state for this error calculator. An
|
|
164
162
|
independent error is calculated based on the input truth values as the
|
|
165
163
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -172,7 +170,7 @@ class ErrSysDigitisation(IErrCalculator):
|
|
|
172
170
|
"""
|
|
173
171
|
return self._err_dep
|
|
174
172
|
|
|
175
|
-
def set_error_dep(self, dependence:
|
|
173
|
+
def set_error_dep(self, dependence: EErrDep) -> None:
|
|
176
174
|
"""Sets the error dependence state for this error calculator. An
|
|
177
175
|
independent error is calculated based on the input truth values as the
|
|
178
176
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -226,18 +224,17 @@ class ErrSysSaturation(IErrCalculator):
|
|
|
226
224
|
"""Systematic error calculator for saturation error base on user specified
|
|
227
225
|
minimum and maximum measurement values. Implements the `IErrCalculator`
|
|
228
226
|
interface.
|
|
227
|
+
|
|
228
|
+
NOTE: For this error to function as expected and clamp the measurement
|
|
229
|
+
within the specified range it must be placed last in the error chain and
|
|
230
|
+
the behaviour must be set to: EErrDependence.DEPENDENT.
|
|
229
231
|
"""
|
|
230
232
|
__slots__ = ("_min","_max","_err_dep")
|
|
231
233
|
|
|
232
234
|
def __init__(self,
|
|
233
235
|
meas_min: float,
|
|
234
236
|
meas_max: float) -> None:
|
|
235
|
-
"""
|
|
236
|
-
|
|
237
|
-
NOTE: For this error to function as expected and clamp the measurement
|
|
238
|
-
within the specified range it must be placed last in the error chain and
|
|
239
|
-
the behaviour must be set to: EErrDependence.DEPENDENT.
|
|
240
|
-
|
|
237
|
+
"""
|
|
241
238
|
Parameters
|
|
242
239
|
----------
|
|
243
240
|
meas_min : float
|
|
@@ -257,9 +254,9 @@ class ErrSysSaturation(IErrCalculator):
|
|
|
257
254
|
|
|
258
255
|
self._min = meas_min
|
|
259
256
|
self._max = meas_max
|
|
260
|
-
self._err_dep =
|
|
257
|
+
self._err_dep = EErrDep.DEPENDENT
|
|
261
258
|
|
|
262
|
-
def get_error_dep(self) ->
|
|
259
|
+
def get_error_dep(self) -> EErrDep:
|
|
263
260
|
"""Gets the error dependence state for this error calculator. An
|
|
264
261
|
independent error is calculated based on the input truth values as the
|
|
265
262
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -272,7 +269,7 @@ class ErrSysSaturation(IErrCalculator):
|
|
|
272
269
|
"""
|
|
273
270
|
return self._err_dep
|
|
274
271
|
|
|
275
|
-
def set_error_dep(self, dependence:
|
|
272
|
+
def set_error_dep(self, dependence: EErrDep) -> None:
|
|
276
273
|
"""Sets the error dependence state for this error calculator. An
|
|
277
274
|
independent error is calculated based on the input truth values as the
|
|
278
275
|
error basis. A dependent error is calculated based on the accumulated
|
pyvale/errorsysfield.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ==============================================================================
|
|
2
2
|
# pyvale: the python validation engine
|
|
3
3
|
# License: MIT
|
|
4
4
|
# Copyright (C) 2025 The Computer Aided Validation Team
|
|
5
|
-
#
|
|
5
|
+
# ==============================================================================
|
|
6
6
|
|
|
7
7
|
import copy
|
|
8
8
|
from dataclasses import dataclass
|
|
@@ -15,9 +15,16 @@ from pyvale.sensordata import SensorData
|
|
|
15
15
|
from pyvale.integratortype import EIntSpatialType
|
|
16
16
|
from pyvale.errorcalculator import (IErrCalculator,
|
|
17
17
|
EErrType,
|
|
18
|
-
|
|
18
|
+
EErrDep)
|
|
19
19
|
from pyvale.errordriftcalc import IDriftCalculator
|
|
20
|
-
from pyvale.generatorsrandom import
|
|
20
|
+
from pyvale.generatorsrandom import IGenRandom
|
|
21
|
+
|
|
22
|
+
# TODO:
|
|
23
|
+
# - Implement different perturbed sampling times for each sensor or allow all
|
|
24
|
+
# to lock to the same time step as it works now.
|
|
25
|
+
# - Need to check that we perform field rotations correctly for sensor angles.
|
|
26
|
+
# - This needs to be updated to take rotation objects for offsets and to build
|
|
27
|
+
# and compose rotations
|
|
21
28
|
|
|
22
29
|
|
|
23
30
|
@dataclass(slots=True)
|
|
@@ -45,25 +52,26 @@ class ErrFieldData:
|
|
|
45
52
|
num_time_steps,). If None then no time offset is applied.
|
|
46
53
|
"""
|
|
47
54
|
|
|
48
|
-
pos_rand_xyz: tuple[
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"""Tuple of random generators (implementations of `
|
|
55
|
+
pos_rand_xyz: tuple[IGenRandom | None,
|
|
56
|
+
IGenRandom | None,
|
|
57
|
+
IGenRandom | None] = (None,None,None)
|
|
58
|
+
"""Tuple of random generators (implementations of `IGenRandom`
|
|
52
59
|
interface) for perturbing the sensor positions. The generators perturb the
|
|
53
60
|
X, Y and Z coordinates in order. If None then that axis is not randomly
|
|
54
|
-
perturbed from the nominal sensor position.
|
|
61
|
+
perturbed from the nominal sensor position. Note that the random generators
|
|
62
|
+
should return position perturbations consistent with the simulation units.
|
|
55
63
|
"""
|
|
56
64
|
|
|
57
|
-
ang_rand_zyx: tuple[
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"""Tuple of random generators (implementations of `
|
|
65
|
+
ang_rand_zyx: tuple[IGenRandom | None,
|
|
66
|
+
IGenRandom | None,
|
|
67
|
+
IGenRandom | None] = (None,None,None)
|
|
68
|
+
"""Tuple of random generators (implementations of `IGenRandom`
|
|
61
69
|
interface) for perturbing the sensor angles. The generators perturb
|
|
62
70
|
rotations about the the Z, Y and X axis in order. If None then that axis is
|
|
63
71
|
not randomly perturbed from the nominal sensor position.
|
|
64
72
|
"""
|
|
65
73
|
|
|
66
|
-
time_rand:
|
|
74
|
+
time_rand: IGenRandom | None = None
|
|
67
75
|
"""Random generator for perturbing sensor array sampling times for the
|
|
68
76
|
purpose of calculating field based errors. If None then sensor sampling
|
|
69
77
|
times will not be perturbed from the nominal times.
|
|
@@ -81,11 +89,13 @@ class ErrFieldData:
|
|
|
81
89
|
specified above. shape=(3,)
|
|
82
90
|
"""
|
|
83
91
|
|
|
84
|
-
# DEV FEATURE: locks the coordinate even if offsets and random generators
|
|
92
|
+
# DEV FEATURE: locks the coordinate even if offsets and random generators
|
|
93
|
+
# are specified. These allow individual sensors to be locked when we only
|
|
94
|
+
# specify a random generator for each axis not each sensor.
|
|
85
95
|
pos_lock_xyz: np.ndarray | None = None
|
|
86
96
|
ang_lock_zyx: np.ndarray | None = None
|
|
87
97
|
|
|
88
|
-
#TODO: implement drift for other dimensions, pos/angle
|
|
98
|
+
# TODO: implement drift for other dimensions, pos/angle
|
|
89
99
|
time_drift: IDriftCalculator | None = None
|
|
90
100
|
"""Temporal drift calculation
|
|
91
101
|
"""
|
|
@@ -107,9 +117,8 @@ class ErrSysField(IErrCalculator):
|
|
|
107
117
|
def __init__(self,
|
|
108
118
|
field: IField,
|
|
109
119
|
field_err_data: ErrFieldData,
|
|
110
|
-
err_dep:
|
|
111
|
-
"""
|
|
112
|
-
|
|
120
|
+
err_dep: EErrDep = EErrDep.INDEPENDENT) -> None:
|
|
121
|
+
"""
|
|
113
122
|
Parameters
|
|
114
123
|
----------
|
|
115
124
|
field : IField
|
|
@@ -120,15 +129,15 @@ class ErrSysField(IErrCalculator):
|
|
|
120
129
|
Dataclass specifying which sensor array parameters will be perturbed
|
|
121
130
|
and how they will be perturbed. See the `ErrFieldData` class for
|
|
122
131
|
more detail
|
|
123
|
-
err_dep :
|
|
124
|
-
Error calculation dependence, by default
|
|
132
|
+
err_dep : EErrDep, optional
|
|
133
|
+
Error calculation dependence, by default EErrDep.DEPENDENT.
|
|
125
134
|
"""
|
|
126
135
|
self._field = field
|
|
127
136
|
self._field_err_data = field_err_data
|
|
128
137
|
self._err_dep = err_dep
|
|
129
138
|
self._sensor_data_perturbed = SensorData()
|
|
130
139
|
|
|
131
|
-
def get_error_dep(self) ->
|
|
140
|
+
def get_error_dep(self) -> EErrDep:
|
|
132
141
|
"""Gets the error dependence state for this error calculator. An
|
|
133
142
|
independent error is calculated based on the input truth values as the
|
|
134
143
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -136,12 +145,12 @@ class ErrSysField(IErrCalculator):
|
|
|
136
145
|
|
|
137
146
|
Returns
|
|
138
147
|
-------
|
|
139
|
-
|
|
148
|
+
EErrDep
|
|
140
149
|
Enumeration defining INDEPENDENT or DEPENDENT behaviour.
|
|
141
150
|
"""
|
|
142
151
|
return self._err_dep
|
|
143
152
|
|
|
144
|
-
def set_error_dep(self, dependence:
|
|
153
|
+
def set_error_dep(self, dependence: EErrDep) -> None:
|
|
145
154
|
"""Sets the error dependence state for this error calculator. An
|
|
146
155
|
independent error is calculated based on the input truth values as the
|
|
147
156
|
error basis. A dependent error is calculated based on the accumulated
|
|
@@ -149,7 +158,7 @@ class ErrSysField(IErrCalculator):
|
|
|
149
158
|
|
|
150
159
|
Parameters
|
|
151
160
|
----------
|
|
152
|
-
dependence :
|
|
161
|
+
dependence : EErrDep
|
|
153
162
|
Enumeration defining INDEPENDENT or DEPENDENT behaviour.
|
|
154
163
|
"""
|
|
155
164
|
self._err_dep = dependence
|
|
@@ -231,9 +240,9 @@ class ErrSysField(IErrCalculator):
|
|
|
231
240
|
|
|
232
241
|
def _perturb_sensor_positions(sens_pos_nominal: np.ndarray,
|
|
233
242
|
pos_offset_xyz: np.ndarray | None,
|
|
234
|
-
pos_rand_xyz: tuple[
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
pos_rand_xyz: tuple[IGenRandom | None,
|
|
244
|
+
IGenRandom | None,
|
|
245
|
+
IGenRandom | None] | None,
|
|
237
246
|
pos_loc_xyz: np.ndarray | None,
|
|
238
247
|
) -> np.ndarray:
|
|
239
248
|
"""Helper function for perturbing the sensor positions from their nominal
|
|
@@ -249,9 +258,9 @@ def _perturb_sensor_positions(sens_pos_nominal: np.ndarray,
|
|
|
249
258
|
Offsets to apply to the sensor positions as an array with shape=
|
|
250
259
|
(num_sensors,3) wherethe columns represent the position in the X, Y and
|
|
251
260
|
Z axes. If None then no offset is applied.
|
|
252
|
-
pos_rand_xyz : tuple[
|
|
253
|
-
|
|
254
|
-
|
|
261
|
+
pos_rand_xyz : tuple[IGenRandom | None,
|
|
262
|
+
IGenRandom | None,
|
|
263
|
+
IGenRandom | None] | None
|
|
255
264
|
Random generators for sensor position perturbations along the the X, Y
|
|
256
265
|
and Z axes. If None then no perturbation is applied.
|
|
257
266
|
pos_loc_xyz : np.ndarray | None
|
|
@@ -284,7 +293,7 @@ def _perturb_sensor_positions(sens_pos_nominal: np.ndarray,
|
|
|
284
293
|
def _perturb_sample_times(sim_time: np.ndarray,
|
|
285
294
|
time_nominal: np.ndarray | None,
|
|
286
295
|
time_offset: np.ndarray | None,
|
|
287
|
-
time_rand:
|
|
296
|
+
time_rand: IGenRandom | None,
|
|
288
297
|
time_drift: IDriftCalculator | None
|
|
289
298
|
) -> np.ndarray | None:
|
|
290
299
|
"""Helper function for calculating perturbed sensor sampling times for the
|
|
@@ -300,7 +309,7 @@ def _perturb_sample_times(sim_time: np.ndarray,
|
|
|
300
309
|
time_offset : np.ndarray | None
|
|
301
310
|
Array of time offsets to apply to all sensors. If None then no offsets
|
|
302
311
|
are applied.
|
|
303
|
-
time_rand :
|
|
312
|
+
time_rand : IGenRandom | None
|
|
304
313
|
Random generator for perturbing the sampling times of all sensors. If
|
|
305
314
|
None then no random perturbation of sampling times occurs.
|
|
306
315
|
time_drift : IDriftCalculator | None
|
|
@@ -336,9 +345,9 @@ def _perturb_sample_times(sim_time: np.ndarray,
|
|
|
336
345
|
def _perturb_sensor_angles(n_sensors: int,
|
|
337
346
|
angles_nominal: tuple[Rotation,...] | None,
|
|
338
347
|
angle_offsets_zyx: np.ndarray | None,
|
|
339
|
-
rand_ang_zyx: tuple[
|
|
340
|
-
|
|
341
|
-
|
|
348
|
+
rand_ang_zyx: tuple[IGenRandom | None,
|
|
349
|
+
IGenRandom | None,
|
|
350
|
+
IGenRandom | None] | None,
|
|
342
351
|
angle_loc_zyx: np.ndarray | None,
|
|
343
352
|
) -> tuple[Rotation,...] | None:
|
|
344
353
|
"""Helper function for perturbing sensor angles for the purpose of
|
|
@@ -356,9 +365,9 @@ def _perturb_sensor_angles(n_sensors: int,
|
|
|
356
365
|
Angle offsets to apply to the sensor array as an array with shape=(
|
|
357
366
|
num_sensors,3) where the columns are the rotations about Z, Y and X in
|
|
358
367
|
degrees. If None then no offsets are applied.
|
|
359
|
-
rand_ang_zyx : tuple[
|
|
360
|
-
|
|
361
|
-
|
|
368
|
+
rand_ang_zyx : tuple[IGenRandom | None,
|
|
369
|
+
IGenRandom | None,
|
|
370
|
+
IGenRandom | None] | None
|
|
362
371
|
Random generators for perturbing sensor angles about the Z, Y and X axis
|
|
363
372
|
respectively. If None then no random perturbation to the sensor angle
|
|
364
373
|
occurs.
|
|
@@ -402,5 +411,4 @@ def _perturb_sensor_angles(n_sensors: int,
|
|
|
402
411
|
sensor_rot = Rotation.from_euler("zyx",sensor_rot_angs, degrees=True)
|
|
403
412
|
angles_perturbed[ii] = sensor_rot*rot_nom
|
|
404
413
|
|
|
405
|
-
return tuple(angles_perturbed)
|
|
406
|
-
|
|
414
|
+
return tuple(angles_perturbed)
|