diff --git a/Analysis/RivetAnalysis.cc b/Analysis/RivetAnalysis.cc --- a/Analysis/RivetAnalysis.cc +++ b/Analysis/RivetAnalysis.cc @@ -1,192 +1,211 @@ // -*- C++ -*- // // This is the implementation of the non-inlined, non-templated member // functions of the RivetAnalysis class. // #include #include "ThePEG/Interface/Interfaced.h" #include "ThePEG/Interface/ClassDocumentation.h" #include "ThePEG/Interface/ParVector.h" #include "ThePEG/Interface/Parameter.h" #include "ThePEG/Interface/Switch.h" #include "ThePEG/Persistency/PersistentOStream.h" #include "ThePEG/Persistency/PersistentIStream.h" #include "ThePEG/Vectors/HepMCConverter.h" #include "ThePEG/Config/HepMCHelper.h" #include "ThePEG/Repository/EventGenerator.h" #include "ThePEG/Repository/CurrentGenerator.h" #include "RivetAnalysis.h" #include "Rivet/AnalysisHandler.hh" #include "Rivet/Tools/RivetPaths.hh" #include "Rivet/Tools/Logging.hh" +#include "ThePEG/Utilities/DescribeClass.h" using namespace ThePEG; -RivetAnalysis::RivetAnalysis() : debug(false), _rivet(), _nevent(0) +RivetAnalysis::RivetAnalysis() : _debug(false), _rivet(), _nevent(0) {} void RivetAnalysis::analyze(ThePEG::tEventPtr event, long ieve, int loop, int state) { ++_nevent; AnalysisHandler::analyze(event, ieve, loop, state); // Rotate to CMS, extract final state particles and call analyze(particles). // convert to hepmc HepMC::GenEvent * hepmc = ThePEG::HepMCConverter::convert(*event); // analyse the event if(_nevent>1) CurrentGenerator::Redirect stdout(cout); if ( _rivet ){ #if ThePEG_RIVET_VERSION > 1 try { _rivet->analyze(*hepmc); } catch (const YODA::Exception & e) { Throw() << "Warning: Rivet/Yoda got the exception: "<< e.what()<<"\n" << Exception::warning; } #else #error "Unknown ThePEG_RIVET_VERSION" #endif } if(_nevent<=1) { // check that analysis list is still available if ( _rivet->analysisNames().size() != _analyses.size() ) { throw ThePEG::Exception() << "Rivet could not find all requested analyses.\n" << "Use 'rivet --list-analyses' to check availability.\n" << ThePEG::Exception::runerror; } } // delete hepmc event delete hepmc; } ThePEG::IBPtr RivetAnalysis::clone() const { return new_ptr(*this); } ThePEG::IBPtr RivetAnalysis::fullclone() const { return new_ptr(*this); } void RivetAnalysis::persistentOutput(ThePEG::PersistentOStream & os) const { - os << _analyses << _paths << filename << debug; + os << _analyses << _preload << _paths << _filename << _debug; } void RivetAnalysis::persistentInput(ThePEG::PersistentIStream & is, int) { - is >> _analyses >> _paths >> filename >> debug; + is >> _analyses >> _preload >> _paths >> _filename >> _debug; } -ThePEG::ClassDescription RivetAnalysis::initRivetAnalysis; -// Definition of the static class description member. +// The following static variable is needed for the type +// description system in ThePEG. +DescribeClass +describeRivetAnalysis("ThePEG::RivetAnalysis", "RivetAnalysis.so"); void RivetAnalysis::Init() { static ThePEG::ClassDocumentation documentation ("The RivetAnalysis class is a simple class to allow analyses" " from the Rivet library to be called from ThePEG"); static ThePEG::ParVector interfaceAnalyses ("Analyses", "The names of the Rivet analyses to use", &RivetAnalysis::_analyses, -1, "", "","" "", false, false, ThePEG::Interface::nolimits); + static ParVector interfacePreLoad + ("PreLoad", + "The yoda files to be preloaded", + &RivetAnalysis::_preload, -1, "", "", "", + false, false, Interface::nolimits); + static ThePEG::ParVector interfacePaths ("Paths", "The directory paths where Rivet should look for analyses.", &RivetAnalysis::_paths, -1, "", "","" "", false, false, ThePEG::Interface::nolimits); static Parameter interfaceFilename ("Filename", #if ThePEG_RIVET_VERSION > 1 "The name of the file where the YODA histograms are put. If empty, " "the run name will be used instead. '.yoda' will in any case be " "appended to the file name.", #else #error "Unknown ThePEG_RIVET_VERSION" #endif - &RivetAnalysis::filename, "", true, false); + &RivetAnalysis::_filename, "", true, false); static Switch interfaceDebug ("Debug", "Enable debug information from Rivet", - &RivetAnalysis::debug, false, true, false); + &RivetAnalysis::_debug, false, true, false); static SwitchOption interfaceDebugNo (interfaceDebug, "No", "Disable debug information.", false); static SwitchOption interfaceDebugYes (interfaceDebug, "Yes", "Enable debug information from Rivet.", true); interfaceAnalyses.rank(10); } void RivetAnalysis::dofinish() { AnalysisHandler::dofinish(); if( _nevent > 0 && _rivet ) { CurrentGenerator::Redirect stdout(cout); #if ThePEG_RIVET_VERSION > 2 _rivet->setCrossSection(make_pair(generator()->integratedXSec()/picobarn, generator()->integratedXSecErr()/picobarn)); #else _rivet->setCrossSection(generator()->integratedXSec()/picobarn); #endif _rivet->finalize(); - string fname = filename; + string fname = _filename; #if ThePEG_RIVET_VERSION > 1 if ( fname.empty() ) fname = generator()->path() + "/" + generator()->runName() + ".yoda"; #else #error "Unknown ThePEG_RIVET_VERSION" #endif _rivet->writeData(fname); } delete _rivet; _rivet = nullptr; } void RivetAnalysis::doinit() { AnalysisHandler::doinit(); if(_analyses.empty()) throw ThePEG::Exception() << "Must have at least one analysis loaded in " << "RivetAnalysis::doinitrun()" << ThePEG::Exception::runerror; // check that analysis list is available _rivet = new Rivet::AnalysisHandler; //(fname); for ( int i = 0, N = _paths.size(); i < N; ++i ) Rivet::addAnalysisLibPath(_paths[i]); _rivet->addAnalyses(_analyses); if ( _rivet->analysisNames().size() != _analyses.size() ) { throw ThePEG::Exception() << "Rivet could not find all requested analyses.\n" << "Use 'rivet --list-analyses' to check availability.\n" << ThePEG::Exception::runerror; } delete _rivet; _rivet = 0; } void RivetAnalysis::doinitrun() { AnalysisHandler::doinitrun(); // create Rivet analysis handler CurrentGenerator::Redirect stdout(cout); - _rivet = new Rivet::AnalysisHandler; //(fname); + _rivet = new Rivet::AnalysisHandler; for ( int i = 0, N = _paths.size(); i < N; ++i ) Rivet::addAnalysisLibPath(_paths[i]); _rivet->addAnalyses(_analyses); // check that analysis list is still available if ( _rivet->analysisNames().size() != _analyses.size() ) { throw ThePEG::Exception() << "Rivet could not find all requested analyses.\n" << "Use 'rivet --list-analyses' to check availability.\n" << ThePEG::Exception::runerror; } - if ( debug ) + // preload files +#if ThePEG_RIVET_VERSION > 2 + for(string fname : _preload) { + _rivet->readData(fname); + } +#else + if(!_preload.empty()) + throw Exception() << "You have requested yoda files are preloaded by Rivet but this only supported for Rivet 3 and above"; +#endif + // debugging + if ( _debug ) Rivet::Log::setLevel("Rivet",Rivet::Log::DEBUG); } diff --git a/Analysis/RivetAnalysis.h b/Analysis/RivetAnalysis.h --- a/Analysis/RivetAnalysis.h +++ b/Analysis/RivetAnalysis.h @@ -1,201 +1,171 @@ // -*- C++ -*- #ifndef THEPEG_RivetAnalysis_H #define THEPEG_RivetAnalysis_H // // This is the declaration of the RivetAnalysis class. // #include "ThePEG/Handlers/AnalysisHandler.h" #include "Rivet/AnalysisHandler.hh" namespace ThePEG { /** * Here is the documentation of the RivetAnalysis class. * * @see \ref RivetAnalysisInterfaces "The interfaces" * defined for RivetAnalysis. */ class RivetAnalysis: public ThePEG::AnalysisHandler { public: /** * The default constructor. */ RivetAnalysis(); public: /** @name Virtual functions required by the AnalysisHandler class. */ //@{ /** * Analyze a given Event. Note that a fully generated event * may be presented several times, if it has been manipulated in * between. The default version of this function will call transform * to make a lorentz transformation of the whole event, then extract * all final state particles and call analyze(tPVector) of this * analysis object and those of all associated analysis objects. The * default version will not, however, do anything on events which * have not been fully generated, or have been manipulated in any * way. * @param event pointer to the Event to be analyzed. * @param ieve the event number. * @param loop the number of times this event has been presented. * If negative the event is now fully generated. * @param state a number different from zero if the event has been * manipulated in some way since it was last presented. */ virtual void analyze(ThePEG::tEventPtr event, long ieve, int loop, int state); //@} public: /** @name Functions used by the persistent I/O system. */ //@{ /** * Function used to write out object persistently. * @param os the persistent output stream written to. */ void persistentOutput(ThePEG::PersistentOStream & os) const; /** * Function used to read in object persistently. * @param is the persistent input stream read from. * @param version the version number of the object when written. */ void persistentInput(ThePEG::PersistentIStream & is, int version); //@} /** * The standard Init function used to initialize the interfaces. * Called exactly once for each class by the class description system * before the main function starts or * when this class is dynamically loaded. */ static void Init(); protected: /** @name Clone Methods. */ //@{ /** * Make a simple clone of this object. * @return a pointer to the new object. */ virtual ThePEG::IBPtr clone() const; /** Make a clone of this object, possibly modifying the cloned object * to make it sane. * @return a pointer to the new object. */ virtual ThePEG::IBPtr fullclone() const; //@} protected: /** @name Standard Interfaced functions. */ //@{ /** * Initialize this object. Called in the read phase. */ virtual void doinit(); /** * Initialize this object. Called in the run phase just before * a run begins. */ virtual void doinitrun(); /** * Finalize this object. Called in the run phase just after a * run has ended. Used eg. to write out statistics. */ virtual void dofinish(); //@} private: /** * The static object used to initialize the description of this class. * Indicates that this is a concrete class with persistent data. */ static ThePEG::ClassDescription initRivetAnalysis; /** * The assignment operator is private and must never be called. * In fact, it should not even be implemented. */ RivetAnalysis & operator=(const RivetAnalysis &) = delete; private: /** * The Analyses to use */ vector _analyses; /** + * Yoda files to be preloaded + */ + vector _preload; + + /** * Search paths for finding rivet analyses. */ vector _paths; /** * The base name of the output file. */ - string filename; + string _filename; /** * Enable debugging information from Rivet */ - bool debug; + bool _debug; /** * The RivetAnalysisHandler */ Rivet::AnalysisHandler * _rivet; /** * Event count */ unsigned long _nevent; }; } -#include "ThePEG/Utilities/ClassTraits.h" - -namespace ThePEG { - -/** @cond TRAITSPECIALIZATIONS */ - -/** This template specialization informs ThePEG about the - * base classes of RivetAnalysis. */ -template <> -struct BaseClassTrait { - /** Typedef of the first base class of RivetAnalysis. */ - typedef AnalysisHandler NthBase; -}; - -/** This template specialization informs ThePEG about the name of - * the RivetAnalysis class and the shared object where it is defined. */ -template <> -struct ClassTraits - : public ClassTraitsBase { - /** Return a platform-independent class name */ - static string className() { return "ThePEG::RivetAnalysis"; } - /** - * The name of a file containing the dynamic library where the class - * RivetAnalysis is implemented. It may also include several, space-separated, - * libraries if the class RivetAnalysis depends on other classes (base classes - * excepted). In this case the listed libraries will be dynamically - * linked in the order they are specified. - */ - static string library() { return "RivetAnalysis.so"; } -}; - -/** @endcond */ - -} - #endif /* THEPEG_RivetAnalysis_H */