rivet is hosted by Hepforge, IPPP Durham
Analysis.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Config/RivetCommon.hh"
00003 #include "Rivet/Analysis.hh"
00004 #include "Rivet/AnalysisHandler.hh"
00005 #include "Rivet/AnalysisInfo.hh"
00006 #include "Rivet/BeamConstraint.hh"
00007 #include "Rivet/Tools/RivetYODA.hh"
00008 #include "Rivet/Tools/Logging.hh"
00009 
00010 namespace Rivet {
00011 
00012 
00013   Analysis::Analysis(const string& name)
00014     : _crossSection(-1.0),
00015       _gotCrossSection(false),
00016       _analysishandler(NULL)
00017   {
00018     ProjectionApplier::_allowProjReg = false;
00019     _defaultname = name;
00020 
00021     AnalysisInfo* ai = AnalysisInfo::make(name);
00022     assert(ai != 0);
00023     _info.reset(ai);
00024     assert(_info.get() != 0);
00025   }
00026 
00027   double Analysis::sqrtS() const {
00028     return handler().sqrtS();
00029   }
00030 
00031   const ParticlePair& Analysis::beams() const {
00032     return handler().beams();
00033   }
00034 
00035   const PdgIdPair Analysis::beamIds() const {
00036     return handler().beamIds();
00037   }
00038 
00039 
00040   const string Analysis::histoDir() const {
00041     /// @todo Cache in a member variable
00042     string _histoDir;
00043     if (_histoDir.empty()) {
00044       _histoDir = "/" + name();
00045       if (handler().runName().length() > 0) {
00046         _histoDir = "/" + handler().runName() + _histoDir;
00047       }
00048       while (find_first(_histoDir, "//")) {
00049         replace_all(_histoDir, "//", "/");
00050       }
00051     }
00052     return _histoDir;
00053   }
00054 
00055 
00056   const string Analysis::histoPath(const string& hname) const {
00057     const string path = histoDir() + "/" + hname;
00058     return path;
00059   }
00060 
00061 
00062   const string Analysis::histoPath(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00063     return histoDir() + "/" + makeAxisCode(datasetId, xAxisId, yAxisId);
00064   }
00065 
00066 
00067   const string Analysis::makeAxisCode(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00068     stringstream axisCode;
00069     axisCode << "d";
00070     if (datasetId < 10) axisCode << 0;
00071     axisCode << datasetId;
00072     axisCode << "-x";
00073     if (xAxisId < 10) axisCode << 0;
00074     axisCode << xAxisId;
00075     axisCode << "-y";
00076     if (yAxisId < 10) axisCode << 0;
00077     axisCode << yAxisId;
00078     return axisCode.str();
00079   }
00080 
00081 
00082   Log& Analysis::getLog() const {
00083     string logname = "Rivet.Analysis." + name();
00084     return Log::getLog(logname);
00085   }
00086 
00087 
00088   size_t Analysis::numEvents() const {
00089     return handler().numEvents();
00090   }
00091 
00092 
00093   double Analysis::sumOfWeights() const {
00094     return handler().sumOfWeights();
00095   }
00096 
00097 
00098   ///////////////////////////////////////////
00099 
00100 
00101   bool Analysis::isCompatible(const ParticlePair& beams) const {
00102     return isCompatible(beams.first.pid(),  beams.second.pid(),
00103                         beams.first.energy(), beams.second.energy());
00104   }
00105 
00106 
00107   bool Analysis::isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const {
00108     PdgIdPair beams(beam1, beam2);
00109     pair<double,double> energies(e1, e2);
00110     return isCompatible(beams, energies);
00111   }
00112 
00113 
00114   bool Analysis::isCompatible(const PdgIdPair& beams, const pair<double,double>& energies) const {
00115     // First check the beam IDs
00116     bool beamIdsOk = false;
00117     foreach (const PdgIdPair& bp, requiredBeams()) {
00118       if (compatible(beams, bp)) {
00119         beamIdsOk =  true;
00120         break;
00121       }
00122     }
00123     if (!beamIdsOk) return false;
00124 
00125     // Next check that the energies are compatible (within 1% or 1 GeV, whichever is larger, for a bit of UI forgiveness)
00126 
00127     /// @todo Use some sort of standard ordering to improve comparisons, esp. when the two beams are different particles
00128     bool beamEnergiesOk = requiredEnergies().size() > 0 ? false : true;
00129     typedef pair<double,double> DoublePair;
00130     foreach (const DoublePair& ep, requiredEnergies()) {
00131       if ((fuzzyEquals(ep.first, energies.first, 0.01) && fuzzyEquals(ep.second, energies.second, 0.01)) ||
00132           (fuzzyEquals(ep.first, energies.second, 0.01) && fuzzyEquals(ep.second, energies.first, 0.01)) ||
00133           (abs(ep.first - energies.first) < 1*GeV && abs(ep.second - energies.second) < 1*GeV) ||
00134           (abs(ep.first - energies.second) < 1*GeV && abs(ep.second - energies.first) < 1*GeV)) {
00135         beamEnergiesOk =  true;
00136         break;
00137       }
00138     }
00139     return beamEnergiesOk;
00140 
00141     /// @todo Need to also check internal consistency of the analysis'
00142     /// beam requirements with those of the projections it uses.
00143   }
00144 
00145 
00146   ///////////////////////////////////////////
00147 
00148 
00149   Analysis& Analysis::setCrossSection(double xs) {
00150     _crossSection = xs;
00151     _gotCrossSection = true;
00152     return *this;
00153   }
00154 
00155   double Analysis::crossSection() const {
00156     if (!_gotCrossSection || std::isnan(_crossSection)) {
00157       string errMsg = "You did not set the cross section for the analysis " + name();
00158       throw Error(errMsg);
00159     }
00160     return _crossSection;
00161   }
00162 
00163   double Analysis::crossSectionPerEvent() const {
00164     const double sumW = sumOfWeights();
00165     assert(sumW != 0.0);
00166     return _crossSection / sumW;
00167   }
00168 
00169 
00170 
00171   ////////////////////////////////////////////////////////////
00172   // Histogramming
00173 
00174 
00175   void Analysis::_cacheRefData() const {
00176     if (_refdata.empty()) {
00177       MSG_TRACE("Getting refdata cache for paper " << name());
00178       _refdata = getRefData(name());
00179     }
00180   }
00181 
00182 
00183   const Scatter2D& Analysis::refData(const string& hname) const {
00184     _cacheRefData();
00185     MSG_TRACE("Using histo bin edges for " << name() << ":" << hname);
00186     if (!_refdata[hname]) {
00187       MSG_ERROR("Can't find reference histogram " << hname);
00188     }
00189     return *_refdata[hname];
00190   }
00191 
00192 
00193   const Scatter2D& Analysis::refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const {
00194     const string hname = makeAxisCode(datasetId, xAxisId, yAxisId);
00195     return refData(hname);
00196   }
00197 
00198 
00199   Histo1DPtr Analysis::bookHisto1D(const string& hname,
00200                                    size_t nbins, double lower, double upper,
00201                                    const string& title,
00202                                    const string& xtitle,
00203                                    const string& ytitle) {
00204     const string path = histoPath(hname);
00205     Histo1DPtr hist( new Histo1D(nbins, lower, upper, path, title) );
00206     addAnalysisObject(hist);
00207     MSG_TRACE("Made histogram " << hname <<  " for " << name());
00208     hist->setAnnotation("XLabel", xtitle);
00209     hist->setAnnotation("YLabel", ytitle);
00210     return hist;
00211   }
00212 
00213 
00214   Histo1DPtr Analysis::bookHisto1D(const string& hname,
00215                                    const vector<double>& binedges,
00216                                    const string& title,
00217                                    const string& xtitle,
00218                                    const string& ytitle) {
00219     const string path = histoPath(hname);
00220     Histo1DPtr hist( new Histo1D(binedges, path, title) );
00221     addAnalysisObject(hist);
00222     MSG_TRACE("Made histogram " << hname <<  " for " << name());
00223     hist->setAnnotation("XLabel", xtitle);
00224     hist->setAnnotation("YLabel", ytitle);
00225     return hist;
00226   }
00227 
00228 
00229   Histo1DPtr Analysis::bookHisto1D(const string& hname,
00230                                    const Scatter2D& refscatter,
00231                                    const string& title,
00232                                    const string& xtitle,
00233                                    const string& ytitle) {
00234     const string path = histoPath(hname);
00235     Histo1DPtr hist( new Histo1D(refscatter, path) );
00236     addAnalysisObject(hist);
00237     MSG_TRACE("Made histogram " << hname <<  " for " << name());
00238     hist->setTitle(title);
00239     hist->setAnnotation("XLabel", xtitle);
00240     hist->setAnnotation("YLabel", ytitle);
00241     return hist;
00242   }
00243 
00244 
00245   Histo1DPtr Analysis::bookHisto1D(const string& hname,
00246                                    const string& title,
00247                                    const string& xtitle,
00248                                    const string& ytitle) {
00249     const Scatter2D& refdata = refData(hname);
00250     return bookHisto1D(hname, refdata, title, xtitle, ytitle);
00251   }
00252 
00253 
00254   Histo1DPtr Analysis::bookHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00255                                    const string& title,
00256                                    const string& xtitle,
00257                                    const string& ytitle) {
00258     const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId);
00259     return bookHisto1D(axisCode, title, xtitle, ytitle);
00260   }
00261 
00262 
00263   /// @todo Add booking methods which take a path, titles and *a reference Scatter from which to book*
00264 
00265 
00266   /////////////////
00267 
00268 
00269   Histo2DPtr Analysis::bookHisto2D(const string& hname,
00270                                    size_t nxbins, double xlower, double xupper,
00271                                    size_t nybins, double ylower, double yupper,
00272                                    const string& title,
00273                                    const string& xtitle,
00274                                    const string& ytitle,
00275                                    const string& ztitle)
00276   {
00277     const string path = histoPath(hname);
00278     Histo2DPtr hist( new Histo2D(nxbins, xlower, xupper, nybins, ylower, yupper, path, title) );
00279     addAnalysisObject(hist);
00280     MSG_TRACE("Made 2D histogram " << hname <<  " for " << name());
00281     hist->setAnnotation("XLabel", xtitle);
00282     hist->setAnnotation("YLabel", ytitle);
00283     hist->setAnnotation("ZLabel", ztitle);
00284     return hist;
00285   }
00286 
00287 
00288   Histo2DPtr Analysis::bookHisto2D(const string& hname,
00289                                    const vector<double>& xbinedges,
00290                                    const vector<double>& ybinedges,
00291                                    const string& title,
00292                                    const string& xtitle,
00293                                    const string& ytitle,
00294                                    const string& ztitle)
00295   {
00296     const string path = histoPath(hname);
00297     Histo2DPtr hist( new Histo2D(xbinedges, ybinedges, path, title) );
00298     addAnalysisObject(hist);
00299     MSG_TRACE("Made 2D histogram " << hname <<  " for " << name());
00300     hist->setAnnotation("XLabel", xtitle);
00301     hist->setAnnotation("YLabel", ytitle);
00302     hist->setAnnotation("ZLabel", ztitle);
00303     return hist;
00304   }
00305 
00306 
00307   // Histo2DPtr Analysis::bookHisto2D(const string& hname,
00308   //                                  const Scatter3D& refscatter,
00309   //                                  const string& title="",
00310   //                                  const string& xtitle="",
00311   //                                  const string& ytitle="",
00312   //                                  const string& ztitle="") {
00313   //   const string path = histoPath(hname);
00314   //   Histo2DPtr hist( new Histo2D(refscatter, path) );
00315   //   addAnalysisObject(hist);
00316   //   MSG_TRACE("Made 2D histogram " << hname <<  " for " << name());
00317   //   hist->setTitle(title);
00318   //   hist->setAnnotation("XLabel", xtitle);
00319   //   hist->setAnnotation("YLabel", ytitle);
00320   //   hist->setAnnotation("ZLabel", ztitle);
00321   //   return hist;
00322   // }
00323 
00324 
00325   // Histo2DPtr Analysis::bookHisto2D(const string& hname,
00326   //                                  const string& title,
00327   //                                  const string& xtitle,
00328   //                                  const string& ytitle,
00329   //                                  const string& ztitle) {
00330   //   const Scatter3D& refdata = refData(hname);
00331   //   return bookHisto2D(hname, refdata, title, xtitle, ytitle, ztitle);
00332   // }
00333 
00334 
00335   // Histo2DPtr Analysis::bookHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00336   //                                  const string& title,
00337   //                                  const string& xtitle,
00338   //                                  const string& ytitle,
00339   //                                  const string& ztitle) {
00340   //   const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId);
00341   //   return bookHisto2D(axisCode, title, xtitle, ytitle, ztitle);
00342   // }
00343 
00344 
00345   /////////////////
00346 
00347 
00348   Profile1DPtr Analysis::bookProfile1D(const string& hname,
00349                                        size_t nbins, double lower, double upper,
00350                                        const string& title,
00351                                        const string& xtitle,
00352                                        const string& ytitle) {
00353     const string path = histoPath(hname);
00354     Profile1DPtr prof( new Profile1D(nbins, lower, upper, path, title) );
00355     addAnalysisObject(prof);
00356     MSG_TRACE("Made profile histogram " << hname <<  " for " << name());
00357     prof->setAnnotation("XLabel", xtitle);
00358     prof->setAnnotation("YLabel", ytitle);
00359     return prof;
00360   }
00361 
00362 
00363   Profile1DPtr Analysis::bookProfile1D(const string& hname,
00364                                        const vector<double>& binedges,
00365                                        const string& title,
00366                                        const string& xtitle,
00367                                        const string& ytitle) {
00368     const string path = histoPath(hname);
00369     Profile1DPtr prof( new Profile1D(binedges, path, title) );
00370     addAnalysisObject(prof);
00371     MSG_TRACE("Made profile histogram " << hname <<  " for " << name());
00372     prof->setAnnotation("XLabel", xtitle);
00373     prof->setAnnotation("YLabel", ytitle);
00374     return prof;
00375   }
00376 
00377 
00378   Profile1DPtr Analysis::bookProfile1D(const string& hname,
00379                                        const Scatter2D& refscatter,
00380                                        const string& title,
00381                                        const string& xtitle,
00382                                        const string& ytitle) {
00383     const string path = histoPath(hname);
00384     Profile1DPtr prof( new Profile1D(refscatter, path) );
00385     addAnalysisObject(prof);
00386     MSG_TRACE("Made profile histogram " << hname <<  " for " << name());
00387     prof->setTitle(title);
00388     prof->setAnnotation("XLabel", xtitle);
00389     prof->setAnnotation("YLabel", ytitle);
00390     return prof;
00391   }
00392 
00393 
00394   Profile1DPtr Analysis::bookProfile1D(const string& hname,
00395                                        const string& title,
00396                                        const string& xtitle,
00397                                        const string& ytitle) {
00398     const Scatter2D& refdata = refData(hname);
00399     return bookProfile1D(hname, refdata, title, xtitle, ytitle);
00400   }
00401 
00402 
00403   Profile1DPtr Analysis::bookProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00404                                        const string& title,
00405                                        const string& xtitle,
00406                                        const string& ytitle) {
00407     const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId);
00408     return bookProfile1D(axisCode, title, xtitle, ytitle);
00409   }
00410 
00411 
00412   ///////////////////
00413 
00414 
00415 
00416   Profile2DPtr Analysis::bookProfile2D(const string& hname,
00417                                    size_t nxbins, double xlower, double xupper,
00418                                    size_t nybins, double ylower, double yupper,
00419                                    const string& title,
00420                                    const string& xtitle,
00421                                    const string& ytitle,
00422                                    const string& ztitle)
00423   {
00424     const string path = histoPath(hname);
00425     Profile2DPtr prof( new Profile2D(nxbins, xlower, xupper, nybins, ylower, yupper, path, title) );
00426     addAnalysisObject(prof);
00427     MSG_TRACE("Made 2D profile histogram " << hname <<  " for " << name());
00428     prof->setAnnotation("XLabel", xtitle);
00429     prof->setAnnotation("YLabel", ytitle);
00430     prof->setAnnotation("ZLabel", ztitle);
00431     return prof;
00432   }
00433 
00434 
00435   Profile2DPtr Analysis::bookProfile2D(const string& hname,
00436                                    const vector<double>& xbinedges,
00437                                    const vector<double>& ybinedges,
00438                                    const string& title,
00439                                    const string& xtitle,
00440                                    const string& ytitle,
00441                                    const string& ztitle)
00442   {
00443     const string path = histoPath(hname);
00444     Profile2DPtr prof( new Profile2D(xbinedges, ybinedges, path, title) );
00445     addAnalysisObject(prof);
00446     MSG_TRACE("Made 2D profile histogram " << hname <<  " for " << name());
00447     prof->setAnnotation("XLabel", xtitle);
00448     prof->setAnnotation("YLabel", ytitle);
00449     prof->setAnnotation("ZLabel", ztitle);
00450     return prof;
00451   }
00452 
00453 
00454   // Profile2DPtr Analysis::bookProfile2D(const string& hname,
00455   //                                  const Scatter3D& refscatter,
00456   //                                  const string& title="",
00457   //                                  const string& xtitle="",
00458   //                                  const string& ytitle="",
00459   //                                  const string& ztitle="") {
00460   //   const string path = histoPath(hname);
00461   //   Profile2DPtr prof( new Profile2D(refscatter, path) );
00462   //   addAnalysisObject(prof);
00463   //   MSG_TRACE("Made 2D profile histogram " << hname <<  " for " << name());
00464   //   prof->setTitle(title);
00465   //   prof->setAnnotation("XLabel", xtitle);
00466   //   prof->setAnnotation("YLabel", ytitle);
00467   //   prof->setAnnotation("ZLabel", ztitle);
00468   //   return prof;
00469   // }
00470 
00471 
00472   // Profile2DPtr Analysis::bookProfile2D(const string& hname,
00473   //                                  const string& title,
00474   //                                  const string& xtitle,
00475   //                                  const string& ytitle,
00476   //                                  const string& ztitle) {
00477   //   const Scatter3D& refdata = refData(hname);
00478   //   return bookProfile2D(hname, refdata, title, xtitle, ytitle, ztitle);
00479   // }
00480 
00481 
00482   // Profile2DPtr Analysis::bookProfile2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00483   //                                  const string& title,
00484   //                                  const string& xtitle,
00485   //                                  const string& ytitle,
00486   //                                  const string& ztitle) {
00487   //   const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId);
00488   //   return bookProfile2D(axisCode, title, xtitle, ytitle, ztitle);
00489   // }
00490 
00491 
00492   /////////////////
00493 
00494 
00495   Scatter2DPtr Analysis::bookScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId,
00496                                        bool copy_pts,
00497                                        const string& title,
00498                                        const string& xtitle,
00499                                        const string& ytitle) {
00500     const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId);
00501     return bookScatter2D(axisCode, copy_pts, title, xtitle, ytitle);
00502   }
00503 
00504 
00505   Scatter2DPtr Analysis::bookScatter2D(const string& hname,
00506                                        bool copy_pts,
00507                                        const string& title,
00508                                        const string& xtitle,
00509                                        const string& ytitle) {
00510     Scatter2DPtr s;
00511     const string path = histoPath(hname);
00512     if (copy_pts) {
00513       const Scatter2D& refdata = refData(hname);
00514       s.reset( new Scatter2D(refdata, path) );
00515       foreach (Point2D& p, s->points()) p.setY(0, 0);
00516     } else {
00517       s.reset( new Scatter2D(path) );
00518     }
00519     addAnalysisObject(s);
00520     MSG_TRACE("Made scatter " << hname <<  " for " << name());
00521     s->setTitle(title);
00522     s->setAnnotation("XLabel", xtitle);
00523     s->setAnnotation("YLabel", ytitle);
00524     return s;
00525   }
00526 
00527 
00528   Scatter2DPtr Analysis::bookScatter2D(const string& hname,
00529                                        size_t npts, double lower, double upper,
00530                                        const string& title,
00531                                        const string& xtitle,
00532                                        const string& ytitle) {
00533     const string path = histoPath(hname);
00534     Scatter2DPtr s( new Scatter2D(path) );
00535     const double binwidth = (upper-lower)/npts;
00536     for (size_t pt = 0; pt < npts; ++pt) {
00537       const double bincentre = lower + (pt + 0.5) * binwidth;
00538       s->addPoint(bincentre, 0, binwidth/2.0, 0);
00539     }
00540     addAnalysisObject(s);
00541     MSG_TRACE("Made scatter " << hname <<  " for " << name());
00542     s->setTitle(title);
00543     s->setAnnotation("XLabel", xtitle);
00544     s->setAnnotation("YLabel", ytitle);
00545     return s;
00546   }
00547 
00548 
00549   Scatter2DPtr Analysis::bookScatter2D(const string& hname,
00550                                        const vector<double>& binedges,
00551                                        const string& title,
00552                                        const string& xtitle,
00553                                        const string& ytitle) {
00554     const string path = histoPath(hname);
00555     Scatter2DPtr s( new Scatter2D(path) );
00556     for (size_t pt = 0; pt < binedges.size()-1; ++pt) {
00557       const double bincentre = (binedges[pt] + binedges[pt+1]) / 2.0;
00558       const double binwidth = binedges[pt+1] - binedges[pt];
00559       s->addPoint(bincentre, 0, binwidth/2.0, 0);
00560     }
00561     addAnalysisObject(s);
00562     MSG_TRACE("Made scatter " << hname <<  " for " << name());
00563     s->setTitle(title);
00564     s->setAnnotation("XLabel", xtitle);
00565     s->setAnnotation("YLabel", ytitle);
00566     return s;
00567   }
00568 
00569 
00570   /////////////////////
00571 
00572 
00573   void Analysis::divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const {
00574     // preserve the path info
00575     const string path = s->path();
00576     *s = *h1 / *h2;
00577     s->setPath(path);
00578   }
00579 
00580   void Analysis::divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const {
00581     // preserve the path info
00582     const string path = s->path();
00583     *s = *p1 / *p2;
00584     s->setPath(path);
00585   }
00586 
00587   void Analysis::divide(const Histo1D& h1, const Histo1D& h2, Scatter2DPtr s) const {
00588     // preserve the path info
00589     const string path = s->path();
00590     *s = h1 / h2;
00591     s->setPath(path);
00592   }
00593 
00594   void Analysis::divide(const Profile1D& p1, const Profile1D& p2, Scatter2DPtr s) const {
00595     // preserve the path info
00596     const string path = s->path();
00597     *s = p1 / p2;
00598     s->setPath(path);
00599   }
00600 
00601   void Analysis::normalize(Histo1DPtr histo, double norm, bool includeoverflows) {
00602     if (!histo) {
00603       MSG_ERROR("Failed to normalize histo=NULL in analysis " << name() << " (norm=" << norm << ")");
00604       return;
00605     }
00606     MSG_TRACE("Normalizing histo " << histo->path() << " to " << norm);
00607     try {
00608       histo->normalize(norm, includeoverflows);
00609     } catch (YODA::Exception& we) {
00610       MSG_WARNING("Could not normalize histo " << histo->path());
00611       return;
00612     }
00613   }
00614 
00615 
00616   void Analysis::scale(Histo1DPtr histo, double scale) {
00617     if (!histo) {
00618       MSG_ERROR("Failed to scale histo=NULL in analysis " << name() << " (scale=" << scale << ")");
00619       return;
00620     }
00621     if (std::isnan(scale) || std::isinf(scale)) {
00622       MSG_ERROR("Failed to scale histo=" << histo->path() << " in analysis: " << name() << " (invalid scale factor = " << scale << ")");
00623       scale = 0;
00624     }
00625     MSG_TRACE("Scaling histo " << histo->path() << " by factor " << scale);
00626     try {
00627       histo->scaleW(scale);
00628     } catch (YODA::Exception& we) {
00629       MSG_WARNING("Could not scale histo " << histo->path());
00630       return;
00631     }
00632     // // Transforming the histo into a scatter after scaling
00633     // vector<double> x, y, ex, ey;
00634     // for (size_t i = 0, N = histo->numBins(); i < N; ++i) {
00635     //   x.push_back( histo->bin(i).midpoint() );
00636     //   ex.push_back(histo->bin(i).width()*0.5);
00637     //   y.push_back(histo->bin(i).height()*scale);
00638     //   ey.push_back(histo->bin(i).heightErr()*scale);
00639     // }
00640     // string title = histo->title();
00641     // Scatter2DPtr dps( new Scatter2D(x, y, ex, ey, hpath, title) );
00642     // addAnalysisObject(dps);
00643   }
00644 
00645 
00646   /// @todo 2D versions of scale and normalize...
00647 
00648 
00649   void Analysis::integrate(Histo1DPtr h, Scatter2DPtr s) const {
00650     // preserve the path info
00651     const string path = s->path();
00652     *s = toIntegralHisto(*h);
00653     s->setPath(path);
00654   }
00655 
00656   void Analysis::integrate(const Histo1D& h, Scatter2DPtr s) const {
00657     // preserve the path info
00658     const string path = s->path();
00659     *s = toIntegralHisto(h);
00660     s->setPath(path);
00661   }
00662 
00663 
00664   /// @todo 2D versions of integrate... defined how, exactly?!?
00665 
00666 
00667   //////////////////////////////////
00668 
00669 
00670   void Analysis::addAnalysisObject(AnalysisObjectPtr ao) {
00671     _analysisobjects.push_back(ao);
00672   }
00673 
00674   void Analysis::removeAnalysisObject(const string& path) {
00675     for (vector<AnalysisObjectPtr>::iterator it = _analysisobjects.begin();  it != _analysisobjects.end(); ++it) {
00676       if ((*it)->path() == path) {
00677         _analysisobjects.erase(it);
00678         break;
00679       }
00680     }
00681   }
00682 
00683   void Analysis::removeAnalysisObject(AnalysisObjectPtr ao) {
00684     for (vector<AnalysisObjectPtr>::iterator it = _analysisobjects.begin();  it != _analysisobjects.end(); ++it) {
00685       if (*it == ao) {
00686         _analysisobjects.erase(it);
00687         break;
00688       }
00689     }
00690  }
00691 
00692 
00693 }