ATLAS_2011_I944826.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/ChargedFinalState.hh" 00004 #include "Rivet/Projections/IdentifiedFinalState.hh" 00005 #include "Rivet/Projections/UnstableFinalState.hh" 00006 00007 namespace Rivet { 00008 00009 using namespace Cuts; 00010 00011 00012 class ATLAS_2011_I944826 : public Analysis { 00013 public: 00014 00015 /// Constructor 00016 ATLAS_2011_I944826() 00017 : Analysis("ATLAS_2011_I944826") 00018 { 00019 _sum_w_ks = 0.0; 00020 _sum_w_lambda = 0.0; 00021 _sum_w_passed = 0.0; 00022 } 00023 00024 00025 /// Book histograms and initialise projections before the run 00026 void init() { 00027 00028 UnstableFinalState ufs(-MAXDOUBLE, MAXDOUBLE, 100*MeV); 00029 addProjection(ufs, "UFS"); 00030 00031 ChargedFinalState mbts( etaIn(-3.84, -2.09) 00032 | etaIn( 2.09, 3.84) ); 00033 addProjection(mbts, "MBTS"); 00034 00035 IdentifiedFinalState nstable( etaIn(-2.5, 2.5) 00036 & (pT >= 100*MeV) ); 00037 nstable.acceptIdPair(PID::ELECTRON) 00038 .acceptIdPair(PID::MUON) 00039 .acceptIdPair(PID::PIPLUS) 00040 .acceptIdPair(PID::KPLUS) 00041 .acceptIdPair(PID::PROTON); 00042 addProjection(nstable, "nstable"); 00043 00044 if (fuzzyEquals(sqrtS()*GeV, 7000, 1e-3)) { 00045 _hist_Ks_pT = bookHisto1D(1, 1, 1); 00046 _hist_Ks_y = bookHisto1D(2, 1, 1); 00047 _hist_Ks_mult = bookHisto1D(3, 1, 1); 00048 _hist_L_pT = bookHisto1D(7, 1, 1); 00049 _hist_L_y = bookHisto1D(8, 1, 1); 00050 _hist_L_mult = bookHisto1D(9, 1, 1); 00051 _hist_Ratio_v_y = bookScatter2D(13, 1, 1); 00052 _hist_Ratio_v_pT = bookScatter2D(14, 1, 1); 00053 // 00054 _temp_lambda_v_y = Histo1D(10, 0.0, 2.5); 00055 _temp_lambdabar_v_y = Histo1D(10, 0.0, 2.5); 00056 _temp_lambda_v_pT = Histo1D(18, 0.5, 4.1); 00057 _temp_lambdabar_v_pT = Histo1D(18, 0.5, 4.1); 00058 } 00059 else if (fuzzyEquals(sqrtS()*GeV, 900, 1E-3)) { 00060 _hist_Ks_pT = bookHisto1D(4, 1, 1); 00061 _hist_Ks_y = bookHisto1D(5, 1, 1); 00062 _hist_Ks_mult = bookHisto1D(6, 1, 1); 00063 _hist_L_pT = bookHisto1D(10, 1, 1); 00064 _hist_L_y = bookHisto1D(11, 1, 1); 00065 _hist_L_mult = bookHisto1D(12, 1, 1); 00066 _hist_Ratio_v_y = bookScatter2D(15, 1, 1); 00067 _hist_Ratio_v_pT = bookScatter2D(16, 1, 1); 00068 // 00069 _temp_lambda_v_y = Histo1D(5, 0.0, 2.5); 00070 _temp_lambdabar_v_y = Histo1D(5, 0.0, 2.5); 00071 _temp_lambda_v_pT = Histo1D(8, 0.5, 3.7); 00072 _temp_lambdabar_v_pT = Histo1D(8, 0.5, 3.7); 00073 } 00074 } 00075 00076 00077 // This function is required to impose the flight time cuts on Kaons and Lambdas 00078 double getPerpFlightDistance(const Rivet::Particle& p) { 00079 const HepMC::GenParticle* genp = p.genParticle(); 00080 HepMC::GenVertex* prodV = genp->production_vertex(); 00081 HepMC::GenVertex* decV = genp->end_vertex(); 00082 const HepMC::ThreeVector prodPos = prodV->point3d(); 00083 if (decV) { 00084 const HepMC::ThreeVector decPos = decV->point3d(); 00085 double dy = prodPos.y() - decPos.y(); 00086 double dx = prodPos.x() - decPos.x(); 00087 return add_quad(dx, dy); 00088 } 00089 return numeric_limits<double>::max(); 00090 } 00091 00092 00093 bool daughtersSurviveCuts(const Rivet::Particle& p) { 00094 // We require the Kshort or Lambda to decay into two charged 00095 // particles with at least pT = 100 MeV inside acceptance region 00096 const HepMC::GenParticle* genp = p.genParticle(); 00097 HepMC::GenVertex* decV = genp->end_vertex(); 00098 bool decision = true; 00099 00100 if (!decV) return false; 00101 if (decV->particles_out_size() == 2) { 00102 std::vector<double> pTs; 00103 std::vector<int> charges; 00104 std::vector<double> etas; 00105 foreach (HepMC::GenParticle* gp, particles(decV, HepMC::children)) { 00106 pTs.push_back(gp->momentum().perp()); 00107 etas.push_back(fabs(gp->momentum().eta())); 00108 charges.push_back( Rivet::PID::threeCharge(gp->pdg_id()) ); 00109 // gp->print(); 00110 } 00111 if ( (pTs[0]/Rivet::GeV < 0.1) || (pTs[1]/Rivet::GeV < 0.1) ) { 00112 decision = false; 00113 MSG_DEBUG("Failed pT cut: " << pTs[0]/Rivet::GeV << " " << pTs[1]/Rivet::GeV); 00114 } 00115 if ( etas[0] > 2.5 || etas[1] > 2.5 ) { 00116 decision = false; 00117 MSG_DEBUG("Failed eta cut: " << etas[0] << " " << etas[1]); 00118 } 00119 if ( charges[0] * charges[1] >= 0 ) { 00120 decision = false; 00121 MSG_DEBUG("Failed opposite charge cut: " << charges[0] << " " << charges[1]); 00122 } 00123 } 00124 else { 00125 decision = false; 00126 MSG_DEBUG("Failed nDaughters cut: " << decV->particles_out_size()); 00127 } 00128 00129 return decision; 00130 } 00131 00132 /// Perform the per-event analysis 00133 void analyze(const Event& event) { 00134 const double weight = event.weight(); 00135 00136 // ATLAS MBTS trigger requirement of at least one hit in either hemisphere 00137 if (applyProjection<FinalState>(event, "MBTS").size() < 1) { 00138 MSG_DEBUG("Failed trigger cut"); 00139 vetoEvent; 00140 } 00141 00142 // Veto event also when we find less than 2 particles in the acceptance region of type 211,2212,11,13,321 00143 if (applyProjection<FinalState>(event, "nstable").size() < 2) { 00144 MSG_DEBUG("Failed stable particle cut"); 00145 vetoEvent; 00146 } 00147 _sum_w_passed += weight; 00148 00149 // This ufs holds all the Kaons and Lambdas 00150 const UnstableFinalState& ufs = applyProjection<UnstableFinalState>(event, "UFS"); 00151 00152 // Some conters 00153 int n_KS0 = 0; 00154 int n_LAMBDA = 0; 00155 00156 // Particle loop 00157 foreach (const Particle& p, ufs.particles()) { 00158 00159 // General particle quantities 00160 const double pT = p.pT(); 00161 const double y = p.rapidity(); 00162 const PdgId apid = p.abspid(); 00163 00164 double flightd = 0.0; 00165 00166 // Look for Kaons, Lambdas 00167 switch (apid) { 00168 00169 case PID::K0S: 00170 flightd = getPerpFlightDistance(p); 00171 if (!inRange(flightd/mm, 4., 450.) ) { 00172 MSG_DEBUG("Kaon failed flight distance cut:" << flightd); 00173 break; 00174 } 00175 if (daughtersSurviveCuts(p) ) { 00176 _hist_Ks_y ->fill(y, weight); 00177 _hist_Ks_pT->fill(pT/GeV, weight); 00178 _sum_w_ks += weight; 00179 n_KS0++; 00180 } 00181 break; 00182 00183 case PID::LAMBDA: 00184 if (pT < 0.5*GeV) { // Lambdas have an additional pT cut of 500 MeV 00185 MSG_DEBUG("Lambda failed pT cut:" << pT/GeV << " GeV"); 00186 break; 00187 } 00188 flightd = getPerpFlightDistance(p); 00189 if (!inRange(flightd/mm, 17., 450.)) { 00190 MSG_DEBUG("Lambda failed flight distance cut:" << flightd/mm << " mm"); 00191 break; 00192 } 00193 if ( daughtersSurviveCuts(p) ) { 00194 if (p.pid() == PID::LAMBDA) { 00195 _temp_lambda_v_y.fill(fabs(y), weight); 00196 _temp_lambda_v_pT.fill(pT/GeV, weight); 00197 _hist_L_y->fill(y, weight); 00198 _hist_L_pT->fill(pT/GeV, weight); 00199 _sum_w_lambda += weight; 00200 n_LAMBDA++; 00201 } else if (p.pid() == -PID::LAMBDA) { 00202 _temp_lambdabar_v_y.fill(fabs(y), weight); 00203 _temp_lambdabar_v_pT.fill(pT/GeV, weight); 00204 } 00205 } 00206 break; 00207 00208 } 00209 } 00210 00211 // Fill multiplicity histos 00212 _hist_Ks_mult->fill(n_KS0, weight); 00213 _hist_L_mult->fill(n_LAMBDA, weight); 00214 } 00215 00216 00217 00218 /// Normalise histograms etc., after the run 00219 void finalize() { 00220 MSG_DEBUG("# Events that pass the trigger: " << _sum_w_passed); 00221 MSG_DEBUG("# Kshort events: " << _sum_w_ks); 00222 MSG_DEBUG("# Lambda events: " << _sum_w_lambda); 00223 00224 /// @todo Replace with normalize()? 00225 scale(_hist_Ks_pT, 1.0/_sum_w_ks); 00226 scale(_hist_Ks_y, 1.0/_sum_w_ks); 00227 scale(_hist_Ks_mult, 1.0/_sum_w_passed); 00228 00229 /// @todo Replace with normalize()? 00230 scale(_hist_L_pT, 1.0/_sum_w_lambda); 00231 scale(_hist_L_y, 1.0/_sum_w_lambda); 00232 scale(_hist_L_mult, 1.0/_sum_w_passed); 00233 00234 // Division of histograms to obtain lambda_bar/lambda ratios 00235 divide(_temp_lambdabar_v_y, _temp_lambda_v_y, _hist_Ratio_v_y); 00236 divide(_temp_lambdabar_v_pT, _temp_lambda_v_pT, _hist_Ratio_v_pT); 00237 } 00238 00239 00240 private: 00241 00242 /// Counters 00243 double _sum_w_ks, _sum_w_lambda, _sum_w_passed; 00244 00245 /// @name Persistent histograms 00246 //@{ 00247 Histo1DPtr _hist_Ks_pT, _hist_Ks_y, _hist_Ks_mult; 00248 Histo1DPtr _hist_L_pT, _hist_L_y, _hist_L_mult; 00249 Scatter2DPtr _hist_Ratio_v_pT, _hist_Ratio_v_y; 00250 //@} 00251 00252 /// @name Temporary histograms 00253 //@{ 00254 Histo1D _temp_lambda_v_y, _temp_lambdabar_v_y; 00255 Histo1D _temp_lambda_v_pT, _temp_lambdabar_v_pT; 00256 //@} 00257 00258 }; 00259 00260 00261 // The hook for the plugin system 00262 DECLARE_RIVET_PLUGIN(ATLAS_2011_I944826); 00263 00264 } Generated on Tue Sep 30 2014 19:45:41 for The Rivet MC analysis system by ![]() |