Analysis.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Rivet.hh" 00003 #include "Rivet/RivetYODA.hh" 00004 #include "Rivet/AnalysisHandler.hh" 00005 #include "Rivet/AnalysisInfo.hh" 00006 #include "Rivet/Analysis.hh" 00007 #include "Rivet/Tools/Logging.hh" 00008 00009 namespace Rivet { 00010 Analysis::Analysis(const string& name) 00011 : _crossSection(-1.0), 00012 _gotCrossSection(false), 00013 _analysishandler(NULL) 00014 { 00015 ProjectionApplier::_allowProjReg = false; 00016 _defaultname = name; 00017 00018 AnalysisInfo* ai = AnalysisInfo::make(name); 00019 assert(ai != 0); 00020 _info.reset(ai); 00021 assert(_info.get() != 0); 00022 } 00023 00024 double Analysis::sqrtS() const { 00025 return handler().sqrtS(); 00026 } 00027 00028 const ParticlePair& Analysis::beams() const { 00029 return handler().beams(); 00030 } 00031 00032 const PdgIdPair Analysis::beamIds() const { 00033 return handler().beamIds(); 00034 } 00035 00036 00037 const string Analysis::histoDir() const { 00038 /// @todo This doesn't change: calc and cache at first use! 00039 string path = "/" + name(); 00040 if (handler().runName().length() > 0) { 00041 path = "/" + handler().runName() + path; 00042 } 00043 while (find_first(path, "//")) { 00044 replace_all(path, "//", "/"); 00045 } 00046 return path; 00047 } 00048 00049 00050 const string Analysis::histoPath(const string& hname) const { 00051 const string path = histoDir() + "/" + hname; 00052 return path; 00053 } 00054 00055 00056 const string Analysis::histoPath(size_t datasetId, size_t xAxisId, size_t yAxisId) const { 00057 return histoDir() + "/" + makeAxisCode(datasetId, xAxisId, yAxisId); 00058 } 00059 00060 00061 const string Analysis::makeAxisCode(size_t datasetId, size_t xAxisId, size_t yAxisId) const { 00062 stringstream axisCode; 00063 axisCode << "d"; 00064 if (datasetId < 10) axisCode << 0; 00065 axisCode << datasetId; 00066 axisCode << "-x"; 00067 if (xAxisId < 10) axisCode << 0; 00068 axisCode << xAxisId; 00069 axisCode << "-y"; 00070 if (yAxisId < 10) axisCode << 0; 00071 axisCode << yAxisId; 00072 return axisCode.str(); 00073 } 00074 00075 00076 Log& Analysis::getLog() const { 00077 string logname = "Rivet.Analysis." + name(); 00078 return Log::getLog(logname); 00079 } 00080 00081 00082 size_t Analysis::numEvents() const { 00083 return handler().numEvents(); 00084 } 00085 00086 00087 double Analysis::sumOfWeights() const { 00088 return handler().sumOfWeights(); 00089 } 00090 00091 00092 /////////////////////////////////////////// 00093 00094 00095 bool Analysis::isCompatible(const ParticlePair& beams) const { 00096 return isCompatible(beams.first.pdgId(), beams.second.pdgId(), 00097 beams.first.energy(), beams.second.energy()); 00098 } 00099 00100 00101 bool Analysis::isCompatible(PdgId beam1, PdgId beam2, double e1, double e2) const { 00102 PdgIdPair beams(beam1, beam2); 00103 pair<double,double> energies(e1, e2); 00104 return isCompatible(beams, energies); 00105 } 00106 00107 00108 bool Analysis::isCompatible(const PdgIdPair& beams, const pair<double,double>& energies) const { 00109 // First check the beam IDs 00110 bool beamIdsOk = false; 00111 foreach (const PdgIdPair& bp, requiredBeams()) { 00112 if (compatible(beams, bp)) { 00113 beamIdsOk = true; 00114 break; 00115 } 00116 } 00117 if (!beamIdsOk) return false; 00118 00119 // Next check that the energies are compatible (within 1%, to give a bit of UI forgiveness) 00120 bool beamEnergiesOk = requiredEnergies().size()>0 ? false : true; 00121 typedef pair<double,double> DoublePair; 00122 foreach (const DoublePair& ep, requiredEnergies()) { 00123 if ((fuzzyEquals(ep.first, energies.first, 0.01) && fuzzyEquals(ep.second, energies.second, 0.01)) || 00124 (fuzzyEquals(ep.first, energies.second, 0.01) && fuzzyEquals(ep.second, energies.first, 0.01))) { 00125 beamEnergiesOk = true; 00126 break; 00127 } 00128 } 00129 return beamEnergiesOk; 00130 00131 /// @todo Need to also check internal consistency of the analysis' 00132 /// beam requirements with those of the projections it uses. 00133 } 00134 00135 00136 /////////////////////////////////////////// 00137 00138 00139 Analysis& Analysis::setCrossSection(double xs) { 00140 _crossSection = xs; 00141 _gotCrossSection = true; 00142 return *this; 00143 } 00144 00145 double Analysis::crossSection() const { 00146 if (!_gotCrossSection || std::isnan(_crossSection)) { 00147 string errMsg = "You did not set the cross section for the analysis " + name(); 00148 throw Error(errMsg); 00149 } 00150 return _crossSection; 00151 } 00152 00153 double Analysis::crossSectionPerEvent() const { 00154 const double sumW = sumOfWeights(); 00155 assert(sumW != 0.0); 00156 return _crossSection / sumW; 00157 } 00158 00159 00160 00161 //////////////////////////////////////////////////////////// 00162 // Histogramming 00163 00164 00165 void Analysis::_cacheRefData() const { 00166 if (_refdata.empty()) { 00167 MSG_TRACE("Getting refdata cache for paper " << name()); 00168 _refdata = getRefData(name()); 00169 } 00170 } 00171 00172 00173 const Scatter2D & Analysis::referenceData(const string& hname) const { 00174 _cacheRefData(); 00175 MSG_TRACE("Using histo bin edges for " << name() << ":" << hname); 00176 if (!_refdata[hname]) { 00177 MSG_ERROR("Can't find reference histogram " << hname); 00178 } 00179 return *_refdata[hname]; 00180 } 00181 00182 00183 const Scatter2D & Analysis::referenceData(size_t datasetId, size_t xAxisId, size_t yAxisId) const { 00184 const string hname = makeAxisCode(datasetId, xAxisId, yAxisId); 00185 return referenceData(hname); 00186 } 00187 00188 00189 Histo1DPtr Analysis::bookHisto1D(size_t datasetId, size_t xAxisId, 00190 size_t yAxisId, const string& title, 00191 const string& xtitle, const string& ytitle) 00192 { 00193 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00194 return bookHisto1D(axisCode, title, xtitle, ytitle); 00195 } 00196 00197 00198 Histo1DPtr Analysis::bookHisto1D(const string& hname, const string& title, 00199 const string& xtitle, const string& ytitle) 00200 { 00201 const Scatter2D & refdata = referenceData(hname); 00202 const string path = histoPath(hname); 00203 Histo1DPtr hist( new Histo1D(refdata, path) ); 00204 addPlot(hist); 00205 MSG_TRACE("Made histogram " << hname << " for " << name()); 00206 hist->setTitle(title); 00207 hist->setAnnotation("XLabel", xtitle); 00208 hist->setAnnotation("YLabel", ytitle); 00209 return hist; 00210 } 00211 00212 00213 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00214 size_t nbins, double lower, double upper, 00215 const string& title, 00216 const string& xtitle, const string& ytitle) { 00217 const string path = histoPath(hname); 00218 Histo1DPtr hist( new Histo1D(nbins, lower, upper, path, title) ); 00219 addPlot(hist); 00220 MSG_TRACE("Made histogram " << hname << " for " << name()); 00221 hist->setAnnotation("XLabel", xtitle); 00222 hist->setAnnotation("YLabel", ytitle); 00223 return hist; 00224 } 00225 00226 00227 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00228 const vector<double>& binedges, 00229 const string& title, 00230 const string& xtitle, 00231 const string& ytitle) { 00232 const string path = histoPath(hname); 00233 Histo1DPtr hist( new Histo1D(binedges, path, title) ); 00234 addPlot(hist); 00235 MSG_TRACE("Made histogram " << hname << " for " << name()); 00236 hist->setAnnotation("XLabel", xtitle); 00237 hist->setAnnotation("YLabel", ytitle); 00238 return hist; 00239 } 00240 00241 // IHistogram2D* 00242 // Analysis::bookHistogram2D(const string& hname, 00243 // size_t nxbins, double xlower, double xupper, 00244 // size_t nybins, double ylower, double yupper, 00245 // const string& title, const string& xtitle, 00246 // const string& ytitle, const string& ztitle) { 00247 // _makeHistoDir(); 00248 // const string path = histoPath(hname); 00249 // IHistogram2D* hist = 00250 // histogramFactory().createHistogram2D(path, title, nxbins, xlower, xupper, 00251 // nybins, ylower, yupper); 00252 // MSG_TRACE("Made 2D histogram " << hname << " for " << name()); 00253 // hist->setXTitle(xtitle); 00254 // hist->setYTitle(ytitle); 00255 // hist->setZTitle(ztitle); 00256 // return hist; 00257 // } 00258 00259 00260 // IHistogram2D* 00261 // Analysis::bookHistogram2D(const string& hname, 00262 // const vector<double>& xbinedges, 00263 // const vector<double>& ybinedges, 00264 // const string& title, const string& xtitle, 00265 // const string& ytitle, const string& ztitle) { 00266 // _makeHistoDir(); 00267 // const string path = histoPath(hname); 00268 // IHistogram2D* hist = 00269 // histogramFactory().createHistogram2D(path, title, xbinedges, ybinedges); 00270 // MSG_TRACE("Made 2D histogram " << hname << " for " << name()); 00271 // hist->setXTitle(xtitle); 00272 // hist->setYTitle(ytitle); 00273 // hist->setZTitle(ztitle); 00274 // return hist; 00275 // } 00276 00277 00278 ///////////////// 00279 00280 00281 Profile1DPtr Analysis::bookProfile1D(size_t datasetId, size_t xAxisId, 00282 size_t yAxisId, const string& title, 00283 const string& xtitle, const string& ytitle) { 00284 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00285 return bookProfile1D(axisCode, title, xtitle, ytitle); 00286 } 00287 00288 00289 Profile1DPtr Analysis::bookProfile1D(const string& hname, const string& title, 00290 const string& xtitle, const string& ytitle) 00291 { 00292 const Scatter2D & refdata = referenceData(hname); 00293 const string path = histoPath(hname); 00294 Profile1DPtr prof( new Profile1D(refdata, path) ); 00295 addPlot(prof); 00296 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00297 prof->setTitle(title); 00298 prof->setAnnotation("XLabel", xtitle); 00299 prof->setAnnotation("YLabel", ytitle); 00300 return prof; 00301 } 00302 00303 00304 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00305 size_t nbins, double lower, double upper, 00306 const string& title, 00307 const string& xtitle, const string& ytitle) { 00308 const string path = histoPath(hname); 00309 Profile1DPtr prof( new Profile1D(nbins, lower, upper, path, title) ); 00310 addPlot(prof); 00311 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00312 prof->setAnnotation("XLabel", xtitle); 00313 prof->setAnnotation("YLabel", ytitle); 00314 return prof; 00315 } 00316 00317 00318 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00319 const vector<double>& binedges, 00320 const string& title, 00321 const string& xtitle, const string& ytitle) { 00322 const string path = histoPath(hname); 00323 Profile1DPtr prof( new Profile1D(binedges, path, title) ); 00324 addPlot(prof); 00325 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00326 prof->setAnnotation("XLabel", xtitle); 00327 prof->setAnnotation("YLabel", ytitle); 00328 return prof; 00329 } 00330 00331 00332 /////////////////// 00333 00334 00335 Scatter2DPtr Analysis::bookScatter2D(size_t datasetId, size_t xAxisId, 00336 size_t yAxisId, const string& title, 00337 const string& xtitle, const string& ytitle) { 00338 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00339 return bookScatter2D(axisCode, title, xtitle, ytitle); 00340 } 00341 00342 00343 Scatter2DPtr Analysis::bookScatter2D(const string& hname, const string& title, 00344 const string& xtitle, const string& ytitle) { 00345 const string path = histoPath(hname); 00346 Scatter2DPtr dps( new Scatter2D(path, title) ); 00347 addPlot(dps); 00348 MSG_TRACE("Made data point set " << hname << " for " << name()); 00349 dps->setAnnotation("XLabel", xtitle); 00350 dps->setAnnotation("YLabel", ytitle); 00351 return dps; 00352 } 00353 00354 00355 Scatter2DPtr Analysis::bookScatter2D(const string& hname, 00356 size_t npts, double lower, double upper, 00357 const string& title, 00358 const string& xtitle, const string& ytitle) { 00359 Scatter2DPtr dps = bookScatter2D(hname, title, xtitle, ytitle); 00360 const double binwidth = (upper-lower)/npts; 00361 for (size_t pt = 0; pt < npts; ++pt) { 00362 const double bincentre = lower + (pt + 0.5) * binwidth; 00363 // @todo YODA check 00364 dps->addPoint(bincentre, 0, binwidth/2.0, 0); 00365 // IMeasurement* meas = dps->point(pt)->coordinate(0); 00366 // meas->setValue(bincentre); 00367 // meas->setErrorPlus(binwidth/2.0); 00368 // meas->setErrorMinus(binwidth/2.0); 00369 } 00370 return dps; 00371 } 00372 00373 // @todo YODA 00374 // Scatter2DPtr Analysis::bookScatter2D(size_t datasetId, size_t xAxisId, 00375 // size_t yAxisId, const string& title, 00376 // const string& xtitle, const string& ytitle) { 00377 // // Get the bin edges (only read the AIDA file once) 00378 // _cacheXAxisData(); 00379 // // Build the axis code 00380 // const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00381 // //const map<string, vector<DPSXPoint> > xpoints = getDPSXValsErrs(papername); 00382 // MSG_TRACE("Using DPS x-positions for " << name() << ":" << axisCode); 00383 // Scatter2DPtr dps = bookScatter2D(axisCode, title, xtitle, ytitle); 00384 // const vector<Point2D> xpts = _dpsData.find(axisCode)->second; 00385 // foreach ( const Point2D & pt, xpts ) { 00386 // // \todo YODA check 00387 // dps->addPoint(pt.x(), pt.xErrMinus(), pt.xErrPlus(), 0, 0, 0); 00388 // // dps->addPoint(xpts[pt].val, xpts[pt].errminus, xpts[pt].errplus, 0, 0, 0); 00389 // // IMeasurement* meas = dps->point(pt)->coordinate(0); 00390 // // meas->setValue(xpts[pt].val); 00391 // // meas->setErrorPlus(xpts[pt].errplus); 00392 // // meas->setErrorMinus(xpts[pt].errminus); 00393 // } 00394 // MSG_TRACE("Made DPS " << axisCode << " for " << name()); 00395 // return dps; 00396 // } 00397 00398 00399 void Analysis::divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const { 00400 // preserve the path info 00401 std::string path = s->path(); 00402 *s = *h1 / *h2; 00403 s->setPath( path ); 00404 } 00405 00406 void Analysis::divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const { 00407 // preserve the path info 00408 std::string path = s->path(); 00409 *s = *p1 / *p2; 00410 s->setPath( path ); 00411 } 00412 00413 void Analysis::divide(const Histo1D & h1, 00414 const Histo1D & h2, 00415 Scatter2DPtr s) const { 00416 // preserve the path info 00417 std::string path = s->path(); 00418 *s = h1 / h2; 00419 s->setPath( path ); 00420 } 00421 00422 void Analysis::divide(const Profile1D & p1, 00423 const Profile1D & p2, 00424 Scatter2DPtr s) const { 00425 // preserve the path info 00426 std::string path = s->path(); 00427 *s = p1 / p2; 00428 s->setPath( path ); 00429 } 00430 00431 void Analysis::normalize(Histo1DPtr histo, double norm, bool includeoverflows) { 00432 if (!histo) { 00433 MSG_ERROR("Failed to normalize histo=NULL in analysis " << name() << " (norm=" << norm << ")"); 00434 return; 00435 } 00436 MSG_TRACE("Normalizing histo " << histo->path() << " to " << norm); 00437 try { 00438 histo->normalize(norm, includeoverflows); 00439 } catch (YODA::WeightError& we) { 00440 MSG_WARNING("Could not normalize histo " << histo->path()); 00441 return; 00442 } 00443 } 00444 00445 00446 void Analysis::scale(Histo1DPtr histo, double scale) { 00447 if (!histo) { 00448 MSG_ERROR("Failed to scale histo=NULL in analysis " << name() << " (scale=" << scale << ")"); 00449 return; 00450 } 00451 MSG_TRACE("Scaling histo " << histo->path() << "by factor " << scale); 00452 try { 00453 histo->scaleW(scale); 00454 } catch (YODA::WeightError& we) { 00455 MSG_WARNING("Could not normalize histo " << histo->path()); 00456 return; 00457 } 00458 // // Transforming the histo into a scatter after scaling 00459 // vector<double> x, y, ex, ey; 00460 // for (size_t i = 0, N = histo->numBins(); i < N; ++i) { 00461 // x.push_back( histo->bin(i).midpoint() ); 00462 // ex.push_back(histo->bin(i).width()*0.5); 00463 // y.push_back(histo->bin(i).height()*scale); 00464 // ey.push_back(histo->bin(i).heightErr()*scale); 00465 // } 00466 // string title = histo->title(); 00467 // Scatter2DPtr dps( new Scatter2D(x, y, ex, ey, hpath, title) ); 00468 // addPlot(dps); 00469 } 00470 00471 00472 /// @todo 2D versions of scale and normalize... or ditch these completely? 00473 00474 00475 void Analysis::addPlot(AnalysisObjectPtr ao) { 00476 _plotobjects.push_back(ao); 00477 } 00478 00479 } Generated on Fri Dec 21 2012 15:03:38 for The Rivet MC analysis system by ![]() |