Esempio n. 1
0
def forward_model ( mcmc_results, parameter_names, \
        observations="sim04_obs_l10_g6_n58.csv", \
        meteo_drivers="sim04_met_l10_g6_n58.csv"):
    from dalec import dalec
    meteo_data = np.loadtxt( meteo_drivers, delimiter="," )
    obs_nee = np.loadtxt ( observations, delimiter="," )
    missing_obs = obs_nee[ :, 1] < -9998
    nsamples = mcmc_results.shape[1]/2
    parameters = mcmc_results[:, :nsamples]
    sel = np.random.randint ( 0, nsamples-1, size=500 )
    #x_init = np.array ( [ 0.513303, 4891.44, 134.927, 82.27539, \
    #    74.74379, 12526.28 ] )
    i = 0
    model_nee = np.zeros ( ( 500, meteo_data.shape[0] ) )
    for params in sel:
        if parameters.shape[0] == 23:
            retval = dalec ( parameters[17:, params], \
            parameters[:17, params], meteo_data, \
            -2, 1, 60, 42.2, 2.7)
            #self.psid, self.rtot, self.lma, self.lat, self.nit )
        elif parameters.shape[0] == 24:
            retval = dalec ( parameters[18:, params], \
                parameters[1:18, params], meteo_data, \
                -2, 1, 60, 42.2, 2.7)
                #self.psid, self.rtot, self.lma, self.lat, self.nit )
        else:
            print ">>>>>> Something fishy"
        model_nee[ i, : ] =  retval[ :, -4 ]
        i = i + 1
    #plt.plot ( meteo_data[~missing_obs,0], obs_nee[~missing_obs,1], 'ro' )
    #plt.plot 
    return (model_nee, meteo_data[:,0], obs_nee[:,1], missing_obs, meteo_data )
Esempio n. 2
0
    def likelihood_function ( self, theta ):
        """
        This calculates the likelihood function. It first transforms the
        theta vector into a parameters per grid cell that are then passed on to
        the model object.
        """
        # Load the parameters into a dictionary indexed by grid_ids
        parameters = self._transform_variables_lognorm ( theta )
        if self.truncate:
            if np.any ( parameters > self.hi_val ) or \
                        np.any ( parameters < self.lo_val ):
                return -np.inf
        # Parameter have been loaded nto parameter_list for all grid cells
        # All that needs doing now is to run the model forward for each
        # grid cell and calculate the likelihood function
        retval = dalec ( parameters[17:], parameters[:17], self.meteo_data, \
            self.psid, self.rtot, self.lma, self.lat, self.nit )
        model_nee =  retval[ :, -4 ]
        
        delta = (self.obs_nee[~self.missing_obs, 1] - \
                    model_nee[~self.missing_obs] )**2
        delta = delta / (self.flux_unc**2 )            
        delta = delta[::self.obs_thin]
        p = -0.5*np.sum ( delta )

        p -= delta.shape[0]*( np.log ( np.sqrt(2.*np.pi)*self.flux_unc ))
        self.it += 1
        #pdb.set_trace()
        if self.it%500 == 0:
            print self.it, np.sum(delta), p
            self._plot_fit ( model_nee, p )
        return p
Esempio n. 3
0
    def likelihood_function ( self, theta ):
        """
        This calculates the likelihood function. It first transforms the
        theta vector into a parameters per grid cell that are then passed on to
        the model object.
        """
        # Load the parameters into a dictionary indexed by grid_ids
        tau = theta[0]
        #parameters = self._transform_variables_lognorm ( theta[1:] )
        parameters = theta[1:]
        if self.truncate:
            if np.any ( parameters > self.hi_val ) or \
                    np.any ( parameters < self.lo_val ):
                return -np.inf
        #print tau
        # Parameter have been loaded nto parameter_list for all grid cells
        # All that needs doing now is to run the model forward for each
        # grid cell and calculate the likelihood function
        retval = dalec ( parameters[17:], parameters[:17], self.meteo_data, \
                self.psid, self.rtot, self.lma, self.lat, self.nit )
        model_nee =  retval[ :, -4 ]
        first = True
        p = 0.0
        
        n_obs = self.missing_obs.shape[0]
        for isample in np.arange ( self.missing_obs.shape[0] ):
            if not self.missing_obs [ isample ]:
                if first:
                    # First observation, edge condition, so asymptotic behaviour
                        
                    first = False
                    t_prev = self.meteo_data[ isample, 0 ]

                    p -= np.sum ( np.log ( 2.*np.pi*self.flux_unc ))
                    delta = (self.obs_nee[isample, 1] - \
                            model_nee[isample] )
                    p -= 0.5*(delta**2)/self.flux_unc**2
                    delta_prev = delta
                    # Remember to store t_prev and  delta_prev
                else:
                    # Autoregressive part
                    t_curr = self.meteo_data [isample, 0]
                    # sigma temperated by the temporal correlation
                    sigma_dash = self.flux_unc * np.sqrt ( \
                        (1. - np.exp (-2.*(t_curr-t_prev)/tau))  )
                    delta = (self.obs_nee[isample, 1] - \
                            model_nee[isample] )
                    arf = delta - np.exp (-(t_curr-t_prev)/tau)*delta_prev
                    arf2 = arf*arf 
                    p -= np.log ( np.sqrt(2.*np.pi)*sigma_dash )
                    p -= 0.5*arf2/(sigma_dash*sigma_dash)
                    t_prev = t_curr
                    delta_prev = delta
        self.it += 1
        if self.it % 500 == 0:
            self._plot_fit ( model_nee, p, flag="arf" )
                
        return p
Esempio n. 4
0
    def run_model(self, x, i, store=False):
        """Runs the model forward to ``i+1`` using input state ``x``, 
        assuming parameter vectors stored in the class. The output
        is returned to the user, but also stored in ``self.previous_state``,
        if you told the method to store the data. This is an option as
        one might be using this code within an ensemble.
        
        NOTE
        ----
        Not all fluxes are returned! For example, respiration and litter
        fluxes are ignored. Feel free to add them in.
        
        Parameters
        -----------
        x: iter
            The state, defined as Cf, Cr, Cw, C**t, Csom
            
        i: int
            The time step
            
        Returns
        --------
        nee, gpp, Cf, Cr, Cw, C**t, Csom 
            A tuple containing the updated state, as well as the fluxes
        """
        # Extract drivers...

        doy, temp, tmx, tmn, irad, psid, ca, rtot, nitro = self.drivers[i, :]
        tmp = 0.5 * (tmx - tmn)

        # Extract the state components from the input
        Cf, Cr, Cw, C**t, Csom = x
        # Run DALEC
        ( nee, gpp, Ra, Rh1, Rh2, Af, Ar, Aw, Lw, Lr, D, \
            Cf, Cr, Cw, C**t, Csom, lai ) = dalec ( doy, \
            tmn, tmp, tmx, irad, ca, nitro, \
            self.model_params[0], self.model_params[1], \
            self.model_params[2:], \
            Cf, Cr, Cw, C**t, Csom, psid=psid, rtot=rtot )
        # Do we store the output?
        if store:
            self.previous_state.append ( [  nee, gpp, Ra, Rh1, Rh2, Af, Ar, Aw, Lw, Lr, D, \
            Cf, Cr, Cw, C**t, Csom, lai  ] )

        return ( nee, gpp, Ra, Rh1, Rh2, Af, Ar, Aw, Lw, Lr, D, \
            Cf, Cr, Cw, C**t, Csom )
Esempio n. 5
0
 def likelihood_function ( self, theta ):
     """
     This calculates the likelihood function. It first transforms the
     theta vector into a parameters per grid cell that are then passed on to
     the model object.
     """
     # Load the parameters into a dictionary indexed by grid_ids
     parameters = self._transform_variables_uniform ( theta )
     # Parameter have been loaded nto parameter_list for all grid cells
     # All that needs doing now is to run the model forward for each
     # grid cell and calculate the likelihood function
     retval = dalec ( self.x_init, parameters, self.meteo_data )
     model_nee =  retval[ :, -4 ]
     
     delta = (self.obs_nee[~self.missing_obs, 1] - \
     model_nee[~self.missing_obs] )**2
     p = 0.5*np.sum ( delta[::10] ) / (self.flux_unc**2 )
     p -= np.sum ( np.log ( 2.*np.pi*self.flux_unc ))
     return p