def test_normalization(self): # test normalization results for extreme case of isotropic scattering. # this is done by testing for different geometries the following cases: # Isotropic := 1/pi = CosineLobe(i=0) = HenyeyGreenstein(t=0) N = 20 t_0 = np.random.random(N) * np.pi t_ex = np.random.random(N) * np.pi p_0 = np.pi / 4. p_ex = np.pi / 4. for i in range(N): I = Isotropic() self.assertTrue( np.allclose(I.brdf(t_0[i], t_ex[i], p_0, p_ex), 1. / np.pi)) ncoefs = 10 C = CosineLobe(ncoefs=ncoefs, i=0) self.assertTrue( np.allclose(C.brdf(t_0[i], t_ex[i], p_0, p_ex), 1. / np.pi)) H = HenyeyGreenstein(t=0, ncoefs=5) self.assertTrue( np.allclose(H.brdf(t_0[i], t_ex[i], p_0, p_ex), 1. / np.pi)) LCH = LinCombSRF([[.5, HenyeyGreenstein(t=0, ncoefs=5)], [.5, HenyeyGreenstein(t=0, ncoefs=5)]]) self.assertTrue( np.allclose(LCH.brdf(t_0[i], t_ex[i], p_0, p_ex), 1. / np.pi))
def test_expansion_cosine_lobe(self): # theta_i = np.pi/2. # theta_s = 0.234234 # phi_i = np.pi/2. # phi_s = 0. # reference solution based on first N Legrende polynomials ncoefs = 10 # means coefficients 0...9; i=5 is for the example in the paper S = CosineLobe(ncoefs=ncoefs, i=5) # input parameters are set in a way that COS_THETA = 1 # and therefore only the legendre coefficients should be returned # which is always 1 in case that cos_THETA=1 t_0 = 0.1234 t_ex = np.pi / 2. p_0 = 0.3456 p_ex = 0. r = S._eval_legpoly(t_0, t_ex, p_0, p_ex, geometry='ffff') # calculate reference solution refs = [] for k in range(ncoefs): refs.append(S._get_legcoef(k) * 1.) ref = np.array(refs).sum() self.assertAlmostEqual(r, ref, 15)
def test_cosine_coeff(self): # test legcoefs for example in paper n = 10 S = CosineLobe(ncoefs=n, i=5) for i in range(n): z1 = 120. * (1. / 128. + i / 64.) / np.sqrt(np.pi) z2 = sc.gamma((7. - i) * 0.5) * sc.gamma((8. + i) * 0.5) self.assertAlmostEqual(S._get_legcoef(i), z1 / z2) self.assertAlmostEqual( S._get_legcoef(0), 15. / (16. * sc.gamma(3.5) * sc.gamma(4.) * np.sqrt(np.pi))) self.assertAlmostEqual( S._get_legcoef(2), 75. / (16. * sc.gamma(2.5) * sc.gamma(5.) * np.sqrt(np.pi)))
def test_fn_coefficients_RayCosine(self): # test if calculation of fn coefficients is correct # for a cosine lobe with reduced number of coefficients # this is done by comparing the obtained coefficients # against the analytical solution using a Rayleigh volume # and isotropic surface scattering phase function S = CosineLobe(ncoefs=1, i=5) V = Rayleigh(tau=0.7, omega=0.3) # --> cosTHETA = 0. # tests are using full Volume phase function, but only # ncoef times the coefficients from the surface t_0 = np.pi / 2. t_ex = 0.234234 p_0 = np.pi / 2. p_ex = 0. RT = RT1(self.I0, t_0, t_ex, p_0, p_ex, V=V, SRF=S, geometry='vvvv') res = RT._fnevals(t_0, p_0, t_ex, p_ex) # ncoefs = 1 # analtytical solution for ncoefs = 1 --> n=0 a0 = (3. / (16. * np.pi)) * (4. / 3.) a2 = (3. / (16. * np.pi)) * (2. / 3.) b0 = (15. * np.sqrt(np.pi)) / (16. * gamma(3.5) * gamma(4.)) # print 'a0:', a0, V._get_legcoef(0) # print 'a2:', a2, V._get_legcoef(2) # print 'b0: ', b0, S._get_legcoef(0) ref0 = 1. / 4. * b0 * (8. * a0 - a2 - 3. * a2 * np.cos(2. * t_0)) ref2 = 3. / 4. * a2 * b0 * (1. + 3. * np.cos(2. * t_0)) self.assertTrue(np.allclose([ref0, ref2], [res[0], res[2]])) # ncoefs = 2 # first and third coef should be the same as for ncoefs=1 S = CosineLobe(ncoefs=2, i=5, NormBRDF=np.pi) RT = RT1(self.I0, t_0, t_ex, p_0, p_ex, V=V, SRF=S, geometry='ffff') res2 = RT._fnevals(t_0, p_0, t_ex, p_ex) self.assertTrue(np.allclose([ref0, ref2], [res2[0], res2[2]]))
def test_example_2_int(self): print('Testing Example 2 ...') inc = self.inc2 # ---- evaluation of second example V = HenyeyGreenstein(tau=0.7, omega=0.3, t=0.7, ncoefs=20) SRF = CosineLobe(ncoefs=10, i=5, NormBRDF=np.pi) R = RT1(1., np.deg2rad(inc), np.deg2rad(inc), np.zeros_like(inc), np.full_like(inc, np.pi), V=V, SRF=SRF, geometry='mono') self.assertTrue(np.allclose(self.int_num_2, R.calc()[3], atol=1e-6))
def test_example_1_int(self): print('Testing Example 1 ...') inc = self.inc1 # ---- evaluation of first example V = Rayleigh(tau=np.array([0.7]), omega=np.array([0.3])) # 11 instead of 10 coefficients used to assure 7 digit precision SRF = CosineLobe(ncoefs=11, i=5, NormBRDF=np.array([np.pi])) R = RT1(1., np.deg2rad(inc), np.deg2rad(inc), np.zeros_like(inc), np.full_like(inc, np.pi), V=V, SRF=SRF, geometry='mono') self.assertTrue(np.allclose(self.int_num_1, R.calc()[3]))
def test_example1_fn(self): S = CosineLobe( ncoefs=10, i=5, NormBRDF=np.pi ) # somehow this is only working for ncoefs=1 at the moment! V = Rayleigh(tau=0.7, omega=0.3) I0 = 1. phi_0 = 0. #~ phi_0 = np.pi/2. phi_ex = np.pi # backscatter case fn = None for i in range(0, len(self.inc), self.step): #~ if self.n[i] % 2 == 1: #~ continue # todo skipping odds at the moment t_0 = self.inc[i] t_ex = t_0 * 1. RT = RT1(I0, t_0, t_ex, phi_0, phi_ex, RV=V, SRF=S, fn=fn) self.assertAlmostEqual(self.inc[i], RT.theta_0) mysol = RT._get_fn(int(self.n[i]), RT.theta_0, phi_0) print('inc,n,fnref,mysol:', RT.t_0, self.n[i], self.fn[i], mysol) fn = RT.fn self.assertEqual( self.tau[i], V.tau ) # check that tau for reference is the same as used for Volume object if self.fn[i] == 0.: self.assertEqual(mysol, self.fn[i]) else: #~ if np.abs(self.fn[i]) > 1.E-: #~ thres = 1.E-3 ## 1 promille threshold #~ else: thres = 1.E-8 # one percent threshold for very small numbers ratio = mysol / self.fn[i] self.assertTrue(np.abs(1. - ratio) < thres)
def test_example1_Fint(self): # backscatter case S = CosineLobe(ncoefs=10, i=5, NormBRDF=np.pi) V = Rayleigh(tau=0.7, omega=0.3) I0 = 1. phi_0 = 0. phi_ex = np.pi # backscatter case for i in range(0, len(self.inc), self.step): print('i,n:', i, self.n[i]) t_0 = self.inc[i] t_ex = t_0 * 1. RT = RT1(I0, t_0, t_ex, phi_0, phi_ex, RV=V, SRF=S) self.assertEqual( self.tau[i], V.tau ) # check that tau for reference is the same as used for Volume object Fint1 = RT._calc_Fint(t_0, t_ex, phi_0, phi_ex) # todo clairfy usage of phi!!! Fint2 = RT._calc_Fint(t_ex, t_0, phi_ex, phi_0) self.assertEqual(Fint1, Fint2)
def test_cosine(self): S = CosineLobe(ncoefs=10, i=5) t_0 = np.pi / 2. t_ex = 0.234234 p_0 = np.pi / 2. p_ex = 0. self.assertAlmostEqual(S.scat_angle(t_0, t_ex, p_0, p_ex, S.a), 0., 15) self.assertAlmostEqual(S.brdf(t_0, t_ex, p_0, p_ex), 0., 20) t_0 = 0. t_ex = np.deg2rad(60.) p_0 = 0. p_ex = 0. self.assertAlmostEqual(S.scat_angle(t_0, t_ex, p_0, p_ex, S.a), 0.5, 15) self.assertAlmostEqual(S.brdf(t_0, t_ex, p_0, p_ex), 0.5**5. / np.pi, 10)
possible choices for example = ? 1 : example 1 from the paper 2 : example 2 from the paper 3 : example using a linear-combination for p and the BRDF ''' example = 3 # ----------- definition of examples ----------- if example == 1: # define incidence-angle range for generation of backscatter-plots inc = np.arange(1., 89., 1.) # Example 1 V = Rayleigh(tau=0.55, omega=0.24) SRF = CosineLobe(ncoefs=15, i=6, a=[.28, 1., 1.]) label = 'Example 1' elif example == 2: # define incidence-angle range for generation of backscatter-plots inc = np.arange(1., 89., 1.) V = HenyeyGreenstein(tau=0.7, omega=0.3, t=0.7, ncoefs=20) SRF = CosineLobe(ncoefs=10, i=5) label = 'Example 2' elif example == 3: # define incidence-angle range for generation of backscatter-plots inc = np.arange(1., 89., 1.) # list of volume-scattering phase-functions to be combined phasechoices = [ # forward-scattering-peak HenyeyGreenstein(t=0.5, ncoefs=10, a=[-1., 1., 1.]),
import sys sys.path.append('..') from rt1.rt1 import RT1 from rt1.volume import Rayleigh from rt1.surface import CosineLobe import numpy as np import time # some speed benchmarking ... S = CosineLobe(ncoefs=10, i=5) V = Rayleigh(tau=0.7, omega=0.3) I0 = 1. theta_i = np.pi / 2. theta_ex = 0.234234 phi_i = np.pi / 2. phi_ex = 0. RT = RT1(I0, theta_i, theta_ex, phi_i, phi_ex, RV=V, SRF=S, geometry='vvvv') #~ print RT.fn #~ print len(RT.fn) #~ start = time.time() #~ for i in xrange(10): #~ for n in xrange(len(RT.fn)): #~ RT._get_fn(n, theta_i, phi_i, theta_ex, phi_ex)