acoular 24.10__tar.gz → 25.1__tar.gz
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-24.10 → acoular-25.1}/PKG-INFO +38 -17
- {acoular-24.10 → acoular-25.1}/README.md +22 -13
- {acoular-24.10 → acoular-25.1}/acoular/__init__.py +5 -2
- acoular-25.1/acoular/aiaa/__init__.py +12 -0
- {acoular-24.10/acoular/tools → acoular-25.1/acoular/aiaa}/aiaa.py +23 -28
- {acoular-24.10 → acoular-25.1}/acoular/base.py +75 -55
- acoular-25.1/acoular/calib.py +173 -0
- {acoular-24.10 → acoular-25.1}/acoular/configuration.py +11 -9
- {acoular-24.10 → acoular-25.1}/acoular/demo/__init__.py +1 -0
- {acoular-24.10 → acoular-25.1}/acoular/demo/acoular_demo.py +29 -16
- acoular-25.1/acoular/deprecation.py +85 -0
- {acoular-24.10 → acoular-25.1}/acoular/environments.py +31 -19
- {acoular-24.10 → acoular-25.1}/acoular/fastFuncs.py +90 -84
- {acoular-24.10 → acoular-25.1}/acoular/fbeamform.py +203 -411
- {acoular-24.10 → acoular-25.1}/acoular/fprocess.py +49 -41
- {acoular-24.10 → acoular-25.1}/acoular/grids.py +101 -143
- {acoular-24.10 → acoular-25.1}/acoular/h5cache.py +29 -40
- {acoular-24.10 → acoular-25.1}/acoular/h5files.py +2 -6
- acoular-25.1/acoular/microphones.py +130 -0
- acoular-25.1/acoular/process.py +771 -0
- {acoular-24.10 → acoular-25.1}/acoular/sdinput.py +23 -20
- {acoular-24.10 → acoular-25.1}/acoular/signals.py +116 -109
- {acoular-24.10 → acoular-25.1}/acoular/sources.py +201 -240
- {acoular-24.10 → acoular-25.1}/acoular/spectra.py +53 -229
- {acoular-24.10 → acoular-25.1}/acoular/tbeamform.py +79 -202
- {acoular-24.10 → acoular-25.1}/acoular/tfastfuncs.py +21 -21
- {acoular-24.10 → acoular-25.1}/acoular/tools/__init__.py +2 -8
- acoular-25.1/acoular/tools/helpers.py +403 -0
- {acoular-24.10 → acoular-25.1}/acoular/tools/metrics.py +4 -4
- acoular-25.1/acoular/tools/utils.py +116 -0
- {acoular-24.10 → acoular-25.1}/acoular/tprocess.py +348 -309
- {acoular-24.10 → acoular-25.1}/acoular/traitsviews.py +10 -10
- {acoular-24.10 → acoular-25.1}/acoular/trajectory.py +7 -10
- {acoular-24.10 → acoular-25.1}/acoular/version.py +2 -2
- {acoular-24.10 → acoular-25.1}/pyproject.toml +50 -8
- acoular-24.10/acoular/calib.py +0 -78
- acoular-24.10/acoular/microphones.py +0 -139
- acoular-24.10/acoular/process.py +0 -464
- acoular-24.10/acoular/tools/helpers.py +0 -189
- acoular-24.10/acoular/tools/utils.py +0 -210
- {acoular-24.10 → acoular-25.1}/.gitignore +0 -0
- {acoular-24.10 → acoular-25.1}/AUTHORS.rst +0 -0
- {acoular-24.10 → acoular-25.1}/LICENSE +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/internal.py +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/HW90D240_f10.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/W90_D105_f10.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/acousticam_2c.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/acousticam_4c.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array38.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array92x.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_56.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_56_10_9.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_56_bomb.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_56_v2.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_64.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_84_10_9.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/array_84_bomb_v3.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/calib_vw_ring32.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/gfai_ring32.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/minidsp_uma-16.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/minidsp_uma-16_mirrored.xml +0 -0
- {acoular-24.10 → acoular-25.1}/acoular/xml/tub_vogel64.xml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: acoular
|
|
3
|
-
Version:
|
|
3
|
+
Version: 25.1
|
|
4
4
|
Summary: Python library for acoustic beamforming
|
|
5
5
|
Project-URL: homepage, https://acoular.org
|
|
6
6
|
Project-URL: documentation, https://acoular.org
|
|
@@ -45,8 +45,9 @@ Classifier: License :: OSI Approved :: BSD License
|
|
|
45
45
|
Classifier: Programming Language :: Python :: 3.10
|
|
46
46
|
Classifier: Programming Language :: Python :: 3.11
|
|
47
47
|
Classifier: Programming Language :: Python :: 3.12
|
|
48
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
48
49
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
49
|
-
Requires-Python:
|
|
50
|
+
Requires-Python: <3.14,>=3.10
|
|
50
51
|
Requires-Dist: numba
|
|
51
52
|
Requires-Dist: numpy
|
|
52
53
|
Requires-Dist: scikit-learn
|
|
@@ -63,9 +64,14 @@ Requires-Dist: numpydoc; extra == 'dev'
|
|
|
63
64
|
Requires-Dist: pickleshare; extra == 'dev'
|
|
64
65
|
Requires-Dist: pylops; extra == 'dev'
|
|
65
66
|
Requires-Dist: pytest; extra == 'dev'
|
|
67
|
+
Requires-Dist: pytest-cases; extra == 'dev'
|
|
66
68
|
Requires-Dist: pytest-cov; extra == 'dev'
|
|
69
|
+
Requires-Dist: pytest-env; extra == 'dev'
|
|
70
|
+
Requires-Dist: pytest-mock; extra == 'dev'
|
|
71
|
+
Requires-Dist: pytest-profiling; extra == 'dev'
|
|
72
|
+
Requires-Dist: pytest-regtest; extra == 'dev'
|
|
67
73
|
Requires-Dist: pyyaml; extra == 'dev'
|
|
68
|
-
Requires-Dist: ruff==0.
|
|
74
|
+
Requires-Dist: ruff==0.8.1; extra == 'dev'
|
|
69
75
|
Requires-Dist: setuptools; extra == 'dev'
|
|
70
76
|
Requires-Dist: sounddevice; extra == 'dev'
|
|
71
77
|
Requires-Dist: sphinx; extra == 'dev'
|
|
@@ -89,8 +95,14 @@ Requires-Dist: pylops; extra == 'full'
|
|
|
89
95
|
Requires-Dist: sounddevice; extra == 'full'
|
|
90
96
|
Provides-Extra: tests
|
|
91
97
|
Requires-Dist: h5py; extra == 'tests'
|
|
98
|
+
Requires-Dist: pylops; extra == 'tests'
|
|
92
99
|
Requires-Dist: pytest; extra == 'tests'
|
|
100
|
+
Requires-Dist: pytest-cases; extra == 'tests'
|
|
93
101
|
Requires-Dist: pytest-cov; extra == 'tests'
|
|
102
|
+
Requires-Dist: pytest-env; extra == 'tests'
|
|
103
|
+
Requires-Dist: pytest-mock; extra == 'tests'
|
|
104
|
+
Requires-Dist: pytest-profiling; extra == 'tests'
|
|
105
|
+
Requires-Dist: pytest-regtest; extra == 'tests'
|
|
94
106
|
Requires-Dist: pyyaml; extra == 'tests'
|
|
95
107
|
Requires-Dist: sounddevice; extra == 'tests'
|
|
96
108
|
Requires-Dist: traitsui; extra == 'tests'
|
|
@@ -185,35 +197,44 @@ If you are interested in contributing, have a look at the [CONTRIBUTING.md](CONT
|
|
|
185
197
|
This reads data from 64 microphone channels and computes a beamforming map for the 8kHz third octave band:
|
|
186
198
|
|
|
187
199
|
```python
|
|
188
|
-
from os import
|
|
189
|
-
import acoular
|
|
190
|
-
|
|
200
|
+
from os.path import join, split
|
|
201
|
+
import acoular as ac
|
|
202
|
+
import matplotlib.pylab as plt
|
|
191
203
|
|
|
192
204
|
# this file contains the microphone coordinates
|
|
193
|
-
micgeofile =
|
|
205
|
+
micgeofile = join(split(ac.__file__)[0],'xml','array_64.xml')
|
|
194
206
|
# set up object managing the microphone coordinates
|
|
195
|
-
mg =
|
|
207
|
+
mg = ac.MicGeom( file=micgeofile )
|
|
208
|
+
# generate test data, in real life this would come from an array measurement
|
|
209
|
+
p = ac.demo.create_three_sources(mg, h5savefile='three_sources.h5')
|
|
196
210
|
# set up object managing the microphone array data (usually from measurement)
|
|
197
|
-
ts =
|
|
211
|
+
ts = ac.TimeSamples( file='three_sources.h5')
|
|
198
212
|
# set up object managing the cross spectral matrix computation
|
|
199
|
-
ps =
|
|
213
|
+
ps = ac.PowerSpectra( source=ts, block_size=128, window='Hanning' )
|
|
214
|
+
# alternatively, you can use the in-memory Mixer object directly:
|
|
215
|
+
# ps = ac.PowerSpectra( source=p, block_size=128, window='Hanning' )
|
|
200
216
|
# set up object managing the mapping grid
|
|
201
|
-
rg =
|
|
217
|
+
rg = ac.RectGrid( x_min=-0.2, x_max=0.2, y_min=-0.2, y_max=0.2, z=0.3, \
|
|
202
218
|
increment=0.01 )
|
|
203
219
|
# set up steering vector, implicitely contains also the standard quiescent
|
|
204
220
|
# environment with standard speed of sound
|
|
205
|
-
st =
|
|
221
|
+
st = ac.SteeringVector( grid = rg, mics=mg )
|
|
206
222
|
# set up the object managing the delay & sum beamformer
|
|
207
|
-
bb =
|
|
223
|
+
bb = ac.BeamformerBase( freq_data=ps, steer=st )
|
|
208
224
|
# request the result in the 8kHz third octave band from approriate FFT-Lines
|
|
209
225
|
# this starts the actual computation (data intake, FFT, Welch CSM, beamforming)
|
|
210
226
|
pm = bb.synthetic( 8000, 3 )
|
|
211
227
|
# compute the sound pressure level
|
|
212
|
-
Lm =
|
|
228
|
+
Lm = ac.L_p( pm )
|
|
213
229
|
# plot the map
|
|
214
|
-
imshow( Lm.T, origin='lower', vmin=Lm.max()-10, extent=rg.extend(), \
|
|
230
|
+
plt.imshow( Lm.T, origin='lower', vmin=Lm.max()-10, extent=rg.extend(), \
|
|
215
231
|
interpolation='bicubic')
|
|
216
|
-
|
|
232
|
+
plt.title(f'Beamformer (base) for 3 sources measured for 8000 Hz')
|
|
233
|
+
plt.xlabel('x in m')
|
|
234
|
+
plt.ylabel('y in m')
|
|
235
|
+
plt.colorbar(label=r'$L_p$')
|
|
236
|
+
plt.savefig('three_sources.png', dpi=300, bbox_inches='tight')
|
|
237
|
+
plt.show()
|
|
217
238
|
```
|
|
218
239
|
|
|
219
240
|

|
|
@@ -87,35 +87,44 @@ If you are interested in contributing, have a look at the [CONTRIBUTING.md](CONT
|
|
|
87
87
|
This reads data from 64 microphone channels and computes a beamforming map for the 8kHz third octave band:
|
|
88
88
|
|
|
89
89
|
```python
|
|
90
|
-
from os import
|
|
91
|
-
import acoular
|
|
92
|
-
|
|
90
|
+
from os.path import join, split
|
|
91
|
+
import acoular as ac
|
|
92
|
+
import matplotlib.pylab as plt
|
|
93
93
|
|
|
94
94
|
# this file contains the microphone coordinates
|
|
95
|
-
micgeofile =
|
|
95
|
+
micgeofile = join(split(ac.__file__)[0],'xml','array_64.xml')
|
|
96
96
|
# set up object managing the microphone coordinates
|
|
97
|
-
mg =
|
|
97
|
+
mg = ac.MicGeom( file=micgeofile )
|
|
98
|
+
# generate test data, in real life this would come from an array measurement
|
|
99
|
+
p = ac.demo.create_three_sources(mg, h5savefile='three_sources.h5')
|
|
98
100
|
# set up object managing the microphone array data (usually from measurement)
|
|
99
|
-
ts =
|
|
101
|
+
ts = ac.TimeSamples( file='three_sources.h5')
|
|
100
102
|
# set up object managing the cross spectral matrix computation
|
|
101
|
-
ps =
|
|
103
|
+
ps = ac.PowerSpectra( source=ts, block_size=128, window='Hanning' )
|
|
104
|
+
# alternatively, you can use the in-memory Mixer object directly:
|
|
105
|
+
# ps = ac.PowerSpectra( source=p, block_size=128, window='Hanning' )
|
|
102
106
|
# set up object managing the mapping grid
|
|
103
|
-
rg =
|
|
107
|
+
rg = ac.RectGrid( x_min=-0.2, x_max=0.2, y_min=-0.2, y_max=0.2, z=0.3, \
|
|
104
108
|
increment=0.01 )
|
|
105
109
|
# set up steering vector, implicitely contains also the standard quiescent
|
|
106
110
|
# environment with standard speed of sound
|
|
107
|
-
st =
|
|
111
|
+
st = ac.SteeringVector( grid = rg, mics=mg )
|
|
108
112
|
# set up the object managing the delay & sum beamformer
|
|
109
|
-
bb =
|
|
113
|
+
bb = ac.BeamformerBase( freq_data=ps, steer=st )
|
|
110
114
|
# request the result in the 8kHz third octave band from approriate FFT-Lines
|
|
111
115
|
# this starts the actual computation (data intake, FFT, Welch CSM, beamforming)
|
|
112
116
|
pm = bb.synthetic( 8000, 3 )
|
|
113
117
|
# compute the sound pressure level
|
|
114
|
-
Lm =
|
|
118
|
+
Lm = ac.L_p( pm )
|
|
115
119
|
# plot the map
|
|
116
|
-
imshow( Lm.T, origin='lower', vmin=Lm.max()-10, extent=rg.extend(), \
|
|
120
|
+
plt.imshow( Lm.T, origin='lower', vmin=Lm.max()-10, extent=rg.extend(), \
|
|
117
121
|
interpolation='bicubic')
|
|
118
|
-
|
|
122
|
+
plt.title(f'Beamformer (base) for 3 sources measured for 8000 Hz')
|
|
123
|
+
plt.xlabel('x in m')
|
|
124
|
+
plt.ylabel('y in m')
|
|
125
|
+
plt.colorbar(label=r'$L_p$')
|
|
126
|
+
plt.savefig('three_sources.png', dpi=300, bbox_inches='tight')
|
|
127
|
+
plt.show()
|
|
119
128
|
```
|
|
120
129
|
|
|
121
130
|

|
|
@@ -9,7 +9,7 @@ import os # noqa: I001
|
|
|
9
9
|
# config must be imported before any submodules containing numpy, see #322.
|
|
10
10
|
from .configuration import config
|
|
11
11
|
|
|
12
|
-
from . import demo, tools
|
|
12
|
+
from . import demo, tools, aiaa
|
|
13
13
|
from .base import (
|
|
14
14
|
Generator,
|
|
15
15
|
InOut,
|
|
@@ -74,6 +74,8 @@ from .sdinput import SoundDeviceSamplesGenerator
|
|
|
74
74
|
from .signals import (
|
|
75
75
|
FiltWNoiseGenerator,
|
|
76
76
|
GenericSignalGenerator,
|
|
77
|
+
NoiseGenerator,
|
|
78
|
+
PeriodicSignalGenerator,
|
|
77
79
|
PNoiseGenerator,
|
|
78
80
|
SignalGenerator,
|
|
79
81
|
SineGenerator,
|
|
@@ -93,7 +95,8 @@ from .sources import (
|
|
|
93
95
|
TimeSamples,
|
|
94
96
|
UncorrelatedNoiseSource,
|
|
95
97
|
)
|
|
96
|
-
from .
|
|
98
|
+
from .tools.helpers import synthetic
|
|
99
|
+
from .spectra import BaseSpectra, PowerSpectra, PowerSpectraImport
|
|
97
100
|
from .spectra import PowerSpectra as EigSpectra
|
|
98
101
|
from .tbeamform import (
|
|
99
102
|
BeamformerCleant,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# ------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Acoular Development Team.
|
|
3
|
+
# ------------------------------------------------------------------------------
|
|
4
|
+
"""Provides classes for importing AIAA Array Benchmarks.
|
|
5
|
+
|
|
6
|
+
.. autosummary::
|
|
7
|
+
:toctree: generated/
|
|
8
|
+
|
|
9
|
+
aiaa
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .aiaa import CsmAIAABenchmark, MicAIAABenchmark, TimeSamplesAIAABenchmark, TriggerAIAABenchmark
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# ------------------------------------------------------------------------------
|
|
2
2
|
# Copyright (c) Acoular Development Team.
|
|
3
3
|
# ------------------------------------------------------------------------------
|
|
4
|
-
"""Classes for importing AIAA Array Benchmarks
|
|
5
|
-
|
|
4
|
+
"""Classes for importing AIAA Array Benchmarks.
|
|
5
|
+
|
|
6
6
|
These classes allow importing data from HDF5 files following the specifications of
|
|
7
7
|
the AIAA microphone array methods benchmarking effort:
|
|
8
8
|
https://www-docs.b-tu.de/fg-akustik/public/veroeffentlichungen/ArrayMethodsFileFormatsR2P4Release.pdf .
|
|
@@ -12,8 +12,8 @@ the framework.
|
|
|
12
12
|
|
|
13
13
|
Examples
|
|
14
14
|
--------
|
|
15
|
-
>>> micgeom = MicAIAABenchmark(
|
|
16
|
-
>>> timedata = TimeSamplesAIAABenchmark(
|
|
15
|
+
>>> micgeom = MicAIAABenchmark(file='some_benchmarkdata.h5') # doctest: +SKIP
|
|
16
|
+
>>> timedata = TimeSamplesAIAABenchmark(file='some_benchmarkdata.h5') # doctest: +SKIP
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
.. autosummary::
|
|
@@ -23,10 +23,9 @@ Examples
|
|
|
23
23
|
TriggerAIAABenchmark
|
|
24
24
|
CsmAIAABenchmark
|
|
25
25
|
MicAIAABenchmark
|
|
26
|
-
"""
|
|
26
|
+
""" # noqa: W505
|
|
27
27
|
|
|
28
28
|
import contextlib
|
|
29
|
-
from os import path
|
|
30
29
|
|
|
31
30
|
from numpy import array
|
|
32
31
|
from traits.api import (
|
|
@@ -38,11 +37,13 @@ from traits.api import (
|
|
|
38
37
|
property_depends_on,
|
|
39
38
|
)
|
|
40
39
|
|
|
40
|
+
from acoular.deprecation import deprecated_alias
|
|
41
41
|
from acoular.h5files import H5FileBase, _get_h5file_class
|
|
42
42
|
from acoular.internal import digest
|
|
43
43
|
from acoular.microphones import MicGeom
|
|
44
44
|
from acoular.sources import TimeSamples
|
|
45
45
|
from acoular.spectra import PowerSpectraImport
|
|
46
|
+
from acoular.tools.utils import get_file_basename
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
class TimeSamplesAIAABenchmark(TimeSamples):
|
|
@@ -58,7 +59,7 @@ class TimeSamplesAIAABenchmark(TimeSamples):
|
|
|
58
59
|
"""Loads timedata from .h5 file. Only for internal use."""
|
|
59
60
|
self.data = self.h5f.get_data_by_reference('MicrophoneData/microphoneDataPa')
|
|
60
61
|
self.sample_freq = self.h5f.get_node_attribute(self.data, 'sampleRateHz')
|
|
61
|
-
(self.
|
|
62
|
+
(self.num_samples, self.num_channels) = self.data.shape
|
|
62
63
|
|
|
63
64
|
def _load_metadata(self):
|
|
64
65
|
"""Loads metadata from .h5 file. Only for internal use."""
|
|
@@ -80,23 +81,24 @@ class TriggerAIAABenchmark(TimeSamplesAIAABenchmark):
|
|
|
80
81
|
"""Loads timedata from .h5 file. Only for internal use."""
|
|
81
82
|
self.data = self.h5f.get_data_by_reference('TachoData/tachoDataV')
|
|
82
83
|
self.sample_freq = self.h5f.get_node_attribute(self.data, 'sampleRateHz')
|
|
83
|
-
(self.
|
|
84
|
+
(self.num_samples, self.num_channels) = self.data.shape
|
|
84
85
|
|
|
85
86
|
|
|
87
|
+
@deprecated_alias({'name': 'file'})
|
|
86
88
|
class CsmAIAABenchmark(PowerSpectraImport):
|
|
87
89
|
"""Class to load the CSM that is stored in AIAA Benchmark HDF5 file."""
|
|
88
90
|
|
|
89
91
|
#: Full name of the .h5 file with data
|
|
90
|
-
|
|
92
|
+
file = File(filter=['*.h5'], exists=True, desc='name of data file')
|
|
91
93
|
|
|
92
94
|
#: Basename of the .h5 file with data, is set automatically.
|
|
93
95
|
basename = Property(
|
|
94
|
-
depends_on='
|
|
96
|
+
depends_on=['file'],
|
|
95
97
|
desc='basename of data file',
|
|
96
98
|
)
|
|
97
99
|
|
|
98
100
|
#: number of channels
|
|
99
|
-
|
|
101
|
+
num_channels = Property()
|
|
100
102
|
|
|
101
103
|
#: HDF5 file object
|
|
102
104
|
h5f = Instance(H5FileBase, transient=True)
|
|
@@ -110,19 +112,16 @@ class CsmAIAABenchmark(PowerSpectraImport):
|
|
|
110
112
|
|
|
111
113
|
@cached_property
|
|
112
114
|
def _get_basename(self):
|
|
113
|
-
return
|
|
115
|
+
return get_file_basename(self.file)
|
|
114
116
|
|
|
115
117
|
@on_trait_change('basename')
|
|
116
118
|
def load_data(self):
|
|
117
119
|
"""Open the .h5 file and set attributes."""
|
|
118
|
-
if not path.isfile(self.name):
|
|
119
|
-
# no file there
|
|
120
|
-
raise OSError('No such file: %s' % self.name)
|
|
121
120
|
if self.h5f is not None:
|
|
122
121
|
with contextlib.suppress(OSError):
|
|
123
122
|
self.h5f.close()
|
|
124
123
|
file = _get_h5file_class()
|
|
125
|
-
self.h5f = file(self.
|
|
124
|
+
self.h5f = file(self.file)
|
|
126
125
|
|
|
127
126
|
# @property_depends_on( 'block_size, ind_low, ind_high' )
|
|
128
127
|
def _get_indices(self):
|
|
@@ -131,15 +130,15 @@ class CsmAIAABenchmark(PowerSpectraImport):
|
|
|
131
130
|
except IndexError:
|
|
132
131
|
return range(0)
|
|
133
132
|
|
|
134
|
-
@property_depends_on('digest')
|
|
135
|
-
def
|
|
133
|
+
@property_depends_on(['digest'])
|
|
134
|
+
def _get_num_channels(self):
|
|
136
135
|
try:
|
|
137
136
|
attrs = self.h5f.get_data_by_reference('MetaData/ArrayAttributes')
|
|
138
137
|
return self.h5f.get_node_attribute(attrs, 'microphoneCount')
|
|
139
138
|
except IndexError:
|
|
140
139
|
return 0
|
|
141
140
|
|
|
142
|
-
@property_depends_on('digest')
|
|
141
|
+
@property_depends_on(['digest'])
|
|
143
142
|
def _get_csm(self):
|
|
144
143
|
"""Loads cross spectral matrix from file."""
|
|
145
144
|
csmre = self.h5f.get_data_by_reference('/CsmData/csmReal')[:].transpose((2, 0, 1))
|
|
@@ -167,19 +166,15 @@ class MicAIAABenchmark(MicGeom):
|
|
|
167
166
|
file containing the measurement data.
|
|
168
167
|
"""
|
|
169
168
|
|
|
170
|
-
#: Name of the .h5-file from
|
|
171
|
-
|
|
169
|
+
#: Name of the .h5-file from which to read the data.
|
|
170
|
+
file = File(filter=['*.h5'], exists=True, desc='name of the h5 file containing the microphone geometry')
|
|
172
171
|
|
|
173
|
-
@on_trait_change('
|
|
172
|
+
@on_trait_change('file')
|
|
174
173
|
def import_mpos(self):
|
|
175
174
|
"""Import the microphone positions from .h5 file.
|
|
176
175
|
Called when :attr:`basename` changes.
|
|
177
176
|
"""
|
|
178
|
-
if not path.isfile(self.from_file):
|
|
179
|
-
# no file there
|
|
180
|
-
raise OSError('No such file: %s' % self.from_file)
|
|
181
|
-
|
|
182
177
|
file = _get_h5file_class()
|
|
183
|
-
h5f = file(self.
|
|
184
|
-
self.
|
|
178
|
+
h5f = file(self.file, mode='r')
|
|
179
|
+
self.pos_total = h5f.get_data_by_reference('MetaData/ArrayAttributes/microphonePositionsM')[:].swapaxes(0, 1)
|
|
185
180
|
h5f.close()
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
# ------------------------------------------------------------------------------
|
|
4
4
|
"""Implements base classes for signal processing blocks in Acoular.
|
|
5
5
|
|
|
6
|
-
The classes in this module are abstract base classes that provide a common interface for all classes
|
|
7
|
-
output via the generator :meth:`result` in block-wise manner. They are not intended
|
|
8
|
-
subclassed by classes that implement the actual signal processing.
|
|
6
|
+
The classes in this module are abstract base classes that provide a common interface for all classes
|
|
7
|
+
that generate an output via the generator :meth:`result` in block-wise manner. They are not intended
|
|
8
|
+
to be used directly, but to be subclassed by classes that implement the actual signal processing.
|
|
9
9
|
|
|
10
10
|
.. autosummary::
|
|
11
11
|
:toctree: generated/
|
|
@@ -19,42 +19,54 @@ subclassed by classes that implement the actual signal processing.
|
|
|
19
19
|
TimeInOut
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
+
from abc import abstractmethod
|
|
23
|
+
|
|
22
24
|
from traits.api import (
|
|
25
|
+
ABCHasStrictTraits,
|
|
23
26
|
CArray,
|
|
24
|
-
|
|
27
|
+
CInt,
|
|
25
28
|
Delegate,
|
|
26
29
|
Float,
|
|
27
|
-
HasPrivateTraits,
|
|
28
30
|
Instance,
|
|
29
31
|
Property,
|
|
30
32
|
cached_property,
|
|
31
33
|
)
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
# acoular imports
|
|
36
|
+
from .deprecation import deprecated_alias
|
|
37
|
+
from .internal import digest
|
|
34
38
|
|
|
35
39
|
|
|
36
|
-
|
|
40
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'})
|
|
41
|
+
class Generator(ABCHasStrictTraits):
|
|
37
42
|
"""Interface for any generating signal processing block.
|
|
38
43
|
|
|
39
|
-
It provides a common interface for all classes, which generate an output via the generator
|
|
40
|
-
in block-wise manner. It has a common set of traits that are used by all classes
|
|
41
|
-
This includes the sampling frequency of the signal
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
It provides a common interface for all classes, which generate an output via the generator
|
|
45
|
+
:meth:`result` in block-wise manner. It has a common set of traits that are used by all classes
|
|
46
|
+
that implement this interface. This includes the sampling frequency of the signal
|
|
47
|
+
(:attr:`sample_freq`), the number of samples (:attr:`num_samples`), and the number of channels
|
|
48
|
+
(:attr:`num_channels`). A private trait :attr:`digest` is used to store the internal identifier
|
|
49
|
+
of the object, which is a hash of the object's attributes.
|
|
50
|
+
This is used to check if the object's internal state has changed.
|
|
51
|
+
|
|
44
52
|
"""
|
|
45
53
|
|
|
46
54
|
#: Sampling frequency of the signal, defaults to 1.0
|
|
47
55
|
sample_freq = Float(1.0, desc='sampling frequency')
|
|
48
56
|
|
|
49
57
|
#: Number of signal samples
|
|
50
|
-
|
|
58
|
+
num_samples = CInt
|
|
59
|
+
|
|
60
|
+
#: Number of channels
|
|
61
|
+
num_channels = CInt
|
|
51
62
|
|
|
52
63
|
# internal identifier
|
|
53
|
-
digest = Property(depends_on=['sample_freq', '
|
|
64
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
|
|
54
65
|
|
|
55
66
|
def _get_digest(self):
|
|
56
67
|
return digest(self)
|
|
57
68
|
|
|
69
|
+
@abstractmethod
|
|
58
70
|
def result(self, num):
|
|
59
71
|
"""Python generator that yields the output block-wise.
|
|
60
72
|
|
|
@@ -75,19 +87,19 @@ class Generator(HasPrivateTraits):
|
|
|
75
87
|
class SamplesGenerator(Generator):
|
|
76
88
|
"""Interface for any generating multi-channel time domain signal processing block.
|
|
77
89
|
|
|
78
|
-
It provides a common interface for all SamplesGenerator classes, which generate an output via
|
|
79
|
-
in block-wise manner. This class has no real functionality on its
|
|
80
|
-
|
|
90
|
+
It provides a common interface for all SamplesGenerator classes, which generate an output via
|
|
91
|
+
the generator :meth:`result` in block-wise manner. This class has no real functionality on its
|
|
92
|
+
own and should not be used directly.
|
|
81
93
|
|
|
82
|
-
|
|
83
|
-
numchannels = CLong
|
|
94
|
+
"""
|
|
84
95
|
|
|
85
96
|
# internal identifier
|
|
86
|
-
digest = Property(depends_on=['sample_freq', '
|
|
97
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
|
|
87
98
|
|
|
88
99
|
def _get_digest(self):
|
|
89
100
|
return digest(self)
|
|
90
101
|
|
|
102
|
+
@abstractmethod
|
|
91
103
|
def result(self, num):
|
|
92
104
|
"""Python generator that yields the output block-wise.
|
|
93
105
|
|
|
@@ -100,35 +112,35 @@ class SamplesGenerator(Generator):
|
|
|
100
112
|
Yields
|
|
101
113
|
------
|
|
102
114
|
numpy.ndarray
|
|
103
|
-
The two-dimensional time-data block of shape (num,
|
|
115
|
+
The two-dimensional time-data block of shape (num, num_channels).
|
|
104
116
|
"""
|
|
105
117
|
|
|
106
118
|
|
|
107
119
|
class SpectraGenerator(Generator):
|
|
108
120
|
"""Interface for any generating multi-channel signal frequency domain processing block.
|
|
109
121
|
|
|
110
|
-
It provides a common interface for all SpectraGenerator classes, which generate an output via
|
|
111
|
-
in block-wise manner. This class has no real functionality on its
|
|
112
|
-
|
|
122
|
+
It provides a common interface for all SpectraGenerator classes, which generate an output via
|
|
123
|
+
the generator :meth:`result` in block-wise manner. This class has no real functionality on its
|
|
124
|
+
own and should not be used directly.
|
|
113
125
|
|
|
114
|
-
|
|
115
|
-
numchannels = CLong
|
|
126
|
+
"""
|
|
116
127
|
|
|
117
128
|
#: Number of frequencies
|
|
118
|
-
|
|
129
|
+
num_freqs = CInt
|
|
119
130
|
|
|
120
131
|
#: 1-D array of frequencies
|
|
121
132
|
freqs = CArray
|
|
122
133
|
|
|
123
134
|
#: The length of the block used to calculate the spectra
|
|
124
|
-
block_size =
|
|
135
|
+
block_size = CInt
|
|
125
136
|
|
|
126
137
|
# internal identifier
|
|
127
|
-
digest = Property(depends_on=['sample_freq', '
|
|
138
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels', 'num_freqs', 'block_size'])
|
|
128
139
|
|
|
129
140
|
def _get_digest(self):
|
|
130
141
|
return digest(self)
|
|
131
142
|
|
|
143
|
+
@abstractmethod
|
|
132
144
|
def result(self, num=1):
|
|
133
145
|
"""Python generator that yields the output block-wise.
|
|
134
146
|
|
|
@@ -141,16 +153,18 @@ class SpectraGenerator(Generator):
|
|
|
141
153
|
Yields
|
|
142
154
|
------
|
|
143
155
|
numpy.ndarray
|
|
144
|
-
A two-dimensional block of shape (num,
|
|
156
|
+
A two-dimensional block of shape (num, num_channels * num_freqs).
|
|
145
157
|
"""
|
|
146
158
|
|
|
147
159
|
|
|
160
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
|
|
148
161
|
class TimeOut(SamplesGenerator):
|
|
149
|
-
"""Abstract base class for any signal processing block that receives data from any
|
|
150
|
-
time domain signals.
|
|
162
|
+
"""Abstract base class for any signal processing block that receives data from any
|
|
163
|
+
:attr:`source` domain and returns time domain signals.
|
|
151
164
|
|
|
152
|
-
It provides a base class that can be used to create signal processing blocks that receive data
|
|
153
|
-
generating :attr:`source` and generates a time signal output via the generator
|
|
165
|
+
It provides a base class that can be used to create signal processing blocks that receive data
|
|
166
|
+
from any generating :attr:`source` and generates a time signal output via the generator
|
|
167
|
+
:meth:`result` in block-wise manner.
|
|
154
168
|
"""
|
|
155
169
|
|
|
156
170
|
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
@@ -160,10 +174,10 @@ class TimeOut(SamplesGenerator):
|
|
|
160
174
|
sample_freq = Delegate('source')
|
|
161
175
|
|
|
162
176
|
#: Number of channels in output, as given by :attr:`source`.
|
|
163
|
-
|
|
177
|
+
num_channels = Delegate('source')
|
|
164
178
|
|
|
165
179
|
#: Number of samples in output, as given by :attr:`source`.
|
|
166
|
-
|
|
180
|
+
num_samples = Delegate('source')
|
|
167
181
|
|
|
168
182
|
# internal identifier
|
|
169
183
|
digest = Property(depends_on=['source.digest'])
|
|
@@ -172,6 +186,7 @@ class TimeOut(SamplesGenerator):
|
|
|
172
186
|
def _get_digest(self):
|
|
173
187
|
return digest(self)
|
|
174
188
|
|
|
189
|
+
@abstractmethod
|
|
175
190
|
def result(self, num):
|
|
176
191
|
"""Python generator that processes the source data and yields the time-signal block-wise.
|
|
177
192
|
|
|
@@ -186,18 +201,18 @@ class TimeOut(SamplesGenerator):
|
|
|
186
201
|
Yields
|
|
187
202
|
------
|
|
188
203
|
numpy.ndarray
|
|
189
|
-
Two-dimensional output data block of shape (num,
|
|
204
|
+
Two-dimensional output data block of shape (num, num_channels)
|
|
190
205
|
"""
|
|
191
|
-
yield from self.source.result(num)
|
|
192
206
|
|
|
193
207
|
|
|
208
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples', 'numfreqs': 'num_freqs'}, read_only=True)
|
|
194
209
|
class SpectraOut(SpectraGenerator):
|
|
195
|
-
"""Abstract base class for any signal processing block that receives data from any
|
|
196
|
-
returns frequency domain signals.
|
|
210
|
+
"""Abstract base class for any signal processing block that receives data from any
|
|
211
|
+
:attr:`source` domain and returns frequency domain signals.
|
|
197
212
|
|
|
198
|
-
It provides a base class that can be used to create signal processing blocks that receive data
|
|
199
|
-
generating :attr:`source` domain and generates a frequency domain output via the
|
|
200
|
-
in block-wise manner.
|
|
213
|
+
It provides a base class that can be used to create signal processing blocks that receive data
|
|
214
|
+
from any generating :attr:`source` domain and generates a frequency domain output via the
|
|
215
|
+
generator :meth:`result` in block-wise manner.
|
|
201
216
|
"""
|
|
202
217
|
|
|
203
218
|
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
@@ -207,13 +222,13 @@ class SpectraOut(SpectraGenerator):
|
|
|
207
222
|
sample_freq = Delegate('source')
|
|
208
223
|
|
|
209
224
|
#: Number of channels in output, as given by :attr:`source`.
|
|
210
|
-
|
|
225
|
+
num_channels = Delegate('source')
|
|
211
226
|
|
|
212
227
|
#: Number of snapshots in output, as given by :attr:`source`.
|
|
213
|
-
|
|
228
|
+
num_samples = Delegate('source')
|
|
214
229
|
|
|
215
230
|
#: Number of frequencies in output, as given by :attr:`source`.
|
|
216
|
-
|
|
231
|
+
num_freqs = Delegate('source')
|
|
217
232
|
|
|
218
233
|
#: 1-D array of frequencies, as given by :attr:`source`.
|
|
219
234
|
freqs = Delegate('source')
|
|
@@ -228,6 +243,7 @@ class SpectraOut(SpectraGenerator):
|
|
|
228
243
|
def _get_digest(self):
|
|
229
244
|
return digest(self)
|
|
230
245
|
|
|
246
|
+
@abstractmethod
|
|
231
247
|
def result(self, num=1):
|
|
232
248
|
"""Python generator that processes the source data and yields the output block-wise.
|
|
233
249
|
|
|
@@ -240,17 +256,18 @@ class SpectraOut(SpectraGenerator):
|
|
|
240
256
|
Yields
|
|
241
257
|
------
|
|
242
258
|
numpy.ndarray
|
|
243
|
-
A two-dimensional block of shape (num,
|
|
259
|
+
A two-dimensional block of shape (num, num_channels * num_freqs).
|
|
244
260
|
"""
|
|
245
|
-
yield from self.source.result(num)
|
|
246
261
|
|
|
247
262
|
|
|
263
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
|
|
248
264
|
class InOut(SamplesGenerator, SpectraGenerator):
|
|
249
|
-
"""Abstract base class for any signal processing block that receives data from any
|
|
250
|
-
signals in the same domain.
|
|
265
|
+
"""Abstract base class for any signal processing block that receives data from any
|
|
266
|
+
:attr:`source` domain and returns signals in the same domain.
|
|
251
267
|
|
|
252
|
-
It provides a base class that can be used to create signal processing blocks that receive data
|
|
253
|
-
generating :attr:`source` and generates an output via the generator :meth:`result` in
|
|
268
|
+
It provides a base class that can be used to create signal processing blocks that receive data
|
|
269
|
+
from any generating :attr:`source` and generates an output via the generator :meth:`result` in
|
|
270
|
+
block-wise manner.
|
|
254
271
|
"""
|
|
255
272
|
|
|
256
273
|
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
@@ -260,10 +277,13 @@ class InOut(SamplesGenerator, SpectraGenerator):
|
|
|
260
277
|
sample_freq = Delegate('source')
|
|
261
278
|
|
|
262
279
|
#: Number of channels in output, as given by :attr:`source`.
|
|
263
|
-
|
|
280
|
+
num_channels = Delegate('source')
|
|
281
|
+
|
|
282
|
+
#: Number of frequencies in output, as given by :attr:`source`.
|
|
283
|
+
num_freqs = Delegate('source')
|
|
264
284
|
|
|
265
285
|
#: Number of samples / snapshots in output, as given by :attr:`source`.
|
|
266
|
-
|
|
286
|
+
num_samples = Delegate('source')
|
|
267
287
|
|
|
268
288
|
# internal identifier
|
|
269
289
|
digest = Property(depends_on=['source.digest'])
|
|
@@ -272,6 +292,7 @@ class InOut(SamplesGenerator, SpectraGenerator):
|
|
|
272
292
|
def _get_digest(self):
|
|
273
293
|
return digest(self)
|
|
274
294
|
|
|
295
|
+
@abstractmethod
|
|
275
296
|
def result(self, num):
|
|
276
297
|
"""Python generator that processes the source data and yields the output block-wise.
|
|
277
298
|
|
|
@@ -287,7 +308,6 @@ class InOut(SamplesGenerator, SpectraGenerator):
|
|
|
287
308
|
numpy.ndarray
|
|
288
309
|
Two-dimensional output data block of shape (num, ...)
|
|
289
310
|
"""
|
|
290
|
-
yield from self.source.result(num)
|
|
291
311
|
|
|
292
312
|
|
|
293
313
|
class TimeInOut(TimeOut):
|