Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
QAG4SimulationDistortions.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file QAG4SimulationDistortions.cc
1 
3 
4 #include <qautils/QAHistManagerDef.h>
5 
8 
10 #include <phool/getClass.h>
11 #include <phool/phool.h> // for PHWHERE
12 
14 
15 #include <trackbase/TrkrCluster.h>
21 
22 #include <TAxis.h>
23 #include <TH1.h>
24 #include <TH2.h>
25 #include <TNamed.h>
26 #include <TString.h>
27 #include <TTree.h>
28 #include <TVector3.h>
29 
30 #include <array>
31 #include <cassert>
32 #include <cmath>
33 #include <iostream>
34 #include <map> // for map
35 #include <utility> // for pair
36 
37 namespace
38 {
39 
40  // square
41  template <class T>
42  inline constexpr T square(const T& x)
43  {
44  return x * x;
45  }
46 
47  // radius
48  template <class T>
49  T get_r(const T& x, const T& y)
50  {
51  return std::sqrt(square(x) + square(y));
52  }
53 
54  template <class T>
55  inline constexpr T deltaPhi(const T& phi)
56  {
57  if (phi > M_PI)
58  return phi - 2. * M_PI;
59  else if (phi <= -M_PI)
60  return phi + 2. * M_PI;
61  else
62  return phi;
63  }
64 
66  template <int type>
67  int count_clusters(const std::vector<TrkrDefs::cluskey>& keys)
68  {
69  return std::count_if(keys.begin(), keys.end(),
70  [](const TrkrDefs::cluskey& key)
71  { return TrkrDefs::getTrkrId(key) == type; });
72  }
73 } // namespace
74 
75 //____________________________________________________________________________..
77  : SubsysReco(name)
78 {
79 }
80 
81 //____________________________________________________________________________..
83 {
84 }
85 
86 //____________________________________________________________________________..
88 {
90  assert(hm);
91 
92  TH1* h(nullptr);
93 
94  h = new TH2F(TString(get_histo_prefix()) + "betadz", ";tan#beta; #Deltaz [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5);
95 
96  hm->registerHisto(h);
97 
98  h = new TH2F(TString(get_histo_prefix()) + "alphardphi", ";tan#alpha; r#Delta#phi [cm]", 100, -0.5, 0.5, 100, -0.5, 0.5);
99  hm->registerHisto(h);
100 
101  h = new TH2F(TString(get_histo_prefix()) + "rphiResid", ";r [cm]; #Deltar#phi [cm]", 60, 20, 80, 500, -2, 2);
102  hm->registerHisto(h);
103 
104  h = new TH2F(TString(get_histo_prefix()) + "zResid", ";z [cm]; #Deltaz [cm]", 200, -100, 100, 1000, -2, 2);
105  hm->registerHisto(h);
106 
107  h = new TH2F(TString(get_histo_prefix()) + "etaResid", ";#eta;#Delta#eta", 20, -1, 1, 500, -0.2, 0.2);
108  hm->registerHisto(h);
109 
110  h = new TH2F(TString(get_histo_prefix()) + "etaResidLayer", ";r [cm]; #Delta#eta", 60, 20, 80, 500, -0.2, 0.2);
111  hm->registerHisto(h);
112 
113  h = new TH2F(TString(get_histo_prefix()) + "zResidLayer", ";r [cm]; #Deltaz [cm]", 60, 20, 80, 1000, -2, 2);
114  hm->registerHisto(h);
115 
116  h = new TH2F(TString(get_histo_prefix()) + "deltarphi_layer", ";layer; r.#Delta#phi_{track-cluster} (cm)", 57, 0, 57, 500, -2, 2);
117  hm->registerHisto(h);
118 
119  h = new TH2F(TString(get_histo_prefix()) + "deltaz_layer", ";layer; #Deltaz_{track-cluster} (cm)", 57, 0, 57, 100, -2, 2);
120  hm->registerHisto(h);
121 
122  h = new TH2F(TString(get_histo_prefix()) + "statez_pulls", "layer; #Deltaz_{track-cluster}/#sigma_{z}^{state}", 57, 0, 57, 100, -5, 5);
123  hm->registerHisto(h);
124 
125  h = new TH2F(TString(get_histo_prefix()) + "staterphi_pulls", "layer; #Deltar#phi_{track-cluster}/#sigma_{rphi}^{state}", 57, 0, 57, 100, -5, 5);
126  hm->registerHisto(h);
127 
128  h = new TH2F(TString(get_histo_prefix()) + "clusz_pulls", "layer; #Deltaz_{track-cluster}/#sigma_{z}^{clus}", 57, 0, 57, 100, -5, 5);
129  hm->registerHisto(h);
130 
131  h = new TH2F(TString(get_histo_prefix()) + "clusrphi_pulls", "layer; #Deltar#phi_{track-cluster}/#sigma_{r#phi}^{clus}", 57, 0, 57, 100, -5, 5);
132  hm->registerHisto(h);
133 
134  TTree* t(nullptr);
135 
136  t = new TTree(TString(get_histo_prefix()) + "residTree", "tpc residual info");
137  t->Branch("tanAlpha", &m_tanAlpha, "tanAlpha/D");
138  t->Branch("tanBeta", &m_tanBeta, "tanBeta/D");
139  t->Branch("drphi", &m_drphi, "drphi/D");
140  t->Branch("dz", &m_dz, "dz/D");
141  t->Branch("clusR", &m_clusR, "clusR/D");
142  t->Branch("clusPhi", &m_clusPhi, "clusPhi/D");
143  t->Branch("clusZ", &m_clusZ, "clusZ/D");
144  t->Branch("statePhi", &m_statePhi, "statePhi/D");
145  t->Branch("stateZ", &m_stateZ, "stateZ/D");
146  t->Branch("stateR", &m_stateR, "stateR/D");
147  t->Branch("stateRPhiErr", &m_stateRPhiErr, "stateRPhiErr/D");
148  t->Branch("stateZErr", &m_stateZErr, "stateZErr/D");
149  t->Branch("clusRPhiErr", &m_clusRPhiErr, "clusRPhiErr/D");
150  t->Branch("clusZErr", &m_clusZErr, "clusZErr/D");
151  t->Branch("cluskey", &m_cluskey, "cluskey/l");
152  t->Branch("event", &m_event, "event/I");
153 
154  hm->registerHisto(t);
155 
157 }
158 
159 //____________________________________________________________________________..
161 {
162  m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxSiliconMMTrackMap");
163  m_clusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
164 
165  m_tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
166 
167  if (not m_trackMap or not m_clusterContainer or not m_tGeometry)
168  {
169  std::cout << PHWHERE << "Necessary distortion container not on node tree. Bailing."
170  << std::endl;
171 
173  }
174 
176 }
177 
178 //____________________________________________________________________________..
180 {
182  assert(hm);
183 
184  auto h_beta = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "betadz"));
185  assert(h_beta);
186 
187  auto h_alpha = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "alphardphi"));
188  assert(h_alpha);
189 
190  auto h_rphiResid = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "rphiResid"));
191  assert(h_rphiResid);
192 
193  auto h_zResid = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "zResid"));
194  assert(h_zResid);
195 
196  auto h_etaResid = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "etaResid"));
197  assert(h_etaResid);
198 
199  auto h_etaResidLayer = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "etaResidLayer"));
200  assert(h_etaResidLayer);
201 
202  auto h_zResidLayer = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "zResidLayer"));
203  assert(h_zResidLayer);
204 
205  auto h_deltarphi_layer = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "deltarphi_layer"));
206  assert(h_deltarphi_layer);
207 
208  auto h_deltaz_layer = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "deltaz_layer"));
209  assert(h_deltaz_layer);
210 
211  auto h_statez_pulls = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "statez_pulls"));
212  assert(h_statez_pulls);
213 
214  auto h_staterphi_pulls = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "staterphi_pulls"));
215  assert(h_staterphi_pulls);
216 
217  auto h_clusz_pulls = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "clusz_pulls"));
218  assert(h_clusz_pulls);
219 
220  auto h_clusrphi_pulls = dynamic_cast<TH1*>(hm->getHisto(get_histo_prefix() + "clusrphi_pulls"));
221  assert(h_clusrphi_pulls);
222 
223  auto t_tree = dynamic_cast<TTree*>(hm->getHisto(get_histo_prefix() + "residTree"));
224  assert(t_tree);
225 
226  for (const auto& [key, track] : *m_trackMap)
227  {
228  if (!checkTrack(track))
229  {
230  continue;
231  }
232  auto tpcSeed = track->get_tpc_seed();
233  auto siliconSeed = track->get_silicon_seed();
234 
236  if (not tpcSeed or not siliconSeed)
237  {
238  continue;
239  }
240 
241  for (auto iter = track->begin_states(); iter != track->end_states(); ++iter)
242  {
243  auto state = iter->second;
244 
247  if ((state->get_name()).find("UNKNOWN") != std::string::npos)
248  {
249  continue;
250  }
251 
252  TrkrDefs::cluskey ckey = std::stoll(state->get_name());
253 
254  auto cluster = m_clusterContainer->findCluster(ckey);
255 
256  const auto clusGlobPosition = m_tGeometry->getGlobalPosition(ckey, cluster);
257 
258  const float clusR = get_r(clusGlobPosition(0), clusGlobPosition(1));
259  const float clusPhi = std::atan2(clusGlobPosition(1), clusGlobPosition(0));
260  const float clusZ = clusGlobPosition(2);
261 
262  // cluster errors
263  const float clusRPhiErr = cluster->getRPhiError();
264  const float clusZErr = cluster->getZError();
265 
266  const Acts::Vector3 stateGlobPosition = Acts::Vector3(state->get_x(),
267  state->get_y(),
268  state->get_z());
269  const Acts::Vector3 stateGlobMom = Acts::Vector3(state->get_px(),
270  state->get_py(),
271  state->get_pz());
272 
273  const float stateRPhiErr = state->get_rphi_error();
274  const float stateZErr = state->get_z_error();
275 
276  const float stateR = get_r(stateGlobPosition(0), stateGlobPosition(1));
277 
278  const auto dr = clusR - stateR;
279  const auto trackDrDt = (stateGlobPosition(0) * stateGlobMom(0) + stateGlobPosition(1) * stateGlobMom(1)) / stateR;
280  const auto trackDxDr = stateGlobMom(0) / trackDrDt;
281  const auto trackDyDr = stateGlobMom(1) / trackDrDt;
282  const auto trackDzDr = stateGlobMom(2) / trackDrDt;
283 
284  const auto trackX = stateGlobPosition(0) + dr * trackDxDr;
285  const auto trackY = stateGlobPosition(1) + dr * trackDyDr;
286  const auto trackZ = stateGlobPosition(2) + dr * trackDzDr;
287  const float statePhi = std::atan2(trackY, trackX);
288  const float stateZ = trackZ;
289 
290  // Calculate residuals
291  const float drphi = clusR * deltaPhi(clusPhi - statePhi);
292  const float dz = clusZ - stateZ;
293 
294  const auto trackPPhi = -stateGlobMom(0) * std::sin(statePhi) + stateGlobMom(1) * std::cos(statePhi);
295  const auto trackPR = stateGlobMom(0) * std::cos(statePhi) + stateGlobMom(1) * std::sin(statePhi);
296  const auto trackPZ = stateGlobMom(2);
297 
298  const auto trackAlpha = -trackPPhi / trackPR;
299  const auto trackBeta = -trackPZ / trackPR;
300  const auto trackEta = std::atanh(stateGlobMom(2) / stateGlobMom.norm());
301  const auto clusEta = std::atanh(clusZ / clusGlobPosition.norm());
302 
303  h_alpha->Fill(trackAlpha, drphi);
304  h_beta->Fill(trackBeta, dz);
305  h_rphiResid->Fill(clusR, drphi);
306  h_zResid->Fill(stateZ, dz);
307  h_etaResid->Fill(trackEta, clusEta - trackEta);
308  h_zResidLayer->Fill(clusR, dz);
309  h_etaResidLayer->Fill(clusR, clusEta - trackEta);
310 
311  const auto layer = TrkrDefs::getLayer(ckey);
312  h_deltarphi_layer->Fill(layer, drphi);
313  h_deltaz_layer->Fill(layer, dz);
314 
315  h_statez_pulls->Fill(layer, dz / stateZErr);
316  h_staterphi_pulls->Fill(layer, drphi / stateRPhiErr);
317  h_clusz_pulls->Fill(layer, dz / clusZErr);
318  h_clusrphi_pulls->Fill(layer, drphi / clusRPhiErr);
319 
320  m_tanAlpha = trackAlpha;
321  m_tanBeta = trackBeta;
322  m_drphi = drphi;
323  m_dz = dz;
324  m_clusR = clusR;
325  m_clusPhi = clusPhi;
326  m_clusZ = clusZ;
327  m_statePhi = statePhi;
328  m_stateZ = stateZ;
329  m_stateR = stateR;
330  m_stateRPhiErr = stateRPhiErr;
331  m_stateZErr = stateZErr;
332  m_clusRPhiErr = clusRPhiErr;
333  m_clusZErr = clusZErr;
334  m_cluskey = ckey;
335  t_tree->Fill();
336  }
337  }
338 
339  m_event++;
340 
342 }
343 
345 {
346  if (track->get_pt() < 0.5)
347  {
348  return false;
349  }
350 
351  // ignore tracks with too few mvtx, intt and micromegas hits
352  const auto cluster_keys(get_cluster_keys(track));
353  if (count_clusters<TrkrDefs::mvtxId>(cluster_keys) < 2) return false;
354  if (count_clusters<TrkrDefs::inttId>(cluster_keys) < 2) return false;
355  if (count_clusters<TrkrDefs::micromegasId>(cluster_keys) < 2)
356  {
357  return false;
358  }
359 
360  return true;
361 }
362 
363 std::vector<TrkrDefs::cluskey> QAG4SimulationDistortions::get_cluster_keys(SvtxTrack* track)
364 {
365  std::vector<TrkrDefs::cluskey> out;
366  for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()})
367  {
368  if (seed)
369  {
370  std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out));
371  }
372  }
373  return out;
374 }