rivet is hosted by Hepforge, IPPP Durham
WFinder.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Projections/WFinder.hh"
00003 #include "Rivet/Projections/InvMassFinalState.hh"
00004 #include "Rivet/Projections/MissingMomentum.hh"
00005 #include "Rivet/Projections/MergedFinalState.hh"
00006 #include "Rivet/Projections/LeptonClusters.hh"
00007 #include "Rivet/Projections/VetoedFinalState.hh"
00008 
00009 namespace Rivet {
00010 
00011 
00012   WFinder::WFinder(const FinalState& inputfs,
00013                    double etaMin, double etaMax,
00014                    double pTmin,
00015                    PdgId pid,
00016                    double minmass, double maxmass,
00017                    double missingET,
00018                    double dRmax, bool clusterPhotons, bool trackPhotons,
00019                    double masstarget,
00020                    bool useTransverseMass) {
00021     vector<pair<double, double> > etaRanges;
00022     etaRanges += std::make_pair(etaMin, etaMax);
00023     _init(inputfs, etaRanges, pTmin, pid, minmass, maxmass, missingET,
00024           dRmax, clusterPhotons, trackPhotons, masstarget, useTransverseMass);
00025   }
00026 
00027 
00028   WFinder::WFinder(const FinalState& inputfs,
00029                    const std::vector<std::pair<double, double> >& etaRanges,
00030                    double pTmin,
00031                    PdgId pid,
00032                    double minmass, double maxmass,
00033                    double missingET,
00034                    double dRmax, bool clusterPhotons, bool trackPhotons,
00035                    double masstarget,
00036                    bool useTransverseMass) {
00037     _init(inputfs, etaRanges, pTmin, pid, minmass, maxmass, missingET,
00038           dRmax, clusterPhotons, trackPhotons, masstarget, useTransverseMass);
00039   }
00040 
00041 
00042   WFinder::WFinder(double etaMin, double etaMax,
00043                    double pTmin,
00044                    PdgId pid,
00045                    double minmass, double maxmass,
00046                    double missingET,
00047                    double dRmax, bool clusterPhotons, bool trackPhotons,
00048                    double masstarget,
00049                    bool useTransverseMass) {
00050     vector<pair<double, double> > etaRanges;
00051     etaRanges += std::make_pair(etaMin, etaMax);
00052     FinalState inputfs;
00053     _init(inputfs, etaRanges, pTmin, pid, minmass, maxmass, missingET,
00054           dRmax, clusterPhotons, trackPhotons, masstarget, useTransverseMass);
00055   }
00056 
00057 
00058   WFinder::WFinder(const std::vector<std::pair<double, double> >& etaRanges,
00059                    double pTmin,
00060                    PdgId pid,
00061                    double minmass, double maxmass,
00062                    double missingET,
00063                    double dRmax, bool clusterPhotons, bool trackPhotons,
00064                    double masstarget,
00065                    bool useTransverseMass) {
00066     FinalState inputfs;
00067     _init(inputfs, etaRanges, pTmin, pid, minmass, maxmass, missingET,
00068           dRmax, clusterPhotons, trackPhotons, masstarget, useTransverseMass);
00069   }
00070 
00071 
00072   void WFinder::_init(const FinalState& inputfs,
00073                       const std::vector<std::pair<double, double> >& etaRanges,
00074                       double pTmin,
00075                       PdgId pid,
00076                       double minmass, double maxmass,
00077                       double missingET,
00078                       double dRmax, bool clusterPhotons, bool trackPhotons,
00079                       double masstarget,
00080                       bool useTransverseMass)
00081   {
00082     setName("WFinder");
00083 
00084     _minmass = minmass;
00085     _maxmass = maxmass;
00086     _masstarget = masstarget;
00087     _pid = pid;
00088     _trackPhotons = trackPhotons;
00089     _useTransverseMass = useTransverseMass;
00090 
00091     // Check that the arguments are legal
00092     assert(abs(_pid) == PID::ELECTRON || abs(_pid) == PID::MUON);
00093     _nu_pid = abs(_pid) + 1;
00094     assert(abs(_nu_pid) == PID::NU_E || abs(_nu_pid) == PID::NU_MU);
00095 
00096     // Don't make pT or eta cuts on the neutrino
00097     IdentifiedFinalState neutrinos(inputfs);
00098     neutrinos.acceptNeutrinos();
00099     addProjection(neutrinos, "Neutrinos");
00100 
00101     // Lepton clusters
00102     IdentifiedFinalState bareleptons(inputfs);
00103     bareleptons.acceptIdPair(pid);
00104     LeptonClusters leptons(inputfs, bareleptons, dRmax,
00105                            clusterPhotons, etaRanges, pTmin);
00106     addProjection(leptons, "LeptonClusters");
00107 
00108     // Add MissingMomentum proj to calc MET
00109     MissingMomentum vismom(inputfs);
00110     addProjection(vismom, "MissingET");
00111     // Set ETmiss
00112     _etMiss = missingET;
00113 
00114     VetoedFinalState remainingFS;
00115     remainingFS.addVetoOnThisFinalState(*this);
00116     addProjection(remainingFS, "RFS");
00117   }
00118 
00119 
00120   /////////////////////////////////////////////////////
00121 
00122 
00123   const FinalState& WFinder::remainingFinalState() const {
00124     return getProjection<FinalState>("RFS");
00125   }
00126 
00127   int WFinder::compare(const Projection& p) const {
00128     PCmp LCcmp = mkNamedPCmp(p, "LeptonClusters");
00129     if (LCcmp != EQUIVALENT) return LCcmp;
00130 
00131     const WFinder& other = dynamic_cast<const WFinder&>(p);
00132     return (cmp(_minmass, other._minmass) || cmp(_maxmass, other._maxmass) ||
00133             cmp(_useTransverseMass, other._useTransverseMass) ||
00134             cmp(_etMiss, other._etMiss) ||
00135             cmp(_pid, other._pid) || cmp(_trackPhotons, other._trackPhotons));
00136   }
00137 
00138 
00139   void WFinder::project(const Event& e) {
00140     clear();
00141 
00142     const LeptonClusters& leptons = applyProjection<LeptonClusters>(e, "LeptonClusters");
00143     const FinalState& neutrinos = applyProjection<FinalState>(e, "Neutrinos");
00144 
00145     // Make and register an invariant mass final state for the W decay leptons
00146     vector<pair<PdgId, PdgId> > l_nu_ids;
00147     l_nu_ids += make_pair(abs(_pid), -abs(_nu_pid));
00148     l_nu_ids += make_pair(-abs(_pid), abs(_nu_pid));
00149     InvMassFinalState imfs(l_nu_ids, _minmass, _maxmass, _masstarget);
00150     imfs.useTransverseMass(_useTransverseMass);
00151     Particles tmp;
00152     tmp.insert(tmp.end(), leptons.clusteredLeptons().begin(), leptons.clusteredLeptons().end());
00153     tmp.insert(tmp.end(), neutrinos.particles().begin(), neutrinos.particles().end());
00154     imfs.calc(tmp);
00155 
00156     if (imfs.particlePairs().size() < 1) return;
00157 
00158     ParticlePair Wconstituents(imfs.particlePairs()[0]);
00159     Particle p1(Wconstituents.first), p2(Wconstituents.second);
00160 
00161     if (PID::threeCharge(p1)==0) {
00162       _constituentLeptons += p2;
00163       _constituentNeutrinos += p1;
00164     } else {
00165       _constituentLeptons += p1;
00166       _constituentNeutrinos += p2;
00167     }
00168 
00169     FourMomentum pW = p1.momentum() + p2.momentum();
00170     const int w3charge = PID::threeCharge(p1) + PID::threeCharge(p2);
00171     assert(abs(w3charge) == 3);
00172     const int wcharge = w3charge/3;
00173 
00174     stringstream msg;
00175     string wsign = (wcharge == 1) ? "+" : "-";
00176     string wstr = "W" + wsign;
00177     msg << wstr << " reconstructed from: " << "\n"
00178         << "   " << p1.momentum() << " " << p1.pdgId() << "\n"
00179         << " + " << p2.momentum() << " " << p2.pdgId();
00180     MSG_DEBUG(msg.str());
00181 
00182     // Check missing ET
00183     const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00184     /// @todo Restrict missing momentum eta range? Use vectorET()?
00185     if (vismom.scalarEt() < _etMiss) {
00186       MSG_DEBUG("Not enough missing ET: " << vismom.scalarEt()/GeV
00187                 << " GeV vs. " << _etMiss/GeV << " GeV");
00188       return;
00189     }
00190 
00191     // Make W Particle and insert into particles list
00192     const PdgId wpid = (wcharge == 1) ? PID::WPLUSBOSON : PID::WMINUSBOSON;
00193     _bosons.push_back(Particle(wpid, pW));
00194 
00195     // Find the LeptonClusters and neutrinos which survived the IMFS cut such that we can
00196     // extract their original particles
00197     foreach (const Particle& p, _constituentNeutrinos) {
00198       _theParticles.push_back(p);
00199     }
00200     foreach (const Particle& p, _constituentLeptons) {
00201       foreach (const ClusteredLepton& l, leptons.clusteredLeptons()) {
00202         if (p.pdgId()==l.pdgId() && p.momentum()==l.momentum()) {
00203           _theParticles.push_back(l.constituentLepton());
00204           if (_trackPhotons) {
00205             _theParticles.insert(_theParticles.end(),
00206                                  l.constituentPhotons().begin(), l.constituentPhotons().end());
00207           }
00208         }
00209       }
00210     }
00211   }
00212 
00213 
00214 }