acoular 25.4__py3-none-any.whl → 25.10__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 +2 -4
- acoular/aiaa/aiaa.py +10 -10
- acoular/base.py +12 -34
- acoular/calib.py +20 -19
- acoular/configuration.py +3 -3
- acoular/demo/__init__.py +6 -1
- acoular/demo/acoular_demo.py +34 -10
- acoular/deprecation.py +10 -1
- acoular/environments.py +107 -117
- acoular/fastFuncs.py +16 -10
- acoular/fbeamform.py +300 -402
- acoular/fprocess.py +7 -33
- acoular/grids.py +228 -134
- acoular/h5cache.py +10 -4
- acoular/h5files.py +106 -9
- acoular/internal.py +4 -0
- acoular/microphones.py +22 -10
- acoular/process.py +7 -53
- acoular/sdinput.py +8 -5
- acoular/signals.py +29 -27
- acoular/sources.py +205 -335
- acoular/spectra.py +33 -43
- acoular/tbeamform.py +220 -199
- acoular/tools/helpers.py +52 -33
- acoular/tools/metrics.py +5 -10
- acoular/tprocess.py +1392 -647
- acoular/traitsviews.py +1 -3
- acoular/trajectory.py +5 -5
- acoular/version.py +4 -3
- {acoular-25.4.dist-info → acoular-25.10.dist-info}/METADATA +8 -4
- acoular-25.10.dist-info/RECORD +56 -0
- acoular-25.4.dist-info/RECORD +0 -56
- {acoular-25.4.dist-info → acoular-25.10.dist-info}/WHEEL +0 -0
- {acoular-25.4.dist-info → acoular-25.10.dist-info}/licenses/AUTHORS.rst +0 -0
- {acoular-25.4.dist-info → acoular-25.10.dist-info}/licenses/LICENSE +0 -0
acoular/tools/helpers.py
CHANGED
|
@@ -11,21 +11,13 @@
|
|
|
11
11
|
barspectrum
|
|
12
12
|
bardata
|
|
13
13
|
c_air
|
|
14
|
+
get_data_file
|
|
14
15
|
"""
|
|
15
16
|
|
|
17
|
+
from pathlib import Path
|
|
16
18
|
from warnings import warn
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
array,
|
|
20
|
-
concatenate,
|
|
21
|
-
isscalar,
|
|
22
|
-
newaxis,
|
|
23
|
-
searchsorted,
|
|
24
|
-
sum, # noqa A004
|
|
25
|
-
where,
|
|
26
|
-
zeros_like,
|
|
27
|
-
)
|
|
28
|
-
from numpy.ma import masked_where
|
|
20
|
+
import numpy as np
|
|
29
21
|
|
|
30
22
|
from acoular.tools.utils import mole_fraction_of_water_vapor
|
|
31
23
|
|
|
@@ -77,20 +69,20 @@ def synthetic(data, freqs, f, num=3):
|
|
|
77
69
|
and used :attr:`FFT block size<acoular.spectra.PowerSpectra.block_size>`.
|
|
78
70
|
|
|
79
71
|
"""
|
|
80
|
-
if isscalar(f):
|
|
72
|
+
if np.isscalar(f):
|
|
81
73
|
f = (f,)
|
|
82
74
|
if num == 0:
|
|
83
75
|
# single frequency lines
|
|
84
76
|
res = []
|
|
85
77
|
for i in f:
|
|
86
|
-
ind = searchsorted(freqs, i)
|
|
78
|
+
ind = np.searchsorted(freqs, i)
|
|
87
79
|
if ind >= len(freqs):
|
|
88
80
|
warn(
|
|
89
81
|
f'Queried frequency ({i:g} Hz) not in resolved frequency range. Returning zeros.',
|
|
90
82
|
Warning,
|
|
91
83
|
stacklevel=2,
|
|
92
84
|
)
|
|
93
|
-
h = zeros_like(data[0])
|
|
85
|
+
h = np.zeros_like(data[0])
|
|
94
86
|
else:
|
|
95
87
|
if freqs[ind] != i:
|
|
96
88
|
warn(
|
|
@@ -108,8 +100,8 @@ def synthetic(data, freqs, f, num=3):
|
|
|
108
100
|
for i in f:
|
|
109
101
|
f1 = i * 2.0 ** (-0.5 / num)
|
|
110
102
|
f2 = i * 2.0 ** (+0.5 / num)
|
|
111
|
-
ind1 = searchsorted(freqs, f1)
|
|
112
|
-
ind2 = searchsorted(freqs, f2)
|
|
103
|
+
ind1 = np.searchsorted(freqs, f1)
|
|
104
|
+
ind2 = np.searchsorted(freqs, f2)
|
|
113
105
|
if ind1 == ind2:
|
|
114
106
|
warn(
|
|
115
107
|
f'Queried frequency band ({f1:g} to {f2:g} Hz) does not '
|
|
@@ -118,11 +110,11 @@ def synthetic(data, freqs, f, num=3):
|
|
|
118
110
|
Warning,
|
|
119
111
|
stacklevel=2,
|
|
120
112
|
)
|
|
121
|
-
h = zeros_like(data[0])
|
|
113
|
+
h = np.zeros_like(data[0])
|
|
122
114
|
else:
|
|
123
|
-
h = sum(data[ind1:ind2], 0)
|
|
115
|
+
h = np.sum(data[ind1:ind2], 0)
|
|
124
116
|
res += [h]
|
|
125
|
-
return array(res)
|
|
117
|
+
return np.array(res)
|
|
126
118
|
|
|
127
119
|
|
|
128
120
|
def return_result(source, nmax=-1, num=128):
|
|
@@ -152,8 +144,8 @@ def return_result(source, nmax=-1, num=128):
|
|
|
152
144
|
|
|
153
145
|
if nmax > 0:
|
|
154
146
|
nblocks = (nmax - 1) // num + 1
|
|
155
|
-
return concatenate([res for _, res in zip(range(nblocks), resulter)])[:nmax]
|
|
156
|
-
return concatenate(list(resulter))
|
|
147
|
+
return np.concatenate([res for _, res in zip(range(nblocks), resulter)])[:nmax]
|
|
148
|
+
return np.concatenate(list(resulter))
|
|
157
149
|
|
|
158
150
|
|
|
159
151
|
def barspectrum(data, fftfreqs, num=3, bar=True, xoffset=0.0):
|
|
@@ -201,9 +193,9 @@ def barspectrum(data, fftfreqs, num=3, bar=True, xoffset=0.0):
|
|
|
201
193
|
return (0, 0, 0)
|
|
202
194
|
|
|
203
195
|
# preferred center freqs after din en iso 266 for third-octave bands
|
|
204
|
-
fcbase = array([31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250])
|
|
196
|
+
fcbase = np.array([31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250])
|
|
205
197
|
# DIN band center frequencies from 31.5 Hz to 25 kHz
|
|
206
|
-
fc = concatenate((fcbase, fcbase * 10.0, fcbase[:] * 100.0))[:: (3 // num)]
|
|
198
|
+
fc = np.concatenate((fcbase, fcbase * 10.0, fcbase[:] * 100.0))[:: (3 // num)]
|
|
207
199
|
|
|
208
200
|
# exponent for band width calculation
|
|
209
201
|
ep = 1.0 / (2.0 * num)
|
|
@@ -213,16 +205,16 @@ def barspectrum(data, fftfreqs, num=3, bar=True, xoffset=0.0):
|
|
|
213
205
|
f_low = fftfreqs[1] * 2**ep
|
|
214
206
|
f_high = fftfreqs[-1] * 2**-ep
|
|
215
207
|
# get possible index range
|
|
216
|
-
i_low = 0 if fc[0] >= f_low else where(fc < f_low)[0][-1]
|
|
208
|
+
i_low = 0 if fc[0] >= f_low else np.where(fc < f_low)[0][-1]
|
|
217
209
|
|
|
218
|
-
i_high = fc.shape[0] if fc[-1] <= f_high else where(fc > f_high)[0][0]
|
|
210
|
+
i_high = fc.shape[0] if fc[-1] <= f_high else np.where(fc > f_high)[0][0]
|
|
219
211
|
|
|
220
212
|
# synthesize sound pressure values
|
|
221
|
-
p = array([synthetic(data, fftfreqs, list(fc[i_low:i_high]), num)])
|
|
213
|
+
p = np.array([synthetic(data, fftfreqs, list(fc[i_low:i_high]), num)])
|
|
222
214
|
|
|
223
215
|
if bar:
|
|
224
216
|
# upper and lower band borders
|
|
225
|
-
flu = concatenate(
|
|
217
|
+
flu = np.concatenate(
|
|
226
218
|
(
|
|
227
219
|
fc[i_low : i_low + 1] * 2**-ep,
|
|
228
220
|
(fc[i_low : i_high - 1] * 2**ep + fc[i_low + 1 : i_high] * 2**-ep) / 2.0,
|
|
@@ -230,9 +222,9 @@ def barspectrum(data, fftfreqs, num=3, bar=True, xoffset=0.0):
|
|
|
230
222
|
),
|
|
231
223
|
)
|
|
232
224
|
# band borders as coordinates for bar plotting
|
|
233
|
-
flulist = 2 ** (2 * xoffset * ep) * (array([1, 1])[:, newaxis] * flu[newaxis, :]).T.reshape(-1)[1:-1]
|
|
225
|
+
flulist = 2 ** (2 * xoffset * ep) * (np.array([1, 1])[:, np.newaxis] * flu[np.newaxis, :]).T.reshape(-1)[1:-1]
|
|
234
226
|
# sound pressures as list for bar plotting
|
|
235
|
-
plist = (array([1, 1])[:, newaxis] * p[newaxis, :]).T.reshape(-1)
|
|
227
|
+
plist = (np.array([1, 1])[:, np.newaxis] * p[np.newaxis, :]).T.reshape(-1)
|
|
236
228
|
else:
|
|
237
229
|
flulist = fc[i_low:i_high]
|
|
238
230
|
plist = p[0, :]
|
|
@@ -278,17 +270,19 @@ def bardata(data, fc, num=3, bar=True, xoffset=0.0, masked=-360):
|
|
|
278
270
|
|
|
279
271
|
if bar:
|
|
280
272
|
# upper and lower band borders
|
|
281
|
-
flu = concatenate((fc[:1] * 2**-ep, (fc[:-1] * 2**ep + fc[1:] * 2**-ep) / 2.0, fc[-1:] * 2**ep))
|
|
273
|
+
flu = np.concatenate((fc[:1] * 2**-ep, (fc[:-1] * 2**ep + fc[1:] * 2**-ep) / 2.0, fc[-1:] * 2**ep))
|
|
282
274
|
# band borders as coordinates for bar plotting
|
|
283
|
-
flulist =
|
|
275
|
+
flulist = (
|
|
276
|
+
2 ** (xoffset * 1.0 / num) * (np.array([1, 1])[:, np.newaxis] * flu[np.newaxis, :]).T.reshape(-1)[1:-1]
|
|
277
|
+
)
|
|
284
278
|
# sound pressures as list for bar plotting
|
|
285
|
-
plist = (array([1, 1])[:, newaxis] * data[newaxis, :]).T.reshape(-1)
|
|
279
|
+
plist = (np.array([1, 1])[:, np.newaxis] * data[np.newaxis, :]).T.reshape(-1)
|
|
286
280
|
else:
|
|
287
281
|
flulist = fc
|
|
288
282
|
plist = data
|
|
289
283
|
# print(flulist.shape, plist.shape)
|
|
290
284
|
if masked > -360:
|
|
291
|
-
plist = masked_where(plist <= masked, plist)
|
|
285
|
+
plist = np.ma.masked_where(plist <= masked, plist)
|
|
292
286
|
return (flulist, plist)
|
|
293
287
|
|
|
294
288
|
|
|
@@ -401,3 +395,28 @@ def c_air(t, h, p=101325, co2=0.04):
|
|
|
401
395
|
+ a14 * x_c**2
|
|
402
396
|
+ a15 * x_w * p * x_c
|
|
403
397
|
)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def get_data_file(file):
|
|
401
|
+
"""
|
|
402
|
+
Ensures a file is available locally.
|
|
403
|
+
|
|
404
|
+
If the file does not exist in ``'../data/'`` or the current directory,
|
|
405
|
+
it is downloaded from the Acoular GitHub repository.
|
|
406
|
+
|
|
407
|
+
Returns
|
|
408
|
+
-------
|
|
409
|
+
:class:`pathlib.Path`
|
|
410
|
+
Path to the file.
|
|
411
|
+
"""
|
|
412
|
+
data_file = Path('../data') / file
|
|
413
|
+
if not data_file.exists():
|
|
414
|
+
data_file = Path().cwd() / file
|
|
415
|
+
if not data_file.exists():
|
|
416
|
+
import urllib.request
|
|
417
|
+
|
|
418
|
+
url = 'https://github.com/acoular/acoular/raw/master/examples/data/' + file
|
|
419
|
+
urllib.request.urlretrieve(url, data_file)
|
|
420
|
+
print(f'Calibration file location: {data_file}')
|
|
421
|
+
|
|
422
|
+
return data_file
|
acoular/tools/metrics.py
CHANGED
|
@@ -11,12 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
from copy import copy
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
empty,
|
|
16
|
-
inf,
|
|
17
|
-
minimum,
|
|
18
|
-
ones,
|
|
19
|
-
)
|
|
14
|
+
import numpy as np
|
|
20
15
|
from scipy.spatial.distance import cdist
|
|
21
16
|
from traits.api import Bool, CArray, HasStrictTraits, Instance, Property
|
|
22
17
|
|
|
@@ -82,13 +77,13 @@ class MetricEvaluator(HasStrictTraits):
|
|
|
82
77
|
|
|
83
78
|
def _get_sector_radii(self):
|
|
84
79
|
ns = self.target_data.shape[1]
|
|
85
|
-
radii = ones(ns) * self.sector.r
|
|
80
|
+
radii = np.ones(ns) * self.sector.r
|
|
86
81
|
if self.adaptive_sector_size:
|
|
87
82
|
locs = self.target_grid.pos.T
|
|
88
83
|
intersrcdist = cdist(locs, locs)
|
|
89
|
-
intersrcdist[intersrcdist == 0] = inf
|
|
84
|
+
intersrcdist[intersrcdist == 0] = np.inf
|
|
90
85
|
intersrcdist = intersrcdist.min(0) / 2
|
|
91
|
-
radii = minimum(radii, intersrcdist)
|
|
86
|
+
radii = np.minimum(radii, intersrcdist)
|
|
92
87
|
return radii
|
|
93
88
|
|
|
94
89
|
def _get_sectors(self):
|
|
@@ -115,7 +110,7 @@ class MetricEvaluator(HasStrictTraits):
|
|
|
115
110
|
|
|
116
111
|
"""
|
|
117
112
|
sectors = self.sectors
|
|
118
|
-
results = empty(shape=self.target_data.shape)
|
|
113
|
+
results = np.empty(shape=self.target_data.shape)
|
|
119
114
|
for f in range(self.target_data.shape[0]):
|
|
120
115
|
data = self.data[f]
|
|
121
116
|
for i in range(self.target_data.shape[1]):
|