acoular 24.3__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 (139) 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 +1460 -1404
  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-24.3.dist-info → acoular-24.5.dist-info}/METADATA +45 -46
  31. acoular-24.5.dist-info/RECORD +50 -0
  32. {acoular-24.3.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/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.5.dist-info}/licenses/AUTHORS.rst +0 -0
acoular/signals.py CHANGED
@@ -1,8 +1,6 @@
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
- #------------------------------------------------------------------------------
3
+ # ------------------------------------------------------------------------------
6
4
  """Implements signal generators for the simulation of acoustic sources.
7
5
 
8
6
  .. autosummary::
@@ -18,352 +16,342 @@
18
16
  """
19
17
 
20
18
  # imports from other packages
21
- from __future__ import print_function, division
22
- from numpy import pi, arange, sin, sqrt, repeat, tile, log, zeros, array
19
+ from warnings import warn
20
+
21
+ from numpy import arange, array, log, pi, repeat, sin, sqrt, tile, zeros
23
22
  from numpy.random import RandomState
24
- from traits.api import HasPrivateTraits, Trait, Float, Int, CLong, Bool, \
25
- Property, cached_property, Delegate, CArray
26
23
  from scipy.signal import resample, sosfilt, tf2sos
27
- from warnings import warn
24
+ from traits.api import Bool, CArray, CLong, Delegate, Float, HasPrivateTraits, Int, Property, Trait, cached_property
25
+
26
+ from .internal import digest
28
27
 
29
28
  # acoular imports
30
29
  from .tprocess import SamplesGenerator
31
- from .internal import digest
32
30
 
33
- class SignalGenerator( HasPrivateTraits ):
34
- """
35
- Virtual base class for a simple one-channel signal generator.
36
-
31
+
32
+ class SignalGenerator(HasPrivateTraits):
33
+ """Virtual base class for a simple one-channel signal generator.
34
+
37
35
  Defines the common interface for all SignalGenerator classes. This class
38
36
  may be used as a base for specialized SignalGenerator implementations. It
39
37
  should not be used directly as it contains no real functionality.
40
38
  """
41
39
 
42
40
  #: RMS amplitude of source signal (for point source: in 1 m distance).
43
- rms = Float(1.0,
44
- desc="rms amplitude")
45
-
41
+ rms = Float(1.0, desc='rms amplitude')
42
+
46
43
  #: Sampling frequency of the signal.
47
- sample_freq = Float(1.0,
48
- desc="sampling frequency")
49
-
44
+ sample_freq = Float(1.0, desc='sampling frequency')
45
+
50
46
  #: Number of samples to generate.
51
47
  numsamples = CLong
52
-
48
+
53
49
  # internal identifier
54
50
  digest = Property
55
51
 
56
- def _get_digest( self ):
52
+ def _get_digest(self):
57
53
  return ''
58
54
 
59
55
  def signal(self):
60
- """
61
- Deliver the signal.
62
- """
63
- pass
64
-
56
+ """Deliver the signal."""
57
+
65
58
  def usignal(self, factor):
66
- """
67
- Delivers the signal resampled with a multiple of the sampling freq.
68
-
59
+ """Delivers the signal resampled with a multiple of the sampling freq.
60
+
69
61
  Uses fourier transform method for resampling (from scipy.signal).
70
-
62
+
71
63
  Parameters
72
64
  ----------
73
65
  factor : integer
74
66
  The factor defines how many times the new sampling frequency is
75
67
  larger than :attr:`sample_freq`.
76
-
68
+
77
69
  Returns
78
70
  -------
79
71
  array of floats
80
72
  The resulting signal of length `factor` * :attr:`numsamples`.
73
+
81
74
  """
82
- return resample(self.signal(), factor*self.numsamples)
75
+ return resample(self.signal(), factor * self.numsamples)
83
76
 
84
- class WNoiseGenerator( SignalGenerator ):
85
- """
86
- White noise signal generator.
87
- """
77
+
78
+ class WNoiseGenerator(SignalGenerator):
79
+ """White noise signal generator."""
88
80
 
89
81
  #: Seed for random number generator, defaults to 0.
90
82
  #: This parameter should be set differently for different instances
91
83
  #: to guarantee statistically independent (non-correlated) outputs.
92
- seed = Int(0,
93
- desc="random seed value")
84
+ seed = Int(0, desc='random seed value')
94
85
 
95
86
  # internal identifier
96
- digest = Property(
97
- depends_on = ['rms', 'numsamples', \
98
- 'sample_freq', 'seed', '__class__'],
99
- )
100
-
87
+ digest = Property(
88
+ depends_on=['rms', 'numsamples', 'sample_freq', 'seed', '__class__'],
89
+ )
90
+
101
91
  @cached_property
102
- def _get_digest( self ):
92
+ def _get_digest(self):
103
93
  return digest(self)
104
94
 
105
95
  def signal(self):
106
- """
107
- Deliver the signal.
96
+ """Deliver the signal.
108
97
 
109
98
  Returns
110
99
  -------
111
100
  Array of floats
112
101
  The resulting signal as an array of length :attr:`~SignalGenerator.numsamples`.
102
+
113
103
  """
114
104
  rnd_gen = RandomState(self.seed)
115
- return self.rms*rnd_gen.standard_normal(self.numsamples)
116
-
105
+ return self.rms * rnd_gen.standard_normal(self.numsamples)
106
+
107
+
108
+ class PNoiseGenerator(SignalGenerator):
109
+ """Pink noise signal generator.
117
110
 
118
- class PNoiseGenerator( SignalGenerator ):
119
- """
120
- Pink noise signal generator.
121
-
122
111
  Simulation of pink noise is based on the Voss-McCartney algorithm.
123
112
  Ref.:
124
-
113
+
125
114
  * S.J. Orfanidis: Signal Processing (2010), pp. 729-733
126
115
  * online discussion: http://www.firstpr.com.au/dsp/pink-noise/
127
-
128
- The idea is to iteratively add larger-wavelength noise to get 1/f
116
+
117
+ The idea is to iteratively add larger-wavelength noise to get 1/f
129
118
  characteristic.
130
119
  """
131
-
120
+
132
121
  #: Seed for random number generator, defaults to 0.
133
122
  #: This parameter should be set differently for different instances
134
123
  #: to guarantee statistically independent (non-correlated) outputs.
135
- seed = Int(0,
136
- desc="random seed value")
137
-
138
- #: "Octave depth" -- higher values for 1/f spectrum at low frequencies,
124
+ seed = Int(0, desc='random seed value')
125
+
126
+ #: "Octave depth" -- higher values for 1/f spectrum at low frequencies,
139
127
  #: but longer calculation, defaults to 16.
140
- depth = Int(16,
141
- desc="octave depth")
128
+ depth = Int(16, desc='octave depth')
142
129
 
143
130
  # internal identifier
144
- digest = Property(
145
- depends_on = ['rms', 'numsamples', \
146
- 'sample_freq', 'seed', 'depth', '__class__'],
147
- )
148
-
131
+ digest = Property(
132
+ depends_on=['rms', 'numsamples', 'sample_freq', 'seed', 'depth', '__class__'],
133
+ )
134
+
149
135
  @cached_property
150
- def _get_digest( self ):
136
+ def _get_digest(self):
151
137
  return digest(self)
152
138
 
153
139
  def signal(self):
154
140
  nums = self.numsamples
155
141
  depth = self.depth
156
142
  # maximum depth depending on number of samples
157
- max_depth = int( log(nums) / log(2) )
158
-
143
+ max_depth = int(log(nums) / log(2))
144
+
159
145
  if depth > max_depth:
160
146
  depth = max_depth
161
- print("Pink noise filter depth set to maximum possible value of %d." % max_depth)
162
-
147
+ print('Pink noise filter depth set to maximum possible value of %d.' % max_depth)
148
+
163
149
  rnd_gen = RandomState(self.seed)
164
150
  s = rnd_gen.standard_normal(nums)
165
151
  for _ in range(depth):
166
- ind = 2**_-1
167
- lind = nums-ind
168
- dind = 2**(_+1)
169
- s[ind:] += repeat( rnd_gen.standard_normal(nums // dind+1 ), dind)[:lind]
152
+ ind = 2**_ - 1
153
+ lind = nums - ind
154
+ dind = 2 ** (_ + 1)
155
+ s[ind:] += repeat(rnd_gen.standard_normal(nums // dind + 1), dind)[:lind]
170
156
  # divide by sqrt(depth+1.5) to get same overall level as white noise
171
- return self.rms/sqrt(depth+1.5) * s
157
+ return self.rms / sqrt(depth + 1.5) * s
172
158
 
173
159
 
174
160
  class FiltWNoiseGenerator(WNoiseGenerator):
175
- """
176
- Filtered white noise signal following an autoregressive (AR), moving-average
161
+ """Filtered white noise signal following an autoregressive (AR), moving-average
177
162
  (MA) or autoregressive moving-average (ARMA) process.
178
-
179
- The desired frequency response of the filter can be defined by specifying
180
- the filter coefficients :attr:`ar` and :attr:`ma`.
181
- The RMS value specified via the :attr:`rms` attribute belongs to the white noise
182
- signal and differs from the RMS value of the filtered signal.
183
- For numerical stability at high orders, the filter is a combination of second order
184
- sections (sos).
163
+
164
+ The desired frequency response of the filter can be defined by specifying
165
+ the filter coefficients :attr:`ar` and :attr:`ma`.
166
+ The RMS value specified via the :attr:`rms` attribute belongs to the white noise
167
+ signal and differs from the RMS value of the filtered signal.
168
+ For numerical stability at high orders, the filter is a combination of second order
169
+ sections (sos).
185
170
  """
186
171
 
187
- ar = CArray(value=array([]),dtype=float,
188
- desc="autoregressive coefficients (coefficients of the denominator)")
189
-
190
- ma = CArray(value=array([]),dtype=float,
191
- desc="moving-average coefficients (coefficients of the numerator)")
192
-
172
+ ar = CArray(value=array([]), dtype=float, desc='autoregressive coefficients (coefficients of the denominator)')
173
+
174
+ ma = CArray(value=array([]), dtype=float, desc='moving-average coefficients (coefficients of the numerator)')
175
+
193
176
  # internal identifier
194
- digest = Property(
195
- depends_on = [
196
- 'ar', 'ma', 'rms', 'numsamples', \
197
- 'sample_freq', 'seed', '__class__'
198
- ],
199
- )
200
-
177
+ digest = Property(
178
+ depends_on=[
179
+ 'ar',
180
+ 'ma',
181
+ 'rms',
182
+ 'numsamples',
183
+ 'sample_freq',
184
+ 'seed',
185
+ '__class__',
186
+ ],
187
+ )
188
+
201
189
  @cached_property
202
- def _get_digest( self ):
190
+ def _get_digest(self):
203
191
  return digest(self)
204
192
 
205
- def handle_empty_coefficients(self,coefficients):
193
+ def handle_empty_coefficients(self, coefficients):
206
194
  if coefficients.size == 0:
207
195
  return array([1.0])
208
- else:
209
- return coefficients
210
-
196
+ return coefficients
197
+
211
198
  def signal(self):
212
- """
213
- Deliver the signal.
199
+ """Deliver the signal.
214
200
 
215
201
  Returns
216
202
  -------
217
203
  Array of floats
218
204
  The resulting signal as an array of length :attr:`~SignalGenerator.numsamples`.
205
+
219
206
  """
220
207
  rnd_gen = RandomState(self.seed)
221
208
  ma = self.handle_empty_coefficients(self.ma)
222
209
  ar = self.handle_empty_coefficients(self.ar)
223
210
  sos = tf2sos(ma, ar)
224
211
  ntaps = ma.shape[0]
225
- sdelay = round(0.5*(ntaps-1))
226
- wnoise = self.rms*rnd_gen.standard_normal(self.numsamples+sdelay) # create longer signal to compensate delay
212
+ sdelay = round(0.5 * (ntaps - 1))
213
+ wnoise = self.rms * rnd_gen.standard_normal(
214
+ self.numsamples + sdelay,
215
+ ) # create longer signal to compensate delay
227
216
  return sosfilt(sos, x=wnoise)[sdelay:]
228
217
 
229
218
 
230
- class SineGenerator( SignalGenerator ):
231
- """
232
- Sine signal generator with adjustable frequency and phase.
233
- """
219
+ class SineGenerator(SignalGenerator):
220
+ """Sine signal generator with adjustable frequency and phase."""
234
221
 
235
222
  #: Sine wave frequency, float, defaults to 1000.0.
236
- freq = Float(1000.0,
237
- desc="Frequency")
223
+ freq = Float(1000.0, desc='Frequency')
238
224
 
239
225
  #: Sine wave phase (in radians), float, defaults to 0.0.
240
- phase = Float(0.0,
241
- desc="Phase")
226
+ phase = Float(0.0, desc='Phase')
242
227
 
243
228
  # Internal shadow trait for rms/amplitude values.
244
229
  # Do not set directly.
245
230
  _amp = Float(1.0)
246
-
231
+
247
232
  #: RMS of source signal (for point source: in 1 m distance).
248
233
  #: Deprecated. For amplitude use :attr:`amplitude`.
249
234
  rms = Property(desc='rms amplitude')
250
-
235
+
251
236
  def _get_rms(self):
252
- return self._amp/2**0.5
253
-
237
+ return self._amp / 2**0.5
238
+
254
239
  def _set_rms(self, rms):
255
- warn("Up to Acoular 20.02, rms is interpreted as sine amplitude. "
256
- "This has since been corrected (rms now is 1/sqrt(2) of amplitude). "
257
- "Use 'amplitude' trait to directly set the ampltiude.",
258
- Warning, stacklevel = 2)
240
+ warn(
241
+ 'Up to Acoular 20.02, rms is interpreted as sine amplitude. '
242
+ 'This has since been corrected (rms now is 1/sqrt(2) of amplitude). '
243
+ "Use 'amplitude' trait to directly set the ampltiude.",
244
+ Warning,
245
+ stacklevel=2,
246
+ )
259
247
  self._amp = rms * 2**0.5
260
-
261
- #: Amplitude of source signal (for point source: in 1 m distance).
248
+
249
+ #: Amplitude of source signal (for point source: in 1 m distance).
262
250
  #: Defaults to 1.0.
263
251
  amplitude = Property(desc='amplitude')
264
-
252
+
265
253
  def _get_amplitude(self):
266
254
  return self._amp
267
-
255
+
268
256
  def _set_amplitude(self, amp):
269
257
  self._amp = amp
270
-
258
+
271
259
  # internal identifier
272
- digest = Property(
273
- depends_on = ['_amp', 'numsamples', \
274
- 'sample_freq', 'freq', 'phase', '__class__'],
275
- )
276
-
260
+ digest = Property(
261
+ depends_on=['_amp', 'numsamples', 'sample_freq', 'freq', 'phase', '__class__'],
262
+ )
263
+
277
264
  @cached_property
278
- def _get_digest( self ):
265
+ def _get_digest(self):
279
266
  return digest(self)
280
267
 
281
268
  def signal(self):
282
- """
283
- Deliver the signal.
269
+ """Deliver the signal.
284
270
 
285
271
  Returns
286
272
  -------
287
273
  array of floats
288
274
  The resulting signal as an array of length :attr:`~SignalGenerator.numsamples`.
275
+
289
276
  """
290
- t = arange(self.numsamples, dtype=float)/self.sample_freq
291
- return self.amplitude * sin(2*pi*self.freq * t + self.phase)
277
+ t = arange(self.numsamples, dtype=float) / self.sample_freq
278
+ return self.amplitude * sin(2 * pi * self.freq * t + self.phase)
292
279
 
293
280
 
294
- class GenericSignalGenerator( SignalGenerator ):
295
- """
296
- Generate signal from output of :class:`~acoular.tprocess.SamplesGenerator` object.
297
- """
281
+ class GenericSignalGenerator(SignalGenerator):
282
+ """Generate signal from output of :class:`~acoular.tprocess.SamplesGenerator` object."""
283
+
298
284
  #: Data source; :class:`~acoular.tprocess.SamplesGenerator` or derived object.
299
285
  source = Trait(SamplesGenerator)
300
-
286
+
301
287
  #: Sampling frequency of output signal, as given by :attr:`source`.
302
288
  sample_freq = Delegate('source')
303
-
289
+
304
290
  _numsamples = CLong(0)
305
-
291
+
306
292
  #: Number of samples to generate. Is set to source.numsamples by default.
307
293
  numsamples = Property()
308
-
309
- def _get_numsamples( self ):
294
+
295
+ def _get_numsamples(self):
310
296
  if self._numsamples:
311
297
  return self._numsamples
312
- else:
313
- return self.source.numsamples
314
-
315
- def _set_numsamples( self, numsamples ):
298
+ return self.source.numsamples
299
+
300
+ def _set_numsamples(self, numsamples):
316
301
  self._numsamples = numsamples
317
302
 
318
- #: Boolean flag, if 'True' (default), signal track is repeated if requested
303
+ #: Boolean flag, if 'True' (default), signal track is repeated if requested
319
304
  #: :attr:`numsamples` is higher than available sample number
320
305
  loop_signal = Bool(True)
321
-
306
+
322
307
  # internal identifier
323
- digest = Property(
324
- depends_on = ['source.digest', 'loop_signal', 'numsamples', \
325
- 'rms', '__class__'],
326
- )
327
-
308
+ digest = Property(
309
+ depends_on=['source.digest', 'loop_signal', 'numsamples', 'rms', '__class__'],
310
+ )
311
+
328
312
  @cached_property
329
- def _get_digest( self ):
313
+ def _get_digest(self):
330
314
  return digest(self)
331
-
315
+
332
316
  def signal(self):
333
- """
334
- Deliver the signal.
317
+ """Deliver the signal.
335
318
 
336
319
  Returns
337
320
  -------
338
321
  array of floats
339
322
  The resulting signal as an array of length :attr:`~GenericSignalGenerator.numsamples`.
323
+
340
324
  """
341
325
  block = 1024
342
326
  if self.source.numchannels > 1:
343
- warn("Signal source has more than one channel. Only channel 0 will be used for signal.", Warning, stacklevel = 2)
327
+ warn(
328
+ 'Signal source has more than one channel. Only channel 0 will be used for signal.',
329
+ Warning,
330
+ stacklevel=2,
331
+ )
344
332
  nums = self.numsamples
345
333
  track = zeros(nums)
346
-
334
+
347
335
  # iterate through source generator to fill signal track
348
336
  for i, temp in enumerate(self.source.result(block)):
349
- start = block*i
350
- stop = start + len(temp[:,0])
337
+ start = block * i
338
+ stop = start + len(temp[:, 0])
351
339
  if nums > stop:
352
- track[start:stop] = temp[:,0]
353
- else: # exit loop preliminarily if wanted signal samples are reached
354
- track[start:nums] = temp[:nums-start,0]
340
+ track[start:stop] = temp[:, 0]
341
+ else: # exit loop preliminarily if wanted signal samples are reached
342
+ track[start:nums] = temp[: nums - start, 0]
355
343
  break
356
-
344
+
357
345
  # if the signal should be repeated after finishing and there are still samples open
358
346
  if self.loop_signal and (nums > stop):
359
-
360
347
  # fill up empty track with as many full source signals as possible
361
348
  nloops = nums // stop
362
- if nloops>1: track[stop:stop*nloops] = tile(track[:stop], nloops-1)
349
+ if nloops > 1:
350
+ track[stop : stop * nloops] = tile(track[:stop], nloops - 1)
363
351
  # fill up remaining empty track
364
- res = nums % stop # last part of unfinished loop
365
- if res > 0: track[stop*nloops:] = track[:res]
366
-
352
+ res = nums % stop # last part of unfinished loop
353
+ if res > 0:
354
+ track[stop * nloops :] = track[:res]
355
+
367
356
  # The rms value is just an amplification here
368
- return self.rms*track
369
-
357
+ return self.rms * track