acoular 24.3__py3-none-any.whl → 24.7__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.
- acoular/__init__.py +119 -54
- acoular/calib.py +29 -38
- acoular/configuration.py +132 -82
- acoular/demo/__init__.py +10 -4
- acoular/demo/acoular_demo.py +73 -55
- acoular/environments.py +270 -264
- acoular/fastFuncs.py +366 -196
- acoular/fbeamform.py +1797 -1934
- acoular/grids.py +504 -548
- acoular/h5cache.py +74 -83
- acoular/h5files.py +159 -142
- acoular/internal.py +13 -14
- acoular/microphones.py +57 -53
- acoular/sdinput.py +57 -53
- acoular/signals.py +180 -178
- acoular/sources.py +920 -724
- acoular/spectra.py +353 -363
- acoular/tbeamform.py +416 -416
- acoular/tfastfuncs.py +180 -104
- acoular/tools/__init__.py +25 -0
- acoular/tools/aiaa.py +185 -0
- acoular/tools/helpers.py +189 -0
- acoular/tools/metrics.py +165 -0
- acoular/tprocess.py +1240 -1182
- acoular/traitsviews.py +513 -501
- acoular/trajectory.py +50 -52
- acoular/version.py +5 -6
- acoular/xml/minidsp_uma-16.xml +20 -0
- acoular/xml/{minidsp_uma16.xml → minidsp_uma-16_mirrored.xml} +3 -0
- {acoular-24.3.dist-info → acoular-24.7.dist-info}/METADATA +58 -39
- acoular-24.7.dist-info/RECORD +50 -0
- {acoular-24.3.dist-info → acoular-24.7.dist-info}/WHEEL +1 -1
- acoular-24.7.dist-info/licenses/LICENSE +28 -0
- acoular/fileimport.py +0 -380
- acoular/nidaqimport.py +0 -273
- acoular/tests/reference_data/BeamformerBase.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseFalse1.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseFalse2.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseFalse3.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseFalse4.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseTrue1.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseTrue2.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseTrue3.npy +0 -0
- acoular/tests/reference_data/BeamformerBaseTrue4.npy +0 -0
- acoular/tests/reference_data/BeamformerCMFLassoLarsBIC.npy +0 -0
- acoular/tests/reference_data/BeamformerCMFNNLS.npy +0 -0
- acoular/tests/reference_data/BeamformerCapon.npy +0 -0
- acoular/tests/reference_data/BeamformerClean.npy +0 -0
- acoular/tests/reference_data/BeamformerCleansc.npy +0 -0
- acoular/tests/reference_data/BeamformerCleant.npy +0 -0
- acoular/tests/reference_data/BeamformerCleantSq.npy +0 -0
- acoular/tests/reference_data/BeamformerCleantSqTraj.npy +0 -0
- acoular/tests/reference_data/BeamformerCleantTraj.npy +0 -0
- acoular/tests/reference_data/BeamformerDamas.npy +0 -0
- acoular/tests/reference_data/BeamformerDamasPlus.npy +0 -0
- acoular/tests/reference_data/BeamformerEig.npy +0 -0
- acoular/tests/reference_data/BeamformerEigFalse1.npy +0 -0
- acoular/tests/reference_data/BeamformerEigFalse2.npy +0 -0
- acoular/tests/reference_data/BeamformerEigFalse3.npy +0 -0
- acoular/tests/reference_data/BeamformerEigFalse4.npy +0 -0
- acoular/tests/reference_data/BeamformerEigTrue1.npy +0 -0
- acoular/tests/reference_data/BeamformerEigTrue2.npy +0 -0
- acoular/tests/reference_data/BeamformerEigTrue3.npy +0 -0
- acoular/tests/reference_data/BeamformerEigTrue4.npy +0 -0
- acoular/tests/reference_data/BeamformerFunctional.npy +0 -0
- acoular/tests/reference_data/BeamformerGIB.npy +0 -0
- acoular/tests/reference_data/BeamformerGridlessOrth.npy +0 -0
- acoular/tests/reference_data/BeamformerMusic.npy +0 -0
- acoular/tests/reference_data/BeamformerOrth.npy +0 -0
- acoular/tests/reference_data/BeamformerSODIX.npy +0 -0
- acoular/tests/reference_data/BeamformerTime.npy +0 -0
- acoular/tests/reference_data/BeamformerTimeSq.npy +0 -0
- acoular/tests/reference_data/BeamformerTimeSqTraj.npy +0 -0
- acoular/tests/reference_data/BeamformerTimeTraj.npy +0 -0
- acoular/tests/reference_data/Environment.npy +0 -0
- acoular/tests/reference_data/Example1_numerical_values_testsum.h5 +0 -0
- acoular/tests/reference_data/FiltFiltOctave__.npy +0 -0
- acoular/tests/reference_data/FiltFiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
- acoular/tests/reference_data/FiltFreqWeight_weight_A_.npy +0 -0
- acoular/tests/reference_data/FiltFreqWeight_weight_C_.npy +0 -0
- acoular/tests/reference_data/FiltFreqWeight_weight_Z_.npy +0 -0
- acoular/tests/reference_data/FiltOctave__.npy +0 -0
- acoular/tests/reference_data/FiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
- acoular/tests/reference_data/Filter__.npy +0 -0
- acoular/tests/reference_data/GeneralFlowEnvironment.npy +0 -0
- acoular/tests/reference_data/OctaveFilterBank__.npy +0 -0
- acoular/tests/reference_data/OpenJet.npy +0 -0
- acoular/tests/reference_data/PointSource.npy +0 -0
- acoular/tests/reference_data/PowerSpectra_csm.npy +0 -0
- acoular/tests/reference_data/PowerSpectra_ev.npy +0 -0
- acoular/tests/reference_data/RotatingFlow.npy +0 -0
- acoular/tests/reference_data/SlotJet.npy +0 -0
- acoular/tests/reference_data/TimeAverage__.npy +0 -0
- acoular/tests/reference_data/TimeCumAverage__.npy +0 -0
- acoular/tests/reference_data/TimeExpAverage_weight_F_.npy +0 -0
- acoular/tests/reference_data/TimeExpAverage_weight_I_.npy +0 -0
- acoular/tests/reference_data/TimeExpAverage_weight_S_.npy +0 -0
- acoular/tests/reference_data/TimeInOut__.npy +0 -0
- acoular/tests/reference_data/TimePower__.npy +0 -0
- acoular/tests/reference_data/TimeReverse__.npy +0 -0
- acoular/tests/reference_data/UniformFlowEnvironment.npy +0 -0
- acoular/tests/reference_data/beamformer_traj_time_data.h5 +0 -0
- acoular/tests/run_tests.sh +0 -18
- acoular/tests/run_tests_osx.sh +0 -16
- acoular/tests/test.npy +0 -0
- acoular/tests/test_beamformer_results.py +0 -213
- acoular/tests/test_classes.py +0 -60
- acoular/tests/test_digest.py +0 -125
- acoular/tests/test_environments.py +0 -73
- acoular/tests/test_example1.py +0 -124
- acoular/tests/test_grid.py +0 -92
- acoular/tests/test_integrate.py +0 -102
- acoular/tests/test_signals.py +0 -60
- acoular/tests/test_sources.py +0 -65
- acoular/tests/test_spectra.py +0 -38
- acoular/tests/test_timecache.py +0 -35
- acoular/tests/test_tprocess.py +0 -90
- acoular/tests/test_traj_beamformer_results.py +0 -164
- acoular/tests/unsupported/SpeedComparison/OvernightTestcasesBeamformer_nMics32_nGridPoints100_nFreqs4_nTrials10.png +0 -0
- acoular/tests/unsupported/SpeedComparison/cythonBeamformer.pyx +0 -237
- acoular/tests/unsupported/SpeedComparison/mainForCython.py +0 -103
- acoular/tests/unsupported/SpeedComparison/mainForParallelJit.py +0 -143
- acoular/tests/unsupported/SpeedComparison/setupCythonOpenMP.py +0 -63
- acoular/tests/unsupported/SpeedComparison/sharedFunctions.py +0 -153
- acoular/tests/unsupported/SpeedComparison/timeOverNMics_AllImportantMethods.png +0 -0
- acoular/tests/unsupported/SpeedComparison/timeOverNMics_faverage.png +0 -0
- acoular/tests/unsupported/SpeedComparison/vglOptimierungFAverage.py +0 -204
- acoular/tests/unsupported/SpeedComparison/vglOptimierungGaussSeidel.py +0 -182
- acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAMFULL_INVERSE.py +0 -764
- acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAM_OS.py +0 -231
- acoular/tests/unsupported/SpeedComparison/whatsFastestWayFor_absASquared.py +0 -48
- acoular/tests/unsupported/functionalBeamformer.py +0 -123
- acoular/tests/unsupported/precisionTest.py +0 -153
- acoular/tests/unsupported/validationOfBeamformerFuncsPOSTAcoularIntegration.py +0 -254
- acoular/tests/unsupported/validationOfBeamformerFuncsPREeAcoularIntegration.py +0 -531
- acoular/tools.py +0 -422
- acoular-24.3.dist-info/RECORD +0 -148
- acoular-24.3.dist-info/licenses/LICENSE +0 -29
- {acoular-24.3.dist-info → acoular-24.7.dist-info}/licenses/AUTHORS.rst +0 -0
acoular/tools/helpers.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# ------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Acoular Development Team.
|
|
3
|
+
# ------------------------------------------------------------------------------
|
|
4
|
+
"""Implements some helper functions that are useful for Acoular.
|
|
5
|
+
|
|
6
|
+
.. autosummary::
|
|
7
|
+
:toctree: generated/
|
|
8
|
+
|
|
9
|
+
return_result
|
|
10
|
+
barspectrum
|
|
11
|
+
bardata
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from numpy import (
|
|
15
|
+
array,
|
|
16
|
+
concatenate,
|
|
17
|
+
newaxis,
|
|
18
|
+
where,
|
|
19
|
+
)
|
|
20
|
+
from numpy.ma import masked_where
|
|
21
|
+
|
|
22
|
+
from acoular.spectra import synthetic
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def return_result(source, nmax=-1, num=128):
|
|
26
|
+
"""Collects the output from a
|
|
27
|
+
:meth:`SamplesGenerator.result()<acoular.tprocess.SamplesGenerator.result>`
|
|
28
|
+
generator and returns an assembled array with all the data.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
source: SamplesGenerator or derived object.
|
|
33
|
+
This is the :class:`SamplesGenerator<acoular.tprocess.SamplesGenerator>` data source.
|
|
34
|
+
nmax: integer
|
|
35
|
+
With this parameter, a maximum number of output samples can be set
|
|
36
|
+
(first dimension of array). If set to -1 (default), samples are
|
|
37
|
+
collected as long as the generator yields them.
|
|
38
|
+
num : integer
|
|
39
|
+
This parameter defines the size of the blocks that are fetched.
|
|
40
|
+
Defaults to 128.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
array of floats (number of samples, source.numchannels)
|
|
45
|
+
Array that holds all the data.
|
|
46
|
+
|
|
47
|
+
"""
|
|
48
|
+
resulter = (_.copy() for _ in source.result(num))
|
|
49
|
+
|
|
50
|
+
if nmax > 0:
|
|
51
|
+
nblocks = (nmax - 1) // num + 1
|
|
52
|
+
return concatenate([res for _, res in zip(range(nblocks), resulter)])[:nmax]
|
|
53
|
+
return concatenate(list(resulter))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def barspectrum(data, fftfreqs, num=3, bar=True, xoffset=0.0):
|
|
57
|
+
"""Returns synthesized frequency band values of spectral data to be plotted
|
|
58
|
+
as bar graph with the matlpotlib plot command.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
data : array of floats
|
|
64
|
+
The spectral data (sound pressures in Pa) in an array with one value
|
|
65
|
+
per frequency line.
|
|
66
|
+
fftfreqs : array of floats
|
|
67
|
+
Discrete frequencies from FFT.
|
|
68
|
+
num : integer
|
|
69
|
+
Controls the width of the frequency bands considered; defaults to
|
|
70
|
+
3 (third-octave band).
|
|
71
|
+
bar : bool
|
|
72
|
+
If True, returns bar-like curve. If False, normal plot (direct
|
|
73
|
+
line between data points) is returned.
|
|
74
|
+
xoffset : float
|
|
75
|
+
If bar is True, offset of the perpendicular line (helpful if
|
|
76
|
+
plotting several curves above each other).
|
|
77
|
+
|
|
78
|
+
=== =====================
|
|
79
|
+
num frequency band width
|
|
80
|
+
=== =====================
|
|
81
|
+
1 octave band
|
|
82
|
+
3 third-octave band
|
|
83
|
+
=== =====================
|
|
84
|
+
|
|
85
|
+
Returns
|
|
86
|
+
-------
|
|
87
|
+
(flulist, plist, fc)
|
|
88
|
+
flulist : array of floats
|
|
89
|
+
Lower/upper band frequencies in plottable format.
|
|
90
|
+
plist : array of floats
|
|
91
|
+
Corresponding synthesized frequency band values in plottable format.
|
|
92
|
+
fc : array of floats
|
|
93
|
+
Evaluated band center frequencies.
|
|
94
|
+
|
|
95
|
+
"""
|
|
96
|
+
if num not in [1, 3]:
|
|
97
|
+
print('Only octave and third-octave bands supported at this moment.')
|
|
98
|
+
return (0, 0, 0)
|
|
99
|
+
|
|
100
|
+
# preferred center freqs after din en iso 266 for third-octave bands
|
|
101
|
+
fcbase = array([31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250])
|
|
102
|
+
# DIN band center frequencies from 31.5 Hz to 25 kHz
|
|
103
|
+
fc = concatenate((fcbase, fcbase * 10.0, fcbase[:] * 100.0))[:: (3 // num)]
|
|
104
|
+
|
|
105
|
+
# exponent for band width calculation
|
|
106
|
+
ep = 1.0 / (2.0 * num)
|
|
107
|
+
|
|
108
|
+
# lowest and highest possible center frequencies
|
|
109
|
+
# for chosen band and sampling frequency
|
|
110
|
+
f_low = fftfreqs[1] * 2**ep
|
|
111
|
+
f_high = fftfreqs[-1] * 2**-ep
|
|
112
|
+
# get possible index range
|
|
113
|
+
i_low = 0 if fc[0] >= f_low else where(fc < f_low)[0][-1]
|
|
114
|
+
|
|
115
|
+
i_high = fc.shape[0] if fc[-1] <= f_high else where(fc > f_high)[0][0]
|
|
116
|
+
|
|
117
|
+
# synthesize sound pressure values
|
|
118
|
+
p = array([synthetic(data, fftfreqs, list(fc[i_low:i_high]), num)])
|
|
119
|
+
|
|
120
|
+
if bar:
|
|
121
|
+
# upper and lower band borders
|
|
122
|
+
flu = concatenate(
|
|
123
|
+
(
|
|
124
|
+
fc[i_low : i_low + 1] * 2**-ep,
|
|
125
|
+
(fc[i_low : i_high - 1] * 2**ep + fc[i_low + 1 : i_high] * 2**-ep) / 2.0,
|
|
126
|
+
fc[i_high - 1 : i_high] * 2**ep,
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
# band borders as coordinates for bar plotting
|
|
130
|
+
flulist = 2 ** (2 * xoffset * ep) * (array([1, 1])[:, newaxis] * flu[newaxis, :]).T.reshape(-1)[1:-1]
|
|
131
|
+
# sound pressures as list for bar plotting
|
|
132
|
+
plist = (array([1, 1])[:, newaxis] * p[newaxis, :]).T.reshape(-1)
|
|
133
|
+
else:
|
|
134
|
+
flulist = fc[i_low:i_high]
|
|
135
|
+
plist = p[0, :]
|
|
136
|
+
# print(flulist.shape, plist.shape)
|
|
137
|
+
return (flulist, plist, fc[i_low:i_high])
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def bardata(data, fc, num=3, bar=True, xoffset=0.0, masked=-360):
|
|
141
|
+
"""Returns data to be plotted
|
|
142
|
+
as bar graph with the matlpotlib plot command.
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
data : array of floats
|
|
148
|
+
The spectral data
|
|
149
|
+
fc : array of floats
|
|
150
|
+
Band center frequencies
|
|
151
|
+
bar : bool
|
|
152
|
+
If True, returns bar-like curve. If False, normal plot (direct
|
|
153
|
+
line between data points) is returned.
|
|
154
|
+
xoffset : float
|
|
155
|
+
If bar is True, offset of the perpendicular line (helpful if
|
|
156
|
+
plotting several curves above each other).
|
|
157
|
+
|
|
158
|
+
=== =====================
|
|
159
|
+
num frequency band width
|
|
160
|
+
=== =====================
|
|
161
|
+
1 octave band
|
|
162
|
+
3 third-octave band
|
|
163
|
+
=== =====================
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
(flulist, plist)
|
|
168
|
+
flulist : array of floats
|
|
169
|
+
Lower/upper band frequencies in plottable format.
|
|
170
|
+
plist : array of floats
|
|
171
|
+
Corresponding values in plottable format.
|
|
172
|
+
|
|
173
|
+
"""
|
|
174
|
+
ep = 1.0 / (2.0 * num)
|
|
175
|
+
|
|
176
|
+
if bar:
|
|
177
|
+
# upper and lower band borders
|
|
178
|
+
flu = concatenate((fc[:1] * 2**-ep, (fc[:-1] * 2**ep + fc[1:] * 2**-ep) / 2.0, fc[-1:] * 2**ep))
|
|
179
|
+
# band borders as coordinates for bar plotting
|
|
180
|
+
flulist = 2 ** (xoffset * 1.0 / num) * (array([1, 1])[:, newaxis] * flu[newaxis, :]).T.reshape(-1)[1:-1]
|
|
181
|
+
# sound pressures as list for bar plotting
|
|
182
|
+
plist = (array([1, 1])[:, newaxis] * data[newaxis, :]).T.reshape(-1)
|
|
183
|
+
else:
|
|
184
|
+
flulist = fc
|
|
185
|
+
plist = data
|
|
186
|
+
# print(flulist.shape, plist.shape)
|
|
187
|
+
if masked > -360:
|
|
188
|
+
plist = masked_where(plist <= masked, plist)
|
|
189
|
+
return (flulist, plist)
|
acoular/tools/metrics.py
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# ------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Acoular Development Team.
|
|
3
|
+
# ------------------------------------------------------------------------------
|
|
4
|
+
"""Implements metrics for evaluating signal processing results.
|
|
5
|
+
|
|
6
|
+
.. autosummary::
|
|
7
|
+
:toctree: generated/
|
|
8
|
+
|
|
9
|
+
MetricEvaluator
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from copy import copy
|
|
13
|
+
|
|
14
|
+
from numpy import (
|
|
15
|
+
empty,
|
|
16
|
+
inf,
|
|
17
|
+
minimum,
|
|
18
|
+
ones,
|
|
19
|
+
)
|
|
20
|
+
from scipy.spatial.distance import cdist
|
|
21
|
+
from traits.api import Bool, CArray, HasPrivateTraits, Instance, Property
|
|
22
|
+
|
|
23
|
+
from acoular.fbeamform import L_p, integrate
|
|
24
|
+
from acoular.grids import CircSector, Grid
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MetricEvaluator(HasPrivateTraits):
|
|
28
|
+
"""Evaluate the reconstruction performance of source mapping methods.
|
|
29
|
+
|
|
30
|
+
This class can be used to calculate the following performance metrics
|
|
31
|
+
according to Herold and Sarradj (2017):
|
|
32
|
+
* Specific level error
|
|
33
|
+
* Overall level error
|
|
34
|
+
* Inverse level error
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
#: an array of shape=(nf,ng) containing the squared sound pressure data of the
|
|
38
|
+
#: source mapping. (nf: number of frequencies, ng: number of grid points)
|
|
39
|
+
data = CArray(shape=(None, None), desc='Contains the calculated squared sound pressure values in Pa**2.')
|
|
40
|
+
|
|
41
|
+
#: an array of shape=(nf,ns) containing the squared sound pressure data of the
|
|
42
|
+
#: ground-truth sources. (nf: number of frequencies, ns: number of sources)
|
|
43
|
+
target_data = CArray(shape=(None, None), desc='Contains the ground-truth squared sound pressure values in Pa**2.')
|
|
44
|
+
|
|
45
|
+
#: :class:`~acoular.grids.Grid`-derived object that provides the grid locations
|
|
46
|
+
#: for the calculated source mapping data.
|
|
47
|
+
grid = Instance(Grid, desc='Grid instance that belongs to the calculated data')
|
|
48
|
+
|
|
49
|
+
#: :class:`~acoular.grids.Grid`-derived object that provides the grid locations
|
|
50
|
+
#: for the ground-truth data.
|
|
51
|
+
target_grid = Instance(Grid, desc='Grid instance that belongs to the ground-truth data')
|
|
52
|
+
|
|
53
|
+
#: sector type. Currently only circular sectors are supported.
|
|
54
|
+
sector = Instance(CircSector, default=CircSector())
|
|
55
|
+
|
|
56
|
+
#: if set True: use shrink integration area if two sources are closer
|
|
57
|
+
#: than 2*r. The radius of the integration area is then set to half the
|
|
58
|
+
#: distance between the two sources.
|
|
59
|
+
adaptive_sector_size = Bool(True, desc='adaptive integration area')
|
|
60
|
+
|
|
61
|
+
#: if set `True`, the same amplitude can be assigned to multiple targets if
|
|
62
|
+
#: the integration area overlaps. If set `False`, the amplitude is assigned
|
|
63
|
+
#: to the first target and the other targets are ignored.
|
|
64
|
+
multi_assignment = Bool(
|
|
65
|
+
True,
|
|
66
|
+
desc='if set True, the same amplitude can be assigned to multiple targets if the integration area overlaps',
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
#: returns the determined sector sizes for each ground-truth source position
|
|
70
|
+
sectors = Property()
|
|
71
|
+
|
|
72
|
+
def _validate_shapes(self):
|
|
73
|
+
if self.data.shape[0] != self.target_data.shape[0]:
|
|
74
|
+
msg = 'data and target_data must have the same number of frequencies!'
|
|
75
|
+
raise ValueError(msg)
|
|
76
|
+
if self.data.shape[1] != self.grid.size:
|
|
77
|
+
msg = 'data and grid must have the same number of grid points!'
|
|
78
|
+
raise ValueError(msg)
|
|
79
|
+
if self.target_data.shape[1] != self.target_grid.size:
|
|
80
|
+
msg = 'target_data and target_grid must have the same number of grid points!'
|
|
81
|
+
raise ValueError(msg)
|
|
82
|
+
|
|
83
|
+
def _get_sector_radii(self):
|
|
84
|
+
ns = self.target_data.shape[1]
|
|
85
|
+
radii = ones(ns) * self.sector.r
|
|
86
|
+
if self.adaptive_sector_size:
|
|
87
|
+
locs = self.target_grid.gpos.T
|
|
88
|
+
intersrcdist = cdist(locs, locs)
|
|
89
|
+
intersrcdist[intersrcdist == 0] = inf
|
|
90
|
+
intersrcdist = intersrcdist.min(0) / 2
|
|
91
|
+
radii = minimum(radii, intersrcdist)
|
|
92
|
+
return radii
|
|
93
|
+
|
|
94
|
+
def _get_sectors(self):
|
|
95
|
+
"""Returns a list of CircSector objects for each target location."""
|
|
96
|
+
r = self._get_sector_radii()
|
|
97
|
+
ns = self.target_data.shape[1]
|
|
98
|
+
sectors = []
|
|
99
|
+
for i in range(ns):
|
|
100
|
+
loc = self.target_grid.gpos[:, i]
|
|
101
|
+
sector = copy(self.sector)
|
|
102
|
+
sector.r = r[i]
|
|
103
|
+
sector.x = loc[0]
|
|
104
|
+
sector.y = loc[1]
|
|
105
|
+
sectors.append(sector)
|
|
106
|
+
return sectors
|
|
107
|
+
|
|
108
|
+
def _integrate_sectors(self):
|
|
109
|
+
"""Integrates over target sectors.
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
113
|
+
array (num_freqs,num_sources)
|
|
114
|
+
returns the integrated Pa**2 values for each sector
|
|
115
|
+
|
|
116
|
+
"""
|
|
117
|
+
sectors = self.sectors
|
|
118
|
+
results = empty(shape=self.target_data.shape)
|
|
119
|
+
for f in range(self.target_data.shape[0]):
|
|
120
|
+
data = self.data[f]
|
|
121
|
+
for i in range(self.target_data.shape[1]):
|
|
122
|
+
sector = sectors[i]
|
|
123
|
+
results[f, i] = integrate(data, self.grid, sector)
|
|
124
|
+
if not self.multi_assignment:
|
|
125
|
+
indices = self.grid.subdomain(sector)
|
|
126
|
+
data[indices] = 0 # set values to zero (can not be assigned again)
|
|
127
|
+
return results
|
|
128
|
+
|
|
129
|
+
def get_overall_level_error(self):
|
|
130
|
+
"""Returns the overall level error (Herold and Sarradj, 2017).
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
numpy.array
|
|
135
|
+
overall level error of shape=(nf,)
|
|
136
|
+
|
|
137
|
+
"""
|
|
138
|
+
self._validate_shapes()
|
|
139
|
+
return L_p(self.data.sum(axis=1)) - L_p(self.target_data.sum(axis=1))
|
|
140
|
+
|
|
141
|
+
def get_specific_level_error(self):
|
|
142
|
+
"""Returns the specific level error (Herold and Sarradj, 2017).
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
numpy.array
|
|
147
|
+
specific level error of shape=(nf,ns). nf: number of frequencies, ns: number of sources
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
self._validate_shapes()
|
|
151
|
+
sector_result = self._integrate_sectors()
|
|
152
|
+
return L_p(sector_result) - L_p(self.target_data)
|
|
153
|
+
|
|
154
|
+
def get_inverse_level_error(self):
|
|
155
|
+
"""Returns the inverse level error (Herold and Sarradj, 2017).
|
|
156
|
+
|
|
157
|
+
Returns
|
|
158
|
+
-------
|
|
159
|
+
numpy.array
|
|
160
|
+
inverse level error of shape=(nf,1)
|
|
161
|
+
|
|
162
|
+
"""
|
|
163
|
+
self._validate_shapes()
|
|
164
|
+
sector_result = self._integrate_sectors()
|
|
165
|
+
return L_p(sector_result.sum(axis=1)) - L_p(self.data.sum(axis=1))
|