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/TotalVisibleMomentum.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(cphotons, "SignalParticles");
00098     
00099     // Add TotalVisibleMomentum proj to calc MET
00100     TotalVisibleMomentum 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   int WFinder::compare(const Projection& p) const {
00129     PCmp cmp = mkNamedPCmp(p, "IMFS");
00130     if (cmp != EQUIVALENT) return cmp;
00131 
00132     cmp = mkNamedPCmp(p, "CPhotons");
00133     if (cmp != EQUIVALENT) return cmp;
00134 
00135     return EQUIVALENT;
00136   }
00137 
00138 
00139   void WFinder::clear() {
00140     _theParticles.clear();
00141   }
00142 
00143 
00144   void WFinder::project(const Event& e) {
00145     clear();
00146 
00147     const FinalState& imfs = applyProjection<FinalState>(e, "IMFS");
00148     if (imfs.particles().size() != 2) {
00149       getLog() << Log::DEBUG << "No W+- candidates found" << endl;
00150       return;
00151     }
00152 
00153     FourMomentum pW = imfs.particles()[0].momentum() + imfs.particles()[1].momentum();
00154     const int w3charge = PID::threeCharge(imfs.particles()[0]) + PID::threeCharge(imfs.particles()[1]);
00155     assert(abs(w3charge) == 3);
00156     const int wcharge = w3charge/3;
00157 
00158     stringstream msg;
00159     string wsign = (wcharge == 1) ? "+" : "-";
00160     string wstr = "W" + wsign;
00161     msg << wstr << " reconstructed from: " << endl
00162         << "   " << imfs.particles()[0].momentum() << " " << imfs.particles()[0].pdgId() << endl
00163         << " + " << imfs.particles()[1].momentum() << " " << imfs.particles()[1].pdgId() << endl;
00164 
00165     // Add in clustered photons
00166     const FinalState& photons = applyProjection<FinalState>(e, "CPhotons");
00167     foreach (const Particle& photon, photons.particles()) {
00168       msg << " + " << photon.momentum() << " " << photon.pdgId() << endl;
00169       pW += photon.momentum();
00170     }
00171     msg << " = " << pW;
00172 
00173     // Check missing ET
00174     const TotalVisibleMomentum& vismom = applyProjection<TotalVisibleMomentum>(e, "MissingET");
00175     /// @todo Restrict missing momentum eta range?
00176     if (vismom.scalarET() < _etMiss) {
00177       getLog() << Log::DEBUG << "Not enough missing ET: " << vismom.scalarET()/GeV 
00178                << " GeV vs. " << _etMiss/GeV << " GeV" << endl;
00179       return;
00180     }
00181 
00182     // Check mass range again
00183     if (!inRange(pW.mass()/GeV, _m2_min, _m2_max)) return;
00184     getLog() << Log::DEBUG << msg.str() << endl;
00185     
00186     // Make W Particle and insert into particles list
00187     const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00188     _theParticles.push_back(Particle(wpid, pW));
00189   }
00190 
00191 
00192 }