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) == ELECTRON || abs(_pid) == MUON);
00096     _nu_pid = abs(_pid) + 1;
00097     assert(abs(_nu_pid) == NU_E || abs(_nu_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,
00109                            etaRanges, pTmin);
00110     addProjection(leptons, "LeptonClusters");
00111 
00112     // Add MissingMomentum proj to calc MET
00113     MissingMomentum vismom(inputfs);
00114     addProjection(vismom, "MissingET");
00115     // Set ETmiss
00116     _etMiss = missingET;
00117 
00118     VetoedFinalState remainingFS;
00119     remainingFS.addVetoOnThisFinalState(*this);
00120     addProjection(remainingFS, "RFS");
00121   }
00122 
00123 
00124   /////////////////////////////////////////////////////
00125 
00126 
00127   const FinalState& WFinder::remainingFinalState() const {
00128     return getProjection<FinalState>("RFS");
00129   }
00130 
00131   int WFinder::compare(const Projection& p) const {
00132     PCmp LCcmp = mkNamedPCmp(p, "LeptonClusters");
00133     if (LCcmp != EQUIVALENT) return LCcmp;
00134 
00135     const WFinder& other = dynamic_cast<const WFinder&>(p);
00136     return (cmp(_minmass, other._minmass) || cmp(_maxmass, other._maxmass) ||
00137             cmp(_useTransverseMass, other._useTransverseMass) ||
00138             cmp(_etMiss, other._etMiss) ||
00139             cmp(_pid, other._pid) || cmp(_trackPhotons, other._trackPhotons));
00140   }
00141 
00142 
00143   void WFinder::project(const Event& e) {
00144     clear();
00145 
00146     const LeptonClusters& leptons = applyProjection<LeptonClusters>(e, "LeptonClusters");
00147     const FinalState& neutrinos = applyProjection<FinalState>(e, "Neutrinos");
00148 
00149     // Make and register an invariant mass final state for the W decay leptons
00150     vector<pair<PdgId, PdgId> > l_nu_ids;
00151     l_nu_ids += make_pair(abs(_pid), -abs(_nu_pid));
00152     l_nu_ids += make_pair(-abs(_pid), abs(_nu_pid));
00153     InvMassFinalState imfs(l_nu_ids, _minmass, _maxmass, _masstarget);
00154     imfs.useTransverseMass(_useTransverseMass);
00155     ParticleVector tmp;
00156     tmp.insert(tmp.end(), leptons.clusteredLeptons().begin(), leptons.clusteredLeptons().end());
00157     tmp.insert(tmp.end(), neutrinos.particles().begin(), neutrinos.particles().end());
00158     imfs.calc(tmp);
00159 
00160     if (imfs.particlePairs().size() < 1) return;
00161 
00162     ParticlePair Wconstituents(imfs.particlePairs()[0]);
00163     Particle p1(Wconstituents.first), p2(Wconstituents.second);
00164 
00165     if (PID::threeCharge(p1)==0) {
00166       _constituentLeptons += p2;
00167       _constituentNeutrinos += p1;
00168     }
00169     else {
00170       _constituentLeptons += p1;
00171       _constituentNeutrinos += p2;
00172     }
00173 
00174     FourMomentum pW = p1.momentum() + p2.momentum();
00175     const int w3charge = PID::threeCharge(p1) + PID::threeCharge(p2);
00176     assert(abs(w3charge) == 3);
00177     const int wcharge = w3charge/3;
00178 
00179     stringstream msg;
00180     string wsign = (wcharge == 1) ? "+" : "-";
00181     string wstr = "W" + wsign;
00182     msg << wstr << " reconstructed from: " << "\n"
00183         << "   " << p1.momentum() << " " << p1.pdgId() << "\n"
00184         << " + " << p2.momentum() << " " << p2.pdgId();
00185     MSG_DEBUG(msg.str());
00186 
00187     // Check missing ET
00188     const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00189     /// @todo Restrict missing momentum eta range? Use vectorET()?
00190     if (vismom.scalarEt() < _etMiss) {
00191       MSG_DEBUG("Not enough missing ET: " << vismom.scalarEt()/GeV
00192                 << " GeV vs. " << _etMiss/GeV << " GeV");
00193       return;
00194     }
00195 
00196     // Make W Particle and insert into particles list
00197     const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00198     _bosons.push_back(Particle(wpid, pW));
00199 
00200     // Find the LeptonClusters and neutrinos which survived the IMFS cut such that we can
00201     // extract their original particles
00202     foreach (const Particle& p, _constituentNeutrinos) {
00203       _theParticles.push_back(p);
00204     }
00205     foreach (const Particle& p, _constituentLeptons) {
00206       foreach (const ClusteredLepton& l, leptons.clusteredLeptons()) {
00207         if (p.pdgId()==l.pdgId() && p.momentum()==l.momentum()) {
00208           _theParticles.push_back(l.constituentLepton());
00209           if (_trackPhotons) {
00210             _theParticles.insert(_theParticles.end(),
00211                                  l.constituentPhotons().begin(),
00212                                  l.constituentPhotons().end());
00213           }
00214         }
00215       }
00216     }
00217   }
00218 
00219 
00220 }