rivet is hosted by Hepforge, IPPP Durham
ATLAS_2014_I1312627.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/WFinder.hh"
00005 #include "Rivet/Projections/ZFinder.hh"
00006 #include "Rivet/Projections/FastJets.hh"
00007 #include "Rivet/Projections/VetoedFinalState.hh"
00008 
00009 namespace Rivet {
00010 
00011 
00012   /// Measurement of V+jets distributions, taken as ratios between W and Z channels
00013   class ATLAS_2014_I1312627 : public Analysis {
00014   public:
00015 
00016     /// @name Plotting helper types
00017     //@{
00018 
00019     struct Plots {
00020       string ref;
00021       Histo1DPtr comp[2]; // (de)nominator components
00022       Scatter2DPtr ratio; // Rjets plot
00023     };
00024 
00025     typedef map<string, Plots> PlotMap;
00026     typedef PlotMap::value_type PlotMapPair;
00027 
00028     //@}
00029 
00030 
00031     /// Constructor
00032     ATLAS_2014_I1312627(std::string name="ATLAS_2014_I1312627")
00033       : Analysis(name)
00034     {
00035       _mode = 0; // using electron channel for combined data by default
00036       setNeedsCrossSection(true);
00037     }
00038 
00039 
00040     /// @name Analysis methods
00041     //@{
00042 
00043     /// Book histograms and initialise projections before the run
00044     void init() {
00045 
00046       // Set up cuts
00047       Cut cuts;
00048       if (_mode == 2) { // muon channel
00049         cuts = (Cuts::pT > 25.0*GeV) & Cuts::etaIn(-2.4, 2.4);
00050       } else if (_mode) { // electron channel
00051         cuts = (Cuts::pT > 25.0*GeV) & ( Cuts::etaIn(-2.47, -1.52) | Cuts::etaIn(-1.37, 1.37) | Cuts::etaIn(1.52, 2.47) );
00052       } else { // combined data extrapolated to common phase space
00053         cuts = (Cuts::pT > 25.0*GeV) & Cuts::etaIn(-2.5, 2.5);
00054       }
00055 
00056       // Boson finders
00057       FinalState fs;
00058       WFinder wfinder(fs, cuts, _mode > 1? PID::MUON : PID::ELECTRON, 40.0*GeV, MAXDOUBLE, 0.0*GeV, 0.1,
00059                       WFinder::CLUSTERNODECAY, WFinder::NOTRACK, WFinder::TRANSMASS);
00060       addProjection(wfinder, "WF");
00061 
00062       ZFinder zfinder(fs, cuts, _mode > 1? PID::MUON : PID::ELECTRON, 66.0*GeV, 116.0*GeV, 0.1, ZFinder::CLUSTERNODECAY, ZFinder::NOTRACK);
00063       addProjection(zfinder, "ZF");
00064 
00065       // Jets
00066       VetoedFinalState jet_fs(fs);
00067       jet_fs.addVetoOnThisFinalState(getProjection<WFinder>("WF"));
00068       jet_fs.addVetoOnThisFinalState(getProjection<ZFinder>("ZF"));
00069       FastJets jets(jet_fs, FastJets::ANTIKT, 0.4);
00070       jets.useInvisibles(true);
00071       addProjection(jets, "Jets");
00072 
00073 
00074       // Book Rjets plots
00075       _suff = string("-y0") + to_str(_mode + 1);
00076       hInit("Njets_incl",  "d01"); // inclusive number of jets
00077       hInit("Njets_excl",  "d04"); // exclusive number of jets
00078       hInit("Pt1_N1incl",  "d05"); // leading jet pT, at least 1 jet
00079       hInit("Pt1_N1excl",  "d06"); // leading jet pT, exactly 1 jet
00080       hInit("Pt1_N2incl",  "d07"); // leading jet pT, at least 2 jets
00081       hInit("Pt1_N3incl",  "d08"); // leading jet pT, at least 3 jets
00082       hInit("Pt2_N2incl",  "d09"); // subleading jet pT, at least 2 jets
00083       hInit("Pt3_N3incl",  "d10"); // sub-subleading jet pT, at least 3 jets
00084       hInit("ST_N2incl",   "d11"); // scalar jet pT sum, at least 2 jets
00085       hInit("ST_N2excl",   "d12"); // scalar jet pT sum, exactly 2 jets
00086       hInit("ST_N3incl",   "d13"); // scalar jet pT sum, at least 3 jets
00087       hInit("ST_N3excl",   "d14"); // scalar jet pT sum, exactly 3 jets
00088       hInit("DR_N2incl",   "d15"); // deltaR(j1, j2), at least 2 jets
00089       hInit("DPhi_N2incl", "d16"); // deltaPhi(j1, j2), at least 2 jets
00090       hInit("Mjj_N2incl",  "d17"); // mjj, at least 2 jets
00091       hInit("Rap1_N1incl", "d18"); // leading jet rapidity, at least 1 jet
00092       hInit("Rap2_N2incl", "d19"); // subleading jet rapidity, at least 2 jets
00093       hInit("Rap3_N3incl", "d20"); // sub-subleading jet rapidity, at least 3 jets
00094 
00095       // Also book numerator and denominator for Rjets plots
00096       foreach (PlotMapPair& str_plot, _plots) {
00097         str_plot.second.comp[0] = bookHisto1D( str_plot.second.ref + "2" + _suff, *(str_plot.second.ratio) );
00098         str_plot.second.comp[1] = bookHisto1D( str_plot.second.ref + "3" + _suff, *(str_plot.second.ratio) );
00099       }
00100     }
00101 
00102 
00103     /// Perform the per-event analysis
00104     void analyze(const Event& event) {
00105 
00106       // Retrieve boson candidate
00107       const WFinder& wf = applyProjection<WFinder>(event, "WF");
00108       const ZFinder& zf = applyProjection<ZFinder>(event, "ZF");
00109       if (wf.empty() && zf.empty())  vetoEvent;
00110 
00111       // Retrieve jets
00112       const JetAlg& jetfs = applyProjection<JetAlg>(event, "Jets");
00113       Jets all_jets = jetfs.jetsByPt(Cuts::pT > 30*GeV && Cuts::absrap < 4.4);
00114 
00115       // Apply boson cuts and fill histograms
00116       const double weight = event.weight();
00117       if (zf.size() == 2) {
00118         const Particles& leptons = zf.constituents();
00119         if (oppSign(leptons[0], leptons[1]) && deltaR(leptons[0], leptons[1]) > 0.2)
00120           fillPlots(leptons, all_jets, weight, 1);
00121       }
00122       if (!wf.empty()) {
00123         const Particles& leptons = wf.constituentLeptons();
00124         if (wf.constituentNeutrino().pT() > 25*GeV && wf.mT() > 40*GeV )
00125           fillPlots(leptons, all_jets, weight, 0);
00126       }
00127     }
00128 
00129 
00130     /// Normalise histograms etc., after the run
00131     void finalize() {
00132       ///  Normalise, scale and otherwise manipulate histograms here
00133       const double sf( crossSection() / sumOfWeights() );
00134       foreach (PlotMapPair& str_plot, _plots) {
00135         scale(str_plot.second.comp[0], sf);
00136         scale(str_plot.second.comp[1], sf);
00137         divide(str_plot.second.comp[0], str_plot.second.comp[1], str_plot.second.ratio);
00138       }
00139     }
00140     //@}
00141 
00142 
00143     /// Analysis helper functions
00144     //@{
00145 
00146     /// Histogram filling function, to avoid duplication
00147     void fillPlots(const Particles& leptons, Jets& all_jets, const double& weight, int isZ) {
00148       // Do jet-lepton overlap removal
00149       Jets jets;
00150       foreach (const Jet& j, all_jets) {
00151         /// @todo A nice place for a lambda and any() logic when C++11 is available
00152         bool keep = true;
00153         foreach (const Particle& l, leptons) keep &= deltaR(j, l) > 0.5;
00154         if (keep)  jets.push_back(j);
00155       }
00156 
00157       // Calculate jet ST
00158       const size_t njets = jets.size();
00159       double ST = 0.0; // scalar pT sum of all selected jets
00160       for (size_t i = 0; i < njets; ++i)
00161         ST += jets[i].pT() * GeV;
00162 
00163       // Fill jet histos
00164       _plots["Njets_excl"].comp[isZ]->fill(njets + 0.5, weight);
00165       for (size_t i = 0; i <= njets; ++i)
00166         _plots["Njets_incl"].comp[isZ]->fill(i + 0.5, weight);
00167 
00168       if (njets > 0) {
00169         const double pT1  = jets[0].pT()/GeV;
00170         const double rap1 = jets[0].absrap();
00171         _plots["Pt1_N1incl" ].comp[isZ]->fill(pT1,  weight);
00172         _plots["Rap1_N1incl"].comp[isZ]->fill(rap1, weight);
00173 
00174         if (njets == 1) {
00175           _plots["Pt1_N1excl"].comp[isZ]->fill(pT1, weight);
00176         } else if (njets > 1) {
00177           const double pT2  = jets[1].pT()/GeV;
00178           const double rap2 = jets[1].absrap();
00179           const double dR   = deltaR(jets[0], jets[1]);
00180           const double dPhi = deltaPhi(jets[0], jets[1]);
00181           const double mjj  = (jets[0].momentum() + jets[1].momentum()).mass()/GeV;
00182           _plots["Pt1_N2incl" ].comp[isZ]->fill(pT1,  weight);
00183           _plots["Pt2_N2incl" ].comp[isZ]->fill(pT2,  weight);
00184           _plots["Rap2_N2incl"].comp[isZ]->fill(rap2, weight);
00185           _plots["DR_N2incl"  ].comp[isZ]->fill(dR,   weight);
00186           _plots["DPhi_N2incl"].comp[isZ]->fill(dPhi, weight);
00187           _plots["Mjj_N2incl" ].comp[isZ]->fill(mjj,  weight);
00188           _plots["ST_N2incl"  ].comp[isZ]->fill(ST,   weight);
00189 
00190           if (njets == 2) {
00191             _plots["ST_N2excl"].comp[isZ]->fill(ST, weight);
00192           } else if (njets > 2) {
00193             const double pT3  = jets[2].pT()/GeV;
00194             const double rap3 = jets[2].absrap();
00195             _plots["Pt1_N3incl" ].comp[isZ]->fill(pT1,  weight);
00196             _plots["Pt3_N3incl" ].comp[isZ]->fill(pT3,  weight);
00197             _plots["Rap3_N3incl"].comp[isZ]->fill(rap3, weight);
00198             _plots["ST_N3incl"  ].comp[isZ]->fill(ST,   weight);
00199 
00200             if (njets == 3)
00201               _plots["ST_N3excl"].comp[isZ]->fill(ST, weight);
00202           }
00203         }
00204       }
00205     }
00206 
00207 
00208     /// Helper for histogram initialisation
00209     void hInit(string label, string ident) {
00210       string pre = ident + "-x0";
00211       _plots[label].ref = pre;
00212       _plots[label].ratio = bookScatter2D(pre + "1" + _suff, true);
00213     }
00214 
00215     //@}
00216 
00217 
00218   protected:
00219 
00220     // Data members
00221     size_t _mode;
00222     string _suff;
00223 
00224 
00225   private:
00226 
00227     /// @name Map of histograms
00228     PlotMap _plots;
00229 
00230   };
00231 
00232 
00233 
00234   /// Electron-specific version of the ATLAS_2014_I1312627 R-jets analysis
00235   class ATLAS_2014_I1312627_EL : public ATLAS_2014_I1312627 {
00236   public:
00237     ATLAS_2014_I1312627_EL()
00238       : ATLAS_2014_I1312627("ATLAS_2014_I1312627_EL")
00239     { _mode = 1; }
00240   };
00241 
00242 
00243   /// Muon-specific version of the ATLAS_2014_I1312627 R-jets analysis
00244   class ATLAS_2014_I1312627_MU : public ATLAS_2014_I1312627 {
00245   public:
00246     ATLAS_2014_I1312627_MU()
00247       : ATLAS_2014_I1312627("ATLAS_2014_I1312627_MU")
00248     { _mode = 2; }
00249   };
00250 
00251 
00252   // Hooks for the plugin system
00253   DECLARE_RIVET_PLUGIN(ATLAS_2014_I1312627);
00254   DECLARE_RIVET_PLUGIN(ATLAS_2014_I1312627_EL);
00255   DECLARE_RIVET_PLUGIN(ATLAS_2014_I1312627_MU);
00256 
00257 
00258 }