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/ChargedFinalState.hh"
00004 #include "Rivet/Projections/InvMassFinalState.hh"
00005 #include "Rivet/Projections/MissingMomentum.hh"
00006 #include "Rivet/Projections/MergedFinalState.hh"
00007 #include "Rivet/Projections/DressedLeptons.hh"
00008 #include "Rivet/Projections/VetoedFinalState.hh"
00009 #include "Rivet/Projections/Beam.hh"
00010 
00011 namespace Rivet {
00012 
00013 
00014   WFinder::WFinder(const FinalState& inputfs,
00015                    const Cut& fsCut,
00016                    PdgId pid,
00017                    double minmass, double maxmass,
00018                    double missingET,
00019                    double dRmax,
00020                    ClusterPhotons clusterPhotons,
00021                    PhotonTracking trackPhotons,
00022                    MassWindow masstype,
00023                    double masstarget) {
00024     setName("WFinder");
00025 
00026     _minmass = minmass;
00027     _maxmass = maxmass;
00028     _masstarget = masstarget;
00029     _pid = pid;
00030     _trackPhotons = trackPhotons;
00031     _useTransverseMass = (masstype == TRANSMASS);
00032 
00033     // Check that the arguments are legal
00034     assert(abs(_pid) == PID::ELECTRON || abs(_pid) == PID::MUON);
00035     _nu_pid = abs(_pid) + 1;
00036     assert(abs(_nu_pid) == PID::NU_E || abs(_nu_pid) == PID::NU_MU);
00037 
00038     // Lepton clusters
00039     IdentifiedFinalState bareleptons(inputfs);
00040     bareleptons.acceptIdPair(pid);
00041     const bool doClustering = (clusterPhotons != NOCLUSTER);
00042     const bool useDecayPhotons = (clusterPhotons == CLUSTERALL);
00043     DressedLeptons leptons(inputfs, bareleptons, dRmax, fsCut, doClustering, useDecayPhotons);
00044     addProjection(leptons, "DressedLeptons");
00045 
00046     // Add MissingMomentum proj to calc MET
00047     MissingMomentum vismom(inputfs);
00048     addProjection(vismom, "MissingET");
00049     // Set ETmiss
00050     _etMiss = missingET;
00051 
00052     VetoedFinalState remainingFS;
00053     remainingFS.addVetoOnThisFinalState(*this);
00054     addProjection(remainingFS, "RFS");
00055   }
00056 
00057 
00058   /////////////////////////////////////////////////////
00059 
00060 
00061   const VetoedFinalState& WFinder::remainingFinalState() const {
00062     return getProjection<VetoedFinalState>("RFS");
00063   }
00064 
00065 
00066   int WFinder::compare(const Projection& p) const {
00067     PCmp dlcmp = mkNamedPCmp(p, "DressedLeptons");
00068     if (dlcmp != EQUIVALENT) return dlcmp;
00069 
00070     const WFinder& other = dynamic_cast<const WFinder&>(p);
00071     return (cmp(_minmass, other._minmass) || cmp(_maxmass, other._maxmass) ||
00072             cmp(_useTransverseMass, other._useTransverseMass) ||
00073             cmp(_etMiss, other._etMiss) ||
00074             cmp(_pid, other._pid) || cmp(_trackPhotons, other._trackPhotons));
00075   }
00076 
00077 
00078   void WFinder::project(const Event& e) {
00079     clear();
00080 
00081     Beam beam;
00082     beam.project(e);
00083     const double sqrtS = beam.sqrtS();
00084 
00085     // Check missing ET
00086     const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00087     const FourMomentum& Pmiss = FourMomentum(sqrtS,0,0,0) - vismom.visibleMomentum();
00088 
00089     const double met = vismom.vectorEt().mod();
00090     MSG_TRACE("MET = " << met/GeV << " GeV vs. required = " << _etMiss/GeV << " GeV");
00091     if (met < _etMiss) {
00092       MSG_DEBUG("Not enough missing ET: " << met/GeV << " GeV vs. " << _etMiss/GeV << " GeV");
00093       return;
00094     }
00095 
00096 
00097     const DressedLeptons& leptons = applyProjection<DressedLeptons>(e, "DressedLeptons");
00098 
00099     if ( leptons.dressedLeptons().empty() ) {
00100         MSG_DEBUG("No dressed leptons.");
00101         return;
00102     }
00103 
00104     MSG_DEBUG("Found at least one dressed lepton: " << leptons.dressedLeptons()[0].momentum() );
00105     MSG_DEBUG("Found missing 4-momentum: " << Pmiss );
00106 
00107     // Make and register an invariant mass final state for the W decay leptons
00108     vector<pair<PdgId, PdgId> > l_nu_ids;
00109     l_nu_ids += make_pair(abs(_pid), -_nu_pid);
00110     l_nu_ids += make_pair(-abs(_pid), _nu_pid);
00111     InvMassFinalState imfs(l_nu_ids, _minmass, _maxmass, _masstarget);
00112     imfs.useTransverseMass(_useTransverseMass);
00113     Particles tmp;
00114     tmp.insert(tmp.end(), leptons.dressedLeptons().begin(), leptons.dressedLeptons().end());
00115     tmp.push_back(Particle( _nu_pid,Pmiss)); // fake neutrino from Et miss vector
00116     tmp.push_back(Particle(-_nu_pid,Pmiss)); // fake antineutrino from Et miss vector
00117     imfs.calc(tmp);
00118 
00119     if (imfs.particlePairs().size() < 1) return;
00120 
00121     ParticlePair Wconstituents(imfs.particlePairs()[0]);
00122     Particle p1(Wconstituents.first), p2(Wconstituents.second);
00123 
00124     if (threeCharge(p1) == 0) {
00125       _constituentLeptons += p2;
00126       _constituentNeutrinos += p1;
00127     } else {
00128       _constituentLeptons += p1;
00129       _constituentNeutrinos += p2;
00130     }
00131 
00132     FourMomentum pW = p1.momentum() + p2.momentum();
00133     const int w3charge = threeCharge(p1) + threeCharge(p2);
00134     assert(abs(w3charge) == 3);
00135     const int wcharge = w3charge/3;
00136 
00137     stringstream msg;
00138     string wsign = (wcharge == 1) ? "+" : "-";
00139     string wstr = "W" + wsign;
00140     msg << wstr << " " << pW << " reconstructed from: " << "\n"
00141         << "   " << p1.momentum() << " " << p1.pid() << "\n"
00142         << " + " << p2.momentum() << " " << p2.pid();
00143     MSG_DEBUG(msg.str());
00144 
00145     // Make W Particle and insert into particles list
00146     const PdgId wpid = (wcharge == 1) ? PID::WPLUSBOSON : PID::WMINUSBOSON;
00147     _bosons.push_back(Particle(wpid, pW));
00148 
00149     // Find the DressedLeptons which survived the IMFS cut such that we can
00150     // extract their original particles
00151 
00152     // TODO: do we need to add all used invisibles to _theParticles ?
00153 
00154     foreach (const Particle& p, _constituentLeptons) {
00155       foreach (const DressedLepton& l, leptons.dressedLeptons()) {
00156         if (p.pid() == l.pid() && p.momentum() == l.momentum()) {
00157           _theParticles.push_back(l.constituentLepton());
00158           if (_trackPhotons) {
00159             _theParticles.insert(_theParticles.end(), l.constituentPhotons().begin(), l.constituentPhotons().end());
00160           }
00161         }
00162       }
00163     }
00164   }
00165 
00166 
00167 }