rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

CDF_2004_I647490

Transverse cone and `Swiss cheese' underlying event studies
Experiment: CDF (Tevatron Run 1)
Inspire ID: 647490
Status: VALIDATED
Authors:
  • Andy Buckley
References: Beams: p- p+
Beam energies: (315.0, 315.0); (900.0, 900.0) GeV
Run details:
  • QCD events at $\sqrt{s} = 630$ \& 1800 GeV. Several $p_\perp^\text{min}$ cutoffs are probably required to fill the profile histograms, e.g. 0 (min bias), 30, 90, 150 GeV at 1800 GeV, and 0 (min bias), 20, 90, 150 GeV at 630 GeV. Beam energy must be specified as analysis option "ENERGY" when rivet-merge'ing samples.

This analysis studies the underlying event via transverse cones of $R = 0.7$ at 90 degrees in \phi relative to the leading (highest E) jet, at $\sqrt{s} = 630$ and 1800 GeV. This is similar to the 2001 CDF UE analysis, except that cones, rather than the whole central \eta range are used. The transverse cones are categorised as `TransMIN' and `TransMAX' on an event-by-event basis, to give greater sensitivity to the UE component. `Swiss Cheese' distributions, where cones around the leading $n$ jets are excluded from the distributions, are also included for $n = 2, 3$. This analysis is useful for constraining the energy evolution of the underlying event, since it performs the same analyses at two distinct CoM energies. WARNING! The pT plots are normalised to raw number of events. The min bias data have not been reproduced by MC, and are not recommended for tuning. Beam energy must be specified (in GeV) as analysis option "ENERGY" when rivet-merging samples.

Source code: CDF_2004_I647490.cc
  1// -*- C++ -*-
  2// "Acosta" underlying event analysis at CDF, inc. "Swiss Cheese"
  3
  4#include "Rivet/Analysis.hh"
  5#include "Rivet/Jet.hh"
  6#include "Rivet/Projections/ChargedFinalState.hh"
  7#include "Rivet/Projections/FastJets.hh"
  8#include "Rivet/Projections/TriggerCDFRun0Run1.hh"
  9
 10namespace Rivet {
 11
 12
 13  /// @brief CDF calo jet underlying event analysis at 630 and 1800 GeV
 14  ///
 15  /// CDF measurement of underlying event using calorimeter jet scales and
 16  /// alignment, particle flow activity in transverse cones, and the Swiss
 17  /// Cheese analysis method, where cones are excluded around the 2 and 3
 18  /// hardest jets.
 19  ///
 20  /// @author Andy Buckley
 21  class CDF_2004_I647490 : public Analysis {
 22  public:
 23
 24    RIVET_DEFAULT_ANALYSIS_CTOR(CDF_2004_I647490);
 25
 26
 27    /// @name Analysis methods
 28    /// @{
 29
 30    void init() {
 31      // Set up projections
 32      declare(TriggerCDFRun0Run1(), "Trigger");
 33      const FinalState calofs(Cuts::abseta < 1.2);
 34      declare(calofs, "CaloFS");
 35      declare(FastJets(calofs, JetAlg::CDFJETCLU, 0.7), "Jets");
 36      const ChargedFinalState trackfs(Cuts::abseta < 1.2 && Cuts::pT >= 0.4*GeV);
 37      declare(trackfs, "TrackFS");
 38      // Restrict tracks to |eta| < 0.7 for the min bias part.
 39      const ChargedFinalState mbfs(Cuts::abseta < 0.7 && Cuts::pT >= 0.4*GeV);
 40      declare(mbfs, "MBFS");
 41      // Restrict tracks to |eta| < 1 for the Swiss-Cheese part.
 42      const ChargedFinalState cheesefs(Cuts::abseta < 1.0 && Cuts::pT >= 0.4*GeV);
 43      declare(cheesefs, "CheeseFS");
 44      declare(FastJets(cheesefs, JetAlg::CDFJETCLU, 0.7), "CheeseJets");
 45
 46      // Book histograms
 47      if (isCompatibleWithSqrtS(1800*GeV)) {
 48        book(_pt90MaxAvg1800 ,1, 1, 1);
 49        book(_pt90MinAvg1800 ,1, 1, 2);
 50        book(_pt90Max1800 ,2, 1, 1);
 51        book(_pt90Min1800 ,2, 1, 2);
 52        book(_pt90Diff1800 ,2, 1, 3);
 53        book(_num90Max1800 ,4, 1, 1);
 54        book(_num90Min1800 ,4, 1, 2);
 55        book(_pTSum1800_2Jet ,7, 1, 1);
 56        book(_pTSum1800_3Jet ,7, 1, 2);
 57
 58        book(_pt90Dbn1800Et40 ,3, 1, 1);
 59        book(_pt90Dbn1800Et80 ,3, 1, 2);
 60        book(_pt90Dbn1800Et120 ,3, 1, 3);
 61        book(_pt90Dbn1800Et160 ,3, 1, 4);
 62        book(_pt90Dbn1800Et200 ,3, 1, 5);
 63        book(_numTracksDbn1800MB ,5, 1, 1);
 64        book(_ptDbn1800MB ,6, 1, 1);
 65      } else if (isCompatibleWithSqrtS(630*GeV)) {
 66        book(_pt90Max630 ,8, 1, 1);
 67        book(_pt90Min630 ,8, 1, 2);
 68        book(_pt90Diff630 ,8, 1, 3);
 69        book(_pTSum630_2Jet ,9, 1, 1);
 70        book(_pTSum630_3Jet ,9, 1, 2);
 71
 72        book(_numTracksDbn630MB ,10, 1, 1);
 73        book(_ptDbn630MB ,11, 1, 1);
 74      }
 75    }
 76
 77
 78    /// Do the analysis
 79    void analyze(const Event& event) {
 80      // Trigger
 81      const bool trigger = apply<TriggerCDFRun0Run1>(event, "Trigger").minBiasDecision();
 82      if (!trigger) vetoEvent;
 83
 84      {
 85        MSG_DEBUG("Running max/min analysis");
 86        Jets jets = apply<JetFinder>(event, "Jets").jets(cmpMomByE);
 87        if (!jets.empty()) {
 88          // Leading jet must be in central |eta| < 0.5 region
 89          const Jet leadingjet = jets.front();
 90          const double etaLead = leadingjet.eta();
 91          // Get Et of the leading jet: used to bin histograms
 92          const double ETlead = leadingjet.Et();
 93          MSG_DEBUG("Leading Et = " << ETlead/GeV << " GeV");
 94          if (fabs(etaLead) > 0.5 && ETlead < 15*GeV) {
 95            MSG_DEBUG("Leading jet eta = " << etaLead
 96                     << " not in |eta| < 0.5 & pT > 15 GeV");
 97          } else {
 98            // Multiplicity & pT distributions for sqrt(s) = 630 GeV, 1800 GeV
 99            const Particles tracks = apply<FinalState>(event, "TrackFS").particles();
100            const ConesInfo cones = _calcTransCones(leadingjet.momentum(), tracks);
101            if (isCompatibleWithSqrtS(630*GeV)) {
102              _pt90Max630->fill(ETlead/GeV, cones.ptMax/GeV);
103              _pt90Min630->fill(ETlead/GeV, cones.ptMin/GeV);
104              _pt90Diff630->fill(ETlead/GeV, cones.ptDiff/GeV);
105            } else if (isCompatibleWithSqrtS(1800*GeV)) {
106              _num90Max1800->fill(ETlead/GeV, cones.numMax);
107              _num90Min1800->fill(ETlead/GeV, cones.numMin);
108              _pt90Max1800->fill(ETlead/GeV, cones.ptMax/GeV);
109              _pt90Min1800->fill(ETlead/GeV, cones.ptMin/GeV);
110              _pt90Diff1800->fill(ETlead/GeV, cones.ptDiff/GeV);
111              _pt90MaxAvg1800->fill(ETlead/GeV, cones.ptMax/GeV); // /numMax
112              _pt90MinAvg1800->fill(ETlead/GeV, cones.ptMin/GeV); // /numMin
113              //
114              const double ptTransTotal = cones.ptMax + cones.ptMin;
115              if (inRange(ETlead/GeV, 40., 80.)) {
116                _pt90Dbn1800Et40->fill(ptTransTotal/GeV);
117              } else if (inRange(ETlead/GeV, 80., 120.)) {
118                _pt90Dbn1800Et80->fill(ptTransTotal/GeV);
119              } else if (inRange(ETlead/GeV, 120., 160.)) {
120                _pt90Dbn1800Et120->fill(ptTransTotal/GeV);
121              } else if (inRange(ETlead/GeV, 160., 200.)) {
122                _pt90Dbn1800Et160->fill(ptTransTotal/GeV);
123              } else if (inRange(ETlead/GeV, 200., 270.)) {
124                _pt90Dbn1800Et200->fill(ptTransTotal/GeV);
125              }
126            }
127
128          }
129        }
130      }
131
132
133      // Fill min bias total track multiplicity histos
134      {
135        MSG_DEBUG("Running min bias multiplicity analysis");
136        const Particles mbtracks = apply<FinalState>(event, "MBFS").particles();
137        if (isCompatibleWithSqrtS(1800*GeV)) {
138          _numTracksDbn1800MB->fill(mbtracks.size());
139        } else if (isCompatibleWithSqrtS(630*GeV)) {
140          _numTracksDbn630MB->fill(mbtracks.size());
141        }
142        // Run over all charged tracks
143        for (const Particle& t : mbtracks) {
144          FourMomentum trackMom = t.momentum();
145          const double pt = trackMom.pT();
146          // Plot total pT distribution for min bias
147          if (isCompatibleWithSqrtS(1800*GeV)) {
148            _ptDbn1800MB->fill(pt/GeV);
149          } else if (isCompatibleWithSqrtS(630*GeV)) {
150            _ptDbn630MB->fill(pt/GeV);
151          }
152        }
153      }
154
155
156
157      // Construct "Swiss Cheese" pT distributions, with pT contributions from
158      // tracks within R = 0.7 of the 1st, 2nd (and 3rd) jets being ignored. A
159      // different set of charged tracks, with |eta| < 1.0, is used here, and all
160      // the removed jets must have Et > 5 GeV.
161      {
162        MSG_DEBUG("Running Swiss Cheese analysis");
163        const Particles cheesetracks = apply<FinalState>(event, "CheeseFS").particles();
164        Jets cheesejets = apply<JetFinder>(event, "Jets").jets(cmpMomByE);
165        if (cheesejets.empty()) {
166          MSG_DEBUG("No 'cheese' jets found in event");
167          return;
168        }
169        if (cheesejets.size() > 1 &&
170            fabs(cheesejets[0].eta()) <= 0.5 &&
171            cheesejets[0].Et()/GeV > 5.0 &&
172            cheesejets[1].Et()/GeV > 5.0) {
173
174          const double cheeseETlead = cheesejets[0].Et();
175
176          const double eta1 = cheesejets[0].eta();
177          const double phi1 = cheesejets[0].phi();
178          const double eta2 = cheesejets[1].eta();
179          const double phi2 = cheesejets[1].phi();
180
181          double ptSumSub2(0), ptSumSub3(0);
182          for (const Particle& t : cheesetracks) {
183            FourMomentum trackMom = t.momentum();
184            const double pt = trackMom.pT();
185
186            // Subtracting 2 leading jets
187            const double deltaR1 = deltaR(trackMom, eta1, phi1);
188            const double deltaR2 = deltaR(trackMom, eta2, phi2);
189            MSG_TRACE("Track vs jet(1): "
190                     << "|(" << trackMom.eta() << ", " << trackMom.phi() << ") - "
191                     << "|(" << eta1 << ", " << phi1 << ")| = " << deltaR1);
192            MSG_TRACE("Track vs jet(2): "
193                     << "|(" << trackMom.eta() << ", " << trackMom.phi() << ") - "
194                     << "|(" << eta2 << ", " << phi2 << ")| = " << deltaR2);
195            if (deltaR1 > 0.7 && deltaR2 > 0.7) {
196              ptSumSub2 += pt;
197
198              // Subtracting 3rd leading jet
199              if (cheesejets.size() > 2 &&
200                  cheesejets[2].Et()/GeV > 5.0) {
201                const double eta3 = cheesejets[2].eta();
202                const double phi3 = cheesejets[2].phi();
203                const double deltaR3 = deltaR(trackMom, eta3, phi3);
204                MSG_TRACE("Track vs jet(3): "
205                         << "|(" << trackMom.eta() << ", " << trackMom.phi() << ") - "
206                         << "|(" << eta3 << ", " << phi3 << ")| = " << deltaR3);
207                if (deltaR3 > 0.7) {
208                  ptSumSub3 += pt;
209                }
210              }
211            }
212          }
213
214          // Swiss Cheese sub 2,3 jets distributions for sqrt(s) = 630 GeV, 1800 GeV
215          if (isCompatibleWithSqrtS(630*GeV)) {
216            if (!isZero(ptSumSub2)) _pTSum630_2Jet->fill(cheeseETlead/GeV, ptSumSub2/GeV);
217            if (!isZero(ptSumSub3))_pTSum630_3Jet->fill(cheeseETlead/GeV, ptSumSub3/GeV);
218          } else if (isCompatibleWithSqrtS(1800*GeV)) {
219            if (!isZero(ptSumSub2))_pTSum1800_2Jet->fill(cheeseETlead/GeV, ptSumSub2/GeV);
220            if (!isZero(ptSumSub3))_pTSum1800_3Jet->fill(cheeseETlead/GeV, ptSumSub3/GeV);
221          }
222
223        }
224      }
225
226    }
227
228
229    void finalize() {
230      /// @todo Take these normalisations from the data histo (it can't come from just the MC)
231
232      if (isCompatibleWithSqrtS(1800*GeV)) {
233        // Normalize to actual number of entries in pT dbn histos...
234        normalize(_pt90Dbn1800Et40,  1656.75); // norm OK
235        normalize(_pt90Dbn1800Et80,  4657.5); // norm OK
236        normalize(_pt90Dbn1800Et120, 5395.5); // norm OK
237        normalize(_pt90Dbn1800Et160, 7248.75); // norm OK
238        normalize(_pt90Dbn1800Et200, 2442.0); // norm OK
239      }
240
241      // ...and for min bias distributions:
242      if (isCompatibleWithSqrtS(1800*GeV)) {
243        normalize(_numTracksDbn1800MB, 309718.25); // norm OK
244        normalize(_ptDbn1800MB, 33600.0); // norm OK
245      } else if (isCompatibleWithSqrtS(630*GeV)) {
246        normalize(_numTracksDbn630MB, 1101024.0); // norm OK
247        normalize(_ptDbn630MB, 105088.0); // norm OK
248      }
249    }
250
251    /// @}
252
253
254  private:
255
256
257    /// @name Cone machinery
258    /// @{
259
260    /// @cond CONEUE_DETAIL
261
262    struct ConesInfo {
263      ConesInfo() : numMax(0), numMin(0), ptMax(0), ptMin(0), ptDiff(0) {}
264      unsigned int numMax, numMin;
265      double ptMax, ptMin, ptDiff;
266    };
267
268    /// @endcond
269
270
271    ConesInfo _calcTransCones(const double etaLead, const double phiLead,
272                              const Particles& tracks) {
273      const double phiTransPlus = mapAngle0To2Pi(phiLead + PI/2.0);
274      const double phiTransMinus = mapAngle0To2Pi(phiLead - PI/2.0);
275      MSG_DEBUG("phi_lead = " << phiLead
276               << " -> trans = (" << phiTransPlus
277               << ", " << phiTransMinus << ")");
278
279      unsigned int numPlus(0), numMinus(0);
280      double ptPlus(0), ptMinus(0);
281      // Run over all charged tracks
282      for (const Particle& t : tracks) {
283        FourMomentum trackMom = t.momentum();
284        const double pt = trackMom.pT();
285
286        // Find if track mom is in either transverse cone
287        if (deltaR(trackMom, etaLead, phiTransPlus) < 0.7) {
288          ptPlus += pt;
289          numPlus += 1;
290        } else if (deltaR(trackMom, etaLead, phiTransMinus) < 0.7) {
291          ptMinus += pt;
292          numMinus += 1;
293        }
294      }
295
296      ConesInfo rtn;
297      // Assign N_{min,max} from N_{plus,minus}
298      rtn.numMax = (ptPlus >= ptMinus) ? numPlus : numMinus;
299      rtn.numMin = (ptPlus >= ptMinus) ? numMinus : numPlus;
300      // Assign pT_{min,max} from pT_{plus,minus}
301      rtn.ptMax = (ptPlus >= ptMinus) ? ptPlus : ptMinus;
302      rtn.ptMin = (ptPlus >= ptMinus) ? ptMinus : ptPlus;
303      rtn.ptDiff = fabs(rtn.ptMax - rtn.ptMin);
304
305      MSG_DEBUG("Min cone has " << rtn.numMin << " tracks -> "
306               << "pT_min = " << rtn.ptMin/GeV << " GeV");
307      MSG_DEBUG("Max cone has " << rtn.numMax << " tracks -> "
308               << "pT_max = " << rtn.ptMax/GeV << " GeV");
309
310      return rtn;
311    }
312
313
314    ConesInfo _calcTransCones(const FourMomentum& leadvec,
315                              const Particles& tracks) {
316      const double etaLead = leadvec.eta();
317      const double phiLead = leadvec.phi();
318      return _calcTransCones(etaLead, phiLead, tracks);
319    }
320
321    /// @}
322
323
324    /// @name Histogram collections
325    /// @{
326
327    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
328    /// the average \f$ p_T \f$ in the toward, transverse and away regions at
329    /// \f$ \sqrt{s} = 1800 \text{GeV} \f$.
330    /// Corresponds to Table 1, and HepData table 1.
331    Profile1DPtr _pt90MaxAvg1800, _pt90MinAvg1800;
332
333    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
334    /// the \f$ p_T \f$ sum in the toward, transverse and away regions at
335    /// \f$ \sqrt{s} = 1800 \text{GeV} \f$.
336    /// Corresponds to figure 2/3, and HepData table 2.
337    Profile1DPtr _pt90Max1800, _pt90Min1800, _pt90Diff1800;
338
339    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
340    /// the \f$ p_T \f$ sum in the toward, transverse and away regions at
341    /// at \f$ \sqrt{s} = 630 \text{GeV} \f$.
342    /// Corresponds to figure 8, and HepData table 8.
343    Profile1DPtr _pt90Max630, _pt90Min630, _pt90Diff630;
344
345    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
346    /// the cone track multiplicity at \f$ \sqrt{s} = 1800 \text{GeV} \f$.
347    /// Corresponds to figure 5, and HepData table 4.
348    Profile1DPtr _num90Max1800, _num90Min1800;
349
350    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
351    /// the \f$ p_T \f$ sum at \f$ \sqrt{s} = 1800 \text{GeV} \f$.
352    /// Corresponds to figure 7, and HepData table 7.
353    Profile1DPtr _pTSum1800_2Jet, _pTSum1800_3Jet;
354
355    /// Profile histograms, binned in the \f$ E_T \f$ of the leading jet, for
356    /// the \f$ p_T \f$ sum at \f$ \sqrt{s} = 630 \text{GeV} \f$.
357    /// Corresponds to figure 9, and HepData table 9.
358    Profile1DPtr _pTSum630_2Jet, _pTSum630_3Jet;
359
360    /// Histogram of \f$ p_{T\text{sum}} \f$ distribution for 5 different
361    /// \f$ E_{T1} \f$ bins.
362    /// Corresponds to figure 4, and HepData table 3.
363    Histo1DPtr _pt90Dbn1800Et40, _pt90Dbn1800Et80, _pt90Dbn1800Et120,
364      _pt90Dbn1800Et160, _pt90Dbn1800Et200;
365
366    /// Histograms of track multiplicity and \f$ p_T \f$ distributions for
367    /// minimum bias events.
368    /// Figure 6, and HepData tables 5 & 6.
369    /// Figure 10, and HepData tables 10 & 11.
370    Histo1DPtr _numTracksDbn1800MB, _ptDbn1800MB;
371    Histo1DPtr _numTracksDbn630MB, _ptDbn630MB;
372
373    /// @}
374
375  };
376
377
378
379  RIVET_DECLARE_ALIASED_PLUGIN(CDF_2004_I647490, CDF_2004_S5839831);
380
381}