In [1]:
import numpy as np
import pandas as pd
import scipy.optimize as so
import sys
sys.path.append('../models')
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
data = pd.read_csv('../data/hbv_s_data.csv', index_col=0, parse_dates=True)
In [3]:
def calibrate(data, simulation_routine='HBV-s', objective_function='NS', method='DE'):
'''
Inputs:
1. data - meteorological forcing data packed in pandas dataframe:
'Temp' - daily temperature (Celsium degrees)
'Prec' - daily precipitation (mm/day)
'Evap' - daily potential evapotranspiration (mm/day)
2. 'Qobs' - daily river runoff (mm\day)
3. simulation routines (default='HBV')
'HBV'
'HBV-s'
'GR4J'
'GR4J-Cema-Neige'
'SIMHYD'
'SIMHYD-Cema-Neige'
4. objective function for optimization:
'NS' - Nash-Sutcliffe model efficiency criterion
5. optimization method:
'DE' - differential evolution (global optimization routine)
Output:
list of optimal model parameters
'''
### data preparation
Qobs = data['Qobs']
Qm = Qobs.mean()
### initialize the model used for parameters optimization
if simulation_routine == 'HBV':
import hbv
model = hbv.simulation
bnds = hbv.bounds()
elif simulation_routine == 'HBV-s':
import hbv_s
model = hbv_s.simulation
bnds = hbv_s.bounds()
elif simulation_routine == 'GR4J':
import gr4j
model = gr4j.simulation
bnds = gr4j.bounds()
elif simulation_routine == 'GR4J-Cema-Neige':
import gr4j_cemaneige
model = gr4j_cemaneige.simulation
bnds = gr4j_cemaneige.bounds()
elif simulation_routine == 'SIMHYD':
import simhyd
model = simhyd.simulation
bnds = simhyd.bounds()
elif simulation_routine == 'SIMHYD-Cema-Neige':
import simhyd_cemaneige
model = simhyd_cemaneige.simulation
bnds = simhyd_cemaneige.bounds()
else:
print("Incorrect simulation routine name, try one of:\
'HBV', 'HBV-s', 'GR4J', 'GR4J-Cema-Neige', 'SIMHYD', 'SIMHYD-Cema-Neige' ")
### initialize objective function for optimization
def obj_func_calc(params):
# simulate hydrograph
Qsim = model(data, params)
# calculate objective function value
return ((Qobs-Qsim)**2).sum()/((Qobs-Qm)**2).sum()
if objective_function == 'NS':
pass
else:
print("Incorrect objective function name, only 'NS' is available ")
### initialize optimization algorithm
if method == 'DE':
optimizer = so.differential_evolution
else:
print("Incorrect optimization method name, only 'DE' is available ")
result = optimizer(obj_func_calc, bnds, maxiter=5, polish=False, disp=True)
opt_param = result.x
return opt_param
In [4]:
calibrate(data)
Out[4]:
In [4]:
calibrate(data, 'HBV')
Out[4]:
In [6]:
calibrate(data, 'GR4J-Cema-Neige')
Out[6]:
In [7]:
calibrate(data, 'SIMHYD-Cema-Neige')
Out[7]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
import pandas as pd
import sys
sys.path.append('../tools/')
from wfdei_to_lumped_dataframe import dataframe_construction
from metrics import NS
#import hbv_s
In [ ]:
data = dataframe_construction('../data/pur_scheme.csv')
#data['Qsim'] = hbv_s.simulation(data, [1, 260, -0.03, 1.3, 0.61, 0.03, 0.08, 1, 1])
obs = pd.read_csv('../data/pur_observations.csv', index_col=0, parse_dates=True,
squeeze=True, header=None, names=['Date', 'Qobs'])
data = pd.concat([data, obs], axis=1)
#data_for_obs = data.ix[obs.index, ['Qsim', 'Qobs']].dropna()
In [ ]:
data = data['1979':]
In [ ]:
# now it is a data from gridded pur river
calibrate(data)
In [ ]:
"""
[ 5.14239023e+00, 3.59334992e+02, 2.39564956e+00,
9.05581073e+00, 9.73719068e-01, 5.58885084e-02,
8.07197632e-02, 1.00000000e+00, 1.00000000e+00])
"""
In [ ]:
In [ ]:
In [ ]:
In [ ]:
# step by step
import hbv_s
model = hbv_s.simulation
bounds = hbv_s.bounds()
Qobs = data['Qobs']
Qm = Qobs.mean()
def obj_func_calc(params):
# simulate hydrograph
Qsim = model(data, params)
# calculate objective function value
return ((Qobs-Qsim)**2).sum()/((Qobs-Qm)**2).sum()
optimizer = so.differential_evolution
result = optimizer(obj_func_calc, bounds, maxiter=5, disp=True)
plt.plot(range(len(data.Qobs)), data.Qobs, 'b',
range(len(data.Qobs)), model(data, result.x), 'r')
In [ ]: