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