gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
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_0LEP_139invfb) \
61  F(ATLAS_13TeV_0LEPStop_36invfb) \
62  F(ATLAS_13TeV_2LEPStop_36invfb) \
63  F(ATLAS_13TeV_2LEPStop_139invfb) \
64  F(ATLAS_13TeV_2LEPStop_inclusive_139invfb) \
65  F(ATLAS_13TeV_2LEPStop_exclusive_139invfb) \
66  F(ATLAS_13TeV_MultiLEP_confnote_36invfb) \
67  F(ATLAS_13TeV_MultiLEP_36invfb) \
68  F(ATLAS_13TeV_MultiLEP_2Lep0Jets_36invfb) \
69  F(ATLAS_13TeV_MultiLEP_2LepPlusJets_36invfb) \
70  F(ATLAS_13TeV_MultiLEP_3Lep_36invfb) \
71  F(ATLAS_13TeV_MultiLEP_strong_139invfb) \
72  F(ATLAS_13TeV_2OSLEP_chargino_80invfb) \
73  F(ATLAS_13TeV_2OSLEP_chargino_binned_80invfb) \
74  F(ATLAS_13TeV_2OSLEP_chargino_inclusive_80invfb) \
75  F(ATLAS_13TeV_2OSLEP_chargino_139invfb) \
76  F(ATLAS_13TeV_2OSLEP_chargino_inclusive_139invfb) \
77  F(ATLAS_13TeV_2OSLEP_chargino_binned_139invfb) \
78  F(ATLAS_13TeV_4LEP_36invfb) \
79  F(ATLAS_13TeV_4LEP_139invfb) \
80  F(ATLAS_13TeV_2bMET_36invfb) \
81  F(ATLAS_13TeV_3b_24invfb) \
82  F(ATLAS_13TeV_3b_discoverySR_24invfb) \
83  F(ATLAS_13TeV_3b_36invfb) \
84  F(ATLAS_13TeV_3b_discoverySR_36invfb) \
85  F(ATLAS_13TeV_PhotonGGM_36invfb) \
86  F(ATLAS_13TeV_ZGammaGrav_CONFNOTE_80invfb) \
87  F(ATLAS_13TeV_2OSLEP_Z_139invfb) \
88  F(ATLAS_8TeV_0LEP_20invfb) \
89  F(ATLAS_8TeV_0LEPStop_20invfb) \
90  F(ATLAS_8TeV_1LEPStop_20invfb) \
91  F(ATLAS_8TeV_2bStop_20invfb) \
92  F(ATLAS_8TeV_2LEPEW_20invfb) \
93  F(ATLAS_8TeV_2LEPStop_20invfb) \
94  F(ATLAS_8TeV_3LEPEW_20invfb) \
95  F(ATLAS_8TeV_1LEPbb_20invfb) \
96  F(ATLAS_7TeV_1OR2LEPStop_4_7invfb) \
97  F(ATLAS_7TeV_2LEPStop_4_7invfb) \
98  F(CMS_13TeV_0LEP_13invfb) \
99  F(CMS_13TeV_0LEP_36invfb) \
100  F(CMS_13TeV_0LEP_137invfb) \
101  F(CMS_13TeV_1LEPbb_36invfb) \
102  F(CMS_13TeV_1LEPStop_36invfb) \
103  F(CMS_13TeV_2LEPStop_36invfb) \
104  F(CMS_13TeV_2LEPsoft_36invfb) \
105  F(CMS_13TeV_2LEPsoft_36invfb_nocovar) \
106  F(CMS_13TeV_2LEPsoft_stop_36invfb) \
107  F(CMS_13TeV_2LEPsoft_stop_36invfb_nocovar) \
108  F(CMS_13TeV_2OSLEP_36invfb) \
109  F(CMS_13TeV_2OSLEP_36invfb_nocovar) \
110  F(CMS_13TeV_2OSLEP_confnote_36invfb) \
111  F(CMS_13TeV_2OSLEP_chargino_stop_36invfb) \
112  F(CMS_13TeV_2OSLEP_for_stop_36invfb) \
113  F(CMS_13TeV_2OSLEP_for_chargino_36invfb) \
114  F(CMS_13TeV_2SSLEP_Stop_36invfb) \
115  F(CMS_13TeV_2SSLEP_Stop_inclusive_36invfb) \
116  F(CMS_13TeV_2SSLEP_Stop_exclusive_36invfb) \
117  F(CMS_13TeV_2SSLEP_Stop_137invfb) \
118  F(CMS_13TeV_Photon_GMSB_36invfb) \
119  F(CMS_13TeV_2Photon_GMSB_36invfb) \
120  F(CMS_13TeV_1Photon1Lepton_36invfb) \
121  F(CMS_13TeV_1Photon1Lepton_emu_combined_36invfb) \
122  F(CMS_13TeV_MultiLEP_36invfb) \
123  F(CMS_13TeV_MultiLEP_2SSLep_36invfb) \
124  F(CMS_13TeV_MultiLEP_3Lep_36invfb) \
125  F(CMS_13TeV_MultiLEP_Full_36invfb) \
126  F(CMS_13TeV_MultiLEP_Full_2SSLep_36invfb) \
127  F(CMS_13TeV_MultiLEP_Full_3Lep_36invfb) \
128  F(CMS_13TeV_MultiLEP_Full_3Lep_rebinned_36invfb) \
129  F(CMS_13TeV_MONOJET_36invfb) \
130  F(CMS_8TeV_1LEPDMTOP_20invfb) \
131  F(CMS_8TeV_2LEPDMTOP_20invfb) \
132  F(CMS_8TeV_MultiLEP_20invfb) \
133  F(CMS_8TeV_MultiLEP_3Lep_20invfb) \
134  F(CMS_8TeV_MultiLEP_4Lep_20invfb) \
135  F(CMS_8TeV_MONOJET_20invfb) \
136 
137  #define DECLARE_ANALYSIS_FACTORY(ANAME) \
139  Analysis* create_Analysis_ ## ANAME(); \
140  std::string getDetector_ ## ANAME();
141 
143  #ifndef EXCLUDE_ROOT
144  #ifndef EXCLUDE_RESTFRAMES
146  #endif
148  #endif
150 
151 
152  #define IF_X_RTN_CREATE_ANA_X(A) \
153  if (name == #A) return create_Analysis_ ## A();
154 
156  Analysis* mkAnalysis(const str& name)
157  {
158  #ifndef EXCLUDE_ROOT
159  #ifndef EXCLUDE_RESTFRAMES
161  #endif
163  #endif
165 
166  // If we end up here the analysis has not been found
167  utils_error().raise(LOCAL_INFO, "The analysis " + name + " is not a known ColliderBit analysis.");
168  return nullptr;
169  }
170 
172  #define IF_X_RTN_DETECTOR(A) \
173  if (name == #A) return getDetector_ ## A();
174 
176  str getDetector(const str& name)
177  {
178  #ifndef EXCLUDE_ROOT
179  #ifndef EXCLUDE_RESTFRAMES
181  #endif
183  #endif
185 
186  // If we end up here the analysis has not been found
187  utils_error().raise(LOCAL_INFO, "The analysis " + name + " is not a known ColliderBit analysis.");
188  return "";
189  }
190 
192  std::map<str,std::map<int,AnalysisContainer*> > AnalysisContainer::instances_map;
193 
195  AnalysisContainer::AnalysisContainer() : current_collider(""),
196  is_registered(false),
197  n_threads(omp_get_max_threads()),
198  base_key("")
199  {
200  #ifdef ANALYSISCONTAINER_DEBUG
201  std::cout << "DEBUG: thread " << omp_get_thread_num() << ": AnalysisContainer::ctor: created at " << this << std::endl;
202  #endif
203  }
204 
205 
208  {
209  clear();
210  }
211 
212 
215  {
216  base_key = base_key_in;
217 
218  #pragma omp critical
219  {
220  if (instances_map.count(base_key) == 0 || instances_map[base_key].count(omp_get_thread_num()) == 0)
221  {
222  // Add this instance to the instances map
223  instances_map[base_key][omp_get_thread_num()] = this;
224  is_registered = true;
225 
226  #ifdef ANALYSISCONTAINER_DEBUG
227  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;
228  #endif
229  }
230  else
231  {
232  if (not is_registered)
233  {
234  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...");
235  }
236  else
237  {
238  #ifdef ANALYSISCONTAINER_DEBUG
239  std::cout << "DEBUG: thread " << omp_get_thread_num() << ": AnalysisContainer::register_thread: this instance is already in instances_map" << std::endl;
240  #endif
241  }
242  }
243  }
244  }
245 
246 
249  {
251  // Loop through double map and delete the analysis pointers
252  for(auto& collider_map_pair : analyses_map)
253  {
254  for(auto& analysis_pointer_pair : collider_map_pair.second)
255  {
256  delete analysis_pointer_pair.second;
257  analysis_pointer_pair.second = nullptr;
258  }
259  }
260 
261  // Clear the double map
262  analyses_map.clear();
263  }
264 
265 
268  {
269  current_collider = collider_name;
270  }
271 
272 
275  {
276  return current_collider;
277  }
278 
279 
281  bool AnalysisContainer::has_analyses(str collider_name) const
282  {
283  bool result = false;
284 
285  if (analyses_map.count(collider_name) > 0)
286  {
287  if (analyses_map.at(collider_name).size() > 0)
288  {
289  result = true;
290  }
291  }
292 
293  return result;
294  }
295 
298  {
300  }
301 
302 
304  void AnalysisContainer::init(const std::vector<str>& analysis_names, str collider_name)
305  {
306  // If a map of analyses already exist for this collider, clear it
307  if (analyses_map.count(collider_name) > 0)
308  {
309  analyses_map[collider_name].clear();
310  }
311 
312  // Create analysis pointers and add to the map
313  for (auto& aname : analysis_names)
314  {
315  analyses_map[collider_name][aname] = mkAnalysis(aname);
316  }
317  }
318 
320  void AnalysisContainer::init(const std::vector<str>& analysis_names)
321  {
322  init(analysis_names, current_collider);
323  }
324 
325 
327  void AnalysisContainer::reset(str collider_name, str analysis_name)
328  {
329  analyses_map[collider_name][analysis_name]->reset();
330  }
331 
333  void AnalysisContainer::reset(str collider_name)
334  {
335  for (auto& analysis_pointer_pair : analyses_map[collider_name])
336  {
337  analysis_pointer_pair.second->reset();
338  }
339  }
340 
343  {
345  }
346 
349  {
350  for(auto& collider_map_pair : analyses_map)
351  {
352  reset(collider_map_pair.first);
353  }
354  }
355 
356 
358  const Analysis* AnalysisContainer::get_analysis_pointer(str collider_name, str analysis_name) const
359  {
360  return analyses_map.at(collider_name).at(analysis_name);
361  }
362 
364  const std::map<str,Analysis*>& AnalysisContainer::get_collider_analyses_map(str collider_name) const
365  {
366  return analyses_map.at(collider_name);
367  }
368 
370  const std::map<str,Analysis*>& AnalysisContainer::get_current_analyses_map() const
371  {
372  return analyses_map.at(current_collider);
373  }
374 
376  const std::map<str,std::map<str,Analysis*> >& AnalysisContainer::get_full_analyses_map() const
377  {
378  return analyses_map;
379  }
380 
382  void AnalysisContainer::analyze(const HEPUtils::Event& event, str collider_name, str analysis_name) const
383  {
384  analyses_map.at(collider_name).at(analysis_name)->analyze(event);
385  }
386 
388  void AnalysisContainer::analyze(const HEPUtils::Event& event, str collider_name) const
389  {
390  for (auto& analysis_pointer_pair : analyses_map.at(collider_name))
391  {
392  analysis_pointer_pair.second->analyze(event);
393  }
394  }
395 
397  void AnalysisContainer::analyze(const HEPUtils::Event& event) const
398  {
399  analyze(event, current_collider);
400  }
401 
404  void AnalysisContainer::collect_and_add_signal(str collider_name, str analysis_name)
405  {
406  for (auto& thread_container_pair : instances_map.at(base_key))
407  {
408  AnalysisContainer* other_container = thread_container_pair.second;
409  Analysis* other_analysis = other_container->analyses_map.at(collider_name).at(analysis_name);
410  analyses_map.at(collider_name).at(analysis_name)->add(other_analysis);
411  }
412  }
413 
417  {
418  for (auto& analysis_pointer_pair : analyses_map[collider_name])
419  {
420  str analysis_name = analysis_pointer_pair.first;
421  collect_and_add_signal(collider_name, analysis_name);
422  }
423  }
424 
428  {
430  }
431 
433  void AnalysisContainer::scale(str collider_name, str analysis_name, double xsec_per_event)
434  {
435  analyses_map[collider_name][analysis_name]->scale(xsec_per_event);
436  }
437 
439  void AnalysisContainer::scale(str collider_name, double xsec_per_event)
440  {
441  for (auto& analysis_pointer_pair : analyses_map[collider_name])
442  {
443  str analysis_name = analysis_pointer_pair.first;
444  scale(collider_name, analysis_name, xsec_per_event);
445  }
446  }
447 
449  void AnalysisContainer::scale(double xsec_per_event)
450  {
451  scale(current_collider, xsec_per_event);
452  }
453 
455  void AnalysisContainer::scale_all(double xsec_per_event)
456  {
457  for (auto& collider_map_pair : analyses_map)
458  {
459  str collider_name = collider_map_pair.first;
460  scale(collider_name, xsec_per_event);
461  }
462  }
463 
464  }
465 }
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.