acoular 25.10__py3-none-any.whl → 26.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/aiaa/aiaa.py CHANGED
@@ -102,7 +102,7 @@ class CsmAIAABenchmark(PowerSpectraImport):
102
102
  #: HDF5 file object
103
103
  h5f = Instance(H5FileBase, transient=True)
104
104
 
105
- # internal identifier
105
+ #: A unique identifier for the CSM importer, based on its properties. (read-only)
106
106
  digest = Property(depends_on=['basename', '_csmsum'])
107
107
 
108
108
  @cached_property
acoular/base.py CHANGED
@@ -55,7 +55,7 @@ class Generator(ABCHasStrictTraits):
55
55
  """
56
56
 
57
57
  #: Sampling frequency of the signal, defaults to 1.0
58
- sample_freq = Float(1.0, desc='sampling frequency')
58
+ sample_freq = Float(1.0)
59
59
 
60
60
  #: Number of signal samples
61
61
  num_samples = CInt
@@ -63,7 +63,7 @@ class Generator(ABCHasStrictTraits):
63
63
  #: Number of channels
64
64
  num_channels = CInt
65
65
 
66
- # internal identifier
66
+ #: A unique identifier for the generator, based on its properties. (read-only)
67
67
  digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
68
68
 
69
69
  def _get_digest(self):
@@ -96,7 +96,7 @@ class SamplesGenerator(Generator):
96
96
 
97
97
  """
98
98
 
99
- # internal identifier
99
+ #: A unique identifier for the generator, based on its properties. (read-only)
100
100
  digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels'])
101
101
 
102
102
  def _get_digest(self):
@@ -137,7 +137,7 @@ class SpectraGenerator(Generator):
137
137
  #: The length of the block used to calculate the spectra
138
138
  block_size = CInt
139
139
 
140
- # internal identifier
140
+ #: A unique identifier for the generator, based on its properties. (read-only)
141
141
  digest = Property(depends_on=['sample_freq', 'num_samples', 'num_channels', 'num_freqs', 'block_size'])
142
142
 
143
143
  def _get_digest(self):
@@ -181,7 +181,7 @@ class TimeOut(SamplesGenerator):
181
181
  #: Number of samples in output, as given by :attr:`source`.
182
182
  num_samples = Delegate('source')
183
183
 
184
- # internal identifier
184
+ #: A unique identifier for the generator, based on its properties. (read-only)
185
185
  digest = Property(depends_on=['source.digest'])
186
186
 
187
187
  @cached_property
@@ -237,7 +237,7 @@ class SpectraOut(SpectraGenerator):
237
237
  #: The size of the block used to calculate the spectra
238
238
  block_size = Delegate('source')
239
239
 
240
- # internal identifier
240
+ #: A unique identifier for the generator, based on its properties. (read-only)
241
241
  digest = Property(depends_on=['source.digest'])
242
242
 
243
243
  @cached_property
@@ -285,7 +285,7 @@ class InOut(SamplesGenerator, SpectraGenerator):
285
285
  #: Number of samples / snapshots in output, as given by :attr:`source`.
286
286
  num_samples = Delegate('source')
287
287
 
288
- # internal identifier
288
+ #: A unique identifier for the generator, based on its properties. (read-only)
289
289
  digest = Property(depends_on=['source.digest'])
290
290
 
291
291
  @cached_property
acoular/calib.py CHANGED
@@ -78,26 +78,26 @@ class Calib(InOut):
78
78
  """
79
79
 
80
80
  #: Name of the .xml file to be imported.
81
- file = Union(None, File(filter=['*.xml'], exists=True), desc='name of the xml file to import')
81
+ file = Union(None, File(filter=['*.xml'], exists=True))
82
82
 
83
83
  #: Number of microphones in the calibration data,
84
84
  #: is set automatically when read from file or when data is set.
85
- num_mics = CInt(0, desc='number of microphones in the geometry')
85
+ num_mics = CInt(0)
86
86
 
87
87
  #: Array of calibration factors,
88
88
  #: is set automatically when read from file.
89
89
  #: Can be set manually by specifying a NumPy array with shape (num_channels, ) if
90
90
  #: :attr:`source` yields time domain signals. For frequency domain signals, the expected
91
91
  #: shape is (num_channels * num_freqs).
92
- data = CArray(desc='calibration data')
92
+ data = CArray()
93
93
 
94
94
  #: Channels that are to be treated as invalid.
95
- invalid_channels = List(int, desc='list of invalid channels')
95
+ invalid_channels = List(int)
96
96
 
97
97
  #: Channel mask to serve as an index for all valid channels, is set automatically.
98
- channels = Property(depends_on=['invalid_channels', 'num_mics'], desc='channel mask')
98
+ channels = Property(depends_on=['invalid_channels', 'num_mics'])
99
99
 
100
- # Internal identifier
100
+ #: A unique identifier for the object, based on its properties. (read-only)
101
101
  digest = Property(depends_on=['source.digest', 'data'])
102
102
 
103
103
  @observe('data')
acoular/demo/__init__.py CHANGED
@@ -5,15 +5,103 @@
5
5
 
6
6
  .. autosummary::
7
7
  :toctree: generated/
8
+ """
8
9
 
9
- acoular_demo
10
10
 
11
- """
11
+ def create_three_sources(mg, h5savefile='three_sources.h5'):
12
+ """
13
+ Create three noise sources and return them as Mixer.
14
+
15
+ Alias for :func:`create_three_sources_2d`.
16
+ """
17
+ return create_three_sources_2d(mg, h5savefile=h5savefile)
18
+
19
+
20
+ def _create_three_sources(mg, locs, h5savefile='', sfreq=51200, duration=1):
21
+ """Create three noise sources with custom locations and return them as Mixer."""
22
+ import acoular as ac
23
+
24
+ nsamples = duration * sfreq
25
+
26
+ n1 = ac.WNoiseGenerator(sample_freq=sfreq, num_samples=nsamples, seed=1)
27
+ n2 = ac.WNoiseGenerator(sample_freq=sfreq, num_samples=nsamples, seed=2, rms=0.7)
28
+ n3 = ac.WNoiseGenerator(sample_freq=sfreq, num_samples=nsamples, seed=3, rms=0.5)
29
+
30
+ noises = [n1, n2, n3]
31
+ ps = [ac.PointSource(signal=n, mics=mg, loc=loc) for n, loc in list(zip(noises, locs, strict=True))]
32
+ pa = ac.Mixer(source=ps[0], sources=ps[1:])
33
+
34
+ if h5savefile:
35
+ wh5 = ac.WriteH5(source=pa, file=h5savefile)
36
+ wh5.save()
37
+ return pa
38
+
39
+
40
+ def create_three_sources_1d(mg, h5savefile='three_sources_1d.h5'):
41
+ """Create three noise sources on a 1D line and return them as Mixer."""
42
+ locs = [(-0.1, 0, -0.3), (0.15, 0, -0.3), (0, 0, -0.3)]
43
+ return _create_three_sources(mg, locs, h5savefile=h5savefile)
44
+
45
+
46
+ def create_three_sources_2d(mg, h5savefile='three_sources_2d.h5'):
47
+ """Create three noise sources in a 2D plane and return them as Mixer."""
48
+ locs = [(-0.1, -0.1, -0.3), (0.15, 0, -0.3), (0, 0.1, -0.3)]
49
+ return _create_three_sources(mg, locs, h5savefile=h5savefile)
50
+
51
+
52
+ def create_three_sources_3d(mg, h5savefile='three_sources_3d.h5'):
53
+ """Create three noise sources in 3D space and return them as Mixer."""
54
+ locs = [(-0.1, -0.1, -0.3), (0.15, 0, -0.17), (0, 0.1, -0.25)]
55
+ return _create_three_sources(mg, locs, h5savefile=h5savefile)
56
+
57
+
58
+ def run():
59
+ """Run the Acoular demo."""
60
+ from pathlib import Path
61
+
62
+ import acoular as ac
63
+
64
+ ac.config.global_caching = 'none'
65
+
66
+ # set up microphone geometry
67
+
68
+ micgeofile = Path(ac.__file__).parent / 'xml' / 'array_64.xml'
69
+ mg = ac.MicGeom(file=micgeofile)
70
+
71
+ # generate test data, in real life this would come from an array measurement
72
+
73
+ pa = create_three_sources(mg)
74
+
75
+ # analyze the data and generate map
76
+
77
+ ps = ac.PowerSpectra(source=pa, block_size=128, window='Hanning')
78
+
79
+ rg = ac.RectGrid(x_min=-0.2, x_max=0.2, y_min=-0.2, y_max=0.2, z=-0.3, increment=0.01)
80
+ st = ac.SteeringVector(grid=rg, mics=mg)
81
+
82
+ bb = ac.BeamformerBase(freq_data=ps, steer=st)
83
+ pm = bb.synthetic(8000, 3)
84
+ spl = ac.L_p(pm)
85
+
86
+ if ac.config.have_matplotlib:
87
+ from matplotlib.pyplot import axis, colorbar, figure, imshow, plot, show
88
+
89
+ # show map
90
+ imshow(spl.T, origin='lower', vmin=spl.max() - 10, extent=rg.extent, interpolation='bicubic')
91
+ colorbar()
92
+
93
+ # plot microphone geometry
94
+ figure(2)
95
+ plot(mg.pos[0], mg.pos[1], 'o')
96
+ axis('equal')
97
+
98
+ show()
12
99
 
13
- from . import acoular_demo
14
- from .acoular_demo import (
15
- create_three_sources,
16
- create_three_sources_1d,
17
- create_three_sources_2d,
18
- create_three_sources_3d,
19
- )
100
+ else:
101
+ print('Matplotlib not found! Please install matplotlib if you want to plot the results.')
102
+ print('For consolation we do an ASCII map plot of the results here.')
103
+ grayscale = '@%#*+=-:. '[::-1]
104
+ ind = ((spl.T - spl.max() + 9).clip(0, 9)).astype(int)[::-1]
105
+ print(78 * '-')
106
+ print('|\n'.join([' '.join(['|'] + [grayscale[i] for i in row[2:-1]]) for row in ind]) + '|')
107
+ print(7 * '-', ''.join([f'{grayscale[i]}={int(spl.max()) - 9 + i}dB ' for i in range(1, 10)]), 6 * '-')
@@ -0,0 +1,37 @@
1
+ # ------------------------------------------------------------------------------
2
+ # Copyright (c) Acoular Development Team.
3
+ # ------------------------------------------------------------------------------
4
+ """Demo for Acoular.
5
+
6
+ To run the demo, execute the following commands:
7
+
8
+ .. code-block:: python
9
+
10
+ import acoular
11
+
12
+ acoular.demo.run()
13
+
14
+
15
+ Generates a test data set for three sources, analyzes them and generates a
16
+ map of the three sources.
17
+
18
+ The simulation generates the sound pressure at 64 microphones that are
19
+ arrangend in the 'array64' geometry, which is part of the package. The sound
20
+ pressure signals are sampled at 51200 Hz for a duration of 1 second.
21
+
22
+ Source location (relative to array center) and RMS in 1 m distance:
23
+
24
+ ====== =============== ======
25
+ Source Location RMS
26
+ ====== =============== ======
27
+ 1 (-0.1,-0.1,0.3) 1.0 Pa
28
+ 2 (0.15,0,0.3) 0.7 Pa
29
+ 3 (0,0.1,0.3) 0.5 Pa
30
+ ====== =============== ======
31
+
32
+ """
33
+
34
+ if __name__ == '__main__':
35
+ from . import run
36
+
37
+ run()
acoular/environments.py CHANGED
@@ -182,7 +182,7 @@ class Environment(HasStrictTraits):
182
182
 
183
183
  #: The speed of sound in the environment. Default is ``343.0``, which corresponds to the
184
184
  #: approximate speed of sound at 20°C in dry air at sea level, if the unit is m/s.
185
- c = Float(343.0, desc='speed of sound')
185
+ c = Float(343.0)
186
186
 
187
187
  #: The region of interest (ROI) for calculations. (Not needed for most types of environment.)
188
188
  #: Default is :obj:`None`.
@@ -250,11 +250,11 @@ class UniformFlowEnvironment(Environment):
250
250
 
251
251
  #: The Mach number of the flow, defined as the ratio of the flow velocity to the speed of sound.
252
252
  #: Default is ``0.0``, which corresponds to no flow.
253
- ma = Float(0.0, desc='flow mach number')
253
+ ma = Float(0.0)
254
254
 
255
255
  #: A unit vector specifying the direction of the flow in 3D Cartesian coordinates.
256
256
  #: Default is ``(1.0, 0, 0)``, which corresponds to flow in the x-direction.
257
- fdv = CArray(dtype=np.float64, shape=(3,), value=np.array((1.0, 0, 0)), desc='flow direction')
257
+ fdv = CArray(dtype=np.float64, shape=(3,), value=np.array((1.0, 0, 0)))
258
258
 
259
259
  #: A unique identifier based on the environment properties. (read-only)
260
260
  digest = Property(
@@ -344,24 +344,24 @@ class SlotJet(FlowField):
344
344
  """
345
345
 
346
346
  #: Exit velocity at the :attr:`slot jet origin<origin>` (nozzle). Default is ``0.0``.
347
- v0 = Float(0.0, desc='exit velocity')
347
+ v0 = Float(0.0)
348
348
 
349
349
  #: The location of the slot nozzle center. Default is ``(0.0, 0.0, 0.0)``.
350
- origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)), desc='center of nozzle')
350
+ origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)))
351
351
 
352
352
  #: Unit vector representing the flow direction. Default is ``(1.0, 0.0, 0.0)``.
353
- flow = CArray(dtype=np.float64, shape=(3,), value=np.array((1.0, 0.0, 0.0)), desc='flow direction')
353
+ flow = CArray(dtype=np.float64, shape=(3,), value=np.array((1.0, 0.0, 0.0)))
354
354
 
355
355
  #: Unit vector parallel to the slot center plane, used to define the slot orientation.
356
356
  #: Default is ``(0.0, 1.0, 0.0)``.
357
- plane = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 1.0, 0.0)), desc='slot center line direction')
357
+ plane = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 1.0, 0.0)))
358
358
 
359
359
  #: Width of the slot (slot diameter). Default is ``0.2``.
360
- B = Float(0.2, desc='nozzle diameter')
360
+ B = Float(0.2)
361
361
 
362
362
  #: Non-dimensional length of the zone of flow establishment (jet core length).
363
363
  #: Default is ``5.2``.
364
- l = Float(5.2, desc='flow establishment length') # noqa: E741
364
+ l = Float(5.2) # noqa: E741
365
365
 
366
366
  #: A unique identifier based on the field properties. (read-only)
367
367
  digest = Property(
@@ -465,17 +465,17 @@ class OpenJet(FlowField):
465
465
  """
466
466
 
467
467
  #: Exit velocity at the jet origin (nozzle). Default is ``0.0``.
468
- v0 = Float(0.0, desc='exit velocity')
468
+ v0 = Float(0.0)
469
469
 
470
470
  #: The location of the nozzle center. Default is ``(0.0, 0.0, 0.0)``.
471
- origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)), desc='center of nozzle')
471
+ origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)))
472
472
 
473
473
  #: Diameter of the nozzle. Default is ``0.2``.
474
- D = Float(0.2, desc='nozzle diameter')
474
+ D = Float(0.2)
475
475
 
476
476
  #: Non-dimensional length of the zone of flow establishment (jet core length).
477
477
  #: Default is ``6.2``. :cite:`Albertson1950`
478
- l = Float(6.2, desc='flow establishment length') # noqa: E741
478
+ l = Float(6.2) # noqa: E741
479
479
 
480
480
  #: A unique identifier based on the field properties. (read-only)
481
481
  digest = Property(
@@ -575,11 +575,11 @@ class RotatingFlow(FlowField):
575
575
  [ 0. , 0. , 0. ]])
576
576
  """
577
577
 
578
- # Revolutions per minute (RPM). Default is ``0.0``.
579
- # Positive values indicate clockwise rotation of the flow.
580
- # This is contrary to the usual definition of the direction of rotation.
581
- # Deprecated! Please use the differently defined :attr:`rps` attribute instead.
582
- rpm = Property(transient=True, desc='revolutions per minute of the flow; positive values for clockwise rotation')
578
+ #: Revolutions per minute (RPM). Default is ``0.0``.
579
+ #: Positive values indicate clockwise rotation of the flow.
580
+ #: This is contrary to the usual definition of the direction of rotation.
581
+ #: Deprecated! Please use the differently defined :attr:`rps` attribute instead.
582
+ rpm = Property(transient=True)
583
583
 
584
584
  def _get_rpm(self):
585
585
  warn(
@@ -601,14 +601,14 @@ class RotatingFlow(FlowField):
601
601
 
602
602
  #: Rotational speed in revolutions per second. Negative values indicate clockwise
603
603
  #: rigid-body-like rotation of the flow. Default is ``0.0``.
604
- rps = Float(0.0, desc='rotational speed of the flow in Hz')
604
+ rps = Float(0.0)
605
605
 
606
606
  #: Constant flow velocity in the z-direction. Default is ``0.0``.
607
- v0 = Float(0.0, desc='flow velocity')
607
+ v0 = Float(0.0)
608
608
 
609
609
  #: The location of the center of rotation.
610
610
  #: Default is ``(0.0, 0.0, 0.0)``.
611
- origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)), desc='center of rotation')
611
+ origin = CArray(dtype=np.float64, shape=(3,), value=np.array((0.0, 0.0, 0.0)))
612
612
 
613
613
  #: A unique identifier based on the field properties. (read-only)
614
614
  digest = Property(
@@ -798,14 +798,14 @@ class GeneralFlowEnvironment(Environment):
798
798
 
799
799
  #: The flow field object describing the velocity field,
800
800
  #: which must be an instance of :class:`~acoular.environments.FlowField`.
801
- ff = Instance(FlowField, desc='flow field')
801
+ ff = Instance(FlowField)
802
802
 
803
803
  #: The number of rays used per solid angle :math:`\Omega`. Defaults to ``200``.
804
- N = Int(200, desc='number of rays per Om')
804
+ N = Int(200)
805
805
 
806
806
  #: The maximum solid angle (in steradians) used in the ray-tracing algorithm.
807
807
  #: Default is :obj:`numpy.pi`.
808
- Om = Float(np.pi, desc='maximum solid angle')
808
+ Om = Float(np.pi)
809
809
 
810
810
  #: A unique identifier based on the environment properties. (read-only)
811
811
  digest = Property(