BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
IntensityDataIOFactory.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file Device/Histo/IntensityDataIOFactory.cpp
6 //! @brief Implements class OutputDataIOFactory.
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 
23 #include <exception>
24 #include <fstream>
25 #include <memory>
26 
28 
29 #ifdef _WIN32
30 #pragma warning(push)
31 #pragma warning(disable : 4244 4275)
33 #pragma warning(pop)
34 #else
36 #endif
37 
39 {
40  if (DataFormatUtils::isIntFile(file_name))
41  return readOutputData(
42  file_name, [](std::istream& s) { return OutputDataReadWriteINT().readOutputData(s); });
43 #ifdef BORNAGAIN_TIFF_SUPPORT
44  if (DataFormatUtils::isTiffFile(file_name))
45  return readOutputData(
46  file_name, [](std::istream& s) { return OutputDataReadWriteTiff().readOutputData(s); });
47 #endif
48  // Try to read ASCII by default. Binary maps to ASCII.
49  // If the file is not actually a matrix of numbers,
50  // the error will be thrown during the reading.
51  return readOutputData(
52  file_name, [](std::istream& s) { return OutputDataReadWriteNumpyTXT().readOutputData(s); });
53 }
54 
56 {
57  return readOutputData(
58  file_name, [](std::istream& s) { return OutputDataReadReflectometry().readOutputData(s); });
59 }
60 
62 {
63  std::unique_ptr<OutputData<double>> data(readOutputData(file_name));
64  if (!data)
65  throw std::runtime_error("Could not read " + file_name);
66  return IHistogram::createHistogram(*data);
67 }
68 
70  const std::string& file_name)
71 {
72  if (DataFormatUtils::isIntFile(file_name))
74  file_name, [&](std::ostream& s) { OutputDataReadWriteINT().writeOutputData(data, s); });
75 #ifdef BORNAGAIN_TIFF_SUPPORT
76  else if (DataFormatUtils::isTiffFile(file_name))
77  writeOutputData(file_name, [&](std::ostream& s) {
78  OutputDataReadWriteTiff().writeOutputData(data, s);
79  });
80 #endif
81  else
82  writeOutputData(file_name, [&](std::ostream& s) {
84  });
85 }
86 
87 void IntensityDataIOFactory::writeOutputData(const std::string& file_name,
88  std::function<void(std::ostream&)> writeData)
89 {
90  using namespace DataFormatUtils;
91 
92  std::ofstream fout;
93  std::ios_base::openmode openmode = std::ios::out;
94  if (isTiffFile(file_name) || isCompressed(file_name))
95  openmode = std::ios::out | std::ios_base::binary;
96 
97 #ifdef _WIN32
98  fout.open(FileSystemUtils::convert_utf8_to_utf16(file_name), openmode);
99 #else
100  fout.open(file_name, openmode);
101 #endif
102 
103  if (!fout.is_open())
104  throw std::runtime_error("IntensityDataIOFactory::writeOutputData() -> Error. "
105  "Can't open file '"
106  + file_name + "' for writing.");
107  if (!fout.good())
108  throw std::runtime_error("IntensityDataIOFactory::writeOutputData() -> Error! "
109  "File is not good, probably it is a directory.");
110  std::stringstream ss;
111  writeData(ss);
112 
113  boost::iostreams::filtering_streambuf<boost::iostreams::input> input_filtered;
114  if (DataFormatUtils::isGZipped(file_name))
115  input_filtered.push(boost::iostreams::gzip_compressor());
116  else if (DataFormatUtils::isBZipped(file_name))
117  input_filtered.push(boost::iostreams::bzip2_compressor());
118  input_filtered.push(ss);
119 
120  boost::iostreams::copy(input_filtered, fout);
121 
122  fout.close();
123 }
124 
126  const std::string& file_name)
127 {
128  std::unique_ptr<OutputData<double>> data(histogram.createOutputData());
129  writeOutputData(*data, file_name);
130 }
131 
133  const std::string& file_name)
134 {
135  auto data = result.data();
136  writeOutputData(*data, file_name);
137 }
138 
140 IntensityDataIOFactory::readOutputData(const std::string& file_name,
141  std::function<OutputData<double>*(std::istream&)> readData)
142 {
143 
144  if (!FileSystemUtils::IsFileExists(file_name))
145  return nullptr;
146 
147  using namespace DataFormatUtils;
148  std::ifstream input_stream;
149  std::ios_base::openmode openmode = std::ios::in;
150  if (isTiffFile(file_name) || isCompressed(file_name))
151  openmode = std::ios::in | std::ios_base::binary;
152 
153 #ifdef _WIN32
154  input_stream.open(FileSystemUtils::convert_utf8_to_utf16(file_name), openmode);
155 #else
156  input_stream.open(file_name, openmode);
157 #endif
158 
159  if (!input_stream.is_open())
160  throw std::runtime_error(
161  "IntensityDataIOFactory::getFromFilteredStream() -> Error. Can't open file '"
162  + file_name + "' for reading.");
163  if (!input_stream.good())
164  throw std::runtime_error("IntensityDataIOFactory::getFromFilteredStream() -> Error! "
165  "File is not good, probably it is a directory.");
166 
167  boost::iostreams::filtering_streambuf<boost::iostreams::input> input_filtered;
168  if (DataFormatUtils::isGZipped(file_name))
169  input_filtered.push(boost::iostreams::gzip_decompressor());
170  else if (DataFormatUtils::isBZipped(file_name))
171  input_filtered.push(boost::iostreams::bzip2_decompressor());
172  input_filtered.push(input_stream);
173  // we use stringstream since it provides random access which is important for tiff files
174  std::stringstream str;
175  boost::iostreams::copy(input_filtered, str);
176 
177  return readData(str);
178 }
Defines class OutputDataIOFactory.
Defines namespace FileSystemUtils.
Defines interface IHistogram.
Defines class IntensityDataIOFactory.
Defines OutputDataReadReflectometry.
Defines OutputDataReadWriteINT.
Defines OutputDataReadWriteNumpyTXT.
Defines class OutputDataReadWriteTiff.
Defines class SimulationResult.
Contains boost streams related headers.
Base class for 1D and 2D histograms holding values of double type.
Definition: IHistogram.h:27
OutputData< double > * createOutputData(DataType dataType=DataType::INTEGRAL) const
creates new OutputData with histogram's shape and values corresponding to DataType
Definition: IHistogram.cpp:343
static IHistogram * createHistogram(const OutputData< double > &source)
Definition: IHistogram.cpp:243
static OutputData< double > * readOutputData(const std::string &file_name)
Reads file and returns newly created OutputData object.
static void writeOutputData(const OutputData< double > &data, const std::string &file_name)
Writes OutputData in file.
static IHistogram * readIntensityData(const std::string &file_name)
Reads file and returns newly created Histogram object.
static void writeIntensityData(const IHistogram &histogram, const std::string &file_name)
Writes histogram in file.
static OutputData< double > * readReflectometryData(const std::string &file_name)
static void writeSimulationResult(const SimulationResult &result, const std::string &file_name)
Writes OutputData contained in the given SimulationResult object.
Class for reading reflectometry data from ASCII file.
OutputData< double > * readOutputData(std::istream &input_stream)
Class for reading and writing BornAgain native IntensityData from ASCII file.
OutputData< double > * readOutputData(std::istream &input_stream)
void writeOutputData(const OutputData< double > &data, std::ostream &output_stream)
Class for reading and writing OutputData from simple ASCII file with the layout as in numpy....
void writeOutputData(const OutputData< double > &data, std::ostream &output_stream)
OutputData< double > * readOutputData(std::istream &input_stream)
Wrapper around OutputData<double> that also provides unit conversions.
std::unique_ptr< OutputData< double > > data(Axes::Units units=Axes::Units::DEFAULT) const
Utility functions for data input and output.
bool isBZipped(const std::string &name)
Returns true if name contains *.bz2 extension.
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)
bool isTiffFile(const std::string &file_name)
returns true if file name corresponds to tiff file (can be also compressed)
bool isGZipped(const std::string &name)
Returns true if name contains *.gz extension.
std::wstring convert_utf8_to_utf16(const std::string &str)
Converts utf8 string represented by std::string to utf16 string represented by std::wstring.
bool IsFileExists(const std::string &path)
Returns true if file with given name exists on disk.