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