Alexandria  2.14.1
Please provide a description of the project.
AsciiParser.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2020 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/regex.hpp>
27 #include <fstream>
28 #include <iostream>
29 #include <sstream>
30 
31 #include "boost/lexical_cast.hpp"
32 
34 #include "Table/AsciiReader.h"
35 #include "XYDataset/AsciiParser.h"
36 #include "StringFunctions.h"
37 
38 using boost::regex;
39 using boost::regex_match;
40 
41 namespace Euclid {
42 namespace XYDataset {
43 
44 //
45 // Get dataset name from ASCII file
46 //
48 
49  std::ifstream sfile(file);
50  // Check file exists
51  if (!sfile) {
52  throw Elements::Exception() << "File does not exist : " << file;
53  }
54 
55  std::string line{};
56  std::string dataset_name{};
57  // Check dataset name is in the file
58  // Convention: read until found first non empty line, removing empty lines.
59  while (line.empty() && sfile.good()) {
60  std::getline(sfile, line);
61  }
62 
63  boost::regex expression(m_regex_name);
64  boost::smatch s_match;
65  if (boost::regex_match(line, s_match, expression)) {
66  dataset_name = s_match[1].str();
67  }
68  else {
69  // Dataset name is the filename without extension and path
70  std::string str {};
71  str = removeAllBeforeLastSlash(file);
72  dataset_name = removeExtension(str);
73  }
74 
75  return dataset_name;
76 }
77 
78 //
79 // Get dataset from ASCII file
80 //
82 
83  std::unique_ptr<XYDataset> dataset_ptr {};
84  std::ifstream sfile(file);
85  // Check file exists
86  if (sfile) {
87  // Read file into a Table object
88  auto table = Table::AsciiReader{sfile}.fixColumnTypes({typeid(double), typeid(double)}).read();
89  // Put the Table data into vector pair
91  for (auto row : table) {
92  vector_pair.push_back(std::make_pair( boost::get<double>(row[0]), boost::get<double>(row[1]) ));
93  }
94  dataset_ptr = std::unique_ptr<XYDataset> { new XYDataset(vector_pair) };
95  }
96 
97  return dataset_ptr;
98 }
99 
101  bool is_a_dataset_file = false;
102  std::ifstream sfile(file);
103  // Check file exists
104  if (sfile) {
105  std::string line{};
106  // Convention: read until found first non empty line, removing empty lines.
107  // Escape also the dataset name and comment lines
108  boost::regex expression("\\s*#.*");
109  boost::smatch s_match;
110  while ((line.empty() || boost::regex_match(line, s_match, expression)) && sfile.good()) {
111  std::getline(sfile, line);
112  }
113  if (sfile.good()) {
114  // We should have 2 double values only on one line
115  try {
116  std::stringstream ss(line);
117  std::string empty_string{};
118  std::string d1, d2;
119  ss >> d1 >> d2 >> empty_string;
120  boost::lexical_cast<double>(d1);
121  boost::lexical_cast<double>(d2);
122  if (!empty_string.empty()){
123  is_a_dataset_file = false;
124  }
125  else {
126  is_a_dataset_file = true;
127  }
128  }
129  catch(...){
130  is_a_dataset_file = false;
131  }
132  }// Eof sfile.good()
133  } // Eof sfile
134  return is_a_dataset_file;
135 }
136 
137 } // XYDataset namespace
138 } // end of namespace Euclid
std::string
STL class.
Euclid::XYDataset::XYDataset
This module provides an interface for accessing two dimensional datasets (pairs of (X,...
Definition: XYDataset.h:59
Euclid::XYDataset::AsciiParser::getDataset
std::unique_ptr< XYDataset > getDataset(const std::string &file) override
Get a XYDataset object reading data from an ASCII file.
Definition: AsciiParser.cpp:81
std::vector
STL class.
AsciiParser.h
StringFunctions.h
std::stringstream
STL class.
Euclid::XYDataset::removeAllBeforeLastSlash
std::string removeAllBeforeLastSlash(const std::string &input_str)
Definition: StringFunctions.cpp:115
AsciiReader.h
std::vector::push_back
T push_back(T... args)
Exception.h
Elements::Exception
Euclid::XYDataset::AsciiParser::getName
std::string getName(const std::string &file) override
Get the dataset name of a ASCII file.
Definition: AsciiParser.cpp:47
Euclid::XYDataset::removeExtension
std::string removeExtension(const std::string &input_str)
Definition: StringFunctions.cpp:94
Euclid::XYDataset::AsciiParser::m_regex_name
std::string m_regex_name
Definition: AsciiParser.h:118
std::ifstream::good
T good(T... args)
Euclid::Table::AsciiReader
TableReader implementation for reading ASCII tables from streams.
Definition: AsciiReader.h:87
Euclid::XYDataset::AsciiParser::isDatasetFile
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)
Definition: AsciiParser.cpp:100
std::getline
T getline(T... args)
std::make_pair
T make_pair(T... args)
std::unique_ptr
STL class.
Euclid
Definition: InstOrRefHolder.h:29
std::ifstream
STL class.