Example #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
Example #2
0
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),
                            np.zeros(N_samples_canopy), r.T, t.T, rsoil)

rho_canopy = rdot * 0.2 + rsot * (1.0 - 0.2)
#Convolve spectra by full width half maximum
sigma = fwhm / (2.0 * np.sqrt(2.0 * np.log(2.0)))
rho_canopy = gaussian_filter1d(rho_canopy, sigma, axis=0)

rho_canopy_nadir = rho_canopy.T

# Run oblique observations
[_, _, _, _, _, _, _, _, _, _, _, _, _, _, rdot, _, _, rsot, _, _,
 _] = FourSAIL.FourSAIL_vec(input_param['LAI'], input_param['hotspot'], lidf,
                            np.ones(N_samples_canopy) * 37.,
                            np.ones(N_samples_canopy) * 40.,
                            np.zeros(N_samples_canopy), r.T, t.T, rsoil)
Example #3
0
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),
                            np.zeros(N_samples_canopy), r.T, t.T, rsoil)

rho_canopy = rdot * 0.2 + rsot * (1.0 - 0.2)
if fwhm:
    #Convolve spectra by full width half maximum
    sigma = fwhm / (2.0 * np.sqrt(2.0 * np.log(2.0)))
    rho_canopy = gaussian_filter1d(rho_canopy, sigma, axis=0)

rho_canopy = rho_canopy.T

del r, t, lidf, _, rdot, rsot, rsoil

print('Running Sensitivity Analysis')
Example #4
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
Example #5
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