rivet is hosted by Hepforge, IPPP Durham
ATLAS_2014_I1307756.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/IdentifiedFinalState.hh"
00005 #include "Rivet/Projections/FastJets.hh"
00006 
00007 namespace Rivet {
00008 
00009 
00010   class ATLAS_2014_I1307756 : public Analysis {
00011   public:
00012 
00013     /// Constructor
00014     ATLAS_2014_I1307756()
00015       : Analysis("ATLAS_2014_I1307756")
00016     {
00017       _eta_bins_areaoffset.push_back(0.0);
00018       _eta_bins_areaoffset.push_back(1.5);
00019       _eta_bins_areaoffset.push_back(3.0);
00020     }
00021 
00022 
00023     /// @name Analysis methods
00024     //@{
00025 
00026     /// Book histograms and initialise projections before the run
00027     void init() {
00028 
00029       /// Initialise and register projections here
00030       FinalState fs;
00031       addProjection(fs, "FS");
00032 
00033       FastJets fj(fs, FastJets::KT, 0.5);
00034       _area_def = new fastjet::AreaDefinition(fastjet::VoronoiAreaSpec());
00035       fj.useJetArea(_area_def);
00036       addProjection(fj, "KtJetsD05");
00037 
00038       IdentifiedFinalState photonfs(-2.37, 2.37, 22.0*GeV);
00039       photonfs.acceptId(PID::PHOTON);
00040       addProjection(photonfs, "photons");
00041 
00042       // Initialize event count here:
00043       _fidWeights = 0.;
00044     }
00045 
00046 
00047     /// Utility to compute ambiant energy density per eta bin
00048     /// @todo Use bin index lookup util instead...
00049     int getEtaBin(double eta_w) const {
00050       double eta = fabs(eta_w);
00051       int v_iter = 0;
00052       for (v_iter = 0; v_iter < (int)_eta_bins_areaoffset.size()-1; ++v_iter) {
00053         if (inRange(eta, _eta_bins_areaoffset[v_iter], _eta_bins_areaoffset[v_iter+1]))
00054           break;
00055       }
00056       return v_iter;
00057     }
00058 
00059 
00060     /// Perform the per-event analysis
00061     void analyze(const Event& event) {
00062       /// Require at least 2 photons in final state
00063       Particles photons = applyProjection<IdentifiedFinalState>(event, "photons").particlesByPt();
00064       if (photons.size() < 2) vetoEvent;
00065 
00066       /// compute the median energy density per eta bin
00067       vector<double> _ptDensity;
00068       vector< vector<double> > ptDensities;
00069       vector<double> emptyVec;
00070       ptDensities.assign(_eta_bins_areaoffset.size()-1, emptyVec);
00071 
00072       const fastjet::ClusterSequenceArea* clust_seq_area = applyProjection<FastJets>(event, "KtJetsD05").clusterSeqArea();
00073       foreach (const fastjet::PseudoJet& jet, applyProjection<FastJets>(event, "KtJetsD05").pseudoJets(0.0*GeV)) {
00074         const double eta = fabs( jet.eta()  );
00075         const double pt  = fabs( jet.perp() );
00076         const double area = clust_seq_area->area(jet);
00077         if (area > 1e-4 && fabs(eta) < _eta_bins_areaoffset[_eta_bins_areaoffset.size()-1]) {
00078           ptDensities.at(getEtaBin(fabs(eta))).push_back(pt/area);
00079         }
00080       }
00081 
00082       for (size_t b = 0; b < _eta_bins_areaoffset.size()-1; ++b) {
00083         double median = 0.0;
00084         if (ptDensities[b].size() > 0) {
00085           std::sort(ptDensities[b].begin(), ptDensities[b].end());
00086           const int nDens = ptDensities[b].size();
00087           if (nDens % 2 == 0) {
00088             median = (ptDensities[b][nDens/2] + ptDensities[b][(nDens-2)/2]) / 2;
00089           } else {
00090             median = ptDensities[b][(nDens-1)/2];
00091           }
00092         }
00093         _ptDensity.push_back(median);
00094       }
00095 
00096       // Loop over photons and find isolated ones
00097       Particles isolated_photons;
00098       foreach (const Particle& ph, photons) {
00099         Particles fs = applyProjection<FinalState>(event, "FS").particles();
00100         FourMomentum mom_in_EtCone;
00101         foreach (const Particle& p, fs) {
00102 
00103           // Reject if the particle is not in DR=0.4 cone
00104           if (deltaR(ph.momentum(), p.momentum()) > 0.4) continue;
00105 
00106           // Reject if the particle falls in the photon core
00107           if (fabs(ph.eta() - p.eta()) < 0.025 * 7 * 0.5 &&
00108               fabs(ph.phi() - p.phi()) < PI/128. * 5 * 0.5) continue;
00109 
00110           // Reject if the particle is a neutrino (muons are kept)
00111           if (p.isNeutrino()) continue;
00112 
00113           // Sum momenta
00114           mom_in_EtCone += p.momentum();
00115         }
00116 
00117         // Subtract the UE correction (area*density)
00118         double EtCone_area = M_PI*.4*.4 - (7.0*.025)*(5.0*M_PI/128.);
00119         double correction = _ptDensity[getEtaBin(ph.eta())]*EtCone_area;
00120 
00121         // Add isolated photon to list
00122         if (mom_in_EtCone.Et() - correction > 12*GeV) continue;
00123         isolated_photons.push_back(ph);
00124       }
00125 
00126       // Require at least two isolated photons
00127       if (isolated_photons.size() < 2)  vetoEvent ;
00128 
00129       // Select leading pT pair
00130       std::sort(isolated_photons.begin(), isolated_photons.end(), cmpMomByPt);
00131       FourMomentum y1 = isolated_photons[0].momentum();
00132       FourMomentum y2 = isolated_photons[1].momentum();
00133 
00134       // compute invariant mass
00135       FourMomentum yy = y1 + y2;
00136       double Myy = yy.mass();
00137 
00138       // if Myy >= 110 GeV, apply relative cuts
00139       if (Myy/GeV >= 110 && (y1.Et()/Myy < 0.4 || y2.Et()/Myy < 0.3) ) vetoEvent;
00140 
00141       // Add to cross-section
00142       _fidWeights += event.weight();
00143     }
00144 
00145 
00146     /// Normalise histograms etc., after the run
00147     void finalize() {
00148 
00149       // Compute selection efficiency & statistical error
00150       double eff = _fidWeights/sumOfWeights();
00151       double err = sqrt(eff*(1-eff)/numEvents());
00152 
00153       // Compute fiducial cross-section in fb
00154       const double fidCrossSection = eff * crossSection()/femtobarn;
00155 
00156       // Print out result
00157       MSG_INFO("==================================================");
00158       MSG_INFO("==== Total cross-section: " << crossSection()/femtobarn<< " fb");
00159       MSG_INFO("==== Fiducial cross-section: " << fidCrossSection << " fb");
00160       MSG_INFO("==================================================");
00161       MSG_INFO("==== Selection efficiency: " << eff << " +/- " << err << " (statistical error)");
00162       MSG_INFO("==================================================");
00163     }
00164 
00165     //@}
00166 
00167 
00168   private:
00169 
00170     fastjet::AreaDefinition* _area_def;
00171     vector<double> _eta_bins_areaoffset;
00172     float _fidWeights;
00173 
00174   };
00175 
00176 
00177 
00178   // The hook for the plugin system
00179   DECLARE_RIVET_PLUGIN(ATLAS_2014_I1307756);
00180 
00181 }