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.
Files changed (139) hide show
  1. acoular/__init__.py +119 -54
  2. acoular/calib.py +29 -38
  3. acoular/configuration.py +132 -82
  4. acoular/demo/__init__.py +10 -4
  5. acoular/demo/acoular_demo.py +73 -55
  6. acoular/environments.py +270 -264
  7. acoular/fastFuncs.py +366 -196
  8. acoular/fbeamform.py +1797 -1934
  9. acoular/grids.py +504 -548
  10. acoular/h5cache.py +74 -83
  11. acoular/h5files.py +159 -142
  12. acoular/internal.py +13 -14
  13. acoular/microphones.py +57 -53
  14. acoular/sdinput.py +57 -53
  15. acoular/signals.py +180 -178
  16. acoular/sources.py +920 -724
  17. acoular/spectra.py +353 -363
  18. acoular/tbeamform.py +416 -416
  19. acoular/tfastfuncs.py +180 -104
  20. acoular/tools/__init__.py +25 -0
  21. acoular/tools/aiaa.py +185 -0
  22. acoular/tools/helpers.py +189 -0
  23. acoular/tools/metrics.py +165 -0
  24. acoular/tprocess.py +1240 -1182
  25. acoular/traitsviews.py +513 -501
  26. acoular/trajectory.py +50 -52
  27. acoular/version.py +5 -6
  28. acoular/xml/minidsp_uma-16.xml +20 -0
  29. acoular/xml/{minidsp_uma16.xml → minidsp_uma-16_mirrored.xml} +3 -0
  30. {acoular-24.3.dist-info → acoular-24.7.dist-info}/METADATA +58 -39
  31. acoular-24.7.dist-info/RECORD +50 -0
  32. {acoular-24.3.dist-info → acoular-24.7.dist-info}/WHEEL +1 -1
  33. acoular-24.7.dist-info/licenses/LICENSE +28 -0
  34. acoular/fileimport.py +0 -380
  35. acoular/nidaqimport.py +0 -273
  36. acoular/tests/reference_data/BeamformerBase.npy +0 -0
  37. acoular/tests/reference_data/BeamformerBaseFalse1.npy +0 -0
  38. acoular/tests/reference_data/BeamformerBaseFalse2.npy +0 -0
  39. acoular/tests/reference_data/BeamformerBaseFalse3.npy +0 -0
  40. acoular/tests/reference_data/BeamformerBaseFalse4.npy +0 -0
  41. acoular/tests/reference_data/BeamformerBaseTrue1.npy +0 -0
  42. acoular/tests/reference_data/BeamformerBaseTrue2.npy +0 -0
  43. acoular/tests/reference_data/BeamformerBaseTrue3.npy +0 -0
  44. acoular/tests/reference_data/BeamformerBaseTrue4.npy +0 -0
  45. acoular/tests/reference_data/BeamformerCMFLassoLarsBIC.npy +0 -0
  46. acoular/tests/reference_data/BeamformerCMFNNLS.npy +0 -0
  47. acoular/tests/reference_data/BeamformerCapon.npy +0 -0
  48. acoular/tests/reference_data/BeamformerClean.npy +0 -0
  49. acoular/tests/reference_data/BeamformerCleansc.npy +0 -0
  50. acoular/tests/reference_data/BeamformerCleant.npy +0 -0
  51. acoular/tests/reference_data/BeamformerCleantSq.npy +0 -0
  52. acoular/tests/reference_data/BeamformerCleantSqTraj.npy +0 -0
  53. acoular/tests/reference_data/BeamformerCleantTraj.npy +0 -0
  54. acoular/tests/reference_data/BeamformerDamas.npy +0 -0
  55. acoular/tests/reference_data/BeamformerDamasPlus.npy +0 -0
  56. acoular/tests/reference_data/BeamformerEig.npy +0 -0
  57. acoular/tests/reference_data/BeamformerEigFalse1.npy +0 -0
  58. acoular/tests/reference_data/BeamformerEigFalse2.npy +0 -0
  59. acoular/tests/reference_data/BeamformerEigFalse3.npy +0 -0
  60. acoular/tests/reference_data/BeamformerEigFalse4.npy +0 -0
  61. acoular/tests/reference_data/BeamformerEigTrue1.npy +0 -0
  62. acoular/tests/reference_data/BeamformerEigTrue2.npy +0 -0
  63. acoular/tests/reference_data/BeamformerEigTrue3.npy +0 -0
  64. acoular/tests/reference_data/BeamformerEigTrue4.npy +0 -0
  65. acoular/tests/reference_data/BeamformerFunctional.npy +0 -0
  66. acoular/tests/reference_data/BeamformerGIB.npy +0 -0
  67. acoular/tests/reference_data/BeamformerGridlessOrth.npy +0 -0
  68. acoular/tests/reference_data/BeamformerMusic.npy +0 -0
  69. acoular/tests/reference_data/BeamformerOrth.npy +0 -0
  70. acoular/tests/reference_data/BeamformerSODIX.npy +0 -0
  71. acoular/tests/reference_data/BeamformerTime.npy +0 -0
  72. acoular/tests/reference_data/BeamformerTimeSq.npy +0 -0
  73. acoular/tests/reference_data/BeamformerTimeSqTraj.npy +0 -0
  74. acoular/tests/reference_data/BeamformerTimeTraj.npy +0 -0
  75. acoular/tests/reference_data/Environment.npy +0 -0
  76. acoular/tests/reference_data/Example1_numerical_values_testsum.h5 +0 -0
  77. acoular/tests/reference_data/FiltFiltOctave__.npy +0 -0
  78. acoular/tests/reference_data/FiltFiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
  79. acoular/tests/reference_data/FiltFreqWeight_weight_A_.npy +0 -0
  80. acoular/tests/reference_data/FiltFreqWeight_weight_C_.npy +0 -0
  81. acoular/tests/reference_data/FiltFreqWeight_weight_Z_.npy +0 -0
  82. acoular/tests/reference_data/FiltOctave__.npy +0 -0
  83. acoular/tests/reference_data/FiltOctave_band_100_0_fraction_Thirdoctave_.npy +0 -0
  84. acoular/tests/reference_data/Filter__.npy +0 -0
  85. acoular/tests/reference_data/GeneralFlowEnvironment.npy +0 -0
  86. acoular/tests/reference_data/OctaveFilterBank__.npy +0 -0
  87. acoular/tests/reference_data/OpenJet.npy +0 -0
  88. acoular/tests/reference_data/PointSource.npy +0 -0
  89. acoular/tests/reference_data/PowerSpectra_csm.npy +0 -0
  90. acoular/tests/reference_data/PowerSpectra_ev.npy +0 -0
  91. acoular/tests/reference_data/RotatingFlow.npy +0 -0
  92. acoular/tests/reference_data/SlotJet.npy +0 -0
  93. acoular/tests/reference_data/TimeAverage__.npy +0 -0
  94. acoular/tests/reference_data/TimeCumAverage__.npy +0 -0
  95. acoular/tests/reference_data/TimeExpAverage_weight_F_.npy +0 -0
  96. acoular/tests/reference_data/TimeExpAverage_weight_I_.npy +0 -0
  97. acoular/tests/reference_data/TimeExpAverage_weight_S_.npy +0 -0
  98. acoular/tests/reference_data/TimeInOut__.npy +0 -0
  99. acoular/tests/reference_data/TimePower__.npy +0 -0
  100. acoular/tests/reference_data/TimeReverse__.npy +0 -0
  101. acoular/tests/reference_data/UniformFlowEnvironment.npy +0 -0
  102. acoular/tests/reference_data/beamformer_traj_time_data.h5 +0 -0
  103. acoular/tests/run_tests.sh +0 -18
  104. acoular/tests/run_tests_osx.sh +0 -16
  105. acoular/tests/test.npy +0 -0
  106. acoular/tests/test_beamformer_results.py +0 -213
  107. acoular/tests/test_classes.py +0 -60
  108. acoular/tests/test_digest.py +0 -125
  109. acoular/tests/test_environments.py +0 -73
  110. acoular/tests/test_example1.py +0 -124
  111. acoular/tests/test_grid.py +0 -92
  112. acoular/tests/test_integrate.py +0 -102
  113. acoular/tests/test_signals.py +0 -60
  114. acoular/tests/test_sources.py +0 -65
  115. acoular/tests/test_spectra.py +0 -38
  116. acoular/tests/test_timecache.py +0 -35
  117. acoular/tests/test_tprocess.py +0 -90
  118. acoular/tests/test_traj_beamformer_results.py +0 -164
  119. acoular/tests/unsupported/SpeedComparison/OvernightTestcasesBeamformer_nMics32_nGridPoints100_nFreqs4_nTrials10.png +0 -0
  120. acoular/tests/unsupported/SpeedComparison/cythonBeamformer.pyx +0 -237
  121. acoular/tests/unsupported/SpeedComparison/mainForCython.py +0 -103
  122. acoular/tests/unsupported/SpeedComparison/mainForParallelJit.py +0 -143
  123. acoular/tests/unsupported/SpeedComparison/setupCythonOpenMP.py +0 -63
  124. acoular/tests/unsupported/SpeedComparison/sharedFunctions.py +0 -153
  125. acoular/tests/unsupported/SpeedComparison/timeOverNMics_AllImportantMethods.png +0 -0
  126. acoular/tests/unsupported/SpeedComparison/timeOverNMics_faverage.png +0 -0
  127. acoular/tests/unsupported/SpeedComparison/vglOptimierungFAverage.py +0 -204
  128. acoular/tests/unsupported/SpeedComparison/vglOptimierungGaussSeidel.py +0 -182
  129. acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAMFULL_INVERSE.py +0 -764
  130. acoular/tests/unsupported/SpeedComparison/vglOptimierungR_BEAM_OS.py +0 -231
  131. acoular/tests/unsupported/SpeedComparison/whatsFastestWayFor_absASquared.py +0 -48
  132. acoular/tests/unsupported/functionalBeamformer.py +0 -123
  133. acoular/tests/unsupported/precisionTest.py +0 -153
  134. acoular/tests/unsupported/validationOfBeamformerFuncsPOSTAcoularIntegration.py +0 -254
  135. acoular/tests/unsupported/validationOfBeamformerFuncsPREeAcoularIntegration.py +0 -531
  136. acoular/tools.py +0 -422
  137. acoular-24.3.dist-info/RECORD +0 -148
  138. acoular-24.3.dist-info/licenses/LICENSE +0 -29
  139. {acoular-24.3.dist-info → acoular-24.7.dist-info}/licenses/AUTHORS.rst +0 -0
acoular/tfastfuncs.py CHANGED
@@ -1,173 +1,249 @@
1
- # -*- coding: utf-8 -*-
2
- #pylint: disable-msg=E0611, E1101, C0103, R0901, R0902, R0903, R0904, W0232
3
- #------------------------------------------------------------------------------
1
+ # ------------------------------------------------------------------------------
4
2
  # Copyright (c) Acoular Development Team.
5
- #------------------------------------------------------------------------------
6
- """
7
- This file contains NUMBA accelerated functions for time-domain beamformers
8
- """
3
+ # ------------------------------------------------------------------------------
4
+ """Contains NUMBA accelerated functions for time-domain beamformers."""
5
+
9
6
  import numba as nb
10
7
  import numpy as np
11
8
 
12
9
 
13
- cachedOption = True # if True: saves the numba func as compiled func in sub directory
14
- fastOption = True # fastmath options
15
-
16
- @nb.njit([(nb.float64[:,::1], nb.int64[:,::1], nb.float64[:,::1], nb.float64[:,::1], nb.float64[:,::1], nb.float64[:,::1])],
17
- cache=True, parallel=True, fastmath=True)
10
+ @nb.njit(
11
+ [
12
+ (
13
+ nb.float64[:, ::1],
14
+ nb.int64[:, ::1],
15
+ nb.float64[:, ::1],
16
+ nb.float64[:, ::1],
17
+ nb.float64[:, ::1],
18
+ nb.float64[:, ::1],
19
+ ),
20
+ ],
21
+ cache=True,
22
+ parallel=True,
23
+ fastmath=True,
24
+ )
18
25
  def _delayandsum4(data, offsets, ifactor2, steeramp, out, autopower):
19
- """ Performs one time step of delay and sum with output and additional autopower removal
20
-
26
+ """Performs one time step of delay and sum with output and additional autopower removal.
27
+
21
28
  Parameters
22
29
  ----------
23
- data : float64[nSamples, nMics]
30
+ data : float64[nSamples, nMics]
24
31
  The time history for all channels.
25
- offsets : int64[gridSize, nMics]
32
+ offsets : int64[gridSize, nMics]
26
33
  Indices for each grid point and each channel.
27
- ifactor2: float64[gridSize, nMics]
34
+ ifactor2: float64[gridSize, nMics]
28
35
  Second interpolation factor, the first one is computed internally.
29
- steeramp: float64[gridSize, nMics]
30
- Amplitude factor from steering vector.
31
-
36
+ steeramp: float64[gridSize, nMics]
37
+ Amplitude factor from steering vector.
38
+
32
39
  Returns
33
40
  -------
34
41
  None : as the inputs out and autopower get overwritten.
42
+
35
43
  """
36
44
  gridsize, numchannels = offsets.shape
37
45
  num = out.shape[0]
38
- ZERO = data.dtype.type(0.)
39
- ONE = data.dtype.type(1.)
46
+ zero_constant = data.dtype.type(0.0)
40
47
  for n in nb.prange(num):
41
48
  for gi in nb.prange(gridsize):
42
- out[n,gi] = ZERO
43
- autopower[n,gi] = ZERO
49
+ out[n, gi] = zero_constant
50
+ autopower[n, gi] = zero_constant
44
51
  for mi in range(numchannels):
45
- ind = (gi,mi)
46
- r = (data[offsets[ind]+n,mi] * (1.-ifactor2[ind]) \
47
- + data[offsets[ind]+n+1,mi] * ifactor2[ind]) * steeramp[ind]
48
- out[n,gi] += r
49
- autopower[n,gi] += r*r
50
-
51
- @nb.njit([(nb.float32[:,::1], nb.int32[:,:,::1], nb.float32[:,:,::1], nb.float32[:,:,::1], nb.float32[:,::1], nb.float32[:,::1]),
52
- (nb.float64[:,::1], nb.int64[:,:,::1], nb.float64[:,:,::1], nb.float64[:,:,::1], nb.float64[:,::1], nb.float64[:,::1])],
53
- cache=True, parallel=True, fastmath=True)
52
+ ind = (gi, mi)
53
+ r = (
54
+ data[offsets[ind] + n, mi] * (1.0 - ifactor2[ind]) + data[offsets[ind] + n + 1, mi] * ifactor2[ind]
55
+ ) * steeramp[ind]
56
+ out[n, gi] += r
57
+ autopower[n, gi] += r * r
58
+
59
+
60
+ @nb.njit(
61
+ [
62
+ (
63
+ nb.float32[:, ::1],
64
+ nb.int32[:, :, ::1],
65
+ nb.float32[:, :, ::1],
66
+ nb.float32[:, :, ::1],
67
+ nb.float32[:, ::1],
68
+ nb.float32[:, ::1],
69
+ ),
70
+ (
71
+ nb.float64[:, ::1],
72
+ nb.int64[:, :, ::1],
73
+ nb.float64[:, :, ::1],
74
+ nb.float64[:, :, ::1],
75
+ nb.float64[:, ::1],
76
+ nb.float64[:, ::1],
77
+ ),
78
+ ],
79
+ cache=True,
80
+ parallel=True,
81
+ fastmath=True,
82
+ )
54
83
  def _delayandsum5(data, offsets, ifactor2, steeramp, out, autopower):
55
- """ Performs one time step of delay and sum with output and additional autopower removal
56
-
84
+ """Performs one time step of delay and sum with output and additional autopower removal.
85
+
57
86
  Parameters
58
87
  ----------
59
- data : float64[nSamples, nMics]
88
+ data : float64[nSamples, nMics]
60
89
  The time history for all channels.
61
- offsets : int64[nBlockSamples, gridSize, nMics]
90
+ offsets : int64[nBlockSamples, gridSize, nMics]
62
91
  Indices for each grid point and each channel.
63
- ifactor2: float64[nBlockSamples,gridSize, nMics]
92
+ ifactor2: float64[nBlockSamples,gridSize, nMics]
64
93
  Second interpolation factor, the first one is computed internally.
65
- steeramp: float64[nBlockSamples,gridSize, nMics]
66
- Amplitude factor from steering vector.
67
-
94
+ steeramp: float64[nBlockSamples,gridSize, nMics]
95
+ Amplitude factor from steering vector.
96
+
68
97
  Returns
69
98
  -------
70
99
  None : as the inputs out and autopower get overwritten.
100
+
71
101
  """
72
102
  num, gridsize, numchannels = offsets.shape
73
103
  num = out.shape[0]
74
- #ZERO = data.dtype.type(0.)
75
- ONE = data.dtype.type(1.)
104
+ # ZERO = data.dtype.type(0.)
105
+ one_constant = data.dtype.type(1.0)
76
106
  for n in nb.prange(num):
77
107
  for gi in nb.prange(gridsize):
78
- out[n,gi] = 0
79
- autopower[n,gi] = 0
108
+ out[n, gi] = 0
109
+ autopower[n, gi] = 0
80
110
  for mi in range(numchannels):
81
- ind = offsets[n,gi,mi]+n
82
- r = (data[ind,mi] * (ONE - ifactor2[n,gi,mi]) \
83
- + data[ind+1,mi] * ifactor2[n,gi,mi]) * steeramp[n,gi,mi]
84
- out[n,gi] += r
85
- autopower[n,gi] += r*r
86
-
87
- @nb.njit([(nb.float32[:,:,:], nb.float32[:,:], nb.float32[:,:,:]),
88
- (nb.float64[:,:,:], nb.float64[:,:], nb.float64[:,:,:])],
89
- cache=True, parallel=True, fastmath=True)
90
- def _steer_I(rm, r0, amp):
111
+ ind = offsets[n, gi, mi] + n
112
+ r = (
113
+ data[ind, mi] * (one_constant - ifactor2[n, gi, mi]) + data[ind + 1, mi] * ifactor2[n, gi, mi]
114
+ ) * steeramp[
115
+ n,
116
+ gi,
117
+ mi,
118
+ ]
119
+ out[n, gi] += r
120
+ autopower[n, gi] += r * r
121
+
122
+
123
+ @nb.njit(
124
+ [
125
+ (nb.float32[:, :, :], nb.float32[:, :], nb.float32[:, :, :]),
126
+ (nb.float64[:, :, :], nb.float64[:, :], nb.float64[:, :, :]),
127
+ ],
128
+ cache=True,
129
+ parallel=True,
130
+ fastmath=True,
131
+ )
132
+ def _steer_I(rm, r0, amp): # noqa: ARG001, N802
91
133
  num, gridsize, numchannels = rm.shape
92
- amp[0,0,0] = 1.0/numchannels# to get the same type for rm2 as for rm
93
- Nr = amp[0,0,0]
94
- for n in nb.prange(num):
134
+ amp[0, 0, 0] = 1.0 / numchannels # to get the same type for rm2 as for rm
135
+ nr = amp[0, 0, 0]
136
+ for n in nb.prange(num):
95
137
  for gi in nb.prange(gridsize):
96
138
  for mi in nb.prange(numchannels):
97
- amp[n,gi,mi] = Nr
139
+ amp[n, gi, mi] = nr
140
+
98
141
 
99
- @nb.njit([(nb.float32[:,:,:], nb.float32[:,:], nb.float32[:,:,:]),
100
- (nb.float64[:,:,:], nb.float64[:,:], nb.float64[:,:,:])],
101
- cache=True, parallel=True, fastmath=True)
102
- def _steer_II(rm, r0, amp):
142
+ @nb.njit(
143
+ [
144
+ (nb.float32[:, :, :], nb.float32[:, :], nb.float32[:, :, :]),
145
+ (nb.float64[:, :, :], nb.float64[:, :], nb.float64[:, :, :]),
146
+ ],
147
+ cache=True,
148
+ parallel=True,
149
+ fastmath=True,
150
+ )
151
+ def _steer_II(rm, r0, amp): # noqa: N802
103
152
  num, gridsize, numchannels = rm.shape
104
- amp[0,0,0] = 1.0/numchannels# to get the same type for rm2 as for rm
105
- Nr = amp[0,0,0]
106
- for n in nb.prange(num):
153
+ amp[0, 0, 0] = 1.0 / numchannels # to get the same type for rm2 as for rm
154
+ nr = amp[0, 0, 0]
155
+ for n in nb.prange(num):
107
156
  for gi in nb.prange(gridsize):
108
- rm2 = np.divide(Nr,r0[n,gi])
157
+ rm2 = np.divide(nr, r0[n, gi])
109
158
  for mi in nb.prange(numchannels):
110
- amp[n,gi,mi] = rm[n,gi,mi]*rm2
159
+ amp[n, gi, mi] = rm[n, gi, mi] * rm2
111
160
 
112
- @nb.njit([(nb.float32[:,:,:], nb.float32[:,:], nb.float32[:,:,:]),
113
- (nb.float64[:,:,:], nb.float64[:,:], nb.float64[:,:,:])],
114
- cache=True, parallel=True, fastmath=True)
115
- def _steer_III(rm, r0, amp):
161
+
162
+ @nb.njit(
163
+ [
164
+ (nb.float32[:, :, :], nb.float32[:, :], nb.float32[:, :, :]),
165
+ (nb.float64[:, :, :], nb.float64[:, :], nb.float64[:, :, :]),
166
+ ],
167
+ cache=True,
168
+ parallel=True,
169
+ fastmath=True,
170
+ )
171
+ def _steer_III(rm, r0, amp): # noqa: N802
116
172
  num, gridsize, numchannels = rm.shape
117
- rm20 = rm[0,0,0]-rm[0,0,0] # to get the same type for rm2 as for rm
118
- rm1 = rm[0,0,0]/rm[0,0,0]
119
- for n in nb.prange(num):
173
+ rm20 = rm[0, 0, 0] - rm[0, 0, 0] # to get the same type for rm2 as for rm
174
+ rm1 = rm[0, 0, 0] / rm[0, 0, 0]
175
+ for n in nb.prange(num):
120
176
  for gi in nb.prange(gridsize):
121
177
  rm2 = rm20
122
178
  for mi in nb.prange(numchannels):
123
- rm2 += np.divide(rm1,np.square(rm[n,gi,mi]))
124
- rm2 *= r0[n,gi]
179
+ rm2 += np.divide(rm1, np.square(rm[n, gi, mi]))
180
+ rm2 *= r0[n, gi]
125
181
  for mi in nb.prange(numchannels):
126
- amp[n,gi,mi] = np.divide(rm1,rm[n,gi,mi]*rm2)
182
+ amp[n, gi, mi] = np.divide(rm1, rm[n, gi, mi] * rm2)
183
+
127
184
 
128
- @nb.njit([(nb.float32[:,:,:], nb.float32[:,:], nb.float32[:,:,:]),
129
- (nb.float64[:,:,:], nb.float64[:,:], nb.float64[:,:,:])],
130
- cache=True, parallel=True, fastmath=True)
131
- def _steer_IV(rm, r0, amp):
185
+ @nb.njit(
186
+ [
187
+ (nb.float32[:, :, :], nb.float32[:, :], nb.float32[:, :, :]),
188
+ (nb.float64[:, :, :], nb.float64[:, :], nb.float64[:, :, :]),
189
+ ],
190
+ cache=True,
191
+ parallel=True,
192
+ fastmath=True,
193
+ )
194
+ def _steer_IV(rm, r0, amp): # noqa: ARG001, N802
132
195
  num, gridsize, numchannels = rm.shape
133
- amp[0,0,0] = np.sqrt(1.0/numchannels)# to get the same type for rm2 as for rm
134
- Nr = amp[0,0,0]
135
- rm1 = rm[0,0,0]/rm[0,0,0]
136
- rm20 = rm[0,0,0]-rm[0,0,0] # to get the same type for rm2 as for rm
137
- for n in nb.prange(num):
196
+ amp[0, 0, 0] = np.sqrt(1.0 / numchannels) # to get the same type for rm2 as for rm
197
+ nr = amp[0, 0, 0]
198
+ rm1 = rm[0, 0, 0] / rm[0, 0, 0]
199
+ rm20 = rm[0, 0, 0] - rm[0, 0, 0] # to get the same type for rm2 as for rm
200
+ for n in nb.prange(num):
138
201
  for gi in nb.prange(gridsize):
139
202
  rm2 = rm20
140
203
  for mi in nb.prange(numchannels):
141
- rm2 += np.divide(rm1,np.square(rm[n,gi,mi]))
204
+ rm2 += np.divide(rm1, np.square(rm[n, gi, mi]))
142
205
  rm2 = np.sqrt(rm2)
143
206
  for mi in nb.prange(numchannels):
144
- amp[n,gi,mi] = np.divide(Nr,rm[n,gi,mi]*rm2)
207
+ amp[n, gi, mi] = np.divide(nr, rm[n, gi, mi] * rm2)
208
+
145
209
 
146
- @nb.njit([(nb.float32[:,:,::1], nb.float32, nb.float32[:,:,::1], nb.int32[:,:,::1]),
147
- (nb.float64[:,:,::1], nb.float64, nb.float64[:,:,::1], nb.int64[:,:,::1])],
148
- cache=True, parallel=True, fastmath=True)
210
+ @nb.njit(
211
+ [
212
+ (nb.float32[:, :, ::1], nb.float32, nb.float32[:, :, ::1], nb.int32[:, :, ::1]),
213
+ (nb.float64[:, :, ::1], nb.float64, nb.float64[:, :, ::1], nb.int64[:, :, ::1]),
214
+ ],
215
+ cache=True,
216
+ parallel=True,
217
+ fastmath=True,
218
+ )
149
219
  def _delays(rm, c, interp2, index):
150
220
  num, gridsize, numchannels = rm.shape
151
- invc = 1/c
221
+ invc = 1 / c
152
222
  intt = index.dtype.type
153
- for n in nb.prange(num):
223
+ for n in nb.prange(num):
154
224
  for gi in nb.prange(gridsize):
155
225
  for mi in nb.prange(numchannels):
156
- delays = invc * rm[n,gi,mi]
157
- index[n,gi,mi] = intt(delays)
158
- interp2[n,gi,mi] = delays - nb.int64(delays)
226
+ delays = invc * rm[n, gi, mi]
227
+ index[n, gi, mi] = intt(delays)
228
+ interp2[n, gi, mi] = delays - nb.int64(delays)
159
229
 
160
- @nb.njit([(nb.float32[:,:,:], nb.float32[:,:,:], nb.int32[:,:,:]),
161
- (nb.float64[:,:,:], nb.float64[:,:,:], nb.int64[:,:,:])],
162
- cache=True, parallel=True, fastmath=True)
230
+
231
+ @nb.njit(
232
+ [
233
+ (nb.float32[:, :, :], nb.float32[:, :, :], nb.int32[:, :, :]),
234
+ (nb.float64[:, :, :], nb.float64[:, :, :], nb.int64[:, :, :]),
235
+ ],
236
+ cache=True,
237
+ parallel=True,
238
+ fastmath=True,
239
+ )
163
240
  def _modf(delays, interp2, index):
164
241
  num, gridsize, numchannels = delays.shape
165
- for n in nb.prange(num):
242
+ for n in nb.prange(num):
166
243
  for gi in nb.prange(gridsize):
167
244
  for mi in nb.prange(numchannels):
168
- index[n,gi,mi] = int(delays[n,gi,mi])
169
- interp2[n,gi,mi] = delays[n,gi,mi] - index[n,gi,mi]
170
-
245
+ index[n, gi, mi] = int(delays[n, gi, mi])
246
+ interp2[n, gi, mi] = delays[n, gi, mi] - index[n, gi, mi]
171
247
 
172
248
 
173
249
  if __name__ == '__main__':
@@ -0,0 +1,25 @@
1
+ # ------------------------------------------------------------------------------
2
+ # Copyright (c) Acoular Development Team.
3
+ # ------------------------------------------------------------------------------
4
+ """Useful tools for Acoular.
5
+
6
+ .. autosummary::
7
+ :toctree: generated/
8
+
9
+ aiaa
10
+ helpers
11
+ metrics
12
+ """
13
+
14
+ from .aiaa import (
15
+ CsmAIAABenchmark,
16
+ MicAIAABenchmark,
17
+ TimeSamplesAIAABenchmark,
18
+ TriggerAIAABenchmark,
19
+ )
20
+ from .helpers import (
21
+ bardata,
22
+ barspectrum,
23
+ return_result,
24
+ )
25
+ from .metrics import MetricEvaluator
acoular/tools/aiaa.py ADDED
@@ -0,0 +1,185 @@
1
+ # ------------------------------------------------------------------------------
2
+ # Copyright (c) Acoular Development Team.
3
+ # ------------------------------------------------------------------------------
4
+ """Classes for importing AIAA Array Benchmarks
5
+ from . import aiaa
6
+ These classes allow importing data from HDF5 files following the specifications of
7
+ the AIAA microphone array methods benchmarking effort:
8
+ https://www-docs.b-tu.de/fg-akustik/public/veroeffentlichungen/ArrayMethodsFileFormatsR2P4Release.pdf .
9
+
10
+ The classes are derived from according Acoular classes so that they can be used directly within
11
+ the framework.
12
+
13
+ Examples
14
+ --------
15
+ >>> micgeom = MicAIAABenchmark(name='some_benchmarkdata.h5') # doctest: +SKIP
16
+ >>> timedata = TimeSamplesAIAABenchmark(name='some_benchmarkdata.h5') # doctest: +SKIP
17
+
18
+
19
+ .. autosummary::
20
+ :toctree: generated/
21
+
22
+ TimeSamplesAIAABenchmark
23
+ TriggerAIAABenchmark
24
+ CsmAIAABenchmark
25
+ MicAIAABenchmark
26
+ """
27
+
28
+ import contextlib
29
+ from os import path
30
+
31
+ from numpy import array
32
+ from traits.api import (
33
+ File,
34
+ Instance,
35
+ Property,
36
+ cached_property,
37
+ on_trait_change,
38
+ property_depends_on,
39
+ )
40
+
41
+ from acoular.h5files import H5FileBase, _get_h5file_class
42
+ from acoular.internal import digest
43
+ from acoular.microphones import MicGeom
44
+ from acoular.sources import TimeSamples
45
+ from acoular.spectra import PowerSpectraImport
46
+
47
+
48
+ class TimeSamplesAIAABenchmark(TimeSamples):
49
+ """Container for AIAA benchmark data in `*.h5` format.
50
+
51
+ This class loads measured data from h5 files in AIAA benchmark format
52
+ and and provides information about this data.
53
+ Objects of this class behave similar to :class:`~acoular.sources.TimeSamples`
54
+ objects.
55
+ """
56
+
57
+ def load_timedata(self):
58
+ """Loads timedata from .h5 file. Only for internal use."""
59
+ self.data = self.h5f.get_data_by_reference('MicrophoneData/microphoneDataPa')
60
+ self.sample_freq = self.h5f.get_node_attribute(self.data, 'sampleRateHz')
61
+ (self.numsamples, self.numchannels) = self.data.shape
62
+
63
+ def load_metadata(self):
64
+ """Loads metadata from .h5 file. Only for internal use."""
65
+ self.metadata = {}
66
+ if '/MetaData' in self.h5f:
67
+ self.metadata = self.h5f.node_to_dict('/MetaData')
68
+
69
+
70
+ class TriggerAIAABenchmark(TimeSamplesAIAABenchmark):
71
+ """Container for tacho data in `*.h5` format.
72
+
73
+ This class loads tacho data from h5 files as specified in
74
+ "Microphone Array Benchmark b11: Rotating Point Sources"
75
+ (https://doi.org/10.14279/depositonce-8460)
76
+ and and provides information about this data.
77
+ """
78
+
79
+ def load_timedata(self):
80
+ """Loads timedata from .h5 file. Only for internal use."""
81
+ self.data = self.h5f.get_data_by_reference('TachoData/tachoDataV')
82
+ self.sample_freq = self.h5f.get_node_attribute(self.data, 'sampleRateHz')
83
+ (self.numsamples, self.numchannels) = self.data.shape
84
+
85
+
86
+ class CsmAIAABenchmark(PowerSpectraImport):
87
+ """Class to load the CSM that is stored in AIAA Benchmark HDF5 file."""
88
+
89
+ #: Full name of the .h5 file with data
90
+ name = File(filter=['*.h5'], desc='name of data file')
91
+
92
+ #: Basename of the .h5 file with data, is set automatically.
93
+ basename = Property(
94
+ depends_on='name',
95
+ desc='basename of data file',
96
+ )
97
+
98
+ #: number of channels
99
+ numchannels = Property()
100
+
101
+ #: HDF5 file object
102
+ h5f = Instance(H5FileBase, transient=True)
103
+
104
+ # internal identifier
105
+ digest = Property(depends_on=['basename', '_csmsum'])
106
+
107
+ @cached_property
108
+ def _get_digest(self):
109
+ return digest(self)
110
+
111
+ @cached_property
112
+ def _get_basename(self):
113
+ return path.splitext(path.basename(self.name))[0]
114
+
115
+ @on_trait_change('basename')
116
+ def load_data(self):
117
+ """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
+ if self.h5f is not None:
122
+ with contextlib.suppress(OSError):
123
+ self.h5f.close()
124
+ file = _get_h5file_class()
125
+ self.h5f = file(self.name)
126
+
127
+ # @property_depends_on( 'block_size, ind_low, ind_high' )
128
+ def _get_indices(self):
129
+ try:
130
+ return range(self.fftfreq().shape[0]) # [ self.ind_low: self.ind_high ]
131
+ except IndexError:
132
+ return range(0)
133
+
134
+ @property_depends_on('digest')
135
+ def _get_numchannels(self):
136
+ try:
137
+ attrs = self.h5f.get_data_by_reference('MetaData/ArrayAttributes')
138
+ return self.h5f.get_node_attribute(attrs, 'microphoneCount')
139
+ except IndexError:
140
+ return 0
141
+
142
+ @property_depends_on('digest')
143
+ def _get_csm(self):
144
+ """Loads cross spectral matrix from file."""
145
+ csmre = self.h5f.get_data_by_reference('/CsmData/csmReal')[:].transpose((2, 0, 1))
146
+ csmim = self.h5f.get_data_by_reference('/CsmData/csmImaginary')[:].transpose((2, 0, 1))
147
+ csmdatagroup = self.h5f.get_data_by_reference('/CsmData')
148
+ sign = self.h5f.get_node_attribute(csmdatagroup, 'fftSign')
149
+ return csmre + sign * 1j * csmim
150
+
151
+ def fftfreq(self):
152
+ """Return the Discrete Fourier Transform sample frequencies.
153
+
154
+ Returns
155
+ -------
156
+ ndarray
157
+ Array of length *block_size/2+1* containing the sample frequencies.
158
+ """
159
+ return array(self.h5f.get_data_by_reference('/CsmData/binCenterFrequenciesHz')[:].flatten(), dtype=float)
160
+
161
+
162
+ class MicAIAABenchmark(MicGeom):
163
+ """Provides the geometric arrangement of microphones in the array.
164
+
165
+ In contrast to standard Acoular microphone geometries, the AIAA
166
+ benchmark format includes the array geometry as metadata in the
167
+ file containing the measurement data.
168
+ """
169
+
170
+ #: Name of the .h5-file from wich to read the data.
171
+ from_file = File(filter=['*.h5'], desc='name of the h5 file containing the microphone geometry')
172
+
173
+ @on_trait_change('basename')
174
+ def import_mpos(self):
175
+ """Import the microphone positions from .h5 file.
176
+ Called when :attr:`basename` changes.
177
+ """
178
+ if not path.isfile(self.from_file):
179
+ # no file there
180
+ raise OSError('No such file: %s' % self.from_file)
181
+
182
+ file = _get_h5file_class()
183
+ h5f = file(self.from_file, mode='r')
184
+ self.mpos_tot = h5f.get_data_by_reference('MetaData/ArrayAttributes/microphonePositionsM')[:].swapaxes(0, 1)
185
+ h5f.close()