From 6ae9e07b786fc4965dd23fb23d26621933ba51de Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 14 Jul 2020 12:54:34 -0600 Subject: [PATCH 1/2] add Gcc capable Choler models only for the Choler2011 and modified ones. Not for Choler2010. All the choler models are essentially just simplified phenograss models, so to fit them to Gcc there just needs to be the scaling component using MAP also slight adjustment to shorten testing cause it's taking forever now --- GrasslandModels/models/__init__.py | 11 +- GrasslandModels/models/choler2011.py | 347 ++++++++++++++++++ GrasslandModels/models/choler2011_modified.py | 254 +++++++++++++ GrasslandModels/utils.py | 10 + test/test_core_models.py | 12 +- 5 files changed, 628 insertions(+), 6 deletions(-) diff --git a/GrasslandModels/models/__init__.py b/GrasslandModels/models/__init__.py index 3527c16..f45a5c2 100644 --- a/GrasslandModels/models/__init__.py +++ b/GrasslandModels/models/__init__.py @@ -1,6 +1,6 @@ from .phenograss import PhenoGrass, PhenoGrassNDVI -from .choler2011 import CholerPR1, CholerPR2, CholerPR3 -from .choler2011_modified import CholerMPR2, CholerMPR3 +from .choler2011 import CholerPR1, CholerPR2, CholerPR3, CholerPR1Gcc, CholerPR2Gcc, CholerPR3Gcc +from .choler2011_modified import CholerMPR2, CholerMPR3, CholerMPR2Gcc, CholerMPR3Gcc from .choler2010 import CholerM1A, CholerM1B, CholerM2A, CholerM2B from .naive import Naive, Naive2, NaiveMAPCorrected, Naive2MAPCorrected @@ -18,5 +18,10 @@ 'Naive', 'Naive2', 'NaiveMAPCorrected', - 'Naive2MAPCorrected' + 'Naive2MAPCorrected', + 'CholerPR1Gcc', + 'CholerPR2Gcc', + 'CholerPR3Gcc', + 'CholerMPR2Gcc', + 'CholerMPR3Gcc', ] \ No newline at end of file diff --git a/GrasslandModels/models/choler2011.py b/GrasslandModels/models/choler2011.py index efb86ce..91183fa 100644 --- a/GrasslandModels/models/choler2011.py +++ b/GrasslandModels/models/choler2011.py @@ -100,6 +100,112 @@ def _apply_model_numpy(self, elif return_vars == 'all': return {'V':V,'Dt':Dt} +class CholerPR1Gcc(BaseModel): + """ + The "PR1" model described in Choler et al. 2011. + Made to work with Phenocam Gcc with the MAP transformation + """ + def __init__(self, parameters={}): + BaseModel.__init__(self) + self.all_required_parameters = {'b1': (0, 100), 'b2': (0, 100), + 'b3': (0, 100), 'L': (1,30), + 'h': (0,1000)} + self._organize_parameters(parameters) + self._required_predictors = {'precip': 'per_timestep', + 'MAP' : 'per_site'} + + self.state_variables = ['V','Dt','fCover'] + + self.set_internal_method(method='numpy') + + def set_internal_method(self, method = 'numpy'): + if method == 'cython': + raise NotImplementedError('cython method not implemented for this model') + elif method == 'numpy': + self._apply_model = self._apply_model_numpy + else: + raise ValueError('Unknown internal method: ' + method) + + def _apply_model_numpy(self, + # Site specific drivers + precip, # precip, Daily vector + MAP, # mean annual precip, per site + + # Model parameters + b1, + b2, + b3, + L, + h, + + # Contraints on vegetation. + Vmin = 0.001, # Needs to be small non-zero value + Vmax = 1., # 100% cause GCC is scaled 0-1 + # Note in the original Choler 2011 paper, Vmax is a site + # specific value set to the maximum value observed at a site. + # This is not feasable for extrapolation though. + + # Initial conditions + W_initial = 0, + Wstart = 0, + V_initial = 0.001, + # Normally just the V (vegatation cover) should be returned, + # but for diagnostics use 'all' to get V, and Dt + return_vars = 'V' + ): + """ + + """ + L = int(L) # must be a whole number, any floats will be truncated. + + V = np.empty_like(precip).astype('float32') + V[:] = V_initial + + # Derived variables + Dt = np.zeros_like(precip).astype('float32') + + # Site level vars such as lagged plant-water and + # temp responses + # Initialize empty to the shape (,n_sites) + Dtl = np.empty_like(precip[0]) + Dtl1 = np.empty_like(precip[0]) + + n_timesteps = precip.shape[0] - 1 + + for i in range(1,n_timesteps): + + # if we are near the start of the timeseries then initialize + # soil/plant water to something reasonable + if i - L - 1 < 0: + Dt[i] = np.maximum(0, precip[i] - b1) + Dtl[:] = Wstart + Dtl1[:] = Wstart + else: + Dt[i] = np.maximum(0, precip[i] - b1) + Dtl = Dt[i-L] + Dtl1 = Dt[i-L-1] + + # Condition (ii) + # If plant available water is on the decline + # then decay is 1 and senescensce sets in + d = (Dtl <= Dtl1) * 1 + + # Primary veg growth equation + V[i+1] = V[i] + b2 * Dtl * (1 - (V[i]/Vmax)) - d * b3 * V[i] + + # Condtiion (i) + # Constrain veg to 0-1 + V[i+1] = np.maximum(Vmin, np.minimum(Vmax, V[i+1])) + + fCover = V[:] + + scaling_factor = MAP / (MAP + h) + V = V / scaling_factor + + if return_vars == 'V': + return V + elif return_vars == 'all': + return {'V':V,'Dt':Dt,'fCover':fCover} class CholerPR2(BaseModel): """ @@ -212,6 +318,125 @@ def _apply_model_numpy(self, elif return_vars == 'all': return {'V':V, 'W':W, 'Dt':Dt} +class CholerPR2Gcc(BaseModel): + """ + The "PR2" four parameter model described in Choler et al. 2011 + Made to work with Phenocam Gcc with the MAP transformation + """ + def __init__(self, parameters={}): + BaseModel.__init__(self) + self.all_required_parameters = {'b1': (0, 100), 'b2': (0, 100), + 'b3': (0, 100), 'b4': (0, 100), + 'L': (1,30), 'h': (0,1000)} + self._organize_parameters(parameters) + self._required_predictors = {'precip': 'per_timestep', + 'evap' : 'per_timestep', + 'Wcap' : 'per_site', + 'MAP' : 'per_site'} + + self.state_variables = ['V','W','Dt','fCover'] + + self.set_internal_method(method='numpy') + + def set_internal_method(self, method = 'numpy'): + if method == 'cython': + raise NotImplementedError('cython method not implemented for this model') + elif method == 'numpy': + self._apply_model = self._apply_model_numpy + else: + raise ValueError('Unknown internal method: ' + method) + + def _apply_model_numpy(self, + # Site specific drivers + precip, # precip, Daily vector + evap, # potential ET, Daily vector + Wcap, # field capacity, single value/site + MAP, # Mean annual precip, single value/site + # Model parameters + b1, + b2, + b3, + b4, + L, + h, + + # Contraints on vegetation. + Vmin = 0.001, # Needs to be small non-zero value + Vmax = 1., # 100% cause GCC is scaled 0-1 + # Note in the original Choler 2011 paper, Vmax is a site + # specific value set to the maximum value observed at a site. + # This is not feasable for extrapolation though. + + # Initial conditions + W_initial = 0, + Wstart = 0, + V_initial = 0.001, + # Normally just the V (vegatation cover) should be returned, + # but for diagnostics use 'all' to get V, W, and Dt + return_vars = 'V' + ): + """ + + """ + L = int(L) # must be a whole number. and floats will be truncated. + + # Initialize everything + # Primary state variables + W = np.empty_like(precip).astype('float32') + W[:] = W_initial + + V = np.empty_like(precip).astype('float32') + V[:] = V_initial + + # Derived variables + Dt = np.zeros_like(precip).astype('float32') + + # Site level vars such as lagged plant-water and + # temp responses + Dtl = np.empty_like(Wcap) + Dtl1 = np.empty_like(Wcap) + + n_timesteps = precip.shape[0] - 1 + + for i in range(1,n_timesteps): + + # if we are near the start of the timeseries then initialize + # soil/plant water to something reasonable + if i - L - 1 < 0: + Dt[i] = np.maximum(0, W[i] - b1) + Dtl[:] = Wstart + Dtl1[:] = Wstart + else: + Dt[i] = np.maximum(0, W[i] - b1) + Dtl = Dt[i-L] + Dtl1 = Dt[i-L-1] + + # Condition (ii) + # If plant available water is on the decline + # then decay is 1 and senescensce sets in + d = (Dtl <= Dtl1) * 1 + + # Soil water + W[i+1] = W[i] + precip[i] - b4 * ((Dt[i]/(Wcap - b1))**2) * evap[i] + W[i+1] = np.maximum(0, np.minimum(Wcap, W[i+1])) + + # Primary veg growth equation + V[i+1] = V[i] + b2 * Dtl * (1 - (V[i]/Vmax)) - d * b3 * V[i] + + # Condtiion (i) + # Constrain veg to 0-1 + V[i+1] = np.maximum(Vmin, np.minimum(Vmax, V[i+1])) + + fCover = V[:] + + scaling_factor = MAP / (MAP + h) + V = V / scaling_factor + + if return_vars == 'V': + return V + elif return_vars == 'all': + return {'V':V,'W':W,'Dt':Dt,'fCover':fCover} + class CholerPR3(BaseModel): """ The "PR3" four parameter model described in Choler et al. 2011 @@ -323,3 +548,125 @@ def _apply_model_numpy(self, return V elif return_vars == 'all': return {'V':V, 'W':W, 'Dt':Dt} + + +class CholerPR3Gcc(BaseModel): + """ + The "PR3" four parameter model described in Choler et al. 2011 + Made to work with Phenocam Gcc with the MAP transformation + """ + def __init__(self, parameters={}): + BaseModel.__init__(self) + self.all_required_parameters = {'b1': (0, 100), 'b2': (0, 100), + 'b3': (0, 100), 'b4': (0, 100), + 'L': (1,30), 'h':(0,1000)} + self._organize_parameters(parameters) + self._required_predictors = {'precip': 'per_timestep', + 'evap' : 'per_timestep', + 'Wcap' : 'per_site', + 'MAP' : 'per_site'} + + self.state_variables = ['V','W','Dt','fCover'] + + self.set_internal_method(method='numpy') + + def set_internal_method(self, method = 'numpy'): + if method == 'cython': + raise NotImplementedError('cython method not implemented for this model') + elif method == 'numpy': + self._apply_model = self._apply_model_numpy + else: + raise ValueError('Unknown internal method: ' + method) + + def _apply_model_numpy(self, + # Site specific drivers + precip, # precip, Daily vector + evap, # potential ET, Daily vector + Wcap, # field capacity, single value/site + MAP, # Mean ann. precip, single value/site + + # Model parameters + b1, + b2, + b3, + b4, + h, + L, + + # Contraints on vegetation. + Vmin = 0.001, # Needs to be small non-zero value + Vmax = 1., # 100% cause GCC is scaled 0-1 + # Note in the original Choler 2011 paper, Vmax is a site + # specific value set to the maximum value observed at a site. + # This is not feasable for extrapolation though. + + # Initial conditions + W_initial = 0, + Wstart = 0, + V_initial = 0.001, + # Normally just the V (vegatation cover) should be returned, + # but for diagnostics use 'all' to get V, W, and Dt + return_vars = 'V' + ): + """ + + """ + L = int(L) # must be a whole number, any floats will be truncated. + + # Initialize everything + # Primary state variables + W = np.empty_like(precip).astype('float32') + W[:] = W_initial + + V = np.empty_like(precip).astype('float32') + V[:] = V_initial + + # Derived variables + Dt = np.zeros_like(precip).astype('float32') + + # Site level vars such as lagged plant-water and + # temp responses + Dtl = np.empty_like(Wcap) + Dtl1 = np.empty_like(Wcap) + + n_timesteps = precip.shape[0] - 1 + + for i in range(1,n_timesteps): + + # if we are near the start of the timeseries then initialize + # soil/plant water to something reasonable + if i - L - 1 < 0: + Dt[i] = np.maximum(0, W[i] - b1) + Dtl[:] = Wstart + Dtl1[:] = Wstart + else: + Dt[i] = np.maximum(0, W[i] - b1) + Dtl = Dt[i-L] + Dtl1 = Dt[i-L-1] + + # Condition (ii) + # If plant available water is on the decline + # then decay is 1 and senescensce sets in + d = (Dtl <= Dtl1) * 1 + + # Soil water + W[i+1] = W[i] + precip[i] - (1 - V[i]) * ((Dt[i]/(Wcap - b1))**2) * evap[i] - V[i]* b4 *Dt[i] + W[i+1] = np.maximum(0, np.minimum(Wcap, W[i+1])) + + + # Primary veg growth equation + V[i+1] = V[i] + b2 * Dtl * (1 - (V[i]/Vmax)) - d * b3 * V[i] + + # Condtiion (i) + # Constrain veg to 0-1 + V[i+1] = np.maximum(Vmin, np.minimum(Vmax, V[i+1])) + + fCover = V[:] + + scaling_factor = MAP / (MAP + h) + V = V / scaling_factor + + if return_vars == 'V': + return V + elif return_vars == 'all': + return {'V':V,'W':W,'Dt':Dt,'fCover':fCover} \ No newline at end of file diff --git a/GrasslandModels/models/choler2011_modified.py b/GrasslandModels/models/choler2011_modified.py index 6b5f908..96b3575 100644 --- a/GrasslandModels/models/choler2011_modified.py +++ b/GrasslandModels/models/choler2011_modified.py @@ -120,6 +120,132 @@ def _apply_model_numpy(self, elif return_vars == 'all': return {'V':V, 'W':W, 'Dt':Dt} +class CholerMPR2Gcc(BaseModel): + """ + The "PR2" four parameter model described in Choler et al. 2011 + + Modified to use wilting point as an input instead of estimating it + via the b1 parameter. Now 3 parameters. + """ + def __init__(self, parameters={}): + BaseModel.__init__(self) + self.all_required_parameters = {'b2': (0, 100),'b3': (0, 100), + 'b4': (0, 100), 'L': (1,30), + 'h': (0,1000)} + self._organize_parameters(parameters) + self._required_predictors = {'precip': 'per_timestep', + 'evap' : 'per_timestep', + 'Wcap' : 'per_site', + 'Wp' : 'per_site', + 'MAP' : 'per_site'} + + self.state_variables = ['V','W','Dt','fCover'] + + self.set_internal_method(method='numpy') + + def set_internal_method(self, method = 'numpy'): + if method == 'cython': + raise NotImplementedError('cython method not implemented for this model') + elif method == 'numpy': + self._apply_model = self._apply_model_numpy + else: + raise ValueError('Unknown internal method: ' + method) + + def _apply_model_numpy(self, + # Site specific drivers + precip, # precip, Daily vector + evap, # potential ET, Daily vector + Wcap, # field capacity, single value/site + Wp, # wilting point, single value/site + MAP, # mean ann precip, single value/site + + # Model parameters + #b1, Replaced by Wp in the modified model + b2, + b3, + b4, + h, + L, + + # Contraints on vegetation. + Vmin = 0.001, # Needs to be small non-zero value + Vmax = 1., # 100% cause GCC is scaled 0-1 + # Note in the original Choler 2011 paper, Vmax is a site + # specific value set to the maximum value observed at a site. + # This is not feasable for extrapolation though. + + # Initial conditions + W_initial = 0, + Wstart = 0, + V_initial = 0.001, + # Normally just the V (vegatation cover) should be returned, + # but for diagnostics use 'all' to get V, W, and Dt + return_vars = 'V' + ): + """ + + """ + L = int(L) # must be a whole number, any floats will be truncated. + + # Initialize everything + # Primary state variables + W = np.empty_like(precip).astype('float32') + W[:] = W_initial + + V = np.empty_like(precip).astype('float32') + V[:] = V_initial + + # Derived variables + Dt = np.zeros_like(precip).astype('float32') + + # Site level vars such as lagged plant-water and + # temp responses + Dtl = np.empty_like(Wcap) + Dtl1 = np.empty_like(Wcap) + + n_timesteps = precip.shape[0] - 1 + + for i in range(1,n_timesteps): + + # if we are near the start of the timeseries then initialize + # soil/plant water to something reasonable + if i - L - 1 < 0: + Dt[i] = np.maximum(0, W[i] - Wp) + Dtl[:] = Wstart + Dtl1[:] = Wstart + else: + Dt[i] = np.maximum(0, W[i] - Wp) + Dtl = Dt[i-L] + Dtl1 = Dt[i-L-1] + + # Condition (ii) + # If plant available water is on the decline + # then decay is 1 and senescensce sets in + d = (Dtl <= Dtl1) * 1 + + # Soil water + W[i+1] = W[i] + precip[i] - b4 * ((Dt[i]/(Wcap - Wp))**2) * evap[i] + W[i+1] = np.maximum(0, np.minimum(Wcap, W[i+1])) + + # Primary veg growth equation + V[i+1] = V[i] + b2 * Dtl * (1 - (V[i]/Vmax)) - d * b3 * V[i] + + # Condtiion (i) + # Constrain veg to 0-1 + V[i+1] = np.maximum(Vmin, np.minimum(Vmax, V[i+1])) + + fCover = V[:] + + scaling_factor = MAP / (MAP + h) + V = V / scaling_factor + + if return_vars == 'V': + return V + elif return_vars == 'all': + return {'V':V,'W':W,'Dt':Dt,'fCover':fCover} + + + class CholerMPR3(BaseModel): """ The "PR3" four parameter model described in Choler et al. 2011 @@ -235,3 +361,131 @@ def _apply_model_numpy(self, return V elif return_vars == 'all': return {'V':V, 'W':W, 'Dt':Dt} + + +class CholerMPR3Gcc(BaseModel): + """ + The "PR3" four parameter model described in Choler et al. 2011 + + Modified to use wilting point as an input instead of estimating it + via the b1 parameter. Now 3 parameters. + + Made to work with Phenocam Gcc with the MAP transformation + """ + def __init__(self, parameters={}): + BaseModel.__init__(self) + self.all_required_parameters = {'b2': (0, 100), 'b3': (0, 100), + 'b4': (0, 100), 'L': (1,30), + 'h': (0,1000)} + self._organize_parameters(parameters) + self._required_predictors = {'precip': 'per_timestep', + 'evap' : 'per_timestep', + 'Wcap' : 'per_site', + 'Wp' : 'per_site', + 'MAP' : 'per_site'} + + self.state_variables = ['V','W','Dt','fCover'] + + self.set_internal_method(method='numpy') + + def set_internal_method(self, method = 'numpy'): + if method == 'cython': + raise NotImplementedError('cython method not implemented for this model') + elif method == 'numpy': + self._apply_model = self._apply_model_numpy + else: + raise ValueError('Unknown internal method: ' + method) + + def _apply_model_numpy(self, + # Site specific drivers + precip, # precip, Daily vector + evap, # potential ET, Daily vector + Wcap, # field capacity, single value/site + Wp, # wilting point, single value/site + MAP, # mean annual precip, per site + + # Model parameters + #b1, Replaced by Wp in the modified model + b2, + b3, + b4, + h, + L, + + # Contraints on vegetation. + Vmin = 0.001, # Needs to be small non-zero value + Vmax = 1., # 100% cause GCC is scaled 0-1 + # Note in the original Choler 2011 paper, Vmax is a site + # specific value set to the maximum value observed at a site. + # This is not feasable for extrapolation though. + + # Initial conditions + W_initial = 0, + Wstart = 0, + V_initial = 0.001, + # Normally just the V (vegatation cover) should be returned, + # but for diagnostics use 'all' to get V, W, and Dt + return_vars = 'V' + ): + """ + + """ + L = int(L) # must be a whole number, any floats will be truncated. + + # Initialize everything + # Primary state variables + W = np.empty_like(precip).astype('float32') + W[:] = W_initial + + V = np.empty_like(precip).astype('float32') + V[:] = V_initial + + # Derived variables + Dt = np.zeros_like(precip).astype('float32') + + # Site level vars such as lagged plant-water and + # temp responses + Dtl = np.empty_like(Wcap) + Dtl1 = np.empty_like(Wcap) + + n_timesteps = precip.shape[0] - 1 + + for i in range(1,n_timesteps): + + # if we are near the start of the timeseries then initialize + # soil/plant water to something reasonable + if i - L - 1 < 0: + Dt[i] = np.maximum(0, W[i] - Wp) + Dtl[:] = Wstart + Dtl1[:] = Wstart + else: + Dt[i] = np.maximum(0, W[i] - Wp) + Dtl = Dt[i-L] + Dtl1 = Dt[i-L-1] + + # Condition (ii) + # If plant available water is on the decline + # then decay is 1 and senescensce sets in + d = (Dtl <= Dtl1) * 1 + + # Soil water + W[i+1] = W[i] + precip[i] - (1 - V[i]) * ((Dt[i]/(Wcap - Wp))**2) * evap[i] - V[i]* b4 *Dt[i] + W[i+1] = np.maximum(0, np.minimum(Wcap, W[i+1])) + + + # Primary veg growth equation + V[i+1] = V[i] + b2 * Dtl * (1 - (V[i]/Vmax)) - d * b3 * V[i] + + # Condtiion (i) + # Constrain veg to 0-1 + V[i+1] = np.maximum(Vmin, np.minimum(Vmax, V[i+1])) + + fCover = V[:] + + scaling_factor = MAP / (MAP + h) + V = V / scaling_factor + + if return_vars == 'V': + return V + elif return_vars == 'all': + return {'V':V,'W':W,'Dt':Dt,'fCover':fCover} \ No newline at end of file diff --git a/GrasslandModels/utils.py b/GrasslandModels/utils.py index e948000..4965d09 100644 --- a/GrasslandModels/utils.py +++ b/GrasslandModels/utils.py @@ -172,6 +172,16 @@ def load_model(name): return models.NaiveMAPCorrected if name == 'Naive2MAPCorrected': return models.Naive2MAPCorrected + if name == 'CholerPR1Gcc': + return models.CholerPR1Gcc + if name == 'CholerPR2Gcc': + return models.CholerPR2Gcc + if name == 'CholerPR3Gcc': + return models.CholerPR3Gcc + if name == 'CholerMPR2Gcc': + return models.CholerMPR2Gcc + if name == 'CholerMPR3Gcc': + return models.CholerMPR3Gcc else: raise ValueError('Unknown model name: ' + name) diff --git a/test/test_core_models.py b/test/test_core_models.py index 6124e49..91aef86 100644 --- a/test/test_core_models.py +++ b/test/test_core_models.py @@ -16,12 +16,18 @@ 'Naive', 'Naive2', 'NaiveMAPCorrected', - 'Naive2MAPCorrected'] + 'Naive2MAPCorrected', + 'CholerPR1Gcc', + 'CholerPR2Gcc', + 'CholerPR3Gcc', + 'CholerMPR2Gcc', + 'CholerMPR3Gcc', + ] GCC, predictor_vars = utils.load_test_data() -quick_testing_params = {'maxiter':3, - 'popsize':2, +quick_testing_params = {'maxiter':2, + 'popsize':1, 'mutation':(0.5,1), 'recombination':0.25, 'disp':False} From e03c3bb721df7b4ef5051cf8f782c6b7f9810e3a Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 14 Jul 2020 12:57:22 -0600 Subject: [PATCH 2/2] default Vmax to 0.99 Vmax at 1 will potentially get it stuck there, see https://github.com/sdtaylor/GrasslandModels/issues/37 --- GrasslandModels/models/choler2010.py | 4 ++-- GrasslandModels/models/choler2011.py | 12 ++++++------ GrasslandModels/models/choler2011_modified.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/GrasslandModels/models/choler2010.py b/GrasslandModels/models/choler2010.py index 8947106..4348a6f 100644 --- a/GrasslandModels/models/choler2010.py +++ b/GrasslandModels/models/choler2010.py @@ -43,7 +43,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2010 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -177,7 +177,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2010 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. diff --git a/GrasslandModels/models/choler2011.py b/GrasslandModels/models/choler2011.py index 91183fa..752c9e5 100644 --- a/GrasslandModels/models/choler2011.py +++ b/GrasslandModels/models/choler2011.py @@ -38,7 +38,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -140,7 +140,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -248,7 +248,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -362,7 +362,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -478,7 +478,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -595,7 +595,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. diff --git a/GrasslandModels/models/choler2011_modified.py b/GrasslandModels/models/choler2011_modified.py index 96b3575..2aab638 100644 --- a/GrasslandModels/models/choler2011_modified.py +++ b/GrasslandModels/models/choler2011_modified.py @@ -50,7 +50,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -169,7 +169,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -291,7 +291,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though. @@ -414,7 +414,7 @@ def _apply_model_numpy(self, # Contraints on vegetation. Vmin = 0.001, # Needs to be small non-zero value - Vmax = 1., # 100% cause GCC is scaled 0-1 + Vmax = 0.99, # 100% cause GCC is scaled 0-1 # Note in the original Choler 2011 paper, Vmax is a site # specific value set to the maximum value observed at a site. # This is not feasable for extrapolation though.