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