def calc_emissivity_4SAIL(lai, vza, alpha, emis_veg=0.98, emis_soil=0.95, tau=0.0): ''' Estimates surface directional emissivity using 4SAIL Radiative Transfer Model Parameters ---------- lai : array_like Leaf Area Index vza : array_like View Zenith Angle alpha : array_like Average leaf angle in Campbell ellipsoidal leaf inclination distribution function emis_veg : float Leaf emissivity emis_soil : bool Bare soil emissivity tau : float Leaf thermal transmittance, default=0 Returns ------- emissivity : array_like surface directional emissivity ''' # Get array dimensions and check for consistency in the dimensions lai = np.asarray(lai) vza = _check_default_parameter_size(vza, lai) alpha = _check_default_parameter_size(alpha, lai) dims = lai.shape # Vectorize the inputs lai = lai.reshape(-1) vza = vza.reshape(-1) alpha = alpha.reshape(-1) # Solar parameters (illumination angles and hotpost) in FourSAIL are not relevant: hotspot, sza, psi = np.zeros(lai.shape), np.zeros(lai.shape), np.zeros( lai.shape) lidf = sail.CalcLIDF_Campbell_vec(alpha, n_elements=18) [_, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, _, _, _, _] = sail.FourSAIL_vec(lai, hotspot, lidf, sza, vza, psi, np.ones(lai.shape)[np.newaxis, :] - emis_veg, np.zeros(lai.shape)[np.newaxis, :], np.ones(lai.shape)[np.newaxis, :] - emis_soil) # Kirchoff law emissivity = 1.0 - rdot # Convert output vector to original array emissivity = emissivity.reshape(dims) return emissivity
def run(N, chloro, caroten, brown, EWT, LMA, Ant, LAI, hot_spot, solar_zenith, solar_azimuth, view_zenith, view_azimuth, LIDF, skyl=0.2, soilType=DEFAULT_SOIL): ''' Runs Prospect5 4SAIL model to estimate canopy directional reflectance factor. Parameters ---------- N : float Leaf structural parameter. chloro : float chlorophyll a+b content (mug cm-2). caroten : float carotenoids content (mug cm-2). brown : float brown pigments concentration (unitless). EWT : float equivalent water thickness (g cm-2 or cm). LMA : float dry matter content (g cm-2). LAI : float Leaf Area Index. hot_spot : float Hotspot parameter. solar_zenith : float Sun Zenith Angle (degrees). solar_azimuth : float Sun Azimuth Angle (degrees). view_zenith : float View(sensor) Zenith Angle (degrees). view_azimuth : float View(sensor) Zenith Angle (degrees). LIDF : float or tuple(float,float) Leaf Inclination Distribution Function parameter. * if float, mean leaf angle for the Cambpell Spherical LIDF. * if tuple, (a,b) parameters of the Verhoef's bimodal LIDF |LIDF[0]| + |LIDF[1]|<=1. skyl : float, optional Fraction of diffuse shortwave radiation, default=0.2. soilType : str, optional filename of the soil type, defautl use inceptisol soil type, see SoilSpectralLibrary folder. Returns ------- wl : array_like wavelenghts. rho_canopy : array_like canopy reflectance factors. References ---------- .. [Feret08] Feret et al. (2008), PROSPECT-4 and 5: Advances in the Leaf Optical Properties Model Separating Photosynthetic Pigments, Remote Sensing of Environment. .. [Verhoef2007] Verhoef, W.; Jia, Li; Qing Xiao; Su, Z., (2007) Unified Optical-Thermal Four-Stream Radiative Transfer Theory for Homogeneous Vegetation Canopies, IEEE Transactions on Geoscience and Remote Sensing, vol.45, no.6, pp.1808-1822, http://dx.doi.org/10.1109/TGRS.2007.895844. ''' # Read the soil reflectance rsoil = np.genfromtxt(os.path.join(SOIL_FOLDER, soilType)) #wl_soil=rsoil[:,0] rsoil = np.array(rsoil[:, 1]) # Calculate the lidf if type(LIDF) == tuple or type(LIDF) == list: if len(LIDF) != 2: print( "ERROR, Verhoef's bimodal LIDF distribution must have two elements (LIDFa, LIDFb)" ) return None, None elif LIDF[0] + LIDF[1] > 1: print( "ERROR, |LIDFa| + |LIDFb| > 1 in Verhoef's bimodal LIDF distribution" ) else: lidf = FourSAIL.CalcLIDF_Verhoef(LIDF[0], LIDF[1]) else: lidf = FourSAIL.CalcLIDF_Campbell(LIDF) # PROSPECT5 for leaf bihemispherical reflectance and transmittance wl, rho_leaf, tau_leaf = ProspectD.ProspectD(N, chloro, caroten, brown, EWT, LMA, Ant) # Get the relative sun-view azimth angle psi = abs(solar_azimuth - view_azimuth) # 4SAIL for canopy reflectance and transmittance factors [ tss, too, tsstoo, rdd, tdd, rsd, tsd, rdo, tdo, rso, rsos, rsod, rddt, rsdt, rdot, rsodt, rsost, rsot, gammasdf, gammasdb, gammaso ] = FourSAIL.FourSAIL(LAI, hot_spot, lidf, solar_zenith, view_zenith, psi, rho_leaf, tau_leaf, rsoil) rho_canopy = rdot * skyl + rsot * (1 - skyl) return wl, rho_canopy
def run_TIR(emisVeg, emisSoil, T_Veg, T_Soil, LAI, hot_spot, solar_zenith, solar_azimuth, view_zenith, view_azimuth, LIDF, T_VegSunlit=None, T_SoilSunlit=None, T_atm=0): ''' Estimates the broadband at-sensor thermal radiance using 4SAIL model. Parameters ---------- emisVeg : float Leaf hemispherical emissivity. emisSoil : float Soil hemispherical emissivity. T_Veg : float Leaf temperature (Kelvin). T_Soil : float Soil temperature (Kelvin). LAI : float Leaf Area Index. hot_spot : float Hotspot parameter. solar_zenith : float Sun Zenith Angle (degrees). solar_azimuth : float Sun Azimuth Angle (degrees). view_zenith : float View(sensor) Zenith Angle (degrees). view_azimuth : float View(sensor) Zenith Angle (degrees). LIDF : float or tuple(float,float) Leaf Inclination Distribution Function parameter. * if float, mean leaf angle for the Cambpell Spherical LIDF. * if tuple, (a,b) parameters of the Verhoef's bimodal LIDF |LIDF[0]| + |LIDF[1]|<=1. T_VegSunlit : float, optional Sunlit leaf temperature accounting for the thermal hotspot effect, default T_VegSunlit=T_Veg. T_SoilSunlit : float, optional Sunlit soil temperature accounting for the thermal hotspot effect default T_SoilSunlit=T_Soil. T_atm : float, optional Apparent sky brightness temperature (Kelvin), default T_atm =0K (no downwellig radiance). Returns ------- Lw : float At sensor broadband radiance (W m-2). TB_obs : float At sensor brightness temperature (Kelvin). emiss : float Surface directional emissivity. References ---------- .. [Verhoef2007] Verhoef, W.; Jia, Li; Qing Xiao; Su, Z., (2007) Unified Optical-Thermal Four-Stream Radiative Transfer Theory for Homogeneous Vegetation Canopies, IEEE Transactions on Geoscience and Remote Sensing, vol.45, no.6, pp.1808-1822, http://dx.doi.org/10.1109/TGRS.2007.895844. ''' # Apply Kirchoff's law to get the soil and leaf bihemispherical reflectances rsoil = 1 - emisSoil rho_leaf = 1 - emisVeg tau_leaf = 0 # Calculate the lidf, if type(LIDF) == tuple or type(LIDF) == list: if len(LIDF) != 2: print( "ERROR, Verhoef's bimodal LIDF distribution must have two elements (LIDFa, LIDFb)" ) return None, None elif LIDF[0] + LIDF[1] > 1: print( "ERROR, |LIDFa| + |LIDFb| > 1 in Verhoef's bimodal LIDF distribution" ) else: lidf = FourSAIL.CalcLIDF_Verhoef(LIDF[0], LIDF[1]) else: lidf = FourSAIL.CalcLIDF_Campbell(LIDF) # Get the relative sun-view azimth angle psi = abs(solar_azimuth - view_azimuth) # 4SAIL for canopy reflectance and transmittance factors [ tss, too, tsstoo, rdd, tdd, rsd, tsd, rdo, tdo, rso, rsos, rsod, rddt, rsdt, rdot, rsodt, rsost, rsot, gammasdf, gammasdb, gammaso ] = FourSAIL.FourSAIL(LAI, hot_spot, lidf, solar_zenith, view_zenith, psi, rho_leaf, tau_leaf, rsoil) tso = tss * too + tss * (tdo + rsoil * rdd * too) / (1. - rsoil * rdd) gammad = 1 - rdd - tdd gammao = 1 - rdo - tdo - too ttot = (too + tdo) / (1. - rsoil * rdd) gammaot = gammao + ttot * rsoil * gammad gammasot = gammaso + ttot * rsoil * gammasdf aeev = gammaot aees = ttot * emisSoil # Get the different canopy broadband emssion components Hvc = CalcStephanBoltzmann(T_Veg) Hgc = CalcStephanBoltzmann(T_Soil) Hsky = CalcStephanBoltzmann(T_atm) if T_VegSunlit: # Accout for different suntlit shaded temperatures Hvh = CalcStephanBoltzmann(T_VegSunlit) else: Hvh = Hvc if T_SoilSunlit: # Accout for different suntlit shaded temperatures Hgh = CalcStephanBoltzmann(T_SoilSunlit) else: Hgh = Hgc # Calculate the blackbody emission temperature Lw = (rdot * Hsky + (aeev * Hvc + gammasot * emisVeg * (Hvh - Hvc) + aees * Hgc + tso * emisSoil * (Hgh - Hgc))) / np.pi TB_obs = (np.pi * Lw / SB)**(0.25) # Estimate the apparent surface directional emissivity emiss = 1 - rdot return Lw, TB_obs, emiss
input_param[param] = samples[:, i] samples_new = np.zeros((N_samples_canopy, len(ObjParams))) j = 0 for i, param in enumerate(FourSAIL.paramsPro4SAIL): if param in ObjParams: samples_new[:, j] = input_param[param] j += 1 print('Running ProspectD+4SAIL') l, r, t = ProspectD.ProspectD_vec(input_param['N_leaf'], input_param['Cab'], input_param['Car'], input_param['Cbrown'], input_param['Cw'], input_param['Cm'], input_param['Ant']) lidf = FourSAIL.CalcLIDF_Campbell_vec(input_param['leaf_angle']) # Read the soil reflectance rsoil = np.genfromtxt( pth.join(soil_folder, 'ipgp.jussieu.soil.prosail.dry.coarse.1.spectrum.txt')) #wl_soil=rsoil[:,0] rsoil = np.array(rsoil[:, 1]) rsoil = np.repeat(rsoil[:, np.newaxis], N_samples_canopy, axis=1) # Run nadir observations [_, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _, _] = FourSAIL.FourSAIL_vec(input_param['LAI'], input_param['hotspot'], lidf, np.ones(N_samples_canopy) * 37., np.zeros(N_samples_canopy),
def CalcfAPAR_4SAIL(skyl, LAI, lidf, hotspot, sza, rho_leaf, tau_leaf, rsoil): '''Estimates the fraction of Absorbed PAR using the 4SAIL Radiative Transfer Model. Parameters ---------- skyl : float Ratio of diffuse to total PAR radiation LAI : float Leaf (Plant) Area Index lidf : list Leaf Inclination Distribution Function, 5 degrees step hotspot : float hotspot parameters, use 0 to ignore the hotspot effect (turbid medium) sza : float Sun Zenith Angle (degrees) rho_leaf : list Narrowband leaf bihemispherical reflectance, it might be simulated with PROSPECT (400-700 @1nm) tau_leaf : list Narrowband leaf bihemispherical transmittance, it might be simulated with PROSPECT (400-700 @1nm) rsoil : list Narrowband soil bihemispherical reflectance (400-700 @1nm) Returns ------- fAPAR : float Fraction of Absorbed Photosynthetically Active Radiation''' #Input the angle step to perform the hemispherical integration stepvza = 10 steppsi = 30 Es = 1.0 - skyl Ed = skyl #Initialize values So_sw = np.zeros(len(rho_leaf)) # Start the hemispherical integration vzas_psis = ((vza, psi) for vza in range(5, 90, stepvza) for psi in range(0, 360, steppsi)) for vza, psi in vzas_psis: [ tss, too, tsstoo, rdd, tdd, rsd, tsd, rdo, tdo, rso, rsos, rsod, rddt, rsdt, rdot, rsodt, rsost, rsot, gammasdf, gammasdb, gammaso ] = FourSAIL.FourSAIL(LAI, hotspot, lidf, sza, vza, psi, rho_leaf, tau_leaf, rsoil) # Downwelling solar beam radiation at ground level (beam transmissnion) Es_1 = tss * Es # Upwelling diffuse shortwave radiation at ground level Ed_up_1 = (rsoil * (Es_1 + tsd * Es + tdd * Ed)) / (1. - rsoil * rdd) # Downwelling diffuse shortwave radiation at ground level Ed_down_1 = tsd * Es + tdd * Ed + rdd * Ed_up_1 # Upwelling shortwave (beam and diffuse) radiation towards the observer (at angle psi/vza) Eo_0 = (rso * Es + rdo * Ed + tdo * Ed_up_1 + too * Ed_up_1) # Calculate the reflectance factor and project into the solid angle cosvza = np.cos(np.radians(vza)) sinvza = np.sin(np.radians(vza)) # Spectral flux at the top of the canopy So = Eo_0 * cosvza * sinvza * np.radians(stepvza) * np.radians(steppsi) # Spectral flux at ground lnevel Sn_soil = (1. - rsoil) * (Es_1 + Ed_down_1 ) # narrowband net soil shortwave radiation # Get the to of the canopy flux (as it is not Lambertian) So_sw_dir = So / np.pi # Add the top of the canopy flux to the integral and continue through the hemisphere So_sw = So_sw + So_sw_dir # Calculate the vegetation (sw/lw) net radiation (divergence) as residual of top of the canopy and net soil radiation Esw = Es + Ed Rn_sw_veg_nb = Esw - So_sw - Sn_soil # narrowband net canopy sw radiation fAPAR = sum(Rn_sw_veg_nb) / len( Rn_sw_veg_nb) # broadband net canopy sw radiation fIPAR = 1.0 - (Es_1 + Ed_down_1) / Esw fIPAR = sum(fIPAR) / len(fIPAR) return fAPAR, fIPAR
samples[:, 4], samples[:, 5], samples[:, 6]) N_samples_canopy = N * (problem_canopy['num_vars'] + 2) print('Generating %s simulations for SAIL' % N_samples_canopy) samples = saltelli.sample(problem_canopy, N, calc_second_order=calc_second_order) print('Running ProspectD+4SAIL') l, r, t = ProspectD.ProspectD_vec(samples[:, 0], samples[:, 1], samples[:, 2], samples[:, 3], samples[:, 4], samples[:, 5], samples[:, 6]) lidf = FourSAIL.CalcLIDF_Campbell_vec(samples[:, 8]) # Read the soil reflectance rsoil = np.genfromtxt( pth.join(soil_folder, 'ipgp.jussieu.soil.prosail.dry.coarse.1.spectrum.txt')) #wl_soil=rsoil[:,0] rsoil = np.array(rsoil[:, 1]) rsoil = np.repeat(rsoil[:, np.newaxis], N_samples_canopy, axis=1) [_, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _, _] = FourSAIL.FourSAIL_vec(samples[:, 7], np.ones(N_samples_canopy) * 0.01, lidf, np.ones(N_samples_canopy) * 37., np.zeros(N_samples_canopy),
def FCost_ProSail_wl(x0, ObjParam, FixedValues, n_obs, rho_canopy, vza, sza, psi, skyl, rsoil, wls, scale): ''' Cost Function for inverting PROSPEC5 + 4SAIL based on the Mean Square Error of observed vs. modeled reflectances and scaled [0,1] parameters Parameters ---------- x0 : list Scaled (0-1) a priori PROSAIL values to be retrieved during the inversion. ObjParam : list PROSAIL parameters to be retrieved during the inversion, sorted in the same order as in the param list. ObjParam'=['N_leaf','Cab','Car','Cbrown', 'Cw','Cm', 'LAI', 'leaf_angle','hotspot']. FixedValues' : dict Values of the parameters that are fixed during the inversion. The dictionary must complement the list from ObjParam. N_obs : int the total number of observations used for the inversion. N_Obs=1. rho_canopy : 2D-array observed surface reflectances. The size of this list be N_obs x n_wls. vza : list View Zenith Angle for each one of the observations. The size must be equal to N_obs. sza : list Sun Zenith Angle for each one of the observations. The size must be equal to N_obs. psi : list Relative View-Sun Angle for each one of the observations. The size must be equal to N_obs. skyl : 2D-array ratio of diffuse radiation for each one of the observations. The size must be equal to N_obs x wls. rsoil : 1D-array background (soil) reflectance. The size must be equal to n_wls. wls : list wavebands used in the inversion. The size must be equal to n_wls. scale : list minimum and scale tuple (min,scale) for each objective parameter. Returns ------- mse : float Mean Square Error of observed vs. modelled surface reflectance This is the function to be minimized.''' param_list = FourSAILJacobian.paramsPro4SAIL # Get the a priori parameters and fixed parameters for the inversion input_parameters = dict() i = 0 j = 0 for param in param_list: if param in ObjParam: #Transform the random variables (0-1) into biophysical variables input_parameters[param] = x0[i] * float(scale[i][1]) + float( scale[i][0]) i = i + 1 else: input_parameters[param] = FixedValues[j] j = j + 1 # Start processing n_wl = len(wls) error = np.zeros(n_obs * n_wl) #Calculate LIDF lidf = FourSAIL.CalcLIDF_Campbell(float(input_parameters['leaf_angle'])) i = 0 for obs in range(n_obs): j = 0 for wl in wls: [l, r, t] = ProspectD.ProspectD_wl( wl, input_parameters['N_leaf'], input_parameters['Cab'], input_parameters['Car'], input_parameters['Cbrown'], input_parameters['Cw'], input_parameters['Cm'], input_parameters['Ant']) [ _, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _, _ ] = FourSAIL.FourSAIL_wl(input_parameters['LAI'], input_parameters['hotspot'], lidf, float(sza[obs]), float(vza[obs]), float(psi[obs]), r, t, float(rsoil[j])) r2 = rdot * float(skyl[obs, j]) + rsot * (1 - float(skyl[obs, j])) error[i] = (r2 - rho_canopy[obs, j])**2 i += 1 j += 1 mse = 0.5 * np.mean(error) return mse
# leaf_args[i] = leaf_args[i] + step[param] # l, rho_leaf_up, tau_leaf_up, *_ = JacProspectD(*leaf_args) # Jac_rho_leaf_numerical[i] = (rho_leaf_up - rho_leaf) / step[param] # Jac_tau_leaf_numerical[i] = (tau_leaf_up - tau_leaf) / step[param] # # for i,param in enumerate(leaf_params): # ax1.plot(l, # np.abs((Jac_rho_leaf[i]-Jac_rho_leaf_numerical[i])/Jac_rho_leaf_numerical[i]), # color=colors[i], label = param) # ax2.plot(l,Jac_rho_leaf_numerical[i], # color=colors[i], label = param) # ax3.plot(l,Jac_rho_leaf[i], # color=colors[i], label = param) # #============================================================================== lidf = FourSAIL.CalcLIDF_Campbell(leaf_angle, n_elements=18) [ tss, too, tsstoo, rdd, tdd, rsd, tsd, rdo, tdo, rso, rsos, rsod, rddt, rsdt, rdot, rsodt, rsost, rsot, gammasdf, gammasdb, gammaso ] = FourSAIL.FourSAIL(LAI, hotspot, lidf, sza, vza, psi, rho_leaf, tau_leaf, rsoil) rho_canopy = skyl * rdot + (1 - skyl) * rsot Jac_rho_canopy_numerical = np.zeros((len(Params), 2101)) for j, param in enumerate(Params): canopy_args = [ N_leaf, Cab, Car, Cbrown, Cw, Cm, Ant, LAI, hotspot, leaf_angle ] canopy_args[j] = canopy_args[j] + step[param] l, rho_leaf_up, tau_leaf_up = ProspectD(*canopy_args[0:7])
def calc_fapar_4sail(skyl, LAI, lidf, hotspot, sza, rho_leaf, tau_leaf, rsoil): '''Estimates the fraction of Absorbed and intercepted PAR using the 4SAIL Radiative Transfer Model. Parameters ---------- skyl : float Ratio of diffuse to total PAR radiation LAI : float Leaf (Plant) Area Index lidf : list Leaf Inclination Distribution Function, 5 degrees step hotspot : float hotspot parameters, use 0 to ignore the hotspot effect (turbid medium) sza : float Sun Zenith Angle (degrees) rho_leaf : list Narrowband leaf bihemispherical reflectance, it might be simulated with PROSPECT (400-700 @1nm) tau_leaf : list Narrowband leaf bihemispherical transmittance, it might be simulated with PROSPECT (400-700 @1nm) rsoil : list Narrowband soil bihemispherical reflectance (400-700 @1nm) Returns ------- fAPAR : float Fraction of Absorbed Photosynthetically Active Radiation fIPAR : float Fraction of Intercepted Photosynthetically Active Radiation''' # Diffuse and direct irradiance Es = 1.0 - skyl Ed = skyl #Initialize values S_0 = np.zeros(rho_leaf.shape) S_1 = np.zeros(rho_leaf.shape) # Start the hemispherical integration vzas_psis = ((vza, psi) for vza in np.arange(0, 90 - STEP_VZA / 2., STEP_VZA) for psi in np.arange(0, 360, STEP_PSI)) step_vza_radians, step_psi_radians = np.radians(STEP_VZA), np.radians( STEP_PSI) for vza, psi in vzas_psis: vza += STEP_VZA / 2. # Calculate the reflectance factor and project into the solid angle cosvza = np.cos(np.radians(vza)) sinvza = np.sin(np.radians(vza)) [ tss, _, _, rdd, tdd, _, tsd, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _, _ ] = FourSAIL.FourSAIL_vec(LAI, hotspot, lidf, sza, np.ones(LAI.shape) * vza, np.ones(LAI.shape) * psi, rho_leaf, tau_leaf, rsoil) # Downwelling solar beam radiation at ground level (beam transmissnion) Es_1 = tss * Es # Upwelling diffuse shortwave radiation at ground level Ed_up_1 = (rsoil * (Es_1 + tsd * Es + tdd * Ed)) / (1. - rsoil * rdd) # Downwelling diffuse shortwave radiation at ground level Ed_down_1 = tsd * Es + tdd * Ed + rdd * Ed_up_1 # Upwelling shortwave (beam and diffuse) radiation towards the observer (at angle psi/vza) Eo_0 = rdot * Ed + rsot * Es # Spectral flux at the top of the canopy # & add the top of the canopy flux to the integral and continue through the hemisphere S_0 += Eo_0 * cosvza * sinvza * step_vza_radians * step_psi_radians # Spectral flus at the bottom of the canopy # & add the bottom of the canopy flux to the integral and continue through the hemisphere S_1 += ( Es_1 + tdd * Ed) * cosvza * sinvza * step_vza_radians * step_psi_radians / np.pi # Absorbed flux at ground lnevel Sn_soil = (1. - rsoil) * (Es_1 + Ed_down_1 ) # narrowband net soil shortwave radiation # Calculate the vegetation (sw/lw) net radiation (divergence) as residual of top of the canopy and net soil radiation Rn_sw_veg_nb = 1.0 - S_0 - Sn_soil # narrowband net canopy sw radiation fAPAR = np.sum( Rn_sw_veg_nb, axis=0) / Rn_sw_veg_nb.shape[0] # broadband net canopy sw radiation fIPAR = np.sum(1.0 - S_1, axis=0) / S_1.shape[0] return fAPAR, fIPAR
def simulate_prosail_lut(input_param, wls_sim, rsoil_vec, skyl=0.1, sza=37, vza=0, psi=0, srf=None, outfile=None, calc_FAPAR=False, reduce_4sail=False): print('Starting Simulations') # Calculate the lidf lidf = FourSAIL.CalcLIDF_Campbell_vec(input_param['leaf_angle']) #for i,wl in enumerate(wls_wim): [wls, r, t] = ProspectD.ProspectD_vec(input_param['N_leaf'], input_param['Cab'], input_param['Car'], input_param['Cbrown'], input_param['Cw'], input_param['Cm'], input_param['Ant']) r = r.T t = t.T if type(skyl) == float: skyl = skyl * np.ones(r.shape) if calc_FAPAR: par_index = wls <= 700 rho_leaf_fapar = np.mean(r[par_index], axis=0).reshape(1, -1) tau_leaf_fapar = np.mean(t[par_index], axis=0).reshape(1, -1) skyl_rho_fapar = np.mean(skyl[par_index], axis=0).reshape(1, -1) rsoil_vec_fapar = np.mean(rsoil_vec[par_index], axis=0).reshape(1, -1) par_index = wls_sim <= 700 #Convolve the simulated spectra to a gaussian filter per band rho_leaf = [] tau_leaf = [] skyl_rho = [] rsoil = [] if srf and reduce_4sail: if type(srf) == float or type(srf) == int: wls_sim = np.asarray(wls_sim) #Convolve spectra by full width half maximum sigma = fwhm2sigma(srf) r = gaussian_filter1d(r, sigma, axis=1) t = gaussian_filter1d(t, sigma, axis=1) s = gaussian_filter1d(skyl, sigma, axis=1) soil = gaussian_filter1d(rsoil_vec, sigma, axis=1) for wl in wls_sim: rho_leaf.append(r[wls == wl].reshape(-1)) tau_leaf.append(t[wls == wl].reshape(-1)) skyl_rho.append(s[wls == wl].reshape(-1)) rsoil.append(soil[wls == wl].reshape(-1)) elif type(srf) == list or type(srf) == tuple: skyl = np.tile(skyl, (r.shape[1], 1)).T for weight in srf: weight = np.tile(weight, (r.shape[1], 1)).T rho_leaf.append( np.sum(weight * r, axis=0) / np.sum(weight, axis=0)) tau_leaf.append( np.sum(weight * t, axis=0) / np.sum(weight, axis=0)) skyl_rho.append( np.sum(weight * skyl, axis=0) / np.sum(weight, axis=0)) rsoil.append( np.sum(weight * rsoil_vec, axis=0) / np.sum(weight, axis=0)) skyl_rho = np.asarray(skyl_rho) elif reduce_4sail: wls_sim = np.asarray(wls_sim) for wl in wls_sim: rho_leaf.append(r[wls == wl].reshape(-1)) tau_leaf.append(t[wls == wl].reshape(-1)) skyl_rho.append(skyl[wls == wl].reshape(-1)) rsoil.append(rsoil_vec[wls == wl].reshape(-1)) else: rho_leaf = r.T tau_leaf = t.T skyl_rho = np.asarray(skyl.T) rsoil = np.asarray(rsoil_vec) rho_leaf = np.asarray(rho_leaf) tau_leaf = np.asarray(tau_leaf) skyl_rho = np.asarray(skyl_rho) rsoil = np.asarray(rsoil) [_, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _, _] = FourSAIL.FourSAIL_vec(input_param['LAI'], input_param['hotspot'], lidf, np.ones(input_param['LAI'].shape) * sza, np.ones(input_param['LAI'].shape) * vza, np.ones(input_param['LAI'].shape) * psi, rho_leaf, tau_leaf, rsoil) r2 = rdot * skyl_rho + rsot * (1 - skyl_rho) del rdot, rsot if calc_FAPAR: fAPAR_array, fIPAR_array = calc_fapar_4sail( skyl_rho_fapar, input_param['LAI'], lidf, input_param['hotspot'], np.ones(input_param['LAI'].shape) * sza, rho_leaf_fapar, tau_leaf_fapar, rsoil_vec_fapar) fAPAR_array[np.isfinite(fAPAR_array)] = np.clip( fAPAR_array[np.isfinite(fAPAR_array)], 0, 1) fIPAR_array[np.isfinite(fIPAR_array)] = np.clip( fIPAR_array[np.isfinite(fIPAR_array)], 0, 1) input_param['fAPAR'] = fAPAR_array input_param['fIPAR'] = fIPAR_array del fAPAR_array, fIPAR_array rho_canopy = [] if srf and not reduce_4sail: if type(srf) == float or type(srf) == int: #Convolve spectra by full width half maximum sigma = fwhm2sigma(srf) r2 = gaussian_filter1d(r2, sigma, axis=1) for wl in wls_sim: rho_canopy.append(r2[wls == wl].reshape(-1)) elif type(srf) == list or type(srf) == tuple: for weight in srf: weight = np.tile(weight, (1, r2.shape[2])).T rho_canopy.append( np.sum(weight * r2, axis=0) / np.sum(weight, axis=0)) elif reduce_4sail: rho_canopy = np.asarray(r2) else: for wl in wls_sim: rho_canopy.append(r2[wls == wl].reshape(-1)) rho_canopy = np.asarray(rho_canopy) if outfile: fid = open(outfile + '_rho', 'wb') pickle.dump(rho_canopy, fid, -1) fid.close() fid = open(outfile + '_param', 'wb') pickle.dump(input_param, fid, -1) fid.close() return rho_canopy.T, input_param