AnalysisHandler.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Config/RivetCommon.hh" 00003 #include "Rivet/AnalysisHandler.hh" 00004 #include "Rivet/Analysis.hh" 00005 #include "Rivet/ParticleName.hh" 00006 #include "Rivet/BeamConstraint.hh" 00007 #include "Rivet/Tools/Logging.hh" 00008 #include "Rivet/Projections/Beam.hh" 00009 00010 namespace Rivet { 00011 00012 00013 namespace { 00014 inline bool cmpAOByPath(const AnalysisObjectPtr a, const AnalysisObjectPtr b) { 00015 return a->path() < b->path(); 00016 } 00017 } 00018 00019 00020 AnalysisHandler::AnalysisHandler(const string& runname) 00021 : _runname(runname), _numEvents(0), 00022 _sumOfWeights(0.0), _xs(NAN), 00023 _initialised(false), _ignoreBeams(false) 00024 {} 00025 00026 AnalysisHandler::~AnalysisHandler() 00027 {} 00028 00029 00030 Log& AnalysisHandler::getLog() const { 00031 return Log::getLog("Rivet.Analysis.Handler"); 00032 } 00033 00034 00035 void AnalysisHandler::init(const GenEvent& ge) { 00036 if (_initialised) 00037 throw UserError("AnalysisHandler::init has already been called: cannot re-initialize!"); 00038 00039 setRunBeams(Rivet::beams(ge)); 00040 MSG_DEBUG("Initialising the analysis handler"); 00041 _numEvents = 0; 00042 _sumOfWeights = 0.0; 00043 00044 // Check that analyses are beam-compatible, and remove those that aren't 00045 const size_t num_anas_requested = analysisNames().size(); 00046 vector<string> anamestodelete; 00047 foreach (const AnaHandle a, _analyses) { 00048 if (!_ignoreBeams && !a->isCompatible(beams())) { 00049 //MSG_DEBUG(a->name() << " requires beams " << a->requiredBeams() << " @ " << a->requiredEnergies() << " GeV"); 00050 anamestodelete.push_back(a->name()); 00051 } 00052 } 00053 foreach (const string& aname, anamestodelete) { 00054 MSG_WARNING("Analysis '" << aname << "' is incompatible with the provided beams: removing"); 00055 removeAnalysis(aname); 00056 } 00057 if (num_anas_requested > 0 && analysisNames().empty()) { 00058 cerr << "All analyses were incompatible with the first event's beams\n" 00059 << "Exiting, since this probably wasn't intentional!" << endl; 00060 exit(1); 00061 } 00062 00063 // Warn if any analysis' status is not unblemished 00064 foreach (const AnaHandle a, analyses()) { 00065 if (toUpper(a->status()) == "PRELIMINARY") { 00066 MSG_WARNING("Analysis '" << a->name() << "' is preliminary: be careful, it may change and/or be renamed!"); 00067 } else if (toUpper(a->status()) == "OBSOLETE") { 00068 MSG_WARNING("Analysis '" << a->name() << "' is obsolete: please update!"); 00069 } else if (toUpper(a->status()).find("UNVALIDATED") != string::npos) { 00070 MSG_WARNING("Analysis '" << a->name() << "' is unvalidated: be careful, it may be broken!"); 00071 } 00072 } 00073 00074 // Initialize the remaining analyses 00075 foreach (AnaHandle a, _analyses) { 00076 MSG_DEBUG("Initialising analysis: " << a->name()); 00077 try { 00078 // Allow projection registration in the init phase onwards 00079 a->_allowProjReg = true; 00080 a->init(); 00081 //MSG_DEBUG("Checking consistency of analysis: " << a->name()); 00082 //a->checkConsistency(); 00083 } catch (const Error& err) { 00084 cerr << "Error in " << a->name() << "::init method: " << err.what() << endl; 00085 exit(1); 00086 } 00087 MSG_DEBUG("Done initialising analysis: " << a->name()); 00088 } 00089 _initialised = true; 00090 MSG_DEBUG("Analysis handler initialised"); 00091 } 00092 00093 00094 void AnalysisHandler::analyze(const GenEvent& ge) { 00095 // Call init with event as template if not already initialised 00096 if (!_initialised) { 00097 init(ge); 00098 } 00099 // Proceed with event analysis 00100 assert(_initialised); 00101 // Ensure that beam details match those from first event 00102 const PdgIdPair beams = Rivet::beamIds(ge); 00103 const double sqrts = Rivet::sqrtS(ge); 00104 if (!compatible(beams, _beams) || !fuzzyEquals(sqrts, sqrtS())) { 00105 cerr << "Event beams mismatch: " 00106 << PID::toBeamsString(beams) << " @ " << sqrts/GeV << " GeV" << " vs. first beams " 00107 << this->beams() << " @ " << this->sqrtS()/GeV << " GeV" << endl; 00108 exit(1); 00109 } 00110 00111 00112 Event event(ge); 00113 _numEvents++; 00114 // Weights 00115 const double weight = event.weight(); 00116 _sumOfWeights += weight; 00117 MSG_DEBUG("Event #" << _numEvents << " weight = " << weight); 00118 #ifdef HEPMC_HAS_CROSS_SECTION 00119 if (ge.cross_section()) { 00120 _xs = ge.cross_section()->cross_section(); 00121 } 00122 #endif 00123 foreach (AnaHandle a, _analyses) { 00124 //MSG_DEBUG("About to run analysis " << a->name()); 00125 try { 00126 a->analyze(event); 00127 } catch (const Error& err) { 00128 cerr << "Error in " << a->name() << "::analyze method: " 00129 << err.what() << endl; 00130 exit(1); 00131 } 00132 //MSG_DEBUG("Finished running analysis " << a->name()); 00133 } 00134 } 00135 00136 00137 void AnalysisHandler::finalize() { 00138 if (!_initialised) return; 00139 MSG_INFO("Finalising analyses"); 00140 foreach (AnaHandle a, _analyses) { 00141 a->setCrossSection(_xs); 00142 try { 00143 a->finalize(); 00144 } catch (const Error& err) { 00145 cerr << "Error in " << a->name() << "::finalize method: " 00146 << err.what() << endl; 00147 exit(1); 00148 } 00149 } 00150 00151 // Print out number of events processed 00152 MSG_INFO("Processed " << _numEvents << " event" << (_numEvents == 1 ? "" : "s")); 00153 00154 // // Delete analyses 00155 // MSG_DEBUG("Deleting analyses"); 00156 // _analyses.clear(); 00157 00158 // Print out MCnet boilerplate 00159 cout << endl; 00160 cout << "The MCnet usage guidelines apply to Rivet: see http://www.montecarlonet.org/GUIDELINES" << endl; 00161 cout << "Please acknowledge plots made with Rivet analyses, and cite arXiv:1003.0694 (http://arxiv.org/abs/1003.0694)" << endl; 00162 } 00163 00164 00165 AnalysisHandler& AnalysisHandler::addAnalysis(const string& analysisname) { 00166 // Check for a duplicate analysis 00167 /// @todo Might we want to be able to run an analysis twice, with different params? 00168 /// Requires avoiding histo tree clashes, i.e. storing the histos on the analysis objects. 00169 foreach (const AnaHandle& a, _analyses) { 00170 if (a->name() == analysisname) { 00171 MSG_WARNING("Analysis '" << analysisname << "' already registered: skipping duplicate"); 00172 return *this; 00173 } 00174 } 00175 AnaHandle analysis( AnalysisLoader::getAnalysis(analysisname) ); 00176 if (analysis.get() != 0) { // < Check for null analysis. 00177 MSG_DEBUG("Adding analysis '" << analysisname << "'"); 00178 analysis->_analysishandler = this; 00179 _analyses.insert(analysis); 00180 } else { 00181 MSG_WARNING("Analysis '" << analysisname << "' not found."); 00182 } 00183 // MSG_WARNING(_analyses.size()); 00184 // foreach (const AnaHandle& a, _analyses) MSG_WARNING(a->name()); 00185 return *this; 00186 } 00187 00188 00189 AnalysisHandler& AnalysisHandler::removeAnalysis(const string& analysisname) { 00190 shared_ptr<Analysis> toremove; 00191 foreach (const AnaHandle a, _analyses) { 00192 if (a->name() == analysisname) { 00193 toremove = a; 00194 break; 00195 } 00196 } 00197 if (toremove.get() != 0) { 00198 MSG_DEBUG("Removing analysis '" << analysisname << "'"); 00199 _analyses.erase(toremove); 00200 } 00201 return *this; 00202 } 00203 00204 00205 vector<AnalysisObjectPtr> AnalysisHandler::getData() const { 00206 vector<AnalysisObjectPtr> rtn; 00207 foreach (const AnaHandle a, analyses()) { 00208 vector<AnalysisObjectPtr> aos = a->analysisObjects(); 00209 // MSG_WARNING(a->name() << " " << aos.size()); 00210 foreach (const AnalysisObjectPtr ao, aos) { 00211 // Exclude paths starting with /TMP/ from final write-out 00212 /// @todo This needs to be much more nuanced for re-entrant histogramming 00213 if (ao->path().find("/TMP/") != string::npos) continue; 00214 rtn.push_back(ao); 00215 } 00216 } 00217 sort(rtn.begin(), rtn.end(), cmpAOByPath); 00218 return rtn; 00219 } 00220 00221 00222 void AnalysisHandler::writeData(const string& filename) const { 00223 const vector<AnalysisObjectPtr> aos = getData(); 00224 WriterYODA::write(filename, aos.begin(), aos.end()); 00225 } 00226 00227 00228 string AnalysisHandler::runName() const { return _runname; } 00229 size_t AnalysisHandler::numEvents() const { return _numEvents; } 00230 double AnalysisHandler::sumOfWeights() const { return _sumOfWeights; } 00231 00232 00233 void AnalysisHandler::setSumOfWeights(const double& sum) { 00234 _sumOfWeights=sum; 00235 } 00236 00237 00238 std::vector<std::string> AnalysisHandler::analysisNames() const { 00239 std::vector<std::string> rtn; 00240 foreach (AnaHandle a, _analyses) { 00241 rtn.push_back(a->name()); 00242 } 00243 return rtn; 00244 } 00245 00246 00247 AnalysisHandler& AnalysisHandler::addAnalyses(const std::vector<std::string>& analysisnames) { 00248 foreach (const string& aname, analysisnames) { 00249 //MSG_DEBUG("Adding analysis '" << aname << "'"); 00250 addAnalysis(aname); 00251 } 00252 return *this; 00253 } 00254 00255 00256 AnalysisHandler& AnalysisHandler::removeAnalyses(const std::vector<std::string>& analysisnames) { 00257 foreach (const string& aname, analysisnames) { 00258 removeAnalysis(aname); 00259 } 00260 return *this; 00261 } 00262 00263 00264 bool AnalysisHandler::needCrossSection() const { 00265 bool rtn = false; 00266 foreach (const AnaHandle a, _analyses) { 00267 if (!rtn) rtn = a->needsCrossSection(); 00268 if (rtn) break; 00269 } 00270 return rtn; 00271 } 00272 00273 00274 AnalysisHandler& AnalysisHandler::setCrossSection(double xs) { 00275 _xs = xs; 00276 return *this; 00277 } 00278 00279 00280 bool AnalysisHandler::hasCrossSection() const { 00281 return (!std::isnan(crossSection())); 00282 } 00283 00284 00285 AnalysisHandler& AnalysisHandler::addAnalysis(Analysis* analysis) { 00286 analysis->_analysishandler = this; 00287 _analyses.insert(AnaHandle(analysis)); 00288 return *this; 00289 } 00290 00291 00292 PdgIdPair AnalysisHandler::beamIds() const { 00293 return Rivet::beamIds(beams()); 00294 } 00295 00296 00297 double AnalysisHandler::sqrtS() const { 00298 return Rivet::sqrtS(beams()); 00299 } 00300 00301 void AnalysisHandler::setIgnoreBeams(bool ignore) { 00302 _ignoreBeams=ignore; 00303 } 00304 00305 00306 } Generated on Tue May 13 2014 11:38:25 for The Rivet MC analysis system by ![]() |