Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SEnergyCorrelator.ana.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SEnergyCorrelator.ana.h
1 // ----------------------------------------------------------------------------
2 // 'SEnergyCorrelator.ana.h'
3 // Derek Anderson
4 // 02.14.2023
5 //
6 // A module to implement Peter Komiske's EEC library
7 // in the sPHENIX software stack for the Cold QCD
8 // Energy-Energy Correlator analysis.
9 // ----------------------------------------------------------------------------
10 
11 #pragma once
12 
13 using namespace std;
14 using namespace fastjet;
15 
16 
17 
18 namespace SColdQcdCorrelatorAnalysis {
19 
20  // analysis methods ---------------------------------------------------------
21 
22  void SEnergyCorrelator::DoCorrelatorCalculation() {
23 
24  // print debug statement
25  if (m_inDebugMode) PrintDebug(31);
26 
27  // announce start of event loop
28  const uint64_t nEvts = m_inChain -> GetEntriesFast();
29  PrintMessage(7, nEvts);
30 
31  // event loop
32  uint64_t nBytes = 0;
33  for (uint64_t iEvt = 0; iEvt < nEvts; iEvt++) {
34 
35  const uint64_t entry = LoadTree(iEvt);
36  if (entry < 0) break;
37 
38  const uint64_t bytes = GetEntry(iEvt);
39  if (bytes < 0) {
40  break;
41  } else {
42  nBytes += bytes;
43  //PrintMessage(8, nEvts, iEvt);
44  }
45 
46  // jet loop
47  uint64_t nJets = (int) m_evtNumJets;
48  for (uint64_t iJet = 0; iJet < nJets; iJet++) {
49 
50  // clear vector for correlator
51  m_jetCstVector.clear();
52 
53  // get jet info
54  const uint64_t nCsts = m_jetNumCst -> at(iJet);
55  const double ptJet = m_jetPt -> at(iJet);
56  const double etaJet = m_jetEta -> at(iJet);
57 
58  // select jet pt bin & apply jet cuts
59  const uint32_t iPtJetBin = GetJetPtBin(ptJet);
60  const bool isGoodJet = ApplyJetCuts(ptJet, etaJet);
61  if (!isGoodJet) continue;
62 
63  // constituent loop
64  for (uint64_t iCst = 0; iCst < nCsts; iCst++) {
65 
66  // get cst info
67  const double drCst = (m_cstDr -> at(iJet)).at(iCst);
68  const double etaCst = (m_cstEta -> at(iJet)).at(iCst);
69  const double phiCst = (m_cstPhi -> at(iJet)).at(iCst);
70  const double ptCst = (m_cstPt -> at(iJet)).at(iCst);
71 
72  // for weird cst check
73  if (m_doSecondCstLoop) {
74  for (uint64_t jCst = 0; jCst < nCsts; jCst++) {
75 
76  // skip over the same cst
77  if (jCst == iCst) continue;
78 
79  // get cst info
80  const double etaCstB = (m_cstEta -> at(iJet)).at(jCst);
81  const double phiCstB = (m_cstPhi -> at(iJet)).at(jCst);
82  const double ptCstB = (m_cstPt -> at(iJet)).at(jCst);
83 
84  // calculate separation and pt-weight
85  const double dhCstAB = (etaCst - etaCstB);
86  const double dfCstAB = (phiCst - phiCstB);
87  const double drCstAB = sqrt((dhCstAB * dhCstAB) + (dfCstAB * dfCstAB));
88  const double ptFrac = ptCst / ptCstB;
89  const double ztJetA = ptCst / ptJet;
90  const double ztJetB = ptCstB / ptJet;
91  const double ptWeight = (ptCst * ptCstB) / (ptJet * ptJet);
92  hCstPtOneVsDr -> Fill(drCstAB, ptCst);
93  hCstPtTwoVsDr -> Fill(drCstAB, ptCstB);
94  hCstPtFracVsDr -> Fill(drCstAB, ptFrac);
95  hCstPhiOneVsDr -> Fill(drCstAB, phiCst);
96  hCstPhiTwoVsDr -> Fill(drCstAB, phiCstB);
97  hCstEtaOneVsDr -> Fill(drCstAB, etaCst);
98  hCstEtaTwoVsDr -> Fill(drCstAB, etaCstB);
99  hDeltaPhiOneVsDr -> Fill(drCstAB, dfCstAB);
100  hDeltaPhiTwoVsDr -> Fill(drCstAB, dfCstAB);
101  hDeltaEtaOneVsDr -> Fill(drCstAB, dhCstAB);
102  hDeltaEtaTwoVsDr -> Fill(drCstAB, dhCstAB);
103  hJetPtFracOneVsDr -> Fill(drCstAB, ztJetA);
104  hJetPtFracTwoVsDr -> Fill(drCstAB, ztJetB);
105  hCstPairWeightVsDr -> Fill(drCstAB, ptWeight);
106  } // end 2nd cst loop
107  }
108 
109  // create cst 4-vector
110  ROOT::Math::PtEtaPhiMVector rVecCst(ptCst, etaCst, phiCst, 0.140); // FIXME move pion mass to a constant in utilities namespace
111 
112  // if truth tree and needed, check embedding ID
113  if (m_isInputTreeTruth && m_selectSubEvts) {
114  const int embedCst = (m_cstEmbedID -> at(iJet)).at(iCst);
115  const bool isSubEvtGood = CheckIfSubEvtGood(embedCst);
116  if (!isSubEvtGood) continue;
117  }
118 
119  // if needed, apply constituent cuts
120  const bool isGoodCst = ApplyCstCuts(ptCst, drCst);
121  if (m_applyCstCuts && !isGoodCst) continue;
122 
123  // create pseudojet & add to list
124  PseudoJet constituent(rVecCst.Px(), rVecCst.Py(), rVecCst.Pz(), rVecCst.E());
125  constituent.set_user_index(iCst);
126  m_jetCstVector.push_back(constituent);
127  } // end cst loop
128 
129  // run eec computation
130  for (size_t iPtBin = 0; iPtBin < m_nBinsJetPt; iPtBin++) {
131  const bool isInPtBin = ((ptJet >= m_ptJetBins[iPtBin].first) && (ptJet < m_ptJetBins[iPtBin].second));
132  if (isInPtBin) {
133  if (m_jetCstVector.size() > 0) {
134  m_eecLongSide[iPtJetBin] -> compute(m_jetCstVector);
135  }
136  }
137  } // end pTjet bin loop
138  } // end jet loop
139  } // end event loop
140 
141  // announce end of event loop
142  PrintMessage(13);
143  return;
144 
145  } // end 'DoCorrelatorCalculation()'
146 
147 
148 
149  void SEnergyCorrelator::ExtractHistsFromCorr() {
150 
151  // print debug statement
152  if (m_inDebugMode) PrintDebug(25);
153 
154  vector<double> drBinEdges;
155  vector<double> lnDrBinEdges;
156  pair<vector<double>, vector<double>> histContentAndVariance;
157  pair<vector<double>, vector<double>> histContentAndError;
158  for (size_t iPtBin = 0; iPtBin < m_nBinsJetPt; iPtBin++) {
159 
160  // create names
161  TString sPtJetBin("_ptJet");
162  sPtJetBin += floor(m_ptJetBins[iPtBin].first);
163 
164  TString sVarDrAxisName("hCorrelatorVarianceDrAxis");
165  TString sErrDrAxisName("hCorrelatorErrorDrAxis");
166  TString sVarLnDrAxisName("hCorrelatorVarianceLnDrAxis");
167  TString sErrLnDrAxisName("hCorrelatorErrorLnDrAxis");
168  sVarDrAxisName.Append(sPtJetBin.Data());
169  sErrDrAxisName.Append(sPtJetBin.Data());
170  sVarLnDrAxisName.Append(sPtJetBin.Data());
171  sErrLnDrAxisName.Append(sPtJetBin.Data());
172 
173  // clear vectors
174  drBinEdges.clear();
175  lnDrBinEdges.clear();
176  histContentAndVariance.first.clear();
177  histContentAndVariance.second.clear();
178  histContentAndError.first.clear();
179  histContentAndError.second.clear();
180 
181  // grab bin edges, content, and error
182  drBinEdges = m_eecLongSide[iPtBin] -> bin_edges();
183  histContentAndVariance = m_eecLongSide[iPtBin] -> get_hist_vars();
184  histContentAndError = m_eecLongSide[iPtBin] -> get_hist_errs();
185 
186  // create ln(dr) bin edges and arrays
187  const size_t nDrBinEdges = drBinEdges.size();
188  for (size_t iDrEdge = 0; iDrEdge < nDrBinEdges; iDrEdge++) {
189  const double drEdge = drBinEdges.at(iDrEdge);
190  const double lnDrEdge = log(drEdge);
191  lnDrBinEdges.push_back(lnDrEdge);
192  }
193 
194  // bin edge arrays for histograms
195  double drBinEdgeArray[nDrBinEdges];
196  double lnDrBinEdgeArray[nDrBinEdges];
197  for (size_t iDrEdge = 0; iDrEdge < nDrBinEdges; iDrEdge++) {
198  drBinEdgeArray[iDrEdge] = drBinEdges.at(iDrEdge);
199  lnDrBinEdgeArray[iDrEdge] = lnDrBinEdges.at(iDrEdge);
200  }
201 
202  // make sure number of bin edges is reasonable
203  const bool isNumBinEdgesGood = ((nDrBinEdges - 1) == m_nBinsDr);
204  if (!isNumBinEdgesGood) {
205  PrintError(12, nDrBinEdges);
206  assert(isNumBinEdgesGood);
207  }
208 
209  // create output histograms
210  m_outHistVarDrAxis[iPtBin] = new TH1D(sVarDrAxisName.Data(), "", m_nBinsDr, drBinEdgeArray);
211  m_outHistErrDrAxis[iPtBin] = new TH1D(sErrDrAxisName.Data(), "", m_nBinsDr, drBinEdgeArray);
212  m_outHistVarLnDrAxis[iPtBin] = new TH1D(sVarLnDrAxisName.Data(), "", m_nBinsDr, lnDrBinEdgeArray);
213  m_outHistErrLnDrAxis[iPtBin] = new TH1D(sErrLnDrAxisName.Data(), "", m_nBinsDr, lnDrBinEdgeArray);
214  m_outHistVarDrAxis[iPtBin] -> Sumw2();
215  m_outHistErrDrAxis[iPtBin] -> Sumw2();
216  m_outHistVarLnDrAxis[iPtBin] -> Sumw2();
217  m_outHistErrLnDrAxis[iPtBin] -> Sumw2();
218 
219  // set bin content
220  for (size_t iDrEdge = 0; iDrEdge < m_nBinsDr; iDrEdge++) {
221  const size_t iDrBin = iDrEdge + 1;
222  const double binVarContent = histContentAndVariance.first.at(iDrEdge);
223  const double binVarError = histContentAndVariance.second.at(iDrEdge);
224  const double binErrContent = histContentAndError.first.at(iDrEdge);
225  const double binErrError = histContentAndError.second.at(iDrEdge);
226 
227  // check if bin with variances is good & set content/error
228  const bool areVarBinValuesNans = (isnan(binVarContent) || isnan(binVarError));
229  if (areVarBinValuesNans) {
230  PrintError(13, 0, iDrBin);
231  } else {
232  m_outHistVarDrAxis[iPtBin] -> SetBinContent(iDrBin, binVarContent);
233  m_outHistVarLnDrAxis[iPtBin] -> SetBinContent(iDrBin, binVarContent);
234  m_outHistVarDrAxis[iPtBin] -> SetBinError(iDrBin, binVarError);
235  m_outHistVarLnDrAxis[iPtBin] -> SetBinError(iDrBin, binVarError);
236  }
237 
238  // check if bin with errors is good & set content/error
239  const bool areErrBinValuesNans = (isnan(binErrContent) || isnan(binErrError));
240  if (areErrBinValuesNans) {
241  PrintError(14, 0, iDrBin);
242  } else {
243  m_outHistErrDrAxis[iPtBin] -> SetBinContent(iDrBin, binErrContent);
244  m_outHistErrLnDrAxis[iPtBin] -> SetBinContent(iDrBin, binErrContent);
245  m_outHistErrDrAxis[iPtBin] -> SetBinError(iDrBin, binErrError);
246  m_outHistErrLnDrAxis[iPtBin] -> SetBinError(iDrBin, binErrError);
247  }
248  } // end dr bin edge loop
249  } // end jet pt bin loop
250 
251  if (m_inStandaloneMode) PrintMessage(14);
252  return;
253 
254  } // end 'ExtractHistsFromCorr()'
255 
256 
257 
258  bool SEnergyCorrelator::ApplyJetCuts(const double ptJet, const double etaJet) {
259 
260  // print debug statement
261  if (m_inDebugMode && (m_verbosity > 7)) PrintDebug(26);
262 
263  const bool isInPtRange = ((ptJet >= m_ptJetRange.first) && (ptJet < m_ptJetRange.second));
264  const bool isInEtaRange = ((etaJet > m_etaJetRange.first) && (etaJet < m_etaJetRange.second));
265  const bool isGoodJet = (isInPtRange && isInEtaRange);
266  return isGoodJet;
267 
268  } // end 'ApplyJetCuts(double, double)'
269 
270 
271 
272  bool SEnergyCorrelator::ApplyCstCuts(const double momCst, const double drCst) {
273 
274  // print debug statement
275  if (m_inDebugMode && (m_verbosity > 7)) PrintDebug(27);
276 
277  const bool isInMomRange = ((momCst >= m_momCstRange.first) && (momCst < m_momCstRange.second));
278  const bool isInDrRange = ((drCst >= m_drCstRange.first) && (drCst < m_drCstRange.second));
279  const bool isGoodCst = (isInMomRange && isInDrRange);
280  return isGoodCst;
281 
282  } // end 'ApplyCstCuts(double, double)'
283 
284 
285 
286  bool SEnergyCorrelator::CheckIfSubEvtGood(const int embedID) {
287 
288  // print debug statement
289  if (m_inDebugMode && (m_verbosity > 7)) PrintDebug(33);
290 
291  // set ID of signal and background events
292  int signalID = 1;
293  if (m_isInputTreeEmbed) {
294  signalID = 2;
295  }
296  const int bkgdID = 0;
297 
298  bool isSubEvtGood = true;
299  switch (m_subEvtOpt) {
300 
301  // only consider signal event
302  case 1:
303  isSubEvtGood = (embedID == signalID);
304  break;
305 
306  // only consider background events
307  case 2:
308  isSubEvtGood = (embedID <= bkgdID);
309  break;
310 
311  // only consider primary background event
312  case 3:
313  isSubEvtGood = (embedID == bkgdID);
314  break;
315 
316  // only consider pileup events
317  case 4:
318  isSubEvtGood = (embedID < bkgdID);
319  break;
320 
321  // consider only specific events
322  case 5:
323  isSubEvtGood = false;
324  for (const int evtToUse : m_subEvtsToUse) {
325  if (embedID == evtToUse) {
326  isSubEvtGood = true;
327  break;
328  }
329  }
330  break;
331 
332  // by default do nothing
333  default:
334  isSubEvtGood = true;
335  break;
336  }
337  return isSubEvtGood;
338 
339  } // end 'CheckIfSubEvtGood(int)'
340 
341 
342 
343  uint32_t SEnergyCorrelator::GetJetPtBin(const double ptJet) {
344 
345  // print debug statement
346  if (m_inDebugMode && (m_verbosity > 7)) PrintDebug(28);
347 
348  bool isInPtBin(false);
349  uint32_t iJetPtBin(0);
350  for (size_t iPtBin = 0; iPtBin < m_nBinsJetPt; iPtBin++) {
351  isInPtBin = ((ptJet >= m_ptJetBins[iPtBin].first) && (ptJet < m_ptJetBins[iPtBin].second));
352  if (isInPtBin) {
353  iJetPtBin = iPtBin;
354  break;
355  }
356  }
357  return iJetPtBin;
358 
359  } // end 'GetJetPtBin(double)'
360 
361 } // end SColdQcdCorrelatorAnalysis namespace
362 
363 // end ------------------------------------------------------------------------