acoular 24.10__py3-none-any.whl → 25.1__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/__init__.py +5 -2
- acoular/aiaa/__init__.py +12 -0
- acoular/{tools → aiaa}/aiaa.py +23 -28
- acoular/base.py +75 -55
- acoular/calib.py +129 -34
- acoular/configuration.py +11 -9
- acoular/demo/__init__.py +1 -0
- acoular/demo/acoular_demo.py +29 -16
- acoular/deprecation.py +85 -0
- acoular/environments.py +31 -19
- acoular/fastFuncs.py +90 -84
- acoular/fbeamform.py +203 -411
- acoular/fprocess.py +49 -41
- acoular/grids.py +101 -143
- acoular/h5cache.py +29 -40
- acoular/h5files.py +2 -6
- acoular/microphones.py +50 -59
- acoular/process.py +366 -59
- acoular/sdinput.py +23 -20
- acoular/signals.py +116 -109
- acoular/sources.py +201 -240
- acoular/spectra.py +53 -229
- acoular/tbeamform.py +79 -202
- acoular/tfastfuncs.py +21 -21
- acoular/tools/__init__.py +2 -8
- acoular/tools/helpers.py +216 -2
- acoular/tools/metrics.py +4 -4
- acoular/tools/utils.py +106 -200
- acoular/tprocess.py +348 -309
- acoular/traitsviews.py +10 -10
- acoular/trajectory.py +7 -10
- acoular/version.py +2 -2
- {acoular-24.10.dist-info → acoular-25.1.dist-info}/METADATA +38 -17
- acoular-25.1.dist-info/RECORD +56 -0
- {acoular-24.10.dist-info → acoular-25.1.dist-info}/WHEEL +1 -1
- acoular-24.10.dist-info/RECORD +0 -54
- {acoular-24.10.dist-info → acoular-25.1.dist-info}/licenses/AUTHORS.rst +0 -0
- {acoular-24.10.dist-info → acoular-25.1.dist-info}/licenses/LICENSE +0 -0
acoular/grids.py
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"""
|
|
25
25
|
|
|
26
26
|
# imports from other packages
|
|
27
|
-
|
|
28
|
-
from
|
|
27
|
+
import xml.dom.minidom
|
|
28
|
+
from abc import abstractmethod
|
|
29
29
|
|
|
30
30
|
from numpy import (
|
|
31
31
|
absolute,
|
|
@@ -45,7 +45,7 @@ from numpy import (
|
|
|
45
45
|
ones,
|
|
46
46
|
ones_like,
|
|
47
47
|
s_,
|
|
48
|
-
sum,
|
|
48
|
+
sum, # noqa: A004
|
|
49
49
|
tile,
|
|
50
50
|
unique,
|
|
51
51
|
where,
|
|
@@ -56,24 +56,28 @@ from scipy.linalg import norm
|
|
|
56
56
|
# from matplotlib.path import Path
|
|
57
57
|
from scipy.spatial import Delaunay
|
|
58
58
|
from traits.api import (
|
|
59
|
+
ABCHasStrictTraits,
|
|
59
60
|
Bool,
|
|
60
61
|
CArray,
|
|
61
62
|
File,
|
|
62
63
|
Float,
|
|
63
|
-
HasPrivateTraits,
|
|
64
64
|
Instance,
|
|
65
65
|
Int,
|
|
66
66
|
List,
|
|
67
67
|
Property,
|
|
68
|
+
Str,
|
|
68
69
|
Tuple,
|
|
69
70
|
Union,
|
|
70
71
|
cached_property,
|
|
72
|
+
observe,
|
|
71
73
|
on_trait_change,
|
|
72
74
|
property_depends_on,
|
|
73
75
|
)
|
|
74
76
|
from traits.trait_errors import TraitError
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
# acoular imports
|
|
79
|
+
from .deprecation import deprecated_alias
|
|
80
|
+
from .internal import digest, ldigest
|
|
77
81
|
|
|
78
82
|
|
|
79
83
|
def in_hull(p, hull, border=True, tol=0):
|
|
@@ -252,12 +256,13 @@ class Polygon:
|
|
|
252
256
|
return mindst
|
|
253
257
|
|
|
254
258
|
|
|
255
|
-
|
|
259
|
+
@deprecated_alias({'gpos': 'pos'})
|
|
260
|
+
class Grid(ABCHasStrictTraits):
|
|
256
261
|
"""Virtual base class for grid geometries.
|
|
257
262
|
|
|
258
263
|
Defines the common interface for all grid classes and
|
|
259
264
|
provides facilities to query grid properties and related data. This class
|
|
260
|
-
may be used as a base for specialized grid
|
|
265
|
+
may be used as a base for specialized grid implementations. It should not
|
|
261
266
|
be used directly as it contains no real functionality.
|
|
262
267
|
"""
|
|
263
268
|
|
|
@@ -271,45 +276,32 @@ class Grid(HasPrivateTraits):
|
|
|
271
276
|
|
|
272
277
|
#: Grid positions as (3, :attr:`size`) array of floats, without invalid
|
|
273
278
|
#: microphones; readonly.
|
|
274
|
-
|
|
279
|
+
pos = Property(desc='x, y, z positions of grid points')
|
|
275
280
|
|
|
276
281
|
# internal identifier
|
|
277
282
|
digest = Property
|
|
278
283
|
|
|
284
|
+
@abstractmethod
|
|
279
285
|
def _get_digest(self):
|
|
280
|
-
|
|
286
|
+
"""Returns the digest of the grid object."""
|
|
281
287
|
|
|
282
288
|
# 'digest' is a placeholder for other properties in derived classes,
|
|
283
289
|
# necessary to trigger the depends on mechanism
|
|
284
|
-
@property_depends_on('digest')
|
|
290
|
+
@property_depends_on(['digest'])
|
|
291
|
+
@abstractmethod
|
|
285
292
|
def _get_size(self):
|
|
286
|
-
|
|
293
|
+
"""Returns the number of grid points."""
|
|
287
294
|
|
|
288
295
|
# 'digest' is a placeholder for other properties in derived classes
|
|
289
|
-
@property_depends_on('digest')
|
|
296
|
+
@property_depends_on(['digest'])
|
|
297
|
+
@abstractmethod
|
|
290
298
|
def _get_shape(self):
|
|
291
|
-
|
|
299
|
+
"""Returns the shape of the grid as a Tuple."""
|
|
292
300
|
|
|
293
|
-
@property_depends_on('digest')
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
def pos(self):
|
|
298
|
-
"""Calculates grid co-ordinates.
|
|
299
|
-
Deprecated; use :attr:`gpos` attribute instead.
|
|
300
|
-
The :meth:`pos` method will be removed in version 25.01.
|
|
301
|
-
|
|
302
|
-
Returns
|
|
303
|
-
-------
|
|
304
|
-
array of floats of shape (3, :attr:`size`)
|
|
305
|
-
The grid point x, y, z-coordinates in one array.
|
|
306
|
-
|
|
307
|
-
"""
|
|
308
|
-
msg = (
|
|
309
|
-
"The 'pos' method is deprecated and will be removed in version 25.01. " "Use the 'gpos' attribute instead."
|
|
310
|
-
)
|
|
311
|
-
warn(msg, DeprecationWarning, stacklevel=2)
|
|
312
|
-
return self.gpos # array([[0.], [0.], [0.]])
|
|
301
|
+
@property_depends_on(['digest'])
|
|
302
|
+
@abstractmethod
|
|
303
|
+
def _get_pos(self):
|
|
304
|
+
"""Returns the grid positions as (3, size) array of floats."""
|
|
313
305
|
|
|
314
306
|
def subdomain(self, sector):
|
|
315
307
|
"""Queries the indices for a subdomain in the grid.
|
|
@@ -328,13 +320,14 @@ class Grid(HasPrivateTraits):
|
|
|
328
320
|
an array with the same shape as the grid.
|
|
329
321
|
|
|
330
322
|
"""
|
|
331
|
-
xpos = self.
|
|
323
|
+
xpos = self.pos
|
|
332
324
|
# construct grid-shaped array with "True" entries where sector is
|
|
333
325
|
xyi = sector.contains(xpos).reshape(self.shape)
|
|
334
326
|
# return indices of "True" entries
|
|
335
327
|
return where(xyi)
|
|
336
328
|
|
|
337
329
|
|
|
330
|
+
@deprecated_alias({'gpos': 'pos'}, read_only=True)
|
|
338
331
|
class RectGrid(Grid):
|
|
339
332
|
"""Provides a cartesian 2D grid for the beamforming results.
|
|
340
333
|
|
|
@@ -372,22 +365,22 @@ class RectGrid(Grid):
|
|
|
372
365
|
depends_on=['x_min', 'x_max', 'y_min', 'y_max', 'z', 'increment'],
|
|
373
366
|
)
|
|
374
367
|
|
|
375
|
-
@property_depends_on('nxsteps, nysteps')
|
|
368
|
+
@property_depends_on(['nxsteps', 'nysteps'])
|
|
376
369
|
def _get_size(self):
|
|
377
370
|
return self.nxsteps * self.nysteps
|
|
378
371
|
|
|
379
|
-
@property_depends_on('nxsteps, nysteps')
|
|
372
|
+
@property_depends_on(['nxsteps', 'nysteps'])
|
|
380
373
|
def _get_shape(self):
|
|
381
374
|
return (self.nxsteps, self.nysteps)
|
|
382
375
|
|
|
383
|
-
@property_depends_on('x_min, x_max, increment')
|
|
376
|
+
@property_depends_on(['x_min', 'x_max', 'increment'])
|
|
384
377
|
def _get_nxsteps(self):
|
|
385
378
|
i = abs(self.increment)
|
|
386
379
|
if i != 0:
|
|
387
380
|
return int(round((abs(self.x_max - self.x_min) + i) / i))
|
|
388
381
|
return 1
|
|
389
382
|
|
|
390
|
-
@property_depends_on('y_min, y_max, increment')
|
|
383
|
+
@property_depends_on(['y_min', 'y_max', 'increment'])
|
|
391
384
|
def _get_nysteps(self):
|
|
392
385
|
i = abs(self.increment)
|
|
393
386
|
if i != 0:
|
|
@@ -398,8 +391,8 @@ class RectGrid(Grid):
|
|
|
398
391
|
def _get_digest(self):
|
|
399
392
|
return digest(self)
|
|
400
393
|
|
|
401
|
-
@property_depends_on('x_min, x_max, y_min, y_max, increment')
|
|
402
|
-
def
|
|
394
|
+
@property_depends_on(['x_min', 'x_max', 'y_min', 'y_max', 'increment'])
|
|
395
|
+
def _get_pos(self):
|
|
403
396
|
"""Calculates grid co-ordinates.
|
|
404
397
|
|
|
405
398
|
Returns
|
|
@@ -456,7 +449,7 @@ class RectGrid(Grid):
|
|
|
456
449
|
x1, y1, x2, y2, ... : float
|
|
457
450
|
If three parameters are given, then a circular sector is assumed
|
|
458
451
|
that is given by its center (x1, y1) and the radius x2.
|
|
459
|
-
If four
|
|
452
|
+
If four parameters are given, then a rectangular sector is
|
|
460
453
|
assumed that is given by two corners (x1, y1) and (x2, y2).
|
|
461
454
|
If more parameters are given, the subdomain is assumed to have
|
|
462
455
|
polygonial shape with corners at (x_n, y_n).
|
|
@@ -469,7 +462,7 @@ class RectGrid(Grid):
|
|
|
469
462
|
|
|
470
463
|
"""
|
|
471
464
|
if len(r) == 3: # only 3 values given -> use x,y,radius method
|
|
472
|
-
xpos = self.
|
|
465
|
+
xpos = self.pos
|
|
473
466
|
xis = []
|
|
474
467
|
yis = []
|
|
475
468
|
dr2 = (xpos[0, :] - r[0]) ** 2 + (xpos[1, :] - r[1]) ** 2
|
|
@@ -486,7 +479,7 @@ class RectGrid(Grid):
|
|
|
486
479
|
xi1, yi1 = self.index(min(r[0], r[2]), min(r[1], r[3]))
|
|
487
480
|
xi2, yi2 = self.index(max(r[0], r[2]), max(r[1], r[3]))
|
|
488
481
|
return s_[xi1 : xi2 + 1], s_[yi1 : yi2 + 1]
|
|
489
|
-
xpos = self.
|
|
482
|
+
xpos = self.pos
|
|
490
483
|
xis = []
|
|
491
484
|
yis = []
|
|
492
485
|
# replaced matplotlib Path by numpy
|
|
@@ -563,53 +556,34 @@ class RectGrid3D(RectGrid):
|
|
|
563
556
|
else:
|
|
564
557
|
raise (TraitError(args=self, name='increment', info='Float or CArray(3,)', value=increment))
|
|
565
558
|
|
|
566
|
-
# Respective increments in x,y, and z-direction (in m).
|
|
567
|
-
# Deprecated: Use :attr:`~RectGrid.increment` for this functionality
|
|
568
|
-
increment3D = Property(desc='3D step sizes') # noqa N815
|
|
569
|
-
|
|
570
|
-
def _get_increment3D(self): # noqa N802
|
|
571
|
-
msg = "Using 'increment3D' is deprecated and will be removed in version 25.01." "Use 'increment' instead."
|
|
572
|
-
warn(msg, DeprecationWarning, stacklevel=2)
|
|
573
|
-
if isscalar(self._increment):
|
|
574
|
-
return array([self._increment, self._increment, self._increment])
|
|
575
|
-
return self._increment
|
|
576
|
-
|
|
577
|
-
def _set_increment3D(self, inc): # noqa N802
|
|
578
|
-
msg = "Using 'increment3D' is deprecated and will be removed in version 25.01." "Use 'increment' instead."
|
|
579
|
-
warn(msg, DeprecationWarning, stacklevel=2)
|
|
580
|
-
if not isscalar(inc) and len(inc) == 3:
|
|
581
|
-
self._increment = array(inc, dtype=float)
|
|
582
|
-
else:
|
|
583
|
-
raise (TraitError(args=self, name='increment3D', info='CArray(3,)', value=inc))
|
|
584
|
-
|
|
585
559
|
# internal identifier
|
|
586
560
|
digest = Property(
|
|
587
561
|
depends_on=['x_min', 'x_max', 'y_min', 'y_max', 'z_min', 'z_max', '_increment'],
|
|
588
562
|
)
|
|
589
563
|
|
|
590
|
-
@property_depends_on('nxsteps, nysteps, nzsteps')
|
|
564
|
+
@property_depends_on(['nxsteps', 'nysteps', 'nzsteps'])
|
|
591
565
|
def _get_size(self):
|
|
592
566
|
return self.nxsteps * self.nysteps * self.nzsteps
|
|
593
567
|
|
|
594
|
-
@property_depends_on('nxsteps, nysteps, nzsteps')
|
|
568
|
+
@property_depends_on(['nxsteps', 'nysteps', 'nzsteps'])
|
|
595
569
|
def _get_shape(self):
|
|
596
570
|
return (self.nxsteps, self.nysteps, self.nzsteps)
|
|
597
571
|
|
|
598
|
-
@property_depends_on('x_min, x_max, _increment')
|
|
572
|
+
@property_depends_on(['x_min', 'x_max', '_increment'])
|
|
599
573
|
def _get_nxsteps(self):
|
|
600
574
|
i = abs(self.increment) if isscalar(self.increment) else abs(self.increment[0])
|
|
601
575
|
if i != 0:
|
|
602
576
|
return int(round((abs(self.x_max - self.x_min) + i) / i))
|
|
603
577
|
return 1
|
|
604
578
|
|
|
605
|
-
@property_depends_on('y_min, y_max, _increment')
|
|
579
|
+
@property_depends_on(['y_min', 'y_max', '_increment'])
|
|
606
580
|
def _get_nysteps(self):
|
|
607
581
|
i = abs(self.increment) if isscalar(self.increment) else abs(self.increment[1])
|
|
608
582
|
if i != 0:
|
|
609
583
|
return int(round((abs(self.y_max - self.y_min) + i) / i))
|
|
610
584
|
return 1
|
|
611
585
|
|
|
612
|
-
@property_depends_on('z_min, z_max, _increment')
|
|
586
|
+
@property_depends_on(['z_min', 'z_max', '_increment'])
|
|
613
587
|
def _get_nzsteps(self):
|
|
614
588
|
i = abs(self.increment) if isscalar(self.increment) else abs(self.increment[2])
|
|
615
589
|
if i != 0:
|
|
@@ -617,7 +591,7 @@ class RectGrid3D(RectGrid):
|
|
|
617
591
|
return 1
|
|
618
592
|
|
|
619
593
|
@property_depends_on('digest')
|
|
620
|
-
def
|
|
594
|
+
def _get_pos(self):
|
|
621
595
|
"""Calculates grid co-ordinates.
|
|
622
596
|
|
|
623
597
|
Returns
|
|
@@ -698,25 +672,19 @@ class RectGrid3D(RectGrid):
|
|
|
698
672
|
return s_[xi1 : xi2 + 1], s_[yi1 : yi2 + 1], s_[zi1 : zi2 + 1]
|
|
699
673
|
|
|
700
674
|
|
|
675
|
+
@deprecated_alias({'from_file': 'file', 'gpos_file': 'pos'})
|
|
701
676
|
class ImportGrid(Grid):
|
|
702
677
|
"""Loads a 3D grid from xml file."""
|
|
703
678
|
|
|
704
|
-
#: Name of the .xml-file from
|
|
705
|
-
|
|
679
|
+
#: Name of the .xml-file from which to read the data.
|
|
680
|
+
file = File(filter=['*.xml'], exists=True, desc='name of the xml file to import')
|
|
706
681
|
|
|
707
|
-
|
|
682
|
+
_gpos = CArray(dtype=float, desc='x, y, z position of all Grid Points')
|
|
708
683
|
|
|
709
|
-
|
|
710
|
-
basename = Property(depends_on='from_file', desc='basename of xml file')
|
|
684
|
+
subgrids = CArray(desc='names of subgrids for each point')
|
|
711
685
|
|
|
712
686
|
# internal identifier
|
|
713
|
-
digest = Property(
|
|
714
|
-
depends_on=['from_file'],
|
|
715
|
-
)
|
|
716
|
-
|
|
717
|
-
@cached_property
|
|
718
|
-
def _get_basename(self):
|
|
719
|
-
return path.splitext(path.basename(self.from_file))[0]
|
|
687
|
+
digest = Property(depends_on=['_gpos'])
|
|
720
688
|
|
|
721
689
|
@cached_property
|
|
722
690
|
def _get_digest(self):
|
|
@@ -724,42 +692,36 @@ class ImportGrid(Grid):
|
|
|
724
692
|
|
|
725
693
|
# 'digest' is a placeholder for other properties in derived classes,
|
|
726
694
|
# necessary to trigger the depends on mechanism
|
|
727
|
-
@property_depends_on('
|
|
695
|
+
@property_depends_on(['_gpos'])
|
|
728
696
|
def _get_size(self):
|
|
729
|
-
return self.
|
|
697
|
+
return self.pos.shape[-1]
|
|
730
698
|
|
|
731
699
|
# 'digest' is a placeholder for other properties in derived classes
|
|
732
|
-
@property_depends_on('
|
|
700
|
+
@property_depends_on(['_gpos'])
|
|
733
701
|
def _get_shape(self):
|
|
734
|
-
return (self.
|
|
702
|
+
return (self.pos.shape[-1],)
|
|
735
703
|
|
|
736
|
-
@property_depends_on('
|
|
737
|
-
def
|
|
738
|
-
return self.
|
|
704
|
+
@property_depends_on(['_gpos'])
|
|
705
|
+
def _get_pos(self):
|
|
706
|
+
return self._gpos
|
|
739
707
|
|
|
740
|
-
|
|
708
|
+
def _set_pos(self, pos):
|
|
709
|
+
self._gpos = pos
|
|
741
710
|
|
|
742
|
-
@on_trait_change('
|
|
711
|
+
@on_trait_change('file')
|
|
743
712
|
def import_gpos(self):
|
|
744
|
-
"""Import the the grid point locations from .xml file.
|
|
745
|
-
|
|
746
|
-
"""
|
|
747
|
-
if not path.isfile(self.from_file):
|
|
748
|
-
# no file there
|
|
749
|
-
self.gpos_file = array([], 'd')
|
|
750
|
-
return
|
|
751
|
-
import xml.dom.minidom
|
|
752
|
-
|
|
753
|
-
doc = xml.dom.minidom.parse(self.from_file)
|
|
713
|
+
"""Import the the grid point locations from .xml file when :attr:`file` changes."""
|
|
714
|
+
doc = xml.dom.minidom.parse(self.file)
|
|
754
715
|
names = []
|
|
755
716
|
xyz = []
|
|
756
717
|
for el in doc.getElementsByTagName('pos'):
|
|
757
718
|
names.append(el.getAttribute('subgrid'))
|
|
758
719
|
xyz.append([float(el.getAttribute(a)) for a in 'xyz'])
|
|
759
|
-
self.
|
|
720
|
+
self._gpos = array(xyz, 'd').swapaxes(0, 1)
|
|
760
721
|
self.subgrids = array(names)
|
|
761
722
|
|
|
762
723
|
|
|
724
|
+
@deprecated_alias({'gpos': 'pos', 'numpoints': 'num_points'}, read_only=['gpos'])
|
|
763
725
|
class LineGrid(Grid):
|
|
764
726
|
"""Class for Line grid geometries."""
|
|
765
727
|
|
|
@@ -773,7 +735,7 @@ class LineGrid(Grid):
|
|
|
773
735
|
length = Float(1, desc='length of the line source')
|
|
774
736
|
|
|
775
737
|
#:number of grid points.
|
|
776
|
-
|
|
738
|
+
num_points = Int(1, desc='length of the line source')
|
|
777
739
|
|
|
778
740
|
#: Overall number of grid points. Readonly; is set automatically when
|
|
779
741
|
#: other grid defining properties are set
|
|
@@ -781,10 +743,10 @@ class LineGrid(Grid):
|
|
|
781
743
|
|
|
782
744
|
#: Grid positions as (3, :attr:`size`) array of floats, without invalid
|
|
783
745
|
#: microphones; readonly.
|
|
784
|
-
|
|
746
|
+
pos = Property(desc='x, y, z positions of grid points')
|
|
785
747
|
|
|
786
748
|
digest = Property(
|
|
787
|
-
depends_on=['loc', 'direction', 'length', '
|
|
749
|
+
depends_on=['loc', 'direction', 'length', 'num_points', 'size'],
|
|
788
750
|
)
|
|
789
751
|
|
|
790
752
|
@cached_property
|
|
@@ -793,26 +755,27 @@ class LineGrid(Grid):
|
|
|
793
755
|
|
|
794
756
|
# 'digest' is a placeholder for other properties in derived classes,
|
|
795
757
|
# necessary to trigger the depends on mechanism
|
|
796
|
-
@property_depends_on('
|
|
758
|
+
@property_depends_on(['num_points'])
|
|
797
759
|
def _get_size(self):
|
|
798
|
-
return self.
|
|
760
|
+
return self.pos.shape[-1]
|
|
799
761
|
|
|
800
762
|
# 'digest' is a placeholder for other properties in derived classes
|
|
801
|
-
@property_depends_on('
|
|
763
|
+
@property_depends_on(['num_points'])
|
|
802
764
|
def _get_shape(self):
|
|
803
|
-
return self.
|
|
765
|
+
return self.pos.shape[-1]
|
|
804
766
|
|
|
805
|
-
@property_depends_on('
|
|
806
|
-
def
|
|
807
|
-
dist = self.length / (self.
|
|
767
|
+
@property_depends_on(['num_points', 'length', 'direction', 'loc'])
|
|
768
|
+
def _get_pos(self):
|
|
769
|
+
dist = self.length / (self.num_points - 1)
|
|
808
770
|
loc = array(self.loc, dtype=float).reshape((3, 1))
|
|
809
771
|
direc_n = array(self.direction) / norm(self.direction)
|
|
810
|
-
pos = zeros((self.
|
|
811
|
-
for s in range(self.
|
|
772
|
+
pos = zeros((self.num_points, 3))
|
|
773
|
+
for s in range(self.num_points):
|
|
812
774
|
pos[s] = loc.T + direc_n * dist * s
|
|
813
775
|
return pos.T
|
|
814
776
|
|
|
815
777
|
|
|
778
|
+
@deprecated_alias({'gpos': 'pos'}, read_only=True)
|
|
816
779
|
class MergeGrid(Grid):
|
|
817
780
|
"""Base class for merging different grid geometries."""
|
|
818
781
|
|
|
@@ -821,7 +784,7 @@ class MergeGrid(Grid):
|
|
|
821
784
|
#: other grid defining properties are set
|
|
822
785
|
grids = List(desc='list of grids')
|
|
823
786
|
|
|
824
|
-
grid_digest =
|
|
787
|
+
grid_digest = Str(desc='digest of the merged grids')
|
|
825
788
|
|
|
826
789
|
subgrids = Property(desc='names of subgrids for each point')
|
|
827
790
|
|
|
@@ -834,46 +797,41 @@ class MergeGrid(Grid):
|
|
|
834
797
|
def _get_digest(self):
|
|
835
798
|
return digest(self)
|
|
836
799
|
|
|
837
|
-
@
|
|
838
|
-
def
|
|
839
|
-
|
|
840
|
-
for grid in self.grids:
|
|
841
|
-
griddigest.append(grid.digest)
|
|
842
|
-
return griddigest
|
|
800
|
+
@observe('grids.items.digest')
|
|
801
|
+
def _set_sourcesdigest(self, event): # noqa ARG002
|
|
802
|
+
self.grid_digest = ldigest(self.grids)
|
|
843
803
|
|
|
844
804
|
# 'digest' is a placeholder for other properties in derived classes,
|
|
845
805
|
# necessary to trigger the depends on mechanism
|
|
846
|
-
@property_depends_on('digest')
|
|
806
|
+
@property_depends_on(['digest'])
|
|
847
807
|
def _get_size(self):
|
|
848
|
-
return self.
|
|
808
|
+
return self.pos.shape[-1]
|
|
849
809
|
|
|
850
810
|
# 'digest' is a placeholder for other properties in derived classes
|
|
851
|
-
@property_depends_on('digest')
|
|
811
|
+
@property_depends_on(['digest'])
|
|
852
812
|
def _get_shape(self):
|
|
853
|
-
return self.
|
|
813
|
+
return self.pos.shape[-1]
|
|
854
814
|
|
|
855
|
-
@property_depends_on('digest')
|
|
815
|
+
@property_depends_on(['digest'])
|
|
856
816
|
def _get_subgrids(self):
|
|
857
817
|
subgrids = zeros((1, 0), dtype=str)
|
|
858
818
|
for grid in self.grids:
|
|
859
819
|
subgrids = append(subgrids, tile(grid.__class__.__name__ + grid.digest, grid.size))
|
|
860
820
|
return subgrids[:, newaxis].T
|
|
861
821
|
|
|
862
|
-
@property_depends_on('digest')
|
|
863
|
-
def
|
|
822
|
+
@property_depends_on(['digest'])
|
|
823
|
+
def _get_pos(self):
|
|
864
824
|
bpos = zeros((3, 0))
|
|
865
|
-
# subgrids = zeros((1,0))
|
|
866
825
|
for grid in self.grids:
|
|
867
|
-
bpos = append(bpos, grid.
|
|
868
|
-
# subgrids = append(subgrids,str(grid))
|
|
826
|
+
bpos = append(bpos, grid.pos, axis=1)
|
|
869
827
|
return unique(bpos, axis=1)
|
|
870
828
|
|
|
871
829
|
|
|
872
|
-
class Sector(
|
|
830
|
+
class Sector(ABCHasStrictTraits):
|
|
873
831
|
"""Base class for all sector types.
|
|
874
832
|
|
|
875
833
|
Defines the common interface for all tbdsector classes. This class
|
|
876
|
-
may be used as a base for diverse sector
|
|
834
|
+
may be used as a base for diverse sector implementations. If used
|
|
877
835
|
directly, it implements a sector encompassing the whole grid.
|
|
878
836
|
"""
|
|
879
837
|
|
|
@@ -902,7 +860,7 @@ class SingleSector(Sector):
|
|
|
902
860
|
"""Base class for single sector types.
|
|
903
861
|
|
|
904
862
|
Defines the common interface for all single sector classes. This class
|
|
905
|
-
may be used as a base for diverse single sector
|
|
863
|
+
may be used as a base for diverse single sector implementations. If used
|
|
906
864
|
directly, it implements a sector encompassing the whole grid.
|
|
907
865
|
"""
|
|
908
866
|
|
|
@@ -912,14 +870,15 @@ class SingleSector(Sector):
|
|
|
912
870
|
#: Absolute tolerance for sector border
|
|
913
871
|
abs_tol = Float(1e-12, desc='absolute tolerance for sector border')
|
|
914
872
|
|
|
915
|
-
#: Boolean flag, if 'True' (default), the nearest grid point is returned if
|
|
873
|
+
#: Boolean flag, if 'True' (default), the nearest grid point is returned if None is inside the
|
|
874
|
+
#: sector.
|
|
916
875
|
default_nearest = Bool(True, desc='return nearest grid point to center of none inside sector')
|
|
917
876
|
|
|
918
877
|
|
|
919
878
|
class RectSector(SingleSector):
|
|
920
879
|
"""Class for defining a rectangular sector.
|
|
921
880
|
|
|
922
|
-
Can be used for 2D Grids for
|
|
881
|
+
Can be used for 2D Grids for defining a rectangular sector or
|
|
923
882
|
for 3D grids for a rectangular cylinder sector parallel to the z-axis.
|
|
924
883
|
"""
|
|
925
884
|
|
|
@@ -990,7 +949,7 @@ class RectSector(SingleSector):
|
|
|
990
949
|
class RectSector3D(RectSector):
|
|
991
950
|
"""Class for defining a cuboid sector.
|
|
992
951
|
|
|
993
|
-
Can be used for 3D Grids for
|
|
952
|
+
Can be used for 3D Grids for defining a cuboid sector.
|
|
994
953
|
"""
|
|
995
954
|
|
|
996
955
|
#: The lower z position of the cuboid
|
|
@@ -1060,7 +1019,7 @@ class RectSector3D(RectSector):
|
|
|
1060
1019
|
class CircSector(SingleSector):
|
|
1061
1020
|
"""Class for defining a circular sector.
|
|
1062
1021
|
|
|
1063
|
-
Can be used for 2D Grids for
|
|
1022
|
+
Can be used for 2D Grids for defining a circular sector or
|
|
1064
1023
|
for 3D grids for a cylindrical sector parallel to the z-axis.
|
|
1065
1024
|
"""
|
|
1066
1025
|
|
|
@@ -1096,7 +1055,7 @@ class CircSector(SingleSector):
|
|
|
1096
1055
|
# which points are in the circle?
|
|
1097
1056
|
inds = dr2 - self.r**2 < self.abs_tol if self.include_border else dr2 - self.r**2 < -self.abs_tol
|
|
1098
1057
|
|
|
1099
|
-
# if there's no
|
|
1058
|
+
# if there's no point inside
|
|
1100
1059
|
if ~inds.any() and self.default_nearest:
|
|
1101
1060
|
inds[argmin(dr2)] = True
|
|
1102
1061
|
|
|
@@ -1106,17 +1065,16 @@ class CircSector(SingleSector):
|
|
|
1106
1065
|
class PolySector(SingleSector):
|
|
1107
1066
|
"""Class for defining a polygon sector.
|
|
1108
1067
|
|
|
1109
|
-
Can be used for 2D Grids for
|
|
1068
|
+
Can be used for 2D Grids for defining a polygon sector.
|
|
1110
1069
|
"""
|
|
1111
1070
|
|
|
1112
1071
|
# x1, y1, x2, y2, ... xn, yn :
|
|
1113
1072
|
edges = List(Float)
|
|
1114
1073
|
|
|
1115
1074
|
def contains(self, pos):
|
|
1116
|
-
"""Queries whether the coordinates in a given array lie within the
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
is returned if :attr:`~Sector.default_nearest` is True.
|
|
1075
|
+
"""Queries whether the coordinates in a given array lie within the polygon sector. If no
|
|
1076
|
+
coordinate is inside, the nearest one to the rectangle center is returned if
|
|
1077
|
+
:attr:`~Sector.default_nearest` is True.
|
|
1120
1078
|
|
|
1121
1079
|
Parameters
|
|
1122
1080
|
----------
|
|
@@ -1146,7 +1104,7 @@ class PolySector(SingleSector):
|
|
|
1146
1104
|
class ConvexSector(SingleSector):
|
|
1147
1105
|
"""Class for defining a convex hull sector.
|
|
1148
1106
|
|
|
1149
|
-
Can be used for 2D Grids for
|
|
1107
|
+
Can be used for 2D Grids for defining a convex hull sector.
|
|
1150
1108
|
"""
|
|
1151
1109
|
|
|
1152
1110
|
# x1, y1, x2, y2, ... xn, yn :
|