Coverage for kwave/ksensor.py: 62%

39 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2022-10-24 11:55 -0700

1from dataclasses import dataclass 

2import numpy as np 

3 

4from kwave.utils import expand_matrix 

5 

6 

7class kSensor(object): 

8 

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 

14 

15 #: Directivity of the individiual sensor points 

16 self.directivity = None 

17 

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 

20 

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 

27 

28 @mask.setter 

29 def mask(self, val): 

30 self._mask = val 

31 

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) 

36 

37 Args: 

38 expand_size: the number of elements to add in each dimension 

39 

40 Returns: 

41 None 

42 """ 

43 self.mask = expand_matrix(self.mask, expand_size, 0) 

44 

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 

51 

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)) 

56 

57 

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 

66 

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' 

71 

72 #: equivalent element size (the larger the element size the more directional the response) 

73 size : float = None 

74 

75 #: list of the unique directivity angles 

76 unique_angles : np.ndarray = None 

77 

78 #: It is precomputed to allow data casting, as kgrid.kx (etc) are computed on the fly. 

79 wavenumbers : np.ndarray = None 

80 

81 def set_default_size(self, kgrid) -> None: 

82 """ 

83 Set the element size based on the kGrid 

84 

85 Args: 

86 kgrid: Instance of `~kwave.kgrid.kWaveGrid` class 

87 

88 Returns: 

89 None 

90 """ 

91 DEFAULT_SIZE = 10 

92 self.size = DEFAULT_SIZE * max(kgrid.dx, kgrid.dy) 

93 

94 def set_unique_angles(self, sensor_mask) -> None: 

95 """ 

96 Assign unique_angles from sensor_mask 

97 

98 Args: 

99 sensor_mask: 

100 

101 Returns: 

102 None 

103 """ 

104 self.unique_angles = np.unique(self.angle[sensor_mask == 1]) 

105 

106 def set_wavenumbers(self, kgrid) -> None: 

107 """ 

108 Assign the wavenumber vectors 

109 

110 Args: 

111 kgrid: Instance of `~kwave.kgrid.kWaveGrid` class 

112 

113 Returns: 

114 None 

115 """ 

116 self.wavenumbers = np.vstack([kgrid.ky.T, kgrid.kx.T])