Coverage for kwave/kWaveSimulation_helper/create_absorption_variables.py: 21%

1 import math

2 import numpy as np

3

4 from kwave import kWaveGrid, kWaveMedium

5 from kwave.utils import db2neper

6

7

8 def create_absorption_variables(kgrid: kWaveGrid, medium: kWaveMedium, equation_of_state):

9 # define the lossy derivative operators and proportionality coefficients

10 if equation_of_state == 'absorbing':

11 return create_absorbing_medium_variables(kgrid.k, medium)

12 elif equation_of_state == 'stokes':

13 return create_stokes_medium_variables(medium)

14 else:

15 raise NotImplementedError

16

17

18 def create_absorbing_medium_variables(kgrid_k, medium: kWaveMedium):

19 # convert the absorption coefficient to nepers.(rad/s)^-y.m^-1

20 medium.alpha_coeff = db2neper(medium.alpha_coeff, medium.alpha_power)

21

22 absorb_nabla1, absorb_tau = get_absorbtion(kgrid_k, medium)

23 absorb_nabla2, absorb_eta = get_dispersion(kgrid_k, medium)

24

25 absorb_nabla1, absorb_nabla2 = apply_alpha_filter(medium, absorb_nabla1, absorb_nabla2)

26

27 return absorb_nabla1, absorb_nabla2, absorb_tau, absorb_eta

28

29

30 def create_stokes_medium_variables(medium: kWaveMedium):

31 # convert the absorption coefficient to nepers.(rad/s)^-2.m^-1

32 medium.alpha_coeff = db2neper(medium.alpha_coeff, 2)

33

34 # compute the absorbing coefficient

35 absorb_tau = compute_absorbing_coeff(medium)

36 return None, None, absorb_tau, None

37

38

39 def get_absorbtion(kgrid_k, medium):

40 # compute the absorbing fractional Laplacian operator and coefficient

41 if medium.alpha_mode == 'no_absorption':

42 return 0, 0

43

44 nabla1 = kgrid_k**(medium.alpha_power - 2)

45 nabla1[np.isinf(nabla1)] = 0

46 nabla1 = np.fft.ifftshift(nabla1)

47 tau = compute_absorbing_coeff(medium)

48 return nabla1, tau

49

50

51 def get_dispersion(kgrid_k, medium):

52 # compute the dispersive fractional Laplacian operator and coefficient

53 if medium.alpha_mode == 'no_dispersion':

54 return 0, 0

55 nabla2 = kgrid_k ** (medium.alpha_power - 1)

56 nabla2[np.isinf(nabla2)] = 0

57 nabla2 = np.fft.ifftshift(nabla2)

58 eta = compute_dispersive_coeff(medium)

59 return nabla2, eta

60

61

62 def compute_absorbing_coeff(medium):

63 tau = -2 * medium.alpha_coeff * (medium.sound_speed ** (medium.alpha_power - 1))

64

65 # modify the sign of the absorption operator if alpha_sign is defined

66 # (this is used for time-reversal photoacoustic image reconstruction

67 # with absorption compensation)

68 if medium.alpha_sign is not None:

69 tau = np.sign(medium.alpha_sign[0]) * tau

70 return tau

71

72

73 def compute_dispersive_coeff(medium):

74 eta = 2 * medium.alpha_coeff * medium.sound_speed**(medium.alpha_power) * math.tan(math.pi * medium.alpha_power / 2)

75

76 # modify the sign of the absorption operator if alpha_sign is defined

77 # (this is used for time-reversal photoacoustic image reconstruction

78 # with absorption compensation)

79 if medium.alpha_sign is not None:

80 eta = np.sign(medium.alpha_sign[1]) * eta

81 return eta

82

83

84 def apply_alpha_filter(medium, nabla1, nabla2):

85 # pre-filter the absorption parameters if alpha_filter is defined (this

86 # is used for time-reversal photoacoustic image reconstruction

87 # with absorption compensation)

88 if medium.alpha_filter is None:

89 return nabla1, nabla2

90

91 # update command line status

92 print(' filtering absorption variables...')

93

94 # frequency shift the absorption parameters

95 nabla1 = np.fft.fftshift(nabla1)

96 nabla2 = np.fft.fftshift(nabla2)

97

98 # apply the filter

99 nabla1 = nabla1 * medium.alpha_filter

100 nabla2 = nabla2 * medium.alpha_filter

101

102 # shift the parameters back

103 nabla1 = np.fft.ifftshift(nabla1)

104 nabla2 = np.fft.ifftshift(nabla2)

105 return nabla1, nabla2