rivet is hosted by Hepforge, IPPP Durham
ATLAS_2011_S9126244.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/FastJets.hh"
00005 
00006 #include "Rivet/Tools/BinnedHistogram.hh"
00007 
00008 namespace Rivet {
00009 
00010 
00011   struct ATLAS_2011_S9126244_Plots {
00012 
00013     int selectionType; //< The HepData y-axis code
00014     string intermediateHistName;
00015 
00016     // Gap fraction vs DeltaY plot setup
00017     int _gapFractionDeltaYHistIndex;
00018     vector<double> _gapFractionDeltaYSlices;
00019     BinnedHistogram<double> _h_gapVsDeltaYVeto;
00020     BinnedHistogram<double> _h_gapVsDeltaYInc;
00021 
00022     // Gap fraction vs ptBar plot setup
00023     int _gapFractionPtBarHistIndex;
00024     vector<double> _gapFractionPtBarSlices;
00025     BinnedHistogram<double> _h_gapVsPtBarVeto;
00026     BinnedHistogram<double> _h_gapVsPtBarInc;
00027 
00028     // Gap fraction vs Q0 plot setup
00029     int _gapFractionQ0HistIndex;
00030     vector<double> _gapFractionQ0SlicesPtBar;
00031     vector<double> _gapFractionQ0SlicesDeltaY;
00032     vector<Histo1DPtr> _h_vetoPt;
00033     vector<Scatter2DPtr> _d_vetoPtGapFraction;
00034     vector<double> _vetoPtTotalSum; //< @todo Can this just be replaced with _h_vetoPt.integral()?
00035 
00036     // Average njet vs DeltaY setup
00037     int _avgNJetDeltaYHistIndex;
00038     vector<double> _avgNJetDeltaYSlices;
00039     vector<Profile1DPtr> _p_avgJetVsDeltaY;
00040 
00041     // Average njet vs PptBar setup
00042     int _avgNJetPtBarHistIndex;
00043     vector<double> _avgNJetPtBarSlices;
00044     vector<Profile1DPtr> _p_avgJetVsPtBar;
00045   };
00046 
00047 
00048 
00049   /// ATLAS dijet production with central jet veto
00050   /// @todo Make sure that temp histos are removed
00051   class ATLAS_2011_S9126244 : public Analysis {
00052   public:
00053 
00054     /// Constructor
00055     ATLAS_2011_S9126244()
00056       : Analysis("ATLAS_2011_S9126244")
00057     {    }
00058 
00059 
00060   public:
00061 
00062     /// Book histograms and initialise projections before the run
00063     void init() {
00064 
00065       // Initialize the lone projection required
00066       addProjection(FastJets(FinalState(), FastJets::ANTIKT, 0.6), "AntiKtJets06");
00067 
00068       // Initialize plots for each selection type
00069       _selectionPlots[0].intermediateHistName = "highestPt";
00070       _selectionPlots[0].selectionType = 1;
00071       _selectionPlots[0]._gapFractionDeltaYHistIndex = 6;
00072       _selectionPlots[0]._gapFractionPtBarHistIndex = 1;
00073       _selectionPlots[0]._gapFractionQ0HistIndex = 13;
00074       _selectionPlots[0]._avgNJetDeltaYHistIndex = 37;
00075       _selectionPlots[0]._avgNJetPtBarHistIndex = 26;
00076       _selectionPlots[0]._gapFractionDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00077       _selectionPlots[0]._gapFractionPtBarSlices += 1.0, 2.0, 3.0, 4.0, 5.0, 6.0;
00078       _selectionPlots[0]._gapFractionQ0SlicesPtBar += 70.0, 90.0, 120.0, 150.0, 210.0, 240.0;
00079       _selectionPlots[0]._gapFractionQ0SlicesDeltaY += 2.0, 3.0, 4.0, 5.0;
00080       _selectionPlots[0]._avgNJetPtBarSlices += 1.0, 2.0, 3.0, 4.0, 5.0;
00081       _selectionPlots[0]._avgNJetDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00082       initializePlots(_selectionPlots[0]);
00083 
00084       _selectionPlots[1].intermediateHistName = "forwardBackward";
00085       _selectionPlots[1].selectionType = 2;
00086       _selectionPlots[1]._gapFractionDeltaYHistIndex = 6;
00087       _selectionPlots[1]._gapFractionPtBarHistIndex = 1;
00088       _selectionPlots[1]._gapFractionQ0HistIndex = 13;
00089       _selectionPlots[1]._avgNJetDeltaYHistIndex = 37;
00090       _selectionPlots[1]._avgNJetPtBarHistIndex = 26;
00091       _selectionPlots[1]._gapFractionDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00092       _selectionPlots[1]._gapFractionPtBarSlices += 1.0, 2.0, 3.0, 4.0, 5.0, 6.0;
00093       _selectionPlots[1]._gapFractionQ0SlicesPtBar += 70.0, 90.0, 120.0, 150.0, 210.0, 240.0;
00094       _selectionPlots[1]._gapFractionQ0SlicesDeltaY += 2.0, 3.0, 4.0, 5.0;
00095       _selectionPlots[1]._avgNJetPtBarSlices += 1.0, 2.0, 3.0, 4.0, 5.0;
00096       _selectionPlots[1]._avgNJetDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00097       initializePlots(_selectionPlots[1]);
00098 
00099       _selectionPlots[2].intermediateHistName = "forwardBackward_PtBarVeto";
00100       _selectionPlots[2].selectionType = 1;
00101       _selectionPlots[2]._gapFractionDeltaYHistIndex = 19;
00102       _selectionPlots[2]._avgNJetDeltaYHistIndex = 30;
00103       _selectionPlots[2]._gapFractionDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00104       _selectionPlots[2]._avgNJetDeltaYSlices += 70.0, 90.0, 120.0, 150.0, 180.0, 210.0, 240.0, 270.0;
00105       initializePlots(_selectionPlots[2]);
00106     }
00107 
00108 
00109     void initializePlots(ATLAS_2011_S9126244_Plots& plots) {
00110 
00111       // Gap fraction vs DeltaY
00112       if (!plots._gapFractionDeltaYSlices.empty()) {
00113         for (size_t x = 0; x < plots._gapFractionDeltaYSlices.size()-1; x++) {
00114           const string vetoHistName = "gapDeltaYVeto_" + plots.intermediateHistName + "_" + to_str(x);
00115           const string inclusiveHistName = "gapDeltaYInclusive_" + plots.intermediateHistName + "_" + to_str(x);
00116           plots._h_gapVsDeltaYVeto.addHistogram(plots._gapFractionDeltaYSlices[x], plots._gapFractionDeltaYSlices[x+1],
00117                                                 bookHisto1D(plots._gapFractionDeltaYHistIndex+x, 1, plots.selectionType, vetoHistName));
00118           plots._h_gapVsDeltaYInc.addHistogram(plots._gapFractionDeltaYSlices[x], plots._gapFractionDeltaYSlices[x+1],
00119                                                bookHisto1D(plots._gapFractionDeltaYHistIndex+x, 1, plots.selectionType, inclusiveHistName));
00120         }
00121       }
00122 
00123       // Average njet vs DeltaY
00124       if (!plots._avgNJetDeltaYSlices.empty()) {
00125         for (size_t x = 0; x < plots._avgNJetDeltaYSlices.size()-1; x++) {
00126           plots._p_avgJetVsDeltaY += bookProfile1D(plots._avgNJetDeltaYHistIndex+x, 1, plots.selectionType);
00127         }
00128       }
00129 
00130       // Gap fraction vs PtBar
00131       if (!plots._gapFractionPtBarSlices.empty()) {
00132         for (size_t x = 0; x < plots._gapFractionPtBarSlices.size()-1; x++) {
00133           const string vetoHistName = "gapPtBarVeto_" + plots.intermediateHistName + "_" + to_str(x);
00134           const string inclusiveHistName = "gapPtBarInclusive_" + plots.intermediateHistName + "_" + to_str(x);
00135           plots._h_gapVsPtBarVeto.addHistogram(plots._gapFractionPtBarSlices[x], plots._gapFractionPtBarSlices[x+1],
00136                                                bookHisto1D(plots._gapFractionPtBarHistIndex+x, 1, plots.selectionType, vetoHistName));
00137           plots._h_gapVsPtBarInc.addHistogram(plots._gapFractionPtBarSlices[x], plots._gapFractionPtBarSlices[x+1],
00138                                               bookHisto1D(plots._gapFractionPtBarHistIndex+x, 1, plots.selectionType, inclusiveHistName));
00139         }
00140       }
00141 
00142       // Average njet vs PtBar
00143       if (!plots._avgNJetPtBarSlices.empty()) {
00144         for (size_t x=0; x<plots._avgNJetPtBarSlices.size()-1; x++) {
00145           plots._p_avgJetVsPtBar += bookProfile1D(plots._avgNJetPtBarHistIndex+x, 1, plots.selectionType);
00146         }
00147       }
00148 
00149       // Gap fraction vs Q0
00150       int q0PlotCount = 0;
00151       for (size_t x = 0; x < plots._gapFractionQ0SlicesPtBar.size()/2; x++) {
00152         for (size_t y = 0; y < plots._gapFractionQ0SlicesDeltaY.size()/2; y++) {
00153           const string vetoPtHistName = "vetoPt_" + plots.intermediateHistName + "_" + to_str(q0PlotCount);
00154           plots._h_vetoPt += bookHisto1D(vetoPtHistName, refData(plots._gapFractionQ0HistIndex + q0PlotCount, 1, plots.selectionType));
00155           plots._d_vetoPtGapFraction += bookScatter2D(plots._gapFractionQ0HistIndex + q0PlotCount, 1, plots.selectionType);
00156           plots._vetoPtTotalSum += 0.0; //< @todo Can this just be replaced with _h_vetoPt.integral()?
00157           q0PlotCount += 1;
00158         }
00159       }
00160     }
00161 
00162 
00163     /// Perform the per-event analysis
00164     void analyze(const Event& event) {
00165       const double weight = event.weight();
00166 
00167       // Get minimal list of jets needed to be considered
00168       double minimumJetPtBar = 50.0*GeV; // of interval defining jets
00169 
00170       vector<FourMomentum> acceptJets;
00171       foreach (const Jet& jet, applyProjection<FastJets>(event, "AntiKtJets06").jetsByPt(20.0*GeV)) {
00172         if (fabs(jet.rapidity()) < 4.4) {
00173           acceptJets.push_back(jet.momentum());
00174         }
00175       }
00176 
00177       // If we can't form an interval, drop out of the analysis early
00178       if (acceptJets.size() < 2) vetoEvent;
00179 
00180       // Analyze leading jet case
00181       if (acceptJets[0].pT() + acceptJets[1].pT() > 2*minimumJetPtBar) {
00182         analyzeJets(acceptJets, _selectionPlots[0], weight, 20.0*GeV);
00183       }
00184 
00185       // Find the most forward-backward jets
00186       size_t minRapidityJet = 0, maxRapidityJet = 0;
00187       for (size_t j = 1; j < acceptJets.size(); j++) {
00188         if (acceptJets[j].rapidity() > acceptJets[maxRapidityJet].rapidity()) maxRapidityJet = j;
00189         if (acceptJets[j].rapidity() < acceptJets[minRapidityJet].rapidity()) minRapidityJet = j;
00190       }
00191 
00192       // Make a container of jet momenta with the extreme f/b jets at the front
00193       vector<FourMomentum> fwdBkwdJets;
00194       fwdBkwdJets.push_back(acceptJets[maxRapidityJet]);
00195       fwdBkwdJets.push_back(acceptJets[minRapidityJet]);
00196       for (size_t j = 0; j < acceptJets.size(); j++) {
00197         if (j == minRapidityJet || j == maxRapidityJet) continue;
00198         fwdBkwdJets.push_back(acceptJets[j]);
00199       }
00200 
00201       if (fwdBkwdJets[0].pT() + fwdBkwdJets[1].pT() > 2*minimumJetPtBar) {
00202         // Use most forward/backward jets in rapidity to define the interval
00203         analyzeJets(fwdBkwdJets, _selectionPlots[1], weight, 20.0*GeV);
00204         // As before but now using PtBar of interval to define veto threshold
00205         analyzeJets(fwdBkwdJets, _selectionPlots[2], weight, (fwdBkwdJets[0].pT()+fwdBkwdJets[1].pT())/2.0);
00206       }
00207     }
00208 
00209 
00210     /// Fill plots!
00211     void analyzeJets(vector<FourMomentum>& jets, ATLAS_2011_S9126244_Plots& plots,
00212                      const double weight, double vetoPtThreshold) {
00213 
00214       // Calculate the interval size, ptBar and veto Pt (if any)
00215       const double intervalSize = fabs(jets[0].rapidity()-jets[1].rapidity());
00216       const double ptBar = (jets[0].pT()+jets[1].pT())/2.0;
00217 
00218       const double minY = min(jets[0].rapidity(), jets[1].rapidity());
00219       const double maxY = max(jets[0].rapidity(), jets[1].rapidity());
00220 
00221       double vetoPt = 0.0*GeV;
00222       for (size_t j = 2; j < jets.size(); j++) {
00223         if (inRange(jets[j].rapidity(), minY, maxY)) vetoPt = max(jets[j].pT(), vetoPt);
00224       }
00225 
00226       // Fill the gap fraction vs delta Y histograms
00227       plots._h_gapVsDeltaYInc.fill(ptBar/GeV, intervalSize, weight);
00228       if (vetoPt < vetoPtThreshold) {
00229         plots._h_gapVsDeltaYVeto.fill(ptBar/GeV, intervalSize, weight);
00230       }
00231 
00232       // Fill the gap fraction vs ptBar histograms
00233       plots._h_gapVsPtBarInc.fill(intervalSize, ptBar/GeV,  weight);
00234       if (vetoPt < vetoPtThreshold) {
00235         plots._h_gapVsPtBarVeto.fill(intervalSize, ptBar/GeV, weight);
00236       }
00237 
00238       // Count the number of veto jets present
00239       int vetoJetsCount = 0;
00240       for (size_t j = 2; j < jets.size(); j++) {
00241         if (inRange(jets[j].rapidity(), minY, maxY) && jets[j].pT() > vetoPtThreshold) {
00242           vetoJetsCount += 1;
00243         }
00244       }
00245 
00246       // Fill the avg NJet, deltaY slices
00247       if (!plots._avgNJetPtBarSlices.empty()) {
00248       for (size_t i = 0; i < plots._avgNJetPtBarSlices.size()-1; i++) {
00249         if (inRange(intervalSize, plots._avgNJetPtBarSlices[i], plots._avgNJetPtBarSlices[i+1])) {
00250           plots._p_avgJetVsPtBar[i]->fill(ptBar/GeV, vetoJetsCount, weight);
00251         }
00252       }
00253       }
00254 
00255       // Fill the avg NJet, ptBar slices
00256       if (!plots._avgNJetDeltaYSlices.empty()) {
00257       for (size_t i = 0; i < plots._avgNJetDeltaYSlices.size()-1; i++) {
00258         if (inRange(ptBar/GeV, plots._avgNJetDeltaYSlices[i], plots._avgNJetDeltaYSlices[i+1])) {
00259           plots._p_avgJetVsDeltaY[i]->fill(intervalSize, vetoJetsCount, weight);
00260         }
00261       }
00262       }
00263 
00264       // Fill the veto pt plots
00265       int q0PlotCount = 0;
00266       for (size_t x = 0; x < plots._gapFractionQ0SlicesPtBar.size()/2; x++) {
00267         for (size_t y = 0; y < plots._gapFractionQ0SlicesDeltaY.size()/2; y++) {
00268           // Check if it should be filled
00269           if ( ptBar/GeV < plots._gapFractionQ0SlicesPtBar[x*2] ||
00270                ptBar/GeV >= plots._gapFractionQ0SlicesPtBar[x*2+1] ) {
00271             q0PlotCount++;
00272             continue;
00273           }
00274 
00275           if ( intervalSize < plots._gapFractionQ0SlicesDeltaY[y*2] ||
00276                intervalSize >= plots._gapFractionQ0SlicesDeltaY[y*2+1] ) {
00277             q0PlotCount++;
00278             continue;
00279           }
00280 
00281           plots._h_vetoPt[q0PlotCount]->fill(vetoPt, weight);
00282           plots._vetoPtTotalSum[q0PlotCount] += weight;
00283 
00284           q0PlotCount++;
00285         }
00286       }
00287     }
00288 
00289 
00290     /// Derive final distributions for each selection
00291     void finalize() {
00292       foreach (const ATLAS_2011_S9126244_Plots& plots, _selectionPlots) {
00293 
00294         /// @todo Clean up temp histos -- requires restructuring the temp histo struct
00295 
00296         for (size_t x = 0; x < plots._h_gapVsDeltaYVeto.getHistograms().size(); x++) {
00297           divide(plots._h_gapVsDeltaYVeto.getHistograms()[x], plots._h_gapVsDeltaYInc.getHistograms()[x],
00298                  bookScatter2D(plots._gapFractionDeltaYHistIndex+x, 1, plots.selectionType));
00299         }
00300         for (size_t x = 0; x < plots._h_gapVsPtBarVeto.getHistograms().size(); x++) {
00301           divide(plots._h_gapVsPtBarVeto.getHistograms()[x], plots._h_gapVsPtBarInc.getHistograms()[x],
00302                  bookScatter2D(plots._gapFractionPtBarHistIndex+x, 1, plots.selectionType));
00303         }
00304 
00305         for (size_t h = 0; h < plots._d_vetoPtGapFraction.size(); h++) {
00306           finalizeQ0GapFraction(plots._vetoPtTotalSum[h], plots._d_vetoPtGapFraction[h], plots._h_vetoPt[h]);
00307         }
00308       }
00309     }
00310 
00311 
00312     /// Convert the differential histograms to an integral histo and assign binomial errors as a efficiency
00313     /// @todo Should be convertible to a YODA ~one-liner using toIntegralEfficiencyHisto
00314     void finalizeQ0GapFraction(double totalWeightSum, Scatter2DPtr gapFractionDP, Histo1DPtr vetoPtHist) {
00315       for (size_t i = 0; i < vetoPtHist->numBins(); ++i) {
00316         const double vetoPtWeightSum = vetoPtHist->integral(i); //< Integral (with underflow) up to but not including bin i
00317         // Calculate the efficiency & binomial uncertainty
00318         const double eff = (totalWeightSum != 0) ? vetoPtWeightSum/totalWeightSum : 0;
00319         const double effErr = (totalWeightSum != 0) ? sqrt( eff*(1.0-eff)/totalWeightSum ) : 0;
00320         gapFractionDP->addPoint(eff, effErr);
00321       }
00322     }
00323 
00324 
00325   private:
00326 
00327     // Struct containing the complete set of plots, times 3 for the different selections
00328     ATLAS_2011_S9126244_Plots _selectionPlots[3];
00329 
00330   };
00331 
00332 
00333   // The hook for the plugin system
00334   DECLARE_RIVET_PLUGIN(ATLAS_2011_S9126244);
00335 
00336 }