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