Analysis.hh
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #ifndef RIVET_Analysis_HH 00003 #define RIVET_Analysis_HH 00004 00005 #include "Rivet/Config/RivetCommon.hh" 00006 #include "Rivet/AnalysisInfo.hh" 00007 #include "Rivet/Event.hh" 00008 #include "Rivet/Projection.hh" 00009 #include "Rivet/ProjectionApplier.hh" 00010 #include "Rivet/ProjectionHandler.hh" 00011 #include "Rivet/AnalysisLoader.hh" 00012 #include "Rivet/Tools/RivetYODA.hh" 00013 #include "Rivet/Tools/Logging.hh" 00014 #include "Rivet/Tools/ParticleUtils.hh" 00015 #include "Rivet/Tools/Cuts.hh" 00016 00017 00018 /// @def vetoEvent 00019 /// Preprocessor define for vetoing events, including the log message and return. 00020 #define vetoEvent \ 00021 do { MSG_DEBUG("Vetoing event on line " << __LINE__ << " of " << __FILE__); return; } while(0) 00022 00023 00024 namespace Rivet { 00025 00026 00027 // Forward declaration 00028 class AnalysisHandler; 00029 00030 /// @brief This is the base class of all analysis classes in Rivet. 00031 /// 00032 /// There are 00033 /// three virtual functions which should be implemented in base classes: 00034 /// 00035 /// void init() is called by Rivet before a run is started. Here the 00036 /// analysis class should book necessary histograms. The needed 00037 /// projections should probably rather be constructed in the 00038 /// constructor. 00039 /// 00040 /// void analyze(const Event&) is called once for each event. Here the 00041 /// analysis class should apply the necessary Projections and fill the 00042 /// histograms. 00043 /// 00044 /// void finalize() is called after a run is finished. Here the analysis 00045 /// class should do whatever manipulations are necessary on the 00046 /// histograms. Writing the histograms to a file is, however, done by 00047 /// the Rivet class. 00048 class Analysis : public ProjectionApplier { 00049 00050 /// The AnalysisHandler is a friend. 00051 friend class AnalysisHandler; 00052 00053 00054 public: 00055 00056 /// @name Standard constructors and destructors. 00057 //@{ 00058 00059 // /// The default constructor. 00060 // Analysis(); 00061 00062 /// Constructor 00063 Analysis(const std::string& name); 00064 00065 /// The destructor. 00066 virtual ~Analysis() {} 00067 00068 //@} 00069 00070 00071 public: 00072 00073 /// @name Main analysis methods 00074 //@{ 00075 00076 /// Initialize this analysis object. A concrete class should here 00077 /// book all necessary histograms. An overridden function must make 00078 /// sure it first calls the base class function. 00079 virtual void init() { } 00080 00081 /// Analyze one event. A concrete class should here apply the 00082 /// necessary projections on the \a event and fill the relevant 00083 /// histograms. An overridden function must make sure it first calls 00084 /// the base class function. 00085 virtual void analyze(const Event& event) = 0; 00086 00087 /// Finalize this analysis object. A concrete class should here make 00088 /// all necessary operations on the histograms. Writing the 00089 /// histograms to a file is, however, done by the Rivet class. An 00090 /// overridden function must make sure it first calls the base class 00091 /// function. 00092 virtual void finalize() { } 00093 00094 //@} 00095 00096 00097 public: 00098 00099 /// @name Metadata 00100 /// Metadata is used for querying from the command line and also for 00101 /// building web pages and the analysis pages in the Rivet manual. 00102 //@{ 00103 00104 /// Get the actual AnalysisInfo object in which all this metadata is stored. 00105 const AnalysisInfo& info() const { 00106 assert(_info && "No AnalysisInfo object :O"); 00107 return *_info; 00108 } 00109 00110 /// @brief Get the name of the analysis. 00111 /// 00112 /// By default this is computed by combining the results of the experiment, 00113 /// year and Spires ID metadata methods and you should only override it if 00114 /// there's a good reason why those won't work. 00115 virtual std::string name() const { 00116 return (info().name().empty()) ? _defaultname : info().name(); 00117 } 00118 00119 /// Get the Inspire ID code for this analysis. 00120 virtual std::string inspireId() const { 00121 return info().inspireId(); 00122 } 00123 00124 /// Get the SPIRES ID code for this analysis (~deprecated). 00125 virtual std::string spiresId() const { 00126 return info().spiresId(); 00127 } 00128 00129 /// @brief Names & emails of paper/analysis authors. 00130 /// 00131 /// Names and email of authors in 'NAME <EMAIL>' format. The first 00132 /// name in the list should be the primary contact person. 00133 virtual std::vector<std::string> authors() const { 00134 return info().authors(); 00135 } 00136 00137 /// @brief Get a short description of the analysis. 00138 /// 00139 /// Short (one sentence) description used as an index entry. 00140 /// Use @a description() to provide full descriptive paragraphs 00141 /// of analysis details. 00142 virtual std::string summary() const { 00143 return info().summary(); 00144 } 00145 00146 /// @brief Get a full description of the analysis. 00147 /// 00148 /// Full textual description of this analysis, what it is useful for, 00149 /// what experimental techniques are applied, etc. Should be treated 00150 /// as a chunk of restructuredText (http://docutils.sourceforge.net/rst.html), 00151 /// with equations to be rendered as LaTeX with amsmath operators. 00152 virtual std::string description() const { 00153 return info().description(); 00154 } 00155 00156 /// @brief Information about the events needed as input for this analysis. 00157 /// 00158 /// Event types, energies, kinematic cuts, particles to be considered 00159 /// stable, etc. etc. Should be treated as a restructuredText bullet list 00160 /// (http://docutils.sourceforge.net/rst.html) 00161 virtual std::string runInfo() const { 00162 return info().runInfo(); 00163 } 00164 00165 /// Experiment which performed and published this analysis. 00166 virtual std::string experiment() const { 00167 return info().experiment(); 00168 } 00169 00170 /// Collider on which the experiment ran. 00171 virtual std::string collider() const { 00172 return info().collider(); 00173 } 00174 00175 /// When the original experimental analysis was published. 00176 virtual std::string year() const { 00177 return info().year(); 00178 } 00179 00180 /// Journal, and preprint references. 00181 virtual std::vector<std::string> references() const { 00182 return info().references(); 00183 } 00184 00185 /// BibTeX citation key for this article. 00186 virtual std::string bibKey() const { 00187 return info().bibKey(); 00188 } 00189 00190 /// BibTeX citation entry for this article. 00191 virtual std::string bibTeX() const { 00192 return info().bibTeX(); 00193 } 00194 00195 /// Whether this analysis is trusted (in any way!) 00196 virtual std::string status() const { 00197 return (info().status().empty()) ? "UNVALIDATED" : info().status(); 00198 } 00199 00200 /// Any work to be done on this analysis. 00201 virtual std::vector<std::string> todos() const { 00202 return info().todos(); 00203 } 00204 00205 00206 /// Return the allowed pairs of incoming beams required by this analysis. 00207 virtual const std::vector<PdgIdPair>& requiredBeams() const { 00208 return info().beams(); 00209 } 00210 /// Declare the allowed pairs of incoming beams required by this analysis. 00211 virtual Analysis& setRequiredBeams(const std::vector<PdgIdPair>& requiredBeams) { 00212 info().setBeams(requiredBeams); 00213 return *this; 00214 } 00215 00216 00217 /// Sets of valid beam energy pairs, in GeV 00218 virtual const std::vector<std::pair<double, double> >& requiredEnergies() const { 00219 return info().energies(); 00220 } 00221 /// Declare the list of valid beam energy pairs, in GeV 00222 virtual Analysis& setRequiredEnergies(const std::vector<std::pair<double, double> >& requiredEnergies) { 00223 info().setEnergies(requiredEnergies); 00224 return *this; 00225 } 00226 00227 00228 /// Return true if this analysis needs to know the process cross-section. 00229 /// @todo Remove this and require HepMC >= 2.06 00230 bool needsCrossSection() const { 00231 return info().needsCrossSection(); 00232 } 00233 /// Declare whether this analysis needs to know the process cross-section from the generator. 00234 /// @todo Remove this and require HepMC >= 2.06 00235 Analysis& setNeedsCrossSection(bool needed=true) { 00236 info().setNeedsCrossSection(needed); 00237 return *this; 00238 } 00239 00240 //@} 00241 00242 00243 /// @name Internal metadata modifying methods 00244 //@{ 00245 00246 /// Get the actual AnalysisInfo object in which all this metadata is stored (non-const). 00247 AnalysisInfo& info() { 00248 assert(_info && "No AnalysisInfo object :O"); 00249 return *_info; 00250 } 00251 00252 //@} 00253 00254 00255 /// @name Run conditions 00256 //@{ 00257 00258 /// Incoming beams for this run 00259 const ParticlePair& beams() const; 00260 00261 /// Incoming beam IDs for this run 00262 const PdgIdPair beamIds() const; 00263 00264 /// Centre of mass energy for this run 00265 double sqrtS() const; 00266 00267 //@} 00268 00269 00270 /// @name Analysis / beam compatibility testing 00271 //@{ 00272 00273 /// Check if analysis is compatible with the provided beam particle IDs and energies 00274 bool isCompatible(const ParticlePair& beams) const; 00275 00276 /// Check if analysis is compatible with the provided beam particle IDs and energies 00277 bool isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const; 00278 00279 /// Check if analysis is compatible with the provided beam particle IDs and energies 00280 bool isCompatible(const PdgIdPair& beams, const std::pair<double,double>& energies) const; 00281 00282 //@} 00283 00284 00285 /// Set the cross section from the generator 00286 Analysis& setCrossSection(double xs); 00287 00288 /// Access the controlling AnalysisHandler object. 00289 AnalysisHandler& handler() const { return *_analysishandler; } 00290 00291 00292 protected: 00293 00294 /// Get a Log object based on the name() property of the calling analysis object. 00295 Log& getLog() const; 00296 00297 /// Get the process cross-section in pb. Throws if this hasn't been set. 00298 double crossSection() const; 00299 00300 /// Get the process cross-section per generated event in pb. Throws if this 00301 /// hasn't been set. 00302 double crossSectionPerEvent() const; 00303 00304 /// Get the number of events seen (via the analysis handler). Use in the 00305 /// finalize phase only. 00306 size_t numEvents() const; 00307 00308 /// Get the sum of event weights seen (via the analysis handler). Use in the 00309 /// finalize phase only. 00310 double sumOfWeights() const; 00311 00312 00313 protected: 00314 00315 /// @name Histogram paths 00316 //@{ 00317 00318 /// Get the canonical histogram "directory" path for this analysis. 00319 const std::string histoDir() const; 00320 00321 /// Get the canonical histogram path for the named histogram in this analysis. 00322 const std::string histoPath(const std::string& hname) const; 00323 00324 /// Get the canonical histogram path for the numbered histogram in this analysis. 00325 const std::string histoPath(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const; 00326 00327 /// Get the internal histogram name for given d, x and y (cf. HepData) 00328 const std::string makeAxisCode(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const; 00329 00330 //@} 00331 00332 00333 /// @name Histogram reference data 00334 //@{ 00335 00336 /// Get reference data for a named histo 00337 /// @todo Move to the templated version when we have C++11 and can have a default fn template type 00338 const YODA::Scatter2D& refData(const string& hname) const; 00339 00340 /// Get reference data for a numbered histo 00341 /// @todo Move to the templated version when we have C++11 and can have a default fn template type 00342 const YODA::Scatter2D& refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const; 00343 00344 /// Get reference data for a named histo 00345 /// @todo Would be nice to just use these and ditch the S2D no-template version, 00346 /// but we need C++11 for default args in function templates 00347 // template <typename T=Scatter2D> 00348 /// @todo SFINAE to ensure that the type inherits from YODA::AnalysisObject? 00349 template <typename T> 00350 const T& refData(const string& hname) const { 00351 _cacheRefData(); 00352 MSG_TRACE("Using histo bin edges for " << name() << ":" << hname); 00353 if (!_refdata[hname]) { 00354 MSG_ERROR("Can't find reference histogram " << hname); 00355 throw Exception("Reference data " + hname + " not found."); 00356 } 00357 return dynamic_cast<T&>(*_refdata[hname]); 00358 } 00359 00360 /// Get reference data for a numbered histo 00361 /// @todo Would be nice to just use these and ditch the S2D no-template version, 00362 /// but we need C++11 for default args in function templates 00363 // template <typename T=Scatter2D> 00364 /// @todo SFINAE to ensure that the type inherits from YODA::AnalysisObject? 00365 template <typename T> 00366 const T& refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00367 const string hname = makeAxisCode(datasetId, xAxisId, yAxisId); 00368 return refData(hname); 00369 } 00370 00371 //@} 00372 00373 00374 /// @name Counter booking 00375 //@{ 00376 00377 /// Book a counter. 00378 CounterPtr bookCounter(const std::string& name, 00379 const std::string& title=""); 00380 // const std::string& valtitle="" 00381 00382 /// Book a counter, using a path generated from the dataset and axis ID codes 00383 /// 00384 /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00385 CounterPtr bookCounter(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00386 const std::string& title=""); 00387 // const std::string& valtitle="" 00388 00389 //@} 00390 00391 00392 /// @name 1D histogram booking 00393 //@{ 00394 00395 /// Book a 1D histogram with @a nbins uniformly distributed across the range @a lower - @a upper . 00396 Histo1DPtr bookHisto1D(const std::string& name, 00397 size_t nbins, double lower, double upper, 00398 const std::string& title="", 00399 const std::string& xtitle="", 00400 const std::string& ytitle=""); 00401 00402 /// Book a 1D histogram with non-uniform bins defined by the vector of bin edges @a binedges . 00403 Histo1DPtr bookHisto1D(const std::string& name, 00404 const std::vector<double>& binedges, 00405 const std::string& title="", 00406 const std::string& xtitle="", 00407 const std::string& ytitle=""); 00408 00409 /// Book a 1D histogram with binning from a reference scatter. 00410 Histo1DPtr bookHisto1D(const std::string& name, 00411 const Scatter2D& refscatter, 00412 const std::string& title="", 00413 const std::string& xtitle="", 00414 const std::string& ytitle=""); 00415 00416 /// Book a 1D histogram, using the binnings in the reference data histogram. 00417 Histo1DPtr bookHisto1D(const std::string& name, 00418 const std::string& title="", 00419 const std::string& xtitle="", 00420 const std::string& ytitle=""); 00421 00422 /// Book a 1D histogram, using the binnings in the reference data histogram. 00423 /// 00424 /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00425 Histo1DPtr bookHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00426 const std::string& title="", 00427 const std::string& xtitle="", 00428 const std::string& ytitle=""); 00429 00430 //@} 00431 00432 00433 /// @name 2D histogram booking 00434 //@{ 00435 00436 /// Book a 2D histogram with @a nxbins and @a nybins uniformly 00437 /// distributed across the ranges @a xlower - @a xupper and @a 00438 /// ylower - @a yupper respectively along the x- and y-axis. 00439 Histo2DPtr bookHisto2D(const std::string& name, 00440 size_t nxbins, double xlower, double xupper, 00441 size_t nybins, double ylower, double yupper, 00442 const std::string& title="", 00443 const std::string& xtitle="", 00444 const std::string& ytitle="", 00445 const std::string& ztitle=""); 00446 00447 /// Book a 2D histogram with non-uniform bins defined by the 00448 /// vectorx of bin edges @a xbinedges and @a ybinedges. 00449 Histo2DPtr bookHisto2D(const std::string& name, 00450 const std::vector<double>& xbinedges, 00451 const std::vector<double>& ybinedges, 00452 const std::string& title="", 00453 const std::string& xtitle="", 00454 const std::string& ytitle="", 00455 const std::string& ztitle=""); 00456 00457 // /// Book a 2D histogram with binning from a reference scatter. 00458 // Histo2DPtr bookHisto2D(const std::string& name, 00459 // const Scatter3D& refscatter, 00460 // const std::string& title="", 00461 // const std::string& xtitle="", 00462 // const std::string& ytitle="", 00463 // const std::string& ztitle=""); 00464 00465 // /// Book a 2D histogram, using the binnings in the reference data histogram. 00466 // Histo2DPtr bookHisto2D(const std::string& name, 00467 // const std::string& title="", 00468 // const std::string& xtitle="", 00469 // const std::string& ytitle="", 00470 // const std::string& ztitle=""); 00471 00472 // /// Book a 2D histogram, using the binnings in the reference data histogram. 00473 // /// 00474 // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00475 // Histo2DPtr bookHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00476 // const std::string& title="", 00477 // const std::string& xtitle="", 00478 // const std::string& ytitle="", 00479 // const std::string& ztitle=""); 00480 00481 //@} 00482 00483 00484 /// @name 1D profile histogram booking 00485 //@{ 00486 00487 /// Book a 1D profile histogram with @a nbins uniformly distributed across the range @a lower - @a upper . 00488 Profile1DPtr bookProfile1D(const std::string& name, 00489 size_t nbins, double lower, double upper, 00490 const std::string& title="", 00491 const std::string& xtitle="", 00492 const std::string& ytitle=""); 00493 00494 /// Book a 1D profile histogram with non-uniform bins defined by the vector of bin edges @a binedges . 00495 Profile1DPtr bookProfile1D(const std::string& name, 00496 const std::vector<double>& binedges, 00497 const std::string& title="", 00498 const std::string& xtitle="", 00499 const std::string& ytitle=""); 00500 00501 /// Book a 1D profile histogram with binning from a reference scatter. 00502 Profile1DPtr bookProfile1D(const std::string& name, 00503 const Scatter2D& refscatter, 00504 const std::string& title="", 00505 const std::string& xtitle="", 00506 const std::string& ytitle=""); 00507 00508 /// Book a 1D profile histogram, using the binnings in the reference data histogram. 00509 Profile1DPtr bookProfile1D(const std::string& name, 00510 const std::string& title="", 00511 const std::string& xtitle="", 00512 const std::string& ytitle=""); 00513 00514 /// Book a 1D profile histogram, using the binnings in the reference data histogram. 00515 /// 00516 /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00517 Profile1DPtr bookProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00518 const std::string& title="", 00519 const std::string& xtitle="", 00520 const std::string& ytitle=""); 00521 00522 //@} 00523 00524 00525 /// @name 2D profile histogram booking 00526 //@{ 00527 00528 /// Book a 2D profile histogram with @a nxbins and @a nybins uniformly 00529 /// distributed across the ranges @a xlower - @a xupper and @a ylower - @a 00530 /// yupper respectively along the x- and y-axis. 00531 Profile2DPtr bookProfile2D(const std::string& name, 00532 size_t nxbins, double xlower, double xupper, 00533 size_t nybins, double ylower, double yupper, 00534 const std::string& title="", 00535 const std::string& xtitle="", 00536 const std::string& ytitle="", 00537 const std::string& ztitle=""); 00538 00539 /// Book a 2D profile histogram with non-uniform bins defined by the vectorx 00540 /// of bin edges @a xbinedges and @a ybinedges. 00541 Profile2DPtr bookProfile2D(const std::string& name, 00542 const std::vector<double>& xbinedges, 00543 const std::vector<double>& ybinedges, 00544 const std::string& title="", 00545 const std::string& xtitle="", 00546 const std::string& ytitle="", 00547 const std::string& ztitle=""); 00548 00549 /// Book a 2D profile histogram with binning from a reference scatter. 00550 // Profile2DPtr bookProfile2D(const std::string& name, 00551 // const Scatter3D& refscatter, 00552 // const std::string& title="", 00553 // const std::string& xtitle="", 00554 // const std::string& ytitle="", 00555 // const std::string& ztitle=""); 00556 00557 // /// Book a 2D profile histogram, using the binnings in the reference data histogram. 00558 // Profile2DPtr bookProfile2D(const std::string& name, 00559 // const std::string& title="", 00560 // const std::string& xtitle="", 00561 // const std::string& ytitle="", 00562 // const std::string& ztitle=""); 00563 00564 // /// Book a 2D profile histogram, using the binnings in the reference data histogram. 00565 // /// 00566 // /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00567 // Profile2DPtr bookProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00568 // const std::string& title="", 00569 // const std::string& xtitle="", 00570 // const std::string& ytitle="", 00571 // const std::string& ztitle=""); 00572 00573 //@} 00574 00575 00576 /// @name 2D scatter booking 00577 //@{ 00578 00579 /// @brief Book a 2-dimensional data point set with the given name. 00580 /// 00581 /// @note Unlike histogram booking, scatter booking by default makes no 00582 /// attempt to use reference data to pre-fill the data object. If you want 00583 /// this, which is sometimes useful e.g. when the x-position is not really 00584 /// meaningful and can't be extracted from the data, then set the @a 00585 /// copy_pts parameter to true. This creates points to match the reference 00586 /// data's x values and errors, but with the y values and errors zeroed... 00587 /// assuming that there is a reference histo with the same name: if there 00588 /// isn't, an exception will be thrown. 00589 Scatter2DPtr bookScatter2D(const std::string& name, 00590 bool copy_pts=false, 00591 const std::string& title="", 00592 const std::string& xtitle="", 00593 const std::string& ytitle=""); 00594 00595 /// @brief Book a 2-dimensional data point set, using the binnings in the reference data histogram. 00596 /// 00597 /// The paper, dataset and x/y-axis IDs will be used to build the histo name in the HepData standard way. 00598 /// 00599 /// @note Unlike histogram booking, scatter booking by default makes no 00600 /// attempt to use reference data to pre-fill the data object. If you want 00601 /// this, which is sometimes useful e.g. when the x-position is not really 00602 /// meaningful and can't be extracted from the data, then set the @a 00603 /// copy_pts parameter to true. This creates points to match the reference 00604 /// data's x values and errors, but with the y values and errors zeroed. 00605 Scatter2DPtr bookScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00606 bool copy_pts=false, 00607 const std::string& title="", 00608 const std::string& xtitle="", 00609 const std::string& ytitle=""); 00610 00611 /// @brief Book a 2-dimensional data point set with equally spaced x-points in a range. 00612 /// 00613 /// The y values and errors will be set to 0. 00614 Scatter2DPtr bookScatter2D(const std::string& name, 00615 size_t npts, double lower, double upper, 00616 const std::string& title="", 00617 const std::string& xtitle="", 00618 const std::string& ytitle=""); 00619 00620 /// @brief Book a 2-dimensional data point set based on provided contiguous "bin edges". 00621 /// 00622 /// The y values and errors will be set to 0. 00623 Scatter2DPtr bookScatter2D(const std::string& hname, 00624 const std::vector<double>& binedges, 00625 const std::string& title, 00626 const std::string& xtitle, 00627 const std::string& ytitle); 00628 00629 //@} 00630 00631 00632 public: 00633 00634 00635 /// @name Analysis object manipulation 00636 /// @todo Should really be protected: only public to keep BinnedHistogram happy for now... 00637 //@{ 00638 00639 /// Multiplicatively scale the given counter, @a cnt, by factor @s factor. 00640 void scale(CounterPtr cnt, double factor); 00641 00642 /// Multiplicatively scale the given counters, @a cnts, by factor @s factor. 00643 /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh) 00644 /// @todo Use SFINAE for a generic iterable of CounterPtrs 00645 void scale(const std::vector<CounterPtr>& cnts, double factor) { 00646 for (auto& c : cnts) scale(c, factor); 00647 } 00648 /// @todo YUCK! 00649 template <std::size_t array_size> 00650 void scale(const CounterPtr (&cnts)[array_size], double factor) { 00651 // for (size_t i = 0; i < std::extent<decltype(cnts)>::value; ++i) scale(cnts[i], factor); 00652 for (auto& c : cnts) scale(c, factor); 00653 } 00654 00655 00656 /// Normalize the given histogram, @a histo, to area = @a norm. 00657 void normalize(Histo1DPtr histo, double norm=1.0, bool includeoverflows=true); 00658 00659 /// Normalize the given histograms, @a histos, to area = @a norm. 00660 /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh) 00661 /// @todo Use SFINAE for a generic iterable of Histo1DPtrs 00662 void normalize(const std::vector<Histo1DPtr>& histos, double norm=1.0, bool includeoverflows=true) { 00663 for (auto& h : histos) normalize(h, norm, includeoverflows); 00664 } 00665 /// @todo YUCK! 00666 template <std::size_t array_size> 00667 void normalize(const Histo1DPtr (&histos)[array_size], double norm=1.0, bool includeoverflows=true) { 00668 for (auto& h : histos) normalize(h, norm, includeoverflows); 00669 } 00670 00671 /// Multiplicatively scale the given histogram, @a histo, by factor @s factor. 00672 void scale(Histo1DPtr histo, double factor); 00673 00674 /// Multiplicatively scale the given histograms, @a histos, by factor @s factor. 00675 /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh) 00676 /// @todo Use SFINAE for a generic iterable of Histo1DPtrs 00677 void scale(const std::vector<Histo1DPtr>& histos, double factor) { 00678 for (auto& h : histos) scale(h, factor); 00679 } 00680 /// @todo YUCK! 00681 template <std::size_t array_size> 00682 void scale(const Histo1DPtr (&histos)[array_size], double factor) { 00683 for (auto& h : histos) scale(h, factor); 00684 } 00685 00686 00687 /// Normalize the given histogram, @a histo, to area = @a norm. 00688 void normalize(Histo2DPtr histo, double norm=1.0, bool includeoverflows=true); 00689 00690 /// Normalize the given histograms, @a histos, to area = @a norm. 00691 /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh) 00692 /// @todo Use SFINAE for a generic iterable of Histo2DPtrs 00693 void normalize(const std::vector<Histo2DPtr>& histos, double norm=1.0, bool includeoverflows=true) { 00694 for (auto& h : histos) normalize(h, norm, includeoverflows); 00695 } 00696 /// @todo YUCK! 00697 template <std::size_t array_size> 00698 void normalize(const Histo2DPtr (&histos)[array_size], double norm=1.0, bool includeoverflows=true) { 00699 for (auto& h : histos) normalize(h, norm, includeoverflows); 00700 } 00701 00702 /// Multiplicatively scale the given histogram, @a histo, by factor @s factor. 00703 void scale(Histo2DPtr histo, double factor); 00704 00705 /// Multiplicatively scale the given histograms, @a histos, by factor @s factor. 00706 /// @note Constness intentional, if weird, to allow passing rvalue refs of smart ptrs (argh) 00707 /// @todo Use SFINAE for a generic iterable of Histo2DPtrs 00708 void scale(const std::vector<Histo2DPtr>& histos, double factor) { 00709 for (auto& h : histos) scale(h, factor); 00710 } 00711 /// @todo YUCK! 00712 template <std::size_t array_size> 00713 void scale(const Histo2DPtr (&histos)[array_size], double factor) { 00714 for (auto& h : histos) scale(h, factor); 00715 } 00716 00717 00718 /// Helper for counter division. 00719 /// 00720 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00721 void divide(CounterPtr c1, CounterPtr c2, Scatter1DPtr s) const; 00722 00723 /// Helper for histogram division with raw YODA objects. 00724 /// 00725 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00726 void divide(const YODA::Counter& c1, const YODA::Counter& c2, Scatter1DPtr s) const; 00727 00728 00729 /// Helper for histogram division. 00730 /// 00731 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00732 void divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const; 00733 00734 /// Helper for histogram division with raw YODA objects. 00735 /// 00736 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00737 void divide(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const; 00738 00739 00740 /// Helper for profile histogram division. 00741 /// 00742 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00743 void divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const; 00744 00745 /// Helper for profile histogram division with raw YODA objects. 00746 /// 00747 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00748 void divide(const YODA::Profile1D& p1, const YODA::Profile1D& p2, Scatter2DPtr s) const; 00749 00750 00751 /// Helper for 2D histogram division. 00752 /// 00753 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00754 void divide(Histo2DPtr h1, Histo2DPtr h2, Scatter3DPtr s) const; 00755 00756 /// Helper for 2D histogram division with raw YODA objects. 00757 /// 00758 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00759 void divide(const YODA::Histo2D& h1, const YODA::Histo2D& h2, Scatter3DPtr s) const; 00760 00761 00762 /// Helper for 2D profile histogram division. 00763 /// 00764 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00765 void divide(Profile2DPtr p1, Profile2DPtr p2, Scatter3DPtr s) const; 00766 00767 /// Helper for 2D profile histogram division with raw YODA objects 00768 /// 00769 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00770 void divide(const YODA::Profile2D& p1, const YODA::Profile2D& p2, Scatter3DPtr s) const; 00771 00772 00773 /// Helper for histogram efficiency calculation. 00774 /// 00775 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00776 void efficiency(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const; 00777 00778 /// Helper for histogram efficiency calculation. 00779 /// 00780 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00781 void efficiency(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const; 00782 00783 00784 /// Helper for histogram asymmetry calculation. 00785 /// 00786 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00787 void asymm(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const; 00788 00789 /// Helper for histogram asymmetry calculation. 00790 /// 00791 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00792 void asymm(const YODA::Histo1D& h1, const YODA::Histo1D& h2, Scatter2DPtr s) const; 00793 00794 00795 /// Helper for converting a differential histo to an integral one. 00796 /// 00797 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00798 void integrate(Histo1DPtr h, Scatter2DPtr s) const; 00799 00800 /// Helper for converting a differential histo to an integral one. 00801 /// 00802 /// @note Assigns to the (already registered) output scatter, @a s. Preserves the path information of the target. 00803 void integrate(const Histo1D& h, Scatter2DPtr s) const; 00804 00805 //@} 00806 00807 00808 public: 00809 00810 /// List of registered analysis data objects 00811 const vector<AnalysisObjectPtr>& analysisObjects() const { 00812 return _analysisobjects; 00813 } 00814 00815 00816 protected: 00817 00818 /// @name Data object registration, retrieval, and removal 00819 //@{ 00820 00821 /// Register a data object in the histogram system 00822 void addAnalysisObject(AnalysisObjectPtr ao); 00823 00824 /// Get a data object from the histogram system 00825 /// @todo Use this default function template arg in C++11 00826 // template <typename AO=AnalysisObjectPtr> 00827 template <typename AO> 00828 const std::shared_ptr<AO> getAnalysisObject(const std::string& name) const { 00829 foreach (const AnalysisObjectPtr& ao, analysisObjects()) { 00830 if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao); 00831 } 00832 throw Exception("Data object " + histoPath(name) + " not found"); 00833 } 00834 00835 /// Get a data object from the histogram system (non-const) 00836 /// @todo Use this default function template arg in C++11 00837 // template <typename AO=AnalysisObjectPtr> 00838 template <typename AO> 00839 std::shared_ptr<AO> getAnalysisObject(const std::string& name) { 00840 foreach (const AnalysisObjectPtr& ao, analysisObjects()) { 00841 if (ao->path() == histoPath(name)) return dynamic_pointer_cast<AO>(ao); 00842 } 00843 throw Exception("Data object " + histoPath(name) + " not found"); 00844 } 00845 00846 /// Unregister a data object from the histogram system (by name) 00847 void removeAnalysisObject(const std::string& path); 00848 00849 /// Unregister a data object from the histogram system (by pointer) 00850 void removeAnalysisObject(AnalysisObjectPtr ao); 00851 00852 00853 /// Get a named Histo1D object from the histogram system 00854 const Histo1DPtr getHisto1D(const std::string& name) const { 00855 return getAnalysisObject<Histo1D>(name); 00856 } 00857 00858 /// Get a named Histo1D object from the histogram system (non-const) 00859 Histo1DPtr getHisto1D(const std::string& name) { 00860 return getAnalysisObject<Histo1D>(name); 00861 } 00862 00863 /// Get a Histo1D object from the histogram system by axis ID codes (non-const) 00864 const Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00865 return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00866 } 00867 00868 /// Get a Histo1D object from the histogram system by axis ID codes (non-const) 00869 Histo1DPtr getHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) { 00870 return getAnalysisObject<Histo1D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00871 } 00872 00873 00874 // /// Get a named Histo2D object from the histogram system 00875 // const Histo2DPtr getHisto2D(const std::string& name) const { 00876 // return getAnalysisObject<Histo2D>(name); 00877 // } 00878 00879 // /// Get a named Histo2D object from the histogram system (non-const) 00880 // Histo2DPtr getHisto2D(const std::string& name) { 00881 // return getAnalysisObject<Histo2D>(name); 00882 // } 00883 00884 // /// Get a Histo2D object from the histogram system by axis ID codes (non-const) 00885 // const Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00886 // return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00887 // } 00888 00889 // /// Get a Histo2D object from the histogram system by axis ID codes (non-const) 00890 // Histo2DPtr getHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) { 00891 // return getAnalysisObject<Histo2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00892 // } 00893 00894 00895 /// Get a named Profile1D object from the histogram system 00896 const Profile1DPtr getProfile1D(const std::string& name) const { 00897 return getAnalysisObject<Profile1D>(name); 00898 } 00899 00900 /// Get a named Profile1D object from the histogram system (non-const) 00901 Profile1DPtr getProfile1D(const std::string& name) { 00902 return getAnalysisObject<Profile1D>(name); 00903 } 00904 00905 /// Get a Profile1D object from the histogram system by axis ID codes (non-const) 00906 const Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00907 return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00908 } 00909 00910 /// Get a Profile1D object from the histogram system by axis ID codes (non-const) 00911 Profile1DPtr getProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) { 00912 return getAnalysisObject<Profile1D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00913 } 00914 00915 00916 // /// Get a named Profile2D object from the histogram system 00917 // const Profile2DPtr getProfile2D(const std::string& name) const { 00918 // return getAnalysisObject<Profile2D>(name); 00919 // } 00920 00921 // /// Get a named Profile2D object from the histogram system (non-const) 00922 // Profile2DPtr getProfile2D(const std::string& name) { 00923 // return getAnalysisObject<Profile2D>(name); 00924 // } 00925 00926 // /// Get a Profile2D object from the histogram system by axis ID codes (non-const) 00927 // const Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00928 // return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00929 // } 00930 00931 // /// Get a Profile2D object from the histogram system by axis ID codes (non-const) 00932 // Profile2DPtr getProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) { 00933 // return getAnalysisObject<Profile2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00934 // } 00935 00936 00937 /// Get a named Scatter2D object from the histogram system 00938 const Scatter2DPtr getScatter2D(const std::string& name) const { 00939 return getAnalysisObject<Scatter2D>(name); 00940 } 00941 00942 /// Get a named Scatter2D object from the histogram system (non-const) 00943 Scatter2DPtr getScatter2D(const std::string& name) { 00944 return getAnalysisObject<Scatter2D>(name); 00945 } 00946 00947 /// Get a Scatter2D object from the histogram system by axis ID codes (non-const) 00948 const Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00949 return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00950 } 00951 00952 /// Get a Scatter2D object from the histogram system by axis ID codes (non-const) 00953 Scatter2DPtr getScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) { 00954 return getAnalysisObject<Scatter2D>(makeAxisCode(datasetId, xAxisId, yAxisId)); 00955 } 00956 00957 //@} 00958 00959 00960 private: 00961 00962 /// Name passed to constructor (used to find .info analysis data file, and as a fallback) 00963 string _defaultname; 00964 00965 /// Pointer to analysis metadata object 00966 unique_ptr<AnalysisInfo> _info; 00967 00968 /// Storage of all plot objects 00969 /// @todo Make this a map for fast lookup by path? 00970 vector<AnalysisObjectPtr> _analysisobjects; 00971 00972 /// @name Cross-section variables 00973 //@{ 00974 double _crossSection; 00975 bool _gotCrossSection; 00976 //@} 00977 00978 /// The controlling AnalysisHandler object. 00979 AnalysisHandler* _analysishandler; 00980 00981 /// Collection of cached refdata to speed up many autobookings: the 00982 /// reference data file should only be read once. 00983 mutable std::map<std::string, AnalysisObjectPtr> _refdata; 00984 00985 00986 private: 00987 00988 /// @name Utility functions 00989 //@{ 00990 00991 /// Get the reference data for this paper and cache it. 00992 void _cacheRefData() const; 00993 00994 //@} 00995 00996 00997 /// The assignment operator is private and must never be called. 00998 /// In fact, it should not even be implemented. 00999 Analysis& operator=(const Analysis&); 01000 01001 }; 01002 01003 01004 } 01005 01006 01007 // Include definition of analysis plugin system so that analyses automatically see it when including Analysis.hh 01008 #include "Rivet/AnalysisBuilder.hh" 01009 01010 /// @def DECLARE_RIVET_PLUGIN 01011 /// Preprocessor define to prettify the global-object plugin hook mechanism. 01012 #define DECLARE_RIVET_PLUGIN(clsname) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname 01013 01014 /// @def DECLARE_ALIASED_RIVET_PLUGIN 01015 /// Preprocessor define to prettify the global-object plugin hook mechanism, with an extra alias name for this analysis. 01016 // #define DECLARE_ALIASED_RIVET_PLUGIN(clsname, alias) Rivet::AnalysisBuilder<clsname> plugin_ ## clsname ## ( ## #alias ## ) 01017 #define DECLARE_ALIASED_RIVET_PLUGIN(clsname, alias) DECLARE_RIVET_PLUGIN(clsname)( #alias ) 01018 01019 /// @def DEFAULT_RIVET_ANA_CONSTRUCTOR 01020 /// Preprocessor define to prettify the manky constructor with name string argument 01021 #define DEFAULT_RIVET_ANALYSIS_CTOR(clsname) clsname() : Analysis(# clsname) {} 01022 01023 // DEPRECATED ALIAS 01024 #define DEFAULT_RIVET_ANA_CONSTRUCTOR(clsname) DEFAULT_RIVET_ANALYSIS_CTOR(clsname) 01025 01026 01027 #endif Generated on Tue Dec 13 2016 16:32:34 for The Rivet MC analysis system by ![]() |