00001
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
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
00071 IdentifiedFinalState fs_nu;
00072 fs_nu.acceptNeutrinos();
00073
00074
00075 MergedFinalState mergedFS(fs_l, fs_nu);
00076
00077
00078 _m2_min = m2_min;
00079 _m2_max = m2_max;
00080
00081
00082 _etMiss = missingET;
00083
00084
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
00092 ClusteredPhotons cphotons(FinalState(), imfs, dRmax);
00093 addProjection(cphotons, "CPhotons");
00094
00095
00096 MergedFinalState signalFS(imfs, cphotons);
00097 addProjection(cphotons, "SignalParticles");
00098
00099
00100 TotalVisibleMomentum vismom(signalFS);
00101 addProjection(vismom, "MissingET");
00102
00103
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
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
00174 const TotalVisibleMomentum& vismom = applyProjection<TotalVisibleMomentum>(e, "MissingET");
00175
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
00183 if (!inRange(pW.mass()/GeV, _m2_min, _m2_max)) return;
00184 getLog() << Log::DEBUG << msg.str() << endl;
00185
00186
00187 const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00188 _theParticles.push_back(Particle(wpid, pW));
00189 }
00190
00191
00192 }