rivet is hosted by Hepforge, IPPP Durham
Run.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Run.hh"
00003 #include "Rivet/AnalysisHandler.hh"
00004 #include "HepMC/IO_GenEvent.h"
00005 #include "Rivet/Math/MathUtils.hh"
00006 #include <limits>
00007 
00008 namespace Rivet {
00009 
00010 
00011   Run::Run(AnalysisHandler& ah)
00012     : _ah(ah), _fileweight(1.0), _xs(NAN)
00013   { }
00014 
00015 
00016   Run::~Run() { }
00017 
00018 
00019   Run& Run::setCrossSection(const double xs) {
00020     _xs = xs;
00021     return *this;
00022   }
00023 
00024 
00025   double Run::crossSection() const {
00026     return _ah.crossSection();
00027   }
00028 
00029 
00030   Run& Run::setListAnalyses(const bool dolist) {
00031     _listAnalyses = dolist;
00032     return *this;
00033   }
00034 
00035 
00036   // Fill event and check for a bad read state
00037   bool Run::readEvent() {
00038     /// @todo Clear rather than new the GenEvent object per-event?
00039     _evt.reset(new GenEvent());
00040     if (_io->rdstate() != 0 || !_io->fill_next_event(_evt.get()) ) {
00041       Log::getLog("Rivet.Run") << Log::DEBUG << "Read failed. End of file?" << endl;
00042       return false;
00043     }
00044     // Rescale event weights by file-level weight, if scaling is non-trivial
00045     if (!fuzzyEquals(_fileweight, 1.0)) {
00046       for (size_t i = 0; i < (size_t) _evt->weights().size(); ++i) {
00047         _evt->weights()[i] *= _fileweight;
00048       }
00049     }
00050     return true;
00051   }
00052   
00053   // Fill event and check for a bad read state --- to skip, maybe HEPMC3 will have a better way
00054   bool Run::skipEvent() {
00055     if (_io->rdstate() != 0 || !_io->fill_next_event(_evt.get()) ) {
00056       Log::getLog("Rivet.Run") << Log::DEBUG << "Read failed. End of file?" << endl;
00057       return false;
00058     }
00059     return true;
00060   }
00061 
00062 
00063   bool Run::openFile(const std::string& evtfile, double weight) {
00064     // Set current weight-scaling member
00065     _fileweight = weight;
00066 
00067     // Set up HepMC input reader objects
00068     if (evtfile == "-") {
00069       _io.reset(new HepMC::IO_GenEvent(std::cin));
00070     } else {
00071       // Ignore the HepMC::IO_GenEvent(filename, ios) constructor, since it's only available from HepMC 2.4
00072       _istr.reset(new std::fstream(evtfile.c_str(), std::ios::in));
00073       _io.reset(new HepMC::IO_GenEvent(*_istr));
00074     }
00075     if (_io->rdstate() != 0) {
00076       Log::getLog("Rivet.Run") << Log::ERROR << "Read error on file " << evtfile << endl;
00077       return false;
00078     }
00079     return true;
00080   }
00081 
00082 
00083   bool Run::init(const std::string& evtfile, double weight) {
00084     if (!openFile(evtfile, weight)) return false;
00085 
00086     // Read first event to define run conditions
00087     bool ok = readEvent();
00088     if (!ok) return false;
00089     if (_evt->particles_size() == 0) {
00090       Log::getLog("Rivet.Run") << Log::ERROR << "Empty first event." << endl;
00091       return false;
00092     }
00093 
00094     // Initialise AnalysisHandler with beam information from first event
00095     _ah.init(*_evt);
00096 
00097     // Set cross-section from command line
00098     if (!std::isnan(_xs)) {
00099       Log::getLog("Rivet.Run")
00100         << Log::DEBUG << "Setting user cross-section = " << _xs << " pb" << endl;
00101       _ah.setCrossSection(_xs);
00102     }
00103 
00104     // List the chosen & compatible analyses if requested
00105     if (_listAnalyses) {
00106       foreach (const std::string& ana, _ah.analysisNames()) {
00107         cout << ana << endl;
00108       }
00109     }
00110 
00111     return true;
00112   }
00113 
00114 
00115   bool Run::processEvent() {
00116     // Set cross-section if found in event and not from command line
00117     #ifdef HEPMC_HAS_CROSS_SECTION
00118     if (std::isnan(_xs) && _evt->cross_section()) {
00119       const double xs = _evt->cross_section()->cross_section(); ///< in pb
00120       Log::getLog("Rivet.Run")
00121         << Log::DEBUG << "Setting cross-section = " << xs << " pb" << endl;
00122       _ah.setCrossSection(xs);
00123     }
00124     #endif
00125     // Complain about absence of cross-section if required!
00126     if (_ah.needCrossSection() && !_ah.hasCrossSection()) {
00127       Log::getLog("Rivet.Run")
00128         << Log::ERROR
00129         << "Total cross-section needed for at least one of the analyses. "
00130         << "Please set it (on the command line with '-x' if using the 'rivet' program)" << endl;
00131       return false;
00132     }
00133 
00134     // Analyze event
00135     _ah.analyze(*_evt);
00136 
00137     return true;
00138   }
00139 
00140 
00141   bool Run::finalize() {
00142     _evt.reset();
00143     _istr.reset();
00144     _io.reset();
00145 
00146     if (!std::isnan(_xs)) _ah.setCrossSection(_xs);
00147     _ah.finalize();
00148 
00149     return true;
00150   }
00151 
00152 
00153 
00154 
00155 }