Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
    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),
Exemplo n.º 5
0
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
Exemplo n.º 6
0
                                        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),
Exemplo n.º 7
0
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
Exemplo n.º 8
0
    #         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])
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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