gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-252-gf9a3f78
a Global And Modular Bsm Inference Tool
AnalysisContainer.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
26 
27 #include <stdexcept>
28 
29 #include <omp.h>
30 
31 #include "gambit/cmake/cmake_variables.hpp"
35 
36 // #define ANALYSISCONTAINER_DEBUG
37 
38 namespace Gambit
39 {
40  namespace ColliderBit
41  {
42 
43  // Add analysis names here and only here (trick to avoid duplication)
44  // - If the analysis depends on RestFrames (which uses ROOT), add it to MAP_ANALYSES_WITH_ROOT_RESTFRAMES
45  // - If the analysis only depends on ROOT, add it to MAP_ANALYSES_WITH_ROOT
46  // - Else, add the analysis to MAP_ANALYSES
47  #define MAP_ANALYSES_WITH_ROOT_RESTFRAMES(F) \
48  F(ATLAS_13TeV_RJ3L_2Lep2Jets_36invfb) \
49  F(ATLAS_13TeV_RJ3L_3Lep_36invfb) \
50  F(ATLAS_13TeV_RJ3L_lowmass_36invfb) \
51 
52  #define MAP_ANALYSES_WITH_ROOT(F) \
53  F(ATLAS_13TeV_1LEPStop_36invfb) \
54 
55  #define MAP_ANALYSES(F) \
56  F(Minimum) \
57  F(Covariance) \
58  F(ATLAS_13TeV_0LEP_13invfb) \
59  F(ATLAS_13TeV_0LEP_36invfb) \
60  F(ATLAS_13TeV_0LEPStop_36invfb) \
61  F(ATLAS_13TeV_2LEPStop_36invfb) \
62  F(ATLAS_13TeV_MultiLEP_confnote_36invfb) \
63  F(ATLAS_13TeV_MultiLEP_36invfb) \
64  F(ATLAS_13TeV_MultiLEP_2Lep0Jets_36invfb) \
65  F(ATLAS_13TeV_MultiLEP_2LepPlusJets_36invfb) \
66  F(ATLAS_13TeV_MultiLEP_3Lep_36invfb) \
67  F(ATLAS_13TeV_2OSLEP_chargino_80invfb) \
68  F(ATLAS_13TeV_2OSLEP_chargino_binned_80invfb) \
69  F(ATLAS_13TeV_2OSLEP_chargino_inclusive_80invfb)\
70  F(ATLAS_13TeV_4LEP_36invfb) \
71  F(ATLAS_13TeV_2bMET_36invfb) \
72  F(ATLAS_13TeV_3b_24invfb) \
73  F(ATLAS_13TeV_3b_discoverySR_24invfb) \
74  F(ATLAS_13TeV_3b_36invfb) \
75  F(ATLAS_13TeV_3b_discoverySR_36invfb) \
76  F(ATLAS_13TeV_PhotonGGM_36invfb) \
77  F(ATLAS_13TeV_ZGammaGrav_CONFNOTE_80invfb) \
78  F(ATLAS_8TeV_0LEP_20invfb) \
79  F(ATLAS_8TeV_0LEPStop_20invfb) \
80  F(ATLAS_8TeV_1LEPStop_20invfb) \
81  F(ATLAS_8TeV_2bStop_20invfb) \
82  F(ATLAS_8TeV_2LEPEW_20invfb) \
83  F(ATLAS_8TeV_2LEPStop_20invfb) \
84  F(ATLAS_8TeV_3LEPEW_20invfb) \
85  F(ATLAS_8TeV_1LEPbb_20invfb) \
86  F(CMS_13TeV_0LEP_13invfb) \
87  F(CMS_13TeV_0LEP_36invfb) \
88  F(CMS_13TeV_1LEPbb_36invfb) \
89  F(CMS_13TeV_1LEPStop_36invfb) \
90  F(CMS_13TeV_2LEPStop_36invfb) \
91  F(CMS_13TeV_2LEPsoft_36invfb) \
92  F(CMS_13TeV_2LEPsoft_36invfb_nocovar) \
93  F(CMS_13TeV_2OSLEP_36invfb) \
94  F(CMS_13TeV_2OSLEP_36invfb_nocovar) \
95  F(CMS_13TeV_2OSLEP_confnote_36invfb) \
96  F(CMS_13TeV_2OSLEP_chargino_stop_36invfb) \
97  F(CMS_13TeV_Photon_GMSB_36invfb) \
98  F(CMS_13TeV_2OSLEP_for_stop_36invfb) \
99  F(CMS_13TeV_2OSLEP_for_chargino_36invfb) \
100  F(CMS_13TeV_MultiLEP_36invfb) \
101  F(CMS_13TeV_MultiLEP_2SSLep_36invfb) \
102  F(CMS_13TeV_MultiLEP_3Lep_36invfb) \
103  F(CMS_13TeV_MultiLEP_Full_36invfb) \
104  F(CMS_13TeV_MultiLEP_Full_2SSLep_36invfb) \
105  F(CMS_13TeV_MultiLEP_Full_3Lep_36invfb) \
106  F(CMS_13TeV_MultiLEP_Full_3Lep_rebinned_36invfb) \
107  F(CMS_13TeV_MONOJET_36invfb) \
108  F(CMS_8TeV_1LEPDMTOP_20invfb) \
109  F(CMS_8TeV_2LEPDMTOP_20invfb) \
110  F(CMS_8TeV_MultiLEP_20invfb) \
111  F(CMS_8TeV_MultiLEP_3Lep_20invfb) \
112  F(CMS_8TeV_MultiLEP_4Lep_20invfb) \
113  F(CMS_8TeV_MONOJET_20invfb) \
114 
115  #define DECLARE_ANALYSIS_FACTORY(ANAME) \
117  Analysis* create_Analysis_ ## ANAME(); \
118  std::string getDetector_ ## ANAME();
119 
121  #ifndef EXCLUDE_ROOT
122  #ifndef EXCLUDE_RESTFRAMES
124  #endif
126  #endif
128 
129 
130  #define IF_X_RTN_CREATE_ANA_X(A) \
131  if (name == #A) return create_Analysis_ ## A();
132 
134  Analysis* mkAnalysis(const str& name)
135  {
136  #ifndef EXCLUDE_ROOT
137  #ifndef EXCLUDE_RESTFRAMES
139  #endif
141  #endif
143 
144  // If we end up here the analysis has not been found
145  utils_error().raise(LOCAL_INFO, "The analysis " + name + " is not a known ColliderBit analysis.");
146  return nullptr;
147  }
148 
150  #define IF_X_RTN_DETECTOR(A) \
151  if (name == #A) return getDetector_ ## A();
152 
154  str getDetector(const str& name)
155  {
156  #ifndef EXCLUDE_ROOT
157  #ifndef EXCLUDE_RESTFRAMES
159  #endif
161  #endif
163 
164  // If we end up here the analysis has not been found
165  utils_error().raise(LOCAL_INFO, "The analysis " + name + " is not a known ColliderBit analysis.");
166  return "";
167  }
168 
170  std::map<str,std::map<int,AnalysisContainer*> > AnalysisContainer::instances_map;
171 
173  AnalysisContainer::AnalysisContainer() : current_collider(""),
174  is_registered(false),
175  n_threads(omp_get_max_threads()),
176  base_key("")
177  {
178  #ifdef ANALYSISCONTAINER_DEBUG
179  std::cout << "DEBUG: thread " << omp_get_thread_num() << ": AnalysisContainer::ctor: created at " << this << std::endl;
180  #endif
181  }
182 
183 
186  {
187  clear();
188  }
189 
190 
193  {
194  base_key = base_key_in;
195 
196  #pragma omp critical
197  {
198  if (instances_map.count(base_key) == 0 || instances_map[base_key].count(omp_get_thread_num()) == 0)
199  {
200  // Add this instance to the instances map
201  instances_map[base_key][omp_get_thread_num()] = this;
202  is_registered = true;
203 
204  #ifdef ANALYSISCONTAINER_DEBUG
205  std::cout << "DEBUG: thread " << omp_get_thread_num() << ": AnalysisContainer::register_thread: added " << this << " to instances_map with key " << base_key << "-" << omp_get_thread_num() << std::endl;
206  #endif
207  }
208  else
209  {
210  if (not is_registered)
211  {
212  utils_error().raise(LOCAL_INFO, "There is already an entry with this key in instances_map, but it's not this one! Something has gone wrong...");
213  }
214  else
215  {
216  #ifdef ANALYSISCONTAINER_DEBUG
217  std::cout << "DEBUG: thread " << omp_get_thread_num() << ": AnalysisContainer::register_thread: this instance is already in instances_map" << std::endl;
218  #endif
219  }
220  }
221  }
222  }
223 
224 
227  {
229  // Loop through double map and delete the analysis pointers
230  for(auto& collider_map_pair : analyses_map)
231  {
232  for(auto& analysis_pointer_pair : collider_map_pair.second)
233  {
234  delete analysis_pointer_pair.second;
235  analysis_pointer_pair.second = nullptr;
236  }
237  }
238 
239  // Clear the double map
240  analyses_map.clear();
241  }
242 
243 
246  {
247  current_collider = collider_name;
248  }
249 
250 
253  {
254  return current_collider;
255  }
256 
257 
259  bool AnalysisContainer::has_analyses(str collider_name) const
260  {
261  bool result = false;
262 
263  if (analyses_map.count(collider_name) > 0)
264  {
265  if (analyses_map.at(collider_name).size() > 0)
266  {
267  result = true;
268  }
269  }
270 
271  return result;
272  }
273 
276  {
278  }
279 
280 
282  void AnalysisContainer::init(const std::vector<str>& analysis_names, str collider_name)
283  {
284  // If a map of analyses already exist for this collider, clear it
285  if (analyses_map.count(collider_name) > 0)
286  {
287  analyses_map[collider_name].clear();
288  }
289 
290  // Create analysis pointers and add to the map
291  for (auto& aname : analysis_names)
292  {
293  analyses_map[collider_name][aname] = mkAnalysis(aname);
294  }
295  }
296 
298  void AnalysisContainer::init(const std::vector<str>& analysis_names)
299  {
300  init(analysis_names, current_collider);
301  }
302 
303 
305  void AnalysisContainer::reset(str collider_name, str analysis_name)
306  {
307  analyses_map[collider_name][analysis_name]->reset();
308  }
309 
311  void AnalysisContainer::reset(str collider_name)
312  {
313  for (auto& analysis_pointer_pair : analyses_map[collider_name])
314  {
315  analysis_pointer_pair.second->reset();
316  }
317  }
318 
321  {
323  }
324 
327  {
328  for(auto& collider_map_pair : analyses_map)
329  {
330  reset(collider_map_pair.first);
331  }
332  }
333 
334 
336  const Analysis* AnalysisContainer::get_analysis_pointer(str collider_name, str analysis_name) const
337  {
338  return analyses_map.at(collider_name).at(analysis_name);
339  }
340 
342  const std::map<str,Analysis*>& AnalysisContainer::get_collider_analyses_map(str collider_name) const
343  {
344  return analyses_map.at(collider_name);
345  }
346 
348  const std::map<str,Analysis*>& AnalysisContainer::get_current_analyses_map() const
349  {
350  return analyses_map.at(current_collider);
351  }
352 
354  const std::map<str,std::map<str,Analysis*> >& AnalysisContainer::get_full_analyses_map() const
355  {
356  return analyses_map;
357  }
358 
360  void AnalysisContainer::analyze(const HEPUtils::Event& event, str collider_name, str analysis_name) const
361  {
362  analyses_map.at(collider_name).at(analysis_name)->analyze(event);
363  }
364 
366  void AnalysisContainer::analyze(const HEPUtils::Event& event, str collider_name) const
367  {
368  for (auto& analysis_pointer_pair : analyses_map.at(collider_name))
369  {
370  analysis_pointer_pair.second->analyze(event);
371  }
372  }
373 
375  void AnalysisContainer::analyze(const HEPUtils::Event& event) const
376  {
377  analyze(event, current_collider);
378  }
379 
382  void AnalysisContainer::collect_and_add_signal(str collider_name, str analysis_name)
383  {
384  for (auto& thread_container_pair : instances_map.at(base_key))
385  {
386  if (thread_container_pair.first == omp_get_thread_num()) continue;
387  AnalysisContainer* other_container = thread_container_pair.second;
388  Analysis* other_analysis = other_container->analyses_map.at(collider_name).at(analysis_name);
389  analyses_map.at(collider_name).at(analysis_name)->add(other_analysis);
390  }
391  }
392 
396  {
397  for (auto& analysis_pointer_pair : analyses_map[collider_name])
398  {
399  str analysis_name = analysis_pointer_pair.first;
400  collect_and_add_signal(collider_name, analysis_name);
401  }
402  }
403 
407  {
409  }
410 
412  void AnalysisContainer::scale(str collider_name, str analysis_name, double xsec_per_event)
413  {
414  analyses_map[collider_name][analysis_name]->scale(xsec_per_event);
415  }
416 
418  void AnalysisContainer::scale(str collider_name, double xsec_per_event)
419  {
420  for (auto& analysis_pointer_pair : analyses_map[collider_name])
421  {
422  str analysis_name = analysis_pointer_pair.first;
423  scale(collider_name, analysis_name, xsec_per_event);
424  }
425  }
426 
428  void AnalysisContainer::scale(double xsec_per_event)
429  {
430  scale(current_collider, xsec_per_event);
431  }
432 
434  void AnalysisContainer::scale_all(double xsec_per_event)
435  {
436  for (auto& collider_map_pair : analyses_map)
437  {
438  str collider_name = collider_map_pair.first;
439  scale(collider_name, xsec_per_event);
440  }
441  }
442 
443  }
444 }
MAP_ANALYSES_WITH_ROOT_RESTFRAMES(DECLARE_ANALYSIS_FACTORY) MAP_ANALYSES_WITH_ROOT(DECLARE_ANALYSIS_FACTORY) MAP_ANALYSES(DECLARE_ANALYSIS_FACTORY) Analysis *mkAnalysis(const str &name)
Forward declarations using DECLARE_ANALYSIS_FACTORY(ANAME)
#define IF_X_RTN_CREATE_ANA_X(A)
str current_collider
String identifying the currently active collider.
void analyze(const HEPUtils::Event &, str, str) const
Pass event through specific analysis.
void init(const std::vector< str > &, str)
Initialize analyses (by names) for a specified collider.
void reset()
Reset all analyses for the current collider.
const std::map< str, Analysis * > & get_current_analyses_map() const
Get analyses map for the current collider.
EXPORT_SYMBOLS error & utils_error()
Utility errors.
const std::map< str, Analysis * > & get_collider_analyses_map(str) const
Get analyses map for a specific collider.
void clear()
Delete and clear the analyses contained within this instance.
static std::map< str, std::map< int, AnalysisContainer * > > instances_map
A map with pointers to all instances of this class.
#define LOCAL_INFO
Definition: local_info.hpp:34
void register_thread(str)
Add container to instances map.
bool has_analyses() const
Does this instance contain analyses for the current collider.
#define MAP_ANALYSES_WITH_ROOT(F)
str base_key
Key for the instances_map.
Analysis * mkAnalysis(const str &name)
Create a new analysis based on a name string.
void reset_all()
Reset all analyses for all colliders.
std::map< str, std::map< str, Analysis * > > analyses_map
A map of maps of pointer-to-Analysis.
const Analysis * get_analysis_pointer(str, str) const
Get pointer to specific analysis.
const std::map< str, std::map< str, Analysis * > > & get_full_analyses_map() const
Get the full analyses map.
void collect_and_add_signal()
Collect signal predictions from other threads and add to this one, for all analyses for the current c...
str get_current_collider() const
Get name of current collider.
#define MAP_ANALYSES(F)
A class for collider analyses within ColliderBit.
Definition: Analysis.hpp:41
Class for holding ColliderBit analyses.
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
void set_current_collider(str)
Set name of current collider.
str getDetector(const str &name)
Return the detector to be used for a given analysis name, checking that the analysis exists...
void scale_all(double)
Scale results for all analyses across all colliders.
Exception objects required for standalone compilation.
void scale(str, str, double)
Scale results for specific analysis.
A class for managing collections of Analysis instances.
bool is_registered
Has this instance been registered in the instances_map?
TODO: see if we can use this one:
Definition: Analysis.hpp:33
Class for ColliderBit analyses.
#define DECLARE_ANALYSIS_FACTORY(ANAME)
For analysis factory function declaration.
#define IF_X_RTN_DETECTOR(A)
For the string-based analysis checker and detector retriever getDetector.