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 #include <iostream>
00005 #include <fstream>
00006 
00007 namespace Rivet {
00008 
00009 
00010   class ATLAS_2012_I1091481 : public Analysis {
00011   public:
00012 
00013     /// Constructor
00014     ATLAS_2012_I1091481()
00015       : Analysis("ATLAS_2012_I1091481")
00016     {
00017     }
00018 
00019 
00020   public:
00021 
00022     /// Book histograms and initialise projections before the run
00023     void init() {
00024 
00025       /// @todo Initialise and register projections here
00026       ChargedFinalState cfs100(-2.5, 2.5, 0.1*GeV);
00027       addProjection(cfs100,"CFS100");
00028       ChargedFinalState cfs500(-2.5, 2.5, 0.5*GeV);
00029       addProjection(cfs500,"CFS500");
00030 
00031 
00032       // collision energy
00033       int isqrts = -1;
00034       if (fuzzyEquals(sqrtS(), 900*GeV)) isqrts = 2;
00035       else if (fuzzyEquals(sqrtS(), 7*TeV)) isqrts = 1;
00036       assert(isqrts >= 0);
00037 
00038       _sE_10_100   = bookHisto1D(isqrts, 1, 1);
00039       _sE_1_100    = bookHisto1D(isqrts, 1, 2);
00040       _sE_10_500   = bookHisto1D(isqrts, 1, 3);
00041 
00042       _sEta_10_100 = bookHisto1D(isqrts, 2, 1);
00043       _sEta_1_100  = bookHisto1D(isqrts, 2, 2);
00044       _sEta_10_500 = bookHisto1D(isqrts, 2, 3);
00045     }
00046 
00047     // Recalculate particle energy assuming pion mass
00048     double getPionEnergy(const Particle& p) {
00049       double m_pi = 0.1396*GeV;
00050       double p2  = p.momentum().vector3().mod2()/(GeV*GeV);
00051       return sqrt(pow(m_pi,2) + p2);
00052     }
00053 
00054     // S_eta core for one event
00055     //
00056     //  -1 + 1/Nch * |sum_j^Nch exp[i*(xi eta_j - Phi_j)]|^2
00057     //
00058     double getSeta(const Particles& part, double xi) {
00059       std::complex<double> c_eta (0.0, 0.0);
00060       foreach (const Particle& p, part) {
00061         double eta = p.eta();
00062         double phi = p.momentum().phi();
00063         double arg = xi*eta-phi;
00064          std::complex<double> temp(cos(arg), sin(arg));
00065          c_eta += temp;
00066       }
00067       // Not 100% sure about the -1 here
00068       return std::norm(c_eta)/part.size() - 1.0;
00069     }
00070 
00071     // S_E core for one event
00072     //
00073     //  -1 + 1/Nch * |sum_j^Nch exp[i*(omega X_j - Phi_j)]|^2
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].momentum().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       // Not 100% sure about the -1 here
00086       return std::norm(c_E)/part.size() - 1.0;
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).midpoint();
00094         double y;
00095         if (SE) y = getSE(part, x);
00096         else    y = getSeta(part, x);
00097         h->fill(x, y*weight);
00098       }
00099     }
00100 
00101     /// Perform the per-event analysis
00102     void analyze(const Event& event) {
00103       double weight = event.weight();
00104 
00105       // Charged fs
00106       const ChargedFinalState& cfs100 = applyProjection<ChargedFinalState>(event, "CFS100");
00107       const Particles    part100 = cfs100.particlesByEta();
00108       const ChargedFinalState& cfs500 = applyProjection<ChargedFinalState>(event, "CFS500");
00109       const Particles&   part500 = cfs500.particlesByEta();
00110 
00111       // Veto event if the most inclusive phase space has less than 10 particles and the max pT is > 10 GeV
00112       if (part100.size() < 11) vetoEvent;
00113       double ptmax = cfs100.particlesByPt()[0].pT()/GeV;
00114       if (ptmax > 10.0) vetoEvent;
00115 
00116       // Fill the pt>100, pTmax<10 GeV histos
00117       fillS(_sE_10_100, part100, weight, true);
00118       fillS(_sEta_10_100, part100, weight, false);
00119 
00120       // Fill the pt>100, pTmax<1 GeV histos
00121       if (ptmax < 1.0) {
00122         fillS(_sE_1_100,   part100, weight, true);
00123         fillS(_sEta_1_100, part100, weight, false);
00124       }
00125 
00126       // Fill the pt>500, pTmax<10 GeV histos
00127       if (part500.size() > 10) {
00128         fillS(_sE_10_500, part500, weight, true);
00129         fillS(_sEta_10_500, part500, weight, false);
00130       }
00131     }
00132 
00133     /// Normalise histograms etc., after the run
00134     void finalize() {
00135       // The scaling takes the multiple fills per event into account
00136       // --- not sure about the normalisation
00137       scale(_sE_10_100, 1.0/(sumOfWeights()*_sE_10_100->numBins()));
00138       scale(_sE_1_100 , 1.0/(sumOfWeights()*_sE_1_100 ->numBins()));
00139       scale(_sE_10_500, 1.0/(sumOfWeights()*_sE_10_500->numBins()));
00140 
00141       scale(_sEta_10_100, 1.0/(sumOfWeights()*_sEta_10_100->numBins()));
00142       scale(_sEta_1_100 , 1.0/(sumOfWeights()*_sEta_1_100 ->numBins()));
00143       scale(_sEta_10_500, 1.0/(sumOfWeights()*_sEta_10_500->numBins()));
00144     }
00145 
00146     //@}
00147 
00148   private:
00149 
00150     Histo1DPtr _sE_10_100;
00151     Histo1DPtr _sE_1_100;
00152     Histo1DPtr _sE_10_500;
00153 
00154     Histo1DPtr _sEta_10_100;
00155     Histo1DPtr _sEta_1_100;
00156     Histo1DPtr _sEta_10_500;
00157   };
00158 
00159   // The hook for the plugin system
00160   DECLARE_RIVET_PLUGIN(ATLAS_2012_I1091481);
00161 }