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