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/ClusteredPhotons.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 ChargedFinalState& fs_l,
00016                    PdgId pid,
00017                    double m2_min, double m2_max,
00018                    double missingET,
00019                    double dRmax) {
00020     _init(fs_l, pid, m2_min, m2_max, missingET, dRmax);
00021   }
00022 
00023 
00024   WFinder::WFinder(double etaMin, double etaMax,
00025                    double pTmin,
00026                    PdgId pid,
00027                    double m2_min, double m2_max,
00028                    double missingET,
00029                    double dRmax) {
00030     vector<pair<double, double> > etaRanges;
00031     etaRanges += std::make_pair(etaMin, etaMax);
00032     _init(etaRanges, pTmin, pid, m2_min, m2_max, missingET, dRmax);
00033   }
00034 
00035 
00036   WFinder::WFinder(const std::vector<std::pair<double, double> >& etaRanges,
00037                    double pTmin,
00038                    PdgId pid,
00039                    double m2_min, double m2_max,
00040                    double missingET,
00041                    double dRmax) {
00042     _init(etaRanges, pTmin, pid, m2_min, m2_max, missingET, dRmax);
00043   }
00044 
00045 
00046   void WFinder::_init(const std::vector<std::pair<double, double> >& etaRanges,
00047                       double pTmin,
00048                       PdgId pid,
00049                       double m2_min, double m2_max,
00050                       double missingET,
00051                       double dRmax) {
00052     ChargedFinalState fs_l(etaRanges, pTmin);
00053     _init(fs_l, pid, m2_min, m2_max, missingET, dRmax);
00054   }
00055 
00056 
00057   void WFinder::_init(const ChargedFinalState& fs_l,
00058                       PdgId pid,
00059                       double m2_min, double m2_max,
00060                       double missingET,
00061                       double dRmax)
00062   {
00063     setName("WFinder");
00064 
00065     // Check that the arguments are legal
00066     assert(abs(pid) == ELECTRON || abs(pid) == MUON);
00067     PdgId nu_pid = abs(pid) + 1;
00068     assert(abs(nu_pid) == NU_E || abs(nu_pid) == NU_MU);
00069 
00070     // Don't make pT or eta cuts on the neutrino
00071     IdentifiedFinalState fs_nu;
00072     fs_nu.acceptNeutrinos();
00073 
00074     // Make a merged final state projection for charged and neutral leptons
00075     MergedFinalState mergedFS(fs_l, fs_nu);
00076 
00077     // Mass range
00078     _m2_min = m2_min;
00079     _m2_max = m2_max;
00080 
00081     // Set ETmiss
00082     _etMiss = missingET;
00083 
00084     // Make and register an invariant mass final state for the W decay leptons
00085     vector<pair<PdgId, PdgId> > l_nu_ids;
00086     l_nu_ids += make_pair(abs(pid), -abs(nu_pid));
00087     l_nu_ids += make_pair(-abs(pid), abs(nu_pid));
00088     InvMassFinalState imfs(mergedFS, l_nu_ids, m2_min, m2_max);
00089     addProjection(imfs, "IMFS");
00090 
00091     // A projection for clustering photons on to the charged lepton
00092     ClusteredPhotons cphotons(FinalState(), imfs, dRmax);
00093     addProjection(cphotons, "CPhotons");
00094 
00095     // Projection for all signal constituents
00096     MergedFinalState signalFS(imfs, cphotons);
00097     addProjection(signalFS, "SignalParticles");
00098 
00099     // Add MissingMomentum proj to calc MET
00100     MissingMomentum vismom(signalFS);
00101     addProjection(vismom, "MissingET");
00102 
00103     // FS for non-signal bits of the event
00104     VetoedFinalState remainingFS;
00105     remainingFS.addVetoOnThisFinalState(signalFS);
00106     addProjection(remainingFS, "RFS");
00107   }
00108 
00109 
00110   /////////////////////////////////////////////////////
00111 
00112 
00113   const FinalState& WFinder::remainingFinalState() const {
00114     return getProjection<FinalState>("RFS");
00115   }
00116 
00117 
00118   const FinalState& WFinder::constituentsFinalState() const {
00119     return getProjection<FinalState>("SignalParticles");
00120   }
00121 
00122 
00123   const FinalState& WFinder::constituentLeptonsFinalState() const {
00124     return getProjection<FinalState>("IMFS");
00125   }
00126 
00127 
00128   const FinalState& WFinder::clusteredPhotonsFinalState() const
00129   {
00130     return getProjection<FinalState>("CPhotons");
00131   }
00132 
00133 
00134   int WFinder::compare(const Projection& p) const {
00135     PCmp cmp = mkNamedPCmp(p, "IMFS");
00136     if (cmp != EQUIVALENT) return cmp;
00137 
00138     cmp = mkNamedPCmp(p, "CPhotons");
00139     if (cmp != EQUIVALENT) return cmp;
00140 
00141     return EQUIVALENT;
00142   }
00143 
00144 
00145   void WFinder::clear() {
00146     _theParticles.clear();
00147   }
00148 
00149 
00150   void WFinder::project(const Event& e) {
00151     clear();
00152 
00153     const FinalState& imfs = applyProjection<FinalState>(e, "IMFS");
00154     if (imfs.particles().size() != 2) {
00155       getLog() << Log::DEBUG << "No W+- candidates found" << endl;
00156       return;
00157     }
00158 
00159     FourMomentum pW = imfs.particles()[0].momentum() + imfs.particles()[1].momentum();
00160     const int w3charge = PID::threeCharge(imfs.particles()[0]) + PID::threeCharge(imfs.particles()[1]);
00161     assert(abs(w3charge) == 3);
00162     const int wcharge = w3charge/3;
00163 
00164     stringstream msg;
00165     string wsign = (wcharge == 1) ? "+" : "-";
00166     string wstr = "W" + wsign;
00167     msg << wstr << " reconstructed from: " << endl
00168         << "   " << imfs.particles()[0].momentum() << " " << imfs.particles()[0].pdgId() << endl
00169         << " + " << imfs.particles()[1].momentum() << " " << imfs.particles()[1].pdgId() << endl;
00170 
00171     // Add in clustered photons
00172     const FinalState& photons = applyProjection<FinalState>(e, "CPhotons");
00173     foreach (const Particle& photon, photons.particles()) {
00174       msg << " + " << photon.momentum() << " " << photon.pdgId() << endl;
00175       pW += photon.momentum();
00176     }
00177     msg << " = " << pW;
00178 
00179     // Check missing ET
00180     const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00181     /// @todo Restrict missing momentum eta range? Use vectorET()?
00182     if (vismom.scalarET() < _etMiss) {
00183       getLog() << Log::DEBUG << "Not enough missing ET: " << vismom.scalarET()/GeV
00184                << " GeV vs. " << _etMiss/GeV << " GeV" << endl;
00185       return;
00186     }
00187 
00188     // Check mass range again
00189     if (!inRange(pW.mass()/GeV, _m2_min, _m2_max)) return;
00190     getLog() << Log::DEBUG << msg.str() << endl;
00191 
00192     // Make W Particle and insert into particles list
00193     const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00194     _theParticles.push_back(Particle(wpid, pW));
00195   }
00196 
00197 
00198 }