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