Analysis.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Rivet.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.pdgId(), beams.second.pdgId(), 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 /// @todo Use some sort of standard ordering to improve comparisons, esp. when the two beams are different particles 00127 bool beamEnergiesOk = requiredEnergies().size() > 0 ? false : true; 00128 typedef pair<double,double> DoublePair; 00129 foreach (const DoublePair& ep, requiredEnergies()) { 00130 if ((fuzzyEquals(ep.first, energies.first, 0.01) && fuzzyEquals(ep.second, energies.second, 0.01)) || 00131 (fuzzyEquals(ep.first, energies.second, 0.01) && fuzzyEquals(ep.second, energies.first, 0.01)) || 00132 ((ep.first - energies.first) < 1*GeV && (ep.second - energies.second) < 1*GeV) || 00133 ((ep.first - energies.second) < 1*GeV && (ep.second - energies.first) < 1*GeV)) { 00134 beamEnergiesOk = true; 00135 break; 00136 } 00137 } 00138 return beamEnergiesOk; 00139 00140 /// @todo Need to also check internal consistency of the analysis' 00141 /// beam requirements with those of the projections it uses. 00142 } 00143 00144 00145 /////////////////////////////////////////// 00146 00147 00148 Analysis& Analysis::setCrossSection(double xs) { 00149 _crossSection = xs; 00150 _gotCrossSection = true; 00151 return *this; 00152 } 00153 00154 double Analysis::crossSection() const { 00155 if (!_gotCrossSection || std::isnan(_crossSection)) { 00156 string errMsg = "You did not set the cross section for the analysis " + name(); 00157 throw Error(errMsg); 00158 } 00159 return _crossSection; 00160 } 00161 00162 double Analysis::crossSectionPerEvent() const { 00163 const double sumW = sumOfWeights(); 00164 assert(sumW != 0.0); 00165 return _crossSection / sumW; 00166 } 00167 00168 00169 00170 //////////////////////////////////////////////////////////// 00171 // Histogramming 00172 00173 00174 void Analysis::_cacheRefData() const { 00175 if (_refdata.empty()) { 00176 MSG_TRACE("Getting refdata cache for paper " << name()); 00177 _refdata = getRefData(name()); 00178 } 00179 } 00180 00181 00182 const Scatter2D& Analysis::refData(const string& hname) const { 00183 _cacheRefData(); 00184 MSG_TRACE("Using histo bin edges for " << name() << ":" << hname); 00185 if (!_refdata[hname]) { 00186 MSG_ERROR("Can't find reference histogram " << hname); 00187 } 00188 return *_refdata[hname]; 00189 } 00190 00191 00192 const Scatter2D& Analysis::refData(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId) const { 00193 const string hname = makeAxisCode(datasetId, xAxisId, yAxisId); 00194 return refData(hname); 00195 } 00196 00197 00198 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00199 size_t nbins, double lower, double upper, 00200 const string& title, 00201 const string& xtitle, 00202 const string& ytitle) { 00203 const string path = histoPath(hname); 00204 Histo1DPtr hist( new Histo1D(nbins, lower, upper, path, title) ); 00205 addAnalysisObject(hist); 00206 MSG_TRACE("Made histogram " << hname << " for " << name()); 00207 hist->setAnnotation("XLabel", xtitle); 00208 hist->setAnnotation("YLabel", ytitle); 00209 return hist; 00210 } 00211 00212 00213 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00214 const vector<double>& binedges, 00215 const string& title, 00216 const string& xtitle, 00217 const string& ytitle) { 00218 const string path = histoPath(hname); 00219 Histo1DPtr hist( new Histo1D(binedges, path, title) ); 00220 addAnalysisObject(hist); 00221 MSG_TRACE("Made histogram " << hname << " for " << name()); 00222 hist->setAnnotation("XLabel", xtitle); 00223 hist->setAnnotation("YLabel", ytitle); 00224 return hist; 00225 } 00226 00227 00228 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00229 const Scatter2D& refscatter, 00230 const string& title, 00231 const string& xtitle, 00232 const string& ytitle) { 00233 const string path = histoPath(hname); 00234 Histo1DPtr hist( new Histo1D(refscatter, path) ); 00235 addAnalysisObject(hist); 00236 MSG_TRACE("Made histogram " << hname << " for " << name()); 00237 hist->setTitle(title); 00238 hist->setAnnotation("XLabel", xtitle); 00239 hist->setAnnotation("YLabel", ytitle); 00240 return hist; 00241 } 00242 00243 00244 Histo1DPtr Analysis::bookHisto1D(const string& hname, 00245 const string& title, 00246 const string& xtitle, 00247 const string& ytitle) { 00248 const Scatter2D& refdata = refData(hname); 00249 return bookHisto1D(hname, refdata, title, xtitle, ytitle); 00250 } 00251 00252 00253 Histo1DPtr Analysis::bookHisto1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00254 const string& title, 00255 const string& xtitle, 00256 const string& ytitle) { 00257 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00258 return bookHisto1D(axisCode, title, xtitle, ytitle); 00259 } 00260 00261 00262 /// @todo Add booking methods which take a path, titles and *a reference Scatter from which to book* 00263 00264 00265 ///////////////// 00266 00267 00268 // Histo2DPtr Analysis::bookHisto2D(const string& hname, 00269 // size_t nxbins, double xlower, double xupper, 00270 // size_t nybins, double ylower, double yupper, 00271 // const string& title, 00272 // const string& xtitle, 00273 // const string& ytitle, 00274 // const string& ztitle) 00275 // { 00276 // const string path = histoPath(hname); 00277 // Histo2DPtr hist( new Histo2D(path, nxbins, xlower, xupper, nybins, ylower, yupper) ); 00278 // addAnalysisObject(hist); 00279 // MSG_TRACE("Made histogram " << hname << " for " << name()); 00280 // hist->setTitle(title); 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(path, xbinedges, ybinedges) ); 00298 // addAnalysisObject(hist); 00299 // MSG_TRACE("Made histogram " << hname << " for " << name()); 00300 // hist->setTitle(title); 00301 // hist->setAnnotation("XLabel", xtitle); 00302 // hist->setAnnotation("YLabel", ytitle); 00303 // hist->setAnnotation("ZLabel", ztitle); 00304 // return hist; 00305 // } 00306 00307 00308 // Histo2DPtr Analysis::bookHisto2D(const string& hname, 00309 // const Scatter3D& refscatter, 00310 // const string& title="", 00311 // const string& xtitle="", 00312 // const string& ytitle="", 00313 // const string& ztitle="") { 00314 // const string path = histoPath(hname); 00315 // Histo2DPtr hist( new Histo2D(refscatter, path) ); 00316 // addAnalysisObject(hist); 00317 // MSG_TRACE("Made histogram " << hname << " for " << name()); 00318 // hist->setTitle(title); 00319 // hist->setAnnotation("XLabel", xtitle); 00320 // hist->setAnnotation("YLabel", ytitle); 00321 // hist->setAnnotation("ZLabel", ztitle); 00322 // return hist; 00323 // } 00324 00325 00326 // Histo2DPtr Analysis::bookHisto2D(const string& hname, 00327 // const string& title, 00328 // const string& xtitle, 00329 // const string& ytitle, 00330 // const string& ztitle) { 00331 // const Scatter3D& refdata = refData(hname); 00332 // return bookHisto2D(hname, refdata, title, xtitle, ytitle, ztitle); 00333 // } 00334 00335 00336 // Histo2DPtr Analysis::bookHisto2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00337 // const string& title, 00338 // const string& xtitle, 00339 // const string& ytitle, 00340 // const string& ztitle) { 00341 // const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00342 // return bookHisto2D(axisCode, title, xtitle, ytitle, ztitle); 00343 // } 00344 00345 00346 ///////////////// 00347 00348 00349 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00350 size_t nbins, double lower, double upper, 00351 const string& title, 00352 const string& xtitle, 00353 const string& ytitle) { 00354 const string path = histoPath(hname); 00355 Profile1DPtr prof( new Profile1D(nbins, lower, upper, path, title) ); 00356 addAnalysisObject(prof); 00357 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00358 prof->setAnnotation("XLabel", xtitle); 00359 prof->setAnnotation("YLabel", ytitle); 00360 return prof; 00361 } 00362 00363 00364 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00365 const vector<double>& binedges, 00366 const string& title, 00367 const string& xtitle, 00368 const string& ytitle) { 00369 const string path = histoPath(hname); 00370 Profile1DPtr prof( new Profile1D(binedges, path, title) ); 00371 addAnalysisObject(prof); 00372 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00373 prof->setAnnotation("XLabel", xtitle); 00374 prof->setAnnotation("YLabel", ytitle); 00375 return prof; 00376 } 00377 00378 00379 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00380 const Scatter2D& refscatter, 00381 const string& title, 00382 const string& xtitle, 00383 const string& ytitle) { 00384 const string path = histoPath(hname); 00385 Profile1DPtr prof( new Profile1D(refscatter, path) ); 00386 addAnalysisObject(prof); 00387 MSG_TRACE("Made profile histogram " << hname << " for " << name()); 00388 prof->setTitle(title); 00389 prof->setAnnotation("XLabel", xtitle); 00390 prof->setAnnotation("YLabel", ytitle); 00391 return prof; 00392 } 00393 00394 00395 Profile1DPtr Analysis::bookProfile1D(const string& hname, 00396 const string& title, 00397 const string& xtitle, 00398 const string& ytitle) { 00399 const Scatter2D& refdata = refData(hname); 00400 return bookProfile1D(hname, refdata, title, xtitle, ytitle); 00401 } 00402 00403 00404 Profile1DPtr Analysis::bookProfile1D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00405 const string& title, 00406 const string& xtitle, 00407 const string& ytitle) { 00408 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00409 return bookProfile1D(axisCode, title, xtitle, ytitle); 00410 } 00411 00412 00413 /////////////////// 00414 00415 00416 Scatter2DPtr Analysis::bookScatter2D(unsigned int datasetId, unsigned int xAxisId, unsigned int yAxisId, 00417 bool copy_pts, 00418 const string& title, 00419 const string& xtitle, 00420 const string& ytitle) { 00421 const string axisCode = makeAxisCode(datasetId, xAxisId, yAxisId); 00422 return bookScatter2D(axisCode, copy_pts, title, xtitle, ytitle); 00423 } 00424 00425 00426 Scatter2DPtr Analysis::bookScatter2D(const string& hname, 00427 bool copy_pts, 00428 const string& title, 00429 const string& xtitle, 00430 const string& ytitle) { 00431 Scatter2DPtr s; 00432 const string path = histoPath(hname); 00433 if (copy_pts) { 00434 const Scatter2D& refdata = refData(hname); 00435 s.reset( new Scatter2D(refdata, path) ); 00436 foreach (Point2D& p, s->points()) p.setY(0, 0); 00437 } else { 00438 s.reset( new Scatter2D(path) ); 00439 } 00440 addAnalysisObject(s); 00441 MSG_TRACE("Made scatter " << hname << " for " << name()); 00442 s->setTitle(title); 00443 s->setAnnotation("XLabel", xtitle); 00444 s->setAnnotation("YLabel", ytitle); 00445 return s; 00446 } 00447 00448 00449 Scatter2DPtr Analysis::bookScatter2D(const string& hname, 00450 size_t npts, double lower, double upper, 00451 const string& title, 00452 const string& xtitle, 00453 const string& ytitle) { 00454 const string path = histoPath(hname); 00455 Scatter2DPtr s( new Scatter2D(path) ); 00456 const double binwidth = (upper-lower)/npts; 00457 for (size_t pt = 0; pt < npts; ++pt) { 00458 const double bincentre = lower + (pt + 0.5) * binwidth; 00459 s->addPoint(bincentre, 0, binwidth/2.0, 0); 00460 } 00461 addAnalysisObject(s); 00462 MSG_TRACE("Made scatter " << hname << " for " << name()); 00463 s->setTitle(title); 00464 s->setAnnotation("XLabel", xtitle); 00465 s->setAnnotation("YLabel", ytitle); 00466 return s; 00467 } 00468 00469 00470 Scatter2DPtr Analysis::bookScatter2D(const string& hname, 00471 const vector<double>& binedges, 00472 const string& title, 00473 const string& xtitle, 00474 const string& ytitle) { 00475 const string path = histoPath(hname); 00476 Scatter2DPtr s( new Scatter2D(path) ); 00477 for (size_t pt = 0; pt < binedges.size()-1; ++pt) { 00478 const double bincentre = (binedges[pt] + binedges[pt+1]) / 2.0; 00479 const double binwidth = binedges[pt+1] - binedges[pt]; 00480 s->addPoint(bincentre, 0, binwidth/2.0, 0); 00481 } 00482 addAnalysisObject(s); 00483 MSG_TRACE("Made scatter " << hname << " for " << name()); 00484 s->setTitle(title); 00485 s->setAnnotation("XLabel", xtitle); 00486 s->setAnnotation("YLabel", ytitle); 00487 return s; 00488 } 00489 00490 00491 ///////////////////// 00492 00493 00494 void Analysis::divide(Histo1DPtr h1, Histo1DPtr h2, Scatter2DPtr s) const { 00495 // preserve the path info 00496 const string path = s->path(); 00497 *s = *h1 / *h2; 00498 s->setPath(path); 00499 } 00500 00501 void Analysis::divide(Profile1DPtr p1, Profile1DPtr p2, Scatter2DPtr s) const { 00502 // preserve the path info 00503 const string path = s->path(); 00504 *s = *p1 / *p2; 00505 s->setPath(path); 00506 } 00507 00508 void Analysis::divide(const Histo1D& h1, const Histo1D& h2, Scatter2DPtr s) const { 00509 // preserve the path info 00510 const string path = s->path(); 00511 *s = h1 / h2; 00512 s->setPath(path); 00513 } 00514 00515 void Analysis::divide(const Profile1D& p1, const Profile1D& p2, Scatter2DPtr s) const { 00516 // preserve the path info 00517 const string path = s->path(); 00518 *s = p1 / p2; 00519 s->setPath(path); 00520 } 00521 00522 void Analysis::normalize(Histo1DPtr histo, double norm, bool includeoverflows) { 00523 if (!histo) { 00524 MSG_ERROR("Failed to normalize histo=NULL in analysis " << name() << " (norm=" << norm << ")"); 00525 return; 00526 } 00527 MSG_TRACE("Normalizing histo " << histo->path() << " to " << norm); 00528 try { 00529 histo->normalize(norm, includeoverflows); 00530 } catch (YODA::Exception& we) { 00531 MSG_WARNING("Could not normalize histo " << histo->path()); 00532 return; 00533 } 00534 } 00535 00536 00537 void Analysis::scale(Histo1DPtr histo, double scale) { 00538 if (!histo) { 00539 MSG_ERROR("Failed to scale histo=NULL in analysis " << name() << " (scale=" << scale << ")"); 00540 return; 00541 } 00542 if (std::isnan(scale) || std::isinf(scale)) { 00543 MSG_ERROR("Failed to scale histo=" << histo->path() << " in analysis: " << name() << " (invalid scale factor = " << scale << ")"); 00544 scale = 0; 00545 } 00546 MSG_TRACE("Scaling histo " << histo->path() << " by factor " << scale); 00547 try { 00548 histo->scaleW(scale); 00549 } catch (YODA::Exception& we) { 00550 MSG_WARNING("Could not scale histo " << histo->path()); 00551 return; 00552 } 00553 // // Transforming the histo into a scatter after scaling 00554 // vector<double> x, y, ex, ey; 00555 // for (size_t i = 0, N = histo->numBins(); i < N; ++i) { 00556 // x.push_back( histo->bin(i).midpoint() ); 00557 // ex.push_back(histo->bin(i).width()*0.5); 00558 // y.push_back(histo->bin(i).height()*scale); 00559 // ey.push_back(histo->bin(i).heightErr()*scale); 00560 // } 00561 // string title = histo->title(); 00562 // Scatter2DPtr dps( new Scatter2D(x, y, ex, ey, hpath, title) ); 00563 // addAnalysisObject(dps); 00564 } 00565 00566 00567 /// @todo 2D versions of scale and normalize... 00568 00569 00570 void Analysis::integrate(Histo1DPtr h, Scatter2DPtr s) const { 00571 // preserve the path info 00572 const string path = s->path(); 00573 *s = toIntegralHisto(*h); 00574 s->setPath(path); 00575 } 00576 00577 void Analysis::integrate(const Histo1D& h, Scatter2DPtr s) const { 00578 // preserve the path info 00579 const string path = s->path(); 00580 *s = toIntegralHisto(h); 00581 s->setPath(path); 00582 } 00583 00584 00585 /// @todo 2D versions of integrate... defined how, exactly?!? 00586 00587 00588 ////////////////////////////////// 00589 00590 00591 void Analysis::addAnalysisObject(AnalysisObjectPtr ao) { 00592 _analysisobjects.push_back(ao); 00593 } 00594 00595 void Analysis::removeAnalysisObject(const string& path) { 00596 for (vector<AnalysisObjectPtr>::iterator it = _analysisobjects.begin(); it != _analysisobjects.end(); ++it) { 00597 if ((*it)->path() == path) { 00598 _analysisobjects.erase(it); 00599 break; 00600 } 00601 } 00602 } 00603 00604 void Analysis::removeAnalysisObject(AnalysisObjectPtr ao) { 00605 for (vector<AnalysisObjectPtr>::iterator it = _analysisobjects.begin(); it != _analysisobjects.end(); ++it) { 00606 if (*it == ao) { 00607 _analysisobjects.erase(it); 00608 break; 00609 } 00610 } 00611 } 00612 00613 00614 } Generated on Fri Oct 25 2013 12:41:43 for The Rivet MC analysis system by ![]() |