ATLAS_2012_I1119557.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Analysis.hh" 00003 #include "Rivet/Projections/FastJets.hh" 00004 #include "Rivet/Projections/FinalState.hh" 00005 00006 namespace Rivet { 00007 00008 00009 namespace { // unnamed namespace 00010 // Forward declarations of calculator functions: implementations at bottom of file 00011 double getWidth(const Jet& jet); 00012 /// @todo Re-enable eccentricity calculation 00013 // double getEcc(const Jet& jet); 00014 double getPFlow(const Jet& jet); 00015 double getAngularity(const Jet& jet); 00016 } 00017 00018 00019 class ATLAS_2012_I1119557 : public Analysis { 00020 public: 00021 00022 ATLAS_2012_I1119557() 00023 : Analysis("ATLAS_2012_I1119557") 00024 { } 00025 00026 00027 void init() { 00028 const FinalState fs; 00029 addProjection(fs, "FinalState"); 00030 00031 FastJets fj06(fs, FastJets::ANTIKT, 0.6); 00032 addProjection(fj06, "AntiKT06"); 00033 FastJets fj10(fs, FastJets::ANTIKT, 1.0); 00034 addProjection(fj10, "AntiKT10"); 00035 00036 for (size_t alg = 0; alg < 2; ++alg) { 00037 _hs_mass[alg] = bookHisto1D(1, alg+1, 1); 00038 _hs_width[alg] = bookHisto1D(2, alg+1, 1); 00039 /// @todo Commented eccentricity out for now: reinstate 00040 // _hs_eccentricity[alg] = bookHisto1D(3, alg+1, 1); 00041 } 00042 _h_planarFlow = bookHisto1D(4, 2, 1); 00043 _h_angularity = bookHisto1D(5, 1, 1); 00044 00045 } 00046 00047 00048 /// Perform the per-event analysis 00049 void analyze(const Event& event) { 00050 const double weight = event.weight(); 00051 Jets jetAr[2]; 00052 jetAr[0] = applyProjection<FastJets>(event, "AntiKT06").jetsByPt(Cuts::pT > 300*GeV && Cuts::abseta < 2.0); 00053 jetAr[1] = applyProjection<FastJets>(event, "AntiKT10").jetsByPt(Cuts::pT > 300*GeV && Cuts::abseta < 2.0); 00054 00055 for (size_t alg = 0; alg < 2; ++alg) { 00056 // Require at least one jet 00057 if (jetAr[alg].size() < 1) continue; 00058 00059 // The leading jet 00060 const Jet& jet = jetAr[alg][0]; 00061 const double m = jet.mass(); 00062 const double eta = jet.eta(); 00063 00064 _hs_mass[alg]->fill(m/GeV, weight); 00065 _hs_width[alg]->fill(getWidth(jet), weight); 00066 /// @todo Commented eccentricity out for now: reinstate 00067 // if (fabs(eta) < 0.7 && m > 100*GeV) _hs_eccentricity[alg]->fill(getEcc(jet), weight); 00068 00069 if (fabs(eta) < 0.7) { 00070 if (alg == 0 && inRange(m/GeV, 100., 130.)) _h_angularity->fill(getAngularity(jet), weight); 00071 if (alg == 1 && inRange(m/GeV, 130., 210.)) _h_planarFlow->fill(getPFlow(jet), weight); 00072 } 00073 } 00074 } 00075 00076 00077 /// Normalise histograms etc., after the run 00078 void finalize() { 00079 for (size_t alg = 0; alg < 2; ++alg) { 00080 normalize(_hs_mass[alg]); 00081 normalize(_hs_width[alg]); 00082 /// @todo Commented eccentricity out for now: reinstate 00083 // normalize(_hs_eccentricity[alg]); 00084 } 00085 normalize(_h_planarFlow); 00086 normalize(_h_angularity); 00087 } 00088 00089 00090 private: 00091 00092 Histo1DPtr _hs_mass[2]; 00093 Histo1DPtr _hs_width[2]; 00094 /// @todo Commented eccentricity out for now: reinstate 00095 // Histo1DPtr _hs_eccentricity[2]; 00096 Histo1DPtr _h_planarFlow; 00097 Histo1DPtr _h_angularity; 00098 }; 00099 00100 00101 DECLARE_RIVET_PLUGIN(ATLAS_2012_I1119557); 00102 00103 00104 00105 namespace { // unnamed namespace 00106 00107 // Adapted code from Lily 00108 /// @todo Convert to use the Rivet rotation matrix code (should be simpler) 00109 FourMomentum RotateAxes(const Rivet::FourMomentum& p, double M[3][3]){ 00110 double px_rot = M[0][0]*(p.px()) + M[0][1]*(p.py()) + M[0][2]*(p.pz()); 00111 double py_rot = M[1][0]*(p.px()) + M[1][1]*(p.py()) + M[1][2]*(p.pz()); 00112 double pz_rot = M[2][0]*(p.px()) + M[2][1]*(p.py()) + M[2][2]*(p.pz()); 00113 return FourMomentum(p.E(), px_rot, py_rot, pz_rot); 00114 } 00115 00116 // Untouched code from Lily 00117 /// @todo Convert to use the Rivet rotation matrix code (should be simpler) 00118 void CalcRotationMatrix(double nvec[3],double rot_mat[3][3]){ 00119 // clear momentum tensor 00120 for (size_t i = 0; i < 3; i++) { 00121 for (size_t j = 0; j < 3; j++) { 00122 rot_mat[i][j] = 0.; 00123 } 00124 } 00125 double mag3 = sqrt(nvec[0]*nvec[0] + nvec[1]*nvec[1]+ nvec[2]*nvec[2]); 00126 double mag2 = sqrt(nvec[0]*nvec[0] + nvec[1]*nvec[1]); 00127 /// @todo cout is not a valid response to a numerical error! Is the error condition reported?!? Assert added by AB for Rivet 1.8.2 00128 assert(mag3 > 0); 00129 if (mag3 <= 0) { 00130 cout << "rotation axis is null" << endl; 00131 return; 00132 } 00133 00134 double ctheta0 = nvec[2]/mag3; 00135 double stheta0 = mag2/mag3; 00136 double cphi0 = (mag2 > 0.) ? nvec[0]/mag2 : 0; 00137 double sphi0 = (mag2 > 0.) ? nvec[1]/mag2 : 0; 00138 00139 rot_mat[0][0] = -ctheta0*cphi0; 00140 rot_mat[0][1] = -ctheta0*sphi0; 00141 rot_mat[0][2] = stheta0; 00142 rot_mat[1][0] = sphi0; 00143 rot_mat[1][1] = -1.*cphi0; 00144 rot_mat[1][2] = 0.; 00145 rot_mat[2][0] = stheta0*cphi0; 00146 rot_mat[2][1] = stheta0*sphi0; 00147 rot_mat[2][2] = ctheta0; 00148 } 00149 00150 00151 /// Jet width calculation 00152 double getWidth(const Jet& jet) { 00153 const double phi_jet = jet.phi(); 00154 const double eta_jet = jet.eta(); 00155 double width(0), pTsum(0); 00156 foreach (const Particle& p, jet.particles()) { 00157 double pT = p.pT(); 00158 double eta = p.eta(); 00159 double phi = p.phi(); 00160 width += sqrt(pow(phi_jet - phi,2) + pow(eta_jet - eta, 2)) * pT; 00161 pTsum += pT; 00162 } 00163 const double rtn = (pTsum != 0.0) ? width/pTsum : -1; 00164 return rtn; 00165 } 00166 00167 00168 /// Eccentricity calculation, copied and adapted from Lily's code 00169 /// @todo Re-enable eccentricity calculation 00170 // double getEcc(const Jet& jet) { 00171 // vector<double> phis; 00172 // vector<double> etas; 00173 // vector<double> energies; 00174 00175 // double etaSum(0), phiSum(0), eTot(0); 00176 // foreach (const Particle& p, jet.particles()) { 00177 // const double E = p.E(); 00178 // const double eta = p.eta(); 00179 00180 // energies.push_back(E); 00181 // etas.push_back(jet.eta() - eta); 00182 00183 // eTot += E; 00184 // etaSum += eta * E; 00185 00186 // /// @todo Replace with the Rivet deltaPhi function (or the mapAngleTo* functions) 00187 // double dPhi = jet.phi() - p.phi(); 00188 // //if DPhi does not lie within 0 < DPhi < PI take 2*PI off DPhi 00189 // //this covers cases where DPhi is greater than PI 00190 // if( fabs( dPhi - TWOPI ) < fabs(dPhi) ) dPhi -= TWOPI; 00191 // //if DPhi does not lie within -PI < DPhi < 0 add 2*PI to DPhi 00192 // //this covers cases where DPhi is less than -PI 00193 // else if( fabs(dPhi + TWOPI) < fabs(dPhi) ) dPhi += TWOPI; 00194 // phis.push_back(dPhi); 00195 00196 // phiSum += dPhi * E; 00197 // } 00198 00199 // //these are the "pull" away from the jet axis 00200 // etaSum = etaSum/eTot; 00201 // phiSum = phiSum/eTot; 00202 00203 // // now for every cluster we alter its position by moving it: 00204 // // away from the new axis if it is in the direction of -ve pull 00205 // // closer to the new axis if it is in the direction of +ve pull 00206 // // the effect of this will be that the new energy weighted center will be on the old jet axis. 00207 // double little_x(0), little_y(0); 00208 // for (size_t k = 0; k < jet.particles().size(); ++k) { 00209 // little_x+= etas[k]-etaSum; 00210 // little_y+= phis[k]-phiSum; 00211 // etas[k] = etas[k]-etaSum; 00212 // phis[k] = phis[k]-phiSum; 00213 // } 00214 00215 // double x1(0), x2(0); 00216 // for (size_t i = 0; i < jet.particles().size(); ++i) { 00217 // x1 += 2. * energies[i]* etas[i] * phis[i]; // this is 2*X*Y 00218 // x2 += energies[i]*(phis[i] * phis[i] - etas[i] * etas[i] ); // this is X^2 - Y^2 00219 // } 00220 00221 // // Variance calculations 00222 // double theta = .5*atan2(x1, x2); 00223 // double sinTheta =sin(theta); 00224 // double cosTheta = cos(theta); 00225 // double theta2 = theta + 0.5*PI; 00226 // double sinThetaPrime = sin(theta2); 00227 // double cosThetaPrime = cos(theta2); 00228 00229 // double varX(0), varY(0); 00230 // for (size_t i = 0; i < jet.particles().size(); i++) { 00231 // const double x = sinTheta*etas[i] + cosTheta*phis[i]; 00232 // const double y = sinThetaPrime*etas[i] + cosThetaPrime*phis[i]; 00233 // varX += energies[i]* sqr(x); 00234 // varY += energies[i]* sqr(y); 00235 // } 00236 // const double varianceMax = max(varX, varY); 00237 // const double varianceMin = min(varX, varY); 00238 // const double ecc = (varianceMax != 0.0) ? 1 - varianceMin/varianceMax : -1; 00239 // return ecc; 00240 // } 00241 00242 00243 /// Planar flow calculation, copied and adapted from Lily's code 00244 double getPFlow(const Jet& jet) { 00245 const double phi0 = jet.phi(); 00246 const double eta0 = jet.eta(); 00247 00248 double nref[3]; ///< @todo 3-vector to rotate x to? Use Rivet vector classes 00249 nref[0] = cos(phi0)/cosh(eta0); 00250 nref[1] = sin(phi0)/cosh(eta0); 00251 nref[2] = tanh(eta0); 00252 00253 // Rotation matrix to align with nref 00254 double rotationMatrix[3][3]; 00255 CalcRotationMatrix(nref, rotationMatrix); 00256 00257 double iw00(0.), iw01(0.), iw11(0.), iw10(0.); 00258 foreach (const Particle& p, jet.particles()) { 00259 double a = 1./(p.E()*jet.mass()); 00260 FourMomentum rotclus = RotateAxes(p.momentum(), rotationMatrix); 00261 iw00 += a*pow(rotclus.px(), 2); 00262 iw01 += a*rotclus.px()*rotclus.py(); 00263 iw10 += a*rotclus.py()*rotclus.px(); 00264 iw11 += a*pow(rotclus.py(), 2); 00265 } 00266 00267 const double det = iw00*iw11 - iw01*iw10; 00268 const double trace = iw00 + iw11; 00269 00270 const double pf = (trace != 0.0) ? (4.0*det)/sqr(trace) : -1; 00271 return pf; 00272 } 00273 00274 00275 /// Angularity calculation, copied and adapted from Lily's code 00276 double getAngularity(const Jet& jet) { 00277 double sum_a = 0.; 00278 // a can take any value < 2 (e.g. 1,0,-0.5 etc) for infrared safety 00279 const double a = -2.; 00280 foreach (const Particle& p, jet.particles()) { 00281 double e_i = p.E(); 00282 double theta_i = jet.momentum().angle(p.momentum()); 00283 double e_theta_i = e_i * pow(sin(theta_i), a) * pow(1-cos(theta_i), 1-a); 00284 sum_a += e_theta_i; 00285 } 00286 const double rtn = (jet.mass() != 0.0 && !std::isnan(sum_a)) ? sum_a/jet.mass() : -1; 00287 return rtn; 00288 } 00289 00290 } 00291 00292 00293 } Generated on Wed Oct 7 2015 12:09:10 for The Rivet MC analysis system by ![]() |