00001
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
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
00067 IdentifiedFinalState neutrinos;
00068 neutrinos.acceptNeutrinos();
00069 addProjection(neutrinos, "Neutrinos");
00070
00071
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
00081 MissingMomentum vismom(fs);
00082 addProjection(vismom, "MissingET");
00083
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
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
00156 const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00157
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
00165 const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00166 _bosons.push_back(Particle(wpid, pW));
00167
00168
00169
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 }