PDG_TAUS.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/TauFinder.hh" 00004 00005 namespace Rivet { 00006 00007 00008 class PDG_TAUS : public Analysis { 00009 public: 00010 00011 /// Constructor 00012 PDG_TAUS() 00013 : Analysis("PDG_TAUS"), 00014 _weights_had(0), 00015 _weights_mu(0), 00016 _weights_el(0) 00017 { } 00018 00019 00020 /// @name Analysis methods 00021 //@{ 00022 00023 /// Book histograms and initialise projections before the run 00024 void init() { 00025 00026 TauFinder tauleptonic(TauFinder::LEPTONIC); // open cuts, leptonic decays 00027 addProjection(tauleptonic, "TauLeptonic"); 00028 00029 TauFinder tauhadronic(TauFinder::HADRONIC); // open cuts, hadronic decays 00030 addProjection(tauhadronic, "TauHadronic"); 00031 00032 populateDecayMap(); 00033 00034 _h_ratio_mu = bookHisto1D(1, 1, 1); 00035 _h_ratio_el = bookHisto1D(1, 1, 2); 00036 _h_1prong_pinu = bookHisto1D(2, 1, 1); 00037 _h_1prong_Kpnu = bookHisto1D(2, 1, 2); 00038 _h_1prong_pipinu = bookHisto1D(2, 1, 3); 00039 _h_1prong_Kppinu = bookHisto1D(2, 1, 4); 00040 _h_1prong_pipipinu = bookHisto1D(2, 1, 5); 00041 _h_1prong_Knpinu = bookHisto1D(2, 1, 6); 00042 _h_3prong_pipipinu = bookHisto1D(2, 2, 1); 00043 _h_5prong = bookHisto1D(2, 3, 1); 00044 } 00045 00046 00047 /// Perform the per-event analysis 00048 void analyze(const Event& e) { 00049 const double weight = e.weight(); 00050 00051 const TauFinder& taulep = applyProjection<TauFinder>(e, "TauLeptonic"); 00052 const TauFinder& tauhad = applyProjection<TauFinder>(e, "TauHadronic"); 00053 00054 // Hadronic tau decays --- prong decays 00055 foreach(const Particle& tau, tauhad.taus()) { 00056 _weights_had += weight; 00057 int prongs = countProngs(tau); // number of charged particles among decay products 00058 // Only do 1 prong decays here 00059 if (prongs == 1) { 00060 ////// Exclusive decay modes "1-prong" 00061 if (analyzeDecay(tau, decay_pids["pinu"], true)) _h_1prong_pinu->fill(1, weight); 00062 if (analyzeDecay(tau, decay_pids["Kpnu"], true)) _h_1prong_Kpnu->fill(1, weight); 00063 if (analyzeDecay(tau, decay_pids["pipinu"], true)) _h_1prong_pipinu->fill(1, weight); 00064 if (analyzeDecay(tau, decay_pids["Kppinu"] , true)) _h_1prong_Kppinu->fill(1, weight); 00065 if (analyzeDecay(tau, decay_pids["pipipinu"], true)) _h_1prong_pipipinu->fill(1, weight); 00066 // Kshort, Klong --- (twice) filling the K0 labelled PDG histo 00067 if (analyzeDecay(tau, decay_pids["KSpinu"] , true)) _h_1prong_Knpinu->fill(1, weight); 00068 if (analyzeDecay(tau, decay_pids["KLpinu"] , true)) _h_1prong_Knpinu->fill(1, weight); 00069 } 00070 else if (prongs == 3) { 00071 if (analyzeDecay(tau, decay_pids["3pipipinu"], true)) _h_3prong_pipipinu->fill(1, weight); 00072 } 00073 else if (prongs == 5 && !any(tau.children(), HasAbsPID(310))) _h_5prong->fill(1, weight); 00074 } 00075 00076 // Leptonic tau decays --- look for radiative and non-radiative 1 prong decays 00077 foreach(const Particle& tau, taulep.taus()) { 00078 int prongs = countProngs(tau); // number of charged particles among decay products 00079 // Only do 1 prong decays here 00080 if (prongs == 1) { 00081 analyzeRadiativeDecay(tau, decay_pids["muids"], _weights_mu, weight, true, _h_ratio_mu); 00082 analyzeRadiativeDecay(tau, decay_pids["elids"], _weights_el, weight, true, _h_ratio_el); 00083 } 00084 } 00085 } 00086 00087 00088 /// Normalise histograms etc., after the run 00089 void finalize() { 00090 scale(_h_ratio_mu, 1./_weights_mu); 00091 scale(_h_ratio_el, 1./_weights_el); 00092 00093 const double norm = _weights_had + _weights_mu + _weights_el; 00094 scale(_h_1prong_pinu, 1./norm); 00095 scale(_h_1prong_Kpnu, 1./norm); 00096 scale(_h_1prong_pipinu, 1./norm); 00097 scale(_h_1prong_Kppinu, 1./norm); 00098 scale(_h_1prong_pipipinu, 1./norm); 00099 scale(_h_1prong_Knpinu, 1./norm); 00100 scale(_h_3prong_pipipinu, 1./norm); 00101 scale(_h_5prong, 1./norm); 00102 } 00103 00104 00105 // Short hand 00106 bool contains(Particle& mother, int id, bool abs=false) { 00107 if (abs) return any(mother.children(), HasAbsPID(id)); 00108 return any(mother.children(), HasPID(id)); 00109 } 00110 00111 00112 // Count charged decay products 00113 int countProngs(Particle mother) { 00114 int n_prongs = 0; 00115 foreach(Particle p, mother.children()) 00116 if (p.threeCharge()!=0) ++n_prongs; 00117 return n_prongs; 00118 } 00119 00120 00121 // Set up a lookup table for decays 00122 void populateDecayMap() { 00123 decay_pids["muids"] += 13,14,16; 00124 decay_pids["elids"] += 11,12,16; 00125 decay_pids["pinu"] += 211,16; 00126 decay_pids["Kpnu"] += 321,16; 00127 decay_pids["pipinu"] += 111,211,16; 00128 decay_pids["Kppinu"] += 111,321,16; 00129 decay_pids["pipipinu"] += 111,111,211,16; 00130 decay_pids["KSpinu"] += 211,310,16; 00131 decay_pids["KLpinu"] += 211,130,16; 00132 decay_pids["3pipipinu"] += 211,211,211,16; 00133 } 00134 00135 00136 bool analyzeDecay(Particle mother, vector<int> ids, bool absolute) { 00137 // There is no point in looking for decays with less particles than to be analysed 00138 if (mother.children().size() == ids.size()) { 00139 bool decayfound = true; 00140 foreach (int id, ids) { 00141 if (!contains(mother, id, absolute)) decayfound = false; 00142 } 00143 return decayfound; 00144 } // end of first if 00145 return false; 00146 } 00147 00148 00149 // Look for radiative (and non-radiative) tau decays to fill a ratio histo 00150 void analyzeRadiativeDecay(Particle mother, vector<int> ids, double &w_incl, double e_weight, bool absolute, Histo1DPtr h_ratio) { 00151 // w_incl ... reference to a global weight counter for all leptonic tau decays 00152 // e_weight ... the current event weight 00153 // h_ratio ... pointer to ratio histo --- filled with e_weight in case of radiative events only 00154 00155 // There is no point in looking for decays with less particles than to be analysed 00156 if (mother.children().size() >= ids.size()) { 00157 bool decayfound = true; 00158 foreach (int id, ids) { 00159 if (!contains(mother, id, absolute)) decayfound = false; 00160 } 00161 // Do not increment counters if the specified decay products were not found 00162 if (decayfound) { 00163 w_incl += e_weight; // the (global) weight counter for leptonic decays 00164 bool radiative = any(mother.children(), HasPID(PID::PHOTON)); 00165 00166 // Only fill the histo if there is a radiative decay 00167 if (radiative) { 00168 // Iterate over decay products to find photon with 5MeV energy 00169 foreach (const Particle& son, mother.children()) { 00170 if (son.pid() == PID::PHOTON) { 00171 // Require photons to have at least 5 MeV energy in the rest frame of the tau 00172 // boosted taus 00173 if (!mother.momentum().boostVector().isZero()) { 00174 LorentzTransform cms_boost; 00175 Vector3 bv = -mother.momentum().boostVector(); 00176 cms_boost = LorentzTransform(bv); 00177 if (cms_boost.transform(son.momentum())[0]/MeV > 5.) { 00178 h_ratio->fill(1, e_weight); 00179 break; 00180 } 00181 } 00182 // not boosted taus 00183 else { 00184 if (son.momentum()[0]/MeV > 5.) { 00185 h_ratio->fill(1, e_weight); 00186 break; 00187 } 00188 } 00189 } 00190 } // end loop over decay products 00191 } // end of radiative 00192 } // end of decayfound 00193 } // end of first if 00194 } 00195 00196 00197 private: 00198 00199 /// @name Histograms 00200 //@{ 00201 Histo1DPtr _h_ratio_mu, _h_ratio_el; 00202 Histo1DPtr _h_1prong_pinu, _h_1prong_Kpnu, _h_1prong_Kppinu, _h_1prong_pipinu, _h_1prong_pipipinu, _h_1prong_Knpinu; 00203 Histo1DPtr _h_3prong_pipipinu; 00204 Histo1DPtr _h_5prong; 00205 //@} 00206 00207 double _weights_had, _weights_mu, _weights_el; 00208 map<string, vector<int> > decay_pids; 00209 00210 }; 00211 00212 00213 // The hook for the plugin system 00214 DECLARE_RIVET_PLUGIN(PDG_TAUS); 00215 00216 } Generated on Thu Mar 10 2016 08:29:52 for The Rivet MC analysis system by ![]() |