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