Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SchemeDefinitions.cc
Go to the documentation of this file.
1 ///
2 /// @file SchemeDefinitions.cc
3 /// @brief Container class for Scheme Definitions
4 ///
5 
6 //**** This file is a part of the HAMMER library
7 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
8 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
9 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
10 
11 // -*- C++ -*-
12 #include <fstream>
13 
14 #include <boost/algorithm/string.hpp>
15 
16 #include "yaml-cpp/yaml.h"
17 
18 #include "Hammer/Exceptions.hh"
21 #include "Hammer/Tools/Pdg.hh"
22 #include "Hammer/Tools/Utils.hh"
23 #include "Hammer/Math/Utils.hh"
25 
26 using namespace std;
27 
28 namespace Hammer {
29 
30 
31  Log& SchemeDefinitions::getLog() const {
32  return Log::getLog("Hammer.SchemeDefinitions");
33  }
34 
35  void SchemeDefinitions::write(flatbuffers::FlatBufferBuilder* msgwriter,
36  vector<flatbuffers::Offset<Serial::FBFFScheme>>* schemes) const {
37  schemes->reserve(_formFactorSchemes.size());
38  for (auto& elem : _formFactorSchemes) {
39  vector<uint16_t> chs;
40  vector<uint64_t> ids;
41  vector<string> keys;
42  vector<string> vals;
43  for (auto& elem2 : elem.second) {
44  chs.push_back(static_cast<uint16_t>(elem2.second));
45  ids.push_back(elem2.first);
46  }
47  if(elem.first == "Denominator") {
48  for(auto& elem2: _formFactorBase) {
49  keys.push_back(elem2.first);
50  vals.push_back(elem2.second);
51  }
52  }
53  else {
54  auto it = _formFactorSchemeNames.find(elem.first);
55  for(auto& elem2: it->second) {
56  keys.push_back(elem2.first);
57  vals.push_back(elem2.second);
58  }
59  }
60  auto serialChs = msgwriter->CreateVector(chs);
61  auto serialIds = msgwriter->CreateVector(ids);
62  auto serialProcs = msgwriter->CreateVectorOfStrings(keys);
63  auto serialGroups = msgwriter->CreateVectorOfStrings(vals);
64  auto name = msgwriter->CreateString(elem.first);
65  Serial::FBFFSchemeBuilder serialFF{*msgwriter};
66  serialFF.add_name(name);
67  serialFF.add_ffids(serialIds);
68  serialFF.add_ffschemes(serialChs);
69  serialFF.add_ffproc(serialProcs);
70  serialFF.add_ffgroup(serialGroups);
71  auto resFF = serialFF.Finish();
72  schemes->push_back(resFF);
73  }
74  }
75 
76  bool SchemeDefinitions::read(const Serial::FBHeader* msgreader, bool merge) {
77  auto schemes = msgreader->ffschemes();
78  if(!merge) {
79  _formFactorSchemes.clear();
80  _formFactorSchemeNames.clear();
81  _formFactorBase.clear();
82  }
83  for (unsigned int i = 0; i < schemes->size(); ++i) {
84  string name = schemes->Get(i)->name()->c_str();
85  auto it = _formFactorSchemes.find(name);
86  //if(merge && it != _formFactorSchemes.end()) {
87  if(it != _formFactorSchemes.end()) {
88  bool result = true;
89  auto ids = schemes->Get(i)->ffids();
90  auto chs = schemes->Get(i)->ffschemes();
91  for (unsigned int j = 0; j < ids->size(); ++j) {
92  auto it2 = it->second.find(ids->Get(j));
93  if(it2 == it->second.end() || it2->second != chs->Get(j)) {
94  result = false;
95  }
96  }
97  if(name == "Denominator") {
98  auto procs = schemes->Get(i)->ffproc();
99  auto groups = schemes->Get(i)->ffgroup();
100  for (unsigned int j = 0; j < procs->size(); ++j) {
101  auto itd = _formFactorBase.find(procs->Get(j)->c_str());
102  if(itd != _formFactorBase.end()) {
103  if(itd->second != groups->Get(j)->c_str()) {
104  result = false;
105  break;
106  }
107  }
108  _formFactorBase.emplace(procs->Get(j)->c_str(), groups->Get(j)->c_str());
109  }
110  }
111  else {
112  auto it2 = _formFactorSchemeNames.find(name);
113  if(it2 == _formFactorSchemeNames.end()) {
114  it2 = _formFactorSchemeNames.insert(make_pair(name, map<string, string>{})).first;
115  }
116  auto procs = schemes->Get(i)->ffproc();
117  auto groups = schemes->Get(i)->ffgroup();
118  for (unsigned int j = 0; j < procs->size(); ++j) {
119  auto itn = it2->second.find(procs->Get(j)->c_str());
120  if (itn != it2->second.end()) {
121  if (itn->second != groups->Get(j)->c_str()) {
122  result = false;
123  break;
124  }
125  }
126  it2->second.emplace(procs->Get(j)->c_str(), groups->Get(j)->c_str());
127  }
128  }
129  if(!result) return false;
130  }
131  else {
132  auto res = _formFactorSchemes.insert({name, map<HashId, FFIndex>{}});
133  auto ids = schemes->Get(i)->ffids();
134  auto chs = schemes->Get(i)->ffschemes();
135  for (unsigned int j = 0; j < ids->size(); ++j) {
136  res.first->second.insert({ids->Get(j), chs->Get(j)});
137  }
138  if (name == "Denominator") {
139  auto procs = schemes->Get(i)->ffproc();
140  auto groups = schemes->Get(i)->ffgroup();
141  for (unsigned int j = 0; j < procs->size(); ++j) {
142  _formFactorBase.insert({procs->Get(j)->c_str(), groups->Get(j)->c_str()});
143  }
144  } else {
145  auto res2 = _formFactorSchemeNames.insert({name, map<string, string>{}});
146  auto procs = schemes->Get(i)->ffproc();
147  auto groups = schemes->Get(i)->ffgroup();
148  for (unsigned int j = 0; j < procs->size(); ++j) {
149  res2.first->second.insert({procs->Get(j)->c_str(), groups->Get(j)->c_str()});
150  }
151  }
152  }
153  }
154  return true;
155  }
156 
157  void SchemeDefinitions::addFFScheme(const string& name, const map<string, string>& schemes) {
158  auto it = _formFactorSchemeNames.find(name);
159  if (it != _formFactorSchemeNames.end()) {
160  it->second = schemes;
161  }
162  else {
163  _formFactorSchemeNames.insert({name, schemes});
164  }
165  }
166 
167  void SchemeDefinitions::removeFFScheme(const string& name) {
168  auto it = _formFactorSchemeNames.find(name);
169  if (it != _formFactorSchemeNames.end()) {
170  _formFactorSchemeNames.erase(it);
171  }
172  }
173 
174  void SchemeDefinitions::setFFInputScheme(const map<string, string>& schemes) {
175  _formFactorBase = schemes;
176  }
177 
178  vector<string> SchemeDefinitions::getFFSchemeNames() const {
179  vector<string> names;
180  for (auto& elem : _formFactorSchemeNames) {
181  names.push_back(elem.first);
182  }
183  return names;
184  }
185 
186  const map<HashId, string> SchemeDefinitions::getScheme(const string& name) const {
187  const map<string, string>* toProcess;
188  if(name.size() == 0) {
189  toProcess = &_formFactorBase;
190  }
191  else {
192  auto it = _formFactorSchemeNames.find(name);
193  if (it != _formFactorSchemeNames.end()) {
194  toProcess = &(it->second);
195  }
196  else {
197  return map<HashId, string>{};
198  }
199  }
200  map<HashId, string> result;
201  PID& pdg = PID::instance();
202  for(auto& elem: *toProcess) {
203  vector<HashId> tmp = pdg.expandToValidVertexUIDs(elem.first, true);
204  for(auto elem2: tmp) {
205  result[elem2] = elem.second;
206  }
207  }
208  return result;
209  }
210 
211  map<HashId, map<string, vector<string>>> SchemeDefinitions::getFFDuplicates() const {
212  map<HashId, map<string, vector<string>>> result;
213  PID& pdg = PID::instance();
214  for(auto& elem: _formFactorSchemeNames) {
215  for(auto& elem2: elem.second) {
216  vector<string> chunks;
217  boost::algorithm::split(chunks, elem2.second, boost::algorithm::is_any_of("_"));
218  if(chunks.size() >= 2) {
219  string token = chunks[1];
220  for (size_t idx = 2; idx < chunks.size(); ++idx) {token += "_" + chunks[idx];}
221  vector<HashId> tmp = pdg.expandToValidVertexUIDs(elem2.first, true);
222  for(auto id: tmp) {
223  result[id][chunks[0]].push_back(token);
224  }
225  }
226  }
227  }
228  for (auto& elem2 : _formFactorBase) {
229  vector<string> chunks;
230  boost::algorithm::split(chunks, elem2.second, boost::algorithm::is_any_of("_"));
231  if (chunks.size() >= 2) {
232  string token = chunks[1];
233  for (size_t idx = 2; idx < chunks.size(); ++idx) {
234  token += "_" + chunks[idx];
235  }
236  vector<HashId> tmp = pdg.expandToValidVertexUIDs(elem2.first, true);
237  for (auto id : tmp) {
238  result[id][chunks[0]].push_back(token);
239  }
240  }
241  }
242  return result;
243  }
244 
245  const SchemeDict<map<HashId, FFIndex>>& SchemeDefinitions::getSchemeDefs() const {
246  return _formFactorSchemes;
247  }
248 
249  FFIndex SchemeDefinitions::getDenominatorFormFactor(HashId processId) const {
250  auto& den = _formFactorSchemes.find("Denominator")->second;
251  auto it = den.find(processId);
252  if (it != den.end()) {
253  return it->second;
254  } else {
255  return 0;
256  }
257  }
258 
259  set<FFIndex> SchemeDefinitions::getFormFactorIndices(HashId processId) const {
260  set<FFIndex> result;
261  for (auto& elem : _formFactorSchemes) {
262  auto it = elem.second.find(processId);
263  if (it != elem.second.end()) {
264  result.insert(it->second);
265  }
266  }
267  return result;
268  }
269 
270  SchemeDict<FFIndex> SchemeDefinitions::getFFSchemesForProcess(HashId id) const {
271  SchemeDict<FFIndex> result;
272  for (auto& elem : _formFactorSchemes) {
273  auto it = elem.second.find(id);
274  if (it != elem.second.end()) {
275  result.insert({elem.first, it->second});
276  } else {
277  MSG_ERROR("Process not found for scheme '" + elem.first + "', hash Id: " + to_string(id));
278  }
279  }
280  return result;
281  }
282 
283  void SchemeDefinitions::init(map<HashId, vector<string>> formFactGroups) {
284  _formFactorSchemes.clear();
285  auto names = getFFSchemeNames();
286  for (auto& elem : names) {
287  auto res = _formFactorSchemes.insert({elem, map<HashId, FFIndex>{}});
288  if (res.second) {
289  auto dict = getScheme(elem);
290  map<HashId, string>::iterator ite;
291  for (auto& elem2 : dict) {
292  auto it = formFactGroups.find(elem2.first);
293  if (it != formFactGroups.end()) {
294  auto it2 = find(it->second.begin(), it->second.end(), elem2.second);
295  if(it2 == it->second.end()){
296  MSG_ERROR("The parametrization '" + elem2.second + "' in scheme '" + elem +"' is unknown or misassigned. You're gonna need a bigger boat.");
297  }
298  ptrdiff_t pos =
299  distance(it->second.begin(), find(it->second.begin(), it->second.end(), elem2.second));
300  ptrdiff_t dim = static_cast<ptrdiff_t>(it->second.size());
301  if (pos >= 0 && pos < dim) {
302  res.first->second.insert({elem2.first, static_cast<size_t>(pos)});
303  }
304  }
305  }
306  }
307  }
308  auto dict = getScheme();
309  if(dict.size() != 0){
310  auto res = _formFactorSchemes.insert({"Denominator", map<HashId, FFIndex>{}});
311  if (res.second) {
312  for (auto& elem2 : dict) {
313  auto it = formFactGroups.find(elem2.first);
314  if (it != formFactGroups.end()) {
315  ptrdiff_t pos =
316  distance(it->second.begin(), find(it->second.begin(), it->second.end(), elem2.second));
317  ptrdiff_t dim = static_cast<ptrdiff_t>(it->second.size());
318  if (pos >= 0 && pos < dim) {
319  res.first->second.insert({elem2.first, static_cast<size_t>(pos)});
320  }
321  }
322  }
323  }
324  }
325  }
326 
327  YAML::Emitter& operator<<(YAML::Emitter& out, const SchemeDefinitions& s) {
328  out << YAML::convert<SchemeDefinitions>::encode(s);
329  return out;
330  }
331 
332 } // namespace Hammer
333 
334 namespace YAML {
335 
336  Node convert<::Hammer::SchemeDefinitions>::encode(const ::Hammer::SchemeDefinitions& value) {
337  YAML::Node node;
338  if (value._formFactorSchemeNames.size() > 0) {
339  YAML::Node numNode;
340  for(auto& elem: value._formFactorSchemeNames) {
341  YAML::Node tmpAssoc;
342  for(auto& elem2: elem.second) {
343  tmpAssoc[elem2.first] = elem2.second;
344  }
345  numNode[elem.first] = tmpAssoc;
346  }
347  node["NumeratorSchemes"] = numNode;
348  }
349  YAML::Node tmpAssoc;
350  for (auto& elem : value._formFactorBase) {
351  tmpAssoc[elem.first] = elem.second;
352  }
353  node["Denominator"] = tmpAssoc;
354  return node;
355  }
356 
357  bool convert<::Hammer::SchemeDefinitions>::decode(const Node& node, ::Hammer::SchemeDefinitions& value) {
358  if (node.IsMap()) {
359  for (const auto& entry2 : node) {
360  string what = entry2.first.as<string>();
361  if (what == "NumeratorSchemes") {
362  YAML::Node schemes = entry2.second;
363  if (schemes.IsMap()) {
364  value._formFactorSchemeNames.clear();
365  for (const auto& scheme : schemes) {
366  string name = scheme.first.as<string>();
367  auto res = value._formFactorSchemeNames.insert({name, map<string, string>{}});
368  if (scheme.second.IsMap()) {
369  YAML::Node processes = scheme.second;
370  for (const auto& process : processes) {
371  string procname = process.first.as<string>();
372  string proctype = process.second.as<string>();
373  res.first->second.insert({procname, proctype});
374  }
375  } else {
376  return false;
377  }
378  }
379  } else {
380  return false;
381  }
382  } else if (what == "Denominator") {
383  value._formFactorBase.clear();
384  if (entry2.second.IsMap()) {
385  YAML::Node processes = entry2.second;
386  for (const auto& process : processes) {
387  string procname = process.first.as<string>();
388  string proctype = process.second.as<string>();
389  value._formFactorBase.insert({procname, proctype});
390  }
391  } else {
392  return false;
393  }
394  } else {
395  return false;
396  }
397  }
398  } else {
399  return false;
400  }
401  return true;
402  }
403 
404 }
PDG codes to UID functions.
TensorData read(const Serial::FBTensor *msgreader)
Definition: Operations.cc:76
YAML::Emitter & operator<<(YAML::Emitter &out, const ProcessDefinitions &s)
size_t FFIndex
Definition: IndexTypes.hh:69
std::vector< HashId > expandToValidVertexUIDs(const std::string &name, const bool &hadOnly=false) const
Definition: Pdg.cc:833
SchemeDict< std::map< std::string, std::string > > _formFactorSchemeNames
the Hammer numerator form factor schemes
Hammer exception definitions.
Logging class.
Definition: Logging.hh:33
Hammer class for dealing with particle data.
Definition: Pdg.hh:32
Hammer particle data class.
Container class for Scheme Definitions.
std::map< std::string, std::string > _formFactorBase
the Hammer denominator form factor scheme
std::map< SchemeName, T > SchemeDict
Definition: IndexTypes.hh:64
#define MSG_ERROR(x)
Definition: Logging.hh:367
size_t HashId
Definition: IndexTypes.hh:31
Serialization related typedefs and includes.
Hammer settings manager class.