Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Event.cc
Go to the documentation of this file.
1 ///
2 /// @file Event.cc
3 /// @brief Hammer event class
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++ -*-
13 #include "Hammer/Tools/Logging.hh"
14 #include "Hammer/Event.hh"
15 #include "Hammer/Histos.hh"
16 #include "Hammer/IndexLabels.hh"
17 #include "Hammer/Tools/Utils.hh"
20 #include "Hammer/ExternalData.hh"
22 
23 using namespace std;
24 
25 namespace Hammer {
26 
27  namespace MD = MultiDimensional;
28 
29  Event::Event(Histos* histograms, DictionaryManager* dict) {
30  _histograms = histograms;
31  _dictionaries = dict;
32  _eventWeight = 1.0;
33  }
34 
35  Event::~Event() noexcept {
36  clear();
37  _histograms = nullptr;
38  _dictionaries = nullptr;
39  }
40 
41  void Event::clear() {
42  _processes.clear();
43  _histogramBins.clear();
44  _eventWeight = 1.0;
45  _eventId.clear();
46  }
47 
48  void Event::setEventBaseWeight(double weight) {
49  _eventWeight = weight;
50  }
51 
52  double Event::getEventBaseWeight() const {
53  return _eventWeight;
54  }
55 
56  HashId Event::addProcess(Process& p) {
57  // initialize Process first so that id's are visible to user and available
58  // to decide whether ProcManager should be added or not.
59  p.setSettingsHandler(*this);
60  p.initialize();
61  auto res = addProcManager(ProcManager{p});
62  return res;
63  }
64 
65  HashId Event::addProcManager(ProcManager&& pm) {
66  pm.setSettingsHandler(*this);
67  pm.initialize(_dictionaries);
68  HashId idx = pm.inputs().getId();
69  if (idx == 0) {
70  return 0;
71  }
72  _processes.emplace(idx, move(pm));
73  _eventId.insert(idx);
74  return idx;
75  }
76 
77 
78  void Event::removeProcess(HashId idx) {
79  auto it = _processes.find(idx);
80  if (it != _processes.end()) {
81  _processes.erase(it);
82  }
83  auto it2 = _eventId.find(idx);
84  if (it2 != _eventId.end()) {
85  _eventId.erase(it2);
86  }
87  }
88 
89  const ProcManager& Event::getProcManager(HashId id) const {
90  return getOrThrow(_processes, id, RangeError("Invalid process id"));
91  }
92 
93  ProcManager& Event::getProcManager(HashId id) {
94  return getOrThrow(_processes, id, RangeError("Invalid process id"));
95  }
96 
97  void Event::init() {
98  // initSettings();
99  if(_schemes.size() == 0) {
100  _schemes = _dictionaries->schemeDefs().getFFSchemeNames();
101  }
102  }
103 
104  void Event::calc() {
105  for (auto& elem : _processes) {
106  elem.second.calc();
107  }
108  /// @todo anything else?
109  }
110 
111  void Event::setHistogramBin(const string& label, const IndexList indices) {
112  auto it = _histogramBins.find(label);
113  if (it != _histogramBins.end()) {
114  it->second = indices;
115  } else {
116  _histogramBins.insert({label, indices});
117  }
118  }
119 
120  void Event::fillHistograms() {
121  EventUID evtId;
122  transform(_processes.cbegin(), _processes.cend(), inserter(evtId, evtId.end()), [](auto const& m) { return m.first; });
123  if(evtId.size() == 0){
124  evtId.insert(0);
125  }
126  _histograms->setEventId(evtId);
127  for(auto& histobins : _histogramBins){
128  for(auto& scheme : _schemes){
129  Tensor histoWeight;
130  if(_processes.size() > 0) {
131  bool first = true;
132  for(const auto& proc : _processes){
133  if (first) {
134  histoWeight = proc.second.results().processWeight(scheme);
135  first = false;
136  } else {
137  histoWeight.dot(proc.second.results().processWeight(scheme), {IndexLabel::NONE});
138  }
139  }
140  }
141  else {
142  histoWeight = Tensor{"", MD::makeScalar(1.)};
143  }
144  _histograms->fillHisto(histobins.first, scheme, histobins.second, histoWeight, _eventWeight);
145  }
146  }
147  }
148 
149  const EventUID& Event::getEventId() const {
150  return _eventId;
151  }
152 
153  void Event::write(flatbuffers::FlatBufferBuilder* msgwriter) const {
154  vector<flatbuffers::Offset<Serial::FBProcess>> procs;
155  procs.reserve(_processes.size());
156  for (auto& elem : _processes) {
158  elem.second.write(msgwriter, &tmp);
159  procs.push_back(tmp);
160  }
161  vector<uint64_t> ids;
162  ids.reserve(_eventId.size());
163  copy(_eventId.begin(),_eventId.end(), back_inserter(ids));
164  auto serialid = msgwriter->CreateVector(ids);
165  Serial::FBIdSetBuilder evtid{*msgwriter};
166  evtid.add_ids(serialid);
167  auto serialevtid = evtid.Finish();
168  auto serialprocs = msgwriter->CreateVector(procs);
169  Serial::FBEventBuilder serialevent{*msgwriter};
170  serialevent.add_processes(serialprocs);
171  serialevent.add_id(serialevtid);
172  serialevent.add_weight(_eventWeight);
173  auto evtoffset = serialevent.Finish();
174  msgwriter->Finish(evtoffset);
175  }
176 
177  bool Event::read(const Serial::FBEvent* msgreader, bool merge) {
178  if (msgreader != nullptr) {
179  bool result = true;
180  auto procs = msgreader->processes();
181  if(!merge) {
182  _processes.clear();
183  }
184  for (unsigned int i = 0; i < procs->size(); ++i) {
185  auto elem = procs->Get(i);
186  auto it = _processes.find(elem->ids()->id());
187  if (it != _processes.end()) {
188  result &= it->second.read(elem, merge);
189  }
190  else {
191  Process p;
192  p.setSettingsHandler(*this);
193  p.read(elem->ids());
194  p.initialize();
195  auto res = _processes.emplace(p.getId(), ProcManager{p});
196  res.first->second.setSettingsHandler(*this);
197  res.first->second.initialize(_dictionaries);
198  res.first->second.read(elem, false);
199  }
200  }
201  auto evtids = msgreader->id()->ids();
202  if(!merge) {
203  _eventId.clear();
204  }
205  for (unsigned int i = 0; i < evtids->size(); ++i) {
206  _eventId.insert(evtids->Get(i));
207  }
208  _eventWeight = msgreader->weight();
209  return result;
210  }
211  return false;
212  }
213 
214  Log& Event::getLog() const {
215  return Log::getLog("Hammer.Event");
216  }
217 
218  void Event::defineSettings() {
219  setPath("Hammer.Event");
220  }
221 
222  const Tensor& Event::getAmplitude(HashId process, WTerm what) const {
223  return getProcManager(process).results().processAmplitude(what);
224  }
225 
226  const Tensor& Event::getSquaredAmplitude(HashId process, WTerm what) const {
227  return getProcManager(process).results().processAmplitudeSquared(what);
228  }
229 
230  ProcIdDict<reference_wrapper<const Tensor>> Event::getAmplitudes(WTerm what) const {
232  for(auto& proc: _processes) {
233  auto t = cref(proc.second.results().processAmplitude(what));
234  result.insert({proc.first, t});
235  }
236  return result;
237  }
238 
239  ProcIdDict<reference_wrapper<const Tensor>> Event::getSquaredAmplitudes(WTerm what) const {
241  for(auto& proc: _processes) {
242  auto t = cref(proc.second.results().processAmplitudeSquared(what));
243  result.insert({proc.first, t});
244  }
245  return result;
246  }
247 
248  vector<reference_wrapper<const Tensor>> Event::getProcessFormFactors(const string& scheme, HashId process) const {
249  return getProcManager(process).results().processFormFactors(scheme);
250  }
251 
252  ProcIdDict<vector<reference_wrapper<const Tensor>>> Event::getFormFactors(const string& scheme) const {
254  for(auto& proc: _processes) {
255  result.insert({proc.first, proc.second.results().processFormFactors(scheme)});
256  }
257  return result;
258  }
259 
260  const Tensor& Event::getTensorWeight(const string& scheme, HashId process) const {
261  return getProcManager(process).results().processWeight(scheme);
262  }
263 
264  ProcIdDict<reference_wrapper<const Tensor>> Event::getTensorWeights(const string& scheme) const {
266  for(auto& proc: _processes) {
267  auto t = cref(proc.second.results().processWeight(scheme));
268  result.insert({proc.first, t});
269  }
270  return result;
271  }
272 
273  double Event::getWeight(const string& scheme, HashId process) const {
274  const Tensor& t = getProcManager(process).results().processWeight(scheme);
275  auto labst = t.labels();
276  auto ext = _dictionaries->externalData().getExternalVectors(scheme, labst);
277  ext.dot(t);
278  if(ext.rank() != 0) {
279  MSG_ERROR("Invalid rank at end of evaluation");
280  }
281  return ext.element().real();
282  }
283 
284  ProcIdDict<double> Event::getWeights(const string& scheme) const {
285  ProcIdDict<double> result;
286  for(auto& proc: _processes) {
287  const Tensor& t = proc.second.results().processWeight(scheme);
288  auto labst = t.labels();
289  auto ext = _dictionaries->externalData().getExternalVectors(scheme, labst);
290  ext.dot(t);
291  if(ext.rank() != 0) {
292  MSG_ERROR("Invalid rank at end of evaluation");
293  }
294  result.insert({proc.first, ext.element().real()});
295  }
296  return result;
297  }
298 
299 
300 } // namespace Hammer
std::set< ProcessUID > EventUID
Definition: IndexTypes.hh:53
Hammer event class.
auto const & getOrThrow(const std::map< KeyType, ValueType > &data, KeyType key, std::exception error)
Definition: Tools/Utils.hh:51
void read(const Serial::FBProcIDs *msgreader)
Definition: Process.cc:414
TensorData read(const Serial::FBTensor *msgreader)
Definition: Operations.cc:76
LabelsList labels() const
get the labels of all the indices at once
Definition: Tensor.cc:83
HashId getId() const
Definition: Process.cc:389
Container class for values of WC and FF vectors.
Decay process class.
Definition: Process.hh:34
Tensor indices label definitions.
bool initialize()
Definition: Process.cc:275
Message logging routines.
Hammer histogram manager.
Hammer histogram manager class.
Definition: Histos.hh:43
virtual void setSettingsHandler(SettingsHandler &sh)
set link to settings repository handler.
std::vector< IndexType > IndexList
Decay process class.
Definition: ProcManager.hh:42
Order-0 tensor data container.
Logging class.
Definition: Logging.hh:33
Multidimensional tensor class with complex numbers as elements.
Definition: Tensor.hh:33
TensorData makeScalar(complex< double > value)
std::map< ProcessUID, T > ProcIdDict
Definition: IndexTypes.hh:51
Container class for Scheme Definitions.
Tensor & dot(const Tensor &other, const UniqueLabelsList &indices={})
contract this tensor with another and stores the result in this tensor
Definition: Tensor.cc:114
#define MSG_ERROR(x)
Definition: Logging.hh:367
size_t HashId
Definition: IndexTypes.hh:31
Out-of-range error class.
Definition: Exceptions.hh:49
Serialization related typedefs and includes.
Global container class for amplitudes, rates, FFs, data.