|
[Rivet-svn] r2122 - in trunk: . pyext src src/Coreblackhole at projects.hepforge.org blackhole at projects.hepforge.orgTue Dec 1 19:39:13 GMT 2009
Author: buckley Date: Tue Dec 1 19:39:13 2009 New Revision: 2122 Log: Moving core class implementation files into a subdir to allow for more selective rebuilds Added: trunk/src/Core/ trunk/src/Core/Analysis.cc - copied unchanged from r2121, trunk/src/Analysis.cc trunk/src/Core/AnalysisHandler.cc - copied unchanged from r2120, trunk/src/AnalysisHandler.cc trunk/src/Core/AnalysisInfo.cc - copied unchanged from r2121, trunk/src/AnalysisInfo.cc trunk/src/Core/AnalysisLoader.cc - copied unchanged from r2120, trunk/src/AnalysisLoader.cc trunk/src/Core/Cuts.cc - copied unchanged from r2120, trunk/src/Cuts.cc trunk/src/Core/Event.cc - copied unchanged from r2120, trunk/src/Event.cc trunk/src/Core/HistoHandler.cc - copied unchanged from r2120, trunk/src/HistoHandler.cc trunk/src/Core/Jet.cc - copied unchanged from r2120, trunk/src/Jet.cc trunk/src/Core/Makefile.am - copied, changed from r2121, trunk/src/Makefile.am trunk/src/Core/Particle.cc - copied unchanged from r2120, trunk/src/Particle.cc trunk/src/Core/Projection.cc - copied unchanged from r2120, trunk/src/Projection.cc trunk/src/Core/ProjectionApplier.cc - copied unchanged from r2120, trunk/src/ProjectionApplier.cc trunk/src/Core/ProjectionHandler.cc - copied unchanged from r2120, trunk/src/ProjectionHandler.cc trunk/src/Core/Run.cc - copied unchanged from r2120, trunk/src/Run.cc Deleted: trunk/src/Analysis.cc trunk/src/AnalysisHandler.cc trunk/src/AnalysisInfo.cc trunk/src/AnalysisLoader.cc trunk/src/Cuts.cc trunk/src/Event.cc trunk/src/HistoHandler.cc trunk/src/Jet.cc trunk/src/Particle.cc trunk/src/Projection.cc trunk/src/ProjectionApplier.cc trunk/src/ProjectionHandler.cc trunk/src/Run.cc Modified: trunk/configure.ac trunk/pyext/rivet.i trunk/src/Makefile.am Modified: trunk/configure.ac ============================================================================== --- trunk/configure.ac Tue Dec 1 17:04:36 2009 (r2121) +++ trunk/configure.ac Tue Dec 1 19:39:13 2009 (r2122) @@ -2,7 +2,7 @@ AC_PREREQ(2.59) AC_INIT([Rivet],[1.2.0a0],[rivet at projects.hepforge.org],[Rivet]) -AC_CONFIG_SRCDIR([src/Analysis.cc]) +AC_CONFIG_SRCDIR([src/Core/Analysis.cc]) AC_CONFIG_HEADERS([include/Rivet/Config/DummyConfig.hh include/Rivet/Config/RivetConfig.hh include/Rivet/Config/BuildOptions.hh]) AM_INIT_AUTOMAKE(dist-bzip2) AC_CONFIG_MACRO_DIR([m4]) @@ -255,6 +255,7 @@ AC_EMPTY_SUBST AC_CONFIG_FILES(include/Makefile include/Rivet/Makefile) AC_CONFIG_FILES(src/Makefile) +AC_CONFIG_FILES(src/Core/Makefile) AC_CONFIG_FILES(src/Tools/Makefile src/Tools/yaml-cpp/Makefile) AC_CONFIG_FILES(src/Projections/Makefile) AC_CONFIG_FILES(src/Analyses/Makefile) Modified: trunk/pyext/rivet.i ============================================================================== --- trunk/pyext/rivet.i Tue Dec 1 17:04:36 2009 (r2121) +++ trunk/pyext/rivet.i Tue Dec 1 19:39:13 2009 (r2122) @@ -81,8 +81,7 @@ virtual std::string collider() const; virtual std::string year() const; virtual std::string status() const; - // const std::pair<ParticleName,ParticleName>& beams() const { return _beams; } - // const std::vector<std::pair<double,double> >& energies() const { return _energies; } + virtual const std::vector<std::pair<double,double> >& energies() const; virtual std::vector<std::string> authors() const; virtual std::vector<std::string> references() const; virtual const BeamPair& beams() const; Copied: trunk/src/Core/Analysis.cc (from r2121, trunk/src/Analysis.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Analysis.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2121, trunk/src/Analysis.cc) @@ -0,0 +1,514 @@ +// -*- C++ -*- +#include "Rivet/Rivet.hh" +#include "Rivet/RivetAIDA.hh" +#include "Rivet/AnalysisHandler.hh" +#include "Rivet/AnalysisInfo.hh" +#include "Rivet/Analysis.hh" +#include "Rivet/Tools/Logging.hh" +#include "LWH/AIManagedObject.h" +using namespace AIDA; + +namespace Rivet { + + + Analysis::Analysis(const string& name) + : _crossSection(-1.0), + _gotCrossSection(false), + _needsCrossSection(false), + _analysishandler(NULL), + _madeHistoDir(false) + { + ProjectionApplier::_allowProjReg = false; + _defaultname = name; + AnalysisInfo* ai = AnalysisInfo::make(name); + assert(ai != 0); + _info.reset(ai); + assert(_info.get() != 0); + //setBeams(ANY, ANY); + } + + + Analysis::~Analysis() + { } + + + IAnalysisFactory& Analysis::analysisFactory() { + return handler().analysisFactory(); + } + + + ITree& Analysis::tree() { + return handler().tree(); + } + + + IHistogramFactory& Analysis::histogramFactory() { + return handler().histogramFactory(); + } + + + IDataPointSetFactory& Analysis::datapointsetFactory() { + return handler().datapointsetFactory(); + } + + + const string Analysis::histoDir() const { + string path = "/" + name(); + if (handler().runName().length() > 0) { + path = "/" + handler().runName() + path; + } + while (find_first(path, "//")) { + replace_all(path, "//", "/"); + } + return path; + } + + + const string Analysis::histoPath(const string& hname) const { + const string path = histoDir() + "/" + hname; + return path; + } + + + Log& Analysis::getLog() const { + string logname = "Rivet.Analysis." + name(); + return Log::getLog(logname); + } + + + size_t Analysis::numEvents() const { + return handler().numEvents(); + } + + + double Analysis::sumOfWeights() const { + return handler().sumOfWeights(); + } + + + //////////////////////////////////////////////////////////// + // Metadata + + const AnalysisInfo& Analysis::info() const { + assert(_info.get() != 0); + return *_info; + } + + string Analysis::name() const { + if (_info && !_info->name().empty()) return _info->name(); + return _defaultname; + } + + string Analysis::spiresId() const { + if (!_info) return "NONE"; + return _info->spiresId(); + } + + vector<string> Analysis::authors() const { + if (!_info) return std::vector<std::string>(); + return _info->authors(); + } + + string Analysis::summary() const { + if (!_info) return "NONE"; + return _info->summary(); + } + + string Analysis::description() const { + if (!_info) return "NONE"; + return _info->description(); + } + + string Analysis::runInfo() const { + if (!_info) return "NONE"; + return _info->runInfo(); + } + + const std::pair<ParticleName,ParticleName>& Analysis::beams() const { + return info().beams(); + } + + const std::vector<std::pair<double,double> >& Analysis::energies() const { + return info().energies(); + } + + string Analysis::experiment() const { + if (!_info) return "NONE"; + return _info->experiment(); + } + + string Analysis::collider() const { + if (!_info) return "NONE"; + return _info->collider(); + } + + string Analysis::year() const { + if (!_info) return "NONE"; + return _info->year(); + } + + vector<string> Analysis::references() const { + if (!_info) return vector<string>(); + return _info->references(); + } + + string Analysis::status() const { + if (!_info) return "UNVALIDATED"; + return _info->status(); + } + + const BeamPair Analysis::requiredBeams() const { + return make_pdgid_pair(info().beams()); + } + + Analysis& Analysis::setBeams(const ParticleName& beam1, const ParticleName& beam2) { + assert(_info.get() != 0); + _info->_beams = make_pair(beam1, beam2); + return *this; + } + + bool Analysis::isCompatible(const ParticleName& beam1, const ParticleName& beam2) const { + BeamPair beams(beam1, beam2); + return compatible(beams, requiredBeams()); + /// @todo Need to also check internal consistency of the analysis' + /// beam requirements with those of the projections it uses. + } + + bool Analysis::isCompatible(const BeamPair& beams) const { + return compatible(beams, requiredBeams()); + /// @todo Need to also check internal consistency of the analysis' + /// beam requirements with those of the projections it uses. + } + + Analysis& Analysis::setCrossSection(const double& xs) { + _crossSection = xs; + _gotCrossSection = true; + return *this; + } + + bool Analysis::needsCrossSection() const { + return _needsCrossSection; + } + + Analysis& Analysis::setNeedsCrossSection(bool needed) { + _needsCrossSection = needed; + return *this; + } + + double Analysis::crossSection() const { + if (!_gotCrossSection || _crossSection < 0) { + string errMsg = "You did not set the cross section for the analysis " + name(); + throw Error(errMsg); + } + return _crossSection; + } + + double Analysis::crossSectionPerEvent() const { + const double sumW = sumOfWeights(); + assert(sumW > 0); + return _crossSection / sumW; + } + + AnalysisHandler& Analysis::handler() const { + return *_analysishandler; + } + + + + //////////////////////////////////////////////////////////// + // Histogramming + + + void Analysis::_cacheBinEdges() { + _cacheXAxisData(); + if (_histBinEdges.empty()) { + getLog() << Log::TRACE << "Getting histo bin edges from AIDA for paper " << name() << endl; + _histBinEdges = getBinEdges(_dpsData); + } + } + + + void Analysis::_cacheXAxisData() { + if (_dpsData.empty()) { + getLog() << Log::TRACE << "Getting DPS x-axis data from AIDA for paper " << name() << endl; + _dpsData = getDPSXValsErrs(name()); + } + } + + + string Analysis::_makeAxisCode(const size_t datasetId, const size_t xAxisId, const size_t yAxisId) const { + stringstream axisCode; + axisCode << "d"; + if (datasetId < 10) axisCode << 0; + axisCode << datasetId; + axisCode << "-x"; + if (xAxisId < 10) axisCode << 0; + axisCode << xAxisId; + axisCode << "-y"; + if (yAxisId < 10) axisCode << 0; + axisCode << yAxisId; + return axisCode.str(); + } + + + IHistogram1D* Analysis::bookHistogram1D(const size_t datasetId, const size_t xAxisId, + const size_t yAxisId, const string& title, + const string& xtitle, const string& ytitle) + { + const string axisCode = _makeAxisCode(datasetId, xAxisId, yAxisId); + return bookHistogram1D(axisCode, title, xtitle, ytitle); + } + + + IHistogram1D* Analysis::bookHistogram1D(const string& hname, const string& title, + const string& xtitle, const string& ytitle) + { + // Get the bin edges (only read the AIDA file once) + _cacheBinEdges(); + getLog() << Log::TRACE << "Using histo bin edges for " << name() << ":" << hname << endl; + const BinEdges edges = _histBinEdges.find(hname)->second; + _makeHistoDir(); + const string path = histoPath(hname); + IHistogram1D* hist = histogramFactory().createHistogram1D(path, title, edges); + getLog() << Log::TRACE << "Made histogram " << hname << " for " << name() << endl; + hist->setXTitle(xtitle); + hist->setYTitle(ytitle); + return hist; + } + + + IHistogram1D* Analysis::bookHistogram1D(const string& hname, + const size_t nbins, const double lower, const double upper, + const string& title, + const string& xtitle, const string& ytitle) { + _makeHistoDir(); + const string path = histoPath(hname); + IHistogram1D* hist = histogramFactory().createHistogram1D(path, title, nbins, lower, upper); + getLog() << Log::TRACE << "Made histogram " << hname << " for " << name() << endl; + hist->setXTitle(xtitle); + hist->setYTitle(ytitle); + return hist; + } + + + IHistogram1D* Analysis::bookHistogram1D(const string& hname, + const vector<double>& binedges, + const string& title, + const string& xtitle, const string& ytitle) { + _makeHistoDir(); + const string path = histoPath(hname); + IHistogram1D* hist = histogramFactory().createHistogram1D(path, title, binedges); + getLog() << Log::TRACE << "Made histogram " << hname << " for " << name() << endl; + hist->setXTitle(xtitle); + hist->setYTitle(ytitle); + return hist; + } + + + ///////////////// + + + IProfile1D* Analysis::bookProfile1D(const size_t datasetId, const size_t xAxisId, + const size_t yAxisId, const string& title, + const string& xtitle, const string& ytitle) { + const string axisCode = _makeAxisCode(datasetId, xAxisId, yAxisId); + return bookProfile1D(axisCode, title, xtitle, ytitle); + } + + + IProfile1D* Analysis::bookProfile1D(const string& hname, const string& title, + const string& xtitle, const string& ytitle) + { + // Get the bin edges (only read the AIDA file once) + _cacheBinEdges(); + getLog() << Log::TRACE << "Using profile histo bin edges for " << name() << ":" << hname << endl; + const BinEdges edges = _histBinEdges.find(hname)->second; + if (getLog().isActive(Log::TRACE)) { + stringstream edges_ss; + foreach (const double be, edges) { + edges_ss << " " << be; + } + getLog() << Log::TRACE << "Edges:" << edges_ss.str() << endl; + } + _makeHistoDir(); + const string path = histoPath(hname); + IProfile1D* prof = histogramFactory().createProfile1D(path, title, edges); + getLog() << Log::TRACE << "Made profile histogram " << hname << " for " << name() << endl; + prof->setXTitle(xtitle); + prof->setYTitle(ytitle); + return prof; + } + + + IProfile1D* Analysis::bookProfile1D(const string& hname, + const size_t nbins, const double lower, const double upper, + const string& title, + const string& xtitle, const string& ytitle) { + _makeHistoDir(); + const string path = histoPath(hname); + IProfile1D* prof = histogramFactory().createProfile1D(path, title, nbins, lower, upper); + getLog() << Log::TRACE << "Made profile histogram " << hname << " for " << name() << endl; + prof->setXTitle(xtitle); + prof->setYTitle(ytitle); + return prof; + } + + + IProfile1D* Analysis::bookProfile1D(const string& hname, + const vector<double>& binedges, + const string& title, + const string& xtitle, const string& ytitle) { + _makeHistoDir(); + const string path = histoPath(hname); + IProfile1D* prof = histogramFactory().createProfile1D(path, title, binedges); + getLog() << Log::TRACE << "Made profile histogram " << hname << " for " << name() << endl; + prof->setXTitle(xtitle); + prof->setYTitle(ytitle); + return prof; + } + + + /////////////////// + + + + IDataPointSet* Analysis::bookDataPointSet(const string& hname, const string& title, + const string& xtitle, const string& ytitle) { + _makeHistoDir(); + const string path = histoPath(hname); + IDataPointSet* dps = datapointsetFactory().create(path, title, 2); + getLog() << Log::TRACE << "Made data point set " << hname << " for " << name() << endl; + dps->setXTitle(xtitle); + dps->setYTitle(ytitle); + return dps; + } + + + IDataPointSet* Analysis::bookDataPointSet(const string& hname, + const size_t npts, const double lower, const double upper, + const string& title, + const string& xtitle, const string& ytitle) { + IDataPointSet* dps = bookDataPointSet(hname, title, xtitle, ytitle); + for (size_t pt = 0; pt < npts; ++pt) { + const double binwidth = (upper-lower)/npts; + const double bincentre = lower + (pt + 0.5) * binwidth; + dps->addPoint(); + IMeasurement* meas = dps->point(pt)->coordinate(0); + meas->setValue(bincentre); + meas->setErrorPlus(binwidth/2.0); + meas->setErrorMinus(binwidth/2.0); + } + return dps; + } + + + IDataPointSet* Analysis::bookDataPointSet(const size_t datasetId, const size_t xAxisId, + const size_t yAxisId, const string& title, + const string& xtitle, const string& ytitle) { + // Get the bin edges (only read the AIDA file once) + _cacheXAxisData(); + // Build the axis code + const string axisCode = _makeAxisCode(datasetId, xAxisId, yAxisId); + //const map<string, vector<DPSXPoint> > xpoints = getDPSXValsErrs(papername); + getLog() << Log::TRACE << "Using DPS x-positions for " << name() << ":" << axisCode << endl; + IDataPointSet* dps = bookDataPointSet(axisCode, title, xtitle, ytitle); + const vector<DPSXPoint> xpts = _dpsData.find(axisCode)->second; + for (size_t pt = 0; pt < xpts.size(); ++pt) { + dps->addPoint(); + IMeasurement* meas = dps->point(pt)->coordinate(0); + meas->setValue(xpts[pt].val); + meas->setErrorPlus(xpts[pt].errplus); + meas->setErrorMinus(xpts[pt].errminus); + } + getLog() << Log::TRACE << "Made DPS " << axisCode << " for " << name() << endl; + return dps; + } + + + //////////////////// + + + void Analysis::_makeHistoDir() { + if (!_madeHistoDir) { + if (! name().empty()) { + // vector<string> dirs; + // split(dirs, histoDir(), "/"); + // string pathpart; + // foreach (const string& d, dirs) { + //tree().mkdir(); + //} + tree().mkdirs(histoDir()); + } + _madeHistoDir = true; + } + } + + + void Analysis::normalize(AIDA::IHistogram1D*& histo, const double norm) { + if (!histo) { + getLog() << Log::ERROR << "Failed to normalise histo=NULL in analysis " + << name() << "(norm=" << norm << ")" << endl; + return; + } + const string hpath = tree().findPath(dynamic_cast<const AIDA::IManagedObject&>(*histo)); + getLog() << Log::TRACE << "Normalizing histo " << hpath << " to " << norm << endl; + + double oldintg = 0.0; + int nBins = histo->axis().bins(); + for (int iBin = 0; iBin != nBins; ++iBin) { + // Leaving out factor of binWidth because AIDA's "height" already includes a width factor. + oldintg += histo->binHeight(iBin); // * histo->axis().binWidth(iBin); + } + if (oldintg == 0.0) { + getLog() << Log::WARN << "Histo " << hpath << " has null integral during normalisation" << endl; + return; + } + + // Scale by the normalisation factor. + scale(histo, norm/oldintg); + } + + + void Analysis::scale(AIDA::IHistogram1D*& histo, const double scale) { + if (!histo) { + getLog() << Log::ERROR << "Failed to scale histo=NULL in analysis " + << name() << "(scale=" << scale << ")" << endl; + return; + } + const string hpath = tree().findPath(dynamic_cast<const AIDA::IManagedObject&>(*histo)); + getLog() << Log::TRACE << "Scaling histo " << hpath << endl; + + vector<double> x, y, ex, ey; + for (size_t i = 0, N = histo->axis().bins(); i < N; ++i) { + x.push_back(0.5 * (histo->axis().binLowerEdge(i) + histo->axis().binUpperEdge(i))); + ex.push_back(histo->axis().binWidth(i)*0.5); + + // "Bin height" is a misnomer in the AIDA spec: width is neglected. + // We'd like to do this: y.push_back(histo->binHeight(i) * scale); + y.push_back(histo->binHeight(i)*scale/histo->axis().binWidth(i)); + + // "Bin error" is a misnomer in the AIDA spec: width is neglected. + // We'd like to do this: ey.push_back(histo->binError(i) * scale); + ey.push_back(histo->binError(i)*scale/(0.5*histo->axis().binWidth(i))); + } + + string title = histo->title(); + string xtitle = histo->xtitle(); + string ytitle = histo->ytitle(); + + tree().mkdir("/tmpnormalize"); + tree().mv(hpath, "/tmpnormalize"); + + AIDA::IDataPointSet* dps = datapointsetFactory().createXY(hpath, title, x, y, ex, ey); + dps->setXTitle(xtitle); + dps->setYTitle(ytitle); + + tree().rm(tree().findPath(dynamic_cast<AIDA::IManagedObject&>(*histo))); + tree().rmdir("/tmpnormalize"); + + // Set histo pointer to null - it can no longer be used. + histo = 0; + } + + +} Copied: trunk/src/Core/AnalysisHandler.cc (from r2120, trunk/src/AnalysisHandler.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/AnalysisHandler.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/AnalysisHandler.cc) @@ -0,0 +1,297 @@ +// -*- C++ -*- +#include "Rivet/Rivet.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/AnalysisHandler.hh" +#include "Rivet/RivetAIDA.hh" +#include "LWH/AIManagedObject.h" + +using namespace AIDA; + +namespace Rivet { + + + AnalysisHandler::AnalysisHandler(string basefilename, + string runname, HistoFormat storetype) + : _runname(runname), _nRun(0), _iRun(0), _numEvents(0), _sumOfWeights(0.0) { + _theAnalysisFactory = createAnalysisFactory(); + _setupFactories(basefilename, storetype); + } + + + AnalysisHandler::AnalysisHandler(IAnalysisFactory& afac, string basefilename, + string runname, HistoFormat storetype) + : _runname(runname), _nRun(0), _iRun(0), _numEvents(0), _sumOfWeights(0.0), + _theAnalysisFactory(&afac) { + _setupFactories(basefilename, storetype); + } + + + AnalysisHandler::~AnalysisHandler() + { + } + + + Log& AnalysisHandler::getLog() { + return Log::getLog("Rivet.Analysis.Handler"); + } + + + void AnalysisHandler::init(int i, int N) { + getLog() << Log::DEBUG << "Initialising the analysis handler" << endl; + _nRun = N; + _iRun = i; + _numEvents = 0; + _sumOfWeights = 0.0; + foreach (Analysis* a, _analyses) { + getLog() << Log::DEBUG << "Initialising analysis: " << a->name() << endl; + // Allow projection registration in the init phase onwards + a->_allowProjReg = true; + a->init(); + //getLog() << Log::DEBUG << "Checking consistency of analysis: " << a->name() << endl; + //a->checkConsistency(); + getLog() << Log::DEBUG << "Done initialising analysis: " << a->name() << endl; + } + getLog() << Log::DEBUG << "Analysis handler initialised" << endl; + } + + + void AnalysisHandler::analyze(const GenEvent& ge) { + Event event(ge); + _numEvents++; + // Weights + const double weight = event.weight(); + _sumOfWeights += weight; + getLog() << Log::DEBUG << "Event #" << _numEvents << " weight = " << weight << endl; + #ifdef HEPMC_HAS_CROSS_SECTION + if (ge.cross_section()) { + const double xs = ge.cross_section()->cross_section(); + setCrossSection(xs); + } + #endif + foreach (Analysis* a, _analyses) { + getLog() << Log::DEBUG << "About to run analysis " << a->name() << endl; + a->analyze(event); + getLog() << Log::DEBUG << "Finished running analysis " << a->name() << endl; + } + } + + + void AnalysisHandler::finalize() { + getLog() << Log::INFO << "Finalising analyses" << endl; + foreach (Analysis* a, _analyses) { + a->finalize(); + } + + // Print out number of events processed + getLog() << Log::INFO << "Processed " << _numEvents << " event" << (_numEvents == 1 ? "" : "s") << endl; + + // Change AIDA histos into data point sets + getLog() << Log::DEBUG << "Converting histograms to scatter plots" << endl; + assert(_theTree != 0); + _normalizeTree(tree()); + + // Delete analyses + getLog() << Log::DEBUG << "Deleting analyses" << endl; + foreach (Analysis* a, _analyses) { + delete a; + } + _analyses.clear(); + + // Print out MCnet boilerplate + cout << endl; + cout << "The MCnet usage guidelines apply to Rivet: see http://www.montecarlonet.org/GUIDELINES" << endl; + cout << "Please acknowledge plots made with Rivet analyses, and cite arXiv:0809.4638" << endl; + } + + + AnalysisHandler& AnalysisHandler::addAnalysis(const string& analysisname) { + Analysis* analysis = AnalysisLoader::getAnalysis(analysisname); + if (analysis) { // < Check for null analysis. + getLog() << Log::DEBUG << "Adding analysis '" << analysisname << "'" << endl; + analysis->_analysishandler = this; + _analyses.insert(analysis); + } + return *this; + } + + + AnalysisHandler& AnalysisHandler::removeAnalysis(const string& analysisname) { + Analysis* toremove = 0; + foreach (Analysis* a, _analyses) { + if (a->name() == analysisname) { + toremove = a; + break; + } + } + if (toremove) { + getLog() << Log::DEBUG << "Removing analysis '" << analysisname << "'" << endl; + _analyses.erase(toremove); + delete toremove; + } + return *this; + } + + + /// Remove beam-incompatible analyses from the run list. + AnalysisHandler& AnalysisHandler::removeIncompatibleAnalyses(const BeamPair& beams) { + vector<Analysis*> todelete; + foreach (Analysis* a, _analyses) { + if (! a->isCompatible(beams)) { + todelete.push_back(a); + } + } + foreach (Analysis* a, todelete) { + getLog() << Log::WARN << "Removing incompatible analysis '" + << a->name() << "'" << endl; + _analyses.erase(a); + delete a; + } + return *this; + } + + + void AnalysisHandler::_setupFactories(string basefilename, HistoFormat storetype) { + string filename(basefilename), storetypestr(""); + if (storetype == AIDAML) { + if (!endsWith(filename, ".aida")) filename += ".aida"; + storetypestr = "xml"; + } else if (storetype == FLAT) { + if (!endsWith(filename, ".data")) filename += ".data"; + storetypestr = "flat"; + } else if (storetype == ROOT) { + if (!endsWith(filename, ".root")) filename += ".root"; + storetypestr = "root"; + } + _theTree = _theAnalysisFactory->createTreeFactory()->create(filename, storetypestr, false, true); + _theHistogramFactory = _theAnalysisFactory->createHistogramFactory(tree()); + _theDataPointSetFactory = _theAnalysisFactory->createDataPointSetFactory(tree()); + } + + + void AnalysisHandler::commitData() { + tree().commit(); + } + + + void AnalysisHandler::_normalizeTree(ITree& tree) { + Log& log = getLog(); + const vector<string> paths = tree.listObjectNames("/", true); // args set recursive listing + log << Log::TRACE << "Number of objects in AIDA tree = " << paths.size() << endl; + const string tmpdir = "/RivetNormalizeTmp"; + tree.mkdir(tmpdir); + foreach (const string& path, paths) { + + IManagedObject* hobj = tree.find(path); + if (hobj) { + IHistogram1D* histo = dynamic_cast<IHistogram1D*>(hobj); + IProfile1D* prof = dynamic_cast<IProfile1D*>(hobj); + // If it's a normal histo: + if (histo) { + log << Log::TRACE << "Converting histo " << path << " to DPS" << endl; + tree.mv(path, tmpdir); + const size_t lastslash = path.find_last_of("/"); + const string basename = path.substr(lastslash+1, path.length() - (lastslash+1)); + const string tmppath = tmpdir + "/" + basename; + IHistogram1D* tmphisto = dynamic_cast<IHistogram1D*>(tree.find(tmppath)); + if (tmphisto) { + //getLog() << Log::TRACE << "Temp histo " << tmppath << " exists" << endl; + datapointsetFactory().create(path, *tmphisto); + } + tree.rm(tmppath); + } + // If it's a profile histo: + else if (prof) { + log << Log::TRACE << "Converting profile histo " << path << " to DPS" << endl; + tree.mv(path, tmpdir); + const size_t lastslash = path.find_last_of("/"); + const string basename = path.substr(lastslash+1, path.length() - (lastslash+1)); + const string tmppath = tmpdir + "/" + basename; + IProfile1D* tmpprof = dynamic_cast<IProfile1D*>(tree.find(tmppath)); + if (tmpprof) { + //getLog() << Log::TRACE << "Temp profile histo " << tmppath << " exists" << endl; + datapointsetFactory().create(path, *tmpprof); + } + tree.rm(tmppath); + } + + } + + } + tree.rmdir(tmpdir); + } + + + string AnalysisHandler::runName() const { return _runname; } + size_t AnalysisHandler::numEvents() const { return _numEvents; } + double AnalysisHandler::sumOfWeights() const { return _sumOfWeights; } + + void AnalysisHandler::setSumOfWeights(const double& sum) { + _sumOfWeights=sum; + } + + + std::vector<std::string> AnalysisHandler::analysisNames() { + std::vector<std::string> rtn; + foreach (Analysis* a, _analyses) { + rtn.push_back(a->name()); + } + return rtn; + } + + + AnalysisHandler& AnalysisHandler::addAnalyses(const std::vector<std::string>& analysisnames) { + foreach (const string& aname, analysisnames) { + //getLog() << Log::DEBUG << "Adding analysis '" << aname << "'" << endl; + addAnalysis(aname); + } + return *this; + } + + + AnalysisHandler& AnalysisHandler::removeAnalyses(const std::vector<std::string>& analysisnames) { + foreach (const string& aname, analysisnames) { + removeAnalysis(aname); + } + return *this; + } + + + + AIDA::IAnalysisFactory& AnalysisHandler::analysisFactory() { + return *_theAnalysisFactory; + } + + + AIDA::ITree& AnalysisHandler::tree() { + return *_theTree; + } + + + AIDA::IHistogramFactory& AnalysisHandler::histogramFactory() { + return *_theHistogramFactory; + } + + + AIDA::IDataPointSetFactory& AnalysisHandler::datapointsetFactory() { + return *_theDataPointSetFactory; + } + + + bool AnalysisHandler::needCrossSection() const { + bool rtn = false; + foreach (const Analysis* a, _analyses) { + if (!rtn) rtn = a->needsCrossSection(); + if (rtn) break; + } + return rtn; + } + + + AnalysisHandler& AnalysisHandler::setCrossSection(double xs) { + foreach (Analysis* a, _analyses) { + a->setCrossSection(xs); + } + return *this; + } + +} Copied: trunk/src/Core/AnalysisInfo.cc (from r2121, trunk/src/AnalysisInfo.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/AnalysisInfo.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2121, trunk/src/AnalysisInfo.cc) @@ -0,0 +1,173 @@ +#include "Rivet/Rivet.hh" +#include "Rivet/AnalysisInfo.hh" +#include "Rivet/Tools/Utils.hh" +#include "Rivet/Tools/Logging.hh" +#include "yaml.h" +#include <iostream> +#include <fstream> +#include <unistd.h> + +namespace Rivet { + + + /// Ideas: + /// * search RIVET_DATA_PATH etc. for <name>.info.yaml + /// * how to determine the name? + /// * only populate pointer on Analysis when requested + /// * use smart pointer: deletes automatically when Analysis + /// goes out of scope + + + /// Static factory method + AnalysisInfo* AnalysisInfo::make(const std::string& ananame) { + // Build the list of directories to search + vector<string> dirs; + char* env = 0; + // First try to use the Rivet data path variable + env = getenv("RIVET_DATA_PATH"); + if (env) dirs += split(env); + // Then try to use the Rivet data install path + dirs += getRivetDataPath(); + // And the current dir + dirs += "."; + + bool found = false; + string datapath = ""; + foreach (const string& d, dirs) { + if (d.empty()) continue; + /// @todo Use system-independent separator (e.g. Boost.File) + datapath = d + "/" + ananame + ".info"; + Log::getLog("Rivet.AnalysisInfo") + << Log::TRACE << "Looking for analysis data file '" << datapath << "'" << endl; + if (access(datapath.c_str(), R_OK) == 0) { + found = true; + break; + } + } + + // Returned AI, in semi-null state + AnalysisInfo* ai = new AnalysisInfo(); + ai->_beams = make_pair(ANY,ANY); + ai->_name = ananame; + + /// If no ana data file found, return null AI + if (!found) return ai; + + // Read data from YAML document + Log::getLog("Rivet.AnalysisInfo") + << Log::DEBUG << "Reading analysis data from " << datapath << endl; + std::ifstream io(datapath.c_str()); + YAML::Parser parser(io); + YAML::Node doc; + try { + parser.GetNextDocument(doc); + //cout << doc << endl; + } catch (const YAML::ParserException& ex) { + Log::getLog("Rivet.AnalysisInfo") + << Log::ERROR << "Parse error when reading analysis data from " + << datapath << endl; + return ai; + } + + for (YAML::Iterator it = doc.begin(); it != doc.end(); ++it) { + string key; + it.first() >> key; + stringstream sec; + sec << it.second(); + const string secstr = sec.str().substr(0, sec.str().length()-1); + Log::getLog("Rivet.AnalysisInfo") + << Log::TRACE << key << ": " << secstr << endl; + try { + if (key == "Name") { + it.second() >> ai->_name; + } else if (key == "Summary") { + it.second() >> ai->_summary; + } else if (key == "Experiment") { + it.second() >> ai->_experiment; + } else if (key == "Beams") { + const YAML::Node& beams = it.second(); + vector<ParticleName> beampair; + for (YAML::Iterator b = beams.begin(); b != beams.end(); ++b) { + string bstr; + *b >> bstr; + ParticleName beamname = getParticleNameEnum(bstr); + beampair += beamname; + } + assert(beampair.size() == 2); + ai->_beams = make_pair<ParticleName,ParticleName>(beampair[0], beampair[1]); + // } else if (key == "NeedCrossSection") { + // // it.second() >> ai->_needsCrossSection; + } else if (key == "Energies") { + const YAML::Node& energies = it.second(); + vector<pair<double,double> > beam_energy_pairs; + for (YAML::Iterator be = energies.begin(); be != energies.end(); ++be) { + if (be->GetType() == YAML::CT_SCALAR) { + // If beam energy is a scalar, then assume symmetric beams each with half that energy + double sqrts; + *be >> sqrts; + beam_energy_pairs += make_pair(sqrts/2.0, sqrts/2.0); + } else if (be->GetType() == YAML::CT_SEQUENCE) { + const YAML::Node& beamenergy_strs = be.second(); + vector<double> beamenergies; + for (YAML::Iterator e = beamenergy_strs.begin(); e != beamenergy_strs.end(); ++e) { + double beamenergy; + *e >> beamenergy; + beamenergies += beamenergy; + } + assert(beamenergies.size() == 2); + beam_energy_pairs += make_pair(beamenergies[0], beamenergies[1]); + } else { + assert(0 && "Beam energies have to be a list of either numbers or pairs of numbers"); + } + } + ai->_energies = beam_energy_pairs; + } else if (key == "Collider") { + it.second() >> ai->_collider; + } else if (key == "SpiresID") { + it.second() >> ai->_spiresId; + } else if (key == "Status") { + it.second() >> ai->_status; + } else if (key == "RunInfo") { + it.second() >> ai->_runInfo; + } else if (key == "Description") { + it.second() >> ai->_description; + } else if (key == "Year") { + it.second() >> ai->_year; + } else if (key == "Authors") { + const YAML::Node& authors = it.second(); + for (YAML::Iterator a = authors.begin(); a != authors.end(); ++a) { + string astr; + *a >> astr; + ai->_authors += astr; + } + } else if (key == "References") { + const YAML::Node& refs = it.second(); + for (YAML::Iterator r = refs.begin(); r != refs.end(); ++r) { + string rstr; + *r >> rstr; + ai->_references += rstr; + } + } + } catch (const YAML::RepresentationException& ex) { + Log::getLog("Rivet.Analysis") + << Log::WARN << "Type error when reading analysis data '" + << key << "' from " << datapath << endl; + } + } + Log::getLog("Rivet.AnalysisInfo") << Log::DEBUG << ai << endl; + return ai; + } + + + string toString(const AnalysisInfo& ai) { + stringstream ss; + ss << ai.name(); + ss << " - " << ai.summary(); + // ss << " - " << ai.beams(); + // ss << " - " << ai.energies(); + ss << " (" << ai.status() << ")"; + return ss.str(); + } + + +} Copied: trunk/src/Core/AnalysisLoader.cc (from r2120, trunk/src/AnalysisLoader.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/AnalysisLoader.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/AnalysisLoader.cc) @@ -0,0 +1,110 @@ +// -*- C++ -*- +#include "Rivet/AnalysisLoader.hh" +#include "Rivet/Tools/Utils.hh" +#include "Rivet/Tools/osdir.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/Analysis.hh" +#include <dlfcn.h> + +namespace Rivet { + + + // Initialise static ptr collection + AnalysisLoader::AnalysisBuilderMap AnalysisLoader::_ptrs; + + + vector<string> AnalysisLoader::analysisNames() { + _loadAnalysisPlugins(); + vector<string> names; + foreach (const AnalysisBuilderMap::value_type& p, _ptrs) names += p.first; + return names; + } + + + Analysis* AnalysisLoader::getAnalysis(const string& analysisname) { + _loadAnalysisPlugins(); + AnalysisBuilderMap::const_iterator ai = _ptrs.find(analysisname); + if (ai == _ptrs.end()) return 0; + return ai->second->mkAnalysis(); + } + + + vector<Analysis*> AnalysisLoader::getAllAnalyses() { + _loadAnalysisPlugins(); + vector<Analysis*> analyses; + foreach (const AnalysisBuilderMap::value_type& p, _ptrs) { + analyses += p.second->mkAnalysis(); + } + return analyses; + } + + + void AnalysisLoader::_registerBuilder(const AnalysisBuilderBase* ab) { + if (!ab) return; + const string name = ab->name(); + if (_ptrs.find(name) != _ptrs.end()) { + // Protect against overwriting analyses by throwing an error + /// @todo Tidy this up! + Log::getLog("Rivet.AnalysisLoader") << Log::ERROR << "Tried to register a second plugin analysis called '" << name << "'" << endl; + exit(1); + } + Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Registering a plugin analysis called '" << name << "'" << endl; + _ptrs[name] = ab; + } + + + void AnalysisLoader::_loadAnalysisPlugins() { + // Only run once + if (!_ptrs.empty()) return; + + // Build the list of directories to search + vector<string> dirs; + char* env = 0; + // First use the Rivet analysis path variable + env = getenv("RIVET_ANALYSIS_PATH"); + if (env) dirs += split(env); + // Then the Rivet library install path + dirs += getLibPath(); + // And then the user's (non-system) library path + env = getenv("LD_LIBRARY_PATH"); + if (env) dirs += split(env); + // Use the current dir, and its libtool subdir, too. + dirs += "."; + dirs += ".libs"; + + // Find plugin module library files + const string libsuffix = ".so"; + vector<string> pluginfiles; + foreach (const string& d, dirs) { + if (d.empty()) continue; + oslink::directory dir(d); + while (dir) { + string filename = dir.next(); + // Require that name *starts* with 'Rivet' with new loader + if (filename.find("Rivet") != 0) continue; + size_t posn = filename.find(libsuffix); + if (posn == string::npos || posn != filename.length()-libsuffix.length()) continue; + /// @todo Make sure this is an abs path + /// @todo Sys-dependent path separator instead of "/" + const string path = d + "/" + filename; + // Ensure no duplicate paths + if (find(pluginfiles.begin(), pluginfiles.end(), path) == pluginfiles.end()) { + pluginfiles += path; + } + } + } + + // Load the plugin files + Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Candidate analysis plugin libs: " << pluginfiles << endl; + foreach (const string& pf, pluginfiles) { + Log::getLog("Rivet.AnalysisLoader") << Log::TRACE << "Trying to load plugin analyses from file " << pf << endl; + void* handle = dlopen(pf.c_str(), RTLD_LAZY); + if (!handle) { + Log::getLog("Rivet.AnalysisLoader") << Log::WARN << "Cannot open " << pf << ": " << dlerror() << endl; + continue; + } + } + } + + +} Copied: trunk/src/Core/Cuts.cc (from r2120, trunk/src/Cuts.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Cuts.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Cuts.cc) @@ -0,0 +1,77 @@ +// -*- C++ -*- + +#include "Rivet/Rivet.hh" +#include "Rivet/Cuts.hh" + +using std::ostringstream; + +namespace Rivet { + + + Cuts& Cuts::addCut(const string& quantity, const Comparison& comparison, const double value) { + // If this quantity doesn't yet have any associated cuts, make a + // default cut with effectively infinitely loose cuts. + if (_cuts.find(quantity) == _cuts.end()) { + _cuts[quantity] = BinaryCut(); + } + // Combine cuts in the most restrictive way. + switch (comparison) { + case LESS_EQ: + if (value < _cuts[quantity].getLowerThan()) { + _cuts[quantity].setLowerThan(value); + } + break; + case MORE_EQ: + if (value > _cuts[quantity].getHigherThan()) { + _cuts[quantity].setHigherThan(value); + } + break; + case EQUAL: + _cuts[quantity].setLowerThan(value); + _cuts[quantity].setHigherThan(value); + break; + } + + // Allow method chaining. + return *this; + } + + + + bool Cuts::checkConsistency() const { + for (Cuts::const_iterator c = begin(); c != end(); ++c) { + if (c->second.getLowerThan() < c->second.getLowerThan()) { + ostringstream msg; + msg << "Constraints on " << c->first << " are incompatible: " + << ">=" << c->second.getHigherThan() << " AND " + << "<=" << c->second.getLowerThan(); + throw Error(msg.str()); + } + } + return true; + } + + + + ostream& Cuts::print(ostream & os) const { + for (Cuts::const_iterator cut = begin(); cut != end(); ++cut) { + os << endl; + os << setw(12) << std::left << cut->first; + if (cut->second.getHigherThan() > -numeric_limits<double>::max()) { + os << setw(3) << ">="; + os << setw(10) << std::right << cut->second.getHigherThan(); + } else { + os << setw(13) << ""; + } + if (cut->second.getLowerThan() < numeric_limits<double>::max()) { + os << setw(3) << "<="; + os << setw(10) << std::right << cut->second.getLowerThan(); + } else { + os << setw(13) << ""; + } + } + return os; + } + + +} Copied: trunk/src/Core/Event.cc (from r2120, trunk/src/Event.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Event.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Event.cc) @@ -0,0 +1,108 @@ +#include "Rivet/Event.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/Projections/Beam.hh" +#include "Rivet/BeamConstraint.hh" +#include "HepMC/GenEvent.h" + +namespace Rivet { + + + // Convert the GenEvent to use conventional units (GeV, mm) + void _geNormUnits(GenEvent& ge) { + // Specify units if supported + #ifdef HEPMC_HAS_UNITS + ge.use_units(HepMC::Units::GEV, HepMC::Units::MM); + #endif + } + + + void _geRot180x(GenEvent& ge) { + for (HepMC::GenEvent::particle_iterator ip = ge.particles_begin(); ip != ge.particles_end(); ++ip) { + const HepMC::FourVector& mom = (*ip)->momentum(); + (*ip)->set_momentum(HepMC::FourVector(mom.px(), -mom.py(), -mom.pz(), mom.e())); + } + for (HepMC::GenEvent::vertex_iterator iv = ge.vertices_begin(); iv != ge.vertices_end(); ++iv) { + const HepMC::FourVector& pos = (*iv)->position(); + (*iv)->set_position(HepMC::FourVector(pos.x(), -pos.y(), -pos.z(), pos.t())); + } + } + + + // Convert the GenEvent to use conventional alignment + // (proton or electron on +ve z-axis?) + // For example, FHerwig only produces DIS events in the + // unconventional orientation and has to be corrected + void _geNormAlignment(GenEvent& ge) { + if (!ge.valid_beam_particles()) return; + typedef pair<HepMC::GenParticle*, HepMC::GenParticle*> GPPair; + GPPair bps = ge.beam_particles(); + const BeamPair beamids = make_pdgid_pair(bps.first->pdg_id(), bps.second->pdg_id()); + Log::getLog("Rivet.Event") << Log::TRACE << "Beam IDs: " << beamids << endl; + const HepMC::GenParticle* plusgp = 0; + bool rot = false; + + // Rotate e+- p and ppbar to put p along +z + /// @todo e+ e- convention? B-factories different from LEP? + // if (compatible(beamids, make_pdgid_pair(ELECTRON, PROTON)) || + // compatible(beamids, make_pdgid_pair(POSITRON, PROTON)) || + // compatible(beamids, make_pdgid_pair(ANTIPROTON, PROTON)) ) { + // Log::getLog("Rivet.Event") << Log::TRACE << "May need to rotate event..." << endl; + if (bps.first->pdg_id() != PROTON || bps.second->pdg_id() != PROTON) { + if (bps.first->pdg_id() == PROTON) { + plusgp = bps.first; + } else if (bps.second->pdg_id() == PROTON) { + plusgp = bps.second; + } + if (plusgp && plusgp->momentum().pz() < 0) { + rot = true; + } + } + + // Do the rotation + if (rot) { + if (Log::getLog("Rivet.Event").isActive(Log::TRACE)) { + Log::getLog("Rivet.Event") << Log::TRACE << "Rotating event" << endl; + Log::getLog("Rivet.Event") << Log::TRACE << "Before rotation: " + << bps.first->pdg_id() << "@pz=" << bps.first->momentum().pz()/GeV << ", " + << bps.second->pdg_id() << "@pz=" << bps.second->momentum().pz()/GeV << endl; + } + _geRot180x(ge); + } + } + + + Event::Event(const GenEvent& ge) + : _genEvent(ge), _weight(1.0) + { + // Set the weight if there is one, otherwise default to 1.0 + if (!_genEvent.weights().empty()) { + _weight = ge.weights()[0]; + } + + // Use Rivet's preferred units if possible + _geNormUnits(_genEvent); + + // Use the conventional alignment + _geNormAlignment(_genEvent); + + // Debug printout to check that copying/magling has worked + //_genEvent.print(); + } + + + Event::Event(const Event& e) + : _genEvent(e._genEvent), + _weight(e._weight) + { + // + } + + + Event& Event::operator=(const Event& e) { + _genEvent = e._genEvent; + _weight = e._weight; + return *this; + } + + +} Copied: trunk/src/Core/HistoHandler.cc (from r2120, trunk/src/HistoHandler.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/HistoHandler.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/HistoHandler.cc) @@ -0,0 +1,96 @@ +// -*- C++ -*- +#include "Rivet/Rivet.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/HistoHandler.hh" +#include "Rivet/Analysis.hh" +#include <algorithm> + +namespace Rivet { + + + // Initialize instance pointer to null. + HistoHandler* HistoHandler::_instance = 0; + + + HistoHandler* HistoHandler::create() { + if (!_instance) { + _instance = new HistoHandler(); + Log::getLog("Rivet.HistoHandler") + << Log::TRACE << "Created new HistoHandler at " + << _instance << endl; + } + return _instance; + } + + + // Get a logger. + Log& HistoHandler::getLog() const { + return Log::getLog("Rivet.HistoHandler"); + } + + + void HistoHandler::clear() { + _namedhistos.clear(); + } + + + // Delete contained pointers. + HistoHandler::~HistoHandler() { + clear(); + } + + + const AnalysisObject* HistoHandler::registerAnalysisObject(const Analysis& parent, + const AnalysisObject& ao, + const string& name) { + getLog() << Log::TRACE << "Trying to register" + << " analysis object " << &ao + << " for parent " << &parent << "(" << parent.name() << ")" + << " with name '" << name << "'" << endl; + + // If this name is already registered for this analysis, throw a complaint + NamedHistosMap::const_iterator nhs = _namedhistos.find(&parent); + if (nhs != _namedhistos.end()) { + NamedHistos::const_iterator nh = nhs->second.find(name); + if (nh != nhs->second.end()) { + stringstream ss; + ss << "Histogram \"" << name + << "\" already exists for parent analysis " << &parent; + throw Error(ss.str()); + } + } + + _namedhistos[&parent][name] = &ao; + //return *(_namedhistos[&parent][name]); + return const_cast<AnalysisObject*>(_namedhistos[&parent][name]); + } + + + + AnalysisObject* HistoHandler::_getAnalysisObject(const Analysis& parent, + const string& name) const { + getLog() << Log::TRACE << "Searching for child histo '" + << name << "' of " << &parent << endl; + + NamedHistosMap::const_iterator nhs = _namedhistos.find(&parent); + if (nhs == _namedhistos.end()) { + stringstream ss; + ss << "Couldn't find any histograms for parent analysis " << &parent; + throw Error(ss.str()); + } + + NamedHistos::const_iterator nh = nhs->second.find(name); + if (nh == nhs->second.end()) { + stringstream ss; + ss << "Couldn't find histogram \"" << name + << "\" for parent analysis " << &parent; + throw Error(ss.str()); + } + + //return *(nh->second); + AnalysisObject* rtn = const_cast<AnalysisObject*>(nh->second); + return rtn; + } + + +} Copied: trunk/src/Core/Jet.cc (from r2120, trunk/src/Jet.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Jet.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Jet.cc) @@ -0,0 +1,215 @@ +#include "Rivet/Jet.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/Tools/ParticleIdUtils.hh" +#include "Rivet/ParticleName.hh" + +namespace Rivet { + + + Jet::Jet() + : ParticleBase() + { + clear(); + } + + + Jet& Jet::setParticles(const vector<FourMomentum>& particles) { + _particles = particles; + _resetCaches(); + return *this; + } + + + Jet& Jet::addParticle(const FourMomentum& particle) { + _particles.push_back(particle); + _resetCaches(); + return *this; + } + + + Jet& Jet::addParticle(const Particle& particle) { + _fullParticles.push_back(particle); + _particles.push_back(particle.momentum()); + _resetCaches(); + return *this; + } + + + bool Jet::containsParticle(const Particle& particle) const { + const int barcode = particle.genParticle().barcode(); + foreach (const Particle& p, particles()) { + if (p.genParticle().barcode() == barcode) return true; + } + return false; + } + + + bool Jet::containsParticleId(PdgId pid) const { + foreach (const Particle& p, particles()) { + if (p.pdgId() == pid) return true; + } + return false; + } + + + bool Jet::containsParticleId(const vector<PdgId>& pids) const { + foreach (const Particle& p, particles()) { + foreach (PdgId pid, pids) { + if (p.pdgId() == pid) return true; + } + } + return false; + } + + + /// @todo Jet::containsMatch(Matcher m) { ... if m(pid) return true; ... } + + + double Jet::totalEnergy() const { + return momentum().E(); + } + + + double Jet::neutralEnergy() const { + double e_neutral = 0.0; + foreach (const Particle& p, particles()) { + const PdgId pid = p.pdgId(); + if (PID::threeCharge(pid) == 0) { + e_neutral += p.momentum().E(); + } + } + return e_neutral; + } + + + double Jet::hadronicEnergy() const { + double e_hadr = 0.0; + foreach (const Particle& p, particles()) { + const PdgId pid = p.pdgId(); + if (PID::isHadron(pid)) { + e_hadr += p.momentum().E(); + } + } + return e_hadr; + } + + + bool Jet::containsCharm() const { + foreach (const Particle& p, particles()) { + if (abs(p.pdgId()) == CQUARK) return true; + HepMC::GenVertex* gv = p.genParticle().production_vertex(); + if (gv) { + foreach (const GenParticle* pi, Rivet::particles(gv, HepMC::ancestors)) { + const PdgId pid = pi->pdg_id(); + if (PID::isHadron(pid) && PID::hasCharm(pid)) return true; + } + } + } + return false; + } + + + bool Jet::containsBottom() const { + foreach (const Particle& p, particles()) { + if (abs(p.pdgId()) == BQUARK) return true; + HepMC::GenVertex* gv = p.genParticle().production_vertex(); + if (gv) { + foreach (const GenParticle* pi, Rivet::particles(gv, HepMC::ancestors)) { + const PdgId pid = pi->pdg_id(); + if (PID::isHadron(pid) && PID::hasBottom(pid)) return true; + } + } + } + return false; + } + + + Jet& Jet::clear() { + _particles.clear(); + _fullParticles.clear(); + _resetCaches(); + return *this; + } + + + double Jet::ptWeightedEta() const { + _calcPtAvgs(); + assert(_okPtWeightedEta); + return _ptWeightedEta; + } + + + double Jet::ptWeightedPhi() const { + _calcPtAvgs(); + assert(_okPtWeightedPhi); + return _ptWeightedPhi; + } + + + double Jet::eta() const { + return momentum().eta(); + + } + + + double Jet::phi() const { + return momentum().phi(); + } + + + const FourMomentum& Jet::momentum() const { + _calcMomVector(); + return _momentum; + } + + + // FourMomentum& Jet::momentum() { + // _calcMomVector(); + // return _momentum; + // } + + + double Jet::ptSum() const { + return momentum().pT(); + } + + + double Jet::EtSum() const { + return momentum().Et(); + } + + + void Jet::_resetCaches() const { + _okPtWeightedPhi = false; + _okPtWeightedEta = false; + _okMomentum = false; + } + + + void Jet::_calcMomVector() const { + if (!_okMomentum) { + _momentum = accumulate(begin(), end(), FourMomentum()); + _okMomentum = true; + } + } + + + void Jet::_calcPtAvgs() const { + if (!_okPtWeightedEta || !_okPtWeightedPhi) { + double ptwetasum(0.0), ptwdphisum(0.0), ptsum(0.0); + double phi0 = phi(); + foreach (const FourMomentum& p, momenta()) { + double pt = p.pT(); + ptsum += pt; + ptwetasum += pt * p.pseudorapidity(); + ptwdphisum += pt * mapAngleMPiToPi(phi0 - p.azimuthalAngle()); + } + _ptWeightedEta = ptwetasum/ptsum; + _okPtWeightedEta = true; + _ptWeightedPhi = mapAngleMPiToPi(phi0 + ptwdphisum/ptsum); + _okPtWeightedPhi = true; + } + } + + +} Copied and modified: trunk/src/Core/Makefile.am (from r2121, trunk/src/Makefile.am) ============================================================================== --- trunk/src/Makefile.am Tue Dec 1 17:04:36 2009 (r2121, copy source) +++ trunk/src/Core/Makefile.am Tue Dec 1 19:39:13 2009 (r2122) @@ -1,24 +1,10 @@ -SUBDIRS = . Projections Tools Test -if ENABLE_ANALYSES -SUBDIRS += Analyses -endif +noinst_LTLIBRARIES = libRivetCore.la -lib_LTLIBRARIES = libRivet.la - -libRivet_la_SOURCES = \ +libRivetCore_la_SOURCES = \ Event.cc Jet.cc Particle.cc \ ProjectionApplier.cc Projection.cc \ Analysis.cc AnalysisLoader.cc AnalysisInfo.cc \ AnalysisHandler.cc Run.cc ProjectionHandler.cc HistoHandler.cc -libRivet_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/Tools/yaml-cpp $(CPPFLAGS) - -libRivet_la_LDFLAGS = -L$(prefix)/lib \ - -L$(GSLLIBPATH) -L$(GSLCBLASLIBPATH) -export-dynamic $(VERSIONINFOFLAGS) - -FASTJETLIBADD = $(FASTJETCONFIGLIBADD) - -libRivet_la_LIBADD = \ - Projections/libRivetProjections.la \ - Tools/libRivetTools.la -ldl -lm \ - $(GSL_LDFLAGS) $(FASTJETLIBADD) +libRivetCore_la_CPPFLAGS = \ + $(AM_CPPFLAGS) -I$(top_srcdir)/src/Tools/yaml-cpp $(CPPFLAGS) Copied: trunk/src/Core/Particle.cc (from r2120, trunk/src/Particle.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Particle.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Particle.cc) @@ -0,0 +1,16 @@ +#include "Rivet/Particle.hh" + +namespace Rivet { + + + bool Particle::hasAncestor(PdgId pdg_id) const { + GenVertex* prodVtx = genParticle().production_vertex(); + if (prodVtx == 0) return false; + foreach (const GenParticle* ancestor, particles(prodVtx, HepMC::ancestors)) { + if (ancestor->pdg_id() == pdg_id) return true; + } + return false; + } + + +} Copied: trunk/src/Core/Projection.cc (from r2120, trunk/src/Projection.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Projection.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Projection.cc) @@ -0,0 +1,63 @@ +// -*- C++ -*- +#include "Rivet/Projection.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/Event.hh" +#include "Rivet/Cmp.hh" + +namespace Rivet { + + + Projection::Projection() + : _name("BaseProjection") + { + addBeamPair(ANY, ANY); + getLog() << Log::TRACE << "Creating " << name() << " at " << this << endl; + } + + + Projection:: ~Projection() { + getLog() << Log::TRACE << "Destroying " << name() << " at " << this << endl; + } + + + // int Projection::compare(const Projection& p) const { + // return mkNamedPCmp(p, "FS"); + // } + + + bool Projection::before(const Projection& p) const { + const std::type_info& thisid = typeid(*this); + const std::type_info& otherid = typeid(p); + if (thisid == otherid) { + return compare(p) < 0; + } else { + return thisid.before(otherid); + } + } + + + const set<BeamPair> Projection::beamPairs() const { + set<BeamPair> ret = _beamPairs; + set<ConstProjectionPtr> projs = getProjections(); + for (set<ConstProjectionPtr>::const_iterator ip = projs.begin(); ip != projs.end(); ++ip) { + ConstProjectionPtr p = *ip; + getLog() << Log::TRACE << "Proj addr = " << p << endl; + if (p) ret = intersection(ret, p->beamPairs()); + } + return ret; + } + + + Cmp<Projection> Projection::mkNamedPCmp(const Projection& otherparent, + const string& pname) const { + return pcmp(*this, otherparent, pname); + } + + + Cmp<Projection> Projection::mkPCmp(const Projection& otherparent, + const string& pname) const { + return pcmp(*this, otherparent, pname); + } + + +} Copied: trunk/src/Core/ProjectionApplier.cc (from r2120, trunk/src/ProjectionApplier.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/ProjectionApplier.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/ProjectionApplier.cc) @@ -0,0 +1,45 @@ +// -*- C++ -*- +#include "Rivet/ProjectionApplier.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/Event.hh" + +namespace Rivet { + + + // NB. Allow proj registration in constructor by default -- explicitly disable for Analysis + ProjectionApplier::ProjectionApplier() + : _allowProjReg(true), + _projhandler(ProjectionHandler::create()) + { } + + + ProjectionApplier::~ProjectionApplier() { + getProjHandler().removeProjectionApplier(*this); + } + + + const Projection& ProjectionApplier::_applyProjection(const Event& evt, + const string& name) const { + return evt.applyProjection(getProjection(name)); + } + + + const Projection& ProjectionApplier::_applyProjection(const Event& evt, + const Projection& proj) const { + return evt.applyProjection(proj); + } + + + const Projection& ProjectionApplier::_addProjection(const Projection& proj, + const std::string& name) { + if (!_allowProjReg) { + getLog() << Log::ERROR << "Trying to register projection '" + << proj.name() << "' before init phase in '" << this->name() << "'." << endl; + exit(2); + } + const Projection& reg = getProjHandler().registerProjection(*this, proj, name); + return reg; + } + + +} Copied: trunk/src/Core/ProjectionHandler.cc (from r2120, trunk/src/ProjectionHandler.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/ProjectionHandler.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/ProjectionHandler.cc) @@ -0,0 +1,284 @@ +// -*- C++ -*- +#include "Rivet/Rivet.hh" +#include "Rivet/Tools/Logging.hh" +#include "Rivet/ProjectionHandler.hh" +#include "Rivet/Cmp.hh" +#include <algorithm> + +namespace Rivet { + + + // Initialize instance pointer to null. + ProjectionHandler* ProjectionHandler::_instance = 0; + + + //int Log_TRACE = Log::INFO; + + + ProjectionHandler* ProjectionHandler::create() { + if (!_instance) { + _instance = new ProjectionHandler(); + Log::getLog("Rivet.ProjectionHandler") + << Log::TRACE << "Created new ProjectionHandler at " << _instance << endl; + } + return _instance; + } + + + + // Get a logger. + Log& ProjectionHandler::getLog() const { + return Log::getLog("Rivet.ProjectionHandler"); + } + + + + void ProjectionHandler::clear() { + _projs.clear(); + _namedprojs.clear(); + } + + + + // Delete contained pointers. + ProjectionHandler::~ProjectionHandler() { + clear(); + } + + + + // Take a Projection, compare it to the others on record, and return (by + // reference) an equivalent Projection which is guaranteed to be the + // (persistent) version that will be applied to an event. + const Projection& ProjectionHandler::registerProjection(const ProjectionApplier& parent, + const Projection& proj, + const string& name) + { + getLog() << Log::TRACE << "Trying to register" + << " projection " << &proj << " (" << proj.name() << ")" + << " for parent " << &parent << " (" << parent.name() << ")" + << " with name '" << name << "'" << endl; + + // Check for duplicate use of "name" on "parent" + const bool dupOk = _checkDuplicate(parent, proj, name); + if (!dupOk) exit(1); + + // Choose which version of the projection to register with this parent and name + const Projection* p = _getEquiv(proj); + if (p == 0) { // a null pointer is a non-match + // If there is no equivalent projection, clone proj and use the clone for registering + p = _clone(parent, proj); + } + + // Do the registering + p = _register(parent, *p, name); + + // Return registered proj + return *p; + } + + + + + // Attach and retrieve a projection as a pointer. + const Projection* ProjectionHandler::registerProjection(const ProjectionApplier& parent, + const Projection* proj, + const string& name) { + if (proj == 0) return 0; + const Projection& p = registerProjection(parent, *proj, name); + return &p; + } + + + + // Clone neatly + const Projection* ProjectionHandler::_clone(const ProjectionApplier& parent, + const Projection& proj) + { + // Clone a new copy of the passed projection on the heap + getLog() << Log::TRACE << "Cloning projection " << proj.name() << " from " << &proj << endl; + const Projection* newproj = proj.clone(); + getLog() << Log::TRACE << "Cloned projection " << proj.name() << " at " << newproj << endl; + + // Copy all the child ProjHandles when cloning, since otherwise links to "stack parents" + // will be generated by their children, without any connection to the cloned parent + if (&proj != newproj) { + NamedProjsMap::const_iterator nps = _namedprojs.find(&proj); + if (nps != _namedprojs.end()) { + getLog() << Log::TRACE << "Cloning registered projections list: " + << &proj << " -> " << newproj << endl; + _namedprojs[newproj] = nps->second; + } + } + + return newproj; + } + + + + // Take a Projection, compare it to the others on record, and + // return (by reference) an equivalent Projection which is guaranteed to be + // the version that will be applied to an event. + const Projection* ProjectionHandler::_register(const ProjectionApplier& parent, + const Projection& proj, + const string& name) + { + ProjHandle ph(&proj); + getLog() << Log::TRACE << "Registering new projection at " << ph << endl; + + // Add the passed Projection to _projs + _projs.insert(ph); + + // Add the ProjApplier* => name location to the associative container + _namedprojs[&parent][name] = ph; + + return ph.get(); + } + + + + + // Try to find a equivalent projection in the system + const Projection* ProjectionHandler::_getEquiv(const Projection& proj) const + { + // Get class type using RTTI + const std::type_info& newtype = typeid(proj); + getLog() << Log::TRACE << "RTTI type of " << &proj << " is " << newtype.name() << endl; + + // Compare to ALL projections via _projs collection + getLog() << Log::TRACE << "Comparing " << &proj + << " with " << _projs.size() + << " registered projection" << (_projs.size() == 1 ? "" : "s") << endl; + foreach (const ProjHandle& ph, _projs) { + // Make sure the concrete types match, using RTTI. + const std::type_info& regtype = typeid(*ph); + getLog() << Log::TRACE << "RTTI type comparison with " << ph << ": " + << newtype.name() << " vs. " << regtype.name() << endl; + if (newtype != regtype) continue; + getLog() << Log::TRACE << "RTTI type matches with " << ph << endl; + + // Test for semantic match + if (pcmp(*ph, proj) != EQUIVALENT) { + getLog() << Log::TRACE << "Projections at " + << &proj << " and " << ph << " are not equivalent" << endl; + } else { + getLog() << Log::TRACE << "MATCH! Projections at " + << &proj << " and " << ph << " are equivalent" << endl; + return ph.get(); + } + } + + // If no match, just return a null pointer + return 0; + } + + + + string ProjectionHandler::_getStatus() const { + ostringstream msg; + msg << "Current projection hierarchy:" << endl; + foreach (const NamedProjsMap::value_type& nps, _namedprojs) { + //const string parentname = nps.first->name(); + msg << nps.first << endl; //"(" << parentname << ")" << endl; + foreach (const NamedProjs::value_type& np, nps.second) { + msg << " " << np.second << " (" << np.second->name() + << ", locally called '" << np.first << "')" << endl; + } + msg << endl; + } + return msg.str(); + } + + + + // Check that the same parent hasn't already used this name for something else + bool ProjectionHandler::_checkDuplicate(const ProjectionApplier& parent, + const Projection& proj, + const string& name) const + { + NamedProjsMap::const_iterator ipnps = _namedprojs.find(&parent); + if (ipnps != _namedprojs.end()) { + const NamedProjs pnps = ipnps->second; + const NamedProjs::const_iterator ipph = pnps.find(name); + if (ipph != pnps.end()) { + const ProjHandle pph = ipph->second; + getLog() << Log::ERROR << "Projection clash! " + << parent.name() << " (" << &parent << ") " + << "is trying to overwrite its registered '" << name << "' " + << "projection (" << pph << "=" + << pph->name() << ") with a non-equivalent projection " + << "(" << &proj << "=" << proj.name() << ")" << endl; + getLog() << Log::ERROR << _getStatus(); + return false; + } + } + return true; + } + + + + + void ProjectionHandler::removeProjectionApplier(ProjectionApplier& parent) { + NamedProjsMap::iterator npi = _namedprojs.find(&parent); + if (npi != _namedprojs.end()) _namedprojs.erase(npi); + // + const Projection* parentprojptr = dynamic_cast<Projection*>(&parent); + if (parentprojptr) { + ProjHandle parentph(parentprojptr); + ProjHandles::iterator pi = find(_projs.begin(), _projs.end(), parentph); + if (pi != _projs.end()) _projs.erase(pi); + } + } + + + + + set<const Projection*> ProjectionHandler::getChildProjections(const ProjectionApplier& parent, + ProjDepth depth) const + { + set<const Projection*> toplevel; + NamedProjs nps = _namedprojs.find(&parent)->second; + foreach (NamedProjs::value_type& np, nps) { + toplevel.insert(np.second.get()); + } + if (depth == SHALLOW) { + // Only return the projections directly contained within the top level + return toplevel; + } else { + // Return recursively built projection list + set<const Projection*> alllevels = toplevel; + foreach (const Projection* p, toplevel) { + set<const Projection*> allsublevels = getChildProjections(*p, DEEP); + alllevels.insert(allsublevels.begin(), allsublevels.end()); + } + return alllevels; + } + } + + + + + const Projection& ProjectionHandler::getProjection(const ProjectionApplier& parent, + const string& name) const { + getLog() << Log::TRACE << "Searching for child projection '" + << name << "' of " << &parent << endl; + NamedProjsMap::const_iterator nps = _namedprojs.find(&parent); + if (nps == _namedprojs.end()) { + ostringstream msg; + msg << "No projections registered for parent " << &parent; + throw Error(msg.str()); + } + NamedProjs::const_iterator np = nps->second.find(name); + if (np == nps->second.end()) { + ostringstream msg; + msg << "No projection '" << name << "' found for parent " << &parent; + throw Error(msg.str()); + } + // If it's registered with the projection handler, we must be able to safely + // dereference the Projection pointer to a reference... + return *(np->second); + } + + + +} Copied: trunk/src/Core/Run.cc (from r2120, trunk/src/Run.cc) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/src/Core/Run.cc Tue Dec 1 19:39:13 2009 (r2122, copy of r2120, trunk/src/Run.cc) @@ -0,0 +1,155 @@ +// -*- C++ -*- +#include "Rivet/Run.hh" +#include "Rivet/AnalysisHandler.hh" +#include "HepMC/IO_GenEvent.h" +#include "Rivet/Projections/Beam.hh" +#include <limits> + +namespace Rivet { + + + Run::Run(AnalysisHandler& ah) + : _ah(ah), _xs(-1.0) + { } + + + Run::~Run() { } + + + Run& Run::setCrossSection(const double xs) { + _xs = xs; + return *this; + } + + + Run& Run::setListAnalyses(const bool dolist) { + _listAnalyses = dolist; + return *this; + } + + + bool Run::prepareFile(const std::string& evtfile) { + if (evtfile == "-") { + _io.reset(new HepMC::IO_GenEvent(std::cin)); + } else { + // Ignore the HepMC::IO_GenEvent(filename, ios) constructor, since it's only available from HepMC 2.4 + _istr.reset(new std::fstream(evtfile.c_str(), std::ios::in)); + _io.reset(new HepMC::IO_GenEvent(*_istr)); + } + if (_io->rdstate() != 0) { + Log::getLog("Rivet.Run") << Log::ERROR << "Read error on file " << evtfile << endl; + return false; + } + + return true; + } + + + bool Run::processEvent(bool firstEvent) { + // Fill event and check for a bad read state + shared_ptr<GenEvent> evt; + evt.reset(new GenEvent()); + if (_io->rdstate() != 0 || !_io->fill_next_event(evt.get()) ) { + Log::getLog("Rivet.Run") << Log::DEBUG << "Read failed. End of file?" << endl; + return false; + } + + // Get beam details from first event, and ensure they match for all following events + if (evt->particles_size() != 0) { + const BeamPair beams = beamIds(*evt); + const double sqrts = Rivet::sqrtS(*evt); + Log::getLog("Rivet.Run") << Log::DEBUG << "Beams: " + << beams << " @ " << sqrts/GeV << " GeV" << endl; + if (firstEvent) { + _beams = beams; + _sqrts = sqrts; + Log::getLog("Rivet.Run") << Log::INFO << "First event beams: " + << this->beams() << " @ " << this->sqrtS()/GeV << " GeV" << endl; + } else { + if (beams != _beams || !fuzzyEquals(sqrts, sqrtS())) { + Log::getLog("Rivet.Run") << Log::ERROR << "Event beams mismatch: " + << beams << " @ " << sqrts/GeV << " GeV" << " vs. first beams " + << this->beams() << " @ " << this->sqrtS()/GeV << " GeV" << endl; + return false; + } + } + } + + // Set up system based on properties of first event + if (firstEvent) { + // If empty + if (evt->particles_size() == 0) { + Log::getLog("Rivet.Run") << Log::ERROR << "Empty first event." << endl; + return false; + } + + const size_t num_anas_requested = _ah.analysisNames().size(); + _ah.removeIncompatibleAnalyses(beams()); + if (num_anas_requested > 0 && _ah.analysisNames().size() == 0) { + Log::getLog("Rivet.Run") << Log::ERROR + << "All analyses were incompatible with the first event's beams\n" + << "Exiting, since this probably isn't intentional!" << endl; + return false; + } + + if (_listAnalyses) { + foreach (const std::string& ana, _ah.analysisNames()) { + cout << ana << endl; + } + } + + } + + + // Set cross-section if specified from command line + if (_xs > 0.0) { + if (firstEvent) { + Log::getLog("Rivet.Run") << Log::DEBUG + << "Setting user cross-section = " << _xs << " pb" << endl; + _ah.setCrossSection(_xs); + } + } + // Set cross-section if found in event + #ifdef HEPMC_HAS_CROSS_SECTION + else if (evt->cross_section()) { + const double xs = evt->cross_section()->cross_section(); //< in pb + Log::getLog("Rivet.Run") << Log::DEBUG + << "Setting cross-section = " << xs << " pb" << endl; + _ah.setCrossSection(xs); + } + #endif + // Complain about absence of cross-section if required! + else { + if (_ah.needCrossSection()) { + Log::getLog("Rivet.Run") << Log::ERROR + << "Total cross-section needed for at least one of the analyses. " + << "Please set it (on the command line with '-x' if using the 'rivet' program)" << endl; + return false; + } + } + + /// @todo If NOT first event, check that beams aren't changed + + // Analyze event + _ah.analyze(*evt); + + return true; + } + + + bool Run::finalizeFile() { + return true; + } + + + const BeamPair& Run::beams() const { + return _beams; + } + + + double Run::sqrtS() const { + return _sqrts; + } + + +} Modified: trunk/src/Makefile.am ============================================================================== --- trunk/src/Makefile.am Tue Dec 1 17:04:36 2009 (r2121) +++ trunk/src/Makefile.am Tue Dec 1 19:39:13 2009 (r2122) @@ -1,24 +1,21 @@ -SUBDIRS = . Projections Tools Test +SUBDIRS = Core Projections Tools . if ENABLE_ANALYSES SUBDIRS += Analyses endif +SUBDIRS += Test -lib_LTLIBRARIES = libRivet.la +lib_LTLIBRARIES = libRivet.la -libRivet_la_SOURCES = \ - Event.cc Jet.cc Particle.cc \ - ProjectionApplier.cc Projection.cc \ - Analysis.cc AnalysisLoader.cc AnalysisInfo.cc \ - AnalysisHandler.cc Run.cc ProjectionHandler.cc HistoHandler.cc +libRivet_la_SOURCES = -libRivet_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/Tools/yaml-cpp $(CPPFLAGS) - -libRivet_la_LDFLAGS = -L$(prefix)/lib \ - -L$(GSLLIBPATH) -L$(GSLCBLASLIBPATH) -export-dynamic $(VERSIONINFOFLAGS) - -FASTJETLIBADD = $(FASTJETCONFIGLIBADD) +libRivet_la_LDFLAGS = \ + -L$(prefix)/lib \ + -L$(GSLLIBPATH) -L$(GSLCBLASLIBPATH) \ + -export-dynamic $(VERSIONINFOFLAGS) libRivet_la_LIBADD = \ + Core/libRivetCore.la \ Projections/libRivetProjections.la \ - Tools/libRivetTools.la -ldl -lm \ - $(GSL_LDFLAGS) $(FASTJETLIBADD) + Tools/libRivetTools.la \ + -ldl -lm \ + $(GSL_LDFLAGS) $(FASTJETCONFIGLIBADD)
More information about the Rivet-svn mailing list |