rivet is hosted by Hepforge, IPPP Durham
ATLAS_2012_I1091481.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/ChargedFinalState.hh"
00004 
00005 namespace Rivet {
00006 
00007 
00008   class ATLAS_2012_I1091481 : public Analysis {
00009   public:
00010 
00011     /// Constructor
00012     ATLAS_2012_I1091481()
00013       : Analysis("ATLAS_2012_I1091481")
00014     {   }
00015 
00016 
00017     /// Book histograms and initialise projections before the run
00018     void init() {
00019 
00020       ChargedFinalState cfs100(Cuts::abseta < 2.5 && Cuts::pT > 0.1*GeV);
00021       addProjection(cfs100,"CFS100");
00022       ChargedFinalState cfs500(Cuts::abseta < 2.5 && Cuts::pT > 0.5*GeV);
00023       addProjection(cfs500,"CFS500");
00024 
00025       // collision energy
00026       int isqrts = -1;
00027       if (fuzzyEquals(sqrtS(), 900*GeV)) isqrts = 2;
00028       if (fuzzyEquals(sqrtS(),   7*TeV)) isqrts = 1;
00029       assert(isqrts > 0);
00030 
00031       _sE_10_100   = bookHisto1D(isqrts, 1, 1);
00032       _sE_1_100    = bookHisto1D(isqrts, 1, 2);
00033       _sE_10_500   = bookHisto1D(isqrts, 1, 3);
00034 
00035       _sEta_10_100 = bookHisto1D(isqrts, 2, 1);
00036       _sEta_1_100  = bookHisto1D(isqrts, 2, 2);
00037       _sEta_10_500 = bookHisto1D(isqrts, 2, 3);
00038 
00039       norm_inclusive = 0.;
00040       norm_lowPt = 0.;
00041       norm_pt500 = 0.;
00042     }
00043 
00044 
00045     // Recalculate particle energy assuming pion mass
00046     double getPionEnergy(const Particle& p) {
00047       double m_pi = 0.1396*GeV;
00048       double p2 = p.p3().mod2()/(GeV*GeV);
00049       return sqrt(sqr(m_pi) + p2);
00050     }
00051 
00052 
00053     // S_eta core for one event
00054     //
00055     //  -1 + 1/Nch * |sum_j^Nch exp[i*(xi eta_j - Phi_j)]|^2
00056     //
00057     double getSeta(const Particles& part, double xi) {
00058       std::complex<double> c_eta (0.0, 0.0);
00059       foreach (const Particle& p, part) {
00060         double eta = p.eta();
00061         double phi = p.phi();
00062         double arg = xi*eta-phi;
00063          std::complex<double> temp(cos(arg), sin(arg));
00064          c_eta += temp;
00065       }
00066       return std::norm(c_eta)/part.size() - 1.0;
00067     }
00068 
00069 
00070     // S_E core for one event
00071     //
00072     //  -1 + 1/Nch * |sum_j^Nch exp[i*(omega X_j - Phi_j)]|^2
00073     //
00074     double getSE(const Particles& part, double omega) {
00075       double Xj = 0.0;
00076       std::complex<double> c_E (0.0, 0.0);
00077       for (unsigned int i=0; i < part.size(); ++i) {
00078         Xj += 0.5*getPionEnergy(part[i]);
00079         double phi = part[i].phi();
00080         double arg = omega*Xj - phi;
00081         std::complex<double> temp(cos(arg), sin(arg));
00082         c_E += temp;
00083         Xj += 0.5*getPionEnergy(part[i]);
00084       }
00085       return std::norm(c_E)/part.size() - 1.0;
00086     }
00087 
00088 
00089     // Convenient fill function
00090     void fillS(Histo1DPtr h, const Particles& part, double weight, bool SE=true) {
00091       // Loop over bins, take bin centers as parameter values
00092       for(size_t i=0; i < h->numBins(); ++i) {
00093         double x = h->bin(i).xMid();
00094         double width = h->bin(i).xMax() - h->bin(i).xMin();
00095         double y;
00096         if(SE)  y = getSE(part,   x);
00097         else    y = getSeta(part, x);
00098         h->fill(x, y * width * weight);
00099         // Histo1D objects will be converted to Scatter2D objects for plotting
00100         // As part of this conversion, Rivet will divide by bin width
00101         // However, we want the (x,y) of the Scatter2D to be the (binCenter, sumW) of
00102         // the current Histo1D. This is why in the above line we multiply by bin width,
00103         // so as to undo later division by bin width.
00104         //
00105         // Could have used Scatter2D objects in the first place, but they cannot be merged
00106         // as easily as Histo1Ds can using yodamerge (missing ScaledBy attribute)
00107         }
00108     }
00109 
00110 
00111     /// Perform the per-event analysis
00112     void analyze(const Event& event) {
00113       double weight = event.weight();
00114 
00115       // Charged fs
00116       const ChargedFinalState& cfs100  = applyProjection<ChargedFinalState>(event, "CFS100");
00117       const Particles          part100 = cfs100.particles(cmpMomByEta);
00118       const ChargedFinalState& cfs500  = applyProjection<ChargedFinalState>(event, "CFS500");
00119       const Particles&         part500 = cfs500.particles(cmpMomByEta);
00120 
00121       // Veto event if the most inclusive phase space has less than 10 particles and the max pT is > 10 GeV
00122       if (part100.size() < 11) vetoEvent;
00123       double ptmax = cfs100.particlesByPt()[0].pT()/GeV;
00124       if (ptmax > 10.0) vetoEvent;
00125 
00126       // Fill the pt>100, pTmax<10 GeV histos
00127       fillS(_sE_10_100, part100, weight, true);
00128       fillS(_sEta_10_100, part100, weight, false);
00129       norm_inclusive += weight;
00130 
00131       // Fill the pt>100, pTmax<1 GeV histos
00132       if (ptmax < 1.0) {
00133         fillS(_sE_1_100,   part100, weight, true);
00134         fillS(_sEta_1_100, part100, weight, false);
00135         norm_lowPt += weight;
00136       }
00137 
00138       // Fill the pt>500, pTmax<10 GeV histos
00139       if (part500.size() > 10) {
00140         fillS(_sE_10_500,   part500, weight, true );
00141         fillS(_sEta_10_500, part500, weight, false);
00142         norm_pt500 += weight;
00143       }
00144     }
00145 
00146     /// Normalise histograms etc., after the run
00147     void finalize() {
00148       // The scaling takes the multiple fills per event into account
00149       scale(_sE_10_100, 1.0/norm_inclusive);
00150       scale(_sE_1_100 , 1.0/norm_lowPt);
00151       scale(_sE_10_500, 1.0/norm_pt500);
00152 
00153       scale(_sEta_10_100, 1.0/norm_inclusive);
00154       scale(_sEta_1_100 , 1.0/norm_lowPt);
00155       scale(_sEta_10_500, 1.0/norm_pt500);
00156     }
00157 
00158     //@}
00159 
00160 
00161   private:
00162 
00163     Histo1DPtr _sE_10_100;
00164     Histo1DPtr _sE_1_100;
00165     Histo1DPtr _sE_10_500;
00166 
00167     Histo1DPtr _sEta_10_100;
00168     Histo1DPtr _sEta_1_100;
00169     Histo1DPtr _sEta_10_500;
00170 
00171     double norm_inclusive;
00172     double norm_lowPt;
00173     double norm_pt500;
00174   };
00175 
00176 
00177   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1091481);
00178 
00179 }