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