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/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(signalFS, "SignalParticles");
00098
00099
00100 MissingMomentum 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 const FinalState& WFinder::clusteredPhotonsFinalState() const
00129 {
00130 return getProjection<FinalState>("CPhotons");
00131 }
00132
00133
00134 int WFinder::compare(const Projection& p) const {
00135 PCmp cmp = mkNamedPCmp(p, "IMFS");
00136 if (cmp != EQUIVALENT) return cmp;
00137
00138 cmp = mkNamedPCmp(p, "CPhotons");
00139 if (cmp != EQUIVALENT) return cmp;
00140
00141 return EQUIVALENT;
00142 }
00143
00144
00145 void WFinder::clear() {
00146 _theParticles.clear();
00147 }
00148
00149
00150 void WFinder::project(const Event& e) {
00151 clear();
00152 const InvMassFinalState& imfs = applyProjection<InvMassFinalState>(e, "IMFS");
00153
00154 Particle p1,p2;
00155 if(imfs.particles().size() == 2) {
00156 p1 = imfs.particles()[0];
00157 p2 = imfs.particles()[1];
00158 }
00159 else {
00160
00161 if(imfs.particles().empty()) {
00162 getLog() << Log::DEBUG << "No W+- candidates found" << " "
00163 << imfs.particles().size() << " " << endl;
00164 return;
00165 }
00166
00167 double deltaM = 1e30;
00168 for(unsigned int ix=0;ix<imfs.particlePairs().size();++ix) {
00169 FourMomentum pW = imfs.particlePairs()[ix].first .momentum()+
00170 imfs.particlePairs()[ix].second.momentum();
00171 double mW = pW.mass();
00172 if(abs(mW-80.403)<deltaM) {
00173 deltaM = abs(mW-80.4);
00174 p1 = imfs.particlePairs()[ix].first ;
00175 p2 = imfs.particlePairs()[ix].second;
00176 }
00177 }
00178 }
00179
00180 FourMomentum pW = p1.momentum() + p2.momentum();
00181 const int w3charge = PID::threeCharge(p1) + PID::threeCharge(p2);
00182 assert(abs(w3charge) == 3);
00183 const int wcharge = w3charge/3;
00184
00185 stringstream msg;
00186 string wsign = (wcharge == 1) ? "+" : "-";
00187 string wstr = "W" + wsign;
00188 msg << wstr << " reconstructed from: " << endl
00189 << " " << p1.momentum() << " " << p1.pdgId() << endl
00190 << " + " << p2.momentum() << " " << p2.pdgId() << endl;
00191
00192
00193 const FinalState& photons = applyProjection<FinalState>(e, "CPhotons");
00194 foreach (const Particle& photon, photons.particles()) {
00195 msg << " + " << photon.momentum() << " " << photon.pdgId() << endl;
00196 pW += photon.momentum();
00197 }
00198 msg << " = " << pW;
00199
00200
00201 const MissingMomentum& vismom = applyProjection<MissingMomentum>(e, "MissingET");
00202
00203 if (vismom.scalarET() < _etMiss) {
00204 getLog() << Log::DEBUG << "Not enough missing ET: " << vismom.scalarET()/GeV
00205 << " GeV vs. " << _etMiss/GeV << " GeV" << endl;
00206 return;
00207 }
00208
00209
00210 if (!inRange(pW.mass()/GeV, _m2_min, _m2_max)) return;
00211 getLog() << Log::DEBUG << msg.str() << endl;
00212
00213
00214 const PdgId wpid = (wcharge == 1) ? WPLUSBOSON : WMINUSBOSON;
00215 _theParticles.push_back(Particle(wpid, pW));
00216 }
00217
00218
00219 }