gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-252-gf9a3f78
a Global And Modular Bsm Inference Tool
ColliderBit_eventloop.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
36 
38 
39 // #define COLLIDERBIT_DEBUG
40 
41 namespace Gambit
42 {
43 
44  namespace ColliderBit
45  {
46 
47 
49  void operateLHCLoop(MCLoopInfo& result)
50  {
51  using namespace Pipes::operateLHCLoop;
52  static std::streambuf *coutbuf = std::cout.rdbuf(); // save cout buffer for running the loop quietly
53 
54  #ifdef COLLIDERBIT_DEBUG
55  cout << debug_prefix() << endl;
56  cout << debug_prefix() << "~~~~ New point! ~~~~" << endl;
57  #endif
58 
59  // Retrieve run options from the YAML file (or standalone code)
60  static bool first = true;
61  static bool silenceLoop;
62  static std::map<str,int> min_nEvents;
63  static std::map<str,int> max_nEvents;
64  static std::map<str,int> stoppingres;
65  if (first)
66  {
67  // Should we silence stdout during the loop?
68  silenceLoop = runOptions->getValueOrDef<bool>(true, "silenceLoop");
69 
70  // Retrieve all the names of all entries in the yaml options node.
71  std::vector<str> vec = runOptions->getNames();
72  // Step though the names, and accept only those with a "min_nEvents" sub-entry as colliders.
73  for (str& name : vec)
74  {
75  YAML::Node node = runOptions->getNode(name);
76  if (not node.IsScalar() and node["min_nEvents"]) result.collider_names.push_back(name);
77  }
78 
79  // Retrieve the options for each collider.
80  for (auto& collider : result.collider_names)
81  {
82  Options colOptions(runOptions->getValue<YAML::Node>(collider));
83  min_nEvents[collider] = colOptions.getValue<int>("min_nEvents");
84  max_nEvents[collider] = colOptions.getValue<int>("max_nEvents");
85  result.convergence_options[collider].target_stat = colOptions.getValue<double>("target_fractional_uncert");
86  result.convergence_options[collider].stop_at_sys = colOptions.getValueOrDef<bool>(true, "halt_when_systematic_dominated");
87  result.convergence_options[collider].all_analyses_must_converge = colOptions.getValueOrDef<bool>(false, "all_analyses_must_converge");
88  result.convergence_options[collider].all_SR_must_converge = colOptions.getValueOrDef<bool>(false, "all_SR_must_converge");
89  result.maxFailedEvents[collider] = colOptions.getValueOrDef<int>(1, "maxFailedEvents");
90  stoppingres[collider] = colOptions.getValueOrDef<int>(200, "events_between_convergence_checks");
91  result.analyses[collider] = colOptions.getValueOrDef<std::vector<str>>(std::vector<str>(), "analyses");
92  result.event_count[collider] = 0;
93  // Check that the nEvents options given make sense.
94  if (min_nEvents.at(collider) > max_nEvents.at(collider))
95  ColliderBit_error().raise(LOCAL_INFO,"Option min_nEvents is greater than corresponding max_nEvents for collider "
96  +collider+". Please correct your YAML file.");
97  // Check that the analyses all correspond to actual ColliderBit analyses, and sort them into separate maps for each detector.
98  for (str& analysis : result.analyses.at(collider))
99  {
100  result.detector_analyses[collider][getDetector(analysis)].push_back(analysis);
101  }
102  }
103  first = false;
104  }
105 
106  // Do the base-level initialisation
107  Loop::executeIteration(BASE_INIT);
108 
109  // Mute stdout during the loop if requested
110  if (silenceLoop) std::cout.rdbuf(0);
111 
112  // For every collider requested in the yaml file:
113  for (auto& collider : result.collider_names)
114  {
115 
116  // Reset the event_generation_began and exceeded_maxFailedEvents flags
117  result.reset_flags();
118 
119  // Update the collider
120  result.set_current_collider(collider);
121 
122  // Initialise the count of the number of generated events.
123  result.current_event_count() = 0;
124 
125  #ifdef COLLIDERBIT_DEBUG
126  cout << debug_prefix() << "operateLHCLoop: Current collider is " << collider << ".";
127  #endif
128 
130  Loop::reset();
131  #ifdef COLLIDERBIT_DEBUG
132  cout << debug_prefix() << "operateLHCLoop: Will execute COLLIDER_INIT" << endl;
133  #endif
134  Loop::executeIteration(COLLIDER_INIT);
135 
136  // Any problem during COLLIDER_INIT step?
137  piped_warnings.check(ColliderBit_warning());
138  piped_errors.check(ColliderBit_error());
139 
140  //
141  // OMP parallelized sections begin here
142  //
143  #ifdef COLLIDERBIT_DEBUG
144  cout << debug_prefix() << "operateLHCLoop: Will execute START_SUBPROCESS";
145  #endif
146  int currentEvent = 0;
147  #pragma omp parallel
148  {
149  Loop::executeIteration(START_SUBPROCESS);
150  }
151  // Any problems during the START_SUBPROCESS step?
152  piped_warnings.check(ColliderBit_warning());
153  piped_errors.check(ColliderBit_error());
154 
155  // Convergence loop
156  while(currentEvent < max_nEvents.at(collider) and not *Loop::done)
157  {
158  int eventCountBetweenConvergenceChecks = 0;
159 
160  #ifdef COLLIDERBIT_DEBUG
161  cout << debug_prefix() << "Starting main event loop. Will do " << stoppingres.at(collider) << " events before testing convergence." << endl;
162  #endif
163 
164  // Main event loop
165  #pragma omp parallel
166  {
167  while(eventCountBetweenConvergenceChecks < stoppingres.at(collider) and
168  currentEvent < max_nEvents.at(collider) and
169  not *Loop::done and
170  not result.exceeded_maxFailedEvents and
171  not piped_warnings.inquire("exceeded maxFailedEvents") and
172  not piped_errors.inquire()
173  )
174  {
175  result.event_generation_began = true;
176  try
177  {
178  Loop::executeIteration(currentEvent);
179  currentEvent++;
180  eventCountBetweenConvergenceChecks++;
181  }
182  catch (std::domain_error& e)
183  {
184  cout << "\n Continuing to the next event...\n\n";
185  }
186  }
187  }
188  // Update the flag indicating if there have been warnings raised about exceeding the maximum allowed number of failed events
189  result.exceeded_maxFailedEvents = result.exceeded_maxFailedEvents or piped_warnings.inquire("exceeded maxFailedEvents");
190 
191  // Any problems during the main event loop?
192  piped_warnings.check(ColliderBit_warning());
193  piped_errors.check(ColliderBit_error());
194 
195  #ifdef COLLIDERBIT_DEBUG
196  cout << debug_prefix() << "Did " << eventCountBetweenConvergenceChecks << " events of " << currentEvent << " simulated so far." << endl;
197  #endif
198 
199  // Break convergence loop if too many events fail
200  if(result.exceeded_maxFailedEvents) break;
201 
202  // Don't bother with convergence stuff if we haven't passed the minimum number of events yet
203  if (currentEvent >= min_nEvents.at(collider))
204  {
205  #pragma omp parallel
206  {
207  Loop::executeIteration(COLLECT_CONVERGENCE_DATA);
208  }
209  // Any problems during the COLLECT_CONVERGENCE_DATA step?
210  piped_warnings.check(ColliderBit_warning());
211  piped_errors.check(ColliderBit_error());
212 
213  Loop::executeIteration(CHECK_CONVERGENCE);
214  // Any problems during the CHECK_CONVERGENCE step?
215  piped_warnings.check(ColliderBit_warning());
216  piped_errors.check(ColliderBit_error());
217  }
218  }
219 
220  // Store the number of generated events
221  result.current_event_count() = currentEvent;
222 
223  // Break collider loop if too many events have failed
224  if(result.exceeded_maxFailedEvents)
225  {
226  logger() << LogTags::debug << "Too many failed events during event generation." << EOM;
227  break;
228  }
229 
230  #pragma omp parallel
231  {
232  Loop::executeIteration(END_SUBPROCESS);
233  }
234  // Any problems during the END_SUBPROCESS step?
235  piped_warnings.check(ColliderBit_warning());
236  piped_errors.check(ColliderBit_error());
237 
238  //
239  // OMP parallelized sections end here
240  //
241 
242  Loop::executeIteration(COLLIDER_FINALIZE);
243  }
244 
245  // Nicely thank the loop for being quiet, and restore everyone's vocal chords
246  if (silenceLoop) std::cout.rdbuf(coutbuf);
247 
248  // Check for exceptions
250 
251  Loop::executeIteration(BASE_FINALIZE);
252  }
253 
254 
257  {
258  using namespace Pipes::getLHCEventLoopInfo;
259  result.clear();
260  result["did_event_generation"] = double(Dep::RunMC->event_generation_began);
261  result["too_many_failed_events"] = double(Dep::RunMC->exceeded_maxFailedEvents);
262  for (auto& name : Dep::RunMC->collider_names)
263  {
264  result["event_count_" + name] = Dep::RunMC->event_count.at(name);
265  }
266  }
267 
268 
271  {
272  using namespace Pipes::CollectAnalyses;
273  static bool first = true;
274 
275  // Start with an empty vector
276  result.clear();
277 
278  #ifdef COLLIDERBIT_DEBUG
279  cout << debug_prefix() << "CollectAnalyses: Dep::ATLASAnalysisNumbers->size() = " << Dep::ATLASAnalysisNumbers->size() << endl;
280  cout << debug_prefix() << "CollectAnalyses: Dep::CMSAnalysisNumbers->size() = " << Dep::CMSAnalysisNumbers->size() << endl;
281  cout << debug_prefix() << "CollectAnalyses: Dep::IdentityAnalysisNumbers->size() = " << Dep::IdentityAnalysisNumbers->size() << endl;
282  #endif
283 
284  // Add results
285  if (Dep::ATLASAnalysisNumbers->size() != 0) result.insert(result.end(), Dep::ATLASAnalysisNumbers->begin(), Dep::ATLASAnalysisNumbers->end());
286  if (Dep::CMSAnalysisNumbers->size() != 0) result.insert(result.end(), Dep::CMSAnalysisNumbers->begin(), Dep::CMSAnalysisNumbers->end());
287  if (Dep::IdentityAnalysisNumbers->size() != 0) result.insert(result.end(), Dep::IdentityAnalysisNumbers->begin(), Dep::IdentityAnalysisNumbers->end());
288 
289  // When first called, check that all analyses contain at least one signal region.
290  if (first)
291  {
292  // Loop over all AnalysisData pointers
293  for (auto& adp : result)
294  {
295  if (adp->size() == 0)
296  {
297  str errmsg;
298  errmsg = "The analysis " + adp->analysis_name + " has no signal regions.";
299  ColliderBit_error().raise(LOCAL_INFO, errmsg);
300  }
301  }
302  first = false;
303  }
304 
305 
306  // #ifdef COLLIDERBIT_DEBUG
307  // cout << debug_prefix() << "CollectAnalyses: Current size of 'result': " << result.size() << endl;
308  // if (result.size() > 0)
309  // {
310  // cout << debug_prefix() << "CollectAnalyses: Will loop through 'result'..." << endl;
311  // for (auto& adp : result)
312  // {
313  // cout << debug_prefix() << "CollectAnalyses: 'result' contains AnalysisData pointer to " << adp << endl;
314  // cout << debug_prefix() << "CollectAnalyses: -- Will now loop over all signal regions in " << adp << endl;
315  // for (auto& sr : adp->srdata)
316  // {
317  // cout << debug_prefix() << "CollectAnalyses: -- " << adp << " contains signal region: " << sr.sr_label << ", n_signal = " << sr.n_signal << ", n_signal_at_lumi = " << n_signal_at_lumi << endl;
318  // }
319  // cout << debug_prefix() << "CollectAnalyses: -- Done looping over signal regions in " << adp << endl;
320  // }
321  // cout << debug_prefix() << "CollectAnalyses: ...Done looping through 'result'." << endl;
322  // }
323  // #endif
324  }
325 
326 
327  }
328 
329 }
std::map< str, int > event_count
Number of events generated for each collider.
Definition: MCLoopInfo.hpp:46
DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry DecayTable::Entry double
Piped_exceptions piped_errors
Global instance of Piped_exceptions class for errors.
void operateLHCLoop(MCLoopInfo &result)
LHC Loop Manager.
void getLHCEventLoopInfo(map_str_dbl &result)
Store some information about the event generation.
#define LOCAL_INFO
Definition: local_info.hpp:34
const int & current_event_count() const
Get the number of events generated for the current collider.
Definition: MCLoopInfo.cpp:100
Piped_exceptions piped_warnings
Global instance of Piped_exceptions class for warnings.
bool exceeded_maxFailedEvents
Maximum allowed number of failed events has been reached and MC loop terminated.
Definition: MCLoopInfo.hpp:37
bool inquire()
Check whether any exceptions were requested without handling them.
Definition: exceptions.cpp:587
std::map< str, convergence_settings > convergence_options
Convergence options for each collider.
Definition: MCLoopInfo.hpp:49
Piped_invalid_point piped_invalid_point
Global instance of piped invalid point class.
Definition: exceptions.cpp:524
Declarations commont to all ColliderBit event loop functions.
void CollectAnalyses(AnalysisDataPointers &result)
Loop over all analyses and collect them in one place.
TYPE getValue(const args &... keys) const
bool event_generation_began
Event generation has started.
Definition: MCLoopInfo.hpp:34
void reset_flags()
Reset flags.
Definition: MCLoopInfo.cpp:29
std::map< str, int > maxFailedEvents
Maximum allowable number of failed events before MC loop is terminated for each collider.
Definition: MCLoopInfo.hpp:43
const Logging::endofmessage EOM
Explicit const instance of the end of message struct in Gambit namespace.
Definition: logger.hpp:99
std::vector< str > collider_names
The names of all colliders.
Definition: MCLoopInfo.hpp:40
std::map< str, std::map< str, std::vector< str > > > detector_analyses
Analysis list for each detector of each collider.
Definition: MCLoopInfo.hpp:55
void set_current_collider(str &)
Set the current collider.
Definition: MCLoopInfo.cpp:36
Logging::LogMaster & logger()
Function to retrieve a reference to the Gambit global log object.
Definition: logger.cpp:95
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
TYPE getValueOrDef(TYPE def, const args &... keys) const
str getDetector(const str &name)
Return the detector to be used for a given analysis name, checking that the analysis exists...
void check(exception &excep)
Check whether any exceptions were requested, and raise them.
Definition: exceptions.cpp:544
void check()
Check whether an exception was requested, and throw it if necessary.
Definition: exceptions.cpp:473
str debug_prefix()
Debug prefix string giving thread number.
std::map< std::string, double > map_str_dbl
Shorthand for a string-to-double map.
std::vector< T > vec(std::vector< T > vector)
Definition: daFunk.hpp:142
std::vector< const AnalysisData * > AnalysisDataPointers
TODO: see if we can use this one:
Definition: Analysis.hpp:33
A small wrapper object for &#39;options&#39; nodes.
Container for event loop status data and settings.
Definition: MCLoopInfo.hpp:31
std::map< str, std::vector< str > > analyses
Analysis list for each collider.
Definition: MCLoopInfo.hpp:52