rivet is hosted by Hepforge, IPPP Durham
AnalysisHandler Class Reference

#include <AnalysisHandler.hh>

Collaboration diagram for AnalysisHandler:

List of all members.

Public Member Functions

Constructors and destructors. */
 AnalysisHandler (const string &runname="")
 Preferred constructor, with optional run name.
 ~AnalysisHandler ()
 Destructor The destructor is not virtual, as this class should not be inherited from.
Handle analyses
std::vector< std::string > analysisNames () const
 Get a list of the currently registered analyses' names.
const std::set< AnaHandle,
CmpAnaHandle > & 
analyses () const
 Get the collection of currently registered analyses.
AnalysisHandleraddAnalysis (const std::string &analysisname)
AnalysisHandlerremoveAnalysis (const std::string &analysisname)
 Remove an analysis from the run list using its name.
AnalysisHandleraddAnalyses (const std::vector< std::string > &analysisnames)
AnalysisHandlerremoveAnalyses (const std::vector< std::string > &analysisnames)
 Remove analyses from the run list using their names.
AnalysisHandleraddAnalysis (Analysis *analysis)
 Add an analysis to the run list by object.
Main init/execute/finalise
void init (const GenEvent &event)
 Initialize a run, with the run beams taken from the example event.
void analyze (const GenEvent &event)
void finalize ()
Histogram / data object access
std::vector< AnalysisObjectPtrgetData () const
 Get all analyses' plots as a vector of analysis objects.
void writeData (const std::string &filename) const
 Write all analyses' plots to the named file.

Private Member Functions

LoggetLog () const
 Get a logger object.
AnalysisHandleroperator= (const AnalysisHandler &)
 AnalysisHandler (const AnalysisHandler &)

Private Attributes

set< AnaHandle, CmpAnaHandle_analyses
 The collection of Analysis objects to be used.

Run properties

std::string _runname
 Run name.
unsigned int _numEvents
double _sumOfWeights
double _sumOfWeightsSq
double _xs
 Cross-section known to AH.
double _xserr
ParticlePair _beams
 Beams used by this run.
bool _initialised
 Flag to check if init has been called.
bool _ignoreBeams
 Flag whether input event beams should be ignored in compatibility check.
string runName () const
 Get the name of this run.
size_t numEvents () const
double sumOfWeights () const
void setSumOfWeights (const double &sum)
bool needCrossSection () const
 Is cross-section information required by at least one child analysis?
AnalysisHandlersetCrossSection (double xs)
 Set the cross-section for the process being generated.
double crossSection () const
 Get the cross-section known to the handler.
bool hasCrossSection () const
 Whether the handler knows about a cross-section.
AnalysisHandlersetRunBeams (const ParticlePair &beams)
 Set beams for this run.
const ParticlePairbeams () const
 Get beam IDs for this run, usually determined from the first event.
PdgIdPair beamIds () const
 Get beam IDs for this run, usually determined from the first event.
double sqrtS () const
 Get energy for this run, usually determined from the first event.
void setIgnoreBeams (bool ignore=true)
 Setter for _ignoreBeams.

Detailed Description

A class which handles a number of analysis objects to be applied to generated events. An Analysis' AnalysisHandler is also responsible for handling the final writing-out of histograms.

Definition at line 29 of file AnalysisHandler.hh.


Constructor & Destructor Documentation

AnalysisHandler ( const string &  runname = "")

Preferred constructor, with optional run name.

Definition at line 22 of file AnalysisHandler.cc.

    : _runname(runname), _numEvents(0),
      _sumOfWeights(0.0), _xs(NAN),
      _initialised(false), _ignoreBeams(false)
  {}

Destructor The destructor is not virtual, as this class should not be inherited from.

Definition at line 29 of file AnalysisHandler.cc.

  {}
AnalysisHandler ( const AnalysisHandler ) [private]

The copy constructor is private and must never be called. In fact, it should not even be implemented.


Member Function Documentation

AnalysisHandler & addAnalyses ( const std::vector< std::string > &  analysisnames)

Add analyses to the run list using their names. The actual Analysis' to be used will be obtained via AnalysisHandler::addAnalysis(string), which in turn uses AnalysisHandler::getAnalysis(string). If no matching analysis is found for a given name, no analysis is added, but also no error is thrown.

Definition at line 263 of file AnalysisHandler.cc.

References AnalysisHandler::addAnalysis().

                                                                                         {
    foreach (const string& aname, analysisnames) {
      //MSG_DEBUG("Adding analysis '" << aname << "'");
      addAnalysis(aname);
    }
    return *this;
  }
AnalysisHandler & addAnalysis ( const std::string &  analysisname)

Add an analysis to the run list using its name. The actual Analysis to be used will be obtained via AnalysisHandler::getAnalysis(string). If no matching analysis is found, no analysis is added (i.e. the null pointer is checked and discarded.

Todo:
Might we want to be able to run an analysis twice, with different params? Requires avoiding histo tree clashes, i.e. storing the histos on the analysis objects.

Definition at line 173 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, AnalysisLoader::getAnalysis(), MSG_DEBUG, and MSG_WARNING.

Referenced by AnalysisHandler::addAnalyses().

                                                                          {
    // Check for a duplicate analysis
    /// @todo Might we want to be able to run an analysis twice, with different params?
    ///       Requires avoiding histo tree clashes, i.e. storing the histos on the analysis objects.
    foreach (const AnaHandle& a, _analyses) {
      if (a->name() == analysisname) {
        MSG_WARNING("Analysis '" << analysisname << "' already registered: skipping duplicate");
        return *this;
      }
    }
    AnaHandle analysis( AnalysisLoader::getAnalysis(analysisname) );
    if (analysis.get() != 0) { // < Check for null analysis.
      MSG_DEBUG("Adding analysis '" << analysisname << "'");
      analysis->_analysishandler = this;
      _analyses.insert(analysis);
    } else {
      MSG_WARNING("Analysis '" << analysisname << "' not found.");
    }
    // MSG_WARNING(_analyses.size());
    // foreach (const AnaHandle& a, _analyses) MSG_WARNING(a->name());
    return *this;
  }

Add an analysis to the run list by object.

Definition at line 301 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, and Analysis::_analysishandler.

                                                                  {
    analysis->_analysishandler = this;
    _analyses.insert(AnaHandle(analysis));
    return *this;
  }
const std::set<AnaHandle, CmpAnaHandle>& analyses ( ) const [inline]

Get the collection of currently registered analyses.

Definition at line 121 of file AnalysisHandler.hh.

References AnalysisHandler::_analyses.

Referenced by AnalysisHandler::getData(), and AnalysisHandler::init().

                                                            {
      return _analyses;
    }
std::vector< std::string > analysisNames ( ) const

Get a list of the currently registered analyses' names.

Definition at line 254 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses.

Referenced by Run::init(), and AnalysisHandler::init().

                                                            {
    std::vector<std::string> rtn;
    foreach (AnaHandle a, _analyses) {
      rtn.push_back(a->name());
    }
    return rtn;
  }
void analyze ( const GenEvent &  event)

Analyze the given event. This function will call the AnalysisBase::analyze() function of all included analysis objects.

Todo:
Filter/normalize the event here
Todo:
Drop this / just report first weight when we support multiweight events

Definition at line 98 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, AnalysisHandler::_beams, AnalysisHandler::_initialised, AnalysisHandler::_numEvents, AnalysisHandler::_sumOfWeights, AnalysisHandler::_sumOfWeightsSq, AnalysisHandler::_xs, AnalysisHandler::_xserr, AnalysisHandler::beamIds(), AnalysisHandler::beams(), Rivet::compatible(), Rivet::fuzzyEquals(), Rivet::GeV, AnalysisHandler::init(), MSG_DEBUG, MSG_TRACE, Rivet::sqr(), AnalysisHandler::sqrtS(), Rivet::PID::toBeamsString(), and Event::weight().

Referenced by Run::processEvent().

                                                  {
    // Call init with event as template if not already initialised
    if (!_initialised) init(ge);
    assert(_initialised);

    // Ensure that beam details match those from the first event
    const PdgIdPair beams = Rivet::beamIds(ge);
    const double sqrts = Rivet::sqrtS(ge);
    if (!compatible(beams, _beams) || !fuzzyEquals(sqrts, sqrtS())) {
      cerr << "Event beams mismatch: "
           << PID::toBeamsString(beams) << " @ " << sqrts/GeV << " GeV" << " vs. first beams "
           << this->beams() << " @ " << this->sqrtS()/GeV << " GeV" << endl;
      exit(1);
    }

    // Create the Rivet event wrapper
    /// @todo Filter/normalize the event here
    Event event(ge);

    // Weights
    /// @todo Drop this / just report first weight when we support multiweight events
    _numEvents += 1;
    _sumOfWeights += event.weight();
    _sumOfWeightsSq += sqr(event.weight());
    MSG_DEBUG("Event #" << _numEvents << " weight = " << event.weight());

    // Cross-section
    #ifdef HEPMC_HAS_CROSS_SECTION
    if (ge.cross_section()) {
      _xs = ge.cross_section()->cross_section();
      _xserr = ge.cross_section()->cross_section_error();
    }
    #endif

    // Run the analyses
    foreach (AnaHandle a, _analyses) {
      MSG_TRACE("About to run analysis " << a->name());
      try {
        a->analyze(event);
      } catch (const Error& err) {
        cerr << "Error in " << a->name() << "::analyze method: " << err.what() << endl;
        exit(1);
      }
      MSG_TRACE("Finished running analysis " << a->name());
    }
  }
PdgIdPair beamIds ( ) const

Get beam IDs for this run, usually determined from the first event.

Definition at line 308 of file AnalysisHandler.cc.

References AnalysisHandler::beams().

Referenced by AnalysisHandler::analyze(), and Analysis::beamIds().

                                           {
    return Rivet::beamIds(beams());
  }
const ParticlePair& beams ( ) const [inline]

Get beam IDs for this run, usually determined from the first event.

Definition at line 98 of file AnalysisHandler.hh.

References AnalysisHandler::_beams.

Referenced by AnalysisHandler::analyze(), AnalysisHandler::beamIds(), Analysis::beams(), AnalysisHandler::init(), AnalysisHandler::setRunBeams(), and AnalysisHandler::sqrtS().

                                      {
      return _beams;
    }
double crossSection ( ) const [inline]

Get the cross-section known to the handler.

Definition at line 82 of file AnalysisHandler.hh.

References AnalysisHandler::_xs.

Referenced by Run::crossSection(), and AnalysisHandler::hasCrossSection().

                                {
      return _xs;
    }
void finalize ( )

Finalize a run. This function calls the AnalysisBase::finalize() functions of all included analysis objects.

Definition at line 146 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, AnalysisHandler::_initialised, AnalysisHandler::_numEvents, AnalysisHandler::_xs, and MSG_INFO.

Referenced by Run::finalize().

                                 {
    if (!_initialised) return;
    MSG_INFO("Finalising analyses");
    foreach (AnaHandle a, _analyses) {
      a->setCrossSection(_xs);
      try {
        a->finalize();
      } catch (const Error& err) {
        cerr << "Error in " << a->name() << "::finalize method: " << err.what() << endl;
        exit(1);
      }
    }

    // Print out number of events processed
    MSG_INFO("Processed " << _numEvents << " event" << (_numEvents == 1 ? "" : "s"));

    // // Delete analyses
    // MSG_DEBUG("Deleting analyses");
    // _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:1003.0694 (http://arxiv.org/abs/1003.0694)" << endl;
  }
vector< AnalysisObjectPtr > getData ( ) const

Get all analyses' plots as a vector of analysis objects.

Todo:
This needs to be much more nuanced for re-entrant histogramming
Todo:
Use lambda in C++11

Definition at line 213 of file AnalysisHandler.cc.

References AnalysisHandler::_numEvents, AnalysisHandler::_sumOfWeights, AnalysisHandler::_sumOfWeightsSq, AnalysisHandler::_xs, AnalysisHandler::_xserr, and AnalysisHandler::analyses().

Referenced by AnalysisHandler::writeData().

                                                           {
    vector<AnalysisObjectPtr> rtn;
    rtn.push_back( AnalysisObjectPtr(new Counter(YODA::Dbn0D(_numEvents, _sumOfWeights, _sumOfWeightsSq), "/_EVTCOUNT")) );
    YODA::Scatter1D::Points pts; pts.insert(YODA::Point1D(_xs, _xserr));
    rtn.push_back( AnalysisObjectPtr(new Scatter1D(pts, "/_XSEC")) );
    foreach (const AnaHandle a, analyses()) {
      vector<AnalysisObjectPtr> aos = a->analysisObjects();
      // MSG_WARNING(a->name() << " " << aos.size());
      foreach (const AnalysisObjectPtr ao, aos) {
        // Exclude paths starting with /TMP/ from final write-out
        /// @todo This needs to be much more nuanced for re-entrant histogramming
        if (ao->path().find("/TMP/") != string::npos) continue;
        rtn.push_back(ao);
      }
    }
    /// @todo Use lambda in C++11
    sort(rtn.begin(), rtn.end(), cmpAOByPath);
    return rtn;
  }
Log & getLog ( ) const [private]

Get a logger object.

Definition at line 33 of file AnalysisHandler.cc.

                                     {
    return Log::getLog("Rivet.Analysis.Handler");
  }
bool hasCrossSection ( ) const

Whether the handler knows about a cross-section.

Definition at line 296 of file AnalysisHandler.cc.

References AnalysisHandler::crossSection().

Referenced by Run::processEvent().

                                              {
    return (!std::isnan(crossSection()));
  }
void init ( const GenEvent &  event)

Initialize a run, with the run beams taken from the example event.

Definition at line 38 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, AnalysisHandler::_ignoreBeams, AnalysisHandler::_initialised, AnalysisHandler::_numEvents, AnalysisHandler::_sumOfWeights, AnalysisHandler::_sumOfWeightsSq, AnalysisHandler::analyses(), AnalysisHandler::analysisNames(), Rivet::beams(), AnalysisHandler::beams(), MSG_DEBUG, MSG_WARNING, AnalysisHandler::removeAnalysis(), AnalysisHandler::setRunBeams(), and Rivet::toUpper().

Referenced by AnalysisHandler::analyze(), and Run::init().

                                               {
    if (_initialised)
      throw UserError("AnalysisHandler::init has already been called: cannot re-initialize!");

    setRunBeams(Rivet::beams(ge));
    MSG_DEBUG("Initialising the analysis handler");
    _numEvents = 0;
    _sumOfWeights = 0.0;
    _sumOfWeightsSq = 0.0;

    // Check that analyses are beam-compatible, and remove those that aren't
    const size_t num_anas_requested = analysisNames().size();
    vector<string> anamestodelete;
    foreach (const AnaHandle a, _analyses) {
      if (!_ignoreBeams && !a->isCompatible(beams())) {
        //MSG_DEBUG(a->name() << " requires beams " << a->requiredBeams() << " @ " << a->requiredEnergies() << " GeV");
        anamestodelete.push_back(a->name());
      }
    }
    foreach (const string& aname, anamestodelete) {
      MSG_WARNING("Analysis '" << aname << "' is incompatible with the provided beams: removing");
      removeAnalysis(aname);
    }
    if (num_anas_requested > 0 && analysisNames().empty()) {
      cerr << "All analyses were incompatible with the first event's beams\n"
           << "Exiting, since this probably wasn't intentional!" << endl;
      exit(1);
    }

    // Warn if any analysis' status is not unblemished
    foreach (const AnaHandle a, analyses()) {
      if (toUpper(a->status()) == "PRELIMINARY") {
        MSG_WARNING("Analysis '" << a->name() << "' is preliminary: be careful, it may change and/or be renamed!");
      } else if (toUpper(a->status()) == "OBSOLETE") {
        MSG_WARNING("Analysis '" << a->name() << "' is obsolete: please update!");
      } else if (toUpper(a->status()).find("UNVALIDATED") != string::npos) {
        MSG_WARNING("Analysis '" << a->name() << "' is unvalidated: be careful, it may be broken!");
      }
    }

    // Initialize the remaining analyses
    foreach (AnaHandle a, _analyses) {
      MSG_DEBUG("Initialising analysis: " << a->name());
      try {
        // Allow projection registration in the init phase onwards
        a->_allowProjReg = true;
        a->init();
        //MSG_DEBUG("Checking consistency of analysis: " << a->name());
        //a->checkConsistency();
      } catch (const Error& err) {
        cerr << "Error in " << a->name() << "::init method: " << err.what() << endl;
        exit(1);
      }
      MSG_DEBUG("Done initialising analysis: " << a->name());
    }
    _initialised = true;
    MSG_DEBUG("Analysis handler initialised");
  }
bool needCrossSection ( ) const

Is cross-section information required by at least one child analysis?

Definition at line 280 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses.

Referenced by Run::processEvent().

                                               {
    bool rtn = false;
    foreach (const AnaHandle a, _analyses) {
      if (!rtn) rtn = a->needsCrossSection();
      if (rtn) break;
    }
    return rtn;
  }
size_t numEvents ( ) const

Get the number of events seen. Should only really be used by external steering code or analyses in the finalize phase.

Definition at line 245 of file AnalysisHandler.cc.

References AnalysisHandler::_numEvents.

Referenced by Analysis::numEvents().

{ return _numEvents; }
AnalysisHandler& operator= ( const AnalysisHandler ) [private]

The assignment operator is private and must never be called. In fact, it should not even be implemented.

AnalysisHandler & removeAnalyses ( const std::vector< std::string > &  analysisnames)

Remove analyses from the run list using their names.

Definition at line 272 of file AnalysisHandler.cc.

References AnalysisHandler::removeAnalysis().

                                                                                            {
    foreach (const string& aname, analysisnames) {
      removeAnalysis(aname);
    }
    return *this;
  }
AnalysisHandler & removeAnalysis ( const std::string &  analysisname)

Remove an analysis from the run list using its name.

Definition at line 197 of file AnalysisHandler.cc.

References AnalysisHandler::_analyses, and MSG_DEBUG.

Referenced by AnalysisHandler::init(), and AnalysisHandler::removeAnalyses().

                                                                             {
    shared_ptr<Analysis> toremove;
    foreach (const AnaHandle a, _analyses) {
      if (a->name() == analysisname) {
        toremove = a;
        break;
      }
    }
    if (toremove.get() != 0) {
      MSG_DEBUG("Removing analysis '" << analysisname << "'");
      _analyses.erase(toremove);
    }
    return *this;
  }
string runName ( ) const

Get the name of this run.

Definition at line 244 of file AnalysisHandler.cc.

References AnalysisHandler::_runname.

Referenced by Analysis::histoDir().

{ return _runname; }
AnalysisHandler & setCrossSection ( double  xs)

Set the cross-section for the process being generated.

Definition at line 290 of file AnalysisHandler.cc.

References AnalysisHandler::_xs.

Referenced by Run::finalize(), Run::init(), and Run::processEvent().

                                                             {
    _xs = xs;
    return *this;
  }
void setIgnoreBeams ( bool  ignore = true)

Setter for _ignoreBeams.

Definition at line 317 of file AnalysisHandler.cc.

References AnalysisHandler::_ignoreBeams.

                                                  {
    _ignoreBeams=ignore;
  }
AnalysisHandler& setRunBeams ( const ParticlePair beams) [inline]

Set beams for this run.

Definition at line 91 of file AnalysisHandler.hh.

References AnalysisHandler::_beams, AnalysisHandler::beams(), Rivet::GeV, MSG_DEBUG, and AnalysisHandler::sqrtS().

Referenced by AnalysisHandler::init().

                                                            {
      _beams = beams;
      MSG_DEBUG("Setting run beams = " << beams << " @ " << sqrtS()/GeV << " GeV");
      return *this;
    }
void setSumOfWeights ( const double &  sum)

Set sum of weights. This is useful if Rivet is steered externally and the analyses are run for a sub-contribution of the events (but of course have to be normalised to the total sum of weights)

Definition at line 249 of file AnalysisHandler.cc.

References AnalysisHandler::_sumOfWeights.

                                                         {
    _sumOfWeights=sum;
  }
double sqrtS ( ) const

Get energy for this run, usually determined from the first event.

Definition at line 313 of file AnalysisHandler.cc.

References AnalysisHandler::beams().

Referenced by AnalysisHandler::analyze(), AnalysisHandler::setRunBeams(), and Analysis::sqrtS().

                                      {
    return Rivet::sqrtS(beams());
  }
double sumOfWeights ( ) const

Get the sum of the event weights seen - the weighted equivalent of the number of events. Should only really be used by external steering code or analyses in the finalize phase.

Definition at line 246 of file AnalysisHandler.cc.

References AnalysisHandler::_sumOfWeights.

Referenced by Analysis::sumOfWeights().

{ return _sumOfWeights; }
void writeData ( const std::string &  filename) const

Write all analyses' plots to the named file.

Todo:
Move to specific YODA::WriteError type when YODA >= 1.5.0 is well-established

Definition at line 234 of file AnalysisHandler.cc.

References AnalysisHandler::getData().

                                                              {
    const vector<AnalysisObjectPtr> aos = getData();
    try {
      YODA::WriterYODA::write(filename, aos.begin(), aos.end());
    } catch (...) { /// @todo Move to specific YODA::WriteError type when YODA >= 1.5.0 is well-established
      throw UserError("Unexpected error in writing file to: " + filename);
    }
  }

Member Data Documentation

ParticlePair _beams [private]

Beams used by this run.

Definition at line 203 of file AnalysisHandler.hh.

Referenced by AnalysisHandler::analyze(), AnalysisHandler::beams(), and AnalysisHandler::setRunBeams().

bool _ignoreBeams [private]

Flag whether input event beams should be ignored in compatibility check.

Definition at line 209 of file AnalysisHandler.hh.

Referenced by AnalysisHandler::init(), and AnalysisHandler::setIgnoreBeams().

bool _initialised [private]

Flag to check if init has been called.

Definition at line 206 of file AnalysisHandler.hh.

Referenced by AnalysisHandler::analyze(), AnalysisHandler::finalize(), and AnalysisHandler::init().

unsigned int _numEvents [private]
std::string _runname [private]

Run name.

Definition at line 190 of file AnalysisHandler.hh.

Referenced by AnalysisHandler::runName().

double _sumOfWeights [private]
double _xserr [private]

Definition at line 200 of file AnalysisHandler.hh.

Referenced by AnalysisHandler::analyze(), and AnalysisHandler::getData().


The documentation for this class was generated from the following files: