FFSM++ 1.1.0
French Forest Sector Model ++
Loading...
Searching...
No Matches
ModelData.cpp
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2015 by Laboratoire d'Economie Forestière *
3 * http://ffsm-project.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version, given the compliance with the *
9 * exceptions listed in the file COPYING that is distribued together *
10 * with this file. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22
23#include <sys/types.h>
24#include <dirent.h>
25#include <errno.h>
26#include <iostream>
27
28#include <vector>
29#include <string>
30#include <sstream>
31#include <stdexcept>
32#include <algorithm> //alghoritm used to reverse an array ( reverse(v.begin(), v.end()); )
33#include <iomanip> // for unzip
34#include <math.h>
35#include <random> // for random temp directory to unzip
36
37// Qt headers..
38#include <QFile>
39#include <QFileInfo>
40#include <QString>
41#include <QStringList>
42#include <QList>
43
44// Unzip headers..
45#include "unzip.h"
46
47// RegMAS headers..
48#include "ModelData.h"
49//#include "InputDocument.h"
50//#include "InputNode.h"
51#include "MainWindow.h"
52#include "Scheduler.h"
53#include "ModelRegion.h"
54#include "Pixel.h"
55
56typedef map<string, vector <double> > DataMap;
57typedef pair<string, vector <double> > DataPair;
58
59
60
62 MTHREAD = MTHREAD_h;
64 tempBool = true;
65 valueFoundBool = true;
66}
67
71
73ModelData::getForType(string &forTypeId_h){
74 for(int i=0;i<forTypes.size();i++){
75 if(forTypes[i].forTypeId==forTypeId_h) return &forTypes[i];
76 }
77 msgOut(MSG_CRITICAL_ERROR,"forTypeId "+forTypeId_h+" not found. Aborting.");
78}
79
80int
81ModelData::getForTypeCounter(string& forTypeId_h, bool all){
82 vector <string> fTIds = getForTypeIds(all);
83 for(int i=0;i<fTIds.size();i++){
84 if(fTIds[i]==forTypeId_h) return i;
85 }
86 msgOut(MSG_CRITICAL_ERROR,"forTypeId "+forTypeId_h+" not found in "+((string) __func__ )+". Aborting.");
87}
88
89string
90ModelData::getForTypeParentId(const string &forTypeId_h){
91 for(int i=0;i<forTypes.size();i++){
92 if(forTypes[i].forTypeId==forTypeId_h) return forTypes[i].ereditatedFrom;
93 }
94 msgOut(MSG_CRITICAL_ERROR,"forTypeId "+forTypeId_h+" not found. Aborting.");
95}
96
97vector<string>
98ModelData::getForTypeChilds(const string &forTypeId_h){
99 vector<string> childs;
100 for(int i=0;i<forTypes.size();i++){
101 if(forTypes[i].ereditatedFrom==forTypeId_h) {
102 childs.push_back(forTypes[i].forTypeId);
103 }
104 }
105 return childs;
106}
107
108vector<int>
109ModelData::getForTypeChilds_pos(const string &forTypeId_h, bool all){
110 vector <int> childs;
111 vector <string> fTIds = getForTypeIds(all);
112 for(int i=0;i<fTIds.size();i++){
113 forType* ft = getForType(fTIds[i]);
114 if(ft->ereditatedFrom==forTypeId_h) {
115 childs.push_back(i);
116 }
117 }
118 return childs;
119}
120
121vector<string>
123 vector<string> parents;
124 for(int i=0;i<forTypes.size();i++){
125 string parent = forTypes[i].ereditatedFrom;
126 if(!inVector(parent,parents) && parent != ""){
127 parents.push_back(parent);
128 }
129 }
130 return parents;
131}
132
133
134int
135ModelData::getNForTypesChilds(const string& forTypeId_h){
136 int nChilds = 0;
137 for(int i=0;i<forTypes.size();i++){
138 if(forTypes[i].ereditatedFrom==forTypeId_h) {
139 nChilds ++;
140 }
141 }
142 return nChilds;
143}
144
145vector<string>
147 vector<string> toReturn;
148 LLData table = getTable("scenarios");
149 for(int i=0;i<table.nrecords();i++){
150 string scenarioName = table.getData(i,"id");
151 toReturn.push_back(scenarioName);
152 }
153 return toReturn;
154}
155
156int
158 vector<string> scenarios = getScenarios(); /// \todo Check that I can call this function all around the model and not only at the beginning
159 string currentScenario = MTHREAD->getScenarioName();
160 for(int i=0;i<scenarios.size();i++){
161 if (currentScenario == scenarios[i]){
162 return i;
163 }
164 }
165 msgOut(MSG_CRITICAL_ERROR, "function getScenarioIndex() didn't found the current scenarioName within those returned by getScenarios().");
166 return 0;
167}
168
169void
171 LLData table = getTable("scenarios");
172 string choosenScenario = MTHREAD->getScenarioName();
173 for(int i=0;i<table.nrecords();i++){
174 string recordScenarioName = table.getData(i,"id");
175 if (recordScenarioName == choosenScenario){
176 scenario.id = recordScenarioName;
177 scenario.shortDesc = table.getData(i,"shortDesc");
178 scenario.longDesc = table.getData(i,"longDesc");
179 scenario.settingTable = table.getData(i,"settingTable");
180 scenario.forDataTable = table.getData(i,"forDataTable");
181 scenario.prodDataTable = table.getData(i,"prodDataTable");
182 scenario.forToProdTable = table.getData(i,"forToProdTable");
183 scenario.pathTable = table.getData(i,"pathTable");
184 scenario.settingFile = table.getData(i,"settingFile");
185 return;
186 }
187 }
188 msgOut(MSG_CRITICAL_ERROR, "Scenario not found!");
189
190
191}
192
193void
195
196 LLData table = getTable("settings");
197 int nheaders = table.nheaders();
198 for (int i=0; i< table.nrecords();i++){
199 BasicData SETT;
200 SETT.name = table.getData(i,"name");
201 string type = table.getData(i,"type");
202 SETT.type = getType(type);
203 string region_s= table.getData(i,"region");
204 SETT.regId = region_s==""?WORLD:s2i(table.getData(i,"region"));
205 SETT.comment = table.getData(i,"comment");
206 vector <string> values;
207 for (int z=0;z<nheaders-4;z++){ // don't consider name, type, comment and region headers
208 string toSearch = "value_"+i2s(z);
209 string value = table.getData(i,toSearch);
210 if (value != ""){
211 values.push_back(value);
212 }
213 }
214 SETT.values = values;
215 programSettingsVector.push_back(SETT);
216 }
217
218 msgOut(MSG_INFO,"### USING SCENARIO: "+MTHREAD->getScenarioName()+" ###");
219
220 setOutputDirectory(getStringSetting("outputDirname").c_str());
221}
222
223void
225
226 if(scenario.settingTable=="" && scenario.settingFile=="") {return;}
228 msgOut(MSG_CRITICAL_ERROR,"Scenario-specific settings has been indicated to be loaded from BOTH from the spreadsheet and a file. Choose one of them.");
229 }
230 LLData table(MTHREAD,"settings");
231 if(scenario.settingTable!=""){
232 table = getTable(scenario.settingTable, MSG_CRITICAL_ERROR); //this scenario could not have an associated setting sheet
233 } else {
234 table = getTableFromFile("settings",scenario.settingFile);
235 }
236
237
238
239 int nheaders = table.nheaders();
240 for(int i=0; i< table.nrecords(); i++){
241 string name = table.getData(i,"name");
242 string stype = table.getData(i,"type");
243 int type = getType(stype);
244 string region_s= table.getData(i,"region");
245 int regId = region_s==""?WORLD:s2i(table.getData(i,"region"));
246 string comment = table.getData(i,"comment");
247 vector <string> values;
248 for (int z=0;z<nheaders-4;z++){ // don't consider name, type and comment headers
249 string toSearch = "value_"+i2s(z);
250 string value = table.getData(i,toSearch);
251 if (value != ""){
252 values.push_back(value);
253 }
254 }
255 bool found = false;
256 for(uint i=0;i<programSettingsVector.size();i++){
257 if(programSettingsVector[i].name == name && programSettingsVector[i].regId == regId){
258 programSettingsVector[i].values = values;
259 programSettingsVector[i].type = type;
260 programSettingsVector[i].comment = comment;
261 found = true;
262 break;
263 }
264 }
265 if(!found){
266 BasicData SETT;
267 SETT.name = name;
268 SETT.type = type;
269 SETT.regId = regId;
270 SETT.comment = comment;
271 SETT.values = values;
272 programSettingsVector.push_back(SETT);
273 }
274
275 }
276
277 setOutputDirectory(getStringSetting("outputDirname").c_str());
278}
279
280void
281ModelData::addSetting(string name_h, vector <string> values_h, int type_h, string comment_h){
282
283 for (uint i=0;i<programSettingsVector.size();i++){
284 if (programSettingsVector.at(i).name == name_h){
285 msgOut(MSG_ERROR, "I already have setting "+name_h+".. Nothing is added..");
286 return;
287 }
288 }
289 BasicData SETT;
290 SETT.name = name_h;
291 SETT.values = values_h;
292 SETT.type= type_h;
293 SETT.comment = comment_h;
294 programSettingsVector.push_back(SETT);
295}
296
297void
298ModelData::addSetting(string name_h, string value_h, int type_h, string comment_h){
299 vector <string> values;
300 values.push_back(value_h);
301 addSetting(name_h, values, type_h, comment_h);
302}
303
304void
306 cached_initialYear = getIntSetting("initialYear");
308 priProducts = getStringVectorSetting("priProducts");
309 secProducts = getStringVectorSetting("secProducts");
311 allProducts.insert( allProducts.end(), secProducts.begin(), secProducts.end() );
312}
313
314// ###############################################################################
315
316void
318 // first create regions and assign basic data...
319 LLData table = getTable("regions");
320 for (int i=0; i< table.nrecords();i++){
321 ModelRegion REGION(MTHREAD,
322 s2i(table.getData(i,"regId")),
323 table.getData(i,"regSName"),
324 table.getData(i,"regLName"),
325 s2i(table.getData(i,"regLevel")),
326 s2i(table.getData(i,"parRegId")),
327 s2b(table.getData(i,"isResidual")));
328 regionsVector.push_back(REGION);
329 }
330 // Now let's assign the parent/children pointers..
331 for (int i=0; i< regionsVector.size();i++){
332 // let's assign the parent:
333 regionsVector[i].setParent(this->getRegion(regionsVector[i].getParRegId()));
334 // let's assign the children:
335 vector<ModelRegion*> kids;
336 for (int y=0; y< regionsVector.size();y++){
337 if(regionsVector[y].getParRegId() == regionsVector[i].getRegId() ){
338 kids.push_back(&regionsVector[y]);
339 }
340 }
341 regionsVector[i].setChildren(kids);
342 }
343}
344
347 for (int i=0; i< regionsVector.size();i++){
348 if(regionsVector[i].getRegId()==regId_h){
349 return &regionsVector[i];
350 }
351 }
352 msgOut(MSG_CRITICAL_ERROR, "Region id "+i2s(regId_h)+" not found, check your input data. Aborting simulation.");
353}
354
355bool
356ModelData::regionExist (const int & regId_h) const {
357 for (int i=0; i< regionsVector.size();i++){
358 if(regionsVector[i].getRegId()==regId_h){
359 return true;
360 }
361 }
362 return false;
363}
364
365vector <int>
366ModelData::getRegionIds(int level_h, bool excludeResidual){
367 vector <int> toReturn;
368 for(uint i=0;i<regionsVector.size();i++){
369 if(regionsVector[i].getRegLevel()==level_h){
370 if( (!excludeResidual) || (!regionsVector[i].getIsResidual())){
371 toReturn.push_back(regionsVector[i].getRegId());
372 }
373 }
374 }
375 return toReturn;
376}
377
378vector <ModelRegion*>
379ModelData::getAllRegions(bool excludeResidual){
380 vector <ModelRegion*> toReturn;
381 for(uint i=0;i<regionsVector.size();i++){
382 if( (!excludeResidual) || (!regionsVector[i].getIsResidual())){
383 toReturn.push_back(&regionsVector[i]);
384 }
385 }
386 return toReturn;
387}
388
389vector < vector <int> >
390ModelData::getRegionIds( bool excludeResidual){
391 vector < vector <int> > toReturn;
392 vector <int> l1regIds = MTHREAD->MD->getRegionIds(1, excludeResidual);
393 for(uint i=0;i<l1regIds.size();i++){
394 vector<int> l2ChildrenIds;
395 ModelRegion* l1Region = MTHREAD->MD->getRegion(l1regIds[i]);
396 vector<ModelRegion*> l2Childrens = l1Region->getChildren(excludeResidual);
397 for(uint j=0;j<l2Childrens.size();j++){
398 l2ChildrenIds.push_back(l2Childrens[j]->getRegId());
399 }
400 if(l2ChildrenIds.size()){
401 toReturn.push_back(l2ChildrenIds);
402 }
403 }
404 return toReturn;
405}
406
407string
408ModelData::regId2RegSName (const int & regId_h) const {
409 ModelRegion* reg = MTHREAD->MD->getRegion(regId_h);
410 return reg->getRegSName();
411}
412
413int
414ModelData::regSName2RegId (const string & regSName_h) const{
415 ModelRegion* reg;
416 for(uint i=0; i<3; i++){
417 vector <int> regIds = MTHREAD->MD->getRegionIds(i, false);
418 for(uint j=0;j<regIds.size();j++){
419 reg = MTHREAD->MD->getRegion(regIds[j]);
420 if(reg->getRegSName()==regSName_h) {return regIds[j];}
421 }
422 }
423 msgOut(MSG_CRITICAL_ERROR,"Regional short name not found.");
424}
425
426
427
428
429vector <string>
431 vector <string> toReturn;
432 for(uint i=0;i<forTypes.size();i++){
433 if(forTypes[i].memType!=1 || all) {
434 toReturn.push_back(forTypes[i].forTypeId);
435 }
436 }
437 return toReturn;
438}
439
440const bool
441ModelData::assessProdPossibility(const string &prod_h, const string &forType_h, const string &dClass_h){
442 bool ok=false;
443 for(uint i=0;i<forToProdVector.size();i++){
444 if( forToProdVector[i].product == prod_h
445 && forToProdVector[i].forType == forType_h
446 && forToProdVector[i].dClass == dClass_h
447 ){
448 return true;
449 }
450 }
451 return false;
452}
453
454
455const int
457 int maxMaxYears = 0;
458 for(uint i=0;i<forToProdVector.size();i++){
459 if(forToProdVector[i].maxYears > maxMaxYears){
460 maxMaxYears = forToProdVector[i].maxYears;
461 }
462 }
463 return maxMaxYears;
464}
465
466
467const int
468ModelData::getMaxYearUsableDeathTimber(const string &prod_h, const string &forType_h, const string &dClass_h){
469 for(uint i=0;i<forToProdVector.size();i++){
470 if( forToProdVector[i].product == prod_h
471 && forToProdVector[i].forType == forType_h
472 && forToProdVector[i].dClass == dClass_h
473 ){
474 return forToProdVector[i].maxYears;
475 }
476 }
477 msgOut(MSG_CRITICAL_ERROR,"In getMaxYearUsableDeathTimber() I has been asked of a combination that I don't know how to handle.");
478}
479
480void
482 msgOut(MSG_DEBUG,"Loading forest sector data..");
483 LLData table = getTable("forData");
484 int nheaders = table.nheaders();
485 for (int i=0; i< table.nrecords();i++){
486 vector <double> values;
487 for (int z=0;z<nheaders-4;z++){ // don't consider parName, region, forType and diamClass headers
488 string toSearch = "value_"+i2s(z);
489 string value = table.getData(i,toSearch);
490 if (value != ""){
491 values.push_back(s2d(value));
492 }
493 }
494 string keys = makeKeyForData(table.getData(i,"parName"), table.getData(i,"region"),table.getData(i,"forType"),table.getData(i,"freeDim"));
495 forDataMap.insert(std::pair<string, vector<double> >(keys, values));
496 }
497}
498
499void
501
502 if(scenario.forDataTable==""){return;}
504
505 int nheaders = table.nheaders();
506 for(int i=0; i< table.nrecords(); i++){
507 bool found = false;
508 string key = makeKeyForData(table.getData(i,"parName"),table.getData(i,"region"),table.getData(i,"forType"),table.getData(i,"freeDim"));
509 vector <double> values;
510 for (int z=0;z<nheaders-4;z++){ // don't consider parName, region, forType and diamClass headers
511 string toSearch = "value_"+i2s(z);
512 string value = table.getData(i,toSearch);
513 if (value != ""){
514 values.push_back(s2d(value));
515 }
516 }
517 map <string, vector < double > >::iterator p;
518 p=forDataMap.find(key);
519 if(p != forDataMap.end()) {
520 // updating an existing record
521 p->second = values;
522 }
523 else {
524 // new one, adding it
525 forDataMap.insert(std::pair<string, vector<double> >(key, values));
526 }
527 }
528}
529
530void
532
533 msgOut(MSG_DEBUG,"Loading products data..");
534 LLData table = getTable("prodData");
535 int nheaders = table.nheaders();
536
537 for (int i=0; i< table.nrecords();i++){
538// prodData PDATA;
539// PDATA.parName = table.getData(i,"parName");
540// PDATA.region = s2i(table.getData(i,"region"));
541// PDATA.prod = table.getData(i,"prod");
542// PDATA.freeDim = table.getData(i,"freeDim");
543 vector <double> values;
544 for (int z=0;z<nheaders-4;z++){ // don't consider parName, region, prod and freeDim headers
545 string toSearch = "value_"+i2s(z);
546 string value = table.getData(i,toSearch);
547 if (value != ""){
548 values.push_back(s2d(value));
549 }
550 }
551// PDATA.values = values;
552// prodDataVector.push_back(PDATA);
553 string keys = makeKeyProdData(table.getData(i,"parName"), table.getData(i,"region"),table.getData(i,"prod"),table.getData(i,"freeDim"));
554 prodDataMap.insert(std::pair<string, vector<double> >(keys, values));
555 //giving a link to it to its own region:
556// getRegion(PDATA.region)->addProdData(&PDATA);
557 }
558}
559
560void
562
563 if(scenario.prodDataTable==""){return;}
564 LLData table = getTable(scenario.prodDataTable, MSG_CRITICAL_ERROR); //this scenario could not have an associated setting sheet
565
566 int nheaders = table.nheaders();
567 int debug = table.nrecords();
568 for(int i=0; i< table.nrecords(); i++){
569 //prodData PDATA;
570 bool found = false;
571 string key = makeKeyProdData(table.getData(i,"parName"),table.getData(i,"region"),table.getData(i,"prod"),table.getData(i,"freeDim"));
572
573 //PDATA.parName = table.getData(i,"parName");
574 //PDATA.region = s2i(table.getData(i,"region"));
575 //PDATA.prod = table.getData(i,"prod");
576 //PDATA.freeDim = table.getData(i,"freeDim");
577 vector <double> values;
578 for (int z=0;z<nheaders-4;z++){// don't consider parName, region, prod and freeDim headers
579 string toSearch = "value_"+i2s(z);
580 string value = table.getData(i,toSearch);
581 if (value != ""){
582 values.push_back(s2d(value));
583 }
584 }
585 //PDATA.values = values;
586 //for(uint i=0;i<prodDataVector.size();i++){
587 // if(prodDataVector[i].parName == PDATA.parName
588 // && prodDataVector[i].region == PDATA.region
589 // && prodDataVector[i].prod == PDATA.prod
590 // && prodDataVector[i].freeDim == PDATA.freeDim){
591 // // existing prodData..
592 // prodDataVector[i].values = PDATA.values;
593 // found = true;
594 // break;
595 // }
596 //}
597 //if(!found){
598 // // new one, adding it
599 // prodDataVector.push_back(PDATA);
600 // //giving a link to it to its own region:
601 // getRegion(PDATA.region)->addProdData(&PDATA);
602 //}
603
604 map <string, vector < double > >::iterator p;
605 p=prodDataMap.find(key);
606 if(p != prodDataMap.end()) {
607 // updating an existing record
608 p->second = values;
609 }
610 else {
611 // new one, adding it
612 prodDataMap.insert(std::pair<string, vector<double> >(key, values));
613 }
614 }
615}
616
617void
619 msgOut(MSG_DEBUG,"Loading forest resource to primary products io matrix..");
620 LLData table = getTable("forToProd");
621 for (int i=0; i< table.nrecords();i++){
622 forToProd F2PDATA;
623 F2PDATA.product = table.getData(i,"product");
624 F2PDATA.forType = table.getData(i,"forType");
625 F2PDATA.dClass = table.getData(i,"dClass");
626 F2PDATA.maxYears = s2i(table.getData(i,"maxYears"));
627 forToProdVector.push_back(F2PDATA);
628 }
629}
630
631void
633 if(scenario.forToProdTable==""){return;}
634 LLData table = getTable(scenario.forToProdTable, MSG_CRITICAL_ERROR); //this scenario could not have an associated setting sheet
635
636 int nheaders = table.nheaders();
637 forToProdVector.clear();
638 for (int i=0; i< table.nrecords();i++){
639 forToProd F2PDATA;
640 F2PDATA.product = table.getData(i,"product");
641 F2PDATA.forType = table.getData(i,"forType");
642 F2PDATA.dClass = table.getData(i,"dClass");
643 forToProdVector.push_back(F2PDATA);
644 }
645}
646
647void
649 LLData table = getTable("forTypes");
650 for (int i=0; i< table.nrecords();i++){
651 forType FTYPE;
652 FTYPE.forTypeId = table.getData(i,"forTypeId");
653 FTYPE.forLabel = table.getData(i,"forLabel");
654 FTYPE.memType = s2i(table.getData(i,"memType"));
655 FTYPE.forLayer = table.getData(i,"forLayer");
656 FTYPE.ereditatedFrom = table.getData(i,"ereditatedFrom");
657 if(FTYPE.memType == 3 && !getBoolSetting("useSpExplicitForestTypes")) continue;
658 forTypes.push_back(FTYPE);
659 }
660}
661
662void
664
665 msgOut(MSG_DEBUG,"Loading (but not yet applying) reclassification rules..");
666 LLData table = getTable("reclRules");
667 for (int i=0; i< table.nrecords();i++){
668 reclRule RL;
669 RL.regId = s2i(table.getData(i,"regID"));
670 RL.forTypeIn = table.getData(i,"forTypeIn");
671 RL.forTypeOut = table.getData(i,"forTypeOut");
672 RL.coeff = s2d(table.getData(i,"coeff"));
673 reclRules.push_back(RL);
674 }
675}
676
677void
679
680 if(!getBoolSetting("usePathogenModule")) return;
681 msgOut(MSG_DEBUG,"Loading pathogen rules..");
682 LLData table = getTable("pathRules");
683 int nheaders = table.nheaders();
684 for (int i=0; i< table.nrecords();i++){
685 pathRule PR;
686 PR.forType = table.getData(i,"forType");
687 PR.dClass = table.getData(i,"dClass");
688 PR.pathId = table.getData(i,"path_name");
689 PR.pres_min = s2d(table.getData(i,"pres_min"));
690
691 vector <double> values;
692 for (int z=0;z<nheaders-4;z++){ // don't consider forType, dClass, path_name and pres_min headers
693 string toSearch = "year_"+i2s(z);
694 string value = table.getData(i,toSearch);
695 if (value != ""){
696 values.push_back(s2d(value));
697 }
698 }
699 PR.mortCoefficents = values;
700
701 pathRules.push_back(PR);
702 }
703}
704
705void
707
708 if(scenario.pathTable==""){return;}
709 LLData table = getTable(scenario.pathTable, MSG_CRITICAL_ERROR); //this scenario could not have an associated setting sheet
710
711 int nheaders = table.nheaders();
712 for (int i=0; i< table.nrecords();i++){
713 pathRule PR;
714 PR.forType = table.getData(i,"forType");
715 PR.dClass = table.getData(i,"dClass");
716 PR.pathId = table.getData(i,"path_name");
717 PR.pres_min = s2d(table.getData(i,"pres_min"));
718
719 vector <double> values;
720 for (int z=0;z<nheaders-4;z++){ // don't consider forType, dClass, path_name and pres_min headers
721 string toSearch = "year_"+i2s(z);
722 string value = table.getData(i,toSearch);
723 if (value != ""){
724 values.push_back(s2d(value));
725 }
726 }
727 PR.mortCoefficents = values;
728
729 bool found = false;
730 for(uint i=0;i<pathRules.size();i++){
731 if( pathRules[i].forType == PR.forType
732 && pathRules[i].dClass == PR.dClass
733 && pathRules[i].pathId == PR.pathId
734 ){
735 pathRules[i].pres_min = PR.pres_min;
736 pathRules[i].mortCoefficents = PR.mortCoefficents;
737 found = true;
738 break;
739 }
740 }
741 if(!found){
742 pathRules.push_back(PR);
743 }
744 } // end for each table record
745}
746
747/// Cancel all reg1 level data and trasform them in reg2 level if not already existing
748void
750
751 if(!getBoolSetting("applyOverriding")) return;
752 msgOut(MSG_INFO, "Starting regional overriding analysis..");
753
754 DataMap::iterator p;
755 string parName,prod,freeDim,forType,diamClass, key;
756 int regId;
757 DataMap toBeAdded;
758 vector <string> keysToRemove;
759
760
761 //apply override from level 0 to level 1 for forestry data
762 toBeAdded.clear();
763 keysToRemove.clear();
764 for(p=forDataMap.begin();p!=forDataMap.end();p++){
765 unpackKeyForData(p->first,parName,regId,forType,diamClass);
766 if(!regionExist(regId)){
767 msgOut(MSG_CRITICAL_ERROR,"Forest variable has a unknown region code If you want not to model a region, set residual=true.: "+parName+"\t"+i2s(regId));
768 continue;
769 }
770 if(getRegion(regId)->getRegLevel() == 0){
771 vector<ModelRegion*> childs = getRegion(regId)->getChildren(false);
772 for(uint j=0;j<childs.size();j++){
773 bool found = false;
774 key = makeKeyForData(parName,i2s(childs[j]->getRegId()),forType,diamClass);
775 if (!dataMapCheckExist(forDataMap,key,true)){
776 toBeAdded.insert(DataPair(key,p->second));
777 }
778 }
779 keysToRemove.push_back(p->first);
780 }
781 }
782 forDataMap.insert(toBeAdded.begin(),toBeAdded.end());
783 for(uint i=0;i<keysToRemove.size();i++){
784 DataMap::iterator rem = forDataMap.find(keysToRemove[i]);
785 if(rem != forDataMap.end()){
786 forDataMap.erase(rem);
787 }
788 }
789
790
791
792
793 //apply override from level 1 to level 2 for forestry data
794 toBeAdded.clear();
795 keysToRemove.clear();
796 for(p=forDataMap.begin();p!=forDataMap.end();p++){
797 unpackKeyForData(p->first,parName,regId,forType,diamClass);
798 if(!regionExist(regId)){
799 msgOut(MSG_CRITICAL_ERROR,"Forest variable has a unknown region code If you want not to model a region, set residual=true.: "+parName+"\t"+i2s(regId));
800 continue;
801 }
802 if(getRegion(regId)->getRegLevel() == 1){
803 vector<ModelRegion*> childs = getRegion(regId)->getChildren(false);
804 for(uint j=0;j<childs.size();j++){
805 bool found = false;
806 key = makeKeyForData(parName,i2s(childs[j]->getRegId()),forType,diamClass);
807 if (!dataMapCheckExist(forDataMap,key,true)){
808 toBeAdded.insert(DataPair(key,p->second));
809 }
810 }
811 keysToRemove.push_back(p->first);
812 }
813 }
814 forDataMap.insert(toBeAdded.begin(),toBeAdded.end());
815 for(uint i=0;i<keysToRemove.size();i++){
816 DataMap::iterator rem = forDataMap.find(keysToRemove[i]);
817 if(rem != forDataMap.end()){
818 forDataMap.erase(rem);
819 }
820 }
821
822 //apply override from level 0 to level 1 for production data
823 toBeAdded.clear();
824 keysToRemove.clear();
825 for(p=prodDataMap.begin();p!=prodDataMap.end();p++){
826 unpackKeyProdData(p->first,parName,regId,prod,freeDim);
827 if(!regionExist(regId)){
828 msgOut(MSG_CRITICAL_ERROR,"Product variable has a unknown region code If you want not to model a region, set residual=true.: "+parName+"\t"+i2s(regId));
829 continue;
830 }
831 if(getRegion(regId)->getRegLevel() == 0){
832 vector<ModelRegion*> childs = getRegion(regId)->getChildren(false);
833 for(uint j=0;j<childs.size();j++){
834 bool found = false;
835 key = makeKeyProdData(parName,i2s(childs[j]->getRegId()),prod,freeDim);
836 if (!dataMapCheckExist(prodDataMap,key,true)){
837 toBeAdded.insert(DataPair(key,p->second));
838 }
839 }
840 //prodDataMap.erase(p);
841 //p--;
842 keysToRemove.push_back(p->first);
843 }
844 }
845 prodDataMap.insert(toBeAdded.begin(),toBeAdded.end());
846 for(uint i=0;i<keysToRemove.size();i++){
847 DataMap::iterator rem = prodDataMap.find(keysToRemove[i]);
848 if(rem != prodDataMap.end()){
849 prodDataMap.erase(rem);
850 }
851 }
852
853
854 //apply override from level 1 to level 2 for production data
855 toBeAdded.clear();
856 keysToRemove.clear();
857 for(p=prodDataMap.begin();p!=prodDataMap.end();p++){
858 string debug = p->first;
859 unpackKeyProdData(p->first,parName,regId,prod,freeDim);
860 if(!regionExist(regId)){
861 msgOut(MSG_CRITICAL_ERROR,"Product variable has a unknown region code If you want not to model a region, set residual=true.: "+parName+"\t"+i2s(regId));
862 continue;
863 }
864 if(getRegion(regId)->getRegLevel() == 1){
865 vector<ModelRegion*> childs = getRegion(regId)->getChildren(false);
866 for(uint j=0;j<childs.size();j++){
867 bool found = false;
868 key = makeKeyProdData(parName,i2s(childs[j]->getRegId()),prod,freeDim);
869 if (!dataMapCheckExist(prodDataMap,key,true)){
870 toBeAdded.insert(DataPair(key,p->second));
871 }
872 }
873 //prodDataMap.erase(p);
874 //p--;
875 keysToRemove.push_back(p->first);
876 }
877 }
878 prodDataMap.insert(toBeAdded.begin(),toBeAdded.end());
879 for(uint i=0;i<keysToRemove.size();i++){
880 DataMap::iterator rem = prodDataMap.find(keysToRemove[i]);
881 if(rem != prodDataMap.end()){
882 prodDataMap.erase(rem);
883 }
884 }
885
886 //apply override from level 0 to level 1 for reclassification rules
887 for(uint i=0;i<reclRules.size();i++){
888 if(reclRules[i].regId == 0){
889 if(!regionExist(reclRules[i].regId)){
890 msgOut(MSG_CRITICAL_ERROR,"Reclassification rule has a unknown region code If you want not to model a region, set residual=true.: "+i2s(reclRules[i].regId));
891 continue;
892 }
893 for(uint j=0;j<getRegion(reclRules[i].regId)->getNChildren(false);j++){
894 vector<ModelRegion*> childs = getRegion(reclRules[i].regId)->getChildren(false);
895 bool found = 0;
896 for(uint z=0;z<reclRules.size();z++){
897 if( reclRules[z].regId == childs[j]->getRegId()
898 && reclRules[z].forTypeIn == reclRules[i].forTypeIn
899 && reclRules[z].forTypeOut == reclRules[i].forTypeOut
900 ){
901 found = true; // do nothing, this child has been already manually overritten
902 break;
903 }
904 }
905 if(!found){
906 reclRule RR;
907 RR.regId = childs[j]->getRegId();
908 RR.forTypeIn = reclRules[i].forTypeIn;
909 RR.forTypeOut = reclRules[i].forTypeOut;
910 RR.coeff = reclRules[i].coeff;
911 reclRules.push_back(RR);
912 }
913 }
914 reclRules.erase(reclRules.begin()+i);
915 i--;
916 }
917 }
918
919 //apply override from level 1 to level 2 for reclassification rules
920 for(uint i=0;i<reclRules.size();i++){
921 if(!regionExist(reclRules[i].regId)){
922 msgOut(MSG_CRITICAL_ERROR,"Reclassification rule has a unknown region code. If you want not to model a region, set residual=true.: "+i2s(reclRules[i].regId));
923 continue;
924 }
925 if(getRegion(reclRules[i].regId)->getRegLevel() == 1){
926 for(uint j=0;j<getRegion(reclRules[i].regId)->getNChildren(false);j++){
927 vector<ModelRegion*> childs = getRegion(reclRules[i].regId)->getChildren(false);
928 bool found = 0;
929 for(uint z=0;z<reclRules.size();z++){
930 if( reclRules[z].regId == childs[j]->getRegId()
931 && reclRules[z].forTypeIn == reclRules[i].forTypeIn
932 && reclRules[z].forTypeOut == reclRules[i].forTypeOut
933 ){
934 found = true; // do nothing, this child has been already manually overritten
935 break;
936 }
937 }
938 if(!found){
939 reclRule RR;
940 RR.regId = childs[j]->getRegId();
941 RR.forTypeIn = reclRules[i].forTypeIn;
942 RR.forTypeOut = reclRules[i].forTypeOut;
943 RR.coeff = reclRules[i].coeff;
944 reclRules.push_back(RR);
945 }
946 }
947 reclRules.erase(reclRules.begin()+i);
948 i--;
949 }
950 }
951}
952
953/**
954The applyDebugMode flag all level2 regions not in the "debugRegions" option as "residual" (so they are in the map but not in the model code) and remove the primary and secondary products that are not included in the debugPriProducts and debugSecProducts options.
955*/
956void
958 if(! getBoolSetting("debugFlag")) return;
959
960 vector <int> debugRegions = getIntVectorSetting("debugRegions");
961 vector <string> debugPriProducts = getStringVectorSetting("debugPriProducts");
962 vector <string> debugSecProducts = getStringVectorSetting("debugSecProducts");
963
964 for(uint i=0;i< regionsVector.size();i++){
965 if (regionsVector[i].getRegLevel()==2){
966 bool found= false;
967 for(uint j=0;j<debugRegions.size();j++){
968 if (debugRegions[j] == regionsVector[i].getRegId()){
969 found = true;
970 break;
971 }
972 }
973 if(!found){ // not in the list to keep
974 regionsVector[i].setIsResidual(true);
975 }
976 }
977 }
978
979 for (uint i=0; i<programSettingsVector.size();i++){
980 if (programSettingsVector.at(i).name == "priProducts"){
981 programSettingsVector.at(i).values = debugPriProducts;
982 } else if (programSettingsVector.at(i).name == "secProducts"){
983 programSettingsVector.at(i).values = debugSecProducts;
984 }
985 }
986
987}
988
989void
990ModelData::setOutputDirectory(const char* output_dirname_h){
991
992 if (strlen(output_dirname_h)==0){
994 }
995 else {
996 outputDirname=output_dirname_h;
997 }
998 MTHREAD->setOutputDirName(outputDirname); //for the GUI
999}
1000
1001/**
1002Returns the value stored in the settings database.
1003
1004
1005Regional overriding.
1006
1007Concerning the param regId_h:
1008it expect either world (default), a L2 or L1 region.
1009Settings in the memory are stored also with data in one or more of these levels (e.g. we may have a general WORLD value and then a more specific L2 value.
1010The function is done such that if WORLD is used to query it, it returns only a world value, if L1 is used instead, it looks for this L1 value and then eventually
1011(if nothing is found) for WORLD. Finally, if L2 is used, it query, in the order, for L2, L1 or world levels.
1012
1013*/
1014string
1015ModelData::getBaseData (const string &name_h, int type_h, int position, int regId_h){
1016 // If the data is called with DATA_NOW we interpret the array of values as a temporal array and we return the value at the current time.
1017 if(position == DATA_NOW) {
1018 position = MTHREAD->SCD->getIteration();
1019 }
1020
1021 vector <int> regIds;
1022
1023 if(regId_h == WORLD){
1024 regIds.push_back(WORLD);
1025 } else if (getRegion(regId_h)->getRegLevel()==1){
1026 regIds.push_back(regId_h);
1027 regIds.push_back(WORLD);
1028 } else if (getRegion(regId_h)->getRegLevel()==2) {
1029 regIds.push_back(regId_h);
1030 regIds.push_back(getRegion(regId_h)->getParRegId());
1031 regIds.push_back(WORLD);
1032 } else {
1033 msgOut(MSG_CRITICAL_ERROR, "Error in getBaseData(). Data requested for a unknown region level.");
1034 }
1035
1036
1037 for (uint j=0; j<regIds.size();j++){
1038 int regId = regIds[j];
1039 for (uint i=0; i<programSettingsVector.size();i++){
1040 if (programSettingsVector.at(i).name == name_h & programSettingsVector.at(i).regId == regId){
1041 int type = programSettingsVector.at(i).type;
1042 if(type != type_h){msgOut(MSG_CRITICAL_ERROR, "mismatching type in calling getBaseData() for "+name_h);}
1043 if(programSettingsVector.at(i).values.size() > ((uint)position)) {
1044 return programSettingsVector.at(i).values.at(position);
1045 } else if (programSettingsVector.at(i).values.size() > 0 ){
1046 // returning the last available value...
1047 return programSettingsVector.at(i).values.at( programSettingsVector.at(i).values.size()-1 );
1048 }
1049 else {msgOut(MSG_CRITICAL_ERROR, "Error: "+name_h+" doesn't have any value, even on the first position(year)!"); }
1050 }
1051 }
1052 }
1053
1054 msgOut(MSG_CRITICAL_ERROR, "Error calling getBaseData() for "+ name_h +". No setting option or macro data found with this name.");
1055
1056// switch(type_h){
1057// case TYPE_BOOL:
1058// return "0";
1059// case TYPE_INT:
1060// return "0";
1061// case TYPE_DOUBLE:
1062// return "0.0";
1063// case TYPE_STRING:
1064// return "";
1065// default:
1066// msgOut(MSG_CRITICAL_ERROR, "Error calling getBaseData() for "+ i2s(type_h) +". I don't know this type.");
1067// }
1068 return "";
1069}
1070
1071
1072vector <string>
1073ModelData::getVectorBaseData (const string &name_h, int type_h, int regId_h){
1074 vector <int> regIds;
1075 if(regId_h == WORLD){
1076 regIds.push_back(WORLD);
1077 } else if(getRegion(regId_h)->getRegLevel()==1){
1078 regIds.push_back(regId_h);
1079 regIds.push_back(WORLD);
1080 } else if (getRegion(regId_h)->getRegLevel()==2) {
1081 regIds.push_back(regId_h);
1082 regIds.push_back(getRegion(regId_h)->getParRegId());
1083 regIds.push_back(WORLD);
1084 } else {
1085 msgOut(MSG_CRITICAL_ERROR, "Error in getBaseData(). Data requested for a unknown region level.");
1086 }
1087
1088 for (uint j=0; j<regIds.size();j++){
1089 int regId = regIds[j];
1090 for (uint i=0; i<programSettingsVector.size();i++){
1091 if (programSettingsVector.at(i).name == name_h & programSettingsVector.at(i).regId == regId){
1092 int type = programSettingsVector.at(i).type;
1093 if(type != type_h){msgOut(MSG_CRITICAL_ERROR, "mismatching type in calling getVectorBaseData() for "+name_h);}
1094 return programSettingsVector.at(i).values;
1095 }
1096 }
1097 }
1098 msgOut(MSG_CRITICAL_ERROR, "Error calling getVectorBaseData() for "+ name_h +". No setting option or macro data found with this name.");
1099 vector <string> toReturn;
1100 return toReturn;
1101}
1102
1103// ------------- start getSetting() amd getMacro() functions ....... -----------------
1104int
1105ModelData::getIntSetting(const string &name_h, int position, int reg) const{
1106 return s2i( MTHREAD->MD->getBaseData(name_h,TYPE_INT,position, reg) );
1107}
1108double
1109ModelData::getDoubleSetting(const string &name_h, int position, int reg) const{
1110 return s2d( MTHREAD->MD->getBaseData(name_h,TYPE_DOUBLE,position,reg) );
1111}
1112string
1113ModelData::getStringSetting(const string &name_h, int position, int reg) const{
1114 return MTHREAD->MD->getBaseData(name_h,TYPE_STRING,position,reg);
1115}
1116bool
1117ModelData::getBoolSetting(const string &name_h, int position, int reg) const{
1118 return s2b( MTHREAD->MD->getBaseData(name_h,TYPE_BOOL,position,reg) );
1119}
1120vector<int>
1121ModelData::getIntVectorSetting(const string &name_h, int reg) const{
1122 return s2i(MTHREAD->MD->getVectorBaseData(name_h,TYPE_INT,reg));
1123}
1124vector<double>
1125ModelData::getDoubleVectorSetting(const string &name_h, int reg) const{
1126 return s2d(MTHREAD->MD->getVectorBaseData(name_h,TYPE_DOUBLE,reg));
1127}
1128vector<string>
1129ModelData::getStringVectorSetting(const string &name_h, int reg) const{
1130 return MTHREAD->MD->getVectorBaseData(name_h,TYPE_STRING,reg);
1131}
1132vector<bool>
1133ModelData::getBoolVectorSetting(const string &name_h, int reg) const{
1134 return s2b(MTHREAD->MD->getVectorBaseData(name_h,TYPE_BOOL,reg));
1135}
1136
1137// ------ END of getSetting() functions ---------------------
1138
1139//// Never used
1140//void
1141//ModelData::setBasicData(const string &name_h, int value, int position){
1142// setBasicData(name_h, i2s(value), TYPE_INT, position);
1143//}
1144//void
1145//ModelData::setBasicData(const string &name_h, double value, int position){
1146// setBasicData(name_h, d2s(value), TYPE_DOUBLE, position);
1147//}
1148//void
1149//ModelData::setBasicData(const string &name_h, string value, int position){
1150// setBasicData(name_h, value, TYPE_STRING, position);
1151//}
1152//void
1153//ModelData::setBasicData(const string &name_h, bool value, int position){
1154// setBasicData(name_h, b2s(value), TYPE_BOOL, position);
1155//}
1156
1157//void
1158//ModelData::setBasicData(const string &name_h, string value, int type_h, int position){
1159// for (uint i=0; i<programSettingsVector.size();i++){
1160// if (programSettingsVector.at(i).name == name_h){
1161// int type = programSettingsVector.at(i).type;
1162// if(type != type_h){msgOut(MSG_CRITICAL_ERROR, "mismatching type in calling setBasicData() for "+name_h);}
1163// if(programSettingsVector.at(i).values.size() > ((uint)position)) {
1164// programSettingsVector.at(i).values.at(position)=value;
1165// return;
1166// }
1167// else {msgOut(MSG_CRITICAL_ERROR, "out-of-bound error calling setBasicData() for "+name_h); }
1168// }
1169// }
1170// msgOut(MSG_CRITICAL_ERROR, "Error calling setBasicData() for "+ name_h +". No setting option or macro data found with this name.");
1171// return;
1172//}
1173
1174std::string
1176 std::string directory;
1177 std::string filename;
1178 std::string filename_complete;
1179 for (uint i=0; i<iFilesVector.size(); i++){
1180 if (iFilesVector.at(i).type == type_h){
1181 directory=iFilesVector.at(i).directory;
1182 filename=iFilesVector.at(i).name;
1183 break;
1184 }
1185 }
1186 filename_complete = baseDirectory+directory+filename;
1187 return filename_complete;
1188}
1189
1190vector <string>
1192 int i;
1193 if(productionOnly){
1194 i=1;
1195 } else {
1196 i=0;
1197 }
1198 vector <string> toReturn;
1199 for (i;i<diamClasses.size();i++){
1200 toReturn.push_back(diamClasses[i]);
1201 }
1202 return toReturn;
1203}
1204
1205/**
1206Basic function to retrieve products-related data.
1207It addmits the following "filters":
1208@type_h Name of the specific parameter requested
1209@regId_h Look for level1 or level 2 region.
1210@prodId_h Product. It accept three keywords, for summing up all products, primary products or secondary products, namelly PROD_ALL, PROD_PRI, PROD_SEC.
1211@year Unless specified, get the value of the current year. If array is smaller (e.g. because it is time-independent), get the last value.
1212@freeDim_h If specified, look exactly for it, otherwise simply doesn't filter for it.
1213
1214*/
1215const double
1216ModelData::getProdData(const string &type_h, const int& regId_h, const string &prodId_h, const int& year, const string &freeDim_h) {
1217
1218 double value=0;
1219 vector <int> regIds;
1220 string key;
1221 DataMap::const_iterator p;
1222
1223 bool found = false;
1224 vector <string> products;
1225 bool exactMatch=true;
1226
1227 if(prodId_h == PROD_PRI){
1228 products = priProducts;
1229 } else if (prodId_h == PROD_SEC){
1230 products = secProducts;
1231 } else if (prodId_h == PROD_ALL || prodId_h == ""){
1232 products = allProducts;
1233 products.push_back("");
1234 } else {
1235 products.push_back(prodId_h);
1236 }
1237 if(freeDim_h=="") exactMatch=false;
1238
1239 // Make sure to set the new value to all l2 regions if requested for a reg1 level
1240 if(getRegion(regId_h)->getRegLevel()==2){
1241 regIds.push_back(regId_h);
1242 } else if (getRegion(regId_h)->getRegLevel()==1) {
1243 for(uint i=0;i<getRegion(regId_h)->getNChildren();i++){
1244 regIds.push_back(getRegion(regId_h)->getChildren()[i]->getRegId());
1245 }
1246 } else {
1247 msgOut(MSG_CRITICAL_ERROR, "Error in setProdData(). Setting a value for the whole World is not supported.");
1248 }
1249 int regIdsS = regIds.size();
1250
1251
1252 for(uint r=0;r<regIdsS;r++){
1253 for(uint i=0;i<products.size();i++){
1254 key = makeKeyProdData(type_h,i2s(regIds[r]),products[i],freeDim_h);
1255 if (!exactMatch && key.size () > 0) key.resize (key.size () - 1); // bug 20140402, removing the last #
1256 value += dataMapGetValue(prodDataMap,key,year,exactMatch);
1257 if(tempBool) found = true;
1258 }
1259 }
1260
1261 if(!found){
1262 valueFoundBool = false;
1263 msgOut(errorLevel, "Error in getProdData: no combination found for "+type_h+", "+i2s(regId_h)+", "+prodId_h+", "+i2s(year)+", "+freeDim_h+". Returning 0, but double check that this is ok for your model.");
1264 }
1265 return value;
1266
1267
1268}
1269
1270/**
1271Basic function to retrieve forest-related data.
1272It addmits the following "filters":
1273@type_h Name of the specific parameter requested
1274@regId_h Look for a level1 or level2 region
1275@forType_h If specified, look exactly for the specified forest type, otherwise accept the keyword FT_ALL for summing all of them
1276@freeDim_h Normally used for diameter class, but occasionally used for other uses (changed 20140514). It accepts three keywords, for summing up all diameters, production-ready diameters or sub-production ones, namelly DIAM_ALL, DIAM_PROD, DIAM_FIRST.\\
1277If a diameter-independed variable is required, put it in the data with an empty diameter class and retrieve it here using DIAM_ALL.
1278@year Unless specified, get the value of the current year. If array is smaller (e.g. because it is time-independent), get the last value.
1279*/
1280const double
1281ModelData::getForData(const string &type_h, const int& regId_h, const string &forType_h, const string &freeDim_h, const int& year){
1282 vector<int> regIds;
1283 vector <string> dClasses;
1284 vector <string> fTypes;
1285 string key;
1286 DataMap::const_iterator p;
1287 bool found = false;
1288 double value = 0;
1289
1290 // creating the arrays to look up if keywords were specified..
1291 if (forType_h == FT_ALL){ // || forType_h == ""){
1292 fTypes = getForTypeIds();
1293 fTypes.push_back("");
1294 } else {
1295 fTypes.push_back(forType_h);
1296 }
1297 if(freeDim_h == DIAM_ALL){ // || freeDim_h == ""){
1298 dClasses = diamClasses;
1299 dClasses.push_back("");
1300 } else if (freeDim_h == DIAM_PROD){
1301 dClasses = getDiameterClasses(true);
1302 } else if (freeDim_h == DIAM_FIRST){
1303 dClasses.push_back(diamClasses.at(0));
1304 } else {
1305 dClasses.push_back(freeDim_h);
1306 }
1307 // Make sure to set the new value to all l2 regions if requested for a reg1 level
1308 if(getRegion(regId_h)->getRegLevel()==2){
1309 regIds.push_back(regId_h);
1310 } else if (getRegion(regId_h)->getRegLevel()==1) {
1311 for(uint i=0;i<getRegion(regId_h)->getNChildren();i++){
1312 regIds.push_back(getRegion(regId_h)->getChildren()[i]->getRegId());
1313 }
1314 } else {
1315 msgOut(MSG_CRITICAL_ERROR, "Error in getProdData(). Setting a value for the whole World is not supported.");
1316 }
1317 int regIdsS = regIds.size();
1318
1319 // getting the actual data...
1320 for(uint r=0;r< regIds.size();r++){
1321 for(uint i=0;i<dClasses.size();i++){
1322 for (uint y=0;y<fTypes.size();y++){
1323 key = makeKeyForData(type_h,i2s(regIds[r]),fTypes[y],dClasses[i]);
1324 value += dataMapGetValue(forDataMap,key,year,true);
1325 if(tempBool) found = true;
1326 }
1327 }
1328 }
1329
1330 if(!found){
1331 valueFoundBool = false;
1332 msgOut(errorLevel, "Error in getForData(): no combination found for "+type_h+", "+i2s(regId_h)+", "+forType_h+", "+i2s(year)+", "+freeDim_h+". Returning 0, but double check that this is ok for your model.");
1333 }
1334 return value;
1335}
1336
1337
1338/**
1339Basic function to set products-related data.
1340It can change an existing value or extend in time a serie, but it requires the keys (par. name/regId/prodId/freedim) to be already present in the data.
1341@value_h New value to change with/add
1342It addmits the following "filters":
1343@type_h Name of the specific parameter requested
1344@regId_h Set a specific level 2 region, or all its childred l2 region if a reg1 level is specified.
1345@prodId_h Product. It accept three keywords, for changing/inserting the new value to all products, primary products or secondary products, namelly PROD_ALL, PROD_PRI, PROD_SEC.
1346@year Unless specified, set the value of the current year. If array is smaller (e.g. because it is time-independent) fill all the values till the requested one.
1347@create If true, allow creation of new data if not found. Default false (rise an error)
1348@freeDim_h If specified, look exactly for it, otherwise simply doesn't filter for it.
1349
1350*/
1351void
1352ModelData::setProdData(const double& value_h, const string &type_h, const int& regId_h, const string &prodId_h, const int& year, const bool& allowCreate, const string &freeDim_h){
1353
1354 vector<int> regIds;
1355 string key;
1356 DataMap::const_iterator p;
1357 vector <string> products;
1358
1359 if(prodId_h == PROD_PRI){
1360 products = priProducts;
1361 } else if (prodId_h == PROD_SEC){
1362 products = secProducts;
1363 } else if (prodId_h == PROD_ALL){
1364 products = allProducts;
1365 } else {
1366 products.push_back(prodId_h);
1367 }
1368
1369 // Make sure to set the new value to all l2 regions if requested fora reg1 level
1370 if(getRegion(regId_h)->getRegLevel()==2){
1371 regIds.push_back(regId_h);
1372 } else if (getRegion(regId_h)->getRegLevel()==1) {
1373 for(uint i=0;i<getRegion(regId_h)->getNChildren();i++){
1374 regIds.push_back(getRegion(regId_h)->getChildren()[i]->getRegId());
1375 }
1376 } else {
1377 msgOut(MSG_CRITICAL_ERROR, "Error in setProdData(). Setting a value for the whole World is not supported.");
1378 }
1379
1380 bool found = false;
1381 bool tempFound = false;
1382
1383 for(uint r=0;r< regIds.size();r++){
1384 for(uint i=0;i<products.size();i++){
1385 key = makeKeyProdData(type_h,i2s(regIds[r]),products[i],freeDim_h);
1386 tempFound = dataMapSetValue(prodDataMap,key,value_h, year,true);
1387 if(tempFound) found = true;
1388 }
1389 }
1390
1391 if(!found){
1392 if(!allowCreate){
1393 msgOut(MSG_CRITICAL_ERROR, "Error in setProdData: no combination found for "+type_h+", "+i2s(regId_h)+", "+prodId_h+", "+i2s(year)+", "+freeDim_h+". You can allow new variables to be created using the \"allowCreate\" flag.");
1394 } else {
1395 for(uint r=0;r< regIds.size();r++){
1396 for(uint i=0;i<products.size();i++){
1397 key = makeKeyProdData(type_h,i2s(regIds[r]),products[i],freeDim_h);
1398 vector <double> values;
1399 setTimedData(value_h,values,year,MSG_NO_MSG);
1400 prodDataMap.insert(DataPair(key,values));
1401 }
1402 }
1403 }
1404 }
1405
1406}
1407
1408
1409
1410
1411void
1412ModelData::setForData(const double& value_h, const string &type_h, const int& regId_h, const string &forType_h, const string &freeDim_h, const int& year, const bool& allowCreate){
1413
1414 vector<int> regIds;
1415 vector <string> dClasses;
1416 vector <string> fTypes;
1417 string key;
1418 DataMap::const_iterator p;
1419 bool found = false;
1420 bool tempFound = false;
1421
1422 if (forType_h == FT_ALL){
1423 fTypes = getForTypeIds();
1424 } else {
1425 fTypes.push_back(forType_h);
1426 }
1427
1428 if(freeDim_h == DIAM_ALL){
1429 dClasses = diamClasses;
1430 } else if (freeDim_h == DIAM_PROD){
1431 dClasses = getDiameterClasses(true);
1432 } else if (freeDim_h == DIAM_FIRST){
1433 dClasses.push_back(diamClasses.at(0));
1434 } else {
1435 dClasses.push_back(freeDim_h);
1436 }
1437
1438 // Make sure to set the new value to all l2 regions if requested for a reg1 level
1439 if(getRegion(regId_h)->getRegLevel()==2){
1440 regIds.push_back(regId_h);
1441 } else if (getRegion(regId_h)->getRegLevel()==1) {
1442 for(uint i=0;i<getRegion(regId_h)->getNChildren();i++){
1443 regIds.push_back(getRegion(regId_h)->getChildren()[i]->getRegId());
1444 }
1445 } else {
1446 msgOut(MSG_CRITICAL_ERROR, "Error in setProdData(). Setting a value for the whole World is not supported.");
1447 }
1448 int regIdsS = regIds.size();
1449
1450 for(uint r=0;r< regIds.size();r++){
1451 for(uint i=0;i<dClasses.size();i++){
1452 for (uint y=0;y<fTypes.size();y++){
1453 key = makeKeyForData(type_h,i2s(regIds[r]),fTypes[y],dClasses[i]);
1454 tempFound = dataMapSetValue(forDataMap,key,value_h, year,true);
1455 if(tempFound) found = true;
1456 }
1457 }
1458 }
1459
1460 if(!found){
1461 if(!allowCreate){
1462 msgOut(MSG_CRITICAL_ERROR, "Error in setForData: no combination found for "+type_h+", "+i2s(regId_h)+", "+forType_h+", "+i2s(year)+", "+freeDim_h+". You can allow new variables to be created using the \"allowCreate\" flag.");
1463 } else {
1464 for(uint r=0;r< regIds.size();r++){
1465 for(uint i=0;i<dClasses.size();i++){
1466 for (uint y=0;y<fTypes.size();y++){
1467 key = makeKeyForData(type_h,i2s(regIds[r]),fTypes[y],dClasses[i]);
1468 vector <double> values;
1469 setTimedData(value_h,values,year,MSG_NO_MSG);
1470 forDataMap.insert(DataPair(key,values));
1471 }
1472 }
1473 }
1474 }
1475 }
1476}
1477
1478
1479double
1480ModelData::getTimedData(const vector<double> &dated_vector, const int& year_h) const{
1481
1482 int position;
1483 if(year_h==DATA_NOW){
1484 position = MTHREAD->SCD->getYear()-cached_initialYear;
1485 } else {
1486 position = year_h-cached_initialYear;
1487 }
1488
1489 if(dated_vector.size() > position) {
1490 return dated_vector[position];
1491 } else if (dated_vector.size() > 0 ){
1492 // returning the last available value...
1493 return dated_vector[dated_vector.size()-1];
1494 } else {
1495 msgOut(MSG_CRITICAL_ERROR, "Error in getTimedData: requested value doesn't have any value, even on the first position(year)!");
1496 }
1497 return 0;
1498}
1499
1500void
1501ModelData::setTimedData(const double& value_h, vector<double> &dated_vector, const int& year_h, const int& MSG_LEVEL){
1502
1503 int position;
1504 if(year_h==DATA_NOW){
1505 position = MTHREAD->SCD->getYear()-cached_initialYear;
1506 } else {
1507 position = year_h-cached_initialYear;
1508 }
1509
1510 int originalVectorSize = dated_vector.size();
1511 if(dated_vector.size() > position) {
1512 dated_vector[position]=value_h;
1513 } else {
1514 // extending the vector and filling it with the incoming value, but issuing a warning if done for more than one year
1515
1516 for(uint i=0;i<position-originalVectorSize+1;i++){
1517 dated_vector.push_back(value_h);
1518 }
1519 if(position-originalVectorSize > 0 ){
1520 msgOut(MSG_LEVEL, "setTimedData: a dated vector has been filled several years ("+i2s(1+position-originalVectorSize)+") with incoming values to reach desidered position in time.");
1521 }
1522 }
1523}
1524
1525
1526void
1528 msgOut(MSG_INFO, "Loading input files (this can take a few minutes)...");
1529 //QString iFile("data/ffsmInput.ods");
1530 QString iFile(MTHREAD->getInputFileName().c_str());
1531 //cout << "PIPPO !!!!! " << MTHREAD->getInputFileName().c_str() << endl;
1532
1533 //std::random_device rd;
1534 //std::mt19937 localgen(rd());
1535 std::mt19937 localgen(time(0));
1536 std::uniform_int_distribution<> dis(10, 1000000);
1537 int randomNumber = dis(localgen);
1538
1539 QString oDir((MTHREAD->getBaseDirectory()+"tempInput-"+MTHREAD->getScenarioName()+i2s(randomNumber)).c_str());
1540 string forDataCachedFilename = MTHREAD->getBaseDirectory()+"cachedInput/forData.csv";
1541 string prodDataCachedFilename = MTHREAD->getBaseDirectory()+"cachedInput/prodData.csv";
1542
1543 // removing output directory if exist..
1544 QDir oQtDir(oDir);
1545
1546 if(oQtDir.exists()){
1547 bool deleted;
1548 deleted = delDir(oDir);
1549 if(deleted){msgOut(MSG_DEBUG,"Correctly deleted old temporary data");}
1550 else {msgOut(MSG_WARNING, "I could not delete old temporary data dir (hopefully we'll overrite the input files)");}
1551 }
1552
1553 if (!QFile::exists(iFile))
1554 {
1555 cout << "File does not exist." << endl << endl;
1556 //return false;
1557 }
1559 UnZip uz;
1560 ec = uz.openArchive(iFile);
1561 if (ec != UnZip::Ok) {
1562 //cout << "Failed to open archive: " << uz.formatError(ec).toAscii().data() << endl << endl; // Qt4
1563 cout << "Failed to open archive: " << uz.formatError(ec).toLatin1().data() << endl << endl; // Qt5
1564 //return false;
1565 }
1566 ec = uz.extractAll(oDir);
1567 if (ec != UnZip::Ok){
1568 //cout << "Extraction failed: " << uz.formatError(ec).toAscii().data() << endl << endl; // Qt4
1569 cout << "Extraction failed: " << uz.formatError(ec).toLatin1().data() << endl << endl; // Qt5
1570 uz.closeArchive();
1571 //return false;
1572 }
1573
1574 // loading input file into memory...
1575 string inputXMLFileName = MTHREAD->getBaseDirectory()+"tempInput-"+MTHREAD->getScenarioName()+i2s(randomNumber)+"/content.xml";
1576 //string inputXMLFileName = MTHREAD->getBaseDirectory()+"test/content.xml";
1577 //cout << "inputXMLFileName: " << inputXMLFileName << endl;
1578 //mainDocument = new InputDocument();
1579 mainDocument.setWorkingFile(inputXMLFileName);
1580 //InputNode documentContent = mainDocument.getNodeByName("office:document-content");
1581 //InputNode documentBody = mainDocument.getNodeByName("office:body");
1582 //InputNode mainNode = mainDocument.getNodeByName("spreadsheet");
1583 //InputNode pippo = mainDocument.getNodeByName("pippo-pippo");
1584 //InputNode table = mainDocument.getNodeByName("table");
1585 //cout << "Test result: " << table.getStringContent() << endl;
1586
1587
1588 vector <InputNode> tables = mainDocument.getNodesByName("table");
1589 for(uint i=0;i<tables.size();i++){
1590 string tableName = tables[i].getStringAttributeByName("name");
1591 //cout <<tableName<<endl;
1592 if( (tableName == "forData" || tableName == "prodData") && QFile::exists(forDataCachedFilename.c_str()) ) {
1593 msgOut(MSG_INFO,"Attenction, using cached data (csv) for "+tableName);
1594 string fileName = MTHREAD->getBaseDirectory()+"cachedInput/"+tableName+".csv";
1595 LLDataVector.push_back(MTHREAD->MD->getTableFromFile(tableName, fileName));
1596 continue;
1597 }
1598 LLData data(MTHREAD,tables[i].getStringAttributeByName("name"));
1599 vector <InputNode> rows = tables[i].getNodesByName("table-row",MSG_NO_MSG,true);
1600 if(rows.size()<2) continue; //empty table or only with headers
1601 // building headers..
1602 vector <InputNode> cells = rows[0].getNodesByName("table-cell",MSG_NO_MSG,true);
1603 for (uint y=0; y<cells.size(); y++){
1604 int repeated = 1;
1605 if( cells[y].hasAttributeByName("number-columns-repeated")){
1606 repeated = cells[y].getIntAttributeByName("number-columns-repeated");
1607 }
1608 for (int q=0;q<repeated;q++){
1609 if( !cells[y].hasChildNode("p") ){
1610 data.headers.push_back(""); // empty header
1611 } else {
1612 data.headers.push_back(cells[y].getNodeByName("p",MSG_NO_MSG,true).getStringContent());
1613 }
1614 }
1615 }
1616 // loading data...
1617 for (uint j=1; j<rows.size();j++){
1618 //cout << j << endl;
1619 vector <InputNode> cells = rows[j].getNodesByName("table-cell",MSG_NO_MSG,true);
1620 //vector <InputNode> cells = rows[j].getChildNodes();
1621 if (cells.size()<1) continue;
1622 vector<string> record;
1623 // checking the first cell is not a comment nor is empty..
1624 int childCount = cells[0].getChildNodesCount();
1625 if (childCount == 0 || !cells[0].hasChildNode("p")) continue; // empty line, first column empty!
1626 string fistCol = cells[0].getNodeByName("p",MSG_NO_MSG,true).getStringContent();
1627 unsigned int z;
1628 z = fistCol.find("#");
1629 if( z!=string::npos && z == 0) continue; // found "#" on fist position, it's a comment!
1630 for (uint y=0; y<cells.size(); y++){
1631 int repeated = 1;
1632 if( cells[y].hasAttributeByName("number-columns-repeated")){
1633 repeated = cells[y].getIntAttributeByName("number-columns-repeated");
1634 }
1635 for (int q=0;q<repeated;q++){
1636 if( !cells[y].hasChildNode("p") ){
1637 record.push_back(""); // empty header
1638 } else {
1639 // changed 20120625 as for float values the content of p is the visualised value, not the full memorised one.
1640 // this is strange because tought I already tested it.. but maybe is changed the format??
1641 if(cells[y].getStringAttributeByName("value-type")=="float"){
1642 record.push_back(cells[y].getStringAttributeByName("value"));
1643 } else {
1644 record.push_back(cells[y].getNodeByName("p",MSG_NO_MSG,true).getStringContent());
1645 }
1646 }
1647 }
1648 }
1649 data.records.push_back(record);
1650 }
1651 data.clean();
1652 LLDataVector.push_back(data);
1653 }
1654
1655 //debug !!!
1656 /*for (uint i=0; i<LLDataVector.size();i++){
1657 cout << "***************** NEW TABLE: " << LLDataVector[i].tableName << endl;
1658 //cout << "***** Headers: "<< endl;
1659 int headerSize = LLDataVector[i].headers.size();
1660 bool ok = true;
1661 cout << "Header size: " << headerSize << endl;
1662 //for (uint j=0; j<LLDataVector[i].headers.size();j++){
1663 // cout << "["<<j<<"] " << LLDataVector[i].headers[j] << endl;
1664 //}
1665 //cout << "***** Records: " << endl;
1666 for (uint j=0; j<LLDataVector[i].records.size();j++){
1667 //cout << "** Record "<<j<<":"<<endl;
1668 if(LLDataVector[i].records[j].size() != headerSize){
1669 cout << "There is a problem on record " << j <<"!"<< endl;
1670 cout << "His size is: "<< LLDataVector[i].records[j].size() << endl;
1671 ok = false;
1672 }
1673 //for (uint y=0; y<LLDataVector[i].records[j].size();y++){
1674 // cout << "["<<y<<"] " << LLDataVector[i].records[j][y] << endl;
1675 //}
1676 }
1677 if(!ok) {cout <<"Problems with this table :-( !"<<endl;}
1678 }*/
1679
1680
1681
1682 // deleting output directory if exist...
1683 if(oQtDir.exists()){
1684 bool deleted;
1685 deleted = delDir(oDir);
1686 if(deleted){msgOut(MSG_DEBUG,"Correctly deleted old temporary data");}
1687 else {msgOut(MSG_WARNING, "I could not delete old temporary data dir (hopefully we'll overrite the input files)");}
1688 }
1689}
1690
1691
1692/*
1693void
1694ModelData::loadDataFromCache(string tablename){
1695 msgOut(MSG_INFO,"Attenction, using cached data (csv) for "+tablename);
1696 string fileName = MTHREAD->getBaseDirectory()+"cachedInput/"+tablename+".csv";
1697 QFile file(fileName.c_str());
1698 if (!file.open(QFile::ReadOnly)) {
1699 msgOut(MSG_ERROR, "Cannot open file "+fileName+" for reading.");
1700 }
1701 QTextStream in(&file);
1702 LLData data(MTHREAD, tablename);
1703 int countRow = 0;
1704 while (!in.atEnd()) {
1705 QString line = in.readLine();
1706 QStringList fields = line.split(';');
1707 if (countRow==0){ // building headers
1708 for(uint i =0;i<fields.size();i++){
1709 data.headers.push_back(fields.at(i).toStdString());
1710 }
1711 } else {
1712 vector<string> record ; //= fields.toVector().toStdVector();
1713 unsigned int z = fields[0].toStdString().find("#");
1714 if( z!=string::npos && z == 0) continue; // found "#" on fist position, it's a comment!
1715 for(uint i =0;i<fields.size();i++){
1716 string field = fields.at(i).toStdString();
1717 replace(field.begin(), field.end(), ',', '.');
1718 record.push_back(field);
1719 }
1720 data.records.push_back(record);
1721 }
1722 countRow++;
1723 }
1724 data.clean();
1725 LLDataVector.push_back(data);
1726
1727}
1728*/
1729
1730LLData
1731ModelData::getTableFromFile(string tablename, string filename_h){
1732 string fileName = MTHREAD->getBaseDirectory()+filename_h;
1733 QFile file(fileName.c_str());
1734 if (!file.open(QFile::ReadOnly)) {
1735 msgOut(MSG_ERROR, "Cannot open file "+fileName+" for reading.");
1736 }
1737 QTextStream in(&file);
1738 LLData data(MTHREAD, tablename);
1739 int countRow = 0;
1740 while (!in.atEnd()) {
1741 QString line = in.readLine();
1742 if(line=="") continue; //skipping completelly empty lines, even without separators
1743 QStringList fields = line.split(';');
1744 bool emptyLine = true;
1745 if (countRow==0){ // building headers
1746 for(uint i =0;i<fields.size();i++){
1747 data.headers.push_back(fields.at(i).toStdString());
1748 }
1749 } else {
1750 vector<string> record ; //= fields.toVector().toStdVector();
1751 unsigned int z = fields[0].toStdString().find("#");
1752 if( z!=string::npos && z == 0) continue; // found "#" on fist position, it's a comment!
1753 for(uint i =0;i<fields.size();i++){
1754 string field = fields.at(i).toStdString();
1755 replace(field.begin(), field.end(), ',', '.');
1756 record.push_back(field);
1757 if(field!="") emptyLine = false;
1758 }
1759 if(!emptyLine){data.records.push_back(record);};
1760 }
1761 countRow++;
1762 }
1763 data.clean();
1764 return data;
1765}
1766
1767
1768bool
1769ModelData::delDir(QString dirname) {
1770 bool deleted = false;
1771 QDir dir(dirname);
1772 //msgOut(MSG_DEBUG, dir.absolutePath().toStdString());
1773 dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks);
1774 QFileInfoList list = dir.entryInfoList();
1775 deleted = dir.rmdir(dir.absolutePath());
1776 if (deleted) return true;
1777
1778 for (int i = 0; i < list.size(); ++i) {
1779 QFileInfo fileInfo = list.at(i);
1780 if (fileInfo.isFile()){
1781 //msgOut(MSG_DEBUG, "A file, gonna remove it: "+fileInfo.absoluteFilePath().toStdString());
1782 QFile targetFile(fileInfo.absoluteFilePath());
1783 bool fileDeleted = targetFile.remove();
1784 if (!fileDeleted){
1785 msgOut(MSG_CRITICAL_ERROR, "We have a problem: can't delete file "+fileInfo.absoluteFilePath().toStdString());
1786 }
1787 }
1788 else if (fileInfo.isDir()){
1789 //msgOut(MSG_DEBUG, "A directory, gonna go inside it: "+fileInfo.absoluteFilePath().toStdString());
1790 delDir(fileInfo.absoluteFilePath());
1791 dir.rmdir(fileInfo.absoluteFilePath());
1792 }
1793 }
1794
1795 deleted = dir.rmdir(dir.absolutePath());
1796 if (deleted) return true;
1797 return false;
1798}
1799
1800LLData
1801ModelData::getTable(string tableName_h, int debugLevel){
1802 LLData toReturn(MTHREAD,"");
1803 for(uint i=0;i<LLDataVector.size();i++){
1804 if (LLDataVector[i].getTableName() == tableName_h)return LLDataVector[i];
1805 }
1806 msgOut(debugLevel,"No table found with name "+tableName_h);
1807 return toReturn;
1808}
1809
1810
1811bool
1812ModelData::dataMapCheckExist(const DataMap& map, const string& search_for, const bool& exactMatch) const {
1813 /*int dummyYear=MTHREAD->SCD->getYear();
1814 if(dataMapGetValue(map, search_for, dummyYear, exactMatch)==DATA_ERROR) {
1815 return false;
1816 } else {
1817 return true;
1818 }
1819 return false;
1820}*/
1821 bool found = false;
1822 DataMap::const_iterator i;
1823 if(!exactMatch){
1824 i = map.lower_bound(search_for);
1825 for(;i != map.end();i++){
1826 const string& key = i->first;
1827 if (key.compare(0, search_for.size(), search_for) == 0) {// Really a prefix?
1828 return true;
1829 } else {
1830 return false;
1831 }
1832 }
1833 } else {
1834 i = map.find(search_for);
1835 if (i!=map.end()){
1836 return true;
1837 }
1838 }
1839 return false;
1840}
1841
1842
1843double
1844ModelData::dataMapGetValue(const DataMap& map, const string& search_for, const int& year_h, const bool& exactMatch) {
1845 double toReturn = 0;
1846 tempBool = false;
1847 DataMap::const_iterator i;
1848 if(!exactMatch){
1849 i = map.lower_bound(search_for);
1850 for(;i != map.end();i++){
1851 const string& key = i->first;
1852 if (key.compare(0, search_for.size(), search_for) == 0) {// Really a prefix?
1853 tempBool = true;
1854 toReturn += getTimedData( i->second, year_h );
1855 } else {
1856 break;
1857 }
1858 }
1859 } else {
1860 i = map.find(search_for);
1861 if (i!=map.end()){
1862 tempBool = true;
1863 return getTimedData( i->second, year_h );
1864 }
1865 }
1866 return toReturn;
1867}
1868
1869
1870
1871int
1872ModelData::dataMapSetValue( DataMap& map, const string& search_for, const double& value_h, const int& year_h, const bool& exactMatch){
1873 bool found = false;
1874 DataMap::iterator i;
1875 if(!exactMatch){
1876 i = map.lower_bound(search_for);
1877 for(;i != map.end();i++){
1878 const string& key = i->first;
1879 if (key.compare(0, search_for.size(), search_for) == 0) {// Really a prefix?
1880 found = true;
1881 setTimedData(value_h, i->second, year_h);
1882 } else {
1883 break;
1884 }
1885 }
1886 } else {
1887 i = map.find(search_for);
1888 if (i!=map.end()){
1889 found = true;
1890 setTimedData(value_h, i->second, year_h, errorLevel);
1891 }
1892 }
1893 // removed 20120903 as the insertion of new values must be explicitly done, not in all cases we want a new insertion
1894 /*if(!found){
1895 vector < double> newValues;
1896 setTimedData(value_h, newValues, year_h, MSG_NO_MSG); // don't warning if we are making a multi-year value vector, as it is a new one
1897 map.insert(DataPair (search_for,newValues));
1898 }*/
1899 return found;
1900}
1901
1902void
1903ModelData::unpackKeyProdData(const string& key, string& parName, int& regId, string& prod, string& freeDim) const{
1904
1905 int parNameDelimiter = key.find("#",0);
1906 int regIdDelimiter = key.find("#",parNameDelimiter+1);
1907 int prodDelimiter = key.find("#",regIdDelimiter+1);
1908 int freeDimDelimiter = key.find("#",prodDelimiter+1);
1909 if (freeDimDelimiter == string::npos){
1910 msgOut(MSG_CRITICAL_ERROR, "Error in unpacking a key in the map of production data.");
1911 }
1912 parName.assign(key,0,parNameDelimiter);
1913 string regIdString="";
1914 regIdString.assign(key,parNameDelimiter+1,regIdDelimiter-parNameDelimiter-1);
1915 regId = s2i(regIdString);
1916 prod.assign(key,regIdDelimiter+1,prodDelimiter-regIdDelimiter-1);
1917 freeDim.assign(key,prodDelimiter+1,freeDimDelimiter-prodDelimiter-1);
1918
1919}
1920
1921void
1922ModelData::unpackKeyForData(const string& key, string& parName, int &regId, string& forType, string& diamClass) const{
1923 int parNameDelimiter = key.find("#",0);
1924 int regIdDelimiter = key.find("#",parNameDelimiter+1);
1925 int forTypeDelimiter = key.find("#",regIdDelimiter+1);
1926 int diamClassDelimiter = key.find("#",forTypeDelimiter+1);
1927 if (diamClassDelimiter == string::npos){
1928 msgOut(MSG_CRITICAL_ERROR, "Error in unpacking a key in the map of production data.");
1929 }
1930 parName.assign(key,0,parNameDelimiter);
1931 string regIdString="";
1932 regIdString.assign(key,parNameDelimiter+1,regIdDelimiter-parNameDelimiter-1);
1933 regId = s2i(regIdString);
1934 forType.assign(key,regIdDelimiter+1,forTypeDelimiter-regIdDelimiter-1);
1935 diamClass.assign(key,forTypeDelimiter+1,diamClassDelimiter-forTypeDelimiter-1);
1936
1937}
1938
1939
1940/**
1941calculating the discount factor
1942
1943Revenues at years n will be transforemed as average year rate as
1944
1945av.y.rev = rev(n)/ ( (1+ir)^(n-1)+(1+ir)^(n-2)+(1+ir)^(n-3)+...+(1+ir)^(n-n) )
1946
1947Objective is to have the present value of the final harvest (A) equal to the sum pf the present values of yearly activities (B):
1948
1949\image html diagram_calculateAnnualisedEquivalent.png "Comparing present values" width=10cm
1950
1951\f[ PV(A) = SUM(PV(B) \f]
1952\f[ A/(1+r)^n = B/(1+r)^1 + B/(1+r)^2 + … + B/(1+r)^n \f]
1953\f[ A/(1+r)^n = B * ( 1/(1+r)^1 + 1/(1+r)^2 + … + 1/(1+r)^n ) \f]
1954\f[ A/(1+r)^n = B * ( (1+r)^(n-1) + (1+r)^(n-2) + … + (1+r)^(n-n) ) \f]
1955\f[ B = A / ( (1+r)^(n-1) + (1+r)^(n-2) + … + (1+r)^(n-n) ) \f]
1956
195720131204. Changed for the equivalent but simpler eai = rev(t)*i / ((1+i)^t-1)
1958
1959*/
1960double
1961ModelData::calculateAnnualisedEquivalent(const double& amount_h, const int& years_h, const double& ir) const {
1962 // modified and tested 20120912. Before it was running this formula instead:
1963 // av.y.rev = rev(n)/ ( (1+ir)^1+(1+ir)^2+(1+ir)^3+...+(1+ir)^n )
1964 // the difference is that in this way the annual equivalent that is calulated doesn't need to be further discounted for yearly activites (e.g. agric)
1965
1966 //loop(fy$(ord(fy)=1),
1967 // df(fy)= (1+ir)**(ord(fy));
1968 //);
1969 //loop(fy$(ord(fy)>1),
1970 // df(fy)=df(fy-1)+(1+ir)**(ord(fy));
1971 //);
1972 if(years_h<0) return 0.;
1973 if(years_h==0) return amount_h;
1974 //double ir = getDoubleSetting("ir",DATA_NOW);
1975 double eai = amount_h * ir / (pow(1.0+ir,years_h)-1.0);
1976
1977 return eai;
1978
1979 /*
1980 vector <double> df_by;
1981 for(int y=0;y<years_h;y++){
1982 double df;
1983 if(y==0){
1984 df = pow((1+ir),y);
1985 } else {
1986 df = df_by.at(y-1)+pow((1+ir),y);
1987 }
1988 if (y==years_h-1) {
1989 cout << eai << " " << amount_h/df << endl;
1990 return amount_h/df; // big bug 20120904
1991 }
1992 df_by.push_back(df);
1993 }
1994 exit(1);
1995 return 0; // never reached, just to avoid compilation warnings
1996 */
1997}
1998
1999double
2000ModelData::calculateAnnualisedEquivalent(const double& amount_h, const double& years_h, const double& ir) const{
2001 //ceil(x) DNLP returns the smallest integer number greater than or equal to x
2002 //loop( (u,i,lambda,essence),
2003 // cumTp(u,i,lambda,essence) = ceil(cumTp(u,i,lambda,essence));
2004 //);
2005 int ceiledYear = ceil(years_h);
2006 return calculateAnnualisedEquivalent(amount_h, ceiledYear, ir);
2007}
2008
2009/** Get a list of files in a directory */
2010int
2011ModelData::getFilenamesByDir (const string & dir, vector<string> &files, const string & filter){
2012 DIR *dp;
2013 struct dirent *dirp;
2014 if((dp = opendir(dir.c_str())) == NULL) {
2015 msgOut(MSG_ERROR, "Error " + i2s(errno) + " opening the " + dir + " directory.");
2016 //cout << "Error(" << errno << ") opening " << dir << endl;
2017 return errno;
2018 }
2019 while ((dirp = readdir(dp)) != NULL) {
2020 string filename = dirp->d_name;
2021 if(
2022 (filter != "" && filename.substr(filename.find_last_of(".")) == filter) // there is a filter and the last bit of the filename match the filter
2023 || (filter == "" && filename.substr(filename.find_last_of(".") + 1) != "") // there isn't any filter but we don't want stuff like ".." or "."
2024 ) {
2025 files.push_back(string(dirp->d_name));
2026 }
2027 }
2028 closedir(dp);
2029 return 0;
2030}
2031
2032
2033vector<pathRule*>
2034ModelData::getPathMortalityRule(const string& forType, const string& dC){
2035 vector<pathRule*> toReturn;
2036 for(uint i=0;i<pathRules.size();i++){
2037 if(pathRules[i].forType == forType && pathRules[i].dClass == dC){
2038 toReturn.push_back(&pathRules[i]);
2039 }
2040 }
2041 return toReturn;
2042}
2043
2044/**
2045 * @brief ModelData::createCombinationsVector
2046 * Return a vector containing any possible combination of nItems items (including all subsets).
2047 *
2048 * For example with nItems = 3:
2049 * 0: []; 1: [0]; 2: [1]; 3: [0,1]; 4: [2]; 5: [0,2]; 6: [1,2]; 7: [0,1,2]
2050
2051 * @param nItems number of items to create p
2052 * @return A vector with in each slot the items present in that specific combination subset.
2053 */
2054vector < vector <int> >
2056 // Not confuse combination with permutation where order matter. Here it doesn't matter, as much as the algorithm is the same and returns
2057 // to as each position always the same subset
2058 vector < vector <int> > toReturn;
2059 int nCombs = pow(2,nItems);
2060 //int nCombs = nItems;
2061 for (uint i=0; i<nCombs; i++){
2062 vector<int> thisCombItems; //concernedPriProducts;
2063 for(uint j=0;j<nItems;j++){
2064 uint j2 = pow(2,j);
2065 if(i & j2){ // bit a bit operator, p217 C++ book
2066 thisCombItems.push_back(j);
2067 }
2068 }
2069 toReturn.push_back(thisCombItems);
2070 }
2071 return toReturn;
2072}
2073
2074
2075double
2076ModelData::getAvailableDeathTimber(const vector<string> &primProd_h, int regId_h, int year_h){
2077 if (!getBoolSetting("useDeathTimber",DATA_NOW)) return 0;
2078 double toReturn = 0.0;
2079 vector <string> forTypesIds = getForTypeIds();
2080 for (uint i=0;i<forTypesIds.size();i++){
2081 string ft = forTypesIds[i];
2082 for(uint u=0;u<diamClasses.size();u++){
2083 string dc = diamClasses[u];
2084 bool possible = false;
2085 int maxYears = 0;
2086 for (int p=0; p<primProd_h.size();p++){
2087 string primProd = primProd_h[p];
2088 if(assessProdPossibility(primProd,ft, dc)){
2089 possible = true;
2090 maxYears=max(maxYears,getMaxYearUsableDeathTimber(primProd, ft, dc));
2091 }
2092 }
2093 if(possible){
2094 for(int y=year_h;y>year_h-maxYears;y--){
2095 iisskey key(y,regId_h,ft,dc);
2096 toReturn += findMap(deathTimberInventory,key,MSG_NO_MSG,0.0);
2097 }
2098 }
2099 }
2100 }
2101 return toReturn;
2102}
2103
2104vector <int>
2105ModelData::getAllocableProductIdsFromDeathTimber(const int &regId_h, const string &ft, const string &dc, const int &harvesting_year, int request_year){
2106 vector<int> allocableProductIds;
2107 if (!getBoolSetting("useDeathTimber",DATA_NOW)) return allocableProductIds;
2108 if (request_year == DATA_NOW) request_year = MTHREAD->SCD->getYear();
2109 for(uint p=0;p<priProducts.size();p++){
2110 string primProd = priProducts[p];
2111 if(assessProdPossibility(primProd,ft, dc)){
2112 int maxYears = getMaxYearUsableDeathTimber(primProd, ft, dc);
2113 if (request_year-harvesting_year < maxYears){
2114 allocableProductIds.push_back(p);
2115 }
2116 }
2117 }
2118 return allocableProductIds;
2119}
2120
2121
2122
2123double
2124ModelData::getAvailableAliveTimber(const vector<string> &primProd_h, int regId_h){
2125 double toReturn = 0.0;
2126 ModelRegion* REG = MTHREAD->MD->getRegion(regId_h);
2127 vector <Pixel*> regPx = REG->getMyPixels();
2128 vector <string> forTypesIds = getForTypeIds();
2129 for (uint i=0;i<forTypesIds.size();i++){
2130 string ft = forTypesIds[i];
2131 for(uint u=0;u<diamClasses.size();u++){
2132 string dc = diamClasses[u];
2133 bool possible = false;
2134 for (int p=0; p<primProd_h.size();p++){
2135 string primProd = primProd_h[p];
2136 if(assessProdPossibility(primProd,ft, dc)){
2137 possible = true;
2138 }
2139 }
2140 if(possible){
2141 for (uint p=0;p<regPx.size();p++){
2142 Pixel* px = regPx[p];
2143 toReturn += px->vol_l.at(i).at(u)*px->avalCoef.at(i);
2144 }
2145 }
2146 }
2147 }
2148 return toReturn;
2149}
2150
2151// ========================== LLData =======================================
2152
2153LLData::LLData(ThreadManager* MTHREAD_h, string tableName_h){
2154 MTHREAD = MTHREAD_h;
2155 tableName = tableName_h;
2156}
2157
2159
2160}
2161
2162void
2164
2165 //checking the size is correct...
2166 int hsize = headers.size();
2167 for (uint i=0;i<records.size();i++){
2168 if(records[i].size() != hsize){
2169 vector <string> record = records[i];
2170 msgOut(MSG_CRITICAL_ERROR,"Error in the input reading table "+tableName+". Record "+i2s(i)+" has "+i2s(records[i].size())+" fields instead of "+i2s(hsize)+".");
2171 }
2172 }
2173 //cleaning empty-header columns...
2174 for (int i=headers.size()-1;i>=0;i--){
2175 if(headers[i] == ""){
2176 headers.erase(headers.begin()+i);
2177 for (uint j=0;j<records.size();j++){
2178 records[j].erase(records[j].begin()+i);
2179 }
2180 }
2181 }
2182
2183}
2184
2185string
2186LLData::getData(const int &pos_h, const string &header_h, const int &debugLevel) const{
2187
2188 if (records.size()<= pos_h){
2189 msgOut(debugLevel, "Requested position "+i2s(pos_h)+" too high! Not enought records !!");
2190 return "";
2191 }
2192 int hsize = headers.size();
2193 for (uint i=0;i<hsize;i++){
2194 if(headers[i] == header_h) return records[pos_h][i];
2195 }
2196 msgOut(debugLevel, "Header string "+header_h+" not found!");
2197 return "";
2198}
@ WORLD
Request something that is not region-specific.
Definition BaseClass.h:80
@ DATA_NOW
The required data is for the current year.
Definition BaseClass.h:73
#define PROD_PRI
Primary products.
Definition BaseClass.h:151
#define PROD_ALL
All primary and transformed products.
Definition BaseClass.h:148
#define FT_ALL
All forest types.
Definition BaseClass.h:166
@ TYPE_DOUBLE
The required data is a double.
Definition BaseClass.h:67
@ TYPE_BOOL
The required data is a bool.
Definition BaseClass.h:69
@ TYPE_INT
The required data is an integer.
Definition BaseClass.h:66
@ TYPE_STRING
The required data is a string.
Definition BaseClass.h:68
#define DIAM_ALL
All diameter classes.
Definition BaseClass.h:157
#define PROD_SEC
Secondary products.
Definition BaseClass.h:154
#define DIAM_PROD
Diameter classes used for production (e.g. excluded the first one)
Definition BaseClass.h:160
#define DIAM_FIRST
First diameter class (NOT used for production)
Definition BaseClass.h:163
@ MSG_CRITICAL_ERROR
Print an error message and stop the model.
Definition BaseClass.h:62
@ MSG_ERROR
Print an ERROR message, but don't stop the model.
Definition BaseClass.h:61
@ MSG_DEBUG
Print a debug message, normally filtered out.
Definition BaseClass.h:58
@ MSG_WARNING
Print a WARNING message.
Definition BaseClass.h:60
@ MSG_INFO
Print an INFO message.
Definition BaseClass.h:59
@ MSG_NO_MSG
Do not actually output any message.
Definition BaseClass.h:57
map< string, vector< double > > DataMap
Definition ModelData.cpp:56
pair< string, vector< double > > DataPair
Definition ModelData.cpp:57
map< string, vector< double > > DataMap
Definition ModelData.h:43
pair< string, vector< double > > DataPair
Definition ModelData.h:44
ThreadManager * MTHREAD
Pointer to the Thread manager.
Definition BaseClass.h:467
int s2i(const string &string_h) const
string to integer conversion
V findMap(const map< K, V > &mymap, const K &key, const int &error_level=MSG_CRITICAL_ERROR, const V &notFoundValue=numeric_limits< V >::min()) const
Lookup a map for a value. Return the value starting from the key.
Definition BaseClass.h:286
void msgOut(const int &msgCode_h, const string &msg_h, const bool &refreshGUI_h=true) const
Overloaded function to print the output log.
Definition BaseClass.cpp:50
bool inVector(const K &element, const vector< K > &v)
Definition BaseClass.h:429
bool s2b(const string &string_h) const
string to bool conversion
int getType(const string &type_h) const
Return a type according to enum TYPE_* from a string (eg: "string" -> TYPE_STRING (2))
string i2s(const int &int_h) const
integer to string conversion
double s2d(const string &string_h) const
string to double conversion
bool setWorkingFile(std::string filename_h)
Load the file on memory. Return false if no success.
Definition InputNode.cpp:37
vector< InputNode > getNodesByName(string nodeName_h, int debugLevel=MSG_WARNING, bool childFlag=false)
Low level data. XML input is reversed here after unzipping oocalc file and parsing content....
Definition ModelData.h:329
LLData(ThreadManager *MTHREAD_h, string tableName_h)
string getData(const int &pos_h, const string &header_h, const int &debugLevel=MSG_CRITICAL_ERROR) const
void clean()
int nheaders()
Definition ModelData.h:337
int nrecords()
Definition ModelData.h:336
vector< vector< string > > records
Definition ModelData.h:345
string tableName
Definition ModelData.h:343
vector< string > headers
Definition ModelData.h:344
bool regionExist(const int &regId_h) const
vector< string > getForTypeParents()
forType * getForType(int position)
Definition ModelData.h:128
vector< pathRule > pathRules
Vector of pathogen rules.
Definition ModelData.h:228
vector< string > allProducts
Definition ModelData.h:237
vector< int > getIntVectorSetting(const string &name_h, int reg=WORLD) const
vector< int > getAllocableProductIdsFromDeathTimber(const int &regId_h, const string &ft, const string &dc, const int &harvesting_year, int request_year=DATA_NOW)
Returns the ids of the primary products that is possible to obtain using the timber recorded death in...
double getAvailableAliveTimber(const vector< string > &primProd_h, int regId_h)
Returns the timber available for a given set of primary products as stored in the px->vol_l vector.
void cacheSettings()
Called after input reading, it fix frequently used data;.
void setProdData(const double &value_h, const string &type_h, const int &regId_h, const string &prodId_h, const int &year=DATA_NOW, const bool &allowCreate=false, const string &freeDim_h="")
int getForTypeCounter(string &forTypeId_h, bool all=false)
By default it doesn't return forTypes used only as input.
Definition ModelData.cpp:81
double dataMapGetValue(const DataMap &map, const string &search_for, const int &year_h, const bool &exactMatch=true)
void setTimedData(const double &value_h, vector< double > &dated_vector, const int &year_h, const int &MSG_LEVEL=MSG_WARNING)
string outputDirname
Definition ModelData.h:214
vector< string > getScenarios()
vector< IFiles > iFilesVector
List of all input files. Simple (struct)
Definition ModelData.h:221
void setDefaultForData()
void setScenarioData()
Set the infos about this scenario (long description and overriding tables)
bool getBoolSetting(const string &name_h, int position=0, int reg=WORLD) const
vector< ModelRegion > regionsVector
Vector of modelled regions.
Definition ModelData.h:224
vector< bool > getBoolVectorSetting(const string &name_h, int reg=WORLD) const
vector< pathRule * > getPathMortalityRule(const string &forType, const string &dC)
Return the pathogen mortality rule(s) associated with a given ft and dc (plural as more than a single...
string makeKeyProdData(const string &parName, const string &regId, const string &prod, const string &freeDim="") const
Definition ModelData.h:172
string makeKeyForData(const string &parName, const string &regId, const string &forType, const string &diamClass) const
Definition ModelData.h:173
void createRegions()
void setDefaultSettings()
int errorLevel
Definition ModelData.h:244
void setScenarioProdData()
void applyDebugMode()
Works only a specified subset of regions and products.
vector< forType > forTypes
Vector of forest types.
Definition ModelData.h:226
void setDefaultPathogenRules()
map< iisskey, double > deathTimberInventory
Map that register the death of biomass still usable as timber by year, l2_region, forest type and dia...
Definition ModelData.h:230
double getDoubleSetting(const string &name_h, int position=0, int reg=WORLD) const
void setScenarioPathogenRules()
vector< string > getForTypeIds(bool all=false)
By default it doesn't return forTypes used only as input.
vector< vector< int > > createCombinationsVector(const int &nItems)
Return a vector containing any possible combination of nItems items (including any possible subset)....
string getBaseData(const string &name_h, int type_h, int position=0, int regId_h=WORLD)
InputNode mainDocument
For each agricultural soil type (as defined in the setting "agrLandTypes") this list define the objec...
Definition ModelData.h:243
vector< int > getForTypeChilds_pos(const string &forTypeId_h, bool all=false)
void setDefaultProdData()
string getForTypeParentId(const string &forTypeId_h)
Definition ModelData.cpp:90
vector< string > getStringVectorSetting(const string &name_h, int reg=WORLD) const
bool delDir(QString dirname)
Recursivelly delete a directory.
vector< double > getDoubleVectorSetting(const string &name_h, int reg=WORLD) const
vector< string > getForTypeChilds(const string &forTypeId_h)
Definition ModelData.cpp:98
vector< string > priProducts
Definition ModelData.h:235
void setScenarioProductResourceMatrixLink()
void setReclassificationRules()
const int getMaxYearUsableDeathTimber()
const double getForData(const string &type_h, const int &regId_h, const string &forType_h, const string &freeDim_h, const int &year=DATA_NOW)
string baseDirectory
Definition ModelData.h:215
void setScenarioSettings()
vector< LLData > LLDataVector
Vector of Low Level Data.
Definition ModelData.h:223
scenarioData scenario
Definition ModelData.h:202
LLData getTableFromFile(string tablename, string filename_h)
Load and return a data table from a file (instead that from a spreadsheet sheet)
void setOutputDirectory(const char *output_dirname_h)
vector< int > getRegionIds(int level_h, bool excludeResidual=true)
ModelRegion * getRegion(int regId_h)
int getNForTypesChilds(const string &forTypeId_h)
vector< ModelRegion * > getAllRegions(bool excludeResidual=true)
void unpackKeyForData(const string &key, string &parName, int &regId, string &forType, string &diamClass) const
string getFilenameByType(string type_h)
void setForestTypes()
bool tempBool
a temporary bool variable used for various functions
Definition ModelData.h:239
int getIntSetting(const string &name_h, int position=0, int reg=WORLD) const
vector< string > getDiameterClasses(bool productionOnly=false)
void setDefaultProductResourceMatrixLink()
void applyOverrides()
Cancel all reg1 level data and trasform them in reg2 level if not already existing.
void setForData(const double &value_h, const string &type_h, const int &regId_h, const string &forType_h, const string &freeDim_h, const int &year=DATA_NOW, const bool &allowCreate=false)
vector< string > secProducts
Definition ModelData.h:236
void unpackKeyProdData(const string &key, string &parName, int &regId, string &prod, string &freeDim) const
void addSetting(string name_h, vector< string > values_h, int type_h, string comment_h)
double getTimedData(const vector< double > &dated_vector, const int &year_h) const
Return the value for the specified year in a timelly ordered vector, taking the last value if this is...
string getStringSetting(const string &name_h, int position=0, int reg=WORLD) const
bool valueFoundBool
a bool used in getForData() and getProdData() to communicate they didn't found a variable
Definition ModelData.h:240
string regId2RegSName(const int &regId_h) const
int regSName2RegId(const string &regSName_h) const
const bool assessProdPossibility(const string &prod_h, const string &forType_h, const string &dClass_h)
A simple function to assess if a specified product can be made by a certain forest type and diameter ...
void loadInput()
Unzip the OpenOffice input file (NEW 2008.05.13)
vector< reclRule > reclRules
Vector of reclassification rules.
Definition ModelData.h:227
vector< string > getVectorBaseData(const string &name_h, int type_h, int regId_h=WORLD)
map< string, vector< double > > prodDataMap
Product data.
Definition ModelData.h:218
const double getProdData(const string &type_h, const int &regId_h, const string &prodId_h, const int &year=DATA_NOW, const string &freeDim_h="")
int getScenarioIndex()
map< string, vector< double > > forDataMap
Forestry data.
Definition ModelData.h:217
int cached_initialYear
Definition ModelData.h:234
LLData getTable(string tableName_h, int debugLevel=MSG_CRITICAL_ERROR)
bool dataMapCheckExist(const DataMap &map, const string &search_for, const bool &exactMatch=true) const
int getFilenamesByDir(const string &dir, vector< string > &files, const string &filter="")
Return a list of files in a directory.
ModelData(ThreadManager *MTHREAD_h)
Definition ModelData.cpp:61
void setScenarioForData()
double calculateAnnualisedEquivalent(const double &amount_h, const int &years_h, const double &ir) const
Calculate the annual equivalent flow.
int dataMapSetValue(DataMap &map, const string &search_for, const double &value_h, const int &year_h, const bool &exactMatch=true)
vector< string > diamClasses
Diameter classes.
Definition ModelData.h:233
vector< forToProd > forToProdVector
Vector of coefficients from forest resources to primary products.
Definition ModelData.h:219
double getAvailableDeathTimber(const vector< string > &primProd_h, int regId_h, int year_h)
Returns the timber available for a given set of primary products as stored in the deathTimberInventor...
vector< BasicData > programSettingsVector
Setting data. Simple (struct)
Definition ModelData.h:222
vector< Pixel * > getMyPixels()
Definition ModelRegion.h:86
vector< ModelRegion * > getChildren(bool excludeResidual=true)
Returns a pointer to the parent regions.
string getRegSName() const
Definition ModelRegion.h:67
int getNChildren(bool excludeResidual=true)
Pixel-level class.
Definition Pixel.h:47
vector< double > avalCoef
Availability (of wood resources) coefficient. A [0,1] coefficient (new: by forest type) that reduces ...
Definition Pixel.h:148
vector< vector< double > > vol_l
store the volumes of the previous year
Definition Pixel.h:129
int getIteration()
Definition Scheduler.h:48
int getYear()
Definition Scheduler.h:49
Thread manager. Responsable to manage the main thread and "speak" with the GUI.
string getInputFileName()
string getBaseDirectory()
Scheduler * SCD
the scheduler object (simulation-loops scheduler)
string getScenarioName()
ModelData * MD
the model data object
void setOutputDirName(string outputDirname_h)
PKZip 2.0 file decompression. Compatibility with later versions is not ensured as they may use unsupp...
Definition unzip.h:46
void closeArchive()
Definition unzip.cpp:226
ErrorCode openArchive(const QString &filename)
Definition unzip.cpp:190
QString formatError(UnZip::ErrorCode c) const
Definition unzip.cpp:241
ErrorCode
Definition unzip.h:49
@ Ok
Definition unzip.h:50
ErrorCode extractAll(const QString &dirname, ExtractionOptions options=ExtractPaths)
Definition unzip.cpp:325
Class to provide a simple integer-integer-string-string key in std maps.
Definition BaseClass.h:213
Basic data units (struct)
Definition ModelData.h:267
string name
Definition ModelData.h:268
string comment
Definition ModelData.h:273
vector< string > values
Values are stored as "string" because we don't yet know at this point if they are string,...
Definition ModelData.h:270
IO production matrix between the forest resources and the primary products (struct)
Definition ModelData.h:280
string dClass
Definition ModelData.h:283
string product
Definition ModelData.h:281
int maxYears
The maximum year for a tree collapse that this product can be harvested from. E.g....
Definition ModelData.h:285
string forType
Definition ModelData.h:282
Forest types (struct)
Definition ModelData.h:293
string forTypeId
Definition ModelData.h:294
string forLayer
Definition ModelData.h:297
string ereditatedFrom
Definition ModelData.h:298
string forLabel
Definition ModelData.h:295
int memType
Definition ModelData.h:296
Pathogen rule (how pathogen presense influence mortality) for a given forest type and diameter class ...
Definition ModelData.h:318
string dClass
Definition ModelData.h:320
string forType
Definition ModelData.h:319
vector< double > mortCoefficents
Mortality coefficients ordered by number of presence of the pathogen, e.g. first value is the mortali...
Definition ModelData.h:323
double pres_min
Minimum level of presence of the pathogen to be counted as present (tolerance threshold)
Definition ModelData.h:322
string pathId
Pathogen id (name)
Definition ModelData.h:321
IO production matrix between the forest resources and the primary products (struct)
Definition ModelData.h:306
string forTypeOut
Definition ModelData.h:309
int regId
Definition ModelData.h:307
string forTypeIn
Definition ModelData.h:308
double coeff
Definition ModelData.h:310
string longDesc
Definition ModelData.h:63
string prodDataTable
Definition ModelData.h:66
string forDataTable
Definition ModelData.h:65
string settingFile
Definition ModelData.h:69
string forToProdTable
Definition ModelData.h:67
string pathTable
Definition ModelData.h:68
string settingTable
Definition ModelData.h:64
string shortDesc
Definition ModelData.h:62
string id
Definition ModelData.h:61