Alexandria  2.22.0
Please provide a description of the project.
AsciiParser.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
26 #include <boost/algorithm/string.hpp>
27 #include <boost/regex.hpp>
28 #include <fstream>
29 #include <iostream>
30 #include <sstream>
31 
32 #include "boost/lexical_cast.hpp"
33 
35 #include "StringFunctions.h"
36 #include "Table/AsciiReader.h"
37 #include "XYDataset/AsciiParser.h"
38 
39 using boost::regex;
40 using boost::regex_match;
41 
42 namespace Euclid {
43 namespace XYDataset {
44 
45 //
46 // Get dataset name from ASCII file
47 //
49  // The data set name can be a parameter with keyword NAME
50  std::string dataset_name = getParameter(file, "NAME");
51 
52  if (dataset_name == "") {
53  // IF not present chack the first non-empty line (Backward comatibility)
54  std::ifstream sfile(file);
55  std::string line{};
56  // Check dataset name is in the file
57  // Convention: read until found first non empty line, removing empty lines.
58  while (line.empty() && sfile.good()) {
59  std::getline(sfile, line);
60  }
61 
62  boost::regex expression(m_regex_name);
63  boost::smatch s_match;
64  if (boost::regex_match(line, s_match, expression)) {
65  dataset_name = s_match[1].str();
66  } else {
67  // Dataset name is the filename without extension and path
68  std::string str{};
69  str = removeAllBeforeLastSlash(file);
70  dataset_name = removeExtension(str);
71  }
72  }
73 
74  return dataset_name;
75 }
76 
78  std::ifstream sfile(file);
79  if (!sfile) {
80  throw Elements::Exception() << "File does not exist : " << file;
81  }
82 
83  std::string value{};
84  std::string line{};
85  std::string dataset_name{};
86  std::string reg_ex_str = "^\\s*#\\s*" + key_word + "\\s*:\\s*(.+)\\s*$";
87  boost::regex expression(reg_ex_str);
88 
89  while (sfile.good()) {
90  std::getline(sfile, line);
91  boost::smatch s_match;
92  if (!line.empty() && boost::regex_match(line, s_match, expression)) {
93  if (value!="") {
94  value +=";";
95  }
96  std::string new_val = s_match[1].str();
97  boost::trim(new_val);
98  value += new_val;
99 
100  }
101  }
102  return value;
103 }
104 
105 //
106 // Get dataset from ASCII file
107 //
109 
110  std::unique_ptr<XYDataset> dataset_ptr{};
111  std::ifstream sfile(file);
112  // Check file exists
113  if (sfile) {
114  // Read file into a Table object
115  auto table = Table::AsciiReader{sfile}.fixColumnTypes({typeid(double), typeid(double)}).read();
116  // Put the Table data into vector pair
118  for (auto row : table) {
119  vector_pair.push_back(std::make_pair(boost::get<double>(row[0]), boost::get<double>(row[1])));
120  }
121  dataset_ptr = std::unique_ptr<XYDataset>{new XYDataset(vector_pair)};
122  }
123 
124  return dataset_ptr;
125 }
126 
128  bool is_a_dataset_file = false;
129  std::ifstream sfile(file);
130  // Check file exists
131  if (sfile) {
132  std::string line{};
133  // Convention: read until found first non empty line, removing empty lines.
134  // Escape also the dataset name and comment lines
135  boost::regex expression("\\s*#.*");
136  boost::smatch s_match;
137  while ((line.empty() || boost::regex_match(line, s_match, expression)) && sfile.good()) {
138  std::getline(sfile, line);
139  }
140  if (sfile.good()) {
141  // We should have 2 double values only on one line
142  try {
143  std::stringstream ss(line);
144  std::string empty_string{};
145  std::string d1, d2;
146  ss >> d1 >> d2 >> empty_string;
147  boost::lexical_cast<double>(d1);
148  boost::lexical_cast<double>(d2);
149  if (!empty_string.empty()) {
150  is_a_dataset_file = false;
151  } else {
152  is_a_dataset_file = true;
153  }
154  } catch (...) {
155  is_a_dataset_file = false;
156  }
157  } // Eof sfile.good()
158  } // Eof sfile
159  return is_a_dataset_file;
160 }
161 
162 } // namespace XYDataset
163 } // end of namespace Euclid
TableReader implementation for reading ASCII tables from streams.
Definition: AsciiReader.h:87
std::string getParameter(const std::string &file, const std::string &key_word) override
Get the parameter identified by a given key_word value from a file.
Definition: AsciiParser.cpp:77
bool isDatasetFile(const std::string &file) override
Check that the ASCII file is a dataset file(with at least one line with 2 double values)
std::unique_ptr< XYDataset > getDataset(const std::string &file) override
Get a XYDataset object reading data from an ASCII file.
std::string getName(const std::string &file) override
Get the dataset name of a ASCII file.
Definition: AsciiParser.cpp:48
This module provides an interface for accessing two dimensional datasets (pairs of (X,...
Definition: XYDataset.h:59
T getline(T... args)
T good(T... args)
T make_pair(T... args)
std::string removeExtension(const std::string &input_str)
std::string removeAllBeforeLastSlash(const std::string &input_str)
T push_back(T... args)