Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SCheckTrackPairs.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SCheckTrackPairs.h
1 // ----------------------------------------------------------------------------
2 // 'SCheckTrackPairs.h'
3 // Derek Anderson
4 // 11.14.2023
5 //
6 // SCorrelatorQAMaker plugin to iterate through
7 // all pairs of tracks in an event and fill
8 // tuples/histograms comparing them.
9 // ----------------------------------------------------------------------------
10 
11 #ifndef SCHECKTRACKPAIRS_H
12 #define SCHECKTRACKPAIRS_H
13 
14 // c++ utilities
15 #include <string>
16 #include <vector>
17 // root utilities
18 #include <TF1.h>
19 #include <TNtuple.h>
20 #include <Math/Vector3D.h>
21 // f4a libraries
22 #include <fun4all/SubsysReco.h>
25 // phool libraries
26 #include <phool/phool.h>
27 #include <phool/getClass.h>
28 #include <phool/PHIODataNode.h>
29 #include <phool/PHNodeIterator.h>
30 #include <phool/PHCompositeNode.h>
31 // tracking libraries
35 // analysis utilities
36 #include "SBaseQAPlugin.h"
37 #include "/sphenix/user/danderson/eec/SCorrelatorUtilities/TrkTools.h"
38 #include "/sphenix/user/danderson/eec/SCorrelatorUtilities/Constants.h"
39 #include "/sphenix/user/danderson/eec/SCorrelatorUtilities/Interfaces.h"
40 
41 // make common namespaces implicit
42 using namespace std;
43 using namespace findNode;
44 using namespace SColdQcdCorrelatorAnalysis::SCorrelatorUtilities;
45 
46 
47 
48 namespace SColdQcdCorrelatorAnalysis {
49 
50  // SCheckTrackPairsConfig definition ----------------------------------------
51 
53 
59 
60  // for pt-dependent sigma cut
61  pair<float, float> nSigCut;
62  pair<float, float> ptFitMax;
63  pair<TF1*, TF1*> fSigDca;
64 
65  }; // end SCheckTrackPairsConfig
66 
67 
68 
69  // SCheckTrackPairs definition ----------------------------------------------
70 
71  class SCheckTrackPairs : public SubsysReco, public SBaseQAPlugin<SCheckTrackPairsConfig> {
72 
73  public:
74 
75  // ctor/dtor
76  SCheckTrackPairs(const string& name = "CheckTrackPairs") : SubsysReco(name) {};
78 
79  // F4A methods
80  int Init(PHCompositeNode*) override;
81  int process_event(PHCompositeNode*) override;
82  int End(PHCompositeNode*) override;
83 
84  private:
85 
86  // internal methods
87  void InitTuples();
88  void SaveOutput();
89  void ResetVectors();
90  void DoDoubleTrackLoop(PHCompositeNode* topNode);
91  bool IsGoodTrack(SvtxTrack* track, PHCompositeNode* topNode);
92 
93  // vector members
94  vector<float> m_vecTrackPairLeaves;
95  vector<TrkrDefs::cluskey> m_vecClustKeysA;
96  vector<TrkrDefs::cluskey> m_vecClustKeysB;
97 
98  // root members
99  TNtuple* m_ntTrackPairs;
100 
101  }; // end SCheckTrackPairs
102 
103 
104 
105  // SCheckTrackPairs public methods ------------------------------------------
106 
108 
109  InitOutput();
110  InitTuples();
112 
113  } // end 'Init(PHCompositeNode*)'
114 
115 
116 
118 
119  ResetVectors();
120  DoDoubleTrackLoop(topNode);
122 
123  } // end 'process_event(PHCompositeNode* topNode)'
124 
125 
126 
127  int SCheckTrackPairs::End(PHCompositeNode* topNode) {
128 
129  SaveOutput();
130  CloseOutput();
132 
133  } // end 'End(PHCompositeNode*)'
134 
135 
136 
137  // SCheckTrackPairs internal methods ----------------------------------------
138 
139  void SCheckTrackPairs::InitTuples() {
140 
141  if (m_isDebugOn && (m_verbosity > 2)) {
142  cout << "SColdQcdCorrelatorAnalysis::SCheckTrackPairs::InitTuples(): initializing output tuple." << endl;
143  }
144 
145  // create leaf list and add leaves for 1st track in pair
146  vector<string> vecTrkPairLeaves = MakeLeafVector<TrkInfo>("_a");
147  vecTrkPairLeaves.push_back("nClustKey_a");
148 
149  // add leaves for 2nd track in pair
150  AddLeavesToVector<TrkInfo>(vecTrkPairLeaves, "_b");
151  vecTrkPairLeaves.push_back("nClustKey_b");
152 
153  // add leaves for no. of same cluster keys b/n pair and
154  // distance between pair
155  vecTrkPairLeaves.push_back("nSameClustKey");
156  vecTrkPairLeaves.push_back("trackDeltaR");
157 
158  // compress leaves into a colon-separated list
159  string argTrkPairLeaves = FlattenLeafList(vecTrkPairLeaves);
160 
161  // create tuple and return
162  m_ntTrackPairs = new TNtuple("ntTrackPairs", "Pairs of tracks", argTrkPairLeaves.data());
163  m_vecTrackPairLeaves.reserve(vecTrkPairLeaves.size());
164  return;
165 
166  } // end 'InitTuples()'
167 
168 
169 
170  void SCheckTrackPairs::SaveOutput() {
171 
172  if (m_isDebugOn && (m_verbosity > 2)) {
173  cout << "SColdQcdCorrelatorAnalysis::SCheckTrackPairs::SaveOutput(): saving output." << endl;
174  }
175 
176  m_outDir -> cd();
177  m_ntTrackPairs -> Write();
178  return;
179 
180  } // end 'SaveOutput()'
181 
182 
183 
184  void SCheckTrackPairs::ResetVectors() {
185 
186  if (m_isDebugOn && (m_verbosity > 4)) {
187  cout << "SColdQcdCorrelatorAnalysis::SCheckTrackPairs::ResetVectors(): resetting vectors." << endl;
188  }
189 
190  // set leaf values to a default
191  const size_t nLeaves = m_vecTrackPairLeaves.size();
192  for (size_t iLeaf = 0; iLeaf < nLeaves; iLeaf++) {
193  m_vecTrackPairLeaves[iLeaf] = -999.;
194  }
195 
196  // clear cluster keys
197  m_vecClustKeysA.clear();
198  m_vecClustKeysB.clear();
199  return;
200 
201  } // end 'ResetVectors()'
202 
203 
204 
205  void SCheckTrackPairs::DoDoubleTrackLoop(PHCompositeNode* topNode) {
206 
207  if (m_isDebugOn && (m_verbosity > 2)) {
208  cout << "SColdQcdCorrelatorAnalysis::SCheckTrackPairs::DoDoubleTrackLoop(): looping over all pairs of tracks." << endl;
209  }
210 
211  // loop over tracks
212  SvtxTrack* trackA = NULL;
213  SvtxTrack* trackB = NULL;
214  SvtxTrackMap* mapTrks = GetTrackMap(topNode);
215  for (SvtxTrackMap::Iter itTrkA = mapTrks -> begin(); itTrkA != mapTrks -> end(); ++itTrkA) {
216 
217  // grab track A and skip if bad
218  trackA = itTrkA -> second;
219  if (!trackA) continue;
220 
221  const bool isGoodTrackA = IsGoodTrack(trackA, topNode);
222  if (!isGoodTrackA) continue;
223 
224  // grab track info
225  TrkInfo trkInfoA(trackA, topNode);
226 
227  // loop over tracks again
228  for (SvtxTrackMap::Iter itTrkB = mapTrks -> begin(); itTrkB != mapTrks -> end(); ++itTrkB) {
229 
230  // grab track B and skip if bad
231  trackB = itTrkB -> second;
232  if (!trackB) continue;
233 
234  const bool isGoodTrackB = IsGoodTrack(trackB, topNode);
235  if (!isGoodTrackB) continue;
236 
237  // skip if same as track A
238  if ((trackA -> get_id()) == (trackB -> get_id())) continue;
239 
240  // grab track info
241  TrkInfo trkInfoB(trackB, topNode);
242 
243  // calculate delta-R
244  const double dfTrkAB = trkInfoA.phi - trkInfoB.phi;
245  const double dhTrkAB = trkInfoA.eta - trkInfoB.eta;
246  const double drTrkAB = sqrt((dfTrkAB * dfTrkAB) + (dhTrkAB * dhTrkAB));
247 
248  // clear vectors for checking cluster keys
249  m_vecClustKeysA.clear();
250  m_vecClustKeysB.clear();
251 
252  // loop over clusters from track A
253  auto seedTpcA = trackA -> get_tpc_seed();
254  if (seedTpcA) {
255  for (auto local_iterA = seedTpcA -> begin_cluster_keys(); local_iterA != seedTpcA -> end_cluster_keys(); ++local_iterA) {
256  TrkrDefs::cluskey cluster_keyA = *local_iterA;
257  m_vecClustKeysA.push_back(cluster_keyA);
258  }
259  }
260 
261  // loop over clusters from track B
262  auto seedTpcB = trackB -> get_tpc_seed();
263  if (seedTpcB) {
264  for (auto local_iterB = seedTpcB -> begin_cluster_keys(); local_iterB != seedTpcB -> end_cluster_keys(); ++local_iterB) {
265  TrkrDefs::cluskey cluster_keyB = *local_iterB;
266  m_vecClustKeysB.push_back(cluster_keyB);
267  }
268  }
269 
270  // calculate no. of same cluster keys
271  uint64_t nSameKey = 0;
272  for (auto keyA : m_vecClustKeysA) {
273  for (auto keyB : m_vecClustKeysB) {
274  if (keyA == keyB) {
275  ++nSameKey;
276  break;
277  }
278  } // end cluster key B loop
279  } // end cluster key A loop
280 
281  // set tuple leaves
282  m_vecTrackPairLeaves[0] = (float) trkInfoA.id;
283  m_vecTrackPairLeaves[1] = (float) trkInfoA.nMvtxLayer;
284  m_vecTrackPairLeaves[2] = (float) trkInfoA.nInttLayer;
285  m_vecTrackPairLeaves[3] = (float) trkInfoA.nTpcLayer;
286  m_vecTrackPairLeaves[4] = (float) trkInfoA.nMvtxClust;
287  m_vecTrackPairLeaves[5] = (float) trkInfoA.nInttClust;
288  m_vecTrackPairLeaves[6] = (float) trkInfoA.nTpcClust;
289  m_vecTrackPairLeaves[7] = (float) trkInfoA.eta;
290  m_vecTrackPairLeaves[8] = (float) trkInfoA.phi;
291  m_vecTrackPairLeaves[9] = (float) trkInfoA.px;
292  m_vecTrackPairLeaves[10] = (float) trkInfoA.py;
293  m_vecTrackPairLeaves[11] = (float) trkInfoA.pz;
294  m_vecTrackPairLeaves[12] = (float) trkInfoA.pt;
295  m_vecTrackPairLeaves[13] = (float) trkInfoA.ene;
296  m_vecTrackPairLeaves[14] = (float) trkInfoA.dcaXY;
297  m_vecTrackPairLeaves[15] = (float) trkInfoA.dcaZ;
298  m_vecTrackPairLeaves[16] = (float) trkInfoA.ptErr;
299  m_vecTrackPairLeaves[17] = (float) trkInfoA.quality;
300  m_vecTrackPairLeaves[18] = (float) trkInfoA.vtxX;
301  m_vecTrackPairLeaves[19] = (float) trkInfoA.vtxY;
302  m_vecTrackPairLeaves[20] = (float) trkInfoA.vtxZ;
303  m_vecTrackPairLeaves[21] = (float) m_vecClustKeysA.size();
304  m_vecTrackPairLeaves[22] = (float) trkInfoB.id;
305  m_vecTrackPairLeaves[23] = (float) trkInfoB.nMvtxLayer;
306  m_vecTrackPairLeaves[24] = (float) trkInfoB.nInttLayer;
307  m_vecTrackPairLeaves[25] = (float) trkInfoB.nTpcLayer;
308  m_vecTrackPairLeaves[26] = (float) trkInfoB.nMvtxClust;
309  m_vecTrackPairLeaves[27] = (float) trkInfoB.nInttClust;
310  m_vecTrackPairLeaves[28] = (float) trkInfoB.nTpcClust;
311  m_vecTrackPairLeaves[29] = (float) trkInfoB.eta;
312  m_vecTrackPairLeaves[30] = (float) trkInfoB.phi;
313  m_vecTrackPairLeaves[31] = (float) trkInfoB.px;
314  m_vecTrackPairLeaves[32] = (float) trkInfoB.py;
315  m_vecTrackPairLeaves[33] = (float) trkInfoB.pz;
316  m_vecTrackPairLeaves[34] = (float) trkInfoB.pt;
317  m_vecTrackPairLeaves[35] = (float) trkInfoB.ene;
318  m_vecTrackPairLeaves[36] = (float) trkInfoB.dcaXY;
319  m_vecTrackPairLeaves[37] = (float) trkInfoB.dcaZ;
320  m_vecTrackPairLeaves[38] = (float) trkInfoB.ptErr;
321  m_vecTrackPairLeaves[39] = (float) trkInfoB.quality;
322  m_vecTrackPairLeaves[40] = (float) trkInfoB.vtxX;
323  m_vecTrackPairLeaves[41] = (float) trkInfoB.vtxY;
324  m_vecTrackPairLeaves[42] = (float) trkInfoB.vtxZ;
325  m_vecTrackPairLeaves[43] = (float) m_vecClustKeysB.size();
326  m_vecTrackPairLeaves[44] = (float) nSameKey;
327  m_vecTrackPairLeaves[45] = (float) drTrkAB;
328 
329  // fill track pair tuple
330  m_ntTrackPairs -> Fill(m_vecTrackPairLeaves.data());
331 
332  } // end 2nd track loop
333  } // end track loop
334  return;
335 
336  } // end 'DoDoubleTrackLoop(PHCompositeNode*)'
337 
338 
339 
340  bool SCheckTrackPairs::IsGoodTrack(SvtxTrack* track, PHCompositeNode* topNode) {
341 
342  // print debug statement
343  if (m_isDebugOn && (m_verbosity > 4)) {
344  cout << "SCheckTrackPairs::IsGoodTrack(SvtxTrack*, PHCompositeNode*) Checking if track is good..." << endl;
345  }
346 
347  // grab track info
348  TrkInfo info(track, topNode);
349 
350  // if needed, check if dca is in pt-dependent range
351  bool isInDcaSigma = true;
352  if (m_config.doDcaSigCut) {
353  isInDcaSigma = IsInSigmaDcaCut(info, m_config.nSigCut, m_config.ptFitMax, m_config.fSigDca);
354  }
355 
356  // if needed, check if track is from primary vertex
357  const bool isFromPrimVtx = m_config.useOnlyPrimVtx ? IsFromPrimaryVtx(track, topNode) : true;
358 
359  // check if seed is good & track is in acceptance
360  const bool isSeedGood = IsGoodTrackSeed(track, m_config.requireSiSeed);
361  const bool isInAccept = IsInTrackAcceptance(info, m_config.minAccept, m_config.maxAccept);
362 
363  // return overall goodness of track
364  return (isFromPrimVtx && isInDcaSigma && isSeedGood && isInAccept);
365 
366  } // end 'IsGoodTrack(SvtxTrack* track, PHCompositeNode* topNode)'
367 
368 } // end SColdQcdCorrelatorAnalysis namespace
369 
370 #endif
371 
372 // end ------------------------------------------------------------------------