SLHAReader.cc
1 #include <algorithm>
2 #include <fstream>
3 #include <iostream>
4 #include <regex>
5 
6 #include <momemta/SLHAReader.h>
7 
8 namespace SLHA {
9 
10 std::vector<std::string> parse_line_elements(const std::string& line, char delimiter=' ') {
11  std::vector<std::string> elements;
12  std::string temp;
13  std::stringstream linestr(line);
14  while (getline(linestr, temp, delimiter)) {
15  if (temp == std::string(&delimiter, 1))
16  continue;
17  elements.push_back(temp);
18  }
19  return elements;
20 }
21 
22 class invalid_card_error: public std::runtime_error {
23  using std::runtime_error::runtime_error;
24 };
25 
26 Block::Block(const std::string& name /* = ""*/) { _name = name; }
27 
28 void Block::set_name(const std::string& name) { _name = name; }
29 
30 std::string Block::get_name() const { return _name; }
31 
32 int Block::get_indices() const { return _indices; }
33 
34 void Block::set_entry(const std::vector<int>& indices, double value) {
35  if (_entries.empty())
36  _indices = indices.size();
37  else if (indices.size() != _indices)
38  throw invalid_card_error("Wrong number of indices in set_entry");
39 
40  _entries[indices] = value;
41 }
42 
43 double Block::get_entry(const std::vector<int>& indices, double def_val) const {
44  auto it = _entries.find(indices);
45  if (it == _entries.end()) {
46  return def_val;
47  }
48 
49  return it->second;
50 }
51 
52 Reader::Reader(const std::string& file_name /* = ""*/) {
53  if (!file_name.empty())
54  read_slha_file(file_name);
55 }
56 
57 void Reader::read_slha_file(const std::string& file_name) {
58  std::ifstream param_card(file_name.c_str(), std::ifstream::in);
59  if (!param_card.is_open())
60  throw invalid_card_error("Error while opening param card");
61  std::string line;
62  std::string block("");
63 
64  try {
65 
66  while (std::getline(param_card, line)) {
67  // Change to lowercase
68  std::transform(line.begin(), line.end(), line.begin(), ::tolower);
69  // Remove comments
70  line = std::regex_replace(line, std::regex("#.*"), "");
71  // Remove leading, trailing and duplicate whitespaces
72  line = std::regex_replace(line, std::regex("^ *| *$"), "");
73  line = std::regex_replace(line, std::regex(" +"), " ");
74 
75  if (line == "")
76  continue;
77 
78  // Look for block
79  if (line.find("block ") != line.npos) {
80  line = line.substr(6);
81  // Find end of block name
82  size_t space_pos = line.find(' ');
83  if (space_pos != line.npos)
84  line = line.substr(0, space_pos);
85  block = line;
86  continue;
87  }
88  // Look for decay (not part of a block)
89  if (line.find("decay ") == 0) {
90  line = line.substr(6);
91  block = "";
92  auto elements = parse_line_elements(line);
93  if (elements.size() == 2) {
94  int pdg_id = std::stoi(elements[0]);
95  double value = std::stod(elements[1]);
96  set_block_entry("decay", pdg_id, value);
97  } else {
98  throw invalid_card_error("Wrong format for decay block " + line);
99  }
100  continue;
101  }
102  // We have a block, now read this block's entries line by line
103  if (block != "") {
104  auto elements = parse_line_elements(line);
105  // Look for double index blocks
106  if (elements.size() == 3) {
107  int id1 = std::stoi(elements[0]);
108  int id2 = std::stoi(elements[1]);
109  double value = std::stod(elements[2]);
110  set_block_entry(block, { id1, id2 }, value);
111  // Done with this line, read next
112  continue;
113  } else if (elements.size() == 2) {
114  // Look for single index blocks
115  int id = std::stoi(elements[0]);
116  double value = std::stod(elements[1]);
117  set_block_entry(block, { id }, value);
118  // Done with this line, read next
119  continue;
120  } else {
121  throw invalid_card_error("Wrong format for entry in block " + block + "; line: " + line);
122  }
123  }
124  }
125 
126  if (_blocks.size() == 0)
127  throw invalid_card_error("No information read from SLHA card");
128 
129  // End try
130  } catch(std::exception &e) {
131  param_card.close();
132  throw e;
133  }
134 
135  param_card.close();
136 }
137 
138 double Reader::get_block_entry(const std::string& block_name, const std::vector<int>& indices, double def_val) const {
139  auto it = _blocks.find(block_name);
140  if (it == _blocks.end()) {
141  return def_val;
142  }
143 
144  return it->second.get_entry(indices, def_val);
145 }
146 
147 double Reader::get_block_entry(const std::string& block_name, int index, double def_val) const {
148  std::vector<int> indices { index };
149  return get_block_entry(block_name, indices, def_val);
150 }
151 
152 void Reader::set_block_entry(const std::string& block_name, const std::vector<int>& indices, double value) {
153  auto it = _blocks.find(block_name);
154  if (it == _blocks.end()) {
155  Block block(block_name);
156  _blocks[block_name] = block;
157  it = _blocks.find(block_name);
158  }
159  it->second.set_entry(indices, value);
160 }
161 
162 void Reader::set_block_entry(const std::string& block_name, int index, double value) {
163  std::vector<int> indices { index };
164  set_block_entry(block_name, indices, value);
165 }
166 
167 }