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 
00054   bool Run::openFile(const std::string& evtfile, double weight) {
00055     // Set current weight-scaling member
00056     _fileweight = weight;
00057 
00058     // Set up HepMC input reader objects
00059     if (evtfile == "-") {
00060       _io.reset(new HepMC::IO_GenEvent(std::cin));
00061     } else {
00062       // Ignore the HepMC::IO_GenEvent(filename, ios) constructor, since it's only available from HepMC 2.4
00063       _istr.reset(new std::fstream(evtfile.c_str(), std::ios::in));
00064       _io.reset(new HepMC::IO_GenEvent(*_istr));
00065     }
00066     if (_io->rdstate() != 0) {
00067       Log::getLog("Rivet.Run") << Log::ERROR << "Read error on file " << evtfile << endl;
00068       return false;
00069     }
00070     return true;
00071   }
00072 
00073 
00074   bool Run::init(const std::string& evtfile, double weight) {
00075     if (!openFile(evtfile, weight)) return false;
00076 
00077     // Read first event to define run conditions
00078     bool ok = readEvent();
00079     if (!ok) return false;
00080     if (_evt->particles_size() == 0) {
00081       Log::getLog("Rivet.Run") << Log::ERROR << "Empty first event." << endl;
00082       return false;
00083     }
00084 
00085     // Initialise AnalysisHandler with beam information from first event
00086     _ah.init(*_evt);
00087 
00088     // Set cross-section from command line
00089     if (_xs >= 0.0) {
00090       Log::getLog("Rivet.Run")
00091         << Log::DEBUG << "Setting user cross-section = " << _xs << " pb" << endl;
00092       _ah.setCrossSection(_xs);
00093     }
00094 
00095     // List the chosen & compatible analyses if requested
00096     if (_listAnalyses) {
00097       foreach (const std::string& ana, _ah.analysisNames()) {
00098         cout << ana << endl;
00099       }
00100     }
00101 
00102     return true;
00103   }
00104 
00105 
00106   bool Run::processEvent() {
00107     // Set cross-section if found in event and not from command line
00108     #ifdef HEPMC_HAS_CROSS_SECTION
00109     if (std::isnan(_xs) && _evt->cross_section()) {
00110       const double xs = _evt->cross_section()->cross_section(); //< in pb
00111       Log::getLog("Rivet.Run")
00112         << Log::DEBUG << "Setting cross-section = " << xs << " pb" << endl;
00113       _ah.setCrossSection(xs);
00114     }
00115     #endif
00116     // Complain about absence of cross-section if required!
00117     if (_ah.needCrossSection() && !_ah.hasCrossSection()) {
00118       Log::getLog("Rivet.Run")
00119         << Log::ERROR
00120         << "Total cross-section needed for at least one of the analyses. "
00121         << "Please set it (on the command line with '-x' if using the 'rivet' program)" << endl;
00122       return false;
00123     }
00124 
00125     // Analyze event
00126     _ah.analyze(*_evt);
00127 
00128     return true;
00129   }
00130 
00131 
00132   bool Run::finalize() {
00133     _evt.reset();
00134     _istr.reset();
00135     _io.reset();
00136     return true;
00137   }
00138 
00139 
00140 
00141 
00142 }