Alexandria 2.25.0
SDC-CH common library for the Euclid 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"
38
39using boost::regex;
40using boost::regex_match;
41
42namespace Euclid {
43namespace 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)