ATLAS_2012_I1204447.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/FinalState.hh" 00004 #include "Rivet/Projections/ChargedFinalState.hh" 00005 #include "Rivet/Projections/VisibleFinalState.hh" 00006 #include "Rivet/Projections/VetoedFinalState.hh" 00007 #include "Rivet/Projections/IdentifiedFinalState.hh" 00008 #include "Rivet/Projections/UnstableFinalState.hh" 00009 #include "Rivet/Projections/FastJets.hh" 00010 00011 namespace Rivet { 00012 00013 00014 class ATLAS_2012_I1204447 : public Analysis { 00015 public: 00016 00017 /// Constructor 00018 ATLAS_2012_I1204447() 00019 : Analysis("ATLAS_2012_I1204447") { } 00020 00021 00022 /// Book histograms and initialise projections before the run 00023 void init() { 00024 00025 // To calculate the acceptance without having the fiducial lepton efficiencies included, this part can be turned off 00026 _use_fiducial_lepton_efficiency = true; 00027 00028 // Random numbers for simulation of ATLAS detector reconstruction efficiency 00029 srand(160385); 00030 00031 // Read in all signal regions 00032 _signal_regions = getSignalRegions(); 00033 00034 // Set number of events per signal region to 0 00035 for (size_t i = 0; i < _signal_regions.size(); i++) 00036 _eventCountsPerSR[_signal_regions[i]] = 0.0; 00037 00038 // Final state including all charged and neutral particles 00039 const FinalState fs(-5.0, 5.0, 1*GeV); 00040 addProjection(fs, "FS"); 00041 00042 // Final state including all charged particles 00043 addProjection(ChargedFinalState(-2.5,2.5, 1*GeV), "CFS"); 00044 00045 // Final state including all visible particles (to calculate MET, Jets etc.) 00046 addProjection(VisibleFinalState(-5.0,5.0), "VFS"); 00047 00048 // Final state including all AntiKt 04 Jets 00049 VetoedFinalState vfs; 00050 vfs.addVetoPairId(PID::MUON); 00051 addProjection(FastJets(vfs, FastJets::ANTIKT, 0.4), "AntiKtJets04"); 00052 00053 // Final state including all unstable particles (including taus) 00054 addProjection(UnstableFinalState(-5.0,5.0, 5*GeV),"UFS"); 00055 00056 // Final state including all electrons 00057 IdentifiedFinalState elecs(-2.47,2.47, 10*GeV); 00058 elecs.acceptIdPair(PID::ELECTRON); 00059 addProjection(elecs, "elecs"); 00060 00061 // Final state including all muons 00062 IdentifiedFinalState muons(-2.5,2.5, 10*GeV); 00063 muons.acceptIdPair(PID::MUON); 00064 addProjection(muons, "muons"); 00065 00066 // Book histograms 00067 _h_HTlep_all = bookHisto1D("HTlep_all" , 30, 0, 1500); 00068 _h_HTjets_all = bookHisto1D("HTjets_all", 30, 0, 1500); 00069 _h_MET_all = bookHisto1D("MET_all" , 20, 0, 1000); 00070 _h_Meff_all = bookHisto1D("Meff_all" , 30, 0, 3000); 00071 00072 _h_e_n = bookHisto1D("e_n" , 10, -0.5, 9.5); 00073 _h_mu_n = bookHisto1D("mu_n" , 10, -0.5, 9.5); 00074 _h_tau_n = bookHisto1D("tau_n", 10, -0.5, 9.5); 00075 00076 _h_pt_1_3l = bookHisto1D("pt_1_3l", 100, 0, 2000); 00077 _h_pt_2_3l = bookHisto1D("pt_2_3l", 100, 0, 2000); 00078 _h_pt_3_3l = bookHisto1D("pt_3_3l", 100, 0, 2000); 00079 _h_pt_1_2ltau = bookHisto1D("pt_1_2ltau", 100, 0, 2000); 00080 _h_pt_2_2ltau = bookHisto1D("pt_2_2ltau", 100, 0, 2000); 00081 _h_pt_3_2ltau = bookHisto1D("pt_3_2ltau", 100, 0, 2000); 00082 00083 _h_excluded = bookHisto1D("excluded", 2, -0.5, 1.5); 00084 } 00085 00086 00087 /// Perform the per-event analysis 00088 void analyze(const Event& event) { 00089 00090 // Muons 00091 Particles muon_candidates; 00092 const Particles charged_tracks = applyProjection<ChargedFinalState>(event, "CFS").particles(); 00093 const Particles visible_particles = applyProjection<VisibleFinalState>(event, "VFS").particles(); 00094 foreach (const Particle& mu, applyProjection<IdentifiedFinalState>(event, "muons").particlesByPt()) { 00095 // Calculate pTCone30 variable (pT of all tracks within dR<0.3 - pT of muon itself) 00096 double pTinCone = -mu.pT(); 00097 foreach (const Particle& track, charged_tracks) { 00098 if (deltaR(mu.momentum(), track.momentum()) < 0.3) 00099 pTinCone += track.pT(); 00100 } 00101 00102 // Calculate eTCone30 variable (pT of all visible particles within dR<0.3) 00103 double eTinCone = 0.; 00104 foreach (const Particle& visible_particle, visible_particles) { 00105 if (visible_particle.abspid() != PID::MUON && inRange(deltaR(mu.momentum(), visible_particle.momentum()), 0.1, 0.3)) 00106 eTinCone += visible_particle.pT(); 00107 } 00108 00109 // Apply reconstruction efficiency and simulate reco 00110 int muon_id = 13; 00111 if ( mu.hasAncestor(15) || mu.hasAncestor(-15)) muon_id = 14; 00112 const double eff = (_use_fiducial_lepton_efficiency) ? apply_reco_eff(muon_id, mu) : 1.0; 00113 const bool keep_muon = rand()/static_cast<double>(RAND_MAX) <= eff; 00114 00115 // Keep muon if pTCone30/pT < 0.15 and eTCone30/pT < 0.2 and reconstructed 00116 if (keep_muon && pTinCone/mu.pT() <= 0.15 && eTinCone/mu.pT() < 0.2) 00117 muon_candidates.push_back(mu); 00118 } 00119 00120 00121 // Electrons 00122 Particles electron_candidates; 00123 foreach (const Particle& e, applyProjection<IdentifiedFinalState>(event, "elecs").particlesByPt()) { 00124 // Neglect electrons in crack regions 00125 if (inRange(e.abseta(), 1.37, 1.52)) continue; 00126 00127 // Calculate pTCone30 variable (pT of all tracks within dR<0.3 - pT of electron itself) 00128 double pTinCone = -e.pT(); 00129 foreach (const Particle& track, charged_tracks) { 00130 if (deltaR(e.momentum(), track.momentum()) < 0.3) pTinCone += track.pT(); 00131 } 00132 00133 // Calculate eTCone30 variable (pT of all visible particles (except muons) within dR<0.3) 00134 double eTinCone = 0.; 00135 foreach (const Particle& visible_particle, visible_particles) { 00136 if (visible_particle.abspid() != PID::MUON && inRange(deltaR(e.momentum(), visible_particle.momentum()), 0.1, 0.3)) 00137 eTinCone += visible_particle.pT(); 00138 } 00139 00140 // Apply reconstruction efficiency and simulate reco 00141 int elec_id = 11; 00142 if (e.hasAncestor(15) || e.hasAncestor(-15)) elec_id = 12; 00143 const double eff = (_use_fiducial_lepton_efficiency) ? apply_reco_eff(elec_id, e) : 1.0; 00144 const bool keep_elec = rand()/static_cast<double>(RAND_MAX) <= eff; 00145 00146 // Keep electron if pTCone30/pT < 0.13 and eTCone30/pT < 0.2 and reconstructed 00147 if (keep_elec && pTinCone/e.pT() <= 0.13 && eTinCone/e.pT() < 0.2) 00148 electron_candidates.push_back(e); 00149 } 00150 00151 00152 // Taus 00153 /// @todo This could benefit from a tau finder projection 00154 Particles tau_candidates; 00155 foreach (const Particle& tau, applyProjection<UnstableFinalState>(event, "UFS").particlesByPt()) { 00156 // Only pick taus out of all unstable particles 00157 if (tau.abspid() != PID::TAU) continue; 00158 00159 // Check that tau has decayed into daughter particles 00160 /// @todo Huh? Unstable taus with no decay vtx? Can use Particle.isStable()? But why in this situation? 00161 if (tau.genParticle()->end_vertex() == 0) continue; 00162 00163 // Calculate visible tau pT from pT of tau neutrino in tau decay for pT and |eta| cuts 00164 const FourMomentum tau_neutrino_mom = get_tau_neutrino_mom(tau); 00165 const FourMomentum visible_tau_mom = tau.momentum() - tau_neutrino_mom; 00166 if (visible_tau_mom.pT() < 15*GeV || visible_tau_mom.abseta() > 2.5) continue; 00167 00168 // Get prong number (number of tracks) in tau decay and check if tau decays leptonically 00169 unsigned int nprong = 0; 00170 bool lep_decaying_tau = false; 00171 get_prong_number(tau.genParticle(), nprong, lep_decaying_tau); 00172 00173 // Apply reconstruction efficiency 00174 int tau_id = 15; 00175 if (nprong == 1) tau_id = 15; 00176 else if (nprong == 3) tau_id = 16; 00177 00178 // Get fiducial lepton efficiency simulate reco efficiency 00179 const double eff = (_use_fiducial_lepton_efficiency) ? apply_reco_eff(tau_id, tau) : 1.0; 00180 const bool keep_tau = rand()/static_cast<double>(RAND_MAX) <= eff; 00181 00182 // Keep tau if nprong = 1, it decays hadronically, and it's reconstructed by the detector 00183 if ( !lep_decaying_tau && nprong == 1 && keep_tau) tau_candidates.push_back(tau); 00184 } 00185 00186 00187 // Jets (all anti-kt R=0.4 jets with pT > 25 GeV and eta < 4.9) 00188 Jets jet_candidates; 00189 foreach (const Jet& jet, applyProjection<FastJets>(event, "AntiKtJets04").jetsByPt(25*GeV)) { 00190 if (jet.abseta() < 4.9) jet_candidates.push_back(jet); 00191 } 00192 00193 00194 // ETmiss 00195 Particles vfs_particles = applyProjection<VisibleFinalState>(event, "VFS").particles(); 00196 FourMomentum pTmiss; 00197 foreach (const Particle& p, vfs_particles) pTmiss -= p.momentum(); 00198 double eTmiss = pTmiss.pT()/GeV; 00199 00200 00201 //------------------ 00202 // Overlap removal 00203 00204 // electron - electron 00205 Particles electron_candidates_2; 00206 for (size_t ie = 0; ie < electron_candidates.size(); ++ie) { 00207 const Particle & e = electron_candidates[ie]; 00208 bool away = true; 00209 // If electron pair within dR < 0.1: remove electron with lower pT 00210 for (size_t ie2=0; ie2 < electron_candidates_2.size(); ++ie2) { 00211 if ( deltaR( e.momentum(), electron_candidates_2[ie2].momentum()) < 0.1 ) { 00212 away = false; 00213 break; 00214 } 00215 } 00216 // If isolated keep it 00217 if ( away ) 00218 electron_candidates_2.push_back( e ); 00219 } 00220 // jet - electron 00221 Jets recon_jets; 00222 foreach (const Jet& jet, jet_candidates) { 00223 bool away = true; 00224 // if jet within dR < 0.2 of electron: remove jet 00225 foreach (const Particle& e, electron_candidates_2) { 00226 if (deltaR(e.momentum(), jet.momentum()) < 0.2) { 00227 away = false; 00228 break; 00229 } 00230 } 00231 // jet - tau 00232 if (away) { 00233 // If jet within dR < 0.2 of tau: remove jet 00234 foreach (const Particle& tau, tau_candidates) { 00235 if (deltaR(tau.momentum(), jet.momentum()) < 0.2) { 00236 away = false; 00237 break; 00238 } 00239 } 00240 } 00241 // If isolated keep it 00242 if ( away ) 00243 recon_jets.push_back( jet ); 00244 } 00245 00246 00247 // electron - jet 00248 Particles recon_leptons, recon_e; 00249 for (size_t ie = 0; ie < electron_candidates_2.size(); ++ie) { 00250 const Particle& e = electron_candidates_2[ie]; 00251 // If electron within 0.2 < dR < 0.4 from any jets: remove electron 00252 bool away = true; 00253 foreach (const Jet& jet, recon_jets) { 00254 if (deltaR(e.momentum(), jet.momentum()) < 0.4) { 00255 away = false; 00256 break; 00257 } 00258 } 00259 // electron - muon 00260 // if electron within dR < 0.1 of a muon: remove electron 00261 if (away) { 00262 foreach (const Particle& mu, muon_candidates) { 00263 if (deltaR(mu.momentum(), e.momentum()) < 0.1) { 00264 away = false; 00265 break; 00266 } 00267 } 00268 } 00269 // If isolated keep it 00270 if (away) { 00271 recon_e += e; 00272 recon_leptons += e; 00273 } 00274 } 00275 00276 00277 // tau - electron 00278 Particles recon_tau; 00279 foreach ( const Particle& tau, tau_candidates ) { 00280 bool away = true; 00281 // If tau within dR < 0.2 of an electron: remove tau 00282 foreach ( const Particle& e, recon_e ) { 00283 if (deltaR( tau.momentum(), e.momentum()) < 0.2) { 00284 away = false; 00285 break; 00286 } 00287 } 00288 // tau - muon 00289 // If tau within dR < 0.2 of a muon: remove tau 00290 if (away) { 00291 foreach (const Particle& mu, muon_candidates) { 00292 if (deltaR(tau.momentum(), mu.momentum()) < 0.2) { 00293 away = false; 00294 break; 00295 } 00296 } 00297 } 00298 // If isolated keep it 00299 if (away) recon_tau.push_back( tau ); 00300 } 00301 00302 // Muon - jet isolation 00303 Particles recon_mu, trigger_mu; 00304 // If muon within dR < 0.4 of a jet, remove muon 00305 foreach (const Particle& mu, muon_candidates) { 00306 bool away = true; 00307 foreach (const Jet& jet, recon_jets) { 00308 if ( deltaR( mu.momentum(), jet.momentum()) < 0.4 ) { 00309 away = false; 00310 break; 00311 } 00312 } 00313 if (away) { 00314 recon_mu.push_back( mu ); 00315 recon_leptons.push_back( mu ); 00316 if (mu.abseta() < 2.4) trigger_mu.push_back( mu ); 00317 } 00318 } 00319 00320 // End overlap removal 00321 //------------------ 00322 00323 00324 // Jet cleaning 00325 if (rand()/static_cast<double>(RAND_MAX) <= 0.42) { 00326 foreach (const Jet& jet, recon_jets) { 00327 const double eta = jet.rapidity(); 00328 const double phi = jet.azimuthalAngle(MINUSPI_PLUSPI); 00329 if (jet.pT() > 25*GeV && inRange(eta, -0.1, 1.5) && inRange(phi, -0.9, -0.5)) vetoEvent; 00330 } 00331 } 00332 00333 00334 // Post-isolation event cuts 00335 // Require at least 3 charged tracks in event 00336 if (charged_tracks.size() < 3) vetoEvent; 00337 00338 // And at least one e/mu passing trigger 00339 if (!( !recon_e .empty() && recon_e[0] .pT() > 25*GeV) && 00340 !( !trigger_mu.empty() && trigger_mu[0].pT() > 25*GeV) ) { 00341 MSG_DEBUG("Hardest lepton fails trigger"); 00342 vetoEvent; 00343 } 00344 00345 // And only accept events with at least 2 electrons and muons and at least 3 leptons in total 00346 if (recon_mu.size() + recon_e.size() + recon_tau.size() < 3 || recon_leptons.size() < 2) vetoEvent; 00347 00348 // Now it's worth getting the event weight 00349 const double weight = event.weight(); 00350 00351 // Sort leptons by decreasing pT 00352 sortByPt(recon_leptons); 00353 sortByPt(recon_tau); 00354 00355 // Calculate HTlep, fill lepton pT histograms & store chosen combination of 3 leptons 00356 double HTlep = 0.; 00357 Particles chosen_leptons; 00358 if ( recon_leptons.size() > 2 ) { 00359 _h_pt_1_3l->fill(recon_leptons[0].perp()/GeV, weight); 00360 _h_pt_2_3l->fill(recon_leptons[1].perp()/GeV, weight); 00361 _h_pt_3_3l->fill(recon_leptons[2].perp()/GeV, weight); 00362 HTlep = (recon_leptons[0].pT() + recon_leptons[1].pT() + recon_leptons[2].pT())/GeV; 00363 chosen_leptons.push_back( recon_leptons[0] ); 00364 chosen_leptons.push_back( recon_leptons[1] ); 00365 chosen_leptons.push_back( recon_leptons[2] ); 00366 } 00367 else { 00368 _h_pt_1_2ltau->fill(recon_leptons[0].perp()/GeV, weight); 00369 _h_pt_2_2ltau->fill(recon_leptons[1].perp()/GeV, weight); 00370 _h_pt_3_2ltau->fill(recon_tau[0].perp()/GeV, weight); 00371 HTlep = (recon_leptons[0].pT() + recon_leptons[1].pT() + recon_tau[0].pT())/GeV ; 00372 chosen_leptons.push_back( recon_leptons[0] ); 00373 chosen_leptons.push_back( recon_leptons[1] ); 00374 chosen_leptons.push_back( recon_tau[0] ); 00375 } 00376 00377 // Number of prompt e/mu and had taus 00378 _h_e_n ->fill(recon_e.size() , weight); 00379 _h_mu_n ->fill(recon_mu.size() , weight); 00380 _h_tau_n->fill(recon_tau.size(), weight); 00381 00382 // Calculate HTjets 00383 double HTjets = 0.; 00384 foreach ( const Jet & jet, recon_jets ) 00385 HTjets += jet.perp()/GeV; 00386 00387 // Calculate meff 00388 double meff = eTmiss + HTjets; 00389 Particles all_leptons; 00390 foreach ( const Particle & e , recon_e ) { 00391 meff += e.perp()/GeV; 00392 all_leptons.push_back( e ); 00393 } 00394 foreach ( const Particle & mu, recon_mu ) { 00395 meff += mu.perp()/GeV; 00396 all_leptons.push_back( mu ); 00397 } 00398 foreach ( const Particle & tau, recon_tau ) { 00399 meff += tau.perp()/GeV; 00400 all_leptons.push_back( tau ); 00401 } 00402 00403 // Fill histogram of kinematic variables 00404 _h_HTlep_all ->fill(HTlep , weight); 00405 _h_HTjets_all->fill(HTjets, weight); 00406 _h_MET_all ->fill(eTmiss, weight); 00407 _h_Meff_all ->fill(meff , weight); 00408 00409 // Determine signal region (3l/2ltau, onZ/offZ) 00410 string basic_signal_region; 00411 if ( recon_mu.size() + recon_e.size() > 2 ) 00412 basic_signal_region += "3l_"; 00413 else if ( (recon_mu.size() + recon_e.size() == 2) && (recon_tau.size() > 0)) 00414 basic_signal_region += "2ltau_"; 00415 // Is there an OSSF pair or a three lepton combination with an invariant mass close to the Z mass 00416 int onZ = isonZ(chosen_leptons); 00417 if (onZ == 1) basic_signal_region += "onZ"; 00418 else if (onZ == 0) basic_signal_region += "offZ"; 00419 // Check in which signal regions this event falls and adjust event counters 00420 fillEventCountsPerSR(basic_signal_region, onZ, HTlep, eTmiss, HTjets, meff, weight); 00421 } 00422 00423 00424 /// Normalise histograms etc., after the run 00425 void finalize() { 00426 00427 // Normalize to an integrated luminosity of 1 fb-1 00428 double norm = crossSection()/femtobarn/sumOfWeights(); 00429 string best_signal_region = ""; 00430 double ratio_best_SR = 0.; 00431 00432 // Loop over all signal regions and find signal region with best sensitivity (ratio signal events/visible cross-section) 00433 for (size_t i = 0; i < _signal_regions.size(); i++) { 00434 double signal_events = _eventCountsPerSR[_signal_regions[i]] * norm; 00435 // Use expected upper limits to find best signal region 00436 double UL95 = getUpperLimit(_signal_regions[i], false); 00437 double ratio = signal_events / UL95; 00438 if (ratio > ratio_best_SR) { 00439 best_signal_region = _signal_regions[i]; 00440 ratio_best_SR = ratio; 00441 } 00442 } 00443 00444 double signal_events_best_SR = _eventCountsPerSR[best_signal_region] * norm; 00445 double exp_UL_best_SR = getUpperLimit(best_signal_region, false); 00446 double obs_UL_best_SR = getUpperLimit(best_signal_region, true); 00447 00448 // Print out result 00449 cout << "----------------------------------------------------------------------------------------" << endl; 00450 cout << "Best signal region: " << best_signal_region << endl; 00451 cout << "Normalized number of signal events in this best signal region (per fb-1): " << signal_events_best_SR << endl; 00452 cout << "Efficiency*Acceptance: " << _eventCountsPerSR[best_signal_region]/sumOfWeights() << endl; 00453 cout << "Cross-section [fb]: " << crossSection()/femtobarn << endl; 00454 cout << "Expected visible cross-section (per fb-1): " << exp_UL_best_SR << endl; 00455 cout << "Ratio (signal events / expected visible cross-section): " << ratio_best_SR << endl; 00456 cout << "Observed visible cross-section (per fb-1): " << obs_UL_best_SR << endl; 00457 cout << "Ratio (signal events / observed visible cross-section): " << signal_events_best_SR/obs_UL_best_SR << endl; 00458 cout << "----------------------------------------------------------------------------------------" << endl; 00459 00460 cout << "Using the EXPECTED limits (visible cross-section) of the analysis: " << endl; 00461 if (signal_events_best_SR > exp_UL_best_SR) { 00462 cout << "Since the number of signal events > the visible cross-section, this model/grid point is EXCLUDED with 95% CL." << endl; 00463 _h_excluded->fill(1); 00464 } 00465 else { 00466 cout << "Since the number of signal events < the visible cross-section, this model/grid point is NOT EXCLUDED." << endl; 00467 _h_excluded->fill(0); 00468 } 00469 cout << "----------------------------------------------------------------------------------------" << endl; 00470 00471 cout << "Using the OBSERVED limits (visible cross-section) of the analysis: " << endl; 00472 if (signal_events_best_SR > obs_UL_best_SR) { 00473 cout << "Since the number of signal events > the visible cross-section, this model/grid point is EXCLUDED with 95% CL." << endl; 00474 _h_excluded->fill(1); 00475 } 00476 else { 00477 cout << "Since the number of signal events < the visible cross-section, this model/grid point is NOT EXCLUDED." << endl; 00478 _h_excluded->fill(0); 00479 } 00480 cout << "----------------------------------------------------------------------------------------" << endl; 00481 00482 00483 // Normalize to cross section 00484 if (norm != 0) { 00485 scale(_h_HTlep_all, norm); 00486 scale(_h_HTjets_all, norm); 00487 scale(_h_MET_all, norm); 00488 scale(_h_Meff_all, norm); 00489 00490 scale(_h_pt_1_3l, norm); 00491 scale(_h_pt_2_3l, norm); 00492 scale(_h_pt_3_3l, norm); 00493 scale(_h_pt_1_2ltau, norm); 00494 scale(_h_pt_2_2ltau, norm); 00495 scale(_h_pt_3_2ltau, norm); 00496 00497 scale(_h_e_n, norm); 00498 scale(_h_mu_n, norm); 00499 scale(_h_tau_n, norm); 00500 00501 scale(_h_excluded, signal_events_best_SR); 00502 } 00503 } 00504 00505 00506 /// Helper functions 00507 //@{ 00508 00509 /// Function giving a list of all signal regions 00510 vector<string> getSignalRegions() { 00511 00512 // List of basic signal regions 00513 vector<string> basic_signal_regions; 00514 basic_signal_regions.push_back("3l_offZ"); 00515 basic_signal_regions.push_back("3l_onZ"); 00516 basic_signal_regions.push_back("2ltau_offZ"); 00517 basic_signal_regions.push_back("2ltau_onZ"); 00518 00519 // List of kinematic variables 00520 vector<string> kinematic_variables; 00521 kinematic_variables.push_back("HTlep"); 00522 kinematic_variables.push_back("METStrong"); 00523 kinematic_variables.push_back("METWeak"); 00524 kinematic_variables.push_back("Meff"); 00525 kinematic_variables.push_back("MeffStrong"); 00526 00527 vector<string> signal_regions; 00528 // Loop over all kinematic variables and basic signal regions 00529 for (size_t i0 = 0; i0 < kinematic_variables.size(); i0++) { 00530 for (size_t i1 = 0; i1 < basic_signal_regions.size(); i1++) { 00531 // Is signal region onZ? 00532 int onZ = (basic_signal_regions[i1].find("onZ") != string::npos) ? 1 : 0; 00533 // Get cut values for this kinematic variable 00534 vector<int> cut_values = getCutsPerSignalRegion(kinematic_variables[i0], onZ); 00535 // Loop over all cut values 00536 for (size_t i2 = 0; i2 < cut_values.size(); i2++) { 00537 // push signal region into vector 00538 signal_regions.push_back( (kinematic_variables[i0] + "_" + basic_signal_regions[i1] + "_cut_" + toString(i2)) ); 00539 } 00540 } 00541 } 00542 return signal_regions; 00543 } 00544 00545 00546 /// Function giving all cut vales per kinematic variable (taking onZ for MET into account) 00547 vector<int> getCutsPerSignalRegion(const string& signal_region, int onZ=0) { 00548 vector<int> cutValues; 00549 00550 // Cut values for HTlep 00551 if (signal_region.compare("HTlep") == 0) { 00552 cutValues.push_back(0); 00553 cutValues.push_back(100); 00554 cutValues.push_back(150); 00555 cutValues.push_back(200); 00556 cutValues.push_back(300); 00557 } 00558 // Cut values for METStrong (HTjets > 100 GeV) and METWeak (HTjets < 100 GeV) 00559 else if (signal_region.compare("METStrong") == 0 || signal_region.compare("METWeak") == 0) { 00560 if (onZ == 0) cutValues.push_back(0); 00561 else if (onZ == 1) cutValues.push_back(20); 00562 cutValues.push_back(50); 00563 cutValues.push_back(75); 00564 } 00565 // Cut values for Meff and MeffStrong (MET > 75 GeV) 00566 if (signal_region.compare("Meff") == 0 || signal_region.compare("MeffStrong") == 0) { 00567 cutValues.push_back(0); 00568 cutValues.push_back(150); 00569 cutValues.push_back(300); 00570 cutValues.push_back(500); 00571 } 00572 00573 return cutValues; 00574 } 00575 00576 00577 /// function fills map EventCountsPerSR by looping over all signal regions 00578 /// and looking if the event falls into this signal region 00579 void fillEventCountsPerSR(const string& basic_signal_region, int onZ, 00580 double HTlep, double eTmiss, 00581 double HTjets, double meff, 00582 double weight) { 00583 00584 // Get cut values for HTlep, loop over them and add event if cut is passed 00585 vector<int> cut_values = getCutsPerSignalRegion("HTlep", onZ); 00586 for (size_t i = 0; i < cut_values.size(); i++) { 00587 if (HTlep > cut_values[i]) 00588 _eventCountsPerSR[("HTlep_" + basic_signal_region + "_cut_" + toString(cut_values[i]))] += weight; 00589 } 00590 00591 // Get cut values for METStrong, loop over them and add event if cut is passed 00592 cut_values = getCutsPerSignalRegion("METStrong", onZ); 00593 for (size_t i = 0; i < cut_values.size(); i++) { 00594 if (eTmiss > cut_values[i] && HTjets > 100.) 00595 _eventCountsPerSR[("METStrong_" + basic_signal_region + "_cut_" + toString(cut_values[i]))] += weight; 00596 } 00597 00598 // Get cut values for METWeak, loop over them and add event if cut is passed 00599 cut_values = getCutsPerSignalRegion("METWeak", onZ); 00600 for (size_t i = 0; i < cut_values.size(); i++) { 00601 if (eTmiss > cut_values[i] && HTjets <= 100.) 00602 _eventCountsPerSR[("METWeak_" + basic_signal_region + "_cut_" + toString(cut_values[i]))] += weight; 00603 } 00604 00605 // Get cut values for Meff, loop over them and add event if cut is passed 00606 cut_values = getCutsPerSignalRegion("Meff", onZ); 00607 for (size_t i = 0; i < cut_values.size(); i++) { 00608 if (meff > cut_values[i]) 00609 _eventCountsPerSR[("Meff_" + basic_signal_region + "_cut_" + toString(cut_values[i]))] += weight; 00610 } 00611 00612 // Get cut values for MeffStrong, loop over them and add event if cut is passed 00613 cut_values = getCutsPerSignalRegion("MeffStrong", onZ); 00614 for (size_t i = 0; i < cut_values.size(); i++) { 00615 if (meff > cut_values[i] && eTmiss > 75.) 00616 _eventCountsPerSR[("MeffStrong_" + basic_signal_region + "_cut_" + toString(cut_values[i]))] += weight; 00617 } 00618 } 00619 00620 00621 /// Function returning 4-vector of daughter-particle if it is a tau neutrino 00622 /// @todo Move to TauFinder and make less HepMC-ish 00623 FourMomentum get_tau_neutrino_mom(const Particle& p) { 00624 assert(p.abspid() == PID::TAU); 00625 const GenVertex* dv = p.genParticle()->end_vertex(); 00626 assert(dv != NULL); 00627 for (GenVertex::particles_out_const_iterator pp = dv->particles_out_const_begin(); pp != dv->particles_out_const_end(); ++pp) { 00628 if ((*pp)->pdg_id() == PID::NU_TAU) return FourMomentum((*pp)->momentum()); 00629 } 00630 return FourMomentum(); 00631 } 00632 00633 00634 /// Function calculating the prong number of taus 00635 /// @todo Move to TauFinder and make less HepMC-ish 00636 void get_prong_number(const GenParticle* p, unsigned int& nprong, bool& lep_decaying_tau) { 00637 assert(p != NULL); 00638 //const int tau_barcode = p->barcode(); 00639 const GenVertex* dv = p->end_vertex(); 00640 assert(dv != NULL); 00641 for (GenVertex::particles_out_const_iterator pp = dv->particles_out_const_begin(); pp != dv->particles_out_const_end(); ++pp) { 00642 // If they have status 1 and are charged they will produce a track and the prong number is +1 00643 if ((*pp)->status() == 1 ) { 00644 const int id = (*pp)->pdg_id(); 00645 if (Rivet::PID::charge(id) != 0 ) ++nprong; 00646 // Check if tau decays leptonically 00647 // @todo Can a tau decay include a tau in its decay daughters?! 00648 if ((abs(id) == PID::ELECTRON || abs(id) == PID::MUON || abs(id) == PID::TAU) && abs(p->pdg_id()) == PID::TAU) lep_decaying_tau = true; 00649 } 00650 // If the status of the daughter particle is 2 it is unstable and the further decays are checked 00651 else if ((*pp)->status() == 2 ) { 00652 get_prong_number(*pp, nprong, lep_decaying_tau); 00653 } 00654 } 00655 } 00656 00657 00658 /// Function giving fiducial lepton efficiency 00659 double apply_reco_eff(int flavor, const Particle& p) { 00660 float pt = p.pT()/GeV; 00661 float eta = p.eta(); 00662 00663 double eff = 0.; 00664 //double err = 0.; 00665 00666 if (flavor == 11) { // weight prompt electron -- now including data/MC ID SF in eff. 00667 //float rho = 0.820; 00668 float p0 = 7.34; float p1 = 0.8977; 00669 //float ep0= 0.5 ; float ep1= 0.0087; 00670 eff = p1 - p0/pt; 00671 00672 //double err0 = ep0/pt; // d(eff)/dp0 00673 //double err1 = ep1; // d(eff)/dp1 00674 //err = sqrt(err0*err0 + err1*err1 - 2*rho*err0*err1); 00675 00676 double avgrate = 0.6867; 00677 float wz_ele_eta[] = {0.588717,0.603674,0.666135,0.747493,0.762202,0.675051,0.751606,0.745569,0.665333,0.610432,0.592693,}; 00678 //float ewz_ele_eta[] ={0.00292902,0.002476,0.00241209,0.00182319,0.00194339,0.00299785,0.00197339,0.00182004,0.00241793,0.00245997,0.00290394,}; 00679 int ibin = 3; 00680 00681 if (eta >= -2.5 && eta < -2.0) ibin = 0; 00682 if (eta >= -2.0 && eta < -1.5) ibin = 1; 00683 if (eta >= -1.5 && eta < -1.0) ibin = 2; 00684 if (eta >= -1.0 && eta < -0.5) ibin = 3; 00685 if (eta >= -0.5 && eta < -0.1) ibin = 4; 00686 if (eta >= -0.1 && eta < 0.1) ibin = 5; 00687 if (eta >= 0.1 && eta < 0.5) ibin = 6; 00688 if (eta >= 0.5 && eta < 1.0) ibin = 7; 00689 if (eta >= 1.0 && eta < 1.5) ibin = 8; 00690 if (eta >= 1.5 && eta < 2.0) ibin = 9; 00691 if (eta >= 2.0 && eta < 2.5) ibin = 10; 00692 00693 double eff_eta = wz_ele_eta[ibin]; 00694 //double err_eta = ewz_ele_eta[ibin]; 00695 00696 eff = (eff*eff_eta)/avgrate; 00697 } 00698 00699 if (flavor == 12) { // weight electron from tau 00700 //float rho = 0.884; 00701 float p0 = 6.799; float p1 = 0.842; 00702 //float ep0= 0.664; float ep1= 0.016; 00703 eff = p1 - p0/pt; 00704 00705 //double err0 = ep0/pt; // d(eff)/dp0 00706 //double err1 = ep1; // d(eff)/dp1 00707 //err = sqrt(err0*err0 + err1*err1 - 2*rho*err0*err1); 00708 00709 double avgrate = 0.5319; 00710 float wz_elet_eta[] = {0.468945,0.465953,0.489545,0.58709,0.59669,0.515829,0.59284,0.575828,0.498181,0.463536,0.481738,}; 00711 //float ewz_elet_eta[] ={0.00933795,0.00780868,0.00792679,0.00642083,0.00692652,0.0101568,0.00698452,0.00643524,0.0080002,0.00776238,0.0094699,}; 00712 int ibin = 3; 00713 00714 if (eta >= -2.5 && eta < -2.0) ibin = 0; 00715 if (eta >= -2.0 && eta < -1.5) ibin = 1; 00716 if (eta >= -1.5 && eta < -1.0) ibin = 2; 00717 if (eta >= -1.0 && eta < -0.5) ibin = 3; 00718 if (eta >= -0.5 && eta < -0.1) ibin = 4; 00719 if (eta >= -0.1 && eta < 0.1) ibin = 5; 00720 if (eta >= 0.1 && eta < 0.5) ibin = 6; 00721 if (eta >= 0.5 && eta < 1.0) ibin = 7; 00722 if (eta >= 1.0 && eta < 1.5) ibin = 8; 00723 if (eta >= 1.5 && eta < 2.0) ibin = 9; 00724 if (eta >= 2.0 && eta < 2.5) ibin = 10; 00725 00726 double eff_eta = wz_elet_eta[ibin]; 00727 //double err_eta = ewz_elet_eta[ibin]; 00728 00729 eff = (eff*eff_eta)/avgrate; 00730 00731 } 00732 00733 if (flavor == 13) {// weight prompt muon 00734 00735 //if eta>0.1 00736 float p0 = -18.21; float p1 = 14.83; float p2 = 0.9312; 00737 //float ep0= 5.06; float ep1= 1.9; float ep2=0.00069; 00738 00739 if ( fabs(eta) < 0.1) { 00740 p0 = 7.459; p1 = 2.615; p2 = 0.5138; 00741 //ep0 = 10.4; ep1 = 4.934; ep2 = 0.0034; 00742 } 00743 00744 double arg = ( pt-p0 )/( 2.*p1 ) ; 00745 eff = 0.5 * p2 * (1.+erf(arg)); 00746 //err = 0.1*eff; 00747 } 00748 00749 if (flavor == 14) {// weight muon from tau 00750 00751 if (fabs(eta) < 0.1) { 00752 float p0 = -1.756; float p1 = 12.38; float p2 = 0.4441; 00753 //float ep0= 10.39; float ep1= 7.9; float ep2=0.022; 00754 double arg = ( pt-p0 )/( 2.*p1 ) ; 00755 eff = 0.5 * p2 * (1.+erf(arg)); 00756 //err = 0.1*eff; 00757 } 00758 else { 00759 float p0 = 2.102; float p1 = 0.8293; 00760 //float ep0= 0.271; float ep1= 0.0083; 00761 eff = p1 - p0/pt; 00762 //double err0 = ep0/pt; // d(eff)/dp0 00763 //double err1 = ep1; // d(eff)/dp1 00764 //err = sqrt(err0*err0 + err1*err1 - 2*rho*err0*err1); 00765 } 00766 } 00767 00768 if (flavor == 15) {// weight hadronic tau 1p 00769 00770 float wz_tau1p[] = {0.0249278,0.146978,0.225049,0.229212,0.21519,0.206152,0.201559,0.197917,0.209249,0.228336,0.193548,}; 00771 //float ewz_tau1p[] ={0.00178577,0.00425252,0.00535052,0.00592126,0.00484684,0.00612941,0.00792099,0.0083006,0.0138307,0.015568,0.0501751,}; 00772 int ibin = 0; 00773 if (pt > 15) ibin = 1; 00774 if (pt > 20) ibin = 2; 00775 if (pt > 25) ibin = 3; 00776 if (pt > 30) ibin = 4; 00777 if (pt > 40) ibin = 5; 00778 if (pt > 50) ibin = 6; 00779 if (pt > 60) ibin = 7; 00780 if (pt > 80) ibin = 8; 00781 if (pt > 100) ibin = 9; 00782 if (pt > 200) ibin = 10; 00783 00784 eff = wz_tau1p[ibin]; 00785 //err = ewz_tau1p[ibin]; 00786 00787 00788 double avgrate = 0.1718; 00789 float wz_tau1p_eta[] = {0.162132,0.176393,0.139619,0.178813,0.185144,0.210027,0.203937,0.178688,0.137034,0.164216,0.163713,}; 00790 //float ewz_tau1p_eta[] ={0.00706705,0.00617989,0.00506798,0.00525172,0.00581865,0.00865675,0.00599245,0.00529877,0.00506368,0.00617025,0.00726219,}; 00791 00792 ibin = 3; 00793 if (eta >= -2.5 && eta < -2.0) ibin = 0; 00794 if (eta >= -2.0 && eta < -1.5) ibin = 1; 00795 if (eta >= -1.5 && eta < -1.0) ibin = 2; 00796 if (eta >= -1.0 && eta < -0.5) ibin = 3; 00797 if (eta >= -0.5 && eta < -0.1) ibin = 4; 00798 if (eta >= -0.1 && eta < 0.1) ibin = 5; 00799 if (eta >= 0.1 && eta < 0.5) ibin = 6; 00800 if (eta >= 0.5 && eta < 1.0) ibin = 7; 00801 if (eta >= 1.0 && eta < 1.5) ibin = 8; 00802 if (eta >= 1.5 && eta < 2.0) ibin = 9; 00803 if (eta >= 2.0 && eta < 2.5) ibin = 10; 00804 00805 double eff_eta = wz_tau1p_eta[ibin]; 00806 //double err_eta = ewz_tau1p_eta[ibin]; 00807 00808 eff = (eff*eff_eta)/avgrate; 00809 } 00810 00811 if (flavor == 16) { //weight hadronic tau 3p 00812 00813 float wz_tau3p[] = {0.000587199,0.00247181,0.0013031,0.00280112,}; 00814 //float ewz_tau3p[] ={0.000415091,0.000617187,0.000582385,0.00197792,}; 00815 00816 int ibin = 0; 00817 if (pt > 15) ibin = 1; 00818 if (pt > 20) ibin = 2; 00819 if (pt > 40) ibin = 3; 00820 if (pt > 80) ibin = 4; 00821 00822 eff = wz_tau3p[ibin]; 00823 //err = ewz_tau3p[ibin]; 00824 } 00825 00826 return eff; 00827 } 00828 00829 00830 /// Function giving observed upper limit (visible cross-section) 00831 double getUpperLimit(const string& signal_region, bool observed) { 00832 map<string,double> upperLimitsObserved; 00833 upperLimitsObserved["HTlep_3l_offZ_cut_0"] = 11.; 00834 upperLimitsObserved["HTlep_3l_offZ_cut_100"] = 8.7; 00835 upperLimitsObserved["HTlep_3l_offZ_cut_150"] = 4.0; 00836 upperLimitsObserved["HTlep_3l_offZ_cut_200"] = 4.4; 00837 upperLimitsObserved["HTlep_3l_offZ_cut_300"] = 1.6; 00838 upperLimitsObserved["HTlep_2ltau_offZ_cut_0"] = 25.; 00839 upperLimitsObserved["HTlep_2ltau_offZ_cut_100"] = 14.; 00840 upperLimitsObserved["HTlep_2ltau_offZ_cut_150"] = 6.1; 00841 upperLimitsObserved["HTlep_2ltau_offZ_cut_200"] = 3.3; 00842 upperLimitsObserved["HTlep_2ltau_offZ_cut_300"] = 1.2; 00843 upperLimitsObserved["HTlep_3l_onZ_cut_0"] = 48.; 00844 upperLimitsObserved["HTlep_3l_onZ_cut_100"] = 38.; 00845 upperLimitsObserved["HTlep_3l_onZ_cut_150"] = 14.; 00846 upperLimitsObserved["HTlep_3l_onZ_cut_200"] = 7.2; 00847 upperLimitsObserved["HTlep_3l_onZ_cut_300"] = 4.5; 00848 upperLimitsObserved["HTlep_2ltau_onZ_cut_0"] = 85.; 00849 upperLimitsObserved["HTlep_2ltau_onZ_cut_100"] = 53.; 00850 upperLimitsObserved["HTlep_2ltau_onZ_cut_150"] = 11.0; 00851 upperLimitsObserved["HTlep_2ltau_onZ_cut_200"] = 5.2; 00852 upperLimitsObserved["HTlep_2ltau_onZ_cut_300"] = 3.0; 00853 upperLimitsObserved["METStrong_3l_offZ_cut_0"] = 2.6; 00854 upperLimitsObserved["METStrong_3l_offZ_cut_50"] = 2.1; 00855 upperLimitsObserved["METStrong_3l_offZ_cut_75"] = 2.1; 00856 upperLimitsObserved["METStrong_2ltau_offZ_cut_0"] = 4.2; 00857 upperLimitsObserved["METStrong_2ltau_offZ_cut_50"] = 3.1; 00858 upperLimitsObserved["METStrong_2ltau_offZ_cut_75"] = 2.6; 00859 upperLimitsObserved["METStrong_3l_onZ_cut_20"] = 11.0; 00860 upperLimitsObserved["METStrong_3l_onZ_cut_50"] = 6.4; 00861 upperLimitsObserved["METStrong_3l_onZ_cut_75"] = 5.1; 00862 upperLimitsObserved["METStrong_2ltau_onZ_cut_20"] = 5.9; 00863 upperLimitsObserved["METStrong_2ltau_onZ_cut_50"] = 3.4; 00864 upperLimitsObserved["METStrong_2ltau_onZ_cut_75"] = 1.2; 00865 upperLimitsObserved["METWeak_3l_offZ_cut_0"] = 11.; 00866 upperLimitsObserved["METWeak_3l_offZ_cut_50"] = 5.3; 00867 upperLimitsObserved["METWeak_3l_offZ_cut_75"] = 3.1; 00868 upperLimitsObserved["METWeak_2ltau_offZ_cut_0"] = 23.; 00869 upperLimitsObserved["METWeak_2ltau_offZ_cut_50"] = 4.3; 00870 upperLimitsObserved["METWeak_2ltau_offZ_cut_75"] = 3.1; 00871 upperLimitsObserved["METWeak_3l_onZ_cut_20"] = 41.; 00872 upperLimitsObserved["METWeak_3l_onZ_cut_50"] = 16.; 00873 upperLimitsObserved["METWeak_3l_onZ_cut_75"] = 8.0; 00874 upperLimitsObserved["METWeak_2ltau_onZ_cut_20"] = 80.; 00875 upperLimitsObserved["METWeak_2ltau_onZ_cut_50"] = 4.4; 00876 upperLimitsObserved["METWeak_2ltau_onZ_cut_75"] = 1.8; 00877 upperLimitsObserved["Meff_3l_offZ_cut_0"] = 11.; 00878 upperLimitsObserved["Meff_3l_offZ_cut_150"] = 8.1; 00879 upperLimitsObserved["Meff_3l_offZ_cut_300"] = 3.1; 00880 upperLimitsObserved["Meff_3l_offZ_cut_500"] = 2.1; 00881 upperLimitsObserved["Meff_2ltau_offZ_cut_0"] = 25.; 00882 upperLimitsObserved["Meff_2ltau_offZ_cut_150"] = 12.; 00883 upperLimitsObserved["Meff_2ltau_offZ_cut_300"] = 3.9; 00884 upperLimitsObserved["Meff_2ltau_offZ_cut_500"] = 2.2; 00885 upperLimitsObserved["Meff_3l_onZ_cut_0"] = 48.; 00886 upperLimitsObserved["Meff_3l_onZ_cut_150"] = 37.; 00887 upperLimitsObserved["Meff_3l_onZ_cut_300"] = 11.; 00888 upperLimitsObserved["Meff_3l_onZ_cut_500"] = 4.8; 00889 upperLimitsObserved["Meff_2ltau_onZ_cut_0"] = 85.; 00890 upperLimitsObserved["Meff_2ltau_onZ_cut_150"] = 28.; 00891 upperLimitsObserved["Meff_2ltau_onZ_cut_300"] = 5.9; 00892 upperLimitsObserved["Meff_2ltau_onZ_cut_500"] = 1.9; 00893 upperLimitsObserved["MeffStrong_3l_offZ_cut_0"] = 3.8; 00894 upperLimitsObserved["MeffStrong_3l_offZ_cut_150"] = 3.8; 00895 upperLimitsObserved["MeffStrong_3l_offZ_cut_300"] = 2.8; 00896 upperLimitsObserved["MeffStrong_3l_offZ_cut_500"] = 2.1; 00897 upperLimitsObserved["MeffStrong_2ltau_offZ_cut_0"] = 3.9; 00898 upperLimitsObserved["MeffStrong_2ltau_offZ_cut_150"] = 4.0; 00899 upperLimitsObserved["MeffStrong_2ltau_offZ_cut_300"] = 2.9; 00900 upperLimitsObserved["MeffStrong_2ltau_offZ_cut_500"] = 1.5; 00901 upperLimitsObserved["MeffStrong_3l_onZ_cut_0"] = 10.0; 00902 upperLimitsObserved["MeffStrong_3l_onZ_cut_150"] = 10.0; 00903 upperLimitsObserved["MeffStrong_3l_onZ_cut_300"] = 6.8; 00904 upperLimitsObserved["MeffStrong_3l_onZ_cut_500"] = 3.9; 00905 upperLimitsObserved["MeffStrong_2ltau_onZ_cut_0"] = 1.6; 00906 upperLimitsObserved["MeffStrong_2ltau_onZ_cut_150"] = 1.4; 00907 upperLimitsObserved["MeffStrong_2ltau_onZ_cut_300"] = 1.5; 00908 upperLimitsObserved["MeffStrong_2ltau_onZ_cut_500"] = 0.9; 00909 00910 // Expected upper limits are also given but not used in this analysis 00911 map<string,double> upperLimitsExpected; 00912 upperLimitsExpected["HTlep_3l_offZ_cut_0"] = 11.; 00913 upperLimitsExpected["HTlep_3l_offZ_cut_100"] = 8.5; 00914 upperLimitsExpected["HTlep_3l_offZ_cut_150"] = 4.6; 00915 upperLimitsExpected["HTlep_3l_offZ_cut_200"] = 3.6; 00916 upperLimitsExpected["HTlep_3l_offZ_cut_300"] = 1.9; 00917 upperLimitsExpected["HTlep_2ltau_offZ_cut_0"] = 23.; 00918 upperLimitsExpected["HTlep_2ltau_offZ_cut_100"] = 14.; 00919 upperLimitsExpected["HTlep_2ltau_offZ_cut_150"] = 6.4; 00920 upperLimitsExpected["HTlep_2ltau_offZ_cut_200"] = 3.6; 00921 upperLimitsExpected["HTlep_2ltau_offZ_cut_300"] = 1.5; 00922 upperLimitsExpected["HTlep_3l_onZ_cut_0"] = 33.; 00923 upperLimitsExpected["HTlep_3l_onZ_cut_100"] = 25.; 00924 upperLimitsExpected["HTlep_3l_onZ_cut_150"] = 12.; 00925 upperLimitsExpected["HTlep_3l_onZ_cut_200"] = 6.5; 00926 upperLimitsExpected["HTlep_3l_onZ_cut_300"] = 3.1; 00927 upperLimitsExpected["HTlep_2ltau_onZ_cut_0"] = 94.; 00928 upperLimitsExpected["HTlep_2ltau_onZ_cut_100"] = 61.; 00929 upperLimitsExpected["HTlep_2ltau_onZ_cut_150"] = 9.9; 00930 upperLimitsExpected["HTlep_2ltau_onZ_cut_200"] = 4.5; 00931 upperLimitsExpected["HTlep_2ltau_onZ_cut_300"] = 1.9; 00932 upperLimitsExpected["METStrong_3l_offZ_cut_0"] = 3.1; 00933 upperLimitsExpected["METStrong_3l_offZ_cut_50"] = 2.4; 00934 upperLimitsExpected["METStrong_3l_offZ_cut_75"] = 2.3; 00935 upperLimitsExpected["METStrong_2ltau_offZ_cut_0"] = 4.8; 00936 upperLimitsExpected["METStrong_2ltau_offZ_cut_50"] = 3.3; 00937 upperLimitsExpected["METStrong_2ltau_offZ_cut_75"] = 2.1; 00938 upperLimitsExpected["METStrong_3l_onZ_cut_20"] = 8.7; 00939 upperLimitsExpected["METStrong_3l_onZ_cut_50"] = 4.9; 00940 upperLimitsExpected["METStrong_3l_onZ_cut_75"] = 3.8; 00941 upperLimitsExpected["METStrong_2ltau_onZ_cut_20"] = 7.3; 00942 upperLimitsExpected["METStrong_2ltau_onZ_cut_50"] = 2.8; 00943 upperLimitsExpected["METStrong_2ltau_onZ_cut_75"] = 1.5; 00944 upperLimitsExpected["METWeak_3l_offZ_cut_0"] = 10.; 00945 upperLimitsExpected["METWeak_3l_offZ_cut_50"] = 4.7; 00946 upperLimitsExpected["METWeak_3l_offZ_cut_75"] = 3.0; 00947 upperLimitsExpected["METWeak_2ltau_offZ_cut_0"] = 21.; 00948 upperLimitsExpected["METWeak_2ltau_offZ_cut_50"] = 4.0; 00949 upperLimitsExpected["METWeak_2ltau_offZ_cut_75"] = 2.6; 00950 upperLimitsExpected["METWeak_3l_onZ_cut_20"] = 30.; 00951 upperLimitsExpected["METWeak_3l_onZ_cut_50"] = 10.; 00952 upperLimitsExpected["METWeak_3l_onZ_cut_75"] = 5.4; 00953 upperLimitsExpected["METWeak_2ltau_onZ_cut_20"] = 88.; 00954 upperLimitsExpected["METWeak_2ltau_onZ_cut_50"] = 5.5; 00955 upperLimitsExpected["METWeak_2ltau_onZ_cut_75"] = 2.2; 00956 upperLimitsExpected["Meff_3l_offZ_cut_0"] = 11.; 00957 upperLimitsExpected["Meff_3l_offZ_cut_150"] = 8.8; 00958 upperLimitsExpected["Meff_3l_offZ_cut_300"] = 3.7; 00959 upperLimitsExpected["Meff_3l_offZ_cut_500"] = 2.1; 00960 upperLimitsExpected["Meff_2ltau_offZ_cut_0"] = 23.; 00961 upperLimitsExpected["Meff_2ltau_offZ_cut_150"] = 13.; 00962 upperLimitsExpected["Meff_2ltau_offZ_cut_300"] = 4.9; 00963 upperLimitsExpected["Meff_2ltau_offZ_cut_500"] = 2.4; 00964 upperLimitsExpected["Meff_3l_onZ_cut_0"] = 33.; 00965 upperLimitsExpected["Meff_3l_onZ_cut_150"] = 25.; 00966 upperLimitsExpected["Meff_3l_onZ_cut_300"] = 9.; 00967 upperLimitsExpected["Meff_3l_onZ_cut_500"] = 3.9; 00968 upperLimitsExpected["Meff_2ltau_onZ_cut_0"] = 94.; 00969 upperLimitsExpected["Meff_2ltau_onZ_cut_150"] = 35.; 00970 upperLimitsExpected["Meff_2ltau_onZ_cut_300"] = 6.8; 00971 upperLimitsExpected["Meff_2ltau_onZ_cut_500"] = 2.5; 00972 upperLimitsExpected["MeffStrong_3l_offZ_cut_0"] = 3.9; 00973 upperLimitsExpected["MeffStrong_3l_offZ_cut_150"] = 3.9; 00974 upperLimitsExpected["MeffStrong_3l_offZ_cut_300"] = 3.0; 00975 upperLimitsExpected["MeffStrong_3l_offZ_cut_500"] = 2.0; 00976 upperLimitsExpected["MeffStrong_2ltau_offZ_cut_0"] = 3.8; 00977 upperLimitsExpected["MeffStrong_2ltau_offZ_cut_150"] = 3.9; 00978 upperLimitsExpected["MeffStrong_2ltau_offZ_cut_300"] = 3.1; 00979 upperLimitsExpected["MeffStrong_2ltau_offZ_cut_500"] = 1.6; 00980 upperLimitsExpected["MeffStrong_3l_onZ_cut_0"] = 6.9; 00981 upperLimitsExpected["MeffStrong_3l_onZ_cut_150"] = 7.1; 00982 upperLimitsExpected["MeffStrong_3l_onZ_cut_300"] = 4.9; 00983 upperLimitsExpected["MeffStrong_3l_onZ_cut_500"] = 3.0; 00984 upperLimitsExpected["MeffStrong_2ltau_onZ_cut_0"] = 2.4; 00985 upperLimitsExpected["MeffStrong_2ltau_onZ_cut_150"] = 2.5; 00986 upperLimitsExpected["MeffStrong_2ltau_onZ_cut_300"] = 2.0; 00987 upperLimitsExpected["MeffStrong_2ltau_onZ_cut_500"] = 1.1; 00988 00989 if (observed) return upperLimitsObserved[signal_region]; 00990 else return upperLimitsExpected[signal_region]; 00991 } 00992 00993 00994 /// Function checking if there is an OSSF lepton pair or a combination of 3 leptons with an invariant mass close to the Z mass 00995 /// @todo Should the reference Z mass be 91.2? 00996 int isonZ (const Particles& particles) { 00997 int onZ = 0; 00998 double best_mass_2 = 999.; 00999 double best_mass_3 = 999.; 01000 01001 // Loop over all 2 particle combinations to find invariant mass of OSSF pair closest to Z mass 01002 foreach ( const Particle& p1, particles ) { 01003 foreach ( const Particle& p2, particles ) { 01004 double mass_difference_2_old = fabs(91.0 - best_mass_2); 01005 double mass_difference_2_new = fabs(91.0 - (p1.momentum() + p2.momentum()).mass()/GeV); 01006 01007 // If particle combination is OSSF pair calculate mass difference to Z mass 01008 if ( (p1.pid()*p2.pid() == -121 || p1.pid()*p2.pid() == -169) ) { 01009 01010 // Get invariant mass closest to Z mass 01011 if (mass_difference_2_new < mass_difference_2_old) 01012 best_mass_2 = (p1.momentum() + p2.momentum()).mass()/GeV; 01013 01014 // In case there is an OSSF pair take also 3rd lepton into account (e.g. from FSR and photon to electron conversion) 01015 foreach ( const Particle & p3 , particles ) { 01016 double mass_difference_3_old = fabs(91.0 - best_mass_3); 01017 double mass_difference_3_new = fabs(91.0 - (p1.momentum() + p2.momentum() + p3.momentum()).mass()/GeV); 01018 if (mass_difference_3_new < mass_difference_3_old) 01019 best_mass_3 = (p1.momentum() + p2.momentum() + p3.momentum()).mass()/GeV; 01020 } 01021 } 01022 } 01023 } 01024 01025 // Pick the minimum invariant mass of the best OSSF pair combination and the best 3 lepton combination 01026 // If this mass is in a 20 GeV window around the Z mass, the event is classified as onZ 01027 double best_mass = min(best_mass_2, best_mass_3); 01028 if (fabs(91.0 - best_mass) < 20) onZ = 1; 01029 return onZ; 01030 } 01031 01032 //@} 01033 01034 01035 private: 01036 01037 /// Histograms 01038 //@{ 01039 Histo1DPtr _h_HTlep_all, _h_HTjets_all, _h_MET_all, _h_Meff_all; 01040 Histo1DPtr _h_pt_1_3l, _h_pt_2_3l, _h_pt_3_3l, _h_pt_1_2ltau, _h_pt_2_2ltau, _h_pt_3_2ltau; 01041 Histo1DPtr _h_e_n, _h_mu_n, _h_tau_n; 01042 Histo1DPtr _h_excluded; 01043 //@} 01044 01045 /// Fiducial efficiencies to model the effects of the ATLAS detector 01046 bool _use_fiducial_lepton_efficiency; 01047 01048 /// List of signal regions and event counts per signal region 01049 vector<string> _signal_regions; 01050 map<string, double> _eventCountsPerSR; 01051 01052 }; 01053 01054 01055 01056 DECLARE_RIVET_PLUGIN(ATLAS_2012_I1204447); 01057 01058 } Generated on Tue Sep 30 2014 19:45:42 for The Rivet MC analysis system by ![]() |