acoular 25.4__py3-none-any.whl → 25.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.
acoular/sources.py CHANGED
@@ -45,6 +45,7 @@ from numpy import (
45
45
  mod,
46
46
  newaxis,
47
47
  ones,
48
+ ones_like,
48
49
  pi,
49
50
  real,
50
51
  repeat,
@@ -317,7 +318,7 @@ def get_modes(lOrder, direction, mpos, sourceposition=None): # noqa: N803
317
318
  return modes
318
319
 
319
320
 
320
- @deprecated_alias({'name': 'file'})
321
+ @deprecated_alias({'name': 'file'}, removal_version='25.10')
321
322
  class TimeSamples(SamplesGenerator):
322
323
  """
323
324
  Container for processing time data in ``*.h5`` or NumPy array format.
@@ -746,7 +747,7 @@ class MaskedTimeSamples(TimeSamples):
746
747
  i += num
747
748
 
748
749
 
749
- @deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
750
+ @deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True, removal_version='25.10')
750
751
  class PointSource(SamplesGenerator):
751
752
  """
752
753
  Define a fixed point source emitting a signal, intended for simulations.
@@ -1164,46 +1165,48 @@ class MovingPointSource(PointSource):
1164
1165
  # from the end of the calculated signal.
1165
1166
 
1166
1167
  signal = self.signal.usignal(self.up)
1167
- out = empty((num, self.num_channels))
1168
1168
  # shortcuts and initial values
1169
- m = self.mics
1170
- t = self.start * ones(m.num_mics)
1171
- i = 0
1169
+ num_mics = self.num_channels
1170
+ mpos = self.mics.pos[:, :, newaxis]
1171
+ t = self.start + ones(num_mics)[:, newaxis] * arange(num) / self.sample_freq
1172
1172
  epslim = 0.1 / self.up / self.sample_freq
1173
1173
  c0 = self.env.c
1174
1174
  tr = self.trajectory
1175
1175
  n = self.num_samples
1176
- while n:
1177
- n -= 1
1178
- eps = ones(m.num_mics)
1176
+ while n > 0:
1177
+ eps = ones_like(t) # init discrepancy in time
1179
1178
  te = t.copy() # init emission time = receiving time
1180
1179
  j = 0
1181
1180
  # Newton-Rhapson iteration
1182
1181
  while abs(eps).max() > epslim and j < 100:
1183
- loc = array(tr.location(te))
1184
- rm = loc - m.pos # distance vectors to microphones
1182
+ loc = array(tr.location(te.flatten())).reshape((3, num_mics, -1))
1183
+ rm = loc - mpos # distance vectors to microphones
1185
1184
  rm = sqrt((rm * rm).sum(0)) # absolute distance
1186
1185
  loc /= sqrt((loc * loc).sum(0)) # distance unit vector
1187
- der = array(tr.location(te, der=1))
1186
+ der = array(tr.location(te.flatten(), der=1)).reshape((3, num_mics, -1))
1188
1187
  Mr = (der * loc).sum(0) / c0 # radial Mach number
1189
- eps = (te + rm / c0 - t) / (1 + Mr) # discrepancy in time
1188
+ eps[:] = (te + rm / c0 - t) / (1 + Mr) # discrepancy in time
1190
1189
  te -= eps
1191
1190
  j += 1 # iteration count
1192
- t += 1.0 / self.sample_freq
1191
+ t += num / self.sample_freq
1193
1192
  # emission time relative to start time
1194
1193
  ind = (te - self.start_t + self.start) * self.sample_freq
1195
1194
  if self.conv_amp:
1196
1195
  rm *= (1 - Mr) ** 2
1197
1196
  try:
1198
- out[i] = signal[array(0.5 + ind * self.up, dtype=int64)] / rm
1199
- i += 1
1200
- if i == num:
1201
- yield out
1202
- i = 0
1203
- except IndexError: # if no more samples available from the source
1197
+ ind = array(0.5 + ind * self.up, dtype=int64)
1198
+ out = (signal[ind] / rm).T
1199
+ yield out[:n]
1200
+ except IndexError: # last incomplete frame
1201
+ signal_length = signal.shape[0]
1202
+ # Filter ind to exclude columns containing values greater than signal_length
1203
+ mask = (ind < signal_length).all(axis=0)
1204
+ out = (signal[ind[:, mask]] / rm[:, mask]).T
1205
+ # If out is not empty, yield it
1206
+ if out.size > 0:
1207
+ yield out[:n]
1204
1208
  break
1205
- if i > 0: # if there are still samples to yield
1206
- yield out[:i]
1209
+ n -= num
1207
1210
 
1208
1211
 
1209
1212
  class PointSourceDipole(PointSource):
@@ -1947,7 +1950,7 @@ class MovingLineSource(LineSource, MovingPointSource):
1947
1950
  yield out[:i]
1948
1951
 
1949
1952
 
1950
- @deprecated_alias({'numchannels': 'num_channels'}, read_only=True)
1953
+ @deprecated_alias({'numchannels': 'num_channels'}, read_only=True, removal_version='25.10')
1951
1954
  class UncorrelatedNoiseSource(SamplesGenerator):
1952
1955
  """
1953
1956
  Simulate uncorrelated white or pink noise signals at multiple channels.
@@ -2111,7 +2114,7 @@ class UncorrelatedNoiseSource(SamplesGenerator):
2111
2114
  return
2112
2115
 
2113
2116
 
2114
- @deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True)
2117
+ @deprecated_alias({'numchannels': 'num_channels', 'numsamples': 'num_samples'}, read_only=True, removal_version='25.10')
2115
2118
  class SourceMixer(SamplesGenerator):
2116
2119
  """
2117
2120
  Combine signals from multiple sources by mixing their outputs.
acoular/spectra.py CHANGED
@@ -61,8 +61,9 @@ from .internal import digest
61
61
  from .tools.utils import find_basename
62
62
 
63
63
 
64
- @deprecated_alias({'numchannels': 'num_channels'}, read_only=True)
65
- @deprecated_alias({'time_data': 'source'}, read_only=False)
64
+ @deprecated_alias(
65
+ {'numchannels': 'num_channels', 'time_data': 'source'}, read_only=['numchannels'], removal_version='25.10'
66
+ )
66
67
  class BaseSpectra(ABCHasStrictTraits):
67
68
  """
68
69
  Base class for handling spectral data in Acoular.
acoular/tbeamform.py CHANGED
@@ -174,6 +174,9 @@ class BeamformerTime(TimeOut):
174
174
  p_res *= weights
175
175
  if p_res.shape[0] < buffer.result_num: # last block shorter
176
176
  num = p_res.shape[0] - max_sample_delay
177
+ # exit loop if there is not enough data left to be processed
178
+ if num <= 0:
179
+ break
177
180
  n_index = arange(0, num + 1)[:, newaxis]
178
181
  # init step
179
182
  Phi, autopow = self._delay_and_sum(num, p_res, d_interp2, d_index, amp)
acoular/tools/helpers.py CHANGED
@@ -11,8 +11,10 @@
11
11
  barspectrum
12
12
  bardata
13
13
  c_air
14
+ get_data_file
14
15
  """
15
16
 
17
+ from pathlib import Path
16
18
  from warnings import warn
17
19
 
18
20
  from numpy import (
@@ -401,3 +403,28 @@ def c_air(t, h, p=101325, co2=0.04):
401
403
  + a14 * x_c**2
402
404
  + a15 * x_w * p * x_c
403
405
  )
406
+
407
+
408
+ def get_data_file(file):
409
+ """
410
+ Ensures a file is available locally.
411
+
412
+ If the file does not exist in ``'../data/'`` or the current directory,
413
+ it is downloaded from the Acoular GitHub repository.
414
+
415
+ Returns
416
+ -------
417
+ :class:`pathlib.Path`
418
+ Path to the file.
419
+ """
420
+ data_file = Path('../data') / file
421
+ if not data_file.exists():
422
+ data_file = Path().cwd() / file
423
+ if not data_file.exists():
424
+ import urllib.request
425
+
426
+ url = 'https://github.com/acoular/acoular/raw/master/examples/data/' + file
427
+ urllib.request.urlretrieve(url, data_file)
428
+ print(f'Calibration file location: {data_file}')
429
+
430
+ return data_file