gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
solo.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
16 
20 #include "gambit/Utils/cats.hpp"
21 
22 #define NULIKE_VERSION "1.0.7"
23 #define NULIKE_SAFE_VERSION 1_0_7
24 
25 using namespace ColliderBit::Functown;
26 using namespace BackendIniBit::Functown;
27 using namespace CAT(Backends::nulike_,NULIKE_SAFE_VERSION)::Functown;
28 
30 int main(int argc, char* argv[])
31 {
32 
33  try
34  {
35 
36  // Check the number of command line arguments
37  if (argc < 2)
38  {
39  // Tell the user how to run the program and exit
40  cerr << endl << "Usage: " << argv[0] << " <your CBS yaml file>" << endl << endl;
41  return 1;
42  }
43 
44  // Make sure that nulike is present.
45  if (not Backends::backendInfo().works[str("nulike")+NULIKE_VERSION]) backend_error().raise(LOCAL_INFO, str("nulike ")+NULIKE_VERSION+" is missing!");
46 
47  // Print the banner (if you could call it that)
48  cout << endl;
49  cout << "==================================" << endl;
50  cout << "|| ||" << endl;
51  cout << "|| CBS: ColliderBit Solo ||" << endl;
52  cout << "|| GAMBIT Collider Workgroup ||" << endl;
53  cout << "|| ||" << endl;
54  cout << "==================================" << endl;
55  cout << endl;
56 
57  // Read input file name
58  const std::string filename_in = argv[1];
59 
60  // Read the settings in the input file
61  YAML::Node infile;
62  std::vector<str> analyses;
63  Options settings;
64  try
65  {
66  // Load up the file
67  infile = YAML::LoadFile(filename_in);
68  // Retrieve the analyses
69  if (infile["analyses"]) analyses = infile["analyses"].as<std::vector<str>>();
70  else throw std::runtime_error("Analyses list not found in "+filename_in+". Quitting...");
71  // Retrieve the other settings
72  if (infile["settings"]) settings = Options(infile["settings"]);
73  else throw std::runtime_error("Settings section not found in "+filename_in+". Quitting...");
74  }
75  catch (YAML::Exception &e)
76  {
77  throw std::runtime_error("YAML error in "+filename_in+".\n(yaml-cpp error: "+std::string(e.what())+" )");
78  }
79 
80  // Translate relevant settings into appropriate variables
81  bool debug = settings.getValueOrDef<bool>(false, "debug");
82  bool use_lnpiln = settings.getValueOrDef<bool>(false, "use_lognormal_distribution_for_1d_systematic");
83  double jet_pt_min = settings.getValueOrDef<double>(10.0, "jet_pt_min");
84  str event_filename = settings.getValue<str>("event_file");
85  bool event_file_is_LHEF = Gambit::Utils::endsWith(event_filename, ".lhe");
86  bool event_file_is_HepMC = ( Gambit::Utils::endsWith(event_filename, ".hepmc")
87  || Gambit::Utils::endsWith(event_filename, ".hepmc2")
88  || Gambit::Utils::endsWith(event_filename, ".hepmc3") );
89  if (not event_file_is_LHEF and not event_file_is_HepMC)
90  throw std::runtime_error("Unrecognised event file format in "+event_filename+"; must be .lhe or .hepmc.");
91 
92  // Choose the event file reader according to file format
93  if (debug) cout << "Reading " << (event_file_is_LHEF ? "LHEF" : "HepMC") << " file: " << event_filename << endl;
94  auto& getEvent = (event_file_is_LHEF ? getLHEvent : getHepMCEvent);
95 
96  // Initialise logs
98  initialise_standalone_logs("CBS_logs/");
99  logger()<<"Running CBS"<<LogTags::info<<EOM;
100 
101  // Initialise the random number generator, using a hardware seed if no seed is given in the input file.
102  int seed = settings.getValueOrDef<int>(-1, "seed");
103  Random::create_rng_engine("default", seed);
104 
105  // Pass options to the main event loop
106  YAML::Node CBS(infile["settings"]);
107  CBS["analyses"] = analyses;
108  CBS["min_nEvents"] = (long long)(1000);
109  CBS["max_nEvents"] = (long long)(1000000000);
110  operateLHCLoop.setOption<YAML::Node>("CBS", CBS);
111  operateLHCLoop.setOption<bool>("silenceLoop", not debug);
112 
113  // Pass the filename and the jet pt cutoff to the LHEF/HepMC reader function
114  getEvent.setOption<str>((event_file_is_LHEF ? "lhef_filename" : "hepmc_filename"), event_filename);
115  getEvent.setOption<double>("jet_pt_min", jet_pt_min);
116 
117  // Pass options to the cross-section function
118  if (settings.hasKey("cross_section_pb"))
119  {
120  getYAMLCrossSection.setOption<double>("cross_section_pb", settings.getValue<double>("cross_section_pb"));
121  if (settings.hasKey("cross_section_fractional_uncert")) { getYAMLCrossSection.setOption<double>("cross_section_fractional_uncert", settings.getValue<double>("cross_section_fractional_uncert")); }
122  else {getYAMLCrossSection.setOption<double>("cross_section_uncert_pb", settings.getValue<double>("cross_section_uncert_pb")); }
123  }
124  else // <-- must have option "cross_section_fb"
125  {
126  getYAMLCrossSection.setOption<double>("cross_section_fb", settings.getValue<double>("cross_section_fb"));
127  if (settings.hasKey("cross_section_fractional_uncert")) { getYAMLCrossSection.setOption<double>("cross_section_fractional_uncert", settings.getValue<double>("cross_section_fractional_uncert")); }
128  else { getYAMLCrossSection.setOption<double>("cross_section_uncert_fb", settings.getValue<double>("cross_section_uncert_fb")); }
129  }
130 
131  // Pass options to the likelihood function
132  calc_LHC_LogLikes.setOption<int>("covariance_nsamples_start", settings.getValue<int>("covariance_nsamples_start"));
133  calc_LHC_LogLikes.setOption<double>("covariance_marg_convthres_abs", settings.getValue<double>("covariance_marg_convthres_abs"));
134  calc_LHC_LogLikes.setOption<double>("covariance_marg_convthres_rel", settings.getValue<double>("covariance_marg_convthres_rel"));
135 
136  // Resolve ColliderBit dependencies and backend requirements
138  calc_combined_LHC_LogLike.resolveDependency(&operateLHCLoop);
140  calc_LHC_LogLikes.resolveDependency(&CollectAnalyses);
141  calc_LHC_LogLikes.resolveDependency(&operateLHCLoop);
142  calc_LHC_LogLikes.resolveBackendReq(use_lnpiln ? &nulike_lnpiln : &nulike_lnpin);
143  CollectAnalyses.resolveDependency(&runATLASAnalyses);
144  CollectAnalyses.resolveDependency(&runCMSAnalyses);
145  CollectAnalyses.resolveDependency(&runIdentityAnalyses);
146  runATLASAnalyses.resolveDependency(&getATLASAnalysisContainer);
147  runATLASAnalyses.resolveDependency(&smearEventATLAS);
148  runCMSAnalyses.resolveDependency(&getCMSAnalysisContainer);
149  runCMSAnalyses.resolveDependency(&smearEventCMS);
150  runIdentityAnalyses.resolveDependency(&getIdentityAnalysisContainer);
151  runIdentityAnalyses.resolveDependency(&copyEvent);
152  getATLASAnalysisContainer.resolveDependency(&getYAMLCrossSection);
153  getCMSAnalysisContainer.resolveDependency(&getYAMLCrossSection);
154  getIdentityAnalysisContainer.resolveDependency(&getYAMLCrossSection);
155  smearEventATLAS.resolveDependency(&getBuckFastATLAS);
156  smearEventATLAS.resolveDependency(&getEvent);
157  smearEventCMS.resolveDependency(&getBuckFastCMS);
158  smearEventCMS.resolveDependency(&getEvent);
159  copyEvent.resolveDependency(&getBuckFastIdentity);
160  copyEvent.resolveDependency(&getEvent);
161 
162  // Resolve loop manager for ColliderBit event loop
163  getEvent.resolveLoopManager(&operateLHCLoop);
164  getBuckFastATLAS.resolveLoopManager(&operateLHCLoop);
165  getBuckFastCMS.resolveLoopManager(&operateLHCLoop);
166  getBuckFastIdentity.resolveLoopManager(&operateLHCLoop);
167  getATLASAnalysisContainer.resolveLoopManager(&operateLHCLoop);
168  getCMSAnalysisContainer.resolveLoopManager(&operateLHCLoop);
169  getIdentityAnalysisContainer.resolveLoopManager(&operateLHCLoop);
170  smearEventATLAS.resolveLoopManager(&operateLHCLoop);
171  smearEventCMS.resolveLoopManager(&operateLHCLoop);
172  copyEvent.resolveLoopManager(&operateLHCLoop);
173  getYAMLCrossSection.resolveLoopManager(&operateLHCLoop);
174  runATLASAnalyses.resolveLoopManager(&operateLHCLoop);
175  runCMSAnalyses.resolveLoopManager(&operateLHCLoop);
176  runIdentityAnalyses.resolveLoopManager(&operateLHCLoop);
177  std::vector<functor*> nested_functions = initVector<functor*>(&getEvent,
182  &getATLASAnalysisContainer,
183  &getCMSAnalysisContainer,
184  &getIdentityAnalysisContainer,
185  &smearEventATLAS,
186  &smearEventCMS,
187  &copyEvent,
188  &runATLASAnalyses,
189  &runCMSAnalyses,
190  &runIdentityAnalyses);
191  operateLHCLoop.setNestedList(nested_functions);
192 
193  // Call the initialisation function for nulike
194  nulike_1_0_7_init.reset_and_calculate();
195 
196  // Run the detector sim and selected analyses on all the events read in.
197  operateLHCLoop.reset_and_calculate();
198  CollectAnalyses.reset_and_calculate();
199  calc_LHC_LogLikes.reset_and_calculate();
200  get_LHC_LogLike_per_analysis.reset_and_calculate();
201  calc_combined_LHC_LogLike.reset_and_calculate();
202 
203  // Retrieve and print the predicted + observed counts and likelihoods for the individual SRs and analyses, as well as the total likelihood.
204  int n_events = operateLHCLoop(0).event_count.at("CBS");
205  std::stringstream summary_line;
206  for (size_t analysis = 0; analysis < CollectAnalyses(0).size(); ++analysis)
207  {
208  const Gambit::ColliderBit::AnalysisData& adata = *(CollectAnalyses(0).at(analysis));
209  const str& analysis_name = adata.analysis_name;
210  const Gambit::ColliderBit::AnalysisLogLikes& analysis_loglikes = calc_LHC_LogLikes(0).at(analysis_name);
211  summary_line << " " << analysis_name << ": " << endl;
212  for (size_t sr_index = 0; sr_index < adata.size(); ++sr_index)
213  {
214  const Gambit::ColliderBit::SignalRegionData srData = adata[sr_index];
215  const double combined_s_uncertainty = srData.calc_n_sig_scaled_err();
216  const double combined_bg_uncertainty = srData.n_bkg_err;
217  summary_line << " Signal region " << srData.sr_label << " (SR index " << sr_index << "):" << endl;
218  summary_line << " Observed events: " << srData.n_obs << endl;
219  summary_line << " SM prediction: " << srData.n_bkg << " +/- " << combined_bg_uncertainty << endl;
220  summary_line << " Signal prediction: " << srData.n_sig_scaled << " +/- " << combined_s_uncertainty << endl;
221  auto loglike_it = analysis_loglikes.sr_loglikes.find(srData.sr_label);
222  if (loglike_it != analysis_loglikes.sr_loglikes.end())
223  {
224  summary_line << " Log-likelihood: " << loglike_it->second << endl;
225  }
226  }
227  summary_line << " Selected signal region: " << analysis_loglikes.combination_sr_label << endl;
228  summary_line << " Total log-likelihood for analysis:" << analysis_loglikes.combination_loglike << endl << endl;
229  }
230  double loglike = calc_combined_LHC_LogLike(0);
231 
232  cout.precision(5);
233  cout << endl;
234  cout << "Read and analysed " << n_events << " events from " << (event_file_is_LHEF ? "LHE" : "HepMC") << " file." << endl << endl;
235  cout << "Analysis details:" << endl << endl << summary_line.str() << endl;
236  cout << std::scientific << "Total combined ATLAS+CMS log-likelihood: " << loglike << endl;
237  cout << endl;
238 
239  // No more to see here folks, go home.
240  return 0;
241  }
242 
243  catch (std::exception& e)
244  {
245  cerr << "CBS has exited with fatal exception: " << e.what() << endl;
246  }
247 
248  // Finished, but an exception was raised.
249  return 1;
250 
251 }
252 
Rollcall header for ColliderBit module.
void calc_combined_LHC_LogLike(double &result)
Compute the total likelihood combining all analyses.
void operateLHCLoop(MCLoopInfo &result)
LHC Loop Manager.
Container for loglike information for an analysis.
#define NULIKE_VERSION
ColliderBit Solo: an event-based LHC recast tool using the GAMBIT ColliderBit module.
Definition: solo.cpp:22
double n_bkg_err
The absolute error of n_bkg.
void getLHEvent(HEPUtils::Event &result)
A nested function that reads in Les Houches Event files and converts them to HEPUtils::Event format...
Definition: getLHEvent.cpp:38
Includes everything needed to use a GAMBIT module as a standalone analysis code.
#define LOCAL_INFO
Definition: local_info.hpp:34
void calc_LHC_LogLikes(map_str_AnalysisLogLikes &result)
Loop over all analyses and fill a map of AnalysisLogLikes objects.
void getBuckFastCMS(BaseDetector *&result)
Retrieve a BuckFast sim of CMS.
Definition: getBuckFast.cpp:70
double n_bkg
The number of standard model events expected to pass the selection for this signal region...
void get_LHC_LogLike_per_analysis(map_str_dbl &result)
Extract the combined log likelihood for each analysis.
std::map< std::string, double > sr_loglikes
A container for the result of an analysis, potentially with many signal regions and correlations...
void CollectAnalyses(AnalysisDataPointers &result)
Loop over all analyses and collect them in one place.
bool hasKey(const args &... keys) const
Getters for key/value pairs (which is all the options node should contain)
double n_obs
The number of events passing selection for this signal region as reported by the experiment.
General small utility functions.
EXPORT_SYMBOLS bool endsWith(const std::string &str, const std::string &suffix)
Checks whether `str&#39; ends with `suffix&#39;.
TYPE getValue(const args &... keys) const
error & backend_error()
Backend errors.
std::string sr_label
A label for the particular signal region of the analysis.
#define NULIKE_SAFE_VERSION
Definition: solo.cpp:23
void getBuckFastATLAS(BaseDetector *&result)
Retrieve a BuckFast sim of ATLAS.
Definition: getBuckFast.cpp:55
void initialise_standalone_logs(str)
Logger setup standalone utility function.
void getYAMLCrossSection(xsec_container &result)
A function that reads the total cross-section from the input file, but builds up the number of events...
Definition: getxsec.cpp:1272
const Logging::endofmessage EOM
Explicit const instance of the end of message struct in Gambit namespace.
Definition: logger.hpp:100
void set_log_debug_messages(bool flag)
Choose whether "Debug" tagged log messages will be ignored (i.e. not logged)
Definition: logmaster.hpp:138
std::string infile("FlavBit/data/example.slha")
std::string analysis_name
Analysis name.
EXPORT_SYMBOLS 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
int main(int argc, char *argv[])
ColliderBit Solo main program.
Definition: solo.cpp:30
A simple container for the result of one signal region from one analysis.
TYPE getValueOrDef(TYPE def, const args &... keys) const
const std::string filename_in
Definition: 3bithit.cpp:41
void getBuckFastIdentity(BaseDetector *&result)
Retrieve an Identity BuckFast sim (no sim)
Definition: getBuckFast.cpp:85
double n_sig_scaled
n_sig_MC, scaled to luminosity * cross-section
A small wrapper object for &#39;options&#39; nodes.
void getHepMCEvent(HEPUtils::Event &result)
A nested function that reads in HepMC event files and converts them to HEPUtils::Event format...
Concatenation macros.
size_t size() const
Number of analyses.