def test_backend(): """Replicate the test run of the backend T-Matrix code. Replicates the results of the default test run of the backend code by Mishchenko. The user can use the function to manually check that the results match. Small errors may be present due to different compiler optimizations. """ scatterer = Scatterer(radius=10.0, rat=0.1, wavelength=2 * np.pi, m=complex(1.5, 0.02), axis_ratio=0.5, ddelt=1e-3, ndgs=2, np=-1) scatterer.thet0 = 56.0 scatterer.thet = 65.0 scatterer.phi0 = 114.0 scatterer.phi = 128.0 scatterer.alpha = 145.0 scatterer.beta = 52.0 print("Amplitude matrix S:") print(scatterer.get_S()) print("Phase matrix Z:") print(scatterer.get_Z())
def test_rayleigh(self): """Test match with Rayleigh scattering for small spheres """ wl = 100.0 r = 1.0 eps = 1.0 m = complex(1.5,0.5) tm = Scatterer(wavelength=wl, radius=r, axis_ratio=eps, m=m) S = tm.get_S() k = 2*np.pi/wl S_ray = k**2 * (m**2-1)/(m**2+2) * r test_relative(self, S[0,0], S_ray, limit=1e-3) test_relative(self, S[1,1], -S_ray, limit=1e-3) test_less(self, abs(S[0,1]), 1e-25) test_less(self, abs(S[1,0]), 1e-25)
def test_rayleigh(self): """Test match with Rayleigh scattering for small spheres """ wl = 100.0 r = 1.0 eps = 1.0 m = complex(1.5, 0.5) tm = Scatterer(wavelength=wl, radius=r, axis_ratio=eps, m=m) S = tm.get_S() k = 2 * np.pi / wl S_ray = k**2 * (m**2 - 1) / (m**2 + 2) * r test_relative(self, S[0, 0], S_ray, limit=1e-3) test_relative(self, S[1, 1], -S_ray, limit=1e-3) test_less(self, abs(S[0, 1]), 1e-25) test_less(self, abs(S[1, 0]), 1e-25)
def test_backend(): """Replicate the test run of the backend T-Matrix code. Replicates the results of the default test run of the backend code by Mishchenko. The user can use the function to manually check that the results match. Small errors may be present due to different compiler optimizations. """ scatterer = Scatterer(radius=10.0, rat=0.1, wavelength=2*np.pi, m=complex(1.5,0.02), axis_ratio=0.5, ddelt=1e-3, ndgs=2, np=-1) scatterer.thet0 = 56.0 scatterer.thet = 65.0 scatterer.phi0 = 114.0 scatterer.phi = 128.0 scatterer.alpha = 145.0 scatterer.beta = 52.0 print("Amplitude matrix S:") print(scatterer.get_S()) print("Phase matrix Z:") print(scatterer.get_Z())
# scatterer.psd_integrator.init_scatter_table(scatterer,verbose=True) # end = timer() # time = end-start # print(time) #scatterer.psd = ExponentialPSD(N0 = 1e2,Lambda= 0.025,D_max=100.0) it = np.nditer(sze, flags=['multi_index']) for x in it: geom = (ize[it.multi_index], sze[it.multi_index], 0.0, saz[it.multi_index], 0.0, 0.0) scatterer.set_geometry(geom) idx = (n, ) + it.multi_index # refh[it.multi_index] = 10*np.log10(radar.refl(scatterer)) # zdr[idx] = radar.Zdr(scatterer) # rho[it.multi_index] = radar.rho_hv(scatterer) sh[idx] = 4 * np.pi * np.abs(scatterer.get_S()[1, 1])**2 sv[idx] = 4 * np.pi * np.abs(scatterer.get_S()[0, 0])**2 nsh = np.concatenate((sh, sh[:, :, :, :0:-1]), axis=3).T nsv = np.concatenate((sv, sv[:, :, :, :0:-1]), axis=3).T phi = np.linspace(0, 180, nsZe) * np.pi / 180 theta = np.linspace(0, 360, nsAz * 2 - 1) * np.pi / 180 phi, theta = np.meshgrid(phi, theta) a = 0 d = 39 nsv = nsv[:, :, a, d] nsh = nsh[:, :, a, d] nsv = np.log10(nsv) nsh = np.log10(nsh)
def calcScatPropOneFreq(wl, radii, as_ratio, rho, elv, ndgs=30, canting=False, cantingStd=1, meanAngle=0, safeTmatrix=False): """ Calculates the Ze at H and V polarization, Kdp for one wavelength TODO: LDR??? Parameters ---------- wl: wavelength [mm] (single value) radii: radius [mm] of the particle (array[n]) as_ratio: aspect ratio of the super particle (array[n]) rho: density [g/mmˆ3] of the super particle (array[n]) elv: elevation angle [°] ndgs: division points used to integrate over the particle surface canting: boolean (default = False) cantingStd: standard deviation of the canting angle [°] (default = 1) meanAngle: mean value of the canting angle [°] (default = 0) Returns ------- reflect_h: super particle horizontal reflectivity[mm^6/m^3] (array[n]) reflect_v: super particle vertical reflectivity[mm^6/m^3] (array[n]) refIndex: refractive index from each super particle (array[n]) kdp: calculated kdp from each particle (array[n]) """ #---pyTmatrix setup # initialize a scatterer object scatterer = Scatterer(wavelength=wl) scatterer.radius_type = Scatterer.RADIUS_MAXIMUM scatterer.ndgs = ndgs scatterer.ddelta = 1e-6 if canting == True: scatterer.or_pdf = orientation.gaussian_pdf(std=cantingStd, mean=meanAngle) # scatterer.orient = orientation.orient_averaged_adaptive scatterer.orient = orientation.orient_averaged_fixed # geometric parameters - incident direction scatterer.thet0 = 90. - elv scatterer.phi0 = 0. # parameters for backscattering refIndex = np.ones_like(radii, np.complex128) * np.nan reflect_h = np.ones_like(radii) * np.nan reflect_v = np.ones_like(radii) * np.nan # S matrix for Kdp sMat = np.ones_like(radii) * np.nan for i, radius in enumerate(radii[::5]): #TODO remove [::5] # A quick function to save the distribution of values used in the test #with open('/home/dori/table_McRadar.txt', 'a') as f: # f.write('{0:f} {1:f} {2:f} {3:f} {4:f} {5:f} {6:f}\n'.format(wl, elv, # meanAngle, # cantingStd, # radius, # rho[i], # as_ratio[i])) # scattering geometry backward # radius = 100.0 # just a test to force nans scatterer.thet = 180. - scatterer.thet0 scatterer.phi = (180. + scatterer.phi0) % 360. scatterer.radius = radius scatterer.axis_ratio = 1. / as_ratio[i] scatterer.m = refractive.mi(wl, rho[i]) refIndex[i] = refractive.mi(wl, rho[i]) if safeTmatrix: inputs = [ str(scatterer.radius), str(scatterer.wavelength), str(scatterer.m), str(scatterer.axis_ratio), str(int(canting)), str(cantingStd), str(meanAngle), str(ndgs), str(scatterer.thet0), str(scatterer.phi0) ] arguments = ' '.join(inputs) a = subprocess.run( ['spheroidMcRadar'] + inputs, # this script should be installed by McRadar capture_output=True) # print(str(a)) try: back_hh, back_vv, sMatrix, _ = str( a.stdout).split('Results ')[-1].split() back_hh = float(back_hh) back_vv = float(back_vv) sMatrix = float(sMatrix) except: back_hh = np.nan back_vv = np.nan sMatrix = np.nan # print(back_hh, radar.radar_xsect(scatterer, True)) # print(back_vv, radar.radar_xsect(scatterer, False)) reflect_h[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr ) * back_hh # radar.radar_xsect(scatterer, True) # Kwsqrt is not correct by default at every frequency reflect_v[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr ) * back_vv # radar.radar_xsect(scatterer, False) # scattering geometry forward # scatterer.thet = scatterer.thet0 # scatterer.phi = (scatterer.phi0) % 360. #KDP geometry # S = scatterer.get_S() sMat[i] = sMatrix # (S[1,1]-S[0,0]).real # print(sMatrix, sMat[i]) # print(sMatrix) else: reflect_h[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr) * radar.radar_xsect( scatterer, True ) # Kwsqrt is not correct by default at every frequency reflect_v[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr) * radar.radar_xsect( scatterer, False) # scattering geometry forward scatterer.thet = scatterer.thet0 scatterer.phi = (scatterer.phi0) % 360. #KDP geometry S = scatterer.get_S() sMat[i] = (S[1, 1] - S[0, 0]).real kdp = 1e-3 * (180.0 / np.pi) * scatterer.wavelength * sMat del scatterer # TODO: Evaluate the chance to have one Scatterer object already initiated instead of having it locally return reflect_h, reflect_v, refIndex, kdp
for i,d in enumerate(D): ar = a1.get_axis_ratio(d) scatt.radius = d/2. scatt.m = m_func1(d) scatt.axis_ratio = ar # Backward scattering (note that we do not need amplitude matrix for backward scattering) scatt.set_geometry(geom_back) Z_back = scatt.get_Z() # Forward scattering (note that we do not need phase matrix for forward scattering) scatt.set_geometry(geom_forw) S_forw=scatt.get_S() list_SZ_1.append(Z_back[0,0]) ar = a2.get_axis_ratio(d) scatt.radius = d/2. scatt.m = m_func2(d) scatt.axis_ratio = ar # Backward scattering (note that we do not need amplitude matrix for backward scattering) scatt.set_geometry(geom_back) Z_back=scatt.get_Z() # Forward scattering (note that we do not need phase matrix for forward scattering) scatt.set_geometry(geom_forw) S_forw=scatt.get_S()
def calcKdpPropOneFreq(wl, radii, as_ratio, rho, elv, ndgs=2, canting=False, cantingStd=1, meanAngle=0): """ Calculation of the KDP of one particle Parameters ---------- wl: wavelength [mm] (single value) radii: radius [mm] of the particle (array[n]) as_ratio: aspect ratio of the super particle (array[n]) rho: density [g/mmˆ3] of the super particle (array[n]) elv: elevation angle [°] ndgs: number of division points used to integrate over the particle surface (default= 30 it is already high) canting: boolean (default = False) cantingStd: standard deviation of the canting angle [°] (default = 1) meanAngle: mean value of the canting angle [°] (default = 0) Returns ------- kdp: calculated kdp from each particle (array[n]) """ scatterer = Scatterer(wavelength=wl) #, axis_ratio=1./as_ratio) scatterer.radius_type = Scatterer.RADIUS_MAXIMUM scatterer.set_geometry(tmatrix_aux.geom_horiz_forw) scatterer.ndgs = ndgs if canting == True: scatterer.or_pdf = orientation.gaussian_pdf(std=cantingStd, mean=meanAngle) #scatterer.orient = orientation.orient_averaged_adaptive scatterer.orient = orientation.orient_averaged_fixed # geometric parameters scatterer.thet0 = 90. - elv scatterer.phi0 = 0. # geometric parameters scatterer.thet = scatterer.thet0 scatterer.phi = (scatterer.phi0) % 360. #KDP geometry sMat = np.ones_like(radii) * np.nan for i, radius in enumerate(radii): scatterer.axis_ratio = 1. / as_ratio[i] scatterer.radius = radius scatterer.m = refractive.mi(wl, rho[i]) S = scatterer.get_S() sMat[i] = (S[1, 1] - S[0, 0]).real kdp = 1e-3 * (180.0 / np.pi) * scatterer.wavelength * (sMat) return kdp
def calcScatPropOneFreq(wl, radii, as_ratio, rho, elv, ndgs=30, canting=False, cantingStd=1, meanAngle=0): """ Calculates the Ze at H and V polarization, Kdp for one wavelength TODO: LDR??? Parameters ---------- wl: wavelenght [mm] (single value) radii: radius [mm] of the particle (array[n]) as_ratio: aspect ratio of the super particle (array[n]) rho: density [g/mmˆ3] of the super particle (array[n]) elv: elevation angle [°] ndgs: division points used to integrate over the particle surface canting: boolean (default = False) cantingStd: standard deviation of the canting angle [°] (default = 1) meanAngle: mean value of the canting angle [°] (default = 0) Returns ------- reflect_h: super particle horizontal reflectivity[mm^6/m^3] (array[n]) reflect_v: super particle vertical reflectivity[mm^6/m^3] (array[n]) refIndex: refractive index from each super particle (array[n]) kdp: calculated kdp from each particle (array[n]) """ #---pyTmatrix setup # initialize a scatterer object scatterer = Scatterer(wavelength=wl) scatterer.radius_type = Scatterer.RADIUS_MAXIMUM scatterer.ndgs = ndgs scatterer.ddelta = 1e-6 if canting == True: scatterer.or_pdf = orientation.gaussian_pdf(std=cantingStd, mean=meanAngle) # scatterer.orient = orientation.orient_averaged_adaptive scatterer.orient = orientation.orient_averaged_fixed # geometric parameters - incident direction scatterer.thet0 = 90. - elv scatterer.phi0 = 0. # parameters for backscattering refIndex = np.ones_like(radii, np.complex128) * np.nan reflect_h = np.ones_like(radii) * np.nan reflect_v = np.ones_like(radii) * np.nan # S matrix for Kdp sMat = np.ones_like(radii) * np.nan for i, radius in enumerate(radii): # A quick function to save the distribution of values used in the test #with open('/home/dori/table_McRadar.txt', 'a') as f: # f.write('{0:f} {1:f} {2:f} {3:f} {4:f} {5:f} {6:f}\n'.format(wl, elv, # meanAngle, # cantingStd, # radius, # rho[i], # as_ratio[i])) # scattering geometry backward scatterer.thet = 180. - scatterer.thet0 # Is it???? scatterer.phi = (180. + scatterer.phi0) % 360. scatterer.radius = radius scatterer.axis_ratio = 1. / as_ratio[i] scatterer.m = refractive.mi(wl, rho[i]) refIndex[i] = refractive.mi(wl, rho[i]) reflect_h[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr) * radar.radar_xsect( scatterer, True) # Kwsqrt is not correct by default at every frequency reflect_v[i] = scatterer.wavelength**4 / ( np.pi**5 * scatterer.Kw_sqr) * radar.radar_xsect(scatterer, False) # scattering geometry forward scatterer.thet = scatterer.thet0 scatterer.phi = (scatterer.phi0) % 360. #KDP geometry S = scatterer.get_S() sMat[i] = (S[1, 1] - S[0, 0]).real kdp = 1e-3 * (180.0 / np.pi) * scatterer.wavelength * sMat del scatterer # TODO: Evaluate the chance to have one Scatterer object already initiated instead of having it locally return reflect_h, reflect_v, refIndex, kdp