acoular 24.5__py3-none-any.whl → 24.10__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/tbeamform.py CHANGED
@@ -25,7 +25,6 @@ from numpy import (
25
25
  argmax,
26
26
  array,
27
27
  ceil,
28
- concatenate,
29
28
  dot,
30
29
  empty,
31
30
  float32,
@@ -44,17 +43,18 @@ from numpy import (
44
43
  where,
45
44
  zeros,
46
45
  )
47
- from numpy.linalg import norm
46
+ from scipy.linalg import norm
48
47
  from traits.api import Bool, CArray, Delegate, Enum, Float, Instance, Int, List, Property, Range, Trait, cached_property
49
48
  from traits.trait_errors import TraitError
50
49
 
50
+ from .base import SamplesGenerator, TimeOut
51
51
  from .fbeamform import SteeringVector
52
52
  from .grids import RectGrid
53
53
 
54
54
  # acoular imports
55
55
  from .internal import digest
56
- from .tfastfuncs import _delayandsum4, _delayandsum5, _delays, _steer_I, _steer_II, _steer_III, _steer_IV
57
- from .tprocess import TimeInOut
56
+ from .tfastfuncs import _delayandsum4, _delayandsum5, _delays
57
+ from .tools.utils import SamplesBuffer
58
58
  from .trajectory import Trajectory
59
59
 
60
60
 
@@ -92,11 +92,14 @@ def const_power_weight(bf):
92
92
  possible_weights = {'none': None, 'power': const_power_weight}
93
93
 
94
94
 
95
- class BeamformerTime(TimeInOut):
95
+ class BeamformerTime(TimeOut):
96
96
  """Provides a basic time domain beamformer with time signal output
97
97
  for a spatially fixed grid.
98
98
  """
99
99
 
100
+ #: Data source; :class:`~acoular.base.SamplesGenerator` or derived object.
101
+ source = Instance(SamplesGenerator)
102
+
100
103
  # Instance of :class:`~acoular.fbeamform.SteeringVector` or its derived classes
101
104
  # that contains information about the steering vector. This is a private trait.
102
105
  # Do not set this directly, use `steer` trait instead.
@@ -115,9 +118,14 @@ class BeamformerTime(TimeInOut):
115
118
  self._steer_obj = steer
116
119
  elif steer in ('true level', 'true location', 'classic', 'inverse'):
117
120
  # Type of steering vectors, see also :ref:`Sarradj, 2012<Sarradj2012>`.
121
+ msg = (
122
+ "Deprecated use of 'steer' trait. Please use the 'steer' with an object of class "
123
+ "'SteeringVector'. Using a string to specify the steer type will be removed in "
124
+ 'version 25.01.'
125
+ )
118
126
  warn(
119
- "Deprecated use of 'steer' trait. Please use object of class 'SteeringVector' in the future.",
120
- Warning,
127
+ msg,
128
+ DeprecationWarning,
121
129
  stacklevel=2,
122
130
  )
123
131
  self._steer_obj.steer_type = steer
@@ -135,7 +143,11 @@ class BeamformerTime(TimeInOut):
135
143
  return self._steer_obj.env
136
144
 
137
145
  def _set_env(self, env):
138
- warn("Deprecated use of 'env' trait. ", Warning, stacklevel=2)
146
+ msg = (
147
+ "Deprecated use of 'env' trait. Please use the 'steer' trait with an object of class "
148
+ "'SteeringVector'. The 'env' trait will be removed in version 25.01."
149
+ )
150
+ warn(msg, DeprecationWarning, stacklevel=2)
139
151
  self._steer_obj.env = env
140
152
 
141
153
  # The speed of sound.
@@ -147,7 +159,11 @@ class BeamformerTime(TimeInOut):
147
159
  return self._steer_obj.env.c
148
160
 
149
161
  def _set_c(self, c):
150
- warn("Deprecated use of 'c' trait. ", Warning, stacklevel=2)
162
+ msg = (
163
+ "Deprecated use of 'c' trait. Please use the 'steer' trait with an object of class "
164
+ "'SteeringVector'. The 'c' trait will be removed in version 25.01."
165
+ )
166
+ warn(msg, DeprecationWarning, stacklevel=2)
151
167
  self._steer_obj.env.c = c
152
168
 
153
169
  # :class:`~acoular.grids.Grid`-derived object that provides the grid locations.
@@ -159,7 +175,11 @@ class BeamformerTime(TimeInOut):
159
175
  return self._steer_obj.grid
160
176
 
161
177
  def _set_grid(self, grid):
162
- warn("Deprecated use of 'grid' trait. ", Warning, stacklevel=2)
178
+ msg = (
179
+ "Deprecated use of 'grid' trait. Please use the 'steer' trait with an object of class "
180
+ "'SteeringVector'. The 'grid' trait will be removed in version 25.01."
181
+ )
182
+ warn(msg, DeprecationWarning, stacklevel=2)
163
183
  self._steer_obj.grid = grid
164
184
 
165
185
  # :class:`~acoular.microphones.MicGeom` object that provides the microphone locations.
@@ -171,7 +191,11 @@ class BeamformerTime(TimeInOut):
171
191
  return self._steer_obj.mics
172
192
 
173
193
  def _set_mpos(self, mpos):
174
- warn("Deprecated use of 'mpos' trait. ", Warning, stacklevel=2)
194
+ msg = (
195
+ "Deprecated use of 'mpos' trait. Please use the 'steer' trait with an object of class "
196
+ "'SteeringVector' which has an attribute 'mics'. The 'mpos' trait will be removed in version 25.01."
197
+ )
198
+ warn(msg, DeprecationWarning, stacklevel=2)
175
199
  self._steer_obj.mics = mpos
176
200
 
177
201
  # Sound travel distances from microphone array center to grid points (r0)
@@ -181,11 +205,21 @@ class BeamformerTime(TimeInOut):
181
205
  r0 = Property()
182
206
 
183
207
  def _get_r0(self):
208
+ msg = (
209
+ "Deprecated use of 'r0' trait. Please use the 'steer' trait with an object of class "
210
+ "'SteeringVector'. The 'r0' trait will be removed in version 25.01."
211
+ )
212
+ warn(msg, DeprecationWarning, stacklevel=2)
184
213
  return self._steer_obj.r0
185
214
 
186
215
  rm = Property()
187
216
 
188
217
  def _get_rm(self):
218
+ msg = (
219
+ "Deprecated use of 'rm' trait. Please use the 'steer' trait with an object of class "
220
+ "'SteeringVector'. The 'rm' trait will be removed in version 25.01."
221
+ )
222
+ warn(msg, DeprecationWarning, stacklevel=2)
189
223
  return self._steer_obj.rm
190
224
 
191
225
  # --- End of backwards compatibility traits --------------------------------------
@@ -197,12 +231,6 @@ class BeamformerTime(TimeInOut):
197
231
  weights = Trait('none', possible_weights, desc='spatial weighting function')
198
232
  # (from timedomain.possible_weights)
199
233
 
200
- # buffer with microphone time signals used for processing. Internal use
201
- buffer = CArray(desc='buffer containing microphone signals')
202
-
203
- # index indicating position of current processing sample. Internal use.
204
- bufferIndex = Int(desc='index indicating position in buffer')
205
-
206
234
  # internal identifier
207
235
  digest = Property(
208
236
  depends_on=['_steer_obj.digest', 'source.digest', 'weights', '__class__'],
@@ -215,40 +243,28 @@ class BeamformerTime(TimeInOut):
215
243
  def _get_weights(self):
216
244
  return self.weights_(self)[newaxis] if self.weights_ else 1.0
217
245
 
218
- def _fill_buffer(self, num):
219
- """Generator that fills the signal buffer."""
220
- weights = self._get_weights()
221
- for block in self.source.result(num):
222
- block *= weights
223
- ns = block.shape[0]
224
- bufferSize = self.buffer.shape[0]
225
- self.buffer[0 : (bufferSize - ns)] = self.buffer[-(bufferSize - ns) :]
226
- self.buffer[-ns:, :] = block
227
- self.bufferIndex -= ns
228
- yield
229
-
230
246
  def result(self, num=2048):
231
- """Python generator that yields the *squared* deconvolved beamformer
232
- output with optional removal of autocorrelation block-wise.
247
+ """Python generator that yields the time-domain beamformer output.
248
+
249
+ The output time signal starts for source signals that were emitted from
250
+ the :class:`~acoular.grids.Grid` at `t=0`.
233
251
 
234
252
  Parameters
235
253
  ----------
236
- num : integer, defaults to 2048
254
+ num : int
237
255
  This parameter defines the size of the blocks to be yielded
238
- (i.e. the number of samples per block).
239
-
240
- Returns
241
- -------
242
- Samples in blocks of shape \
243
- (num, :attr:`~BeamformerTime.numchannels`).
244
- :attr:`~BeamformerTime.numchannels` is usually very \
245
- large (number of grid points).
246
- The last block may be shorter than num. \
247
- The output starts for signals that were emitted
248
- from the grid at `t=0`.
249
-
256
+ (i.e. the number of samples per block). Defaults to 2048.
257
+
258
+ Yields
259
+ ------
260
+ numpy.ndarray
261
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
262
+ :attr:`~BeamformerTime.numchannels` is usually very \
263
+ large (number of grid points).
264
+ The last block returned by the generator may be shorter than num.
250
265
  """
251
266
  # initialize values
267
+ steer_func = self.steer._steer_funcs_time[self.steer.steer_type]
252
268
  fdtype = float64
253
269
  idtype = int64
254
270
  numMics = self.steer.mics.num_mics
@@ -258,33 +274,29 @@ class BeamformerTime(TimeInOut):
258
274
  # delays = empty((1,self.grid.size,numMics),dtype=fdtype)
259
275
  d_index = empty((1, self.grid.size, numMics), dtype=idtype)
260
276
  d_interp2 = empty((1, self.grid.size, numMics), dtype=fdtype)
261
- _steer_III(self.rm[newaxis, :, :], self.r0[newaxis, :], amp)
262
- _delays(self.rm[newaxis, :, :], c, d_interp2, d_index)
277
+ steer_func(self.steer.rm[newaxis, :, :], self.steer.r0[newaxis, :], amp)
278
+ _delays(self.steer.rm[newaxis, :, :], c, d_interp2, d_index)
263
279
  amp.shape = amp.shape[1:]
264
280
  # delays.shape = delays.shape[1:]
265
281
  d_index.shape = d_index.shape[1:]
266
282
  d_interp2.shape = d_interp2.shape[1:]
267
- maxdelay = int((self.rm / c).max()) + 2 + num # +2 because of interpolation
268
- initialNumberOfBlocks = int(ceil(maxdelay / num))
269
- bufferSize = initialNumberOfBlocks * num
270
- self.buffer = zeros((bufferSize, numMics), dtype=float)
271
- self.bufferIndex = bufferSize # indexing current time sample in buffer
272
- fill_buffer_generator = self._fill_buffer(num)
273
- for _ in range(initialNumberOfBlocks):
274
- next(fill_buffer_generator)
283
+ max_sample_delay = int((self.steer.rm / c).max()) + 2
284
+ weights = self._get_weights()
275
285
 
276
- # start processing
277
- flag = True
278
- while flag:
279
- samplesleft = self.buffer.shape[0] - self.bufferIndex
280
- if samplesleft - maxdelay <= 0:
281
- num += samplesleft - maxdelay
282
- maxdelay += samplesleft - maxdelay
286
+ buffer = SamplesBuffer(
287
+ source=self.source,
288
+ length=int(ceil((num + max_sample_delay) / num)) * num,
289
+ result_num=num + max_sample_delay,
290
+ shift_index_by='num',
291
+ dtype=fdtype,
292
+ )
293
+ for p_res in buffer.result(num):
294
+ p_res *= weights
295
+ if p_res.shape[0] < buffer.result_num: # last block shorter
296
+ num = p_res.shape[0] - max_sample_delay
283
297
  n_index = arange(0, num + 1)[:, newaxis]
284
- flag = False
285
298
  # init step
286
- p_res = array(self.buffer[self.bufferIndex : self.bufferIndex + maxdelay, :])
287
- Phi, autopow = self.delay_and_sum(num, p_res, d_interp2, d_index, amp)
299
+ Phi, autopow = self._delay_and_sum(num, p_res, d_interp2, d_index, amp)
288
300
  if 'Cleant' not in self.__class__.__name__:
289
301
  if 'Sq' not in self.__class__.__name__:
290
302
  yield Phi[:num]
@@ -293,6 +305,7 @@ class BeamformerTime(TimeInOut):
293
305
  else:
294
306
  yield Phi[:num] ** 2
295
307
  else:
308
+ p_res_copy = p_res.copy()
296
309
  Gamma = zeros(Phi.shape)
297
310
  Gamma_autopow = zeros(Phi.shape)
298
311
  J = 0
@@ -304,12 +317,12 @@ class BeamformerTime(TimeInOut):
304
317
  t_float = d_interp2[imax] + d_index[imax] + n_index
305
318
  t_ind = t_float.astype(int64)
306
319
  for m in range(numMics):
307
- p_res[t_ind[: num + 1, m], m] -= self.damp * interp(
320
+ p_res_copy[t_ind[: num + 1, m], m] -= self.damp * interp(
308
321
  t_ind[: num + 1, m],
309
322
  t_float[:num, m],
310
- Phi[:num, imax] * self.r0[imax] / self.rm[imax, m],
323
+ Phi[:num, imax] * self.steer.r0[imax] / self.steer.rm[imax, m],
311
324
  )
312
- nextPhi, nextAutopow = self.delay_and_sum(num, p_res, d_interp2, d_index, amp)
325
+ nextPhi, nextAutopow = self._delay_and_sum(num, p_res_copy, d_interp2, d_index, amp)
313
326
  if self.r_diag:
314
327
  pownextPhi = (nextPhi[:num] ** 2 - nextAutopow).sum(0).clip(min=0)
315
328
  else:
@@ -330,13 +343,8 @@ class BeamformerTime(TimeInOut):
330
343
  yield Gamma[:num] ** 2 - (self.damp**2) * Gamma_autopow[:num]
331
344
  else:
332
345
  yield Gamma[:num] ** 2
333
- self.bufferIndex += num
334
- try:
335
- next(fill_buffer_generator)
336
- except:
337
- pass
338
346
 
339
- def delay_and_sum(self, num, p_res, d_interp2, d_index, amp):
347
+ def _delay_and_sum(self, num, p_res, d_interp2, d_index, amp):
340
348
  """Standard delay-and-sum method."""
341
349
  result = empty((num, self.grid.size), dtype=float) # output array
342
350
  autopow = empty((num, self.grid.size), dtype=float) # output array
@@ -362,6 +370,28 @@ class BeamformerTimeSq(BeamformerTime):
362
370
  def _get_digest(self):
363
371
  return digest(self)
364
372
 
373
+ def result(self, num=2048):
374
+ """Python generator that yields the **squared** time-domain beamformer output.
375
+
376
+ The squared output time signal starts for source signals that were emitted from
377
+ the :class:`~acoular.grids.Grid` at `t=0`.
378
+
379
+ Parameters
380
+ ----------
381
+ num : int
382
+ This parameter defines the size of the blocks to be yielded
383
+ (i.e. the number of samples per block). Defaults to 2048.
384
+
385
+ Yields
386
+ ------
387
+ numpy.ndarray
388
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
389
+ :attr:`~BeamformerTime.numchannels` is usually very \
390
+ large (number of grid points).
391
+ The last block returned by the generator may be shorter than num.
392
+ """
393
+ return super().result(num)
394
+
365
395
 
366
396
  class BeamformerTimeTraj(BeamformerTime):
367
397
  """Provides a basic time domain beamformer with time signal output
@@ -399,7 +429,7 @@ class BeamformerTimeTraj(BeamformerTime):
399
429
  def _get_digest(self):
400
430
  return digest(self)
401
431
 
402
- def get_moving_gpos(self):
432
+ def _get_moving_gpos(self):
403
433
  """Python generator that yields the moving grid coordinates samplewise."""
404
434
 
405
435
  def cross(a, b):
@@ -409,7 +439,7 @@ class BeamformerTimeTraj(BeamformerTime):
409
439
  return array([a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]])
410
440
 
411
441
  start_t = 0.0
412
- gpos = self.grid.pos()
442
+ gpos = self.grid.gpos
413
443
  trajg = self.trajectory.traj(start_t, delta_t=1 / self.source.sample_freq)
414
444
  trajg1 = self.trajectory.traj(start_t, delta_t=1 / self.source.sample_freq, der=1)
415
445
  rflag = (self.rvec == 0).all() # flag translation vs. rotation
@@ -431,7 +461,7 @@ class BeamformerTimeTraj(BeamformerTime):
431
461
  # print(loc[:])
432
462
  yield tpos
433
463
 
434
- def get_macostheta(self, g1, tpos, rm):
464
+ def _get_macostheta(self, g1, tpos, rm):
435
465
  vvec = array(g1) # velocity vector
436
466
  ma = norm(vvec) / self.steer.env.c # machnumber
437
467
  fdv = (vvec / sqrt((vvec * vvec).sum()))[:, newaxis] # unit vecor velocity
@@ -444,30 +474,25 @@ class BeamformerTimeTraj(BeamformerTime):
444
474
  return self.steer.ref # full((self.steer.grid.size,), self.steer.ref)
445
475
  return self.env._r(tpos)
446
476
 
447
- def increase_buffer(self, num):
448
- ar = zeros((num, self.steer.mics.num_mics), dtype=self.buffer.dtype)
449
- self.buffer = concatenate((ar, self.buffer), axis=0)
450
- self.bufferIndex += num
451
-
452
477
  def result(self, num=2048):
453
- """Python generator that yields the deconvolved output block-wise.
478
+ """Python generator that yields the time-domain beamformer output.
479
+
480
+ The output time signal starts for source signals that were emitted from
481
+ the :class:`~acoular.grids.Grid` at `t=0`.
454
482
 
455
483
  Parameters
456
484
  ----------
457
- num : integer, defaults to 2048
485
+ num : int
458
486
  This parameter defines the size of the blocks to be yielded
459
- (i.e. the number of samples per block).
460
-
461
- Returns
462
- -------
463
- Samples in blocks of shape \
464
- (num, :attr:`~BeamformerTime.numchannels`).
465
- :attr:`~BeamformerTime.numchannels` is usually very \
466
- large (number of grid points).
467
- The last block may be shorter than num. \
468
- The output starts for signals that were emitted
469
- from the grid at `t=0`.
470
-
487
+ (i.e. the number of samples per block). Defaults to 2048.
488
+
489
+ Yields
490
+ ------
491
+ numpy.ndarray
492
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
493
+ :attr:`~BeamformerTime.numchannels` is usually very \
494
+ large (number of grid points).
495
+ The last block returned by the generator may be shorter than num.
471
496
  """
472
497
  # initialize values
473
498
  if self.precision == 64:
@@ -489,25 +514,17 @@ class BeamformerTimeTraj(BeamformerTime):
489
514
  d_index = empty((num, self.grid.size, numMics), dtype=idtype)
490
515
  d_interp2 = empty((num, self.grid.size, numMics), dtype=fdtype)
491
516
  blockr0 = empty((num, self.grid.size), dtype=fdtype)
492
- self.buffer = zeros((2 * num, numMics), dtype=fdtype)
493
- self.bufferIndex = self.buffer.shape[0]
494
- movgpos = self.get_moving_gpos() # create moving grid pos generator
517
+ movgpos = self._get_moving_gpos() # create moving grid pos generator
495
518
  movgspeed = self.trajectory.traj(0.0, delta_t=1 / self.source.sample_freq, der=1)
496
- fill_buffer_generator = self._fill_buffer(num)
497
- for _i in range(2):
498
- next(fill_buffer_generator)
519
+ weights = self._get_weights()
499
520
 
500
521
  # preliminary implementation of different steering vectors
501
- steer_func = {
502
- 'classic': _steer_I,
503
- 'inverse': _steer_II,
504
- 'true level': _steer_III,
505
- 'true location': _steer_IV,
506
- }[self.steer.steer_type]
522
+ steer_func = self.steer._steer_funcs_time[self.steer.steer_type]
507
523
 
508
524
  # start processing
509
525
  flag = True
510
- dflag = True # data is available
526
+ buffer = SamplesBuffer(source=self.source, length=num * 2, shift_index_by='num', dtype=fdtype)
527
+ buffered_result = buffer.result(num)
511
528
  while flag:
512
529
  for i in range(num):
513
530
  tpos = next(movgpos).astype(fdtype)
@@ -516,30 +533,27 @@ class BeamformerTimeTraj(BeamformerTime):
516
533
  blockrm[i, :, :] = rm
517
534
  if self.conv_amp:
518
535
  ht = next(movgspeed)
519
- blockrmconv[i, :, :] = rm * (1 - self.get_macostheta(ht, tpos, rm)) ** 2
536
+ blockrmconv[i, :, :] = rm * (1 - self._get_macostheta(ht, tpos, rm)) ** 2
520
537
  if self.conv_amp:
521
538
  steer_func(blockrmconv, blockr0, amp)
522
539
  else:
523
540
  steer_func(blockrm, blockr0, amp)
524
541
  _delays(blockrm, c, d_interp2, d_index)
525
- # _modf(delays, d_interp2, d_index)
526
- maxdelay = (d_index.max((1, 2)) + arange(0, num)).max() + 2 # + because of interpolation
527
- # increase buffer size because of greater delays
528
- while maxdelay > self.buffer.shape[0] and dflag:
529
- self.increase_buffer(num)
530
- try:
531
- next(fill_buffer_generator)
532
- except:
533
- dflag = False
534
- samplesleft = self.buffer.shape[0] - self.bufferIndex
535
- # last block may be shorter
536
- if samplesleft - maxdelay <= 0:
537
- num = sum((d_index.max((1, 2)) + 1 + arange(0, num)) < samplesleft)
542
+ max_sample_delay = (d_index.max((1, 2)) + 2).max() # + because of interpolation
543
+ buffer.result_num = num + max_sample_delay
544
+
545
+ try:
546
+ time_block = next(buffered_result)
547
+ time_block *= weights
548
+ except StopIteration:
549
+ break
550
+ if time_block.shape[0] < buffer.result_num: # last block shorter
551
+ num = sum((d_index.max((1, 2)) + 1 + arange(0, num)) < time_block.shape[0])
538
552
  n_index = arange(num, dtype=idtype)[:, newaxis]
539
553
  flag = False
540
554
  # init step
541
- p_res = self.buffer[self.bufferIndex : self.bufferIndex + maxdelay, :].copy()
542
- Phi, autopow = self.delay_and_sum(num, p_res, d_interp2, d_index, amp)
555
+ p_res = time_block.copy()
556
+ Phi, autopow = self._delay_and_sum(num, p_res, d_interp2, d_index, amp)
543
557
  if 'Cleant' not in self.__class__.__name__:
544
558
  if 'Sq' not in self.__class__.__name__:
545
559
  yield Phi[:num]
@@ -578,7 +592,7 @@ class BeamformerTimeTraj(BeamformerTime):
578
592
  t_float[:num, m],
579
593
  h / blockrm1[:num, imax, m],
580
594
  )
581
- nextPhi, nextAutopow = self.delay_and_sum(num, p_res, d_interp2, d_index, amp)
595
+ nextPhi, nextAutopow = self._delay_and_sum(num, p_res, d_interp2, d_index, amp)
582
596
  if self.r_diag:
583
597
  pownextPhi = (nextPhi[:num] * nextPhi[:num] - nextAutopow).sum(0).clip(min=0)
584
598
  else:
@@ -599,13 +613,8 @@ class BeamformerTimeTraj(BeamformerTime):
599
613
  yield Gamma[:num] ** 2 - (self.damp**2) * Gamma_autopow[:num]
600
614
  else:
601
615
  yield Gamma[:num] ** 2
602
- self.bufferIndex += num
603
- try:
604
- next(fill_buffer_generator)
605
- except:
606
- dflag = False
607
616
 
608
- def delay_and_sum(self, num, p_res, d_interp2, d_index, amp):
617
+ def _delay_and_sum(self, num, p_res, d_interp2, d_index, amp):
609
618
  """Standard delay-and-sum method."""
610
619
  fdtype = float64 if self.precision == 64 else float32
611
620
  result = empty((num, self.grid.size), dtype=fdtype) # output array
@@ -639,12 +648,34 @@ class BeamformerTimeSqTraj(BeamformerTimeSq, BeamformerTimeTraj):
639
648
  def _get_digest(self):
640
649
  return digest(self)
641
650
 
651
+ def result(self, num=2048):
652
+ """Python generator that yields the **squared** time-domain beamformer output.
653
+
654
+ The squared output time signal starts for source signals that were emitted from
655
+ the :class:`~acoular.grids.Grid` at `t=0`.
656
+
657
+ Parameters
658
+ ----------
659
+ num : int
660
+ This parameter defines the size of the blocks to be yielded
661
+ (i.e. the number of samples per block). Defaults to 2048.
662
+
663
+ Yields
664
+ ------
665
+ numpy.ndarray
666
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
667
+ :attr:`~BeamformerTime.numchannels` is usually very \
668
+ large (number of grid points).
669
+ The last block returned by the generator may be shorter than num.
670
+ """
671
+ return super().result(num)
672
+
642
673
 
643
674
  class BeamformerCleant(BeamformerTime):
644
- """CLEANT deconvolution method, see :ref:`Cousson et al., 2019<Cousson2019>`.
675
+ """CLEANT deconvolution method.
645
676
 
646
677
  An implementation of the CLEAN method in time domain. This class can only
647
- be used for static sources.
678
+ be used for static sources. See :cite:`Cousson2019` for details.
648
679
  """
649
680
 
650
681
  #: Boolean flag, always False
@@ -666,13 +697,34 @@ class BeamformerCleant(BeamformerTime):
666
697
  def _get_digest(self):
667
698
  return digest(self)
668
699
 
700
+ def result(self, num=2048):
701
+ """Python generator that yields the deconvolved time-domain beamformer output.
702
+
703
+ The output starts for signals that were emitted from the :class:`~acoular.grids.Grid` at `t=0`.
704
+
705
+ Parameters
706
+ ----------
707
+ num : int
708
+ This parameter defines the size of the blocks to be yielded
709
+ (i.e. the number of samples per block). Defaults to 2048.
710
+
711
+ Yields
712
+ ------
713
+ numpy.ndarray
714
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
715
+ :attr:`~BeamformerTime.numchannels` is usually very \
716
+ large (number of grid points).
717
+ The last block returned by the generator may be shorter than num.
718
+ """
719
+ return super().result(num)
720
+
669
721
 
670
722
  class BeamformerCleantSq(BeamformerCleant):
671
- """CLEANT deconvolution method, see :ref:`Cousson et al., 2019<Cousson2019>`
672
- with optional removal of autocorrelation.
723
+ """CLEANT deconvolution method with optional removal of autocorrelation.
673
724
 
674
725
  An implementation of the CLEAN method in time domain. This class can only
675
- be used for static sources.
726
+ be used for static sources. See :cite:`Cousson2019` for details on the method
727
+ and :cite:`Kujawski2020` for details on the autocorrelation removal.
676
728
  """
677
729
 
678
730
  #: Boolean flag, if 'True' (default), the main diagonal is removed before beamforming.
@@ -687,12 +739,35 @@ class BeamformerCleantSq(BeamformerCleant):
687
739
  def _get_digest(self):
688
740
  return digest(self)
689
741
 
742
+ def result(self, num=2048):
743
+ """Python generator that yields the *squared* deconvolved time-domain beamformer output.
744
+
745
+ The output starts for signals that were emitted from the :class:`~acoular.grids.Grid` at `t=0`.
746
+ Per default, block-wise removal of autocorrelation is performed, which can be turned of by setting
747
+ :attr:`r_diag` to `False`.
748
+
749
+ Parameters
750
+ ----------
751
+ num : int
752
+ This parameter defines the size of the blocks to be yielded
753
+ (i.e. the number of samples per block). Defaults to 2048.
754
+
755
+ Yields
756
+ ------
757
+ numpy.ndarray
758
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
759
+ :attr:`~BeamformerTime.numchannels` is usually very \
760
+ large (number of grid points).
761
+ The last block returned by the generator may be shorter than num.
762
+ """
763
+ return super().result(num)
764
+
690
765
 
691
766
  class BeamformerCleantTraj(BeamformerCleant, BeamformerTimeTraj):
692
- """CLEANT deconvolution method, see :ref:`Cousson et al., 2019<Cousson2019>`.
767
+ """CLEANT deconvolution method.
693
768
 
694
769
  An implementation of the CLEAN method in time domain for moving sources
695
- with known trajectory.
770
+ with known trajectory. See :cite:`Cousson2019` for details.
696
771
  """
697
772
 
698
773
  #: Floating point and integer precision
@@ -718,13 +793,34 @@ class BeamformerCleantTraj(BeamformerCleant, BeamformerTimeTraj):
718
793
  def _get_digest(self):
719
794
  return digest(self)
720
795
 
796
+ def result(self, num=2048):
797
+ """Python generator that yields the deconvolved time-domain beamformer output.
798
+
799
+ The output starts for signals that were emitted from the :class:`~acoular.grids.Grid` at `t=0`.
800
+
801
+ Parameters
802
+ ----------
803
+ num : int
804
+ This parameter defines the size of the blocks to be yielded
805
+ (i.e. the number of samples per block). Defaults to 2048.
806
+
807
+ Yields
808
+ ------
809
+ numpy.ndarray
810
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
811
+ :attr:`~BeamformerTime.numchannels` is usually very \
812
+ large (number of grid points).
813
+ The last block returned by the generator may be shorter than num.
814
+ """
815
+ return super().result(num)
816
+
721
817
 
722
818
  class BeamformerCleantSqTraj(BeamformerCleantTraj, BeamformerTimeSq):
723
- """CLEANT deconvolution method, see :ref:`Cousson et al., 2019<Cousson2019>`
724
- with optional removal of autocorrelation.
819
+ """CLEANT deconvolution method with optional removal of autocorrelation.
725
820
 
726
821
  An implementation of the CLEAN method in time domain for moving sources
727
- with known trajectory.
822
+ with known trajectory. See :cite:`Cousson2019` for details on the method and
823
+ :cite:`Kujawski2020` for details on the autocorrelation removal.
728
824
  """
729
825
 
730
826
  #: Boolean flag, if 'True' (default), the main diagonal is removed before beamforming.
@@ -751,10 +847,36 @@ class BeamformerCleantSqTraj(BeamformerCleantTraj, BeamformerTimeSq):
751
847
  def _get_digest(self):
752
848
  return digest(self)
753
849
 
850
+ def result(self, num=2048):
851
+ """Python generator that yields the *squared* deconvolved time-domain beamformer output.
852
+
853
+ The output starts for signals that were emitted from the :class:`~acoular.grids.Grid` at `t=0`.
854
+ Per default, block-wise removal of autocorrelation is performed, which can be turned of by setting
855
+ :attr:`r_diag` to `False`.
754
856
 
755
- class IntegratorSectorTime(TimeInOut):
857
+ Parameters
858
+ ----------
859
+ num : int
860
+ This parameter defines the size of the blocks to be yielded
861
+ (i.e. the number of samples per block). Defaults to 2048.
862
+
863
+ Yields
864
+ ------
865
+ numpy.ndarray
866
+ Samples in blocks of shape (num, :attr:`~BeamformerTime.numchannels`).
867
+ :attr:`~BeamformerTime.numchannels` is usually very \
868
+ large (number of grid points).
869
+ The last block returned by the generator may be shorter than num.
870
+ """
871
+ return super().result(num)
872
+
873
+
874
+ class IntegratorSectorTime(TimeOut):
756
875
  """Provides an Integrator in the time domain."""
757
876
 
877
+ #: Data source; :class:`~acoular.base.SamplesGenerator` or derived object.
878
+ source = Instance(SamplesGenerator)
879
+
758
880
  #: :class:`~acoular.grids.RectGrid` object that provides the grid locations.
759
881
  grid = Trait(RectGrid, desc='beamforming grid')
760
882