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