def compute(i): s = res.loc[i, 'Dmax'] start = time.time() print(res.loc[i]) if res.loc[i].hasnans(): print('computing') density = rho(s) m = refractive.mi(wl, density) scatterer = Scatterer(radius=0.5 * s, wavelength=wl, m=m, axis_ratio=1.0 / ar, radius_type=Scatterer.RADIUS_MAXIMUM) scatterer.set_geometry(tmatrix_aux.geom_vert_back) scatterer.orient = orientation.orient_averaged_fixed scatterer.or_pdf = orientation.uniform_pdf() res.loc[i, 'f'] = f res.loc[i, 'wl'] = wl res.loc[i, 'rho'] = density res.loc[i, 'mr'] = m.real res.loc[i, 'mi'] = m.imag res.loc[i, 'Dmax'] = s res.loc[i, 'Csca'] = scatter.sca_xsect(scatterer) res.loc[i, 'Cbk'] = scatter.sca_intensity(scatterer) res.loc[i, 'sigmabk'] = radar.radar_xsect(scatterer) res.loc[i, 'Cext'] = scatter.ext_xsect(scatterer) res.loc[i, 'g'] = scatter.asym(scatterer) res.to_csv(savename) end = time.time() print(s, end - start)
def test_against_mie(self): """Test scattering parameters against Mie results """ # Reference values computed with the Mie code of Maetzler sca_xsect_ref = 4.4471684294079958 ext_xsect_ref = 7.8419745883848435 asym_ref = 0.76146646088675629 sca = Scatterer(wavelength=1, radius=1, m=complex(3.0,0.5)) sca_xsect = scatter.sca_xsect(sca) ext_xsect = scatter.ext_xsect(sca) asym = scatter.asym(sca) test_less(self, abs(1-sca_xsect/sca_xsect_ref), 1e-6) test_less(self, abs(1-ext_xsect/ext_xsect_ref), 1e-6) test_less(self, abs(1-asym/asym_ref), 1e-6)
def test_against_mie(self): """Test scattering parameters against Mie results """ # Reference values computed with the Mie code of Maetzler sca_xsect_ref = 4.4471684294079958 ext_xsect_ref = 7.8419745883848435 asym_ref = 0.76146646088675629 sca = Scatterer(wavelength=1, radius=1, m=complex(3.0, 0.5)) sca_xsect = scatter.sca_xsect(sca) ext_xsect = scatter.ext_xsect(sca) asym = scatter.asym(sca) test_less(self, abs(1 - sca_xsect / sca_xsect_ref), 1e-6) test_less(self, abs(1 - ext_xsect / ext_xsect_ref), 1e-6) test_less(self, abs(1 - asym / asym_ref), 1e-6)
def test_integrated_x_sca(self): """Test Rayleigh scattering cross section integrated over sizes. """ m = complex(3.0,0.5) K = (m**2-1)/(m**2+2) N0 = 10 Lambda = 1e4 sca = Scatterer(wavelength=1, m=m) sca.psd_integrator = psd.PSDIntegrator() sca.psd = psd.ExponentialPSD(N0=N0, Lambda=Lambda) sca.psd.D_max = 0.002 sca.psd_integrator.D_max = sca.psd.D_max # 256 is quite low, but we want to run the test reasonably fast sca.psd_integrator.num_points = 256 sca.psd_integrator.init_scatter_table(sca, angular_integration=True) # This size-integrated scattering cross section has an analytical value. # Check that we can reproduce it. sca_xsect_ref = 480*N0*np.pi**5*abs(K)**2/Lambda**7 sca_xsect = scatter.sca_xsect(sca) test_less(self, abs(1-sca_xsect/sca_xsect_ref), 1e-3)
def test_integrated_x_sca(self): """Test Rayleigh scattering cross section integrated over sizes. """ m = complex(3.0, 0.5) K = (m**2 - 1) / (m**2 + 2) N0 = 10 Lambda = 1e4 sca = Scatterer(wavelength=1, m=m) sca.psd_integrator = psd.PSDIntegrator() sca.psd = psd.ExponentialPSD(N0=N0, Lambda=Lambda) sca.psd.D_max = 0.002 sca.psd_integrator.D_max = sca.psd.D_max # 256 is quite low, but we want to run the test reasonably fast sca.psd_integrator.num_points = 256 sca.psd_integrator.init_scatter_table(sca, angular_integration=True) # This size-integrated scattering cross section has an analytical value. # Check that we can reproduce it. sca_xsect_ref = 480 * N0 * np.pi**5 * abs(K)**2 / Lambda**7 sca_xsect = scatter.sca_xsect(sca) test_less(self, abs(1 - sca_xsect / sca_xsect_ref), 1e-3)
def init_scatter_table(self, tm, angular_integration=False, verbose=False): """Initialize the scattering lookup tables. Initialize the scattering lookup tables for the different geometries. Before calling this, the following attributes must be set: num_points, m_func, axis_ratio_func, D_max, geometries and additionally, all the desired attributes of the Scatterer class (e.g. wavelength, aspect ratio). Args: tm: a Scatterer instance. angular_integration: If True, also calculate the angle-integrated quantities (scattering cross section, extinction cross section, asymmetry parameter). These are needed to call the corresponding functions in the scatter module when PSD integration is active. The default is False. verbose: if True, print information about the progress of the calculation (which may take a while). If False (default), run silently. """ self._psd_D = np.linspace(self.D_max / self.num_points, self.D_max, self.num_points) self._S_table = {} self._Z_table = {} self._previous_psd = None self._m_table = np.empty(self.num_points, dtype=complex) if angular_integration: self._angular_table = { "sca_xsect": {}, "ext_xsect": {}, "asym": {} } else: self._angular_table = None (old_m, old_axis_ratio, old_radius, old_geom, old_psd_integrator) = \ (tm.m, tm.axis_ratio, tm.radius, tm.get_geometry(), tm.psd_integrator) try: # temporarily disable PSD integration to avoid recursion tm.psd_integrator = None for geom in self.geometries: self._S_table[geom] = \ np.empty((2,2,self.num_points), dtype=complex) self._Z_table[geom] = np.empty((4, 4, self.num_points)) if angular_integration: for int_var in ["sca_xsect", "ext_xsect", "asym"]: self._angular_table[int_var][geom] = \ np.empty(self.num_points) for (i, D) in enumerate(self._psd_D): if verbose: print("Computing point {i} at D={D}...".format(i=i, D=D)) if self.m_func != None: tm.m = self.m_func(D) if self.axis_ratio_func != None: tm.axis_ratio = self.axis_ratio_func(D) self._m_table[i] = tm.m tm.radius = D / 2.0 for geom in self.geometries: tm.set_geometry(geom) (S, Z) = tm.get_SZ_orient() self._S_table[geom][:, :, i] = S self._Z_table[geom][:, :, i] = Z if angular_integration: self._angular_table["sca_xsect"][geom][i] = \ scatter.sca_xsect(tm) self._angular_table["ext_xsect"][geom][i] = \ scatter.ext_xsect(tm) self._angular_table["asym"][geom][i] = \ scatter.asym(tm) finally: #restore old values (tm.m, tm.axis_ratio, tm.radius, tm.psd_integrator) = \ (old_m, old_axis_ratio, old_radius, old_psd_integrator) tm.set_geometry(old_geom)
) # ar ones = np.ones_like(volume_fractions) ref_soft = snowScatt.refractiveIndex.mixing.eps( [ref_index**2 * ones, complex(1.0, 0.0) * ones], [volume_fractions, 1.0 - volume_fractions]) ref_soft = np.sqrt(ref_soft) for iD, D in enumerate(Dmax): spheroid = tmatrix.Scatterer(radius=0.5 * D, radius_type=tmatrix.Scatterer.RADIUS_MAXIMUM, wavelength=wavelength, m=ref_soft[iD], axis_ratio=1.0 / aspect_ratio) spheroid.set_geometry(tmatrix_aux.geom_vert_back) spheroidCs[iD] = scatter.sca_xsect(spheroid) spheroidCb[iD] = radar.radar_xsect(spheroid) spheroidQb = spheroidCb / (np.pi * reff_sph**2) spheroidQs = spheroidCs / (np.pi * reff_sph**2) spheroid_x = 2.0 * np.pi * reff_sph / wavelength axs[0].plot(spheroid_x, spheroidQb, c='m', label='soft-spheroid') axs[1].plot(spheroid_x, spheroidQs, c='m', label='soft-spheroid') ############################################################################### for ipt, (particle_type, ssrga_particle) in enumerate( zip(particle_types, ssrga_particle_names)): part_sel = [ str(v.values) for v in Cext.particle_name if str(v.values).startswith(particle_type)
Nc = 1 Nl = 1 xr = np.ndarray((Nc, Nl), dtype=np.float64) mr = np.ndarray((Nc, Nl), dtype=np.complex128) xr[:, 0] = x mr[:, 0] = m thetas = np.linspace(0.0, np.pi, 180) terms, Qe, Qs, Qa, Qb, Qp, g, ssa, S1, S2 = scattnlay(xr, mr, theta=thetas) print(S1[0, -1] / k, S2[0, -1] / k) s1 = S1[0, 0] / k s2 = S2[0, 0] / k SM = 0.0 * S SM[0, 0] = -1.0j * s2 SM[1, 1] = -1.0j * s1 print("Cext = ", scatter.ext_xsect(scatterer), Qe[0] * r * r * np.pi) print("Csca = ", scatter.sca_xsect(scatterer), Qs[0] * r * r * np.pi) print("Cbck = ", radar.radar_xsect(scatterer), Qb[0] * r * r * np.pi) print(S[0, 0].real / S1[0, 0].real) print(S[0, 0].imag / S1[0, 0].imag) print(S[1, 1].real / S2[0, 0].real) print(S[1, 1].imag / S2[0, 0].imag) Z11 = 0.5 * (abs(s1)**2 + abs(s2)**2) Z33 = 0.5 * (s1 * s2.conjugate() + s1.conjugate() * s2) print(Z[0, 0] / Z11) print(Z[2, 2] / Z33)
def init_scatter_table(self, tm, angular_integration=False, verbose=False): """Initialize the scattering lookup tables. Initialize the scattering lookup tables for the different geometries. Before calling this, the following attributes must be set: num_points, m_func, axis_ratio_func, D_max, geometries and additionally, all the desired attributes of the Scatterer class (e.g. wavelength, aspect ratio). Args: tm: a Scatterer instance. angular_integration: If True, also calculate the angle-integrated quantities (scattering cross section, extinction cross section, asymmetry parameter). These are needed to call the corresponding functions in the scatter module when PSD integration is active. The default is False. verbose: if True, print information about the progress of the calculation (which may take a while). If False (default), run silently. """ self._psd_D = np.linspace(self.D_max/self.num_points, self.D_max, self.num_points) self._S_table = {} self._Z_table = {} self._previous_psd = None self._m_table = np.empty(self.num_points, dtype=complex) if angular_integration: self._angular_table = {"sca_xsect": {}, "ext_xsect": {}, "asym": {}} else: self._angular_table = None (old_m, old_axis_ratio, old_radius, old_geom, old_psd_integrator) = \ (tm.m, tm.axis_ratio, tm.radius, tm.get_geometry(), tm.psd_integrator) try: # temporarily disable PSD integration to avoid recursion tm.psd_integrator = None for geom in self.geometries: self._S_table[geom] = \ np.empty((2,2,self.num_points), dtype=complex) self._Z_table[geom] = np.empty((4,4,self.num_points)) if angular_integration: for int_var in ["sca_xsect", "ext_xsect", "asym"]: self._angular_table[int_var][geom] = \ np.empty(self.num_points) for (i,D) in enumerate(self._psd_D): if verbose: print("Computing point {i} at D={D}...".format(i=i, D=D)) if self.m_func != None: tm.m = self.m_func(D) if self.axis_ratio_func != None: tm.axis_ratio = self.axis_ratio_func(D) self._m_table[i] = tm.m tm.radius = D/2.0 for geom in self.geometries: tm.set_geometry(geom) (S, Z) = tm.get_SZ_orient() self._S_table[geom][:,:,i] = S self._Z_table[geom][:,:,i] = Z if angular_integration: self._angular_table["sca_xsect"][geom][i] = \ scatter.sca_xsect(tm) self._angular_table["ext_xsect"][geom][i] = \ scatter.ext_xsect(tm) self._angular_table["asym"][geom][i] = \ scatter.asym(tm) finally: #restore old values (tm.m, tm.axis_ratio, tm.radius, tm.psd_integrator) = \ (old_m, old_axis_ratio, old_radius, old_psd_integrator) tm.set_geometry(old_geom)
wl4 = wl**4.0 K = (m**2+1.0)/(m**2-2) K2 = (K*K.conj()).real pref = pi5*K2/wl4 scatt = tmatrix.Scatterer(radius=1.0, wavelength=wl, m=m, axis_ratio=1.0) plt.figure() ax = plt.gca() for th in np.linspace(0.0,180): scatt.thet = th [[S11,S12],[S21,S22]] = scatt.get_S() sig = scatter.sca_xsect(scatt) # ax.scatter(th,1e6*sig,c='m') ax.scatter(th,S11,c='b') ax.scatter(th,S12,c='r') ax.scatter(th,S21,c='g',marker='x') ax.scatter(th,S22,c='k') ax.set_ylim([-0.0015,0.0015]) ax.set_ylim([-0.001355,-0.00135]) plt.figure() ax = plt.gca() for s in np.linspace(1,10,50): scatt = tmatrix.Scatterer(radius=s, wavelength=wl, m=m, axis_ratio=1.0)