acoular 24.7__py3-none-any.whl → 25.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.
- acoular/__init__.py +21 -9
- acoular/aiaa/__init__.py +12 -0
- acoular/{tools → aiaa}/aiaa.py +26 -31
- acoular/base.py +332 -0
- acoular/calib.py +129 -34
- acoular/configuration.py +13 -11
- acoular/demo/__init__.py +1 -0
- acoular/demo/acoular_demo.py +30 -17
- acoular/deprecation.py +85 -0
- acoular/environments.py +38 -24
- acoular/fastFuncs.py +90 -84
- acoular/fbeamform.py +342 -387
- acoular/fprocess.py +376 -0
- acoular/grids.py +122 -150
- acoular/h5cache.py +29 -40
- acoular/h5files.py +2 -6
- acoular/microphones.py +50 -59
- acoular/process.py +771 -0
- acoular/sdinput.py +35 -21
- acoular/signals.py +120 -113
- acoular/sources.py +208 -234
- acoular/spectra.py +59 -254
- acoular/tbeamform.py +280 -280
- acoular/tfastfuncs.py +21 -21
- acoular/tools/__init__.py +3 -7
- acoular/tools/helpers.py +218 -4
- acoular/tools/metrics.py +5 -5
- acoular/tools/utils.py +116 -0
- acoular/tprocess.py +416 -741
- acoular/traitsviews.py +15 -13
- acoular/trajectory.py +7 -10
- acoular/version.py +2 -2
- {acoular-24.7.dist-info → acoular-25.1.dist-info}/METADATA +63 -21
- acoular-25.1.dist-info/RECORD +56 -0
- {acoular-24.7.dist-info → acoular-25.1.dist-info}/WHEEL +1 -1
- acoular-24.7.dist-info/RECORD +0 -50
- {acoular-24.7.dist-info → acoular-25.1.dist-info}/licenses/AUTHORS.rst +0 -0
- {acoular-24.7.dist-info → acoular-25.1.dist-info}/licenses/LICENSE +0 -0
acoular/__init__.py
CHANGED
|
@@ -4,11 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
"""The Acoular library: several classes for the implementation of acoustic beamforming."""
|
|
6
6
|
|
|
7
|
-
import os
|
|
7
|
+
import os # noqa: I001
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
from .calib import Calib
|
|
9
|
+
# config must be imported before any submodules containing numpy, see #322.
|
|
11
10
|
from .configuration import config
|
|
11
|
+
|
|
12
|
+
from . import demo, tools, aiaa
|
|
13
|
+
from .base import (
|
|
14
|
+
Generator,
|
|
15
|
+
InOut,
|
|
16
|
+
SamplesGenerator,
|
|
17
|
+
SpectraGenerator,
|
|
18
|
+
SpectraOut,
|
|
19
|
+
TimeInOut,
|
|
20
|
+
TimeOut,
|
|
21
|
+
)
|
|
22
|
+
from .calib import Calib
|
|
12
23
|
from .environments import (
|
|
13
24
|
Environment,
|
|
14
25
|
FlowField,
|
|
@@ -41,6 +52,7 @@ from .fbeamform import (
|
|
|
41
52
|
SteeringVector,
|
|
42
53
|
integrate,
|
|
43
54
|
)
|
|
55
|
+
from .fprocess import IRFFT, RFFT, AutoPowerSpectra, CrossPowerSpectra, FFTSpectra
|
|
44
56
|
from .grids import (
|
|
45
57
|
CircSector,
|
|
46
58
|
ConvexSector,
|
|
@@ -57,10 +69,13 @@ from .grids import (
|
|
|
57
69
|
Sector,
|
|
58
70
|
)
|
|
59
71
|
from .microphones import MicGeom
|
|
72
|
+
from .process import Average, Cache, SampleSplitter, TimeAverage, TimeCache
|
|
60
73
|
from .sdinput import SoundDeviceSamplesGenerator
|
|
61
74
|
from .signals import (
|
|
62
75
|
FiltWNoiseGenerator,
|
|
63
76
|
GenericSignalGenerator,
|
|
77
|
+
NoiseGenerator,
|
|
78
|
+
PeriodicSignalGenerator,
|
|
64
79
|
PNoiseGenerator,
|
|
65
80
|
SignalGenerator,
|
|
66
81
|
SineGenerator,
|
|
@@ -80,7 +95,8 @@ from .sources import (
|
|
|
80
95
|
TimeSamples,
|
|
81
96
|
UncorrelatedNoiseSource,
|
|
82
97
|
)
|
|
83
|
-
from .
|
|
98
|
+
from .tools.helpers import synthetic
|
|
99
|
+
from .spectra import BaseSpectra, PowerSpectra, PowerSpectraImport
|
|
84
100
|
from .spectra import PowerSpectra as EigSpectra
|
|
85
101
|
from .tbeamform import (
|
|
86
102
|
BeamformerCleant,
|
|
@@ -102,19 +118,15 @@ from .tprocess import (
|
|
|
102
118
|
FiltFreqWeight,
|
|
103
119
|
FiltOctave,
|
|
104
120
|
MaskedTimeInOut,
|
|
121
|
+
MaskedTimeOut,
|
|
105
122
|
Mixer,
|
|
106
123
|
OctaveFilterBank,
|
|
107
|
-
SamplesGenerator,
|
|
108
|
-
SampleSplitter,
|
|
109
124
|
SpatialInterpolator,
|
|
110
125
|
SpatialInterpolatorConstantRotation,
|
|
111
126
|
SpatialInterpolatorRotation,
|
|
112
|
-
TimeAverage,
|
|
113
|
-
TimeCache,
|
|
114
127
|
TimeConvolve,
|
|
115
128
|
TimeCumAverage,
|
|
116
129
|
TimeExpAverage,
|
|
117
|
-
TimeInOut,
|
|
118
130
|
TimePower,
|
|
119
131
|
TimeReverse,
|
|
120
132
|
Trigger,
|
acoular/aiaa/__init__.py
ADDED
|
@@ -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
|
acoular/{tools → aiaa}/aiaa.py
RENAMED
|
@@ -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):
|
|
@@ -54,13 +55,13 @@ class TimeSamplesAIAABenchmark(TimeSamples):
|
|
|
54
55
|
objects.
|
|
55
56
|
"""
|
|
56
57
|
|
|
57
|
-
def
|
|
58
|
+
def _load_timedata(self):
|
|
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
|
-
def
|
|
64
|
+
def _load_metadata(self):
|
|
64
65
|
"""Loads metadata from .h5 file. Only for internal use."""
|
|
65
66
|
self.metadata = {}
|
|
66
67
|
if '/MetaData' in self.h5f:
|
|
@@ -76,27 +77,28 @@ class TriggerAIAABenchmark(TimeSamplesAIAABenchmark):
|
|
|
76
77
|
and and provides information about this data.
|
|
77
78
|
"""
|
|
78
79
|
|
|
79
|
-
def
|
|
80
|
+
def _load_timedata(self):
|
|
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()
|
acoular/base.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# ------------------------------------------------------------------------------
|
|
2
|
+
# Copyright (c) Acoular Development Team.
|
|
3
|
+
# ------------------------------------------------------------------------------
|
|
4
|
+
"""Implements base classes for signal processing blocks in Acoular.
|
|
5
|
+
|
|
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
|
+
|
|
10
|
+
.. autosummary::
|
|
11
|
+
:toctree: generated/
|
|
12
|
+
|
|
13
|
+
Generator
|
|
14
|
+
SamplesGenerator
|
|
15
|
+
SpectraGenerator
|
|
16
|
+
InOut
|
|
17
|
+
TimeOut
|
|
18
|
+
SpectraOut
|
|
19
|
+
TimeInOut
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from abc import abstractmethod
|
|
23
|
+
|
|
24
|
+
from traits.api import (
|
|
25
|
+
ABCHasStrictTraits,
|
|
26
|
+
CArray,
|
|
27
|
+
CInt,
|
|
28
|
+
Delegate,
|
|
29
|
+
Float,
|
|
30
|
+
Instance,
|
|
31
|
+
Property,
|
|
32
|
+
cached_property,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# acoular imports
|
|
36
|
+
from .deprecation import deprecated_alias
|
|
37
|
+
from .internal import digest
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'})
|
|
41
|
+
class Generator(ABCHasStrictTraits):
|
|
42
|
+
"""Interface for any generating signal processing block.
|
|
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
|
+
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
#: Sampling frequency of the signal, defaults to 1.0
|
|
55
|
+
sample_freq = Float(1.0, desc='sampling frequency')
|
|
56
|
+
|
|
57
|
+
#: Number of signal samples
|
|
58
|
+
num_samples = CInt
|
|
59
|
+
|
|
60
|
+
#: Number of channels
|
|
61
|
+
num_channels = CInt
|
|
62
|
+
|
|
63
|
+
# internal identifier
|
|
64
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
|
|
65
|
+
|
|
66
|
+
def _get_digest(self):
|
|
67
|
+
return digest(self)
|
|
68
|
+
|
|
69
|
+
@abstractmethod
|
|
70
|
+
def result(self, num):
|
|
71
|
+
"""Python generator that yields the output block-wise.
|
|
72
|
+
|
|
73
|
+
This method needs to be implemented by the derived classes.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
num : int
|
|
78
|
+
The size of the first dimension of the blocks to be yielded
|
|
79
|
+
|
|
80
|
+
Yields
|
|
81
|
+
------
|
|
82
|
+
numpy.ndarray
|
|
83
|
+
Two-dimensional output data block of shape (num, ...)
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class SamplesGenerator(Generator):
|
|
88
|
+
"""Interface for any generating multi-channel time domain signal processing block.
|
|
89
|
+
|
|
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.
|
|
93
|
+
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
# internal identifier
|
|
97
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
|
|
98
|
+
|
|
99
|
+
def _get_digest(self):
|
|
100
|
+
return digest(self)
|
|
101
|
+
|
|
102
|
+
@abstractmethod
|
|
103
|
+
def result(self, num):
|
|
104
|
+
"""Python generator that yields the output block-wise.
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
num : int
|
|
109
|
+
This parameter defines the size of the blocks to be yielded
|
|
110
|
+
(i.e. the number of samples per block)
|
|
111
|
+
|
|
112
|
+
Yields
|
|
113
|
+
------
|
|
114
|
+
numpy.ndarray
|
|
115
|
+
The two-dimensional time-data block of shape (num, num_channels).
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class SpectraGenerator(Generator):
|
|
120
|
+
"""Interface for any generating multi-channel signal frequency domain processing block.
|
|
121
|
+
|
|
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.
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
#: Number of frequencies
|
|
129
|
+
num_freqs = CInt
|
|
130
|
+
|
|
131
|
+
#: 1-D array of frequencies
|
|
132
|
+
freqs = CArray
|
|
133
|
+
|
|
134
|
+
#: The length of the block used to calculate the spectra
|
|
135
|
+
block_size = CInt
|
|
136
|
+
|
|
137
|
+
# internal identifier
|
|
138
|
+
digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels', 'num_freqs', 'block_size'])
|
|
139
|
+
|
|
140
|
+
def _get_digest(self):
|
|
141
|
+
return digest(self)
|
|
142
|
+
|
|
143
|
+
@abstractmethod
|
|
144
|
+
def result(self, num=1):
|
|
145
|
+
"""Python generator that yields the output block-wise.
|
|
146
|
+
|
|
147
|
+
Parameters
|
|
148
|
+
----------
|
|
149
|
+
num : integer
|
|
150
|
+
This parameter defines the size of the number of snapshots to be yielded.
|
|
151
|
+
Defaults to 1.
|
|
152
|
+
|
|
153
|
+
Yields
|
|
154
|
+
------
|
|
155
|
+
numpy.ndarray
|
|
156
|
+
A two-dimensional block of shape (num, num_channels * num_freqs).
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
|
|
161
|
+
class TimeOut(SamplesGenerator):
|
|
162
|
+
"""Abstract base class for any signal processing block that receives data from any
|
|
163
|
+
:attr:`source` domain and returns time domain signals.
|
|
164
|
+
|
|
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.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
171
|
+
source = Instance(Generator)
|
|
172
|
+
|
|
173
|
+
#: Sampling frequency of output signal, as given by :attr:`source`.
|
|
174
|
+
sample_freq = Delegate('source')
|
|
175
|
+
|
|
176
|
+
#: Number of channels in output, as given by :attr:`source`.
|
|
177
|
+
num_channels = Delegate('source')
|
|
178
|
+
|
|
179
|
+
#: Number of samples in output, as given by :attr:`source`.
|
|
180
|
+
num_samples = Delegate('source')
|
|
181
|
+
|
|
182
|
+
# internal identifier
|
|
183
|
+
digest = Property(depends_on=['source.digest'])
|
|
184
|
+
|
|
185
|
+
@cached_property
|
|
186
|
+
def _get_digest(self):
|
|
187
|
+
return digest(self)
|
|
188
|
+
|
|
189
|
+
@abstractmethod
|
|
190
|
+
def result(self, num):
|
|
191
|
+
"""Python generator that processes the source data and yields the time-signal block-wise.
|
|
192
|
+
|
|
193
|
+
This method needs to be implemented by the derived classes.
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
num : int
|
|
198
|
+
This parameter defines the size of the blocks to be yielded
|
|
199
|
+
(i.e. the number of samples per block)
|
|
200
|
+
|
|
201
|
+
Yields
|
|
202
|
+
------
|
|
203
|
+
numpy.ndarray
|
|
204
|
+
Two-dimensional output data block of shape (num, num_channels)
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples', 'numfreqs': 'num_freqs'}, read_only=True)
|
|
209
|
+
class SpectraOut(SpectraGenerator):
|
|
210
|
+
"""Abstract base class for any signal processing block that receives data from any
|
|
211
|
+
:attr:`source` domain and returns frequency domain signals.
|
|
212
|
+
|
|
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.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
219
|
+
source = Instance(Generator)
|
|
220
|
+
|
|
221
|
+
#: Sampling frequency of output signal, as given by :attr:`source`.
|
|
222
|
+
sample_freq = Delegate('source')
|
|
223
|
+
|
|
224
|
+
#: Number of channels in output, as given by :attr:`source`.
|
|
225
|
+
num_channels = Delegate('source')
|
|
226
|
+
|
|
227
|
+
#: Number of snapshots in output, as given by :attr:`source`.
|
|
228
|
+
num_samples = Delegate('source')
|
|
229
|
+
|
|
230
|
+
#: Number of frequencies in output, as given by :attr:`source`.
|
|
231
|
+
num_freqs = Delegate('source')
|
|
232
|
+
|
|
233
|
+
#: 1-D array of frequencies, as given by :attr:`source`.
|
|
234
|
+
freqs = Delegate('source')
|
|
235
|
+
|
|
236
|
+
#: The size of the block used to calculate the spectra
|
|
237
|
+
block_size = Delegate('source')
|
|
238
|
+
|
|
239
|
+
# internal identifier
|
|
240
|
+
digest = Property(depends_on=['source.digest'])
|
|
241
|
+
|
|
242
|
+
@cached_property
|
|
243
|
+
def _get_digest(self):
|
|
244
|
+
return digest(self)
|
|
245
|
+
|
|
246
|
+
@abstractmethod
|
|
247
|
+
def result(self, num=1):
|
|
248
|
+
"""Python generator that processes the source data and yields the output block-wise.
|
|
249
|
+
|
|
250
|
+
This method needs to be implemented by the derived classes.
|
|
251
|
+
|
|
252
|
+
num : integer
|
|
253
|
+
This parameter defines the the number of snapshots to be yielded.
|
|
254
|
+
Defaults to 1.
|
|
255
|
+
|
|
256
|
+
Yields
|
|
257
|
+
------
|
|
258
|
+
numpy.ndarray
|
|
259
|
+
A two-dimensional block of shape (num, num_channels * num_freqs).
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
|
|
264
|
+
class InOut(SamplesGenerator, SpectraGenerator):
|
|
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.
|
|
267
|
+
|
|
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.
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
#: Data source; :class:`~acoular.base.Generator` or derived object.
|
|
274
|
+
source = Instance(Generator)
|
|
275
|
+
|
|
276
|
+
#: Sampling frequency of output signal, as given by :attr:`source`.
|
|
277
|
+
sample_freq = Delegate('source')
|
|
278
|
+
|
|
279
|
+
#: Number of channels in output, as given by :attr:`source`.
|
|
280
|
+
num_channels = Delegate('source')
|
|
281
|
+
|
|
282
|
+
#: Number of frequencies in output, as given by :attr:`source`.
|
|
283
|
+
num_freqs = Delegate('source')
|
|
284
|
+
|
|
285
|
+
#: Number of samples / snapshots in output, as given by :attr:`source`.
|
|
286
|
+
num_samples = Delegate('source')
|
|
287
|
+
|
|
288
|
+
# internal identifier
|
|
289
|
+
digest = Property(depends_on=['source.digest'])
|
|
290
|
+
|
|
291
|
+
@cached_property
|
|
292
|
+
def _get_digest(self):
|
|
293
|
+
return digest(self)
|
|
294
|
+
|
|
295
|
+
@abstractmethod
|
|
296
|
+
def result(self, num):
|
|
297
|
+
"""Python generator that processes the source data and yields the output block-wise.
|
|
298
|
+
|
|
299
|
+
This method needs to be implemented by the derived classes.
|
|
300
|
+
|
|
301
|
+
Parameters
|
|
302
|
+
----------
|
|
303
|
+
num : int
|
|
304
|
+
The size of the first dimension of the blocks to be yielded
|
|
305
|
+
|
|
306
|
+
Yields
|
|
307
|
+
------
|
|
308
|
+
numpy.ndarray
|
|
309
|
+
Two-dimensional output data block of shape (num, ...)
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class TimeInOut(TimeOut):
|
|
314
|
+
"""Deprecated alias for :class:`~acoular.base.TimeOut`.
|
|
315
|
+
|
|
316
|
+
.. deprecated:: 24.10
|
|
317
|
+
Using :class:`~acoular.base.TimeInOut` is deprecated and will be removed in Acoular 25.07.
|
|
318
|
+
Use :class:`~acoular.base.TimeOut` instead.
|
|
319
|
+
"""
|
|
320
|
+
|
|
321
|
+
#: Data source; :class:`~acoular.base.SamplesGenerator` or derived object.
|
|
322
|
+
source = Instance(SamplesGenerator)
|
|
323
|
+
|
|
324
|
+
def __init__(self, *args, **kwargs):
|
|
325
|
+
super().__init__(*args, **kwargs)
|
|
326
|
+
import warnings
|
|
327
|
+
|
|
328
|
+
warnings.warn(
|
|
329
|
+
'TimeInOut is deprecated and will be removed in Acoular 25.07. Use TimeOut instead.',
|
|
330
|
+
DeprecationWarning,
|
|
331
|
+
stacklevel=2,
|
|
332
|
+
)
|