#ifndef __JAANET__JEVTWEIGHTFACTORMUPAGE__ #define __JAANET__JEVTWEIGHTFACTORMUPAGE__ #include "km3net-dataformat/offline/Evt.hh" #include "km3net-dataformat/offline/Trk.hh" #include "JLang/JException.hh" #include "JLang/JPredicate.hh" #include "JGeometry2D/JCircle2D.hh" #include "TFormula.h" /** * \author bjung */ namespace JAANET { using JLANG::JValueOutOfRange; using JLANG::JNullPointerException; /** * Implementation of reweighting factor for mupage events according to a specifiable ROOT TFormula. * * Note: The ROOT TFormula may assume any number of parameters, but should be restricted to\n * the physical variables listed among `JEvtWeightFactorMupage::variables`.\n * These variables may be specified within the ROOT TFormula as 'x[\]',\n * where \ corresponds to the index of the desired physical variable within `JEvtWeightFactorMupage::variables`. */ struct JEvtWeightFactorMupage : public TFormula { /** * Indices of reweighting variables for MUPAGE. */ enum variables { MUON_MULTIPLICITY, //!< Muon multiplicity MEAN_ZENITH_ANGLE, //!< Average cosine of zenith angle TOTAL_MUON_ENERGY, //!< Muon bundle total energy [GeV] LATERAL_SPREAD, //!< Muon bundle lateral spread [m] NUMBER_OF_VARIABLES //!< Number of reweighting variables; \n //!< N.B.\ This enum value needs to be specified last! }; /** * Default constructor. */ JEvtWeightFactorMupage() : TFormula() {} /** * Constructor. * * \param name name * \param formula formula */ JEvtWeightFactorMupage(const char* name, const char* formula) : TFormula(name, formula) {} /** * Get weighting factor for given event. * * \param evt event * \return weighting factor */ double operator()(const Evt& evt) const { using namespace std; using namespace JPP; vector vars(NUMBER_OF_VARIABLES, 0.0); // Compute average zenith-angle of final state muons and convert to JTrack3E double Etot = 0.0; vector muons; for (vector::const_iterator i = evt.mc_trks.cbegin(); i != evt.mc_trks.cend(); ++i) { if (is_muon(*i) && is_finalstate(*i)) { Etot += i->E; vars[MEAN_ZENITH_ANGLE] += i->dir.z / i->dir.len(); muons.push_back(getTrack(*i)); } } vector::const_iterator iBundle = find_if(evt.mc_trks.cbegin(), evt.mc_trks.cend(), JLANG::make_predicate(&Trk::status, TRK_ST_MUONBUNDLE)); vars[MUON_MULTIPLICITY] = (iBundle != evt.mc_trks.cend() && iBundle->len > 0 ? iBundle->len : (Double_t) muons.size()); vars[TOTAL_MUON_ENERGY] = (iBundle != evt.mc_trks.cend() ? iBundle->E : Etot); vars[MEAN_ZENITH_ANGLE] /= (Double_t) muons.size(); if (muons.size() > 0) { if (this->GetNdim() > (int) LATERAL_SPREAD) { JCircle2D circle = JCircle2D(muons.cbegin(), muons.cend()); // smallest enclosing circle vars[LATERAL_SPREAD] = (Double_t) circle.getRadius(); } return this->DoEval(&vars[0]); } else { THROW(JNullPointerException, "JEvtWeightFactorMupage::operator(): No muon for event " << evt.id << '.' << endl); } } }; } #endif