BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
DataFormatUtils.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Device/InputOutput/DataFormatUtils.cpp
6 //! @brief Implements class DataFormatUtils.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************** //
14 
20 #include "Device/Data/OutputData.h"
21 #include "Fit/Tools/StringUtils.h"
22 #include <iostream>
23 #include <iterator>
24 
25 namespace
26 {
27 std::istringstream getAxisStringRepresentation(std::istream& input_stream);
28 
29 template <class Axis> std::unique_ptr<IAxis> createFixedBinLikeAxis(std::istringstream iss);
30 std::unique_ptr<IAxis> createVariableBinAxis(std::istringstream iss);
31 std::unique_ptr<IAxis> createPointwiseAxis(std::istringstream iss);
32 
33 using createAxisFun = std::function<std::unique_ptr<IAxis>(std::istringstream iss)>;
34 const std::vector<std::pair<std::string, createAxisFun>> type_map = {
35  {"ConstKBinAxis", createFixedBinLikeAxis<ConstKBinAxis>},
36  {"CustomBinAxis", createFixedBinLikeAxis<CustomBinAxis>},
37  {"FixedBinAxis", createFixedBinLikeAxis<FixedBinAxis>},
38  {"PointwiseAxis", createPointwiseAxis},
39  {"VariableBinAxis", createVariableBinAxis}};
40 
41 const std::string GzipExtension = ".gz";
42 const std::string BzipExtension = ".bz2";
43 const std::string IntExtension = ".int";
44 const std::string TiffExtension = ".tif";
45 const std::string TiffExtension2 = ".tiff";
46 } // namespace
47 
48 bool DataFormatUtils::isCompressed(const std::string& name)
49 {
50  return isGZipped(name) || isBZipped(name);
51 }
52 
53 //! Does name contain *.gz extension?
54 
55 bool DataFormatUtils::isGZipped(const std::string& name)
56 {
58 }
59 
60 bool DataFormatUtils::isBZipped(const std::string& name)
61 {
63 }
64 
65 //! Returns file main extension (without .gz).
66 
67 std::string DataFormatUtils::GetFileMainExtension(const std::string& name)
68 {
69  std::string stripped_name(name);
70  if (isGZipped(name)) {
71  stripped_name = name.substr(0, name.size() - GzipExtension.size());
72  } else if (isBZipped(name)) {
73  stripped_name = name.substr(0, name.size() - BzipExtension.size());
74  }
75  return FileSystemUtils::extension(stripped_name);
76 }
77 
78 bool DataFormatUtils::isIntFile(const std::string& file_name)
79 {
80  return GetFileMainExtension(file_name) == IntExtension;
81 }
82 
83 bool DataFormatUtils::isTiffFile(const std::string& file_name)
84 {
85  return (GetFileMainExtension(file_name) == TiffExtension
86  || GetFileMainExtension(file_name) == TiffExtension2);
87 }
88 
89 //! Creates axis of certain type from input stream
90 std::unique_ptr<IAxis> DataFormatUtils::createAxis(std::istream& input_stream)
91 {
92  auto iss = getAxisStringRepresentation(input_stream);
93  std::string type;
94  if (!(iss >> type))
96  "Error in DataFormatUtils::createAxis:: couldn't read axis type from input");
97 
98  for (auto iter = type_map.cbegin(); iter != type_map.end(); ++iter)
99  if (iter->first == type)
100  return iter->second(std::move(iss));
101  throw Exceptions::LogicErrorException("Error in DataFormatUtils::createAxis:"
102  "Unknown axis type '"
103  + type + "'");
104 }
105 
106 //! Fills output data raw buffer from input stream
107 void DataFormatUtils::fillOutputData(OutputData<double>* data, std::istream& input_stream)
108 {
109  std::string line;
110  data->setAllTo(0.0);
111  OutputData<double>::iterator it = data->begin();
112  while (std::getline(input_stream, line)) {
113  if (line.empty() || line[0] == '#')
114  break;
115 
116  std::istringstream iss(line);
117  std::vector<double> buffer;
118  readLineOfDoubles(buffer, iss);
119  for (auto value : buffer) {
120  *it = value;
121  ++it;
122  }
123  }
124  if (it != data->end())
126  "DataFormatUtils::fillOutputData() -> Error while parsing data.");
127 }
128 
129 //! Parse double values from string to vector of double
130 
131 std::vector<double> DataFormatUtils::parse_doubles(const std::string& str)
132 {
133  std::vector<double> result;
134  std::istringstream iss(str);
136  if (result.empty()) {
137  std::string out = str;
138  const size_t max_string_length(10);
139  if (out.size() > max_string_length)
140  out.resize(max_string_length, ' ');
141  out += " ...";
142  throw std::runtime_error("DataFormatUtils::parse_doubles -> Error! Can't parse double "
143  "values from a string '"
144  + out + "'");
145  }
146  return result;
147 }
148 
149 void DataFormatUtils::readLineOfDoubles(std::vector<double>& buffer, std::istringstream& iss)
150 {
151  iss.imbue(std::locale::classic());
152  std::copy(std::istream_iterator<double>(iss), std::istream_iterator<double>(),
153  back_inserter(buffer));
154 }
155 
156 namespace
157 {
158 std::istringstream getAxisStringRepresentation(std::istream& input_stream)
159 {
160  std::string line;
161  std::getline(input_stream, line);
162  const std::vector<std::string> to_replace = {",", "\"", "(", ")", "[", "]"};
163  StringUtils::replaceItemsFromString(line, to_replace, " ");
164  return std::istringstream(line);
165 }
166 
167 //! Creates one of FixedBinAxis from string representation
168 //! FixedBinAxis("axis0", 10, -1, 1)
169 //! ConstKBinAxis("axis0", 10, -1, 1)
170 //! CustomBinAxis("axis0", 10, -1, 1)
171 template <class Axis> std::unique_ptr<IAxis> createFixedBinLikeAxis(std::istringstream iss)
172 {
173  std::string name;
174  size_t nbins(0);
175  if (!(iss >> name >> nbins))
177  "createFixedBinLikeAxis() -> Error. Can't parse the string.");
178 
179  std::vector<double> boundaries;
180  DataFormatUtils::readLineOfDoubles(boundaries, iss);
181  if (boundaries.size() != 2)
183  "Error in createFixedBinLikeAxis: Can't parse the string while "
184  "reading boundaries.");
185 
186  return std::make_unique<Axis>(name, nbins, boundaries[0], boundaries[1]);
187 }
188 
189 //! Creates VariableBinAxis from string representation
190 //! VariableBinAxis("axis0", 4, [-1, -0.5, 0.5, 1, 2])
191 std::unique_ptr<IAxis> createVariableBinAxis(std::istringstream iss)
192 {
193  std::string name;
194  size_t nbins(0);
195  if (!(iss >> name >> nbins))
197  "Error in createVariableBinAxis: Can't parse the string.");
198 
199  std::vector<double> boundaries;
200  DataFormatUtils::readLineOfDoubles(boundaries, iss);
201  if (boundaries.size() != nbins + 1)
203  "Error in createVariableBinAxis: wrong number of boundaries read.");
204 
205  return std::make_unique<VariableBinAxis>(name, nbins, boundaries);
206 }
207 
208 //! Creates createPointwiseAxis from string representation
209 //! PointwiseAxis("axis0", [-0.5, 0.5, 1, 2])
210 std::unique_ptr<IAxis> createPointwiseAxis(std::istringstream iss)
211 {
212  std::string name;
213  if (!(iss >> name))
215  "Error in createPointwiseAxis:Can't parse the string.");
216 
217  std::vector<double> coordinates;
218  DataFormatUtils::readLineOfDoubles(coordinates, iss);
219 
220  return std::make_unique<PointwiseAxis>(name, coordinates);
221 }
222 } // namespace
Defines class ConstKBinAxis.
Defines class CustomBinAxis.
Defines class OutputDataIOFactory.
Defines namespace FileSystemUtils.
Defines and implements template class OutputData.
Defines class PointwiseAxis.
Defines a few helper functions.
iterator end()
Returns read/write iterator that points to the one past last element.
Definition: OutputData.h:96
void setAllTo(const T &value)
Sets content of output data to specific value.
Definition: OutputData.h:479
iterator begin()
Returns read/write iterator that points to the first element.
Definition: OutputData.h:344
bool isBZipped(const std::string &name)
Returns true if name contains *.bz2 extension.
void readLineOfDoubles(std::vector< double > &buffer, std::istringstream &iss)
bool isCompressed(const std::string &name)
Returns true if name contains *.gz extension.
bool isIntFile(const std::string &file_name)
returns true if file name corresponds to BornAgain native format (compressed or not)
std::string GetFileMainExtension(const std::string &name)
Returns file extension after stripping '.gz' if any.
bool isTiffFile(const std::string &file_name)
returns true if file name corresponds to tiff file (can be also compressed)
std::unique_ptr< IAxis > createAxis(std::istream &input_stream)
Creates axis of certain type from input stream.
std::vector< double > parse_doubles(const std::string &str)
Parse double values from string to vector of double.
bool isGZipped(const std::string &name)
Returns true if name contains *.gz extension.
void fillOutputData(OutputData< double > *data, std::istream &input_stream)
Fills output data raw buffer from input stream.
std::string extension(const std::string &path)
Returns extension of given filename.
void replaceItemsFromString(std::string &text, const std::vector< std::string > &items, const std::string &replacement="")
Replaces all occurences of items from string text with delimiter.
Definition: StringUtils.cpp:64
std::function< std::unique_ptr< IAxis >(std::istringstream iss)> createAxisFun
std::unique_ptr< IAxis > createFixedBinLikeAxis(std::istringstream iss)
Creates one of FixedBinAxis from string representation FixedBinAxis("axis0", 10, -1,...
const std::vector< std::pair< std::string, createAxisFun > > type_map
std::unique_ptr< IAxis > createVariableBinAxis(std::istringstream iss)
Creates VariableBinAxis from string representation VariableBinAxis("axis0", 4, [-1,...
std::istringstream getAxisStringRepresentation(std::istream &input_stream)
std::unique_ptr< IAxis > createPointwiseAxis(std::istringstream iss)
Creates createPointwiseAxis from string representation PointwiseAxis("axis0", [-0....