ComPWA
Common Partial-Wave-Analysis Framework
AsciiHeaderIO.cpp
Go to the documentation of this file.
1 // This file is part of the ComPWA framework, check
2 // Copyright (c) 2013 The ComPWA Team.
3 // https://github.com/ComPWA/ComPWA/license.txt for details.
4 
5 #include <algorithm>
6 #include <fstream>
7 #include <regex>
8 #include <sstream>
9 
10 #include "Core/Exceptions.hpp"
12 
13 namespace ComPWA {
14 namespace Data {
15 namespace Ascii {
16 
18 
19 namespace std_fix {
20 std::string tolower(std::string s) {
21  std::transform(s.begin(), s.end(), s.begin(),
22  [](unsigned char c) { return std::tolower(c); });
23  return s;
24 }
25 } // namespace std_fix
26 
28 bool isValueLine(const std::string &line) {
29  std::stringstream ss(line);
30  float value;
31  return (bool)(ss >> value);
32 }
33 
35 
36 std::string AsciiHeader::extractHeaderContent(std::istream &InputStream) {
38  static const std::regex HeaderBegin("<header>", std::regex_constants::icase);
39  static const std::regex HeaderEnd("</header>", std::regex_constants::icase);
41  std::string Line;
42  std::stringstream HeaderContent;
43  std::smatch RegexMatch;
45  auto pos = InputStream.tellg();
46  while (std::getline(InputStream, Line)) {
47  if (isValueLine(Line)) {
48  InputStream.seekg(pos);
49  return ""; // means there is no header
50  }
51  if (std::regex_search(Line, RegexMatch, HeaderBegin)) {
52  HeaderContent << RegexMatch.suffix() << std::endl;
53  break;
54  }
55  }
57  Line = HeaderContent.str();
58  if (std::regex_search(Line, RegexMatch, HeaderEnd)) {
59  Line = RegexMatch.prefix();
60  return Line;
61  }
63  if (InputStream.eof()) {
64  InputStream.clear();
65  InputStream.seekg(pos);
66  throw ComPWA::CorruptFile("No opening <header> tag");
67  }
69  while (std::getline(InputStream, Line)) {
70  if (isValueLine(Line))
71  break;
72  if (std::regex_search(Line, RegexMatch, HeaderEnd)) {
73  HeaderContent << RegexMatch.prefix() << std::endl;
74  return HeaderContent.str();
75  }
76  HeaderContent << Line << std::endl;
77  }
78  InputStream.clear();
79  InputStream.seekg(pos);
80  throw ComPWA::CorruptFile("No closing tag after <header>");
81 }
82 
85 void AsciiHeader::importYAML(const std::string &HeaderContent) {
86  std::stringstream StringStream(HeaderContent);
87  std::string Line;
88  static const std::regex RegexKeyValue(
89  R"(^\s*([^\s]+.*?)\s*:\s+([^\s]+.*?)\s*$)");
90  static const std::regex RegexPID(R"(-?\d+)");
91  static const std::regex RegexEfirst("e.*[mpz]", std::regex_constants::icase);
92  static const std::regex RegexPfirst("[mp].*e", std::regex_constants::icase);
93  while (getline(StringStream, Line)) {
94  std::smatch RegexMatch;
95  std::regex_search(Line, RegexMatch, RegexKeyValue);
96  if (RegexMatch.size() < 3)
97  continue;
98  const std::string Key{std_fix::tolower(RegexMatch[1])};
99  const std::string Value{RegexMatch[2]};
100  if (Key == "pids") {
101  std::sregex_iterator iter(Value.begin(), Value.end(), RegexPID), end;
102  std::vector<int>().swap(PIDs); // completely clear vector
103  for (; iter != end; ++iter)
104  PIDs.push_back(std::stoi(iter->str()));
105  continue;
106  } else if (Key == "unit") {
107  Unit = Value;
108  } else if (Key == "order") {
109  if (std::regex_match(Value, RegexPfirst)) {
110  EnergyFirst = false;
111  } else if (std::regex_match(Value, RegexEfirst)) {
112  EnergyFirst = true;
113  }
114  }
115  }
116 }
117 
118 void AsciiHeader::dumpToYAML(std::ostream &os) const {
119  os << "<header>" << std::endl;
121  if (PIDs.size()) {
122  os << "\tPids: [" << PIDs[0];
123  for (size_t i = 1; i < PIDs.size(); ++i)
124  os << ", " << PIDs[i];
125  os << "]" << std::endl;
126  }
128  os << "\tOrder: ";
129  if (EnergyFirst)
130  os << "E px py pz" << std::endl;
131  else
132  os << "px py pz E" << std::endl;
134  os << "\tUnit: " << Unit << std::endl;
135  os << "</header>" << std::endl;
136 }
137 
138 } // namespace Ascii
139 } // namespace Data
140 } // namespace ComPWA
void importYAML(const std::string &HeaderContent)
Set data members by reading a YAML-like string (including newlines).
Input data file is corrupt or incomplete.
Definition: Exceptions.hpp:86
ComPWA exceptions.
void dumpToYAML(std::ostream &os) const
Serialise data members to YAML format, embedded in XML header tags.
static std::string extractHeaderContent(std::istream &InputStream)
Extract the part that is between the XML/HTML tags <header>...</header> including newlines...