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