1 /**********************************************************
2  * Version $Id: ihacres_elev_cal.cpp 1261 2011-12-16 15:12:15Z oconrad $
3  *********************************************************/
4 ///////////////////////////////////////////////////////////
5 //                    ihacres_elev_cal.cpp               //
6 //                                                       //
7 //                 Copyright (C) 2008 by                 //
8 //                     Stefan Liersch                    //
9 //-------------------------------------------------------//
10 //    e-mail:     stefan.liersch@ufz.de                  //
11 //                stefan.liersch@gmail.com               //
12 //                     2008-01-08                        //
13 ///////////////////////////////////////////////////////////
14 
15 #include "ihacres_elev_cal.h"
16 #include "convert_sl.h"
17 #include "model_tools.h"
18 
19 #include <stdlib.h> // random numbers
20 #include <time.h>	// random numbers
21 
22 // TEST OUTPUT ONLY
23 #include <fstream>
24 
25 //---------------------------------------------------------------------
26 
Cihacres_elev_cal()27 Cihacres_elev_cal::Cihacres_elev_cal()
28 {
29 	//-----------------------------------------------------
30 	// 1. Info...
31 	Set_Name(_TL("IHACRES Elevation Bands Calibration"));
32 
33 	Set_Author(SG_T("copyrights (c) 2008 Stefan Liersch"));
34 
35 	Set_Description(_TW("The Rainfall-Runoff Model IHACRES \n \n \n"
36 		"Reference: \n \n"
37 		"Jakeman, A.J. / Hornberger, G.M. (1993). \n"
38 		"How Much Complexity Is Warranted in a Rainfall-Runoff Model? \n"
39 		"Water Resources Research, (29), NO. 8 (2637-2649) \n \n"
40 		"Kokkonen, T. S. et al. (2003). \n"
41 		"Predicting daily flows in ungauged catchments:"
42 		"model regionalization from catchment descriptors"
43 		"at the Coweeta Hydrologic Laboratory, North Carolina \n "
44 		"Hydrological Processes (17), 2219-2238 \n \n"
45 		"Croke, B. F. W., W. S. Merritt, et al. (2004).\n"
46 		"A dynamic model for predicting hydrologic response"
47 		"to land cover changes in gauged and"
48 		"ungauged catchments. \n"
49 		"Journal Of Hydrology 291(1-2): 115-131."
50 	));
51 
52 	Parameters.Add_Table_Output(
53 		NULL	, "TABLEout"	, _TL("Table"),
54 		_TL("")
55 	);
56 	Parameters.Add_Table_Output(
57 		NULL	, "TABLEparms"	, _TL("Table"),
58 		_TL("")
59 	);
60 
61 	///////////////////////////////////////////////////////////////////
62 	// FIRST TOOL DIALOG
63 	_CreateDialog1();
64 	///////////////////////////////////////////////////////////////////
65 }
66 
~Cihacres_elev_cal()67 Cihacres_elev_cal::~Cihacres_elev_cal()
68 {}
69 //---------------------------------------------------------------------
70 
On_Execute()71 bool Cihacres_elev_cal::On_Execute()
72 {
73 	double		NSE_temp	= 0.0;
74 	double		NSE_max		= -9999.9;
75 	string		nse, nse_text;
76 
77 	CSG_Parameters P;
78 	//std::ofstream f("_out_elev.txt");
79 
80 	// Assign Parameters from first Tool Dialog
81 	//---------------------------------------------------------
82 	int eb			= Parameters("NELEVBANDS")		->asInt();
83 	m_nElevBands	= eb + 2; // because list starts with 2 !
84 	m_nsim			= Parameters("NSIM")			->asInt();
85 	m_Area_tot		= Parameters("AREA_tot")		->asDouble();
86 	m_IHAC_version	= Parameters("IHACVERS")		->asInt();
87 	m_StorConf		= Parameters("STORAGE")			->asInt();
88 	m_bSnowModule	= Parameters("SNOW_TOOL")		->asBool();
89 	m_obj_func		= Parameters("OBJ_FUNC")		->asInt();
90 	m_NSEmin		= Parameters("NSEMIN")			->asDouble();
91 
92 	//---------------------------------------------------------
93 
94 	//---------------------------------------------------------
95 	// Assign number of storages
96 	m_nStorages = ihacres.Assign_nStorages(m_StorConf);
97 	//---------------------------------------------------------
98 
99 	//---------------------------------------------------------
100 	// Initialize pointers
101 	_Init_ElevBands(m_nElevBands);
102 	m_p_linparms	= new C_IHAC_LinearParms(m_nElevBands,m_nStorages);
103 	m_p_lin_lb		= new C_IHAC_LinearParms(m_nElevBands,m_nStorages);
104 	m_p_lin_ub		= new C_IHAC_LinearParms(m_nElevBands,m_nStorages);
105 	m_p_nonlinparms = new C_IHAC_NonLinearParms(m_nElevBands);
106 	m_p_nl_lb		= new C_IHAC_NonLinearParms(m_nElevBands);
107 	m_p_nl_ub		= new C_IHAC_NonLinearParms(m_nElevBands);
108 	//---------------------------------------------------------
109 
110 	//---------------------------------------------------------
111 	// open second and third user dialog
112 	if ( _CreateDialog2() && _CreateDialog3())
113 	{
114 		//---------------------------------------------------------
115 		// searching the first and the last record of the time range
116 		ihacres.AssignFirstLastRec(*m_p_InputTable, m_first, m_last, m_date1, m_date2, m_dateField);
117 		m_nValues = m_last - m_first + 1;
118 		//---------------------------------------------------------
119 
120 		//---------------------------------------------------------
121 		_Init_Pointers(m_nValues);
122 		//---------------------------------------------------------
123 
124 		//---------------------------------------------------------
125 		// read input table
126 		_ReadInputFile();
127 		//---------------------------------------------------------
128 
129 		//---------------------------------------------------------
130 		// PERFORM STREAMFLOW SIMULATION
131 		// FOR EACH ELEVATION BAND
132 		//---------------------------------------------------------
133 		// Convert Streamflow vector from m3/s*day-1 to mm/day
134 		m_p_Q_obs_mmday = model_tools::m3s_to_mmday(m_p_Q_obs_m3s, m_p_Q_obs_mmday, m_nValues, m_Area_tot);
135 
136 		//---------------------------------------------------------
137 		m_pTable_parms = SG_Create_Table();
138 		_CreateTableParms();
139 		m_counter = 0;
140 		//---------------------------------------------------------
141 
142 		///////////////////////////////////////////////////////////
143 		//
144 		//		SIMULATION
145 		//
146 		///////////////////////////////////////////////////////////
147 
148 		// initialize random function
149 		srand((unsigned) time(NULL)); // using time.h
150 
151 		for (int sim = 0; sim < m_nsim && Set_Progress(sim, m_nsim); sim++)
152 		{
153 			_Simulate_NonLinearModule();
154 
155 			_Simulate_Streamflow();
156 
157 			_Sum_Streamflow();
158 
159 			m_NSE = m_NSE_lowflow = m_NSE_highflow = m_PBIAS = 0;
160 			_CalcEfficiency();
161 
162 
163 			// write in output table if criterion is fulfilled
164 			NSE_temp = ihacres._Assign_NSE_temp(m_obj_func, m_NSE, m_NSE_highflow, m_NSE_lowflow);
165 
166 			if (NSE_temp > m_NSEmin)
167 			{
168 				if (NSE_temp > NSE_max)
169 				{
170 					NSE_max = NSE_temp;
171 					nse = convert_sl::Double2String(NSE_max).c_str();
172 					nse_text = "max. NSE ";
173 					nse_text += nse;
174 					Process_Set_Text(CSG_String(nse_text.c_str()));
175 				}
176 
177 				_WriteTableParms();
178 			}
179 		}
180 		//---------------------------------------------------------
181 
182 		m_pTable_parms->Set_Name(SG_T("ihacres_elevbands_cal"));
183 		Parameters("TABLEparms")->Set_Value(m_pTable_parms);
184 
185 		//m_pTable = SG_Create_Table();
186 		//_CreateTableSim();
187 		//// add tables to SAGA Workspace
188 		//m_pTable->Set_Name("ihacres_elevBands_output");
189 		//Parameters("TABLEout")->Set_Value(m_pTable);
190 
191 		delete[] m_p_elevbands; // s�mtliche Unter-Pointer noch l�schen
192 		delete[] m_p_pcpField;
193 		delete[] m_p_tmpField;
194 		delete[] m_p_Q_obs_m3s;
195 		delete[] m_p_Q_obs_mmday;
196 		delete[] m_p_Q_sim_mmday;
197 		delete m_p_linparms;
198 		delete m_p_nonlinparms;
199 		delete m_p_lin_lb;
200 		delete m_p_lin_ub;
201 		delete m_p_nl_lb;
202 		delete m_p_nl_ub;
203 		if (m_bSnowModule) {
204 			delete[] m_pSnowparms;
205 			delete[] m_pSnowparms_lb;
206 			delete[] m_pSnowparms_ub;
207 		}
208 		delete[] m_vq;
209 		delete[] m_vs;
210 
211 		return(true);
212 	} // end if ( _CreateDialog2() )
213 
214 		// delete[] m_p_elevbands;
215 		// delete[] m_p_pcpFields;
216 		// delete[] m_p_tmpFields;
217 		// delete m_p_linparms;
218 		// delete m_p_nonlinparms;
219 	return(false);
220 }
221 
222 //---------------------------------------------------------------------
223 
_Init_ElevBands(int nvals)224 void Cihacres_elev_cal::_Init_ElevBands(int nvals)
225 {
226 	// instantiate elevation bands
227 	m_p_elevbands = new Cihacres_elev_bands[nvals];
228 
229 	// instantiate field numbers
230 	m_p_pcpField = new int[nvals];
231 	m_p_tmpField = new int[nvals];
232 
233 	if (m_bSnowModule)
234 	{
235 		m_pSnowparms	= new CSnowParms[nvals];
236 		m_pSnowparms_lb	= new CSnowParms[nvals];
237 		m_pSnowparms_ub	= new CSnowParms[nvals];
238 	}
239 
240 	m_vq = new double[nvals];
241 	m_vs = new double[nvals];
242 }
243 //---------------------------------------------------------------------
244 
_Init_Pointers(int nvals)245 void Cihacres_elev_cal::_Init_Pointers(int nvals)
246 {
247 	m_vec_date.resize(nvals);
248 	m_p_Q_obs_m3s = new double[nvals];
249 	m_p_Q_obs_mmday = new double[nvals];
250 	m_p_Q_sim_mmday = new double[nvals];
251 
252 	for (int eb = 0; eb < m_nElevBands; eb++)
253 	{
254 		m_p_elevbands[eb].m_p_pcp = new double[nvals];
255 		m_p_elevbands[eb].m_p_tmp = new double[nvals];
256 		m_p_elevbands[eb].m_p_ER = new double[nvals];
257 		m_p_elevbands[eb].m_p_streamflow_sim = new double[nvals];
258 		m_p_elevbands[eb].m_p_Tw = new double[nvals];
259 		m_p_elevbands[eb].m_p_WI = new double[nvals];
260 
261 		if (m_bSnowModule) {
262 			m_p_elevbands[eb].m_p_SnowStorage = new double[nvals];
263 			m_p_elevbands[eb].m_p_MeltRate = new double[nvals];
264 		}
265 	}
266 }
267 //---------------------------------------------------------------------
268 
_ReadInputFile()269 void Cihacres_elev_cal::_ReadInputFile()
270 {
271 	for (int j = 0, k = m_first; j < m_nValues, k < m_last + 1; j++, k++)
272 	{
273 		m_vec_date[j].append(CSG_String(m_p_InputTable->Get_Record(k)->asString(m_dateField)));
274 		m_p_Q_obs_m3s[j] = m_p_InputTable->Get_Record(k)->asDouble(m_streamflowField);
275 
276 		for (int eb = 0; eb < m_nElevBands; eb++)
277 		{
278 			m_p_elevbands[eb].m_p_pcp[j] = m_p_InputTable->Get_Record(k)->asDouble(m_p_pcpField[eb]);
279 			m_p_elevbands[eb].m_p_tmp[j] = m_p_InputTable->Get_Record(k)->asDouble(m_p_tmpField[eb]);
280 		}
281 	}
282 }
283 //---------------------------------------------------------------------
284 
_CalcSnowModule(int eb)285 void Cihacres_elev_cal::_CalcSnowModule(int eb)
286 {
287 	m_p_SnowModule = new CSnowModule(m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_pcp, m_nValues,
288 									m_pSnowparms[eb].T_Rain, m_pSnowparms[eb].T_Melt, m_pSnowparms[eb].DD_FAC);
289 
290 	m_p_elevbands[eb].m_p_MeltRate = m_p_SnowModule->Get_MeltRate(m_p_elevbands[eb].m_p_MeltRate, m_nValues);
291 	m_p_elevbands[eb].m_p_SnowStorage = m_p_SnowModule->Get_SnowStorage(m_p_elevbands[eb].m_p_SnowStorage, m_nValues);
292 
293 	delete m_p_SnowModule;
294 }
295 //---------------------------------------------------------------------
296 
_Simulate_NonLinearModule()297 void Cihacres_elev_cal::_Simulate_NonLinearModule()
298 {
299 	double eR_init = 0.0;
300 	for (int eb = 0; eb < m_nElevBands; eb++)
301 	{
302 		//-------------------------------------------------------------
303 		// Assign random values
304 		//-------------------------------------------------------------
305 		if (m_bSnowModule)
306 		{
307 			m_pSnowparms[eb].T_Rain	= model_tools::Random_double(m_pSnowparms_lb[eb].T_Rain,m_pSnowparms_ub[eb].T_Rain);
308 			m_pSnowparms[eb].T_Melt	= model_tools::Random_double(m_pSnowparms_lb[eb].T_Melt,m_pSnowparms_ub[eb].T_Melt);
309 			m_pSnowparms[eb].DD_FAC = model_tools::Random_double(m_pSnowparms_lb[eb].DD_FAC,m_pSnowparms_ub[eb].DD_FAC);
310 
311 			m_p_SnowModule = new CSnowModule(m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_pcp, m_nValues,
312 				m_pSnowparms[eb].T_Rain, m_pSnowparms[eb].T_Melt, m_pSnowparms[eb].DD_FAC);
313 
314 			m_p_elevbands[eb].m_p_MeltRate = m_p_SnowModule->Get_MeltRate(m_p_elevbands[eb].m_p_MeltRate, m_nValues);
315 			delete m_p_SnowModule;
316 		}
317 
318 		m_p_nonlinparms->mp_tw[eb]	= model_tools::Random_double(m_p_nl_lb->mp_tw[eb], m_p_nl_ub->mp_tw[eb]);
319 		m_p_nonlinparms->mp_f[eb]	= model_tools::Random_double(m_p_nl_lb->mp_f[eb], m_p_nl_ub->mp_f[eb]);
320 		m_p_nonlinparms->mp_c[eb]	= model_tools::Random_double(m_p_nl_lb->mp_c[eb], m_p_nl_ub->mp_c[eb]);
321 
322 		if (m_IHAC_version == 1) { // Croke etal. (2005)
323 			m_p_nonlinparms->mp_l[eb]= model_tools::Random_double(m_p_nl_ub->mp_l[eb],m_p_nl_ub->mp_l[eb]);
324 			m_p_nonlinparms->mp_p[eb]= model_tools::Random_double(m_p_nl_ub->mp_p[eb],m_p_nl_ub->mp_p[eb]);
325 		}
326 
327 		//----------------------------------------------------------
328 		// calculate excess rainfall time series
329 		//----------------------------------------------------------
330 		switch(m_IHAC_version)
331 		{
332 		case 0: // Jakeman & Hornberger (1993)
333 			// The parameter index (fourth parameter) is zero here, because
334 			// the parameter settings of the non-linear module are in all elevationbands equal.
335 			// If they should be different the index parameter can be used to identify the
336 			// corresponding elevation band.
337 			ihacres.CalcWetnessTimeConst(m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_Tw,
338 					m_p_nonlinparms, eb, m_nValues);
339 					// 0 = index (only one instance of m_p_nonlinparms)
340 
341 			if (m_bSnowModule)
342 			{
343 				ihacres.CalcWetnessIndex(m_p_elevbands[eb].m_p_Tw, m_p_elevbands[eb].m_p_pcp,
344 					m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_WI, 0.5, m_p_nonlinparms->mp_c[eb],
345 					m_bSnowModule, m_pSnowparms[eb].T_Rain, m_nValues);
346 
347 				ihacres.CalcExcessRain(m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_tmp,
348 					m_p_elevbands[eb].m_p_WI, m_p_elevbands[eb].m_p_ER, eR_init,
349 					m_p_elevbands[eb].m_sum_eRainGTpcp, m_nValues, m_bSnowModule,
350 					m_pSnowparms[eb].T_Rain, m_pSnowparms[eb].T_Melt,
351 					m_p_elevbands[eb].m_p_MeltRate);
352 			} else {
353 
354 				ihacres.CalcWetnessIndex(m_p_elevbands[eb].m_p_Tw, m_p_elevbands[eb].m_p_pcp,
355 					m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_WI, 0.5, m_p_nonlinparms->mp_c[eb],
356 					m_bSnowModule, 0, m_nValues);
357 
358 				ihacres.CalcExcessRain(m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_tmp,
359 					m_p_elevbands[eb].m_p_WI, m_p_elevbands[eb].m_p_ER, eR_init,
360 					m_p_elevbands[eb].m_sum_eRainGTpcp, m_nValues, m_bSnowModule,
361 					0,0,0);
362 			}
363 			break;
364 		case 1: // Croke et al. (2005)
365 			ihacres.CalcWetnessTimeConst_Redesign(m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_Tw,
366 				m_p_nonlinparms, eb, m_nValues);	// 0 = index (only one instance of m_p_nonlinparms)
367 
368 			if (m_bSnowModule)
369 			{
370 				ihacres.CalcWetnessIndex_Redesign(m_p_elevbands[eb].m_p_Tw, m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_WI, 0.5,
371 					m_bSnowModule, m_pSnowparms[eb].T_Rain, m_nValues);
372 
373 				ihacres.CalcExcessRain_Redesign(m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_WI,
374 					m_p_elevbands[eb].m_p_ER, eR_init, m_p_elevbands[eb].m_sum_eRainGTpcp, m_nValues,
375 					m_p_nonlinparms->mp_c[eb], m_p_nonlinparms->mp_l[eb], m_p_nonlinparms->mp_p[eb],
376 					m_bSnowModule, m_pSnowparms[eb].T_Rain, m_pSnowparms[eb].T_Melt, m_p_elevbands[eb].m_p_MeltRate);
377 			} else {
378 				ihacres.CalcWetnessIndex_Redesign(m_p_elevbands[eb].m_p_Tw, m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_WI, 0.5,
379 					m_bSnowModule, 0, m_nValues);
380 
381 				ihacres.CalcExcessRain_Redesign(m_p_elevbands[eb].m_p_pcp, m_p_elevbands[eb].m_p_tmp, m_p_elevbands[eb].m_p_WI,
382 					m_p_elevbands[eb].m_p_ER, eR_init, m_p_elevbands[eb].m_sum_eRainGTpcp, m_nValues,
383 					m_p_nonlinparms->mp_c[eb], m_p_nonlinparms->mp_l[eb], m_p_nonlinparms->mp_p[eb],
384 					m_bSnowModule, 0,0,0);
385 			}
386 			break;
387 		} // end switch(m_IHAC_vers)
388 	}
389 }
390 //---------------------------------------------------------------------
391 
_Simulate_Streamflow()392 void Cihacres_elev_cal::_Simulate_Streamflow()
393 {
394 	//-------------------------------------------------------------
395 	// Assign random values
396 	//-------------------------------------------------------------
397 	for (int eb = 0; eb < m_nElevBands; eb++)
398 	{
399 		switch(m_StorConf)
400 		{
401 		case 0: // single storage
402 			m_p_linparms->a[eb]	= model_tools::Random_double(m_p_lin_lb->a[eb],m_p_lin_ub->a[eb]);
403 			m_p_linparms->b[eb]	= model_tools::Random_double(m_p_lin_lb->b[eb],m_p_lin_ub->b[eb]);
404 			break;
405 		case 1: // two storages in parallel
406 			do
407 			{
408 				m_p_linparms->aq[eb] = model_tools::Random_double(m_p_lin_lb->aq[eb], m_p_lin_ub->aq[eb]);
409 				m_p_linparms->as[eb] = model_tools::Random_double(m_p_lin_lb->as[eb], m_p_lin_ub->as[eb]);
410 				m_p_linparms->bq[eb] = model_tools::Random_double(m_p_lin_lb->bq[eb], m_p_lin_ub->bq[eb]);
411 				// Calculate parameter m_vq to check parms aq and bq
412 				// Equation after Jakeman & Hornberger (1993)
413 				m_vq[eb] = m_p_linparms->bq[eb] / ( 1 + m_p_linparms->aq[eb] );
414 			}
415 			while (m_vq[eb] < 0.0 || m_vq[eb] > 1.0);
416 			m_p_linparms->bs[eb] = ihacres.Calc_Parm_BS(m_p_linparms->aq[eb], m_p_linparms->as[eb], m_p_linparms->bq[eb]);
417 			break;
418 		}
419 
420 
421 		//----------------------------------------------------------
422 		// calculate streamflow
423 		//----------------------------------------------------------
424 		switch(m_StorConf)
425 		{
426 		case 0: // single storage
427 			ihacres.SimStreamflowSingle(m_p_elevbands[eb].m_p_ER, m_p_Q_obs_mmday[0],
428 				m_p_elevbands[eb].m_p_streamflow_sim, m_delay,
429 				m_p_linparms->a[eb], m_p_linparms->b[eb], m_nValues);
430 			break;
431 		case 1: // two storages in parallel
432 			ihacres.SimStreamflow2Parallel(m_p_elevbands[eb].m_p_ER,
433 				m_p_elevbands[eb].m_p_streamflow_sim, m_p_Q_obs_mmday[0],
434 				m_p_linparms, eb, m_vq[eb], m_vs[eb], m_nValues, m_delay);
435 			break;
436 		case 2: // two storages in series
437 			break;
438 		} // end switch(m_StorConf)
439 	}// end for (int eb...
440 }
441 //---------------------------------------------------------------------
442 
443 //---------------------------------------------------------------------
444 //		Summarize streamflow from elevation bands
445 //---------------------------------------------------------------------
_Sum_Streamflow()446 void Cihacres_elev_cal::_Sum_Streamflow()
447 {
448 	//std::ofstream f("_cal_elev.txt");
449 
450 	double sum = 0.0;
451 	for (int n = 0; n < m_nValues; n++)
452 	{
453 		for (int eb = 0; eb < m_nElevBands; eb++) {
454 			sum += m_p_elevbands[eb].m_p_streamflow_sim[n] * m_p_elevbands[eb].m_area / m_Area_tot;
455 			//f << m_p_elevbands[eb].m_p_streamflow_sim[n] << ", ");
456 		}
457 		//f << std::endl;
458 		m_p_Q_sim_mmday[n] = sum;
459 		sum = 0.0;
460 	}
461 }
462 //---------------------------------------------------------------------
463 
464 
465 //---------------------------------------------------------------------
466 //		Nash-Sutcliffe efficiency
467 //---------------------------------------------------------------------
_CalcEfficiency()468 void Cihacres_elev_cal::_CalcEfficiency()
469 {
470 	m_NSE			= model_tools::CalcEfficiency(m_p_Q_obs_mmday, m_p_Q_sim_mmday, m_nValues);
471 	m_NSE_highflow	= model_tools::Calc_NSE_HighFlow(m_p_Q_obs_mmday, m_p_Q_sim_mmday, m_nValues);
472 	m_NSE_lowflow	= model_tools::Calc_NSE_LowFlow(m_p_Q_obs_mmday, m_p_Q_sim_mmday, m_nValues);
473 	m_PBIAS			= model_tools::Calc_PBIAS(m_p_Q_obs_mmday, m_p_Q_sim_mmday, m_nValues);
474 }
475 //---------------------------------------------------------------------
476 
477 
478 /////////////////////////////////////////////////////////////////////////////
479 //
480 //							CREATE TABLES
481 //
482 /////////////////////////////////////////////////////////////////////////////
483 
484 //---------------------------------------------------------------------
485 //		Create output table
486 //---------------------------------------------------------------------
_CreateTableParms()487 void Cihacres_elev_cal::_CreateTableParms()
488 {
489 	char c[12];
490 
491 	// creating the column titles
492 	m_pTable_parms->Add_Field("NSE",				SG_DATATYPE_Double);
493 	m_pTable_parms->Add_Field("NSE_high",			SG_DATATYPE_Double);
494 	m_pTable_parms->Add_Field("NSE_low",			SG_DATATYPE_Double);
495 	m_pTable_parms->Add_Field("PBIAS",				SG_DATATYPE_Double);
496 	//m_pTable_parms->Add_Field("eR_ovest",			SG_DATATYPE_Double);
497 
498 	for (int i = 0; i < m_nElevBands; i++)
499 	{
500 		sprintf(c,"%s_%d","vq",i+1);
501 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
502 		sprintf(c,"%s_%d","vs",i+1);
503 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
504 		sprintf(c,"%s_%d","T(q)",i+1);
505 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
506 		sprintf(c,"%s_%d","T(s)",i+1);
507 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
508 		sprintf(c,"%s_%d","Tw",i+1);
509 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
510 		sprintf(c,"%s_%d","f",i+1);
511 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
512 		sprintf(c,"%s_%d","c",i+1);
513 		m_pTable_parms->Add_Field(c,					SG_DATATYPE_Double);
514 		if ( m_IHAC_version == 1 ) // Croke etal. (2005)
515 		{
516 			sprintf(c,"%s_%d","l",i+1);
517 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
518 			sprintf(c,"%s_%d","p",i+1);
519 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
520 		}
521 		if (m_bSnowModule)
522 		{
523 			sprintf(c,"%s_%d","T_Rain",i+1);
524 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
525 			sprintf(c,"%s_%d","T_Melt",i+1);
526 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
527 			sprintf(c,"%s_%d","DD_FAC",i+1);
528 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
529 		}
530 		switch(m_StorConf)
531 		{
532 		case 0: // single
533 			sprintf(c,"%s_%d","a",i+1);
534 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
535 			sprintf(c,"%s_%d","b",i+1);
536 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
537 			break;
538 		case 1: // two storages in parallel
539 			sprintf(c,"%s_%d","aq",i+1);
540 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
541 			sprintf(c,"%s_%d","as",i+1);
542 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
543 			sprintf(c,"%s_%d","bq",i+1);
544 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
545 			sprintf(c,"%s_%d","bs",i+1);
546 			m_pTable_parms->Add_Field(c,				SG_DATATYPE_Double);
547 			break;
548 		}
549 	}
550 }
551 //---------------------------------------------------------------------
552 
553 //---------------------------------------------------------------------
554 //		Create output table
555 //---------------------------------------------------------------------
_WriteTableParms()556 void Cihacres_elev_cal::_WriteTableParms()
557 {
558 	int					field = 0;
559 	CSG_Table_Record	*pRecord;
560 
561 	// add a new record to the table
562 	m_pTable_parms->Add_Record();
563 	pRecord	= m_pTable_parms->Get_Record(m_counter);
564 
565 	// writing the data to the current row
566 	pRecord->Set_Value(field,m_NSE); field++;
567 	pRecord->Set_Value(field,m_NSE_highflow); field++;
568 	pRecord->Set_Value(field,m_NSE_lowflow); field++;
569 	pRecord->Set_Value(field,m_PBIAS); field++;
570 	//pRecord->Set_Value(field,m_sum_eRainGTpcp); field++;
571 
572 	for (int eb = 0; eb < m_nElevBands; eb++)
573 	{
574 		pRecord->Set_Value(field,m_vq[eb]); field++;
575 		pRecord->Set_Value(field,m_vs[eb]); field++;
576 		pRecord->Set_Value(field,ihacres.Calc_TimeOfDecay(m_p_linparms->aq[eb])); field++;
577 		pRecord->Set_Value(field,ihacres.Calc_TimeOfDecay(m_p_linparms->as[eb])); field++;
578 		pRecord->Set_Value(field,m_p_nonlinparms->mp_tw[eb]); field++;
579 		pRecord->Set_Value(field,m_p_nonlinparms->mp_f[eb]); field++;
580 		pRecord->Set_Value(field,m_p_nonlinparms->mp_c[eb]); field++;
581 		if ( m_IHAC_version == 1 )
582 		{
583 			pRecord->Set_Value(field,m_p_nonlinparms->mp_l[eb]); field++;
584 			pRecord->Set_Value(field,m_p_nonlinparms->mp_p[eb]); field++;
585 		}
586 		if ( m_bSnowModule )
587 		{
588 			pRecord->Set_Value(field,m_pSnowparms[eb].T_Rain); field++;
589 			pRecord->Set_Value(field,m_pSnowparms[eb].T_Melt); field++;
590 			pRecord->Set_Value(field,m_pSnowparms[eb].DD_FAC); field++;
591 		}
592 		switch ( m_StorConf )
593 		{
594 		case 0: // single storage
595 			pRecord->Set_Value(field,m_p_linparms->a[eb]); field++;
596 			pRecord->Set_Value(field,m_p_linparms->b[eb]); field++;
597 			break;
598 		case 1:
599 			pRecord->Set_Value(field,m_p_linparms->aq[eb]); field++;
600 			pRecord->Set_Value(field,m_p_linparms->as[eb]); field++;
601 			pRecord->Set_Value(field,m_p_linparms->bq[eb]); field++;
602 			pRecord->Set_Value(field,m_p_linparms->bs[eb]); field++;
603 			break;
604 		}
605 	}
606 	m_counter++;
607 }
608 //---------------------------------------------------------------------
609 
610 
611 
612 //---------------------------------------------------------------------
_CreateTableSim()613 void Cihacres_elev_cal::_CreateTableSim()
614 {
615 	int i = 0; // used in function Get_Record(i)
616 	CSG_Table_Record	*pRecord;
617 	CSG_String			tmpName;
618 	double				sim_eb, sim;
619 
620 	// creating the column titles
621 	m_pTable->Add_Field("Date",		SG_DATATYPE_String);
622 	m_pTable->Add_Field("Flow_OBS",	SG_DATATYPE_Double);
623 
624 	for (int eb = 0; eb < m_nElevBands; eb++)
625 	{
626 		tmpName = SG_T("ELEVB_");
627 		tmpName += convert_sl::Int2String(eb+1).c_str();
628 		m_pTable->Add_Field(tmpName.c_str(),	SG_DATATYPE_Double);
629 	}
630 	m_pTable->Add_Field("Flow_SIM",	SG_DATATYPE_Double);
631 
632 	for (int j = 0; j < m_nValues; j++)
633 	{
634 		m_pTable->Add_Record();
635 		pRecord = m_pTable->Get_Record(i);
636 
637 		// writing the data into the rows
638 		pRecord->Set_Value(0,CSG_String(m_vec_date[j].c_str()));
639 		pRecord->Set_Value(1,m_p_Q_obs_m3s[j]);
640 		sim_eb = 0.0;
641 		sim = 0.0;
642 		for (int eb = 0; eb < m_nElevBands; eb++)
643 		{
644 			sim_eb = model_tools::mmday_to_m3s(m_p_elevbands[eb].m_p_streamflow_sim[j],m_p_elevbands[eb].m_area);
645 			//pRecord->Set_Value(3+eb,model_tools::mmday_to_m3s(m_p_elevbands[eb].m_p_streamflow_sim[j],m_p_elevbands[eb].m_area));
646 			pRecord->Set_Value(2+eb, sim_eb);
647 			sim += sim_eb;
648 		}
649 		pRecord->Set_Value(2+m_nElevBands,sim);
650 		i++;
651 	}
652 }
653 
654 
655 //---------------------------------------------------------------------
656 ///////////////////////////////////////////////////////////////////////
657 //
658 //		                          DIALOGS
659 //
660 ///////////////////////////////////////////////////////////////////////
661 //---------------------------------------------------------------------
662 // DIALOG 1
663 //---------------------------------------------------------------------
_CreateDialog1()664 void Cihacres_elev_cal::_CreateDialog1()
665 {
666 	CSG_Parameter	*pNode;
667 	CSG_String		s;
668 
669 	pNode = Parameters.Add_Choice(
670 		NULL	, "NELEVBANDS"		, SG_T("Number of elevation bands"),
671 		_TL(""),
672 		SG_T("2|3|4|5|6|7|8|9|10")
673 	);
674 
675 	pNode = Parameters.Add_Value(
676 		NULL,	"NSIM",	_TL("Number of Simulations"),
677 		_TL("Number of Simulations for Calibration"),
678 		PARAMETER_TYPE_Int,
679 		1000, 1, true, 10000000, true
680 	);
681 
682 	pNode = Parameters.Add_Value(
683 		pNode,	"AREA_tot", _TL("Total Catchment Area [km2]"),
684 			_TL(""),
685 			PARAMETER_TYPE_Double
686 	);
687 
688 	s.Printf(SG_T("Node1"), 1);
689 	pNode = Parameters.Add_Node(NULL,s,SG_T("IHACRES Version"),_TL(""));
690 
691 	Parameters.Add_Choice(
692 		pNode	, "IHACVERS"		, SG_T("IHACRES Version"),
693 		_TL(""),
694 		CSG_String::Format(SG_T("%s|%s|"),
695 			_TL("Jakeman & Hornberger (1993)"),	//  0
696 			_TL("Croke et al. (2005) !!! not yet implemented !!!")	//	1
697 		)
698 	);
699 
700 	s.Printf(SG_T("Node2"), 2);
701 	pNode = Parameters.Add_Node(NULL,s,SG_T("Storage Configuration"),_TL(""));
702 
703 	Parameters.Add_Choice(
704 		pNode	, "STORAGE"		, SG_T("Storage"),
705 		_TL(""),
706 		CSG_String::Format(SG_T("%s|%s|%s|"),
707 			_TL("Single Storage"),			//  0
708 			_TL("Two Parallel Storages"),	//  1
709 			_TL("Two Storages in Series !!! not yet implemented !!!")	//  2
710 		)
711 	);
712 
713 	Parameters.Add_Value(
714 		pNode,	"SNOW_TOOL",	_TL("Using the snow-melt module?"),
715 		_TL("If checked, snow-melt module is used."),
716 		PARAMETER_TYPE_Bool, false
717 	);
718 
719 	s.Printf(SG_T("Node6"), 6);
720 	pNode = Parameters.Add_Node(NULL,s,SG_T("Nash-Sutcliffe Efficiency"),_TL(""));
721 
722 	Parameters.Add_Choice(
723 		pNode, "OBJ_FUNC"		, SG_T("Objective Function"),
724 		_TL(""),
725 		SG_T("NSE|NSE high flow|NSE low flow")
726 	);
727 
728 	Parameters.Add_Value(
729 		pNode,	"NSEMIN",	SG_T("Minimum Nash-Sutcliffe Efficiency"),
730 		SG_T("Minimum Nash-Sutcliffe Efficiency required to print simulation to calibration table"),
731 		PARAMETER_TYPE_Double,
732 		0.7, 0.1, true, 1.0, true
733 	);
734 }
735 //---------------------------------------------------------------------
736 // DIALOG 2
737 //---------------------------------------------------------------------
738 
_CreateDialog2()739 bool Cihacres_elev_cal::_CreateDialog2()
740 {
741 	int		i;
742 
743 	//std::ofstream f("_out_elev.txt");
744 
745 	CSG_Parameters	P;  // used to add Parameters in the second dialog
746 	CSG_Parameter	*pNode, *pNode1;
747 	CSG_String		s;
748 	CSG_String		tmpNode, tmpName;
749 
750 	P.Set_Name(_TL("IHACRES Elevation Bands (Dialog 2)"));
751 	// Input file ----------------------------------------------
752 	pNode = P.Add_Table(
753 		NULL	, "TABLE"	, _TL("IHACRES Input Table"),
754 		_TL(""),
755 		PARAMETER_INPUT
756 	);
757 
758 	P.Add_Table_Field(
759 		pNode	, "DATE_Field"	, _TL("Date Column"),
760 		SG_T("Select the column containing the Date")
761 	);
762 
763 	P.Add_Table_Field(
764 		pNode	, "DISCHARGE_Field"	, _TL("Streamflow (obs.) Column"),
765 		SG_T("Select the column containing the observed streamflow time series")
766 	);
767 
768 	for (i = 0; i < m_nElevBands; i++)
769 	{
770 		tmpNode = convert_sl::Int2String(i+1).c_str();
771 		//s.Printf(tmpNode.c_str(), i);
772 		//pNode1 = P.Add_Node(NULL,s,SG_T("Elevation Band Input",_TL(""));
773 
774 		tmpName = SG_T("PCP Column: Elevation Band: ");
775 		tmpName+=tmpNode;
776 		P.Add_Table_Field(
777 			pNode	, tmpName.c_str(), tmpName.c_str(),
778 			SG_T("Select Precipitation Column")
779 		);
780 
781 		tmpName = SG_T("TMP Column: Elevation Band: ");
782 		tmpName+=tmpNode;
783 		P.Add_Table_Field(
784 			pNode	, tmpName.c_str()	, tmpName.c_str(),
785 			SG_T("Select Temperature Column")
786 		);
787 	}
788 	// Input file ----------------------------------------------
789 
790 	for (i = 0; i < m_nElevBands; i++)
791 	{
792 		tmpNode = SG_T("Node");
793 		tmpNode+=convert_sl::Int2String(i+100).c_str();
794 		tmpName = SG_T("Elevation Band ");
795 		tmpName+=convert_sl::Int2String(i+1).c_str();
796 
797 		s.Printf(tmpNode.c_str(), i+100);
798 		pNode = P.Add_Node(NULL,s,tmpName.c_str(),_TL(""));
799 
800 		tmpName = SG_T("Area [km2] Elev(");
801 		tmpName += tmpNode;
802 		tmpName += _TL(")");
803 		P.Add_Value(
804 			pNode,	tmpName, _TL("Area [km2]"),
805 			_TL(""),
806 			PARAMETER_TYPE_Double
807 		);
808 
809 		tmpName = SG_T("Mean Elevation [m.a.s.l] Elev(");
810 		tmpName += tmpNode;
811 		tmpName += _TL(")");
812 		P.Add_Value(
813 			pNode,	tmpName, _TL("Mean Elevation [m.a.s.l]"),
814 			_TL(""),
815 			PARAMETER_TYPE_Double
816 		);
817 
818 
819 		// Parameters of non-linear module -------------------------
820 
821 		tmpNode = SG_T("Node");
822 		tmpNode+=convert_sl::Int2String(i+150).c_str();
823 		s.Printf(tmpNode.c_str(), i+150);
824 		pNode1 = P.Add_Node(pNode,s,SG_T("Non-Linear Tool"),_TL(""));
825 
826 		tmpName = SG_T("TwFAC_lb(");
827 		tmpName += tmpNode;
828 		tmpName += _TL(")");
829 		P.Add_Value(
830 			pNode1,	tmpName,	_TL("(Tw) wetness decline time constant [lower bound]"),
831 			_TW("Tw is approximately the time constant, or inversely,"
832 			"the rate at which the catchment wetness declines in the absence of rainfall"),
833 			PARAMETER_TYPE_Double,
834 			1.0, 0.01, true, 150.0, true
835 		);
836 		tmpName = SG_T("TwFAC_ub(");
837 		tmpName += tmpNode;
838 		tmpName += _TL(")");
839 		P.Add_Value(
840 			pNode1,	tmpName,	_TL("(Tw) wetness decline time constant [upper bound]"),
841 			_TW("Tw is approximately the time constant, or inversely,"
842 			"the rate at which the catchment wetness declines in the absence of rainfall"),
843 			PARAMETER_TYPE_Double,
844 			1.0, 0.01, true, 150.0, true
845 			);
846 
847 		tmpName = SG_T("TFAC_lb(");
848 		tmpName += tmpNode;
849 		tmpName += _TL(")");
850 		P.Add_Value(
851 			pNode1, tmpName, SG_T("(f) Temperature Modulation Factor [lower bound]"),
852 			_TL("Temperature Modulation Factor f"),
853 			PARAMETER_TYPE_Double,
854 			0.05, 0.0001, true, 5.0, true
855 		);
856 
857 		tmpName = SG_T("TFAC_ub(");
858 		tmpName += tmpNode;
859 		tmpName += _TL(")");
860 		P.Add_Value(
861 			pNode1, tmpName, SG_T("(f) Temperature Modulation Factor [upper bound]"),
862 			_TL("Temperature Modulation Factor f"),
863 			PARAMETER_TYPE_Double,
864 			0.5, 0.0001, true, 5.0, true
865 		);
866 
867 		tmpName = SG_T("CFAC_lb(");
868 		tmpName += tmpNode;
869 		tmpName += _TL(")");
870 		P.Add_Value(
871 			pNode1,tmpName,	_TL("(c) Parameter [lower bound]"),
872 			_TL("Parameter (c) to fit streamflow volume"),
873 			PARAMETER_TYPE_Double,
874 			0.001, 0.0, true, 1.0, true
875 		);
876 		tmpName = SG_T("CFAC_ub(");
877 		tmpName += tmpNode;
878 		tmpName += _TL(")");
879 		P.Add_Value(
880 			pNode1,tmpName,	_TL("(c) Parameter [upper bound]"),
881 			_TL("Parameter (c) to fit streamflow volume"),
882 			PARAMETER_TYPE_Double,
883 			0.01, 0.0, true, 1.0, true
884 		);
885 
886 		switch(m_IHAC_version)
887 		{
888 		case 0: // Jakeman & Hornberger (1993)
889 			break;
890 		case 1: // Croke et al. (2005)
891 			tmpNode = SG_T("Node");
892 			tmpNode+=convert_sl::Int2String(i+200).c_str();
893 			s.Printf(tmpNode.c_str(), i+200);
894 			pNode1 = P.Add_Node(pNode,s,SG_T("Soil Moisture Power Eq."),_TL(""));
895 
896 			tmpName = SG_T("LFAC_lb(");
897 			tmpName += tmpNode;
898 			tmpName += _TL(")");
899 			P.Add_Value(
900 				pNode1,	tmpName, _TL("Parameter (l) [lower bound]"),
901 				_TL("Soil moisture index threshold"),
902 				PARAMETER_TYPE_Double,
903 				0.0, 0.0, true, 5.0, true
904 			);
905 			tmpName = SG_T("LFAC_ub(");
906 			tmpName += tmpNode;
907 			tmpName += _TL(")");
908 			P.Add_Value(
909 				pNode1,	tmpName, _TL("Parameter (l) [upper bound]"),
910 				_TL("Soil moisture index threshold"),
911 				PARAMETER_TYPE_Double,
912 				0.0, 0.0, true, 5.0, true
913 			);
914 
915 			tmpName = SG_T("PFAC_lb(");
916 			tmpName += tmpNode;
917 			tmpName += _TL(")");
918 			P.Add_Value(
919 				pNode1,	tmpName,	_TL("Parameter (p) [lower bound]"),
920 				_TL("non-linear response term"),
921 				PARAMETER_TYPE_Double,
922 				0.0, 0.0, true, 5.0, true
923 			);
924 			tmpName = SG_T("PFAC_ub(");
925 			tmpName += tmpNode;
926 			tmpName += _TL(")");
927 			P.Add_Value(
928 				pNode1,	tmpName,	_TL("Parameter (p) [upper bound]"),
929 				_TL("non-linear response term"),
930 				PARAMETER_TYPE_Double,
931 				0.0, 0.0, true, 5.0, true
932 			);
933 			break;
934 		}
935 		// Parameters of non-linear module -------------------------
936 
937 		// Parameters of linear module -----------------------------
938 		switch(m_StorConf)
939 		{
940 		case 0: // single storage
941 			tmpNode = SG_T("Node");
942 			tmpNode+=convert_sl::Int2String(i+250).c_str();
943 			s.Printf(tmpNode.c_str(), i+250);
944 			pNode1 = P.Add_Node(pNode,s,SG_T("Linear Tool"),_TL(""));
945 
946 			tmpName = SG_T("AFAC_lb(");
947 			tmpName += tmpNode;
948 			tmpName += _TL(")");
949 			P.Add_Value(
950 				pNode1,	tmpName,	_TL("(a) [lower bound]"),
951 				_TL(""),
952 				PARAMETER_TYPE_Double,
953 				-0.8, -0.99, true, -0.01, true
954 			);
955 			tmpName = SG_T("AFAC_ub(");
956 			tmpName += tmpNode;
957 			tmpName += _TL(")");
958 			P.Add_Value(
959 				pNode1,	tmpName,	_TL("(a) [upper bound]"),
960 				_TL(""),
961 				PARAMETER_TYPE_Double,
962 				-0.8, -0.99, true, -0.01, true
963 			);
964 
965 			tmpName = SG_T("BFAC_lb(");
966 			tmpName += tmpNode;
967 			tmpName += _TL(")");
968 			P.Add_Value(
969 				pNode1,	tmpName,	_TL("(b) [lower bound]"),
970 				_TL(""),
971 				PARAMETER_TYPE_Double,
972 				0.2, 0.001, true, 1.0, true
973 			);
974 			tmpName = SG_T("BFAC_ub(");
975 			tmpName += tmpNode;
976 			tmpName += _TL(")");
977 			P.Add_Value(
978 				pNode1,	tmpName,	_TL("(b) [upper bound]"),
979 				_TL(""),
980 				PARAMETER_TYPE_Double,
981 				0.2, 0.001, true, 1.0, true
982 			);
983 			break;
984 
985 		case 1: // two parallel storages
986 			tmpNode = SG_T("Node");
987 			tmpNode+=convert_sl::Int2String(i+250).c_str();
988 			s.Printf(tmpNode.c_str(), i+250);
989 			pNode1 = P.Add_Node(pNode,s,SG_T("Linear Tool"),_TL(""));
990 
991 			// Parameter a
992 
993 			tmpName = SG_T("AQ_lb(");
994 			tmpName += tmpNode;
995 			tmpName += _TL(")");
996 			P.Add_Value(
997 				pNode1,	tmpName,	_TL("a(q) [lower bound]"),
998 				_TL(""),
999 				PARAMETER_TYPE_Double,
1000 				-0.7, -0.99, true, -0.01, true
1001 			);
1002 			tmpName = SG_T("AQ_ub(");
1003 			tmpName += tmpNode;
1004 			tmpName += _TL(")");
1005 			P.Add_Value(
1006 				pNode1,	tmpName,	_TL("a(q) [upper bound]"),
1007 				_TL(""),
1008 				PARAMETER_TYPE_Double,
1009 				-0.7, -0.99, true, -0.01, true
1010 			);
1011 
1012 			tmpName = SG_T("AS_lb(");
1013 			tmpName += tmpNode;
1014 			tmpName += _TL(")");
1015 			P.Add_Value(
1016 				pNode1,	tmpName,	_TL("a(s) [lower bound]"),
1017 				_TL(""),
1018 				PARAMETER_TYPE_Double,
1019 				-0.9, -0.99, true, -0.01, true
1020 			);
1021 			tmpName = SG_T("AS_ub(");
1022 			tmpName += tmpNode;
1023 			tmpName += _TL(")");
1024 			P.Add_Value(
1025 				pNode1,	tmpName,	_TL("a(s) [upper bound]"),
1026 				_TL(""),
1027 				PARAMETER_TYPE_Double,
1028 				-0.9, -0.99, true, -0.01, true
1029 			);
1030 
1031 			// Parameter b
1032 
1033 			tmpName = SG_T("BQ_lb(");
1034 			tmpName += tmpNode;
1035 			tmpName += _TL(")");
1036 			P.Add_Value(
1037 				pNode1,	tmpName,	_TL("b(q) [lower bound]"),
1038 				_TL(""),
1039 				PARAMETER_TYPE_Double,
1040 				0.0, 0.0, true, 1.0, true
1041 			);
1042 			tmpName = SG_T("BQ_ub(");
1043 			tmpName += tmpNode;
1044 			tmpName += _TL(")");
1045 			P.Add_Value(
1046 				pNode1,	tmpName,	_TL("b(q) [upper bound]"),
1047 				_TL(""),
1048 				PARAMETER_TYPE_Double,
1049 				0.0, 0.0, true, 1.0, true
1050 			);
1051 			break;
1052 
1053 		case 2: // two storages in series
1054 			break;
1055 		} // end switch (storconf)
1056 		// Parameters of linear module -----------------------------
1057 
1058 		tmpNode = SG_T("Node");
1059 		tmpNode+=convert_sl::Int2String(i+300).c_str();
1060 		s.Printf(tmpNode.c_str(), i+300);
1061 		pNode1 = P.Add_Node(pNode,s,SG_T("Time Delay after Start of Rainfall (INTEGER)"),_TL(""));
1062 
1063 		tmpName = SG_T("DELAY(");
1064 			tmpName += tmpNode;
1065 			tmpName += _TL(")");
1066 		P.Add_Value(
1067 			pNode1,	tmpName,	SG_T("Time Delay (Rain-Runoff)"),
1068 			SG_T("The delay after the start of rainfall, before the discharge starts to rise."),
1069 			PARAMETER_TYPE_Int,
1070 			0, 1, true, 100, true
1071 		);
1072 
1073 		// snow module parameters ----------------------------------
1074 		if (m_bSnowModule)
1075 		{
1076 			tmpNode = SG_T("Node");
1077 			tmpNode+=convert_sl::Int2String(i+350).c_str();
1078 			s.Printf(tmpNode.c_str(), i+350);
1079 			pNode1 = P.Add_Node(pNode,s,SG_T("Snow Tool Parameters"),_TL(""));
1080 
1081 			tmpName = SG_T("T_RAIN_lb(");
1082 			tmpName += tmpNode;
1083 			tmpName += _TL(")");
1084 			P.Add_Value(
1085 				pNode1,	tmpName,	SG_T("Temperature Threshold for Rainfall [lower bound]"),
1086 				SG_T("Below this threshold precipitation will fall as snow"),
1087 				PARAMETER_TYPE_Double,
1088 				-1.0, -10.0, true, 10.0, true
1089 			);
1090 			tmpName = SG_T("T_RAIN_ub(");
1091 			tmpName += tmpNode;
1092 			tmpName += _TL(")");
1093 			P.Add_Value(
1094 				pNode1,	tmpName,	SG_T("Temperature Threshold for Rainfall [upper bound]"),
1095 				SG_T("Below this threshold precipitation will fall as snow"),
1096 				PARAMETER_TYPE_Double,
1097 				-1.0, -10.0, true, 10.0, true
1098 			);
1099 
1100 			tmpName = SG_T("T_MELT_lb(");
1101 			tmpName += tmpNode;
1102 			tmpName += _TL(")");
1103 			P.Add_Value(
1104 				pNode1,	tmpName,	SG_T("Temperature Threshold for Melting [lower bound]"),
1105 				SG_T("Above this threshold snow will start to melt"),
1106 				PARAMETER_TYPE_Double,
1107 				1.0, -5.0, true, 10.0, true
1108 			);
1109 			tmpName = SG_T("T_MELT_ub(");
1110 			tmpName += tmpNode;
1111 			tmpName += _TL(")");
1112 			P.Add_Value(
1113 				pNode1,	tmpName,	SG_T("Temperature Threshold for Melting [upper bound]"),
1114 				SG_T("Above this threshold snow will start to melt"),
1115 				PARAMETER_TYPE_Double,
1116 				1.0, -5.0, true, 10.0, true
1117 			);
1118 
1119 			tmpName = SG_T("DD_FAC_lb(");
1120 			tmpName += tmpNode;
1121 			tmpName += _TL(")");
1122 			P.Add_Value(
1123 				pNode1,	tmpName,	SG_T("Day-Degree Factor [lower bound]"),
1124 				SG_T("Day-Degree Factor depends on catchment characteristics"),
1125 				PARAMETER_TYPE_Double,
1126 				0.7, 0.7, true, 9.2, true
1127 			);
1128 			tmpName = SG_T("DD_FAC_ub(");
1129 			tmpName += tmpNode;
1130 			tmpName += _TL(")");
1131 			P.Add_Value(
1132 				pNode1,	tmpName,	SG_T("Day-Degree Factor [upper bound]"),
1133 				SG_T("Day-Degree Factor depends on catchment characteristics"),
1134 				PARAMETER_TYPE_Double,
1135 				0.7, 0.7, true, 9.2, true
1136 			);
1137 		}
1138 		// snow module parameters ----------------------------------
1139 	}
1140 
1141 	if( SG_UI_Dlg_Parameters(&P, _TL("IHACRES Distributed Input Dialog 2")) )
1142 	{
1143 		// input table
1144 		m_p_InputTable		= P("TABLE")				->asTable();
1145 		// field numbers
1146 		m_dateField			= P("DATE_Field")			->asInt();
1147 		m_streamflowField	= P("DISCHARGE_Field")		->asInt();
1148 		for (int i = 0; i < m_nElevBands; i++)
1149 		{
1150 			tmpNode = convert_sl::Int2String(i+1).c_str();
1151 
1152 			// get precipitation column of Elevation Band[i]
1153 			tmpName = SG_T("PCP Column: Elevation Band: ");
1154 			tmpName+=tmpNode;
1155 			m_p_pcpField[i]			= P(tmpName)		->asInt();
1156 
1157 			// get temperature column of Elevation Band[i]
1158 			tmpName = SG_T("TMP Column: Elevation Band: ");
1159 			tmpName+=tmpNode;
1160 			m_p_tmpField[i]			= P(tmpName)		->asInt();
1161 
1162 			tmpNode = SG_T("Node");
1163 			tmpNode+=convert_sl::Int2String(i+100).c_str();
1164 
1165 			// get area[km2] of Elevation Band[i]
1166 			tmpName = SG_T("Area [km2] Elev(");
1167 			tmpName += tmpNode;
1168 			tmpName += _TL(")");
1169 			m_p_elevbands[i].m_area	= P(tmpName)		->asDouble();
1170 
1171 			// get mean elevation of Elevation Band[i]
1172 			tmpName = SG_T("Mean Elevation [m.a.s.l] Elev(");
1173 			tmpName += tmpNode;
1174 			tmpName += _TL(")");
1175 			m_p_elevbands[i].m_mean_elev =P(tmpName)	->asDouble();
1176 
1177 
1178 			// non-linear module parameters
1179 			tmpNode = SG_T("Node");
1180 			tmpNode+=convert_sl::Int2String(i+150).c_str();
1181 			// get Tw
1182 			tmpName = SG_T("TwFAC_lb(");
1183 			tmpName += tmpNode;
1184 			tmpName += _TL(")");
1185 			m_p_nl_lb->mp_tw[i]			= P(tmpName)	->asDouble();
1186 
1187 			tmpName = SG_T("TwFAC_ub(");
1188 			tmpName += tmpNode;
1189 			tmpName += _TL(")");
1190 			m_p_nl_ub->mp_tw[i]			= P(tmpName)	->asDouble();
1191 
1192 			// get f
1193 			tmpName = SG_T("TFAC_lb(");
1194 			tmpName += tmpNode;
1195 			tmpName += _TL(")");
1196 			m_p_nl_lb->mp_f[i]			= P(tmpName)	->asDouble();
1197 
1198 			tmpName = SG_T("TFAC_ub(");
1199 			tmpName += tmpNode;
1200 			tmpName += _TL(")");
1201 			m_p_nl_ub->mp_f[i]			= P(tmpName)	->asDouble();
1202 
1203 			// get c
1204 			tmpName = SG_T("CFAC_lb(");
1205 			tmpName += tmpNode;
1206 			tmpName += _TL(")");
1207 			m_p_nl_lb->mp_c[i]			= P(tmpName)	->asDouble();
1208 
1209 			tmpName = SG_T("CFAC_ub(");
1210 			tmpName += tmpNode;
1211 			tmpName += _TL(")");
1212 			m_p_nl_ub->mp_c[i]			= P(tmpName)	->asDouble();
1213 
1214 			switch(m_IHAC_version)
1215 			{
1216 			case 0: // Jakeman & Hornberger (1993)
1217 				break;
1218 			case 1: // Croke et al. (2005)
1219 				tmpNode = SG_T("Node");
1220 				tmpNode+=convert_sl::Int2String(i+200).c_str();
1221 				// get l
1222 				tmpName = SG_T("LFAC_lb(");
1223 				tmpName += tmpNode;
1224 				tmpName += _TL(")");
1225 				m_p_nl_lb->mp_l[i]= P(tmpName)	->asDouble();
1226 
1227 				tmpName = SG_T("LFAC_ub(");
1228 				tmpName += tmpNode;
1229 				tmpName += _TL(")");
1230 				m_p_nl_ub->mp_l[i]= P(tmpName)	->asDouble();
1231 
1232 				// get p
1233 				tmpName = SG_T("PFAC_lb(");
1234 				tmpName += tmpNode;
1235 				tmpName += _TL(")");
1236 				m_p_nl_lb->mp_p[i]= P(tmpName)	->asDouble();
1237 
1238 				tmpName = SG_T("PFAC_ub(");
1239 				tmpName += tmpNode;
1240 				tmpName += _TL(")");
1241 				m_p_nl_ub->mp_p[i]= P(tmpName)	->asDouble();
1242 			}
1243 
1244 			// linear module parameters
1245 			switch(m_nStorages)
1246 			{
1247 			case 1: // single storage
1248 				tmpNode = SG_T("Node");
1249 				tmpNode+=convert_sl::Int2String(i+250).c_str();
1250 				// get a
1251 				tmpName = SG_T("AFAC_lb(");
1252 				tmpName += tmpNode;
1253 				tmpName += _TL(")");
1254 				m_p_lin_lb->a[i]		= P(tmpName)	->asDouble();
1255 
1256 				tmpName = SG_T("AFAC_ub(");
1257 				tmpName += tmpNode;
1258 				tmpName += _TL(")");
1259 				m_p_lin_ub->a[i]		= P(tmpName)	->asDouble();
1260 
1261 				// get b
1262 				tmpName = SG_T("BFAC_lb(");
1263 				tmpName += tmpNode;
1264 				tmpName += _TL(")");
1265 				m_p_lin_lb->b[i]		= P(tmpName)	->asDouble();
1266 
1267 				tmpName = SG_T("BFAC_ub(");
1268 				tmpName += tmpNode;
1269 				tmpName += _TL(")");
1270 				m_p_lin_ub->b[i]		= P(tmpName)	->asDouble();
1271 				break;
1272 			case 2: // two storages
1273 				tmpNode = SG_T("Node");
1274 				tmpNode+=convert_sl::Int2String(i+250).c_str();
1275 				// get aq
1276 				tmpName = SG_T("AQ_lb(");
1277 				tmpName += tmpNode;
1278 				tmpName += _TL(")");
1279 				m_p_lin_lb->aq[i]		= P(tmpName)	->asDouble();
1280 
1281 				tmpName = SG_T("AQ_ub(");
1282 				tmpName += tmpNode;
1283 				tmpName += _TL(")");
1284 				m_p_lin_ub->aq[i]		= P(tmpName)	->asDouble();
1285 
1286 				// get bq
1287 				tmpName = SG_T("BQ_lb(");
1288 				tmpName += tmpNode;
1289 				tmpName += _TL(")");
1290 				m_p_lin_lb->bq[i]		= P(tmpName)	->asDouble();
1291 
1292 				tmpName = SG_T("BQ_ub(");
1293 				tmpName += tmpNode;
1294 				tmpName += _TL(")");
1295 				m_p_lin_ub->bq[i]		= P(tmpName)	->asDouble();
1296 
1297 				// get as
1298 				tmpName = SG_T("AS_lb(");
1299 				tmpName += tmpNode;
1300 				tmpName += _TL(")");
1301 				m_p_lin_lb->as[i]		= P(tmpName)	->asDouble();
1302 
1303 				tmpName = SG_T("AS_ub(");
1304 				tmpName += tmpNode;
1305 				tmpName += _TL(")");
1306 				m_p_lin_ub->as[i]		= P(tmpName)	->asDouble();
1307 				break;
1308 			}
1309 
1310 			// get delay
1311 			tmpNode = SG_T("Node");
1312 			tmpNode+=convert_sl::Int2String(i+300).c_str();
1313 			tmpName = SG_T("DELAY(");
1314 			tmpName += tmpNode;
1315 			tmpName += _TL(")");
1316 			m_delay		= P(tmpName)					->asInt();
1317 
1318 			if (m_bSnowModule)
1319 			{
1320 				tmpNode = SG_T("Node");
1321 				tmpNode+=convert_sl::Int2String(i+350).c_str();
1322 
1323 				tmpName = SG_T("T_RAIN_lb(");
1324 				tmpName += tmpNode;
1325 				tmpName += _TL(")");
1326 				m_pSnowparms_lb[i].T_Rain	= P(tmpName)	->asDouble();
1327 
1328 				tmpName = SG_T("T_RAIN_ub(");
1329 				tmpName += tmpNode;
1330 				tmpName += _TL(")");
1331 				m_pSnowparms_ub[i].T_Rain	= P(tmpName)	->asDouble();
1332 
1333 				tmpName = SG_T("T_MELT_lb(");
1334 				tmpName += tmpNode;
1335 				tmpName += _TL(")");
1336 				m_pSnowparms_lb[i].T_Melt	= P(tmpName)	->asDouble();
1337 
1338 				tmpName = SG_T("T_MELT_ub(");
1339 				tmpName += tmpNode;
1340 				tmpName += _TL(")");
1341 				m_pSnowparms_ub[i].T_Melt	= P(tmpName)	->asDouble();
1342 
1343 				tmpName = SG_T("DD_FAC_lb(");
1344 				tmpName += tmpNode;
1345 				tmpName += _TL(")");
1346 				m_pSnowparms_lb[i].DD_FAC	= P(tmpName)	->asDouble();
1347 
1348 				tmpName = SG_T("DD_FAC_ub(");
1349 				tmpName += tmpNode;
1350 				tmpName += _TL(")");
1351 				m_pSnowparms_ub[i].DD_FAC	= P(tmpName)	->asDouble();
1352 			}
1353 
1354 		} // end for (int i = 0; i < m_nSubbasins; i++)
1355 
1356 		return(true);
1357 	}
1358 	return(false);
1359 }
1360 
1361 //---------------------------------------------------------------------
1362 // DIALOG 3
1363 //---------------------------------------------------------------------
1364 
_CreateDialog3()1365 bool Cihacres_elev_cal::_CreateDialog3()
1366 {
1367 	CSG_String		s;
1368 	CSG_Parameters	P;  // used to add Parameters in the second dialog
1369 	CSG_Parameter	*pNode;
1370 
1371 	//	Dialog design
1372 	P.Set_Name(_TL("Choose Time Range"));
1373 
1374 	s.Printf(SG_T("Node1"), 1);
1375 	pNode = P.Add_Node(NULL,s,SG_T("Time Range"),_TL(""));
1376 
1377 	s.Printf(SG_T("FDAY") , 1-1);
1378 	P.Add_String(pNode,s,_TL("First Day"),_TL(""),
1379 				 m_p_InputTable->Get_Record(0)->asString(m_dateField));
1380 
1381 	s.Printf(SG_T("LDAY") , 1-2);
1382 	P.Add_String(pNode,s,_TL("Last Day"),_TL(""),
1383 				 m_p_InputTable->Get_Record(m_p_InputTable->Get_Record_Count()-1)->asString(m_dateField));
1384 
1385 	if( SG_UI_Dlg_Parameters(&P, _TL("Choose Time Range")) )
1386 	{
1387 		///////////////////////////////////////////////////////////////
1388 		//
1389 		//                ASSIGN DATA FROM SECOND DIALOG
1390 		//
1391 		///////////////////////////////////////////////////////////////
1392 		m_date1		= P(CSG_String::Format(SG_T("FDAY"),m_dateField).c_str())->asString();
1393 		m_date2		= P(CSG_String::Format(SG_T("LDAY"),m_streamflowField).c_str())->asString();
1394 		return(true);
1395 	}
1396 	return(false);
1397 }
1398