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