FFSM++ 1.1.0
French Forest Sector Model ++
Loading...
Searching...
No Matches
BaseClass.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#include <stdio.h>
23#include <algorithm>
24#include <numeric>
25
26#include "BaseClass.h"
27#include "ThreadManager.h"
28
29using namespace std;
30
32{
33 MTHREAD=NULL;
34}
35
40
41/**
42Overloaded method for the output log:
43
44@param msgCode_h: MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR, MSG_CRITICAL_ERROR
45@param msg_h: message text (string)
46@param refreshGUI_h: use this call to "ping" the GUI (optional, default=true)
47
48*/
49void
50BaseClass::msgOut(const int& msgCode_h, const string& msg_h, const bool& refreshGUI_h) const {
51
52 msgOut2(msgCode_h, msg_h, refreshGUI_h);
53
54}
55
56/**
57Overloaded method for the output log:
58
59@param msgCode_h: MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR, MSG_CRITICAL_ERROR
60@param msg_h: message text (int)
61@param refreshGUI_h: use this call to "ping" the GUI (optional, default=true)
62
63*/
64void
65BaseClass::msgOut(const int& msgCode_h, const int& msg_h, const bool& refreshGUI_h) const {
66 msgOut2(msgCode_h, i2s(msg_h), refreshGUI_h);
67}
68
69/**
70Overloaded method for the output log:
71
72@param msgCode_h: MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR, MSG_CRITICAL_ERROR
73@param msg_h: message text (double)
74@param refreshGUI_h: use this call to "ping" the GUI (optional, default=true)
75
76*/
77void
78BaseClass::msgOut(const int& msgCode_h, const double& msg_h, const bool& refreshGUI_h) const {
79 msgOut2(msgCode_h, d2s(msg_h), refreshGUI_h);
80
81}
82
83/**
84Convenient (private) function to actually do the job of the overloaded functions
85
86*/
87void
88BaseClass::msgOut2(const int& msgCode_h, const string& msg_h, const bool& refreshGUI_h) const {
89
90 string prefix;
91 switch (msgCode_h){
92 case MSG_NO_MSG:
93 return;
94 case MSG_DEBUG:
95 prefix="*DEBUG: ";
96 break;
97 case MSG_INFO:
98 prefix="**INFO: ";
99 break;
100 case MSG_WARNING:
101 prefix="**WARNING: ";
102 break;
103 case MSG_ERROR:
104 prefix="***ERROR: ";
105 break;
107 prefix="****CRITICAL ERROR: ";
108 break;
109 default:
110 cerr<<"I got an unknow error code: "<<msgCode_h<<" ("<<msg_h<<")"<<endl;
111 exit(EXIT_FAILURE);
112 }
113
114 string message = prefix+msg_h;
115 if (MTHREAD && MTHREAD->usingGUI()){
116 MTHREAD->msgOut(msgCode_h, message);
117 }
118 else {
119 string totalMsg = prefix+msg_h;
120 cout<< totalMsg <<endl;
121 }
122
123 if(refreshGUI_h) {refreshGUI();}
124
125 //if(msgCode_h==MSG_CRITICAL_ERROR){
126 // if (MTHREAD && MTHREAD->usingGUI()){
127 // throw(2);
128 // }
129 // else {
130 // throw(2);
131 // exit(EXIT_FAILURE);
132 // }
133 //}
134
135 if(msgCode_h==MSG_CRITICAL_ERROR){ // I can't throw an exception for any case, as code would resume from where it has been caught, not from here..
136 throw(msgCode_h);
137 }
138
139}
140
141void
143 if (MTHREAD && MTHREAD->usingGUI()){
145 }
146}
147
148int
149BaseClass::s2i ( const string &string_h) const {
150 if (string_h == "") return 0;
151 int valueAsInteger;
152 stringstream ss(string_h);
153 ss >> valueAsInteger;
154 return valueAsInteger;
155 /*
156 // I can't use stoi as of bug in MinGW
157 try {
158 return stoi(string_h);
159 } catch (...) {
160 if (string_h == "") return 0;
161 else {
162 msgOut(MSG_CRITICAL_ERROR,"Conversion string to integer failed. Some problems with the data? (got\""+string_h+"\")");
163 }
164 }
165 return 0;
166 */
167
168}
169
170double
171BaseClass::s2d (const string& string_h) const {
172 if (string_h == "") return 0.;
173 double valueAsDouble;
174 istringstream totalSString( string_h );
175 totalSString >> valueAsDouble;
176 return valueAsDouble;
177 /*
178 if (string_h == "") return 0.;
179 try {
180 return stod(string_h); // stod want dot as decimal separator in console mode and comma in gui mode. Further the decimal digits left are only 2 !!
181 } catch (...) {
182 if (string_h == "") return 0.;
183 else {
184 msgOut(MSG_CRITICAL_ERROR,"Conversion string to double failed. Some problems with the data? (got\""+string_h+"\")");
185 }
186 }
187 return 0.;
188 */
189}
190
191
192/// Includes comma to dot conversion if needed.
193double
194BaseClass::s2d (const string& string_h, const bool& replaceComma) const {
195 if(replaceComma){
196 string valueAsString = string_h;
197 // replace commas with dots. This is not needed when directly reading the input nodes as double, as the Qt function to Double does the same.
198 replace(valueAsString.begin(), valueAsString.end(), ',', '.');
199 return s2d(valueAsString);
200 }
201 return s2d(string_h);
202 msgOut(MSG_CRITICAL_ERROR, "debug me please!");
203 return 0.;
204}
205
206/// Includes conversion checks.
207bool
208BaseClass::s2b (const string& string_h) const {
209 if (string_h == "true" || string_h == "vero" || string_h == "TRUE" || string_h == "VRAI" || string_h == "1" || string_h == "True")
210 return true;
211 else if (string_h == "false" || string_h == "falso" || string_h == "FALSE" || string_h == "FAUX" || string_h == "0" || string_h == "" || string_h == "False")
212 return false;
213
214 msgOut(MSG_CRITICAL_ERROR,"Conversion string to bool failed. Some problems with the data? (got\""+string_h+"\")");
215 return true;
216}
217
218string
219BaseClass::i2s (const int& int_h) const{
220 //ostringstream out;
221 //out<<int_h;
222 //return out.str();
223 char outChar[24];
224 snprintf ( outChar, sizeof(outChar), "%d", int_h );
225 return string(outChar);
226}
227
228string
229BaseClass::d2s (const double& double_h) const{
230 //ostringstream out;
231 //out<<double_h;
232 //return out.str();
233 char outChar[24];
234 snprintf ( outChar, sizeof(outChar), "%f", double_h );
235 return string(outChar);
236}
237
238string
239BaseClass::b2s (const bool& bool_h) const{
240 if (bool_h) return "true";
241 else return "false";
242}
243
244vector <int>
245BaseClass::s2i(const vector <string>& string_h) const{
246 vector <int> valuesAsInteger;
247 for (uint i=0;i<string_h.size();i++){
248 valuesAsInteger.push_back(s2i(string_h[i]));
249 }
250 return valuesAsInteger;
251}
252
253/// Includes comma to dot conversion if needed.
254vector <double>
255BaseClass::s2d (const vector <string>& string_h, const bool& replaceComma) const{
256 vector <double> valuesAsDouble;
257 for (uint i=0;i<string_h.size();i++){
258 if(replaceComma){
259 string valueAsString = string_h[i];
260 // replace commas with dots. This is not needed when directly reading the input nodes as double, as the Qt function to Double does the same.
261 replace(valueAsString.begin(), valueAsString.end(), ',', '.');
262 valuesAsDouble.push_back(s2d(valueAsString));
263 } else {
264 valuesAsDouble.push_back(s2d(string_h[i]));
265 }
266 }
267 return valuesAsDouble;
268}
269
270/// Includes conversion checks.
271vector <bool>
272BaseClass::s2b(const vector <string> &string_h) const{
273 vector <bool> valuesAsBool;
274 for (uint i=0;i<string_h.size();i++){
275 valuesAsBool.push_back(s2b(string_h[i]));
276 }
277 return valuesAsBool;
278}
279
280vector <string>
281BaseClass::i2s (const vector <int> &int_h) const{
282 vector <string> valuesAsString;
283 for (uint i=0;i<int_h.size();i++){
284 valuesAsString.push_back(i2s(int_h[i]));
285 }
286 return valuesAsString;
287}
288
289vector <string>
290BaseClass::d2s (const vector <double> &double_h) const{
291 vector <string> valuesAsString;
292 for (uint i=0;i<double_h.size();i++){
293 valuesAsString.push_back(d2s(double_h[i]));
294 }
295 return valuesAsString;
296}
297
298vector <string>
299BaseClass::b2s (const vector <bool> &bool_h) const{
300 vector <string> valuesAsString;
301 for (uint i=0;i<bool_h.size();i++){
302 if(bool_h[i]) valuesAsString.push_back("true");
303 else valuesAsString.push_back("false");
304 }
305 return valuesAsString;
306}
307
308
309int
310BaseClass::getType(const string &type_h) const{
311 int toReturn=0;
312 if (type_h == "int") toReturn = TYPE_INT;
313 else if (type_h == "double") toReturn = TYPE_DOUBLE;
314 else if (type_h == "string") toReturn = TYPE_STRING;
315 else if (type_h == "bool") toReturn = TYPE_BOOL;
316 else msgOut(MSG_CRITICAL_ERROR, "Unknow type "+type_h+".");
317 return toReturn;
318}
319
320
321template<typename T> std::string
322BaseClass::toString(const T& x) const {
323 std::ostringstream oss;
324 oss << x;
325 return oss.str();
326}
327
328
329double
330BaseClass::normSample (const double& avg, const double& stdev, const double& minval, const double& maxval) const{
331 if(minval != NULL && maxval != NULL){
332 if (maxval <= minval){
333 msgOut(MSG_CRITICAL_ERROR,"Error in normSample: the maxvalue is lower than the minvalue");
334 }
335 }
336 for(;;){
337 normal_distribution<double> d(avg,stdev);
338 double c = d(*MTHREAD->gen);
339 if( (minval == NULL || c >= minval) && (maxval == NULL || c <= maxval) ){
340 return c;
341 }
342 }
343 return minval;
344}
345
346
347template<typename T> T
348BaseClass::stringTo(const std::string& s) const {
349 std::istringstream iss(s);
350 T x;
351 iss >> x;
352 return x;
353}
354
355int
356BaseClass::vSum (const vector <vector<int> > &vector_h) const{
357 int toReturn = 0;
358 for(vector < vector<int> >::const_iterator j=vector_h.begin();j!=vector_h.end();++j){
359 toReturn += accumulate(j->begin(),j->end(),0);
360 }
361 return toReturn;
362}
363
364double
365BaseClass::vSum (const vector<vector<double> > &vector_h) const{
366 double toReturn = 0.0;
367 for(vector < vector<double> >::const_iterator j=vector_h.begin();j!=vector_h.end();++j){
368 toReturn += accumulate(j->begin(),j->end(),0.0);
369 }
370 return toReturn;
371}
372
373void
374BaseClass::tokenize(const string& str, vector<string>& tokens, const string& delimiter) const {
375 // Skip delimiters at beginning.
376 string::size_type lastPos = str.find_first_not_of(delimiter, 0);
377 // Find first "non-delimiter".
378 string::size_type pos = str.find_first_of(delimiter, lastPos);
379
380 while (string::npos != pos || string::npos != lastPos)
381 {
382 // Found a token, add it to the vector.
383 tokens.push_back(str.substr(lastPos, pos - lastPos));
384 // Skip delimiters. Note the "not_of"
385 lastPos = str.find_first_not_of(delimiter, pos);
386 // Find next "non-delimiter"
387 pos = str.find_first_of(delimiter, lastPos);
388 }
389}
390
391void
392BaseClass::untokenize(string &str, vector<string>& tokens, const string& delimiter) const {
393 // add initial loken in str is not empty
394 if(str != ""){
395 str += delimiter;
396 }
397 for(int i=0;i<tokens.size();i++){
398 str += tokens[i];
399 // don't add final delimiter
400 if(i != (tokens.size()-1)){
401 str += delimiter;
402 }
403 }
404}
405
406///////////////////////////////////// OTHER CLASSES THAN BASECLASS //////////////////
407/// iskey class ///
409 i = 0;
410 s = "";
411}
412iskey::iskey(int i_h, string s_h){
413 i = i_h;
414 s = s_h;
415}
416
418
419}
420
421bool
422iskey::operator == (const iskey & op2) const{
423 if(op2.i == i && op2.s == s){
424 return true;
425 }
426 return false;
427}
428
429bool
430iskey::operator != (const iskey & op2) const{
431 if(op2.i == i && op2.s == s){
432 return false;
433 }
434 return true;
435}
436
437bool
438iskey::operator < (const iskey & op2) const{
439 if (i < op2.i ) return true;
440 if (i == op2.i) {
441 if (s < op2.s) return true;
442 }
443 return false;
444}
445
446bool
447iskey::operator > (const iskey & op2) const{
448 if (i > op2.i ) return true;
449 if (i == op2.i) {
450 if (s > op2.s) return true;
451 }
452 return false;
453}
454
455bool
456iskey::operator <= (const iskey & op2) const{
457 if (i < op2.i ) return true;
458 if (i == op2.i) {
459 if (s <= op2.s) return true;
460 }
461 return false;
462}
463
464bool
465iskey::operator >= (const iskey & op2) const{
466 if (i > op2.i ) return true;
467 if (i == op2.i) {
468 if (s >= op2.s) return true;
469 }
470 return false;
471}
472
473/// iiskey class (note the double ii) ///
475 i = 0;
476 i2 = 0;
477 s = "";
478}
479iiskey::iiskey(int i_h, int i2_h, string s_h){
480 i = i_h;
481 i2 = i2_h;
482 s = s_h;
483}
484
486
487}
488
489bool
490iiskey::operator == (const iiskey & op2) const{
491 if(op2.i == i && op2.i2 == i2 && op2.s == s){
492 return true;
493 }
494 return false;
495}
496
497bool
498iiskey::operator != (const iiskey & op2) const{
499 if(op2.i == i && op2.i2 == i2 && op2.s == s){
500 return false;
501 }
502 return true;
503}
504
505bool
506iiskey::operator < (const iiskey & op2) const{
507 if (i < op2.i ) {return true;}
508 if (i == op2.i) {
509 if (i2 < op2.i2 ) {return true;}
510 if (i2 == op2.i2){
511 if (s < op2.s) {return true;}
512 }
513 }
514 return false;
515}
516
517bool
518iiskey::operator > (const iiskey & op2) const{
519 if (i > op2.i ) {return true;}
520 if (i == op2.i) {
521 if (i2 > op2.i2 ) {return true;}
522 if (i2 == op2.i2){
523 if (s > op2.s) {return true;}
524 }
525 }
526 return false;
527}
528
529bool
530iiskey::operator <= (const iiskey & op2) const{
531 if (i < op2.i ) {return true;}
532 if (i == op2.i) {
533 if (i2 < op2.i2 ) {return true;}
534 if (i2 == op2.i2){
535 if (s <= op2.s) {return true;}
536 }
537 }
538 return false;
539}
540
541bool
542iiskey::operator >= (const iiskey & op2) const{
543 if (i > op2.i ) {return true;}
544 if (i == op2.i) {
545 if (i2 > op2.i2 ) {return true;}
546 if (i2 == op2.i2){
547 if (s >= op2.s) {return true;}
548 }
549 }
550 return false;
551}
552
553/// iisskey class (note the double ii and double ss) ///
555 i = 0;
556 i2 = 0;
557 s = "";
558 s2= "";
559}
560iisskey::iisskey(int i_h, int i2_h, string s_h, string s2_h){
561 i = i_h;
562 i2 = i2_h;
563 s = s_h;
564 s2 = s2_h;
565}
566
570
571bool
573 if(op2.i == i && op2.i2 == i2 && op2.s == s && op2.s2 == s2){
574 return true;
575 }
576 return false;
577}
578
579bool
581 if(op2.i == i && op2.i2 == i2 && op2.s == s && op2.s2 == s2){
582 return false;
583 }
584 return true;
585}
586
587bool
588iisskey::operator < (const iisskey & op2) const{
589 if (i < op2.i ) {return true;}
590 if (i == op2.i) {
591 if (i2 < op2.i2 ) {return true;}
592 if (i2 == op2.i2){
593 if (s < op2.s) {return true;}
594 if (s == op2.s){
595 if (s2 < op2.s2) {return true;}
596 }
597 }
598 }
599 return false;
600}
601
602bool
603iisskey::operator > (const iisskey & op2) const{
604 if (i > op2.i ) {return true;}
605 if (i == op2.i) {
606 if (i2 > op2.i2 ) {return true;}
607 if (i2 == op2.i2){
608 if (s > op2.s) {return true;}
609 if (s == op2.s){
610 if (s2 > op2.s2) {return true;}
611 }
612 }
613 }
614 return false;
615}
616
617bool
618iisskey::operator <= (const iisskey & op2) const{
619 if (i < op2.i ) {return true;}
620 if (i == op2.i) {
621 if (i2 < op2.i2 ) {return true;}
622 if (i2 == op2.i2){
623 if (s < op2.s) {return true;}
624 if (s == op2.s){
625 if (s2 <= op2.s2) {return true;}
626 }
627 }
628 }
629 return false;
630}
631
632bool
634 if (i > op2.i ) {return true;}
635 if (i == op2.i) {
636 if (i2 > op2.i2 ) {return true;}
637 if (i2 == op2.i2){
638 if (s > op2.s) {return true;}
639 if (s == op2.s){
640 if (s2 >= op2.s2) {return true;}
641 }
642 }
643 }
644 return false;
645}
646
647bool
648iisskey::filter(const iisskey & key_h) const{
649 if( (key_h.i == NULL || key_h.i==i) &&
650 (key_h.i2 == NULL || key_h.i2==i2) &&
651 (key_h.s == "" || key_h.s==s) &&
652 (key_h.s2 == "" || key_h.s2==s2) ) return true;
653 return false;
654}
655
656string
658 char outChar1[24];
659 char outChar2[24];
660 snprintf ( outChar1, sizeof(outChar1), "%d", i);
661 snprintf ( outChar2, sizeof(outChar2), "%d", i2);
662 return string(outChar1)+'\t'+string(outChar2)+'\t'+s+'\t'+s2;
663
664}
This file is the header of BaseClass and it is included by ALL compiled code.
@ 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
@ 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
ThreadManager * MTHREAD
Pointer to the Thread manager.
Definition BaseClass.h:467
string b2s(const bool &bool_h) const
bool to string conversion
int s2i(const string &string_h) const
string to integer conversion
void untokenize(string &str, vector< string > &tokens, const string &delimiter=" ") const
int vSum(const vector< int > &vector_h) const
Definition BaseClass.h:276
void tokenize(const string &str, vector< string > &tokens, const string &delimiter=" ") const
Tokenize a string using a delimiter (default is space)
string d2s(const double &double_h) const
double to string conversion
T stringTo(const std::string &s) const
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
double normSample(const double &avg, const double &stdev, const double &minval=NULL, const double &maxval=NULL) const
Sample from a normal distribution with bounds. Slower (double time, but still you see the diff only a...
void refreshGUI() const
Ping to periodically return the control to the GUI.
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
vector< double > s2d(const vector< string > &string_h, const bool &replaceComma=false) const
string to double conversion (vector)
double s2d(const string &string_h) const
string to double conversion
void msgOut2(const int &msgCode_h, const string &msg_h, const bool &refreshGUI_h) const
Do the job of the overloaded functions.
Definition BaseClass.cpp:88
string toString(const T &x) const
void msgOut(const int msgCode_h, const string message_h)
std::mt19937 * gen
used in the sampling from normal distribution
Class to provide a simple integer-integer-string key in std maps.
Definition BaseClass.h:195
string s
Definition BaseClass.h:208
iiskey()
iiskey class (note the double ii) ///
bool operator>(const iiskey &op2) const
int i2
Definition BaseClass.h:207
bool operator>=(const iiskey &op2) const
bool operator<(const iiskey &op2) const
bool operator==(const iiskey &op2) const
bool operator!=(const iiskey &op2) const
bool operator<=(const iiskey &op2) const
int i
Definition BaseClass.h:206
Class to provide a simple integer-integer-string-string key in std maps.
Definition BaseClass.h:213
string print() const
string s
Definition BaseClass.h:228
iisskey()
iisskey class (note the double ii and double ss) ///
bool filter(const iisskey &key_h) const
bool operator>=(const iisskey &op2) const
bool operator==(const iisskey &op2) const
bool operator<(const iisskey &op2) const
bool operator>(const iisskey &op2) const
string s2
Definition BaseClass.h:229
bool operator<=(const iisskey &op2) const
bool operator!=(const iisskey &op2) const
Class to provide a simple integer-string key to be used in std maps.
Definition BaseClass.h:179
string s
Definition BaseClass.h:191
bool operator==(const iskey &op2) const
bool operator<(const iskey &op2) const
bool operator!=(const iskey &op2) const
bool operator>(const iskey &op2) const
bool operator>=(const iskey &op2) const
int i
Definition BaseClass.h:190
bool operator<=(const iskey &op2) const