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