Coverage for kwave/ksensor.py: 62%
39 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-24 11:55 -0700
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-24 11:55 -0700
1from dataclasses import dataclass
2import numpy as np
4from kwave.utils import expand_matrix
7class kSensor(object):
9 def __init__(self, mask=None, record=None):
10 self._mask = mask
11 self.record = record #: cell array of the acoustic parameters to record in the form Recorder
12 # record the time series from the beginning by default
13 self._record_start_index = 1 #: time index at which the sensor should start recording the data specified by sensor.record
15 #: Directivity of the individiual sensor points
16 self.directivity = None
18 self.time_reversal_boundary_data = None #: time varying pressure enforced as a Dirichlet boundary condition over sensor.mask
19 self.frequency_response = None #: two element array specifying the center frequency and percentage bandwidth of a frequency domain Gaussian filter applied to the sensor_data
21 @property
22 def mask(self):
23 """
24 Binary matrix or a set of Cartesian points where the pressure is recorded at each time-step
25 """
26 return self._mask
28 @mask.setter
29 def mask(self, val):
30 self._mask = val
32 def expand_grid(self, expand_size) -> None:
33 """
34 Enlarge the sensor mask (for Cartesian sensor masks and cuboid corners,
35 this has already been converted to a binary mask for display in inputChecking)
37 Args:
38 expand_size: the number of elements to add in each dimension
40 Returns:
41 None
42 """
43 self.mask = expand_matrix(self.mask, expand_size, 0)
45 @property
46 def record_start_index(self):
47 """
48 Time index to start recording if transducer is used as a sensor
49 """
50 return self._record_start_index
52 @record_start_index.setter
53 def record_start_index(self, val):
54 # force the user index to be an integer
55 self._record_start_index = int(round(val))
58@dataclass
59class kSensorDirectivity(object):
60 #: matrix of directivity angles (direction of maximum
61 #: response) for each sensor element defined in
62 #: sensor.mask. The angles are in radians where 0 = max
63 #: sensitivity in x direction (up/down) and pi/2 or -pi/2
64 #: = max sensitivity in y direction (left/right)
65 angle : np.ndarray = None
67 #: string defining the directivity pattern, valid inputs
68 #: are 'pressure' (spatial averaging over the sensor
69 #: surface equivalent to a sinc function) and 'gradient'
70 pattern : str = 'pressure'
72 #: equivalent element size (the larger the element size the more directional the response)
73 size : float = None
75 #: list of the unique directivity angles
76 unique_angles : np.ndarray = None
78 #: It is precomputed to allow data casting, as kgrid.kx (etc) are computed on the fly.
79 wavenumbers : np.ndarray = None
81 def set_default_size(self, kgrid) -> None:
82 """
83 Set the element size based on the kGrid
85 Args:
86 kgrid: Instance of `~kwave.kgrid.kWaveGrid` class
88 Returns:
89 None
90 """
91 DEFAULT_SIZE = 10
92 self.size = DEFAULT_SIZE * max(kgrid.dx, kgrid.dy)
94 def set_unique_angles(self, sensor_mask) -> None:
95 """
96 Assign unique_angles from sensor_mask
98 Args:
99 sensor_mask:
101 Returns:
102 None
103 """
104 self.unique_angles = np.unique(self.angle[sensor_mask == 1])
106 def set_wavenumbers(self, kgrid) -> None:
107 """
108 Assign the wavenumber vectors
110 Args:
111 kgrid: Instance of `~kwave.kgrid.kWaveGrid` class
113 Returns:
114 None
115 """
116 self.wavenumbers = np.vstack([kgrid.ky.T, kgrid.kx.T])