AlmaBTE  1.3
A solver of the space- and time-dependent Boltzmann transport equation for phonons
io_utils.hpp
Go to the documentation of this file.
1 // Copyright 2015-2018 The ALMA Project Developers
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 // implied. See the License for the specific language governing
13 // permissions and limitations under the License.
14 
15 #pragma once
16 
20 
21 #include <iostream>
22 #include <fstream>
23 #include <algorithm>
24 #include <string>
25 #include <vector>
26 #include <ctime>
27 #include <Eigen/Dense>
28 #include <boost/filesystem.hpp>
29 #include <boost/property_tree/ptree.hpp>
30 
31 namespace alma {
37 
38 inline void write_to_csv(const std::string filename,
39  const Eigen::Ref<const Eigen::MatrixXd>& data,
40  char colsep,
41  bool append = false,
42  std::string headermessage = "") {
43  std::ofstream csvwriter;
44 
45  if (append) {
46  csvwriter.open(filename, std::ofstream::out | std::ofstream::app);
47  }
48  else {
49  csvwriter.open(filename, std::ofstream::out);
50  }
51 
52  if (csvwriter.fail()) {
53  std::cout << "************** ERROR IN write_to_csv **************"
54  << std::endl;
55  std::cout << "Unable to write to target file " << filename << std::endl;
56  std::cout
57  << "Verify existence/permissions of the chosen target directory."
58  << std::endl;
59 
60  // create timestamp
61  auto t = std::time(nullptr);
62  auto localtime = std::localtime(&t);
63  std::size_t size = 0;
64  std::vector<char> buffer;
65 
66  do {
67  size += 64;
68  buffer.reserve(size);
69  } while (std::strftime(
70  buffer.data(), size, "%Y%m%d_%H%M%S", localtime) == 0u);
71  std::string timestamp(buffer.data());
72 
73  // create override filename
74  // the filename will have a random component to avoid conflicts if
75  // these redirections happen more than once a second
76  std::string filename_override = "CSV_DUMP_" + timestamp + "_%%%%%%.csv";
77  filename_override =
78  boost::filesystem::unique_path(filename_override).string();
79 
80  std::cout << "Data will be redirected to the current work directory"
81  << std::endl;
82  std::cout << "and written to file " << filename_override << std::endl;
83  std::cout << "***************************************************"
84  << std::endl;
85 
86  csvwriter.close();
87  csvwriter.open(filename_override,
88  std::ofstream::out | std::ofstream::app);
89  csvwriter << "*** The following data was originally destined for file "
90  << filename << "***" << std::endl;
91  }
92 
93  csvwriter << headermessage;
94 
95  int Nrows = data.rows();
96  int Ncols = data.cols();
97 
98  for (int nrow = 0; nrow < Nrows; nrow++) {
99  for (int ncol = 0; ncol < Ncols; ncol++) {
100  csvwriter << data(nrow, ncol);
101 
102  if (ncol == (Ncols - 1)) {
103  csvwriter << std::endl;
104  }
105 
106  else {
107  csvwriter << colsep;
108  }
109  }
110  }
111 
112  csvwriter.close();
113 }
114 
120 
121 inline Eigen::MatrixXd read_from_csv(const std::string filename,
122  char colsep,
123  std::size_t skipheaderlines = 0) {
124  std::ifstream csvreader;
125  csvreader.open(filename);
126  if (csvreader.fail()) {
127  std::cout << "Error in read_from_csv:" << std::endl;
128  std::cout << "Unable to open " << filename << std::endl;
129 
130  exit(1);
131  }
132 
133  std::string linereader;
134  std::vector<double> databuffer;
135  double datavalue;
136  char dump;
137 
138  // read header lines
139 
140  for (std::size_t nskip = 0; nskip < skipheaderlines; nskip++) {
141  getline(csvreader, linereader, '\n');
142  }
143 
144  // GRAB DATA
145 
146  // get first data line
147  getline(csvreader, linereader, '\n');
148 
149  std::size_t Ncols =
150  std::count(linereader.begin(), linereader.end(), colsep) + 1;
151 
152  while (csvreader.good()) {
153  std::stringstream extractor(linereader);
154 
155  for (std::size_t ncol = 0; ncol < Ncols; ncol++) {
156  extractor >> datavalue;
157  databuffer.emplace_back(datavalue);
158  extractor >> dump;
159  }
160 
161  getline(csvreader, linereader, '\n');
162  }
163 
164  csvreader.close();
165 
166  // PUT DATA IN MATRIX FORM
167 
168  int Nrows = databuffer.size() / Ncols;
169 
170  Eigen::MatrixXd result(Nrows, Ncols);
171  result.fill(0.0);
172 
173  for (std::size_t idx = 0; idx < databuffer.size(); idx++) {
174  std::size_t nrow = idx / Ncols;
175  std::size_t ncol = idx % Ncols;
176  result(nrow, ncol) = databuffer.at(idx);
177  }
178 
179  return result;
180 }
181 
183 
184 template <class C>
185 C parseXMLfield(boost::property_tree::ptree::value_type const& v,
186  std::string field) {
187  C result;
188  std::string field_as_attribute = "<xmlattr>." + field;
189 
190  try {
191  result = v.second.get<C>(field);
192  }
193  catch (boost::property_tree::ptree_bad_path& bad_path_error) {
194  try {
195  result = v.second.get<C>(field_as_attribute);
196  }
197  catch (boost::property_tree::ptree_bad_path& bad_path_error) {
198  std::cout << "XML error:" << std::endl;
199  std::cout << "Mandatory attribute \"" << field
200  << "\" is missing in element \"" << v.first << "\""
201  << std::endl;
202 
203  exit(1);
204  }
205  }
206 
207  return result;
208 }
209 
210 
212 
213 template <class C>
214 bool probeXMLfield(boost::property_tree::ptree::value_type const& v,
215  std::string field) {
216  bool result = false;
217  C read_content;
218  std::string field_as_attribute = "<xmlattr>." + field;
219 
220  try {
221  read_content = v.second.get<C>(field);
222  result = true;
223  }
224  catch (boost::property_tree::ptree_bad_path& bad_path_error) {
225  try {
226  read_content = v.second.get<C>(field_as_attribute);
227  result = true;
228  }
229  catch (boost::property_tree::ptree_bad_path& bad_path_error) {
230  result = false;
231  }
232  }
233 
234  return result;
235 }
236 } // namespace alma
C parseXMLfield(boost::property_tree::ptree::value_type const &v, std::string field)
Extract a value from an XML tree.
Definition: io_utils.hpp:185
Definition: analytic1d.hpp:26
void write_to_csv(const std::string filename, const Eigen::Ref< const Eigen::MatrixXd > &data, char colsep, bool append=false, std::string headermessage="")
Save a Matrix of double precision numbers as a csv file.
Definition: io_utils.hpp:38
Eigen::MatrixXd read_from_csv(const std::string filename, char colsep, std::size_t skipheaderlines=0)
Read a csv file into a Matrix.
Definition: io_utils.hpp:121
bool probeXMLfield(boost::property_tree::ptree::value_type const &v, std::string field)
Check if an XML field is present.
Definition: io_utils.hpp:214