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