Esempio n. 1
0
def test_rsdt_prosail5(datadir):
    fname = datadir("REFL_CAN.txt")
    w, resv, rdot, rsot, rddt, rsdt = np.loadtxt(fname,
             unpack=True)
    rr = prosail.run_prosail(1.5, 40., 8., 0.0, 0.01, 0.009, 3., -0.35, 0.01,
                        30., 10., 0., typelidf=1, lidfb=-0.15, 
                        rsoil = 1., psoil=1., factor="DHR")
    assert np.allclose(rsdt, rr, atol=0.01)
def call_prosail ( n, cab, car, cbrown, cw, cm, lai, lidf, rsoil, 
             psoil, hspot, sza, vza, vaa ):
    """Helper function"""
    r = prosail.run_prosail ( n, cab, car, cbrown, cw, cm, 
                             lai, lidf, 0, rsoil, psoil, hspot, sza, vza, vaa, 2 )
    rpass = np.isfinite ( r )
    x = np.arange(400, 2501 )
    ri = np.interp ( x, x[rpass], r[rpass])
    return ri
def brdfModel(s,vza,sza,raa):
  '''
  Run the full BRDF model for parameters in s
  '''
 
  try:
    brdf = []
    for i in xrange(len(s['n'])):
      brdf.append(run_prosail(s['n'][i],s['cab'][i],s['car'][i],s['cbrown'][i],s['cw'][i],s['cm'][i],\
                s['lai'][i],s['ala'][i],0.0,s['bsoil'][i],s['psoil'][i],s['hspot'][i],\
                vza[i],sza[i],raa[i],2))
  except:
    brdf = []
    for i in xrange(len(s['n'])):
      brdf.append(run_prosail(s['n'][i],s['cab'][i],s['car'][i],s['cbrown'][i],s['cw'][i],s['cm'][i],\
                s['lai'][i],s['ala'][i],0.0,s['bsoil'][i],s['psoil'][i],s['hspot'][i],\
                vza,sza,raa,2))
  return (vza,sza,raa),transform(s),fixnan(np.array(brdf))
Esempio n. 4
0
def prosail8d(N, CAB, CW, CM, LAI, LAD, PSOIL, SZA):
    """Generates Prosail Data
    
    Parameters
    ----------
    N : float
        Leaf Structure Parameter
    
    CAB : float 
        Leaf Chlorophyll Concentration
    
    CW : float 
        Equivalent Leaf Water
    
    CM : float
        Leaf Dry Matter
    
    LAI : float
        Leaf Area Index
    
    LAD : float
        Leaf angle distribution
    
    PSOIL : float 
        Solar Scalar 2 (Moisture)
    
    SZA : float
        Solar Zenith Angle
    
    Returns
    -------
    
    spectrum : np.ndarray (2101, )
        The generated spectrum for prosail
    """

    return prosail.run_prosail(
        n=N,  # Leaf Structure Parameter
        cab=CAB,  # Chlorophyll a + b
        car=0,  # Leaf Cartenoid Concentration
        cbrown=0,  # Senescent Pigment
        cw=CW,  # Equivalent Leaf Water
        cm=CM,  # Leaf Dry Matter
        lai=LAI,  # Leaf Area Index
        lidfa=LAD,  # Leaf Angle Distribution (a)
        hspot=0.01,  # HotSpot
        tts=SZA,  # Sun Zenith Angle
        tto=0,  # Sensor zenith angle
        psi=0.0,  # Relative Sensor-Solar Azimuth angle
        ant=0,  # leaf antho. concen.
        alpha=40,  #
        psoil=PSOIL,
        rsoil=1.0,
    )
Esempio n. 5
0
def cpled_model(x, wavebands, sza, saa, vza, vaa, day, month, do_trans=True):
    """A coupled land surface/atmospheric model, predicting TOA refl from
    land surface parameters and atmospheric composition parameters. This
    function provides estimates of TOA refl for 
    * A particular date
    * A particular illumination geometry
    
    The underlying land surface reflectance spectra is simulated using
    PROSAIL, and the atmospheric calculations are done with 6S. The coupling
    assumes a Lambertian land surface

        The input parameter ``x`` is a vector with the following components:
        
        * ``n``
        * ``cab``
        * ``car``
        * ``cbrown``
        * ``cw``
        * ``cm``
        * ``lai``
        * ``ala``
        * ``bsoil``
        * ``psoil``
        * ``aot_550``
        * ``o3_conc``
        * ``cwc``

    """
    from prosail import run_prosail
    # Invert parameter LAI

    if do_trans:
        x = inverse_transform(x)
    ################# surface refl with prosail #####################
    surf_refl = np.c_[ np.arange(400, 2501)/1000., \
        run_prosail(x[0], x[1], x[2], x[3], \
        x[4], x[5], x[6], x[7], 0, x[8], x[9], 0.01, sza, vza, vaa, 2 )]
    ################# Atmospheric modelling with 6s ##################
    o3 = x[-2]
    cwc = x[-1]
    aot = x[-3]
    s, retvals = atcorr ( wavebands, o3, cwc, aot, surf_refl, sza, saa, vza, \
            vaa, day, month )

    ################ Per band coupling ###############################
    refl_toa = []
    for i, sixs_output in enumerate(retvals):
        rho_surf = np.interp( wavebands[i], \
                surf_refl[:,0], surf_refl[:,1])
        refl_toa.append(to_refltoa(sixs_output, rho_surf))
    return np.array(refl_toa)
Esempio n. 6
0
def optical_forward_operator(x, sza, vza, raa, version="PROSAIL_D",
                             hspot=0.01):
    """A generic wrapper to the PROSPECT+SAIL operators. Uses either PROSPECT D
    or PROSPECT 5. The state vector is given as a 1D vector, with parameters
    in order:
    1. N (leaf layers)
    2. Ant (if using PROSPECT-D, Anthocyanins, ug/cm2)
    3. Cab (leaf chlorophyll conc, ug/cm2)
    4. Car (leaf carotenoids conc, ug/cm2)
    5. Cbrown (senescent pigment-like concentration, -)
    6. Cw (equivalent leaf water thickness, cm)
    7. Cm (dry matter, g/cm2)
    8. LAI (leaf area index, m2/m2)
    9. ALA (average leaf angle, deg)
    10. rsoil (dry soil scalar)
    11. psoil (wet soil scalar)

    Additionally, one needs to pass the different view/illumination angles, and
    optionally the value of the hotspot parameter. The function returns the
    top of canopy reflectance between 400 and 2500 nm every 1 nm.
    """
    if not version.upper() in ["PROSAIL_D", "PROSAIL_5"]:
        raise ValueError("Can only deal with SAIL + PROSPECT D or 5!")

    if version.upper() == "PROSAIL_D":
        # Using prospect D
        n, ant, cab, car, cbrown, cw, cm, lai, ala, rsoil, psoil = x
        rho_canopy = run_prosail(n, cab, car,  cbrown, cw, cm, lai, ala, hspot,
                                 sza, vza, raa, ant=ant, prospect_version="D",
                                 rsoil=rsoil, psoil=psoil)

    elif version.upper() == "PROSAIL_5":
        n, cab, car, cbrown, cw, cm, lai, ala, rsoil, psoil = x
        rho_canopy = run_prosail(n, cab, car,  cbrown, cw, cm, lai, ala, hspot,
                                 sza, vza, raa, prospect_version="5",
                                 rsoil=rsoil, psoil=psoil)
    return rho_canopy
Esempio n. 7
0
def generate_spectrum(p):
    return ps.run_prosail(n=p[0],
                          cab=p[1],
                          cw=p[2],
                          car=p[3],
                          cbrown=p[4],
                          cm=p[5],
                          lai=p[6],
                          lidfa=p[7],
                          psoil=p[8],
                          rsoil=p[9],
                          hspot=p[10],
                          tts=p[11],
                          tto=p[12],
                          psi=p[13],
                          ant=p[14],
                          prospect_version="D")
def gen_samp_noise_angle_withsoil(nsamples, parameters,p_mins, p_maxs, tts, tto, psi):
    samples, distributions = gp_emulator.create_training_set(parameters, p_mins, p_maxs, n_train=nsamples)
    simu_ref = np.zeros((nsamples, 2101))
    for i in range (nsamples) :
        noise = np.random.normal(0,1,2101)/500.
        simu_ref[i,:] = prosail.run_prosail(samples[i,0], samples[i,1], samples[i,2], samples[i,3], samples[i,4], 
                                            samples[i,5], samples[i,6], samples[i,7], 
                                            0.01, tts=tts, tto=tto, psi=psi,
                                            prospect_version='D',typelidf = 2,
                                            rsoil = samples[i,8], psoil = samples[i,9])+noise
    for i in range(len(samples)):
        "n", "exp(-cab/100)", "exp(-car/100)", "cbrown", "exp(-50*cw)", "exp(-50*cm)", "exp(-lai/2)", "ala/90.", "bsoil", "psoil"
    samples[:,1] = np.exp(-samples[:,1]/100.)
    samples[:,2] = np.exp(-samples[:,2]/100.)
    samples[:,4] = np.exp(-50.*samples[:,4])
    samples[:,5] = np.exp(-50.*samples[:,5])    
    samples[:,6] = np.exp(-samples[:,6]/2.)
    samples[:,7] = samples[:,7]/90.    
    return simu_ref, samples
Esempio n. 9
0
def trans_prosail ( N, cab, car, cbrown, cw, cm, lai, lidfa, lidfb, bsoil, psoil, \
        hspot, tts, tto, psi ,lidfType):
    """A version of PROSAIL that uses transformed parameters to quasi-linearise
    the   model. See http://dx.doi.org/10.1016/j.rse.2011.12.027"""
    # Define the constants
    slai = -2.0
    skab = -100.0
    skar = -100.0
    skw =  -1./50.
    skm =  -1./100.
    # Transform the parameters to real units
    xlai = slai * np.log ( lai )
    xkab = skab * np.log ( cab )
    xkar = skar * np.log ( car )
    xkw = skw * np.log ( cw )
    xdm = skm * np.log ( cm )
    # Run the PROSAIL model
    retval = run_prosail ( N, xkab, xkar, cbrown, xkw, xdm, xlai, \
            lidfa, lidfb,bsoil, psoil, hspot, tts, tto, psi ,lidfType)
    return retval
Esempio n. 10
0
def call_prosail(n, cab, car, ant, cbrown, cw, cm, lai, lidf, rsoil, psoil,
                 hspot, sza, vza, vaa):
    """Helper function"""
    r = prosail.run_prosail(n,
                            cab,
                            car,
                            cbrown,
                            cw,
                            cm,
                            lai,
                            lidf,
                            hspot,
                            sza,
                            vza,
                            vaa,
                            ant=ant,
                            rsoil=rsoil,
                            psoil=psoil,
                            prospect_version="D")
    rpass = np.isfinite(r)
    x = np.arange(400, 2501)
    ri = np.interp(x, x[rpass], r[rpass])
    return ri
Esempio n. 11
0
def test_rddt_prosail5(datadir):
    fname = datadir("REFL_CAN.txt")
    w, resv, rdot, rsot, rddt, rsdt = np.loadtxt(fname, unpack=True)
    rr = prosail.run_prosail(
        1.5,
        40.0,
        8.0,
        0.0,
        0.01,
        0.009,
        3.0,
        -0.35,
        0.01,
        30.0,
        10.0,
        0.0,
        typelidf=1,
        lidfb=-0.15,
        rsoil=1.0,
        psoil=1.0,
        factor="BHR",
    )
    assert np.allclose(rddt, rr, atol=0.01)
Esempio n. 12
0
import prosail
import numpy as np
import matplotlib.pyplot as plt
from prosail import run_prosail

rr = run_prosail(1.5,
                 40.,
                 8.,
                 0.0,
                 0.01,
                 0.009,
                 3.,
                 -0.35,
                 0.01,
                 30.,
                 10.,
                 0.,
                 typelidf=1,
                 lidfb=-0.15,
                 rsoil=1.,
                 psoil=1.,
                 factor="SDR")
plt.plot(np.arange(400, 2501), rr, 'r-')
plt.show()
Esempio n. 13
0
def do_fwd_model ( x, sza, vza, raa ):
    x = inverse_transform ( x )
    ################# surface refl with prosail #####################
    surf_refl = prosail.run_prosail(x[0], x[1], x[2], x[3], \
        x[4], x[5], x[6], x[7], 0, x[8], x[9], 0.01, sza, vza, raa, 2 )
    return surf_refl
Esempio n. 14
0
def create_observations2 ( state, parameter_grid, latitude, longitude, the_time="10:30",\
        b_min = np.array( [ 620., 841, 459, 545, 1230, 1628, 2105] ), \
        b_max = np.array( [ 670., 876, 479, 565, 1250, 1652, 2155] ), \
        every=5, prop=0.4, WINDOW=3, noise_scalar=1, vza_var=7., emu_dir="./"):
    """This function creates the observations for  a given temporal evolution
    of parameters, loation, and bands. By default, we take only MODIS bands. 
    The function does a number of other things:
    1.- Calculate missing observations due to simulated cloud
    2.- Add noise
    TODO: There's a problem  with pyephem, gives silly solar altitudes!!!"""
    wv = np.arange ( 400, 2501 )
    n_bands = b_min.shape[0]
    band_pass = np.zeros(( n_bands,2101), dtype=np.bool)
    bw = np.zeros( n_bands )
    bh = np.zeros( n_bands )
    for i in xrange( n_bands ):
        band_pass[i,:] = np.logical_and ( wv >= b_min[i], \
                wv <= b_max[i] )
        bw[i] = b_max[i] - b_min[i]
        bh[i] = ( b_max[i] + b_min[i] )/2.
    import ephem
    o = ephem.Observer()
    o.lat, o.long, o.date = latitude, longitude, "2011/1/1 %s" % the_time
    dd = o.date

    t = np.arange ( np.random.randint(1,every), 366 )
    obs_doys = np.array ( [ i for i in t if i % every == 0 ] )
    

    #prop = 0.4
    #WINDOW = 3
    weightings = np.repeat(1.0, WINDOW) / WINDOW
    
    xx = np.convolve(np.random.rand(len(t)*100),weightings,'valid')[WINDOW:WINDOW+len(t)]

    maxx = sorted(xx)[:int(len(xx)*prop)]
    mask = np.in1d(xx,maxx)
    doys_nocloud = t[mask]
    x = np.in1d ( obs_doys, doys_nocloud )
    obs_doys = obs_doys[x]
    vza = np.zeros_like ( obs_doys, dtype=np.float)
    sza = np.zeros_like ( obs_doys, dtype=np.float)
    raa = np.zeros_like ( obs_doys, dtype=np.float)
    rho = np.zeros (( len(bw), obs_doys.shape[0] ))
    sigma_obs = (0.05-0.01)*(bh-bh.min())/(bh.max()-bh.min())
    sigma_obs += 0.01
    sigma_obs = sigma_obs * noise_scalar
    S = np.array([22, 37, 52, 70])
    for i,doy in enumerate(obs_doys):
        j = doy - 1 # location in parameter_grid...
        vza[i] = np.random.rand(1)*vza_var # 15 degs 
        o.date = dd + doy
        sun = ephem.Sun ( o )
        sza[i] = 90. - float(sun.alt )*180./np.pi
        ##sza[i] = S[np.argmin ( np.abs ( xx-S))]
        ##sza[i] = 37
        vaa = np.random.rand(1)*360.
        saa = np.random.rand(1)*360.
        raa[i] = 0.0#vaa - saa
        p = np.r_[parameter_grid[:8,j],0,parameter_grid[8:, j], 0.01,sza[i], vza[i], raa[i], 2 ]
        
        r =  fixnan( np.atleast_2d ( prosail.run_prosail ( *p )) ).squeeze()
        rho[:, i] = np.array ( [r[ band_pass[ii,:]].sum()/bw[ii] \
            for ii in xrange(n_bands) ] )
        rho[:, i] = np.clip (rho[:, i] + np.random.randn ( n_bands )*sigma_obs, 1e-4, 0.999)
        srza = float(int(sza[i]) - (int(sza[i])%5))
        vrza = float(int(vza[i]) - (int(vza[i])%5))
        emulator_name = os.path.join ( emu_dir, "%03.1f_%03.1f_%03.1f_prosail.npz" % ( srza, vrza, raa[i] ) ) 
        if not os.path.exists ( emulator_name ):
            print "Creating emulator for %s" % emulator_name
            gp = create_prosail_emulators ( sza, vza, raa )
            gp.dump_emulator ( emulator_name )
    return obs_doys, vza, sza, raa, rho, sigma_obs     
Esempio n. 15
0
    def gen_lut(self, inv_mapping_table, inv_table,
                landcover_config_path=None, prosail_config_path=None,
                soil_path=None):
        """
        Generates the lookup table and stores it in the DB
        must be run seperately from the inversion part

        Parameters
        ----------
        inv_mapping_table : String
            name of the table storing the inversion mapping required for
            performing the inversion
        inv_table : String
            Name of the table the lookup-table should be written to
            (<schema.table>)
        landcover_config_path : String
            file-path to landcover config file (opt.; per default the OBIA4RTM
            delivered file will be used)
        prosail_config_path : String
            file-path to landcover config file (opt.; per default the OBIA4RTM
            delivered file will be used)
        soil_path : String
            file-path to file with soil reflectance values (opt.; per default
            the OBIA4RTM delivered file will be used)

        Returns:
        --------
        None
        """
        # get scene metadata first
        self.get_scene_metadata()
        # basic setup first
        # get S2 sensor-response function
        resampler = get_resampler(self.conn,
                                  self.cursor,
                                  self.__sensor,
                                  self.__logger)

        # params that could be inverted
        list_of_params = ['n', 'cab', 'car', 'cbrown', 'cw', 'cm', 'lai',
                          'lidfa', 'lidfb', 'rsoil', 'psoil', 'hspot',
                          'typelidf']
        # firstly, create the LUT from the params config file for the
        # defined land cover classes
        if prosail_config_path is None:
            prosail_config = self.set_ProSAIL_config()
        else:
            prosail_config = self.set_ProSAIL_config(prosail_config_path)
        if landcover_config_path is None:
            landcover_config = self.set_landcover_config()
        else:
            landcover_config = self.set_landcover_config(landcover_config_path)
        # default soil-spectra -> use soil_reflectance from ProSAIL package
        if soil_path is None:
            soils = self.set_soilrefl()
        else:
            soils = self.set_soilrefl(soil_path)
        # read in the landcover class information and the corresponding
        # prosail parameter setup
        params_container = read_params_per_class(prosail_config,
                                                 landcover_config,
                                                 self.__logger)
        # extract the land cover classes
        lc_keys = list(params_container.keys())
        # loop over the land cover classes and generate the LUT per class
        for lc in lc_keys:
            # extract the land cover code and semantics
            lc_code = lc[0]  # code
            lc_sema = lc[1]  # meaning
            # get the ProSAIL parameters
            # if a land cover class is not found skip
            try:
                params = params_container.get(lc)
            except (ValueError, KeyError):
                self.__logger.warning("Land cover class '{}' specified in config "\
                                      "file but not found in ProSAIL config - "
                                      " skipping".format(lc_code))
                continue
            param_lut = lut.lookup_table()
            param_lut.generate_param_lut(params)
            print("INFO: Start to generate ProSAIL-LUT for class '{0}' with "\
                  "{1} simulations ('{2}')\n".format(
                    lc_sema,
                    param_lut.lut_size,
                    self.scene_id))
            params_inv = dict()
            for ii in range(param_lut.to_be_inv[0].shape[0]):
                params_inv[str(ii)] = list_of_params[param_lut.to_be_inv[0][ii]]
            # convert to json
            params_inv_json = json.dumps(params_inv)
            # write the metadata into the inversion_mapping table
            insert = "INSERT INTO {0} (acquisition_date, " \
                     "params_to_be_inverted, landuse, sensor, scene_id) " \
                     "VALUES('{1}', '{2}', {3}, '{4}', '{5}') "\
                     "ON CONFLICT(scene_id, landuse) DO NOTHING;".format(
                             inv_mapping_table,
                             self.acquisition_date,
                             params_inv_json,
                             lc_code,
                             self.__sensor,
                             self.scene_id)
            try:
                self.cursor.execute(insert)
                self.conn.commit()
            except DatabaseError:
                self.__logger.error("Failed to insert metadata of inversion process!",
                                    exc_info=True)
                close_logger(self.__logger)
                sys.exit(error_message)

            # loop over the parameters stored in the LUT and generate the 
            # according synthetic spectra
            for ii in range(param_lut.lut_size):
                
                # run ProSAIL for each combination in the LUT
                try:
                    n = param_lut.lut[0,ii]
                    cab = param_lut.lut[1,ii]
                    car = param_lut.lut[2,ii]
                    cbrown = param_lut.lut[3,ii]
                    cw = param_lut.lut[4,ii]
                    cm = param_lut.lut[5,ii]
                    lai = param_lut.lut[6,ii]
                    lidfa = param_lut.lut[7,ii]
                    lidfb = param_lut.lut[8,ii]
                    rsoil = param_lut.lut[9,ii]
                    psoil = param_lut.lut[10,ii]
                    hspot = param_lut.lut[11,ii]
                    typelidf = param_lut.lut[12,ii]
                except IndexError:
                    self.__logger.error("No data available for land cover class "\
                                        "'{}'".format(lc_code))
                    close_logger(self.__logger)
                    return
                # run prosail in forward mode -> resulting spectrum is from 
                # 400 to 2500 nm in 1nm steps
                # use Python ProSAIL bindings
                spectrum = prosail.run_prosail(n,
                                               cab,
                                               car,
                                               cbrown,
                                               cw,
                                               cm,
                                               lai,
                                               lidfa,
                                               hspot,
                                               self.__tts,
                                               self.__tto,
                                               self.__psi,
                                               ant=0.0,
                                               alpha=40.,
                                               prospect_version="5", 
                                               typelidf=typelidf,
                                               lidfb=lidfb,
                                               rsoil0=soils[:,0],
                                               rsoil=rsoil,
                                               psoil=psoil,
                                               factor="SDR")
                # resample to SRF of sensor
                # perform resampling from 1nm to S2-bands
                sensor_spectrum = resampler(spectrum)

                # convert to % reflectance
                sensor_spectrum *= 100.

                # store the results in DB
                insert_statement = "INSERT INTO {0} (id, n, cab, car, cbrown, "\
                                    "cw, cm, lai, lidfa, lidfb, rsoil, psoil, "\
                                    "hspot, tts, tto, psi, typelidf, "\
                                    "b2, b3, b4, b5, b6, b7, b8a, b11, b12, "\
                                    "acquisition_date, landuse, scene_id) "\
                                    "VALUES ({1}, {2}, {3}, {4}, {5}, {6}, {7}, "\
                                    "{8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, " \
                                    "{18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, '{27}', " \
                                    "{28}, '{29}') ON CONFLICT (id, scene_id, landuse) "\
                                    "DO NOTHING;".format(
                                            inv_table,
                                            ii,
                                            np.round(n, 4),
                                            np.round(cab, 4),
                                            np.round(car, 4),
                                            np.round(cbrown, 4),
                                            np.round(cw, 4),
                                            np.round(cm, 4),
                                            np.round(lai, 4),
                                            np.round(lidfa, 4),
                                            np.round(lidfb, 4),
                                            np.round(rsoil, 4),
                                            np.round(psoil, 4),
                                            np.round(hspot, 4),
                                            np.round(self.__tts, 4),
                                            np.round(self.__tto, 4),
                                            np.round(self.__psi, 4),
                                            np.round(typelidf, 2),
                                            np.round(sensor_spectrum[0], 4),
                                            np.round(sensor_spectrum[1], 4),
                                            np.round(sensor_spectrum[2], 4),
                                            np.round(sensor_spectrum[3], 4),
                                            np.round(sensor_spectrum[4], 4),
                                            np.round(sensor_spectrum[5], 4),
                                            np.round(sensor_spectrum[6], 4),
                                            np.round(sensor_spectrum[7], 4),
                                            np.round(sensor_spectrum[8], 4),
                                            self.acquisition_date,
                                            lc_code,
                                            self.scene_id
                                            )
                try:
                    self.cursor.execute(insert_statement)
                    self.conn.commit()
                except DatabaseError:
                    self.__logger.error("INSERT of synthetic spectra failed!",
                                        exc_info=True)
                    continue