00001 // -*- C++ -*- 00002 #ifndef RIVET_Analysis_HH 00003 #define RIVET_Analysis_HH 00004 00005 #include "Rivet/Rivet.hh" 00006 #include "Rivet/Analysis.fhh" 00007 #include "Rivet/AnalysisInfo.hh" 00008 #include "Rivet/Event.hh" 00009 #include "Rivet/Projection.hh" 00010 #include "Rivet/ProjectionApplier.hh" 00011 #include "Rivet/ProjectionHandler.hh" 00012 #include "Rivet/Constraints.hh" 00013 #include "Rivet/AnalysisHandler.fhh" 00014 #include "Rivet/AnalysisLoader.hh" 00015 #include "Rivet/Tools/Logging.fhh" 00016 #include "Rivet/RivetAIDA.fhh" 00017 00018 00019 /// @def vetoEvent 00020 /// Preprocessor define for vetoing events, including the log message and return. 00021 #define vetoEvent \ 00022 do { MSG_DEBUG("Vetoing event on line " << __LINE__ << " of " << __FILE__); return; } while(0) 00023 00024 /// @def DECLARE_RIVET_PLUGIN 00025 /// Preprocessor define to prettify the global-object plugin hook mechanism. 00026 #define DECLARE_RIVET_PLUGIN(clsname) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname 00027 00028 00029 00030 namespace Rivet { 00031 00032 00033 /// @brief This is the base class of all analysis classes in Rivet. 00034 /// 00035 /// There are 00036 /// three virtual functions which should be implemented in base classes: 00037 /// 00038 /// void init() is called by Rivet before a run is started. Here the 00039 /// analysis class should book necessary histograms. The needed 00040 /// projections should probably rather be constructed in the 00041 /// constructor. 00042 /// 00043 /// void analyze(const Event&) is called once for each event. Here the 00044 /// analysis class should apply the necessary Projections and fill the 00045 /// histograms. 00046 /// 00047 /// void finalize() is called after a run is finished. Here the analysis 00048 /// class should do whatever manipulations are necessary on the 00049 /// histograms. Writing the histograms to a file is, however, done by 00050 /// the Rivet class. 00051 class Analysis : public ProjectionApplier { 00052 00053 /// The AnalysisHandler is a friend. 00054 friend class AnalysisHandler; 00055 00056 00057 public: 00058 00059 /// @name Standard constructors and destructors. 00060 //@{ 00061 00062 // /// The default constructor. 00063 // Analysis(); 00064 00065 /// Constructor 00066 Analysis(const std::string& name); 00067 00068 /// The destructor. 00069 virtual ~Analysis() {} 00070 00071 //@} 00072 00073 00074 public: 00075 00076 /// @name Main analysis methods 00077 //@{ 00078 00079 /// Initialize this analysis object. A concrete class should here 00080 /// book all necessary histograms. An overridden function must make 00081 /// sure it first calls the base class function. 00082 virtual void init() = 0; 00083 00084 /// Analyze one event. A concrete class should here apply the 00085 /// necessary projections on the \a event and fill the relevant 00086 /// histograms. An overridden function must make sure it first calls 00087 /// the base class function. 00088 virtual void analyze(const Event& event) = 0; 00089 00090 /// Finalize this analysis object. A concrete class should here make 00091 /// all necessary operations on the histograms. Writing the 00092 /// histograms to a file is, however, done by the Rivet class. An 00093 /// overridden function must make sure it first calls the base class 00094 /// function. 00095 virtual void finalize() = 0; 00096 00097 //@} 00098 00099 00100 public: 00101 00102 /// @name Metadata 00103 /// Metadata is used for querying from the command line and also for 00104 /// building web pages and the analysis pages in the Rivet manual. 00105 //@{ 00106 00107 /// Get the actual AnalysisInfo object in which all this metadata is stored. 00108 const AnalysisInfo& info() const { 00109 assert(_info.get() != 0 && "No AnalysisInfo object :O"); 00110 return *_info; 00111 } 00112 00113 /// @brief Get the name of the analysis. 00114 /// 00115 /// By default this is computed by combining the results of the experiment, 00116 /// year and Spires ID metadata methods and you should only override it if 00117 /// there's a good reason why those won't work. 00118 virtual std::string name() const { 00119 return (info().name().empty()) ? _defaultname : info().name(); 00120 } 00121 00122 /// Get the Inspire ID code for this analysis. 00123 virtual std::string inspireId() const { 00124 return info().inspireId(); 00125 } 00126 00127 /// Get the SPIRES ID code for this analysis (~deprecated). 00128 virtual std::string spiresId() const { 00129 return info().spiresId(); 00130 } 00131 00132 /// @brief Names & emails of paper/analysis authors. 00133 /// 00134 /// Names and email of authors in 'NAME <EMAIL>' format. The first 00135 /// name in the list should be the primary contact person. 00136 virtual std::vector<std::string> authors() const { 00137 return info().authors(); 00138 } 00139 00140 /// @brief Get a short description of the analysis. 00141 /// 00142 /// Short (one sentence) description used as an index entry. 00143 /// Use @a description() to provide full descriptive paragraphs 00144 /// of analysis details. 00145 virtual std::string summary() const { 00146 return info().summary(); 00147 } 00148 00149 /// @brief Get a full description of the analysis. 00150 /// 00151 /// Full textual description of this analysis, what it is useful for, 00152 /// what experimental techniques are applied, etc. Should be treated 00153 /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html), 00154 /// with equations to be rendered as LaTeX with amsmath operators. 00155 virtual std::string description() const { 00156 return info().description(); 00157 } 00158 00159 /// @brief Information about the events needed as input for this analysis. 00160 /// 00161 /// Event types, energies, kinematic cuts, particles to be considered 00162 /// stable, etc. etc. Should be treated as a restructuredText bullet list 00163 /// (http://docutils.sourceforge.net/rst.html) 00164 virtual std::string runInfo() const { 00165 return info().runInfo(); 00166 } 00167 00168 /// Experiment which performed and published this analysis. 00169 virtual std::string experiment() const { 00170 return info().experiment(); 00171 } 00172 00173 /// Collider on which the experiment ran. 00174 virtual std::string collider() const { 00175 return info().collider(); 00176 } 00177 00178 /// When the original experimental analysis was published. 00179 virtual std::string year() const { 00180 return info().year(); 00181 } 00182 00183 /// Journal, and preprint references. 00184 virtual std::vector<std::string> references() const { 00185 return info().references(); 00186 } 00187 00188 /// BibTeX citation key for this article. 00189 virtual std::string bibKey() const { 00190 return info().bibKey(); 00191 } 00192 00193 /// BibTeX citation entry for this article. 00194 virtual std::string bibTeX() const { 00195 return info().bibTeX(); 00196 } 00197 00198 /// Whether this analysis is trusted (in any way!) 00199 virtual std::string status() const { 00200 return (info().status().empty()) ? "UNVALIDATED" : info().status(); 00201 } 00202 00203 /// Any work to be done on this analysis. 00204 virtual std::vector<std::string> todos() const { 00205 return info().todos(); 00206 } 00207 00208 00209 /// Return the allowed pairs of incoming beams required by this analysis. 00210 virtual const std::vector<PdgIdPair>& requiredBeams() const { 00211 return info().beams(); 00212 } 00213 /// Declare the allowed pairs of incoming beams required by this analysis. 00214 virtual Analysis& setRequiredBeams(const std::vector<PdgIdPair>& requiredBeams) { 00215 info().setBeams(requiredBeams); 00216 return *this; 00217 } 00218 00219 00220 /// Sets of valid beam energy pairs, in GeV 00221 virtual const std::vector<std::pair<double, double> >& requiredEnergies() const { 00222 return info().energies(); 00223 } 00224 /// Declare the list of valid beam energy pairs, in GeV 00225 virtual Analysis& setRequiredEnergies(const std::vector<std::pair<double, double> >& requiredEnergies) { 00226 info().setEnergies(requiredEnergies); 00227 return *this; 00228 } 00229 00230 00231 /// Return true if this analysis needs to know the process cross-section. 00232 bool needsCrossSection() const { 00233 return info().needsCrossSection(); 00234 } 00235 /// Declare whether this analysis needs to know the process cross-section from the generator. 00236 Analysis& setNeedsCrossSection(bool needed=true) { 00237 info().setNeedsCrossSection(needed); 00238 return *this; 00239 } 00240 00241 //@} 00242 00243 00244 /// @name Internal metadata modifiying methods 00245 //@{ 00246 00247 /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const). 00248 AnalysisInfo& info() { 00249 assert(_info.get() != 0 && "No AnalysisInfo object :O"); 00250 return *_info; 00251 } 00252 00253 /// Set the required beams 00254 /// @deprecated To be removed in 2.0.0. Use .info file and AnalysisInfo class instead 00255 virtual Analysis& setBeams(PdgId beam1, PdgId beam2) { 00256 /// @todo Print out a warning to use setRequiredBeams() instead (and really to use .info files) 00257 return setRequiredBeams(std::vector<PdgIdPair>(1, make_pair(beam1, beam2))); 00258 } 00259 00260 //@} 00261 00262 00263 /// @name Run conditions 00264 //@{ 00265 00266 /// Incoming beams for this run 00267 const ParticlePair& beams() const; 00268 00269 /// Incoming beam IDs for this run 00270 const PdgIdPair beamIds() const; 00271 00272 /// Centre of mass energy for this run 00273 double sqrtS() const; 00274 00275 //@} 00276 00277 00278 /// @name Analysis / beam compatibility testing 00279 //@{ 00280 00281 /// Check if analysis is compatible with the provided beam particle IDs and energies 00282 bool isCompatible(const ParticlePair& beams) const; 00283 00284 /// Check if analysis is compatible with the provided beam particle IDs and energies 00285 bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const; 00286 00287 /// Check if analysis is compatible with the provided beam particle IDs and energies 00288 bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const; 00289 00290 //@} 00291 00292 00293 public: 00294 00295 /// Access the controlling AnalysisHandler object. 00296 AnalysisHandler& handler() const { return *_analysishandler; } 00297 00298 /// Normalize the given histogram, @a histo. After this call the 00299 /// histogram will have been transformed to a DataPointSet with the 00300 /// same name and path. It has the same effect as 00301 /// @c scale(histo, norm/sumOfWeights). 00302 /// @param histo The histogram to be normalised. 00303 /// @param norm The new area of the histogram. 00304 /// @warning The old histogram will be deleted, and its pointer set to zero. 00305 void normalize(AIDA::IHistogram1D*& histo, double norm=1.0); 00306 00307 /// Multiplicatively scale the given histogram, @a histo. After this call the 00308 /// histogram will have been transformed to a DataPointSet with the same name and path. 00309 /// @param histo The histogram to be scaled. 00310 /// @param scale The factor used to multiply the histogram bin heights. 00311 /// @warning The old histogram will be deleted, and its pointer set to zero. 00312 void scale(AIDA::IHistogram1D*& histo, double scale); 00313 00314 /// Normalize the given histogram, @a histo. After this call the 00315 /// histogram will have been transformed to a DataPointSet with the 00316 /// same name and path. It has the same effect as 00317 /// @c scale(histo, norm/sumOfWeights). 00318 /// @param histo The histogram to be normalised. 00319 /// @param norm The new area of the histogram. 00320 /// @warning The old histogram will be deleted, and its pointer set to zero. 00321 void normalize(AIDA::IHistogram2D*& histo, double norm=1.0); 00322 00323 /// Multiplicatively scale the given histogram, @a histo. After this call the 00324 /// histogram will have been transformed to a DataPointSet with the same name and path. 00325 /// @param histo The histogram to be scaled. 00326 /// @param scale The factor used to multiply the histogram bin heights. 00327 /// @warning The old histogram will be deleted, and its pointer set to zero. 00328 void scale(AIDA::IHistogram2D*& histo, double scale); 00329 00330 /// Set the cross section from the generator 00331 Analysis& setCrossSection(double xs); 00332 00333 00334 protected: 00335 00336 /// Get a Log object based on the name() property of the calling analysis object. 00337 Log& getLog() const; 00338 00339 /// Get the process cross-section in pb. Throws if this hasn't been set. 00340 double crossSection() const; 00341 00342 /// Get the process cross-section per generated event in pb. Throws if this 00343 /// hasn't been set. 00344 double crossSectionPerEvent() const; 00345 00346 /// Get the number of events seen (via the analysis handler). Use in the 00347 /// finalize phase only. 00348 size_t numEvents() const; 00349 00350 /// Get the sum of event weights seen (via the analysis handler). Use in the 00351 /// finalize phase only. 00352 double sumOfWeights() const; 00353 00354 00355 protected: 00356 00357 /// @name AIDA analysis infrastructure. 00358 //@{ 00359 /// Access the AIDA analysis factory of the controlling AnalysisHandler object. 00360 AIDA::IAnalysisFactory& analysisFactory(); 00361 00362 /// Access the AIDA tree of the controlling AnalysisHandler object. 00363 AIDA::ITree& tree(); 00364 00365 /// Access the AIDA histogram factory of the controlling AnalysisHandler object. 00366 AIDA::IHistogramFactory& histogramFactory(); 00367 00368 /// Access the AIDA histogram factory of the controlling AnalysisHandler object. 00369 AIDA::IDataPointSetFactory& datapointsetFactory(); 00370 00371 /// Get the canonical histogram "directory" path for this analysis. 00372 const std::string histoDir() const; 00373 00374 /// Get the canonical histogram path for the named histogram in this analysis. 00375 const std::string histoPath(const std::string& hname) const; 00376 00377 /// Get the internal histogram name for given d, x and y (cf. HepData) 00378 const std::string makeAxisCode(size_t datasetId, size_t xAxisId, size_t yAxisId) const; 00379 00380 //@} 00381 00382 00383 /// @name Internal histogram booking (for use by Analysis sub-classes). 00384 //@{ 00385 00386 /// Get bin edges for a named histo (using ref AIDA caching) 00387 const BinEdges& binEdges(const std::string& hname) const; 00388 00389 /// Get bin edges for a numbered histo (using ref AIDA caching) 00390 const BinEdges& binEdges(size_t datasetId, size_t xAxisId, size_t yAxisId) const; 00391 00392 /// Get bin edges with logarithmic widths 00393 BinEdges logBinEdges(size_t nbins, double lower, double upper); 00394 00395 /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper . 00396 /// (NB. this returns a pointer rather than a reference since it will 00397 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00398 /// get the pointer from a reference before they can use it!) 00399 AIDA::IHistogram1D* bookHistogram1D(const std::string& name, 00400 size_t nbins, double lower, double upper, 00401 const std::string& title="", 00402 const std::string& xtitle="", const std::string& ytitle=""); 00403 00404 /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges . 00405 /// (NB. this returns a pointer rather than a reference since it will 00406 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00407 /// get the pointer from a reference before they can use it!) 00408 AIDA::IHistogram1D* bookHistogram1D(const std::string& name, 00409 const std::vector<double>& binedges, const std::string& title="", 00410 const std::string& xtitle="", const std::string& ytitle=""); 00411 00412 /// Book a 2D histogram with @a nxbins and @a nybins uniformly 00413 /// distributed across the ranges @a xlower - @a xupper and @a 00414 /// ylower - @a yupper respectively along the x- and y-axis. 00415 /// (NB. this returns a pointer rather than a reference since it 00416 /// will have to be stored in the analysis class - there's no 00417 /// point in forcing users to explicitly get the pointer from a 00418 /// reference before they can use it!) 00419 AIDA::IHistogram2D* 00420 bookHistogram2D(const std::string& name, 00421 size_t nxbins, double xlower, double xupper, 00422 size_t nybins, double ylower, double yupper, 00423 const std::string& title="", const std::string& xtitle="", 00424 const std::string& ytitle="", const std::string& ztitle=""); 00425 00426 /// Book a 2D histogram with non-uniform bins defined by the 00427 /// vectorx of bin edges @a xbinedges and @a ybinedges. 00428 /// (NB. this returns a pointer rather than a reference since it 00429 /// will have to be stored in the analysis class - there's no 00430 /// point in forcing users to explicitly get the pointer from a 00431 /// reference before they can use it!) 00432 AIDA::IHistogram2D* 00433 bookHistogram2D(const std::string& name, 00434 const std::vector<double>& xbinedges, 00435 const std::vector<double>& ybinedges, 00436 const std::string& title="", const std::string& xtitle="", 00437 const std::string& ytitle="", const std::string& ztitle=""); 00438 00439 /// Book a 1D histogram based on the name in the corresponding AIDA 00440 /// file. The binnings will be obtained by reading the bundled AIDA data 00441 /// record file with the same filename as the analysis' name() property. 00442 AIDA::IHistogram1D* bookHistogram1D(const std::string& name, const std::string& title="", 00443 const std::string& xtitle="", const std::string& ytitle=""); 00444 00445 /// Book a 1D histogram based on the paper, dataset and x/y-axis IDs in the corresponding 00446 /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file 00447 /// of the same filename as the analysis' name() property. 00448 AIDA::IHistogram1D* bookHistogram1D(size_t datasetId, size_t xAxisId, size_t yAxisId, 00449 const std::string& title="", 00450 const std::string& xtitle="", const std::string& ytitle=""); 00451 00452 //@} 00453 00454 00455 /// @name Internal profile histogram booking (for use by Analysis sub-classes). 00456 //@{ 00457 00458 /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper . 00459 /// (NB. this returns a pointer rather than a reference since it will 00460 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00461 /// get the pointer from a reference before they can use it!) 00462 AIDA::IProfile1D* bookProfile1D(const std::string& name, 00463 size_t nbins, double lower, double upper, 00464 const std::string& title="", 00465 const std::string& xtitle="", const std::string& ytitle=""); 00466 00467 /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges . 00468 /// (NB. this returns a pointer rather than a reference since it will 00469 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00470 /// get the pointer from a reference before they can use it!) 00471 AIDA::IProfile1D* bookProfile1D(const std::string& name, 00472 const std::vector<double>& binedges, 00473 const std::string& title="", 00474 const std::string& xtitle="", const std::string& ytitle=""); 00475 00476 /// Book a 1D profile histogram based on the name in the corresponding AIDA 00477 /// file. The binnings will be obtained by reading the bundled AIDA data 00478 /// record file with the same filename as the analysis' name() property. 00479 AIDA::IProfile1D* bookProfile1D(const std::string& name, const std::string& title="", 00480 const std::string& xtitle="", const std::string& ytitle=""); 00481 00482 /// Book a 1D profile histogram based on the paper, dataset and x/y-axis IDs in the corresponding 00483 /// HepData record. The binnings will be obtained by reading the bundled AIDA data record file 00484 /// of the same filename as the analysis' name() property. 00485 AIDA::IProfile1D* bookProfile1D(size_t datasetId, size_t xAxisId, size_t yAxisId, 00486 const std::string& title="", 00487 const std::string& xtitle="", const std::string& ytitle=""); 00488 //@} 00489 00490 00491 /// @name Internal data point set booking (for use by Analysis sub-classes). 00492 //@{ 00493 00494 /// Book a 2-dimensional data point set. 00495 /// (NB. this returns a pointer rather than a reference since it will 00496 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00497 /// get the pointer from a reference before they can use it!) 00498 AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title="", 00499 const std::string& xtitle="", const std::string& ytitle=""); 00500 00501 00502 /// Book a 2-dimensional data point set with equally spaced points in a range. 00503 /// (NB. this returns a pointer rather than a reference since it will 00504 /// have to be stored in the analysis class - there's no point in forcing users to explicitly 00505 /// get the pointer from a reference before they can use it!) 00506 AIDA::IDataPointSet* bookDataPointSet(const std::string& name, 00507 size_t npts, double lower, double upper, 00508 const std::string& title="", 00509 const std::string& xtitle="", const std::string& ytitle=""); 00510 00511 /// Book a 2-dimensional data point set based on the corresponding AIDA data 00512 /// file. The binnings (x-errors) will be obtained by reading the bundled 00513 /// AIDA data record file of the same filename as the analysis' name() 00514 /// property. 00515 //AIDA::IDataPointSet* bookDataPointSet(const std::string& name, const std::string& title); 00516 00517 /// Book a 2-dimensional data point set based on the paper, dataset and x/y-axis IDs in the corresponding 00518 /// HepData record. The binnings (x-errors) will be obtained by reading the bundled AIDA data record file 00519 /// of the same filename as the analysis' name() property. 00520 AIDA::IDataPointSet* bookDataPointSet(size_t datasetId, size_t xAxisId, size_t yAxisId, 00521 const std::string& title="", 00522 const std::string& xtitle="", const std::string& ytitle=""); 00523 00524 //@} 00525 00526 00527 private: 00528 00529 /// @name Utility functions 00530 //@{ 00531 00532 /// Make the histogram directory. 00533 void _makeHistoDir(); 00534 00535 /// Get the bin edges for this paper from the reference AIDA file, and cache them. 00536 void _cacheBinEdges() const; 00537 00538 /// Get the x-axis points for this paper from the reference AIDA file, and cache them. 00539 void _cacheXAxisData() const; 00540 00541 //@} 00542 00543 00544 protected: 00545 00546 /// Name passed to constructor (used to find .info analysis data file, and as a fallback) 00547 string _defaultname; 00548 00549 /// Pointer to analysis metadata object 00550 shared_ptr<AnalysisInfo> _info; 00551 00552 00553 private: 00554 00555 /// @name Cross-section variables 00556 //@{ 00557 double _crossSection; 00558 bool _gotCrossSection; 00559 //@} 00560 00561 /// The controlling AnalysisHandler object. 00562 AnalysisHandler* _analysishandler; 00563 00564 /// Flag to indicate whether the histogram directory is present 00565 mutable bool _madeHistoDir; 00566 00567 /// Collection of x-axis point data to speed up many autobookings: the 00568 /// reference data file should only be read once. 00569 /// @todo Reduce memory occupancy, or clear after initialisation? 00570 mutable map<string, vector<DPSXPoint> > _dpsData; 00571 00572 /// Collection of cached bin edges to speed up many autobookings: the 00573 /// reference data file should only be read once. 00574 /// @todo Reduce memory occupancy, or clear after initialisation? 00575 mutable map<string, BinEdges> _histBinEdges; 00576 00577 00578 private: 00579 00580 /// The assignment operator is private and must never be called. 00581 /// In fact, it should not even be implemented. 00582 Analysis& operator=(const Analysis&); 00583 00584 }; 00585 00586 00587 } 00588 00589 00590 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh 00591 #include "Rivet/AnalysisBuilder.hh" 00592 00593 00594 #endif