Mechanics of Defect Evolution Library
Loading...
Searching...
No Matches
TextFileParser.h
Go to the documentation of this file.
1/* This file is part of MoDELib, the Mechanics Of Defects Evolution Library.
2 *
3 *
4 * MoDELib is distributed without any warranty under the
5 * GNU General Public License (GPL) v2 <http://www.gnu.org/licenses/>.
6 */
7
8#ifndef model_TextFileParser_H_
9#define model_TextFileParser_H_
10
11//#include <filesystem>
12#include <iostream>
13#include <iomanip>
14#include <string>
15#include <fstream>
16#include <regex>
17#include <vector>
18#include <set>
19#include <map>
20#include <regex>
21
22#include <StrUtilities.h>
23#include <Eigen/Dense>
24
25#include <TerminalColors.h>
26
27namespace model
28{
29
30template<typename T>
32{
33
34 static T toScalar(const std::string& key)
35 {
36 throw std::runtime_error("Unknown conversion from std::string "+key+" to "+typeid(T).name()+".");
37 }
38};
39
40template<>
41struct StringToScalar<int>
42{
43
44 static int toScalar(const std::string& str)
45 {
46 return std::atoi(str.c_str());
47 }
48};
49
50template<>
51struct StringToScalar<long>
52{
53
54 static long toScalar(const std::string& str)
55 {
56 return std::atol(str.c_str());
57 }
58};
59
60template<>
61struct StringToScalar<long long>
62{
63
64 static long long toScalar(const std::string& str)
65 {
66 return std::atoll(str.c_str());
67 }
68};
69
70template<>
71struct StringToScalar<unsigned long>
72{
73
74 static unsigned long toScalar(const std::string& str)
75 {
76 return std::stoul(str.c_str());
77 }
78};
79
80template<>
81struct StringToScalar<unsigned long long>
82{
83
84 static unsigned long long toScalar(const std::string& str)
85 {
86 return std::stoull(str.c_str());
87 }
88};
89
90template<>
91struct StringToScalar<float>
92{
93
94 static float toScalar(const std::string& str)
95 {
96 return std::stof(str.c_str());
97 }
98};
99
100template<>
101struct StringToScalar<double>
102{
103
104 static double toScalar(const std::string& str)
105 {
106 return std::stod(str.c_str());
107 }
108};
109
110
111template<>
112struct StringToScalar<long double>
113{
114
115 static long double toScalar(const std::string& str)
116 {
117 return std::stold(str.c_str());
118 }
119};
120
121
122class TextFileParser : public std::ifstream
123{
124
125 template <typename Scalar>
126 using EigenMapType=Eigen::Map<const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>, 0, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> >;
127
128 std::vector<std::pair<std::string,std::string>> readKey( const std::string& key)
129 {
130 this->clear();
131 this->seekg(0);
132 std::vector<std::pair<std::string,std::string>> returnVector;
133 std::string line;
134
135 while (std::getline(*this, line))
136 {
137 const size_t foundKey=line.find(key);
138 const size_t foundEqual=line.find("=");
139
140 if( foundKey!=std::string::npos
141 && foundEqual!=std::string::npos
142 && foundKey<foundEqual)
143 {
144 const std::string keyRead(StrUtilities::removeSpaces(line.substr(0,foundEqual)));
145
146 if(keyRead==key)
147 {
148
149
150 const size_t foundSemiCol=line.find(";");
151 const size_t foundPound=line.find("#");
152
153 if( //foundKey!=std::string::npos
154 foundEqual!=std::string::npos
155 && foundSemiCol!=std::string::npos
156 //&& foundKey<foundEqual
157 && foundEqual<foundSemiCol
158 && foundSemiCol<foundPound
159 )
160 {
161 const std::string read(line.substr(foundEqual+1,foundSemiCol-foundEqual-1));
162
163 if(foundPound!=std::string::npos)
164 {
165 const std::string comment(line.substr(foundPound,line.size()-foundPound));
166 returnVector.emplace_back(read,comment);
167 }
168 else
169 {
170 returnVector.emplace_back(read,std::string());
171 }
172 }
173 }
174 }
175 }
176 return returnVector;
177 }
178
179
180public:
181
182 const std::string fileName;
183
184 /**********************************************************************/
185 TextFileParser(const std::string& _fileName) :
186 /* init */ std::ifstream(_fileName)
187 /* init */,fileName(_fileName)
188 {
189 if(!this->is_open())
190 {
191 throw std::runtime_error("File "+fileName+" cannot be opened.");
192 }
193 }
194
195// static std::string StrUtilities::removeSpaces(std::string key)
196// {
197// key.erase(std::remove_if(key.begin(), key.end(), [](unsigned char x) { return std::isspace(x); }), key.end());
198// return key;
199// }
200
201 /**********************************************************************/
202 std::string readString(const std::string& key,const bool&verbose=false)
203 {
204 const auto strPair(readKey(key));
205 if(strPair.size())
206 {
207 if(verbose) std::cout<<cyanColor<<key<<"="<<strPair[0].first<<" "<<strPair[0].second<<defaultColor<<std::endl;
208 return strPair[0].first;
209 }
210 else
211 {
212 throw std::runtime_error("File "+fileName+" does not cointain line with format "+key+"=...;");
213 return std::string();
214 }
215 }
216
217 /**********************************************************************/
218 std::vector<std::pair<std::string,std::string>> readStringVector(const std::string& key)
219 {
220 return readKey(key);
221 }
222
223 std::set<std::string> readStringSet(const std::string& key,const bool&verbose=false)
224 {
225 const std::string valStr(readString(key,verbose));
226 std::stringstream ss(valStr);
227 std::string tempVal;
228 std::set<std::string> tempS;
229 while (ss >> tempVal)
230 {
231 tempS.insert(tempVal);
232 }
233 return tempS;
234 }
235
236 /**********************************************************************/
237 template<typename Scalar>
238 Scalar readScalar(const std::string& key,const bool&verbose=false)
239 {
240 const auto strPair(readKey(key));
241 if(strPair.size())
242 {
243 if(verbose) std::cout<<cyanColor<<key<<"="<<std::flush;
244 const Scalar read(StringToScalar<Scalar>::toScalar(strPair[0].first));
245 if(verbose) std::cout<<read<<" "<<strPair[0].second<<defaultColor<<std::endl;
246 return read;
247 }
248 else
249 {
250 throw std::runtime_error("File "+fileName+" does not cointain line with format "+key+"=...;");
251 return Scalar();
252 }
253// if(verbose) std::cout<<cyanColor<<key<<"="<<std::flush;
254// const Scalar read(StringToScalar<Scalar>::toScalar(strPair.first));
255// if(verbose) std::cout<<read<<" "<<strPair.second<<defaultColor<<std::endl;
256// return read;
257 }
258
259 /**********************************************************************/
260 template<typename Scalar>
261 std::set<Scalar> readSet(const std::string& key,const bool&verbose=false)
262 {
263 std::vector<Scalar> tempV(readArray<Scalar>(key,false));
264 std::set<Scalar> tempS;
265 for(const auto& val : tempV)
266 {
267 tempS.insert(val);
268 }
269 if(verbose)
270 {
271 std::cout<<cyanColor<<key<<"=";
272 for(const auto& val : tempS)
273 {
274 std::cout<<" "<<val;
275 }
276 std::cout<<"; "<<defaultColor<<std::endl;
277 }
278 return tempS;
279 }
280
281 template<typename KeyType,typename Scalar>
282 std::tuple<bool,bool,KeyType,std::vector<Scalar>,std::string> splitMapLine(const std::string& line) const
283 {
284 std::tuple<bool,bool,KeyType,std::vector<Scalar>,std::string> temp(std::make_tuple(false,false,KeyType(),std::vector<Scalar>(),std::string()));
285
286 const size_t foundCol=line.find(":");
287 const size_t foundSemiCol=line.find(";");
288 const size_t foundPound=line.find("#");
289
290 if(foundCol!=std::string::npos
291 && (foundPound==std::string::npos || foundPound>foundSemiCol))
292 {
293 std::get<0>(temp)=true; // valid line
294 std::get<1>(temp)=(foundPound!=std::string::npos); // has semicolumn
295 std::get<2>(temp)=StringToScalar<KeyType>::toScalar(StrUtilities::removeSpaces(line.substr(0,foundCol)));
296
297 const std::string valStr(foundSemiCol==std::string::npos? line.substr(foundCol+1,line.size()-foundCol-1) : line.substr(foundCol+1,foundSemiCol-foundCol-1));
298 Scalar tempVal;
299 std::stringstream ss(valStr);
300 while (ss >> tempVal)
301 {
302 std::get<3>(temp).push_back(tempVal);
303 }
304 if(foundPound!=std::string::npos)
305 {
306 std::get<4>(temp)=line.substr(foundPound+1,line.size()-foundPound-1);
307 }
308 }
309 return temp;
310 }
311
312 /**********************************************************************/
313 template<typename KeyType,typename Scalar>
314 std::map<KeyType,std::vector<Scalar>> readArrayMap(const std::string& key,const bool&verbose=false)
315 {
316 this->clear();
317 this->seekg(0);
318
319 std::string line;
320 bool success=false;
321 std::map<KeyType,std::vector<Scalar>> temp;
322
323 while (std::getline(*this, line) || !success)
324 {
325
326 const size_t foundKey=line.find(key);
327 const size_t foundEqual=line.find("=");
328
329 const std::string keyRead(StrUtilities::removeSpaces(line.substr(0,foundEqual)));
330
331 if(keyRead==key
332 && foundKey!=std::string::npos
333 && foundEqual!=std::string::npos
334 && foundKey<foundEqual)
335 {
336
337 success=true;
338 auto tup(splitMapLine<KeyType,Scalar>(line.substr(foundEqual+1,line.size()-foundEqual-1)));
339 if(std::get<0>(tup))
340 {// valid line
341 temp.emplace(std::get<2>(tup),std::get<3>(tup));
342 }
343
344 if(std::get<1>(tup))
345 {// semi column found
346 break;
347 }
348 else
349 {// read following lines
350 while(std::getline(*this, line))
351 {
353
354 if(std::get<0>(tup))
355 {// valid line
356 temp.emplace(std::get<2>(tup),std::get<3>(tup));
357 }
358
359 if(std::get<1>(tup))
360 {// semi column found
361 break;
362 }
363 }
364 }
365
366 }
367 }
368
369 if(!success)
370 {
371 throw std::runtime_error("File "+fileName+" does not cointain line with format "+key+"=...;");
372 }
373
374 if(verbose)
375 {
376 std::cout<<cyanColor<<key<<"="<<std::endl;
377 for(const auto& pair : temp)
378 {
379 std::cout<<pair.first<<" : ";
380 for(const auto& val : pair.second)
381 {
382 std::cout<<val<<" ";
383 }
384 std::cout<<std::endl;
385 }
386// std::cout<<"; "<<comment<<defaultColor<<std::endl;
387
388 }
389
390 return temp;
391 }
392
393 /**********************************************************************/
394 template<typename Scalar>
395 std::vector<Scalar> readArray(const std::string& key,const bool&verbose=false)
396 {
397 this->clear();
398 this->seekg(0);
399
400 std::string line;
401 std::string lines;
402 std::string comment;
403 std::vector<Scalar> array;
404 bool success=false;
405
406 while (std::getline(*this, line))
407 {
408
409 const size_t foundKey=line.find(key);
410 const size_t foundEqual=line.find("=");
411
412 const std::string keyRead(StrUtilities::removeSpaces(line.substr(0,foundEqual)));
413
414 if(keyRead==key)
415 {
416 size_t foundSemiCol=line.find(";");
417 size_t foundPound=line.find("#");
418
419 if( foundKey!=std::string::npos
420 && foundEqual!=std::string::npos
421 && foundKey<foundEqual
422 && (foundPound==std::string::npos || foundPound>foundSemiCol)
423 )
424 {
425 lines+=line;
426 foundSemiCol=line.find(";");
427
428 if( foundSemiCol!=std::string::npos
429 && foundEqual<foundSemiCol)
430 {
431 success=true;
432 }
433 else
434 {
435 while(std::getline(*this, line))
436 {
437 lines+=(" "+line);
438 foundSemiCol=lines.find(";");
439 if(foundSemiCol!=std::string::npos && foundEqual<foundSemiCol)
440 {
441 success=true;
442 break;
443 }
444 }
445 }
446
447 if(success)
448 {
449 foundPound=line.find("#");
450 if(foundPound!=std::string::npos)
451 {
452 comment=lines.substr(foundPound,lines.size()-foundPound);
453 }
454
455
456 Scalar temp;
457 std::stringstream ss(lines.substr(foundEqual+1,foundSemiCol-foundEqual-1));
458 while (ss >> temp)
459 {
460 array.push_back(temp);
461 }
462 break;
463 }
464 }
465 }
466 }
467
468 if(!success)
469 {
470 throw std::runtime_error("File "+fileName+" does not cointain line with format "+key+"=...;");
471 }
472
473 if(verbose)
474 {
475 std::cout<<cyanColor<<key<<"=";
476 for(const auto& val : array)
477 {
478 std::cout<<" "<<val;
479 }
480 std::cout<<"; "<<comment<<defaultColor<<std::endl;
481 }
482
483 return array;
484 }
485
486 /**********************************************************************/
487 template<typename Scalar>
488 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> readMatrix(const std::string& key,const size_t& rows,const size_t& cols,const bool&verbose=false)
489 {
490
491 const std::vector<Scalar> array=readArray<Scalar>(key,false);
492 if(array.size()!=rows*cols)
493 {
494 throw std::runtime_error("Error in reading matrix "+key+": array.size="+std::to_string(array.size())+" is not equal to rows x cols ("+std::to_string(rows)+"x"+std::to_string(cols)+").");
495 // std::cout<<"Error in reading matrix "<<key<<std::endl;
496 // std::cout<<"array.size="<<array.size()<<", is not equal to rows x cols ("<<rows<<"x"<<cols<<"). EXITING"<<std::endl;
497 // exit(EXIT_FAILURE);
498 }
499
500 EigenMapType<Scalar> em(array.data(), rows, cols, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(1, cols));
501 if(verbose) std::cout<<cyanColor<<key<<"=\n"<<em<<defaultColor<<std::endl;
502 return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(em);
503 }
504
505 /**********************************************************************/
506 template<typename Scalar,int rows,int cols>
507 Eigen::Matrix<Scalar,rows,cols> readMatrix(const std::string& key,const bool&verbose=false)
508 {
509 return readMatrix<Scalar>(key,rows,cols,verbose);
510 }
511
512 /**********************************************************************/
513 template<typename Scalar>
514 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> readMatrixCols(const std::string& key,const size_t& cols,const bool&verbose=false)
515 {
516
517 const std::vector<Scalar> array=readArray<Scalar>(key,false);
518 if(array.size()%cols!=0)
519 {
520 throw std::runtime_error("Error in reading matrix "+key+": array.size="+std::to_string(array.size())+" is not a multiple of cols ("+std::to_string(cols)+").");
521 }
522 const size_t rows(array.size()/cols);
523 EigenMapType<Scalar> em(array.data(), rows, cols, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(1, cols));
524 if(verbose) std::cout<<cyanColor<<key<<"=\n"<<em<<defaultColor<<std::endl;
525 return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(em);
526 }
527
528 /**********************************************************************/
529 template<typename Scalar>
530 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> readMatrixRows(const std::string& key,const size_t& rows,const bool&verbose=false)
531 {
532
533 const std::vector<Scalar> array=readArray<Scalar>(key,false);
534 if(array.size()%rows!=0)
535 {
536 throw std::runtime_error("Error in reading matrix "+key+": array.size="+std::to_string(array.size())+" is not a multiple of rows ("+std::to_string(rows)+").");
537 }
538 const size_t cols(array.size()/rows);
539 EigenMapType<Scalar> em(array.data(), rows, cols, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(1, cols));
540 if(verbose) std::cout<<cyanColor<<key<<"=\n"<<em<<defaultColor<<std::endl;
541 return Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>(em);
542 }
543
544};
545
546}
547#endif
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > readMatrixCols(const std::string &key, const size_t &cols, const bool &verbose=false)
TextFileParser(const std::string &_fileName)
std::vector< std::pair< std::string, std::string > > readStringVector(const std::string &key)
std::map< KeyType, std::vector< Scalar > > readArrayMap(const std::string &key, const bool &verbose=false)
const std::string fileName
std::vector< Scalar > readArray(const std::string &key, const bool &verbose=false)
std::string readString(const std::string &key, const bool &verbose=false)
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > readMatrix(const std::string &key, const size_t &rows, const size_t &cols, const bool &verbose=false)
Scalar readScalar(const std::string &key, const bool &verbose=false)
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > readMatrixRows(const std::string &key, const size_t &rows, const bool &verbose=false)
std::tuple< bool, bool, KeyType, std::vector< Scalar >, std::string > splitMapLine(const std::string &line) const
std::set< std::string > readStringSet(const std::string &key, const bool &verbose=false)
std::set< Scalar > readSet(const std::string &key, const bool &verbose=false)
Eigen::Matrix< Scalar, rows, cols > readMatrix(const std::string &key, const bool &verbose=false)
static std::string cyanColor
static std::string defaultColor
static std::string removeSpaces(std::string key)
static double toScalar(const std::string &str)
static float toScalar(const std::string &str)
static int toScalar(const std::string &str)
static long toScalar(const std::string &str)
static long double toScalar(const std::string &str)
static long long toScalar(const std::string &str)
static unsigned long toScalar(const std::string &str)
static unsigned long long toScalar(const std::string &str)
static T toScalar(const std::string &key)
std::string read(const fs::path &path)
newsubseg ss[0]
enum insertvertexresult success
newbad key
vertex temp
vertex first