ATLAS_2014_I1304688.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/VetoedFinalState.hh" 00004 #include "Rivet/Projections/IdentifiedFinalState.hh" 00005 #include "Rivet/Projections/PromptFinalState.hh" 00006 #include "Rivet/Projections/DressedLeptons.hh" 00007 #include "Rivet/Projections/FastJets.hh" 00008 #include <bitset> 00009 00010 namespace Rivet { 00011 00012 00013 00014 00015 /// @brief ATLAS 7 TeV jets in ttbar events analysis 00016 /// 00017 /// @author W. H. Bell <W.Bell@cern.ch> 00018 /// @author A. Grohsjean <alexander.grohsjean@desy.de> 00019 class ATLAS_2014_I1304688 : public Analysis { 00020 public: 00021 00022 ATLAS_2014_I1304688(): 00023 Analysis("ATLAS_2014_I1304688"), 00024 _jet_ntag(0), 00025 _met_et(0.), 00026 _met_phi(0.), 00027 _hMap(), 00028 //_chanLimit(3), 00029 _histLimit(6) 00030 { } 00031 00032 00033 void init() { 00034 // Eta ranges 00035 /// @todo 1 MeV? Really? 00036 Cut eta_full = Cuts::abseta < 5.0 && Cuts::pT > 1.0*MeV; 00037 Cut eta_lep = Cuts::abseta < 2.5; 00038 00039 // All final state particles 00040 FinalState fs(eta_full); 00041 00042 // Get photons to dress leptons 00043 IdentifiedFinalState photons(fs); 00044 photons.acceptIdPair(PID::PHOTON); 00045 00046 // Projection to find the electrons 00047 IdentifiedFinalState el_id(fs); 00048 el_id.acceptIdPair(PID::ELECTRON); 00049 PromptFinalState electrons(el_id); 00050 electrons.acceptTauDecays(true); 00051 addProjection(electrons, "electrons"); 00052 DressedLeptons dressedelectrons(photons, electrons, 0.1, eta_lep && Cuts::pT > 25*GeV, true, true); 00053 addProjection(dressedelectrons, "dressedelectrons"); 00054 DressedLeptons vetodressedelectrons(photons, electrons, 0.1, eta_lep && Cuts::pT >= 15*GeV, true, true); 00055 addProjection(vetodressedelectrons, "vetodressedelectrons"); 00056 DressedLeptons ewdressedelectrons(photons, electrons, 0.1, eta_full, true, true); 00057 addProjection(ewdressedelectrons, "ewdressedelectrons"); 00058 00059 // Projection to find the muons 00060 IdentifiedFinalState mu_id(fs); 00061 mu_id.acceptIdPair(PID::MUON); 00062 PromptFinalState muons(mu_id); 00063 muons.acceptTauDecays(true); 00064 addProjection(muons, "muons"); 00065 vector<pair<double, double> > eta_muon; 00066 DressedLeptons dressedmuons(photons, muons, 0.1, eta_lep && Cuts::pT >= 25*GeV, true, true); 00067 addProjection(dressedmuons, "dressedmuons"); 00068 DressedLeptons vetodressedmuons(photons, muons, 0.1, eta_lep && Cuts::pT >= 15*GeV, true, true); 00069 addProjection(vetodressedmuons, "vetodressedmuons"); 00070 DressedLeptons ewdressedmuons(photons, muons, 0.1, eta_full, true, true); 00071 addProjection(ewdressedmuons, "ewdressedmuons"); 00072 00073 // Projection to find neutrinos and produce MET 00074 IdentifiedFinalState nu_id; 00075 nu_id.acceptNeutrinos(); 00076 PromptFinalState neutrinos(nu_id); 00077 neutrinos.acceptTauDecays(true); 00078 addProjection(neutrinos, "neutrinos"); 00079 00080 // Jet clustering. 00081 VetoedFinalState vfs; 00082 vfs.addVetoOnThisFinalState(ewdressedelectrons); 00083 vfs.addVetoOnThisFinalState(ewdressedmuons); 00084 vfs.addVetoOnThisFinalState(neutrinos); 00085 FastJets jets(vfs, FastJets::ANTIKT, 0.4); 00086 jets.useInvisibles(); 00087 addProjection(jets, "jets"); 00088 00089 // Book histograms 00090 for (unsigned int ihist = 0; ihist < _histLimit ; ihist++) { 00091 const unsigned int threshLimit = _thresholdLimit(ihist); 00092 for (unsigned int ithres = 0; ithres < threshLimit; ithres++) { 00093 _histogram(ihist, ithres); // Create all histograms 00094 } 00095 } 00096 } 00097 00098 00099 void analyze(const Event& event) { 00100 00101 // Get the selected objects, using the projections. 00102 _dressedelectrons = sortByPt(applyProjection<DressedLeptons>(event, "dressedelectrons").dressedLeptons()); 00103 _vetodressedelectrons = applyProjection<DressedLeptons>(event, "vetodressedelectrons").dressedLeptons(); 00104 00105 _dressedmuons = sortByPt(applyProjection<DressedLeptons>(event, "dressedmuons").dressedLeptons()); 00106 _vetodressedmuons = applyProjection<DressedLeptons>(event, "vetodressedmuons").dressedLeptons(); 00107 00108 _neutrinos = applyProjection<PromptFinalState>(event, "neutrinos").particlesByPt(); 00109 00110 _jets = applyProjection<FastJets>(event, "jets").jetsByPt(Cuts::pT > 25*GeV && Cuts::abseta < 2.5); 00111 00112 00113 // Calculate the missing ET, using the prompt neutrinos only (really?) 00114 /// @todo Why not use MissingMomentum? 00115 FourMomentum pmet; 00116 foreach (const Particle& p, _neutrinos) pmet += p.momentum(); 00117 _met_et = pmet.pT(); 00118 _met_phi = pmet.phi(); 00119 00120 // Check overlap of jets/leptons. 00121 unsigned int i,j; 00122 _jet_ntag = 0; 00123 _overlap = false; 00124 for (i = 0; i < _jets.size(); i++) { 00125 const Jet& jet = _jets[i]; 00126 // If dR(el,jet) < 0.4 skip the event 00127 foreach (const DressedLepton& el, _dressedelectrons) { 00128 if (deltaR(jet, el) < 0.4) _overlap = true; 00129 } 00130 // If dR(mu,jet) < 0.4 skip the event 00131 foreach (const DressedLepton& mu, _dressedmuons) { 00132 if (deltaR(jet, mu) < 0.4) _overlap = true; 00133 } 00134 // If dR(jet,jet) < 0.5 skip the event 00135 for (j = 0; j < _jets.size(); j++) { 00136 const Jet& jet2 = _jets[j]; 00137 if (i == j) continue; // skip the diagonal 00138 if (deltaR(jet, jet2) < 0.5) _overlap = true; 00139 } 00140 // Count the number of b-tags 00141 if (!jet.bTags().empty()) _jet_ntag += 1; 00142 } 00143 00144 // Evaluate basic event selection 00145 unsigned int ejets_bits = 0, mujets_bits = 0; 00146 bool pass_ejets = _ejets(ejets_bits); 00147 bool pass_mujets = _mujets(mujets_bits); 00148 00149 // Remove events with object overlap 00150 if (_overlap) vetoEvent; 00151 // basic event selection requirements 00152 if (!pass_ejets && !pass_mujets) vetoEvent; 00153 00154 // Check if the additional pT threshold requirements are passed 00155 bool pass_jetPt = _additionalJetCuts(); 00156 00157 // Count the jet multiplicity for 25, 40, 60 and 80GeV 00158 unsigned int ithres, jet_n[4]; 00159 for (ithres = 0; ithres < 4; ithres++) { 00160 jet_n[ithres] = _countJets(ithres); 00161 } 00162 00163 // Fill histograms 00164 const double weight = event.weight(); 00165 for (unsigned int ihist = 0; ihist < 6; ihist++) { 00166 if (ihist > 0 && !pass_jetPt) continue; // additional pT threshold cuts for pT plots 00167 unsigned int threshLimit = _thresholdLimit(ihist); 00168 for (ithres = 0; ithres < threshLimit; ithres++) { 00169 if (jet_n[ithres] < 3) continue; // 3 or more jets for ljets 00170 // Fill 00171 if (ihist == 0) _histogram(ihist, ithres)->fill(jet_n[ithres], weight); // njets 00172 else if (ihist == 1) _histogram(ihist, ithres)->fill(_jets[0].pT(), weight); // leading jet pT 00173 else if (ihist == 2) _histogram(ihist, ithres)->fill(_jets[1].pT(), weight); // 2nd jet pT 00174 else if (ihist == 3 && jet_n[ithres] >= 3) _histogram(ihist, ithres)->fill(_jets[2].pT(), weight); // 3rd jet pT 00175 else if (ihist == 4 && jet_n[ithres] >= 4) _histogram(ihist, ithres)->fill(_jets[3].pT(), weight); // 4th jet pT 00176 else if (ihist == 5 && jet_n[ithres] >= 5) _histogram(ihist, ithres)->fill(_jets[4].pT(), weight); // 5th jet pT 00177 } 00178 } 00179 } 00180 00181 00182 void finalize() { 00183 // Normalize to cross-section 00184 const double norm = crossSection()/sumOfWeights(); 00185 typedef map<unsigned int, Histo1DPtr>::value_type IDtoHisto1DPtr; ///< @todo Remove when C++11 allowed 00186 foreach (IDtoHisto1DPtr ihpair, _hMap) scale(ihpair.second, norm); ///< @todo Use normalize(ihpair.second, crossSection()) 00187 // Calc averages 00188 for (unsigned int ihist = 0; ihist < _histLimit ; ihist++) { 00189 unsigned int threshLimit = _thresholdLimit(ihist); 00190 for (unsigned int ithres = 0; ithres < threshLimit; ithres++) { 00191 scale(_histogram(ihist, ithres), 0.5); 00192 } 00193 } 00194 } 00195 00196 00197 00198 private: 00199 00200 00201 /// @name Cut helper functions 00202 //@{ 00203 00204 // Event selection functions 00205 bool _ejets(unsigned int& cutBits) { 00206 // 1. More than zero good electrons 00207 cutBits += 1; if (_dressedelectrons.size() == 0) return false; 00208 // 2. No additional electrons passing the veto selection 00209 cutBits += 1 << 1; if (_vetodressedelectrons.size() > 1) return false; 00210 // 3. No muons passing the veto selection 00211 cutBits += 1 << 2; if (_vetodressedmuons.size() > 0) return false; 00212 // 4. total neutrino pT > 30 GeV 00213 cutBits += 1 << 3; if (_met_et <= 30.0*GeV) return false; 00214 // 5. MTW > 35 GeV 00215 cutBits += 1 << 4; 00216 if (_transMass(_dressedelectrons[0].pT(), _dressedelectrons[0].phi(), _met_et, _met_phi) <= 35*GeV) return false; 00217 // 6. At least one b-tagged jet 00218 cutBits += 1 << 5; if (_jet_ntag < 1) return false; 00219 // 7. At least three good jets 00220 cutBits += 1 << 6; if (_jets.size() < 3) return false; 00221 cutBits += 1 << 7; 00222 return true; 00223 } 00224 00225 bool _mujets(unsigned int& cutBits) { 00226 // 1. More than zero good muons 00227 cutBits += 1; if (_dressedmuons.size() == 0) return false; 00228 // 2. No additional muons passing the veto selection 00229 cutBits += 1 << 1; if (_vetodressedmuons.size() > 1) return false; 00230 // 3. No electrons passing the veto selection 00231 cutBits += 1 << 2; if (_vetodressedelectrons.size() > 0) return false; 00232 // 4. total neutrino pT > 30 GeV 00233 cutBits += 1 << 3; if (_met_et <= 30*GeV) return false; 00234 // 5. MTW > 35 GeV 00235 cutBits += 1 << 4; 00236 if (_transMass(_dressedmuons[0].pT(), _dressedmuons[0].phi(), _met_et, _met_phi) <= 35*GeV) return false; 00237 // 6. At least one b-tagged jet 00238 cutBits += 1 << 5; if (_jet_ntag < 1) return false; 00239 // 7. At least three good jets 00240 cutBits += 1 << 6; if (_jets.size() < 3) return false; 00241 cutBits += 1 << 7; 00242 return true; 00243 } 00244 00245 bool _additionalJetCuts() { 00246 if (_jets.size() < 2) return false; 00247 if (_jets[0].pT() <= 50*GeV || _jets[1].pT() <= 35*GeV) return false; 00248 return true; 00249 } 00250 00251 //@} 00252 00253 00254 /// @name Histogram helper functions 00255 //@{ 00256 00257 unsigned int _thresholdLimit(unsigned int histId) { 00258 if (histId == 0) return 4; 00259 return 1; 00260 } 00261 00262 Histo1DPtr _histogram(unsigned int histId, unsigned int thresholdId) { 00263 assert(histId < _histLimit); 00264 assert(thresholdId < _thresholdLimit(histId)); 00265 00266 const unsigned int hInd = (histId == 0) ? thresholdId : (_thresholdLimit(0) + (histId-1) + thresholdId); 00267 if (_hMap.find(hInd) != _hMap.end()) return _hMap[hInd]; 00268 00269 if (histId == 0) _hMap.insert(make_pair(hInd,bookHisto1D(1,thresholdId+1,1))); 00270 else _hMap.insert(make_pair(hInd,bookHisto1D(2,histId,1))); 00271 return _hMap[hInd]; 00272 } 00273 00274 //@} 00275 00276 00277 /// @name Physics object helper functions 00278 //@{ 00279 00280 double _transMass(double ptLep, double phiLep, double met, double phiMet) { 00281 return sqrt(2.0*ptLep*met*(1 - cos(phiLep-phiMet))); 00282 } 00283 00284 unsigned int _countJets(unsigned int ithres) { 00285 if (ithres > 4) assert(0); 00286 double pTcut[4] = {25.,40.,60.,80.}; 00287 unsigned int i, jet_n = 0; 00288 for (i = 0; i < _jets.size(); i++) { 00289 if (_jets[i].pT() > pTcut[ithres]) jet_n++; 00290 } 00291 unsigned int ncutoff[4] = {8,7,6,5}; 00292 if (jet_n > ncutoff[ithres]) jet_n = ncutoff[ithres]; 00293 return jet_n; 00294 } 00295 00296 //@} 00297 00298 00299 private: 00300 00301 /// @name Objects that are used by the event selection decisions 00302 //@{ 00303 vector<DressedLepton> _dressedelectrons; 00304 vector<DressedLepton> _vetodressedelectrons; 00305 vector<DressedLepton> _dressedmuons; 00306 vector<DressedLepton> _vetodressedmuons; 00307 Particles _neutrinos; 00308 Jets _jets; 00309 unsigned int _jet_ntag; 00310 /// @todo Why not store the whole MET FourMomentum? 00311 double _met_et, _met_phi; 00312 bool _overlap; 00313 00314 map<unsigned int, Histo1DPtr> _hMap; 00315 //unsigned int _chanLimit; 00316 unsigned int _histLimit; 00317 //@} 00318 00319 }; 00320 00321 00322 00323 // Declare the class as a hook for the plugin system 00324 DECLARE_RIVET_PLUGIN(ATLAS_2014_I1304688); 00325 00326 } Generated on Thu Mar 10 2016 08:29:47 for The Rivet MC analysis system by ![]() |