Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RICHEvaluator.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RICHEvaluator.C
1 #include "RICHEvaluator.h"
2 #include "dualrich_analyzer.h"
3 #include "TrackProjectorPid.h"
5 
6 // Fun4All includes
9 
10 #include <phool/getClass.h>
11 #include <phool/PHCompositeNode.h>
12 
13 #include <g4main/PHG4Hit.h>
15 #include <g4main/PHG4Particle.h>
16 #include <g4main/PHG4VtxPoint.h>
18 
19 #include <g4hough/SvtxTrackMap.h>
20 #include <g4hough/SvtxTrack.h>
21 #include <g4hough/SvtxTrackState.h>
22 
23 // ROOT includes
24 #include <TTree.h>
25 #include <TFile.h>
26 #include <TString.h>
27 #include <TMath.h>
28 #include <TDatabasePDG.h>
29 #include <TH1.h>
30 
31 // other C++ includes
32 #include <cassert>
33 #include <algorithm>
34 
35 using namespace std;
36 
38  SubsysReco("RICHEvaluator" ),
39  _ievent(0),
40  _detector(richname),
41  _trackmap_name(tracksname),
42  _refractive_index(1),
43  _foutname(filename),
44  _fout_root(nullptr),
45  _trackproj(nullptr),
46  _acquire(nullptr),
47  _pdg(nullptr),
48  _radius(220.)
49 {
50  _richhits_name = "G4HIT_" + _detector;
51 }
52 
53 
54 int
56 {
57  _verbose = false;
58  _ievent = 0;
59 
60  /* create output file */
61  _fout_root = new TFile(_foutname.c_str(), "RECREATE");
62 
63  /* create output tree */
65  init_tree();
67 
68  /* access to PDG databse information */
69  _pdg = new TDatabasePDG();
70 
71  /* Throw warning if refractive index is not greater than 1 */
72  if ( _refractive_index <= 1 )
73  cout << PHWHERE << " WARNING: Refractive index for radiator volume is " << _refractive_index << endl;
74 
75  return 0;
76 }
77 
78 
79 int
81 {
82  /* create track projector object */
83  _trackproj = new TrackProjectorPid( topNode );
84 
85  /* create acquire object */
87 
88  return 0;
89 }
90 
91 
92 int
94 {
95  _ievent ++;
96 
97 
98  /* Get truth information */
99  PHG4TruthInfoContainer* truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
100 
101  /* Get all photon hits in RICH for this event */
102  PHG4HitContainer* richhits = findNode::getClass<PHG4HitContainer>(topNode,_richhits_name);
103 
104  /* Get track collection with all tracks in this event */
105  SvtxTrackMap* trackmap = findNode::getClass<SvtxTrackMap>(topNode,_trackmap_name);
106 
107  /* Check if collections found */
108  if (!truthinfo) {
109  cout << PHWHERE << "PHG4TruthInfoContainer not found on node tree" << endl;
111  }
112  if (!richhits) {
113  cout << PHWHERE << "PHG4HitContainer not found on node tree" << endl;
115  }
116  if (!trackmap) {
117  cout << PHWHERE << "SvtxTrackMap node not found on node tree" << endl;
119  }
120 
121 
122  /* Loop over tracks */
123  for (SvtxTrackMap::ConstIter track_itr = trackmap->begin(); track_itr != trackmap->end(); track_itr++)
124  {
125 
126  bool use_reconstructed_momentum = false;
127  bool use_truth_momentum = false;
128  bool use_emission_momentum = true;
129 
130  bool use_reconstructed_point = false;
131  bool use_approximate_point = true;
132 
133 
134  /* Store angles to get RMS value */
135  TH1F *ch_ang = new TH1F("","",1000,0.0,1.0);
136 
137  SvtxTrack* track_j = dynamic_cast<SvtxTrack*>(track_itr->second);
138 
139  /* Check if track_j is a null pointer. */
140  if (track_j == NULL)
141  continue;
142 
143 
144  /* Fill momv object which is the normalized momentum vector of the track in the RICH (i.e. its direction) */
145  double momv[3] = {0.,0.,0.};
146 
147  if (use_reconstructed_momentum) {
148  /* 'Continue' with next track if RICH projection not found for this track */
150  {
151  cout << "RICH track projection momentum NOT FOUND; next iteration" << endl;
152  continue;
153  }
154  }
155  if (use_truth_momentum) {
156  /* Fill with truth momentum instead of reco */
157  if ( ! _acquire->get_true_momentum( truthinfo, track_j, momv) )
158  {
159  cout << "No truth momentum found for track; next iteration" << endl;
160  continue;
161  }
162  }
163  if (use_emission_momentum) {
164  /* Fill with vector constructed from emission points (from truth) */
165  if ( ! _acquire->get_emission_momentum( truthinfo, richhits, track_j, momv) )
166  {
167  cout << "No truth momentum from emission points found for track; next iteration" << endl;
168  continue;
169  }
170  }
171 
172  double momv_norm = sqrt( momv[0]*momv[0] + momv[1]*momv[1] + momv[2]*momv[2] );
173  momv[0] /= momv_norm;
174  momv[1] /= momv_norm;
175  momv[2] /= momv_norm;
176 
177 
178  /* Get mean emission point from track in RICH */
179  double m_emi[3] = {0.,0.,0.};
180 
181  if (use_reconstructed_point) {
182  /* 'Continue' with next track if RICH projection not found for this track */
184  {
185  cout << "RICH track projection position NOT FOUND; next iteration" << endl;
186  continue;
187  }
188  }
189  if (use_approximate_point) {
190  m_emi[0] = ((_radius)/momv[2])*momv[0];
191  m_emi[1] = ((_radius)/momv[2])*momv[1];
192  m_emi[2] = ((_radius)/momv[2])*momv[2];
193  }
194 
195 
196  /* 'Continue' with next track if track doesn't pass through RICH */
197  if ( ! _trackproj->is_in_RICH( momv ) )
198  continue;
199 
200 
201  /* Calculate truth emission angle and truth mass */
202  if (truthinfo)
203  {
205  }
206 
207  /* Loop over all G4Hits in container (i.e. RICH photons in event) */
208  PHG4HitContainer::ConstRange rich_hits_begin_end = richhits->getHits();
209  PHG4HitContainer::ConstIterator rich_hits_iter;
210 
211  for (rich_hits_iter = rich_hits_begin_end.first; rich_hits_iter != rich_hits_begin_end.second; ++rich_hits_iter)
212  {
213  PHG4Hit *hit_i = rich_hits_iter->second;
214  PHG4Particle* particle = NULL;
215  PHG4Particle* parent = NULL;
216  PHG4VtxPoint* vertex = NULL;
217 
218  if ( truthinfo )
219  {
220  particle = truthinfo->GetParticle( hit_i->get_trkid() );
221  parent = truthinfo->GetParticle( particle->get_parent_id() );
222  vertex = truthinfo->GetVtx( particle->get_vtx_id() );
223  }
224 
225  _hit_x0 = hit_i->get_x(0);
226  _hit_y0 = hit_i->get_y(0);
227  _hit_z0 = hit_i->get_z(0);
228 
229  _emi_x = vertex->get_x();
230  _emi_y = vertex->get_y();
231  _emi_z = vertex->get_z();
232 
233  _track_px = particle->get_px();
234  _track_py = particle->get_py();
235  _track_pz = particle->get_pz();
236 
237  _mtrack_px = parent->get_px();
238  _mtrack_py = parent->get_py();
239  _mtrack_pz = parent->get_pz();
241 
242  _track_e = particle->get_e();
243  _mtrack_e = parent->get_e();
244  _edep = hit_i->get_edep();
245 
246  _bankid = 0;
247  _volumeid = hit_i->get_detid();
248  _hitid = hit_i->get_hit_id();
249  _pid = particle->get_pid();
250  _mpid = parent->get_pid();
251  _trackid = particle->get_track_id();
252  _mtrackid = parent->get_track_id();
253  _otrackid = track_j->get_id();
254 
255  /* Set reconstructed emission angle and reconstructed mass for output tree */
256  _theta_reco = _acquire->calculate_emission_angle( m_emi, momv, hit_i );
257  ch_ang->Fill(_theta_reco);
258 
259  /* Fill tree */
260  _tree_rich->Fill();
261 
262 
263  } // END loop over photons
264 
265 
266  _theta_rms = ch_ang->GetRMS();
267  _theta_mean = ch_ang->GetMean();
268 
269  /* Fill condensed tree after every track */
270  _tree_rich_small->Fill();
271 
272 
273  } // END loop over tracks
274 
275 
276  return 0;
277 }
278 
279 
281 {
282  /* Get truth particle associated with track */
283  PHG4Particle* particle = truthinfo->GetParticle( track->get_truth_track_id() );
284 
285  /* Get particle ID */
286  int pid = particle->get_pid();
287 
288  /* Get particle mass */
289  double mass = _pdg->GetParticle(pid)->Mass();
290 
291  /* Get particle total momentum */
292  double ptotal = sqrt( particle->get_px() * particle->get_px() +
293  particle->get_py() * particle->get_py() +
294  particle->get_pz() * particle->get_pz() );
295 
296  /* Calculate beta = v/c */
297  double beta = ptotal / sqrt( mass * mass + ptotal * ptotal );
298 
299  /* Calculate emission angle for Cerenkov light */
300  double theta_c = acos( 1 / ( index * beta ) );
301 
302  return theta_c;
303 }
304 
305 int
307 {
308  _fout_root->cd();
309  _tree_rich->Write();
310  _tree_rich_small->Write();
311  _fout_root->Close();
312 
313  return 0;
314 }
315 
316 
317 void
319 {
320  _hit_x0 = -999;
321  _hit_y0 = -999;
322  _hit_z0 = -999;
323 
324  _emi_x = -999;
325  _emi_y = -999;
326  _emi_z = -999;
327 
328  _track_px = -999;
329  _track_py = -999;
330  _track_pz = -999;
331 
332  _mtrack_px = -999;
333  _mtrack_py = -999;
334  _mtrack_pz = -999;
335  _mtrack_ptot = -999;
336 
337  _track_e = -999;
338  _mtrack_e = -999;
339  _edep = -999;
340 
341  _bankid = -999;
342  _volumeid = -999;
343  _hitid = -999;
344  _pid = -999;
345  _mpid = -999;
346  _trackid = -999;
347  _mtrackid = -999;
348  _otrackid = -999;
349 
350  _theta_true = -999;
351  _theta_reco = -999;
352  _theta_mean = -999;
353  _theta_rms = -999;
354 
355  return;
356 }
357 
358 
359 int
361 {
362  _tree_rich = new TTree("eval_rich","RICH Evaluator info");
363 
364  _tree_rich->Branch("event", &_ievent, "Event number /I");
365  _tree_rich->Branch("hit_x", &_hit_x0, "Global x-hit /D");
366  _tree_rich->Branch("hit_y", &_hit_y0, "Global y-hit /D");
367  _tree_rich->Branch("hit_z", &_hit_z0, "Global z-hit /D");
368  _tree_rich->Branch("emi_x", &_emi_x, "Photon emission x-coord. /D");
369  _tree_rich->Branch("emi_y", &_emi_y, "Photon emission y-coord. /D");
370  _tree_rich->Branch("emi_z", &_emi_z, "Photon emission z-coord. /D");
371  _tree_rich->Branch("px", &_track_px, "Particle x-momentum /D");
372  _tree_rich->Branch("py", &_track_py, "Particle y-momentum /D");
373  _tree_rich->Branch("pz", &_track_pz, "Particle z-momentum /D");
374  _tree_rich->Branch("mpx", &_mtrack_px, "Mother x-momentum /D");
375  _tree_rich->Branch("mpy", &_mtrack_py, "Mother y-momentum /D");
376  _tree_rich->Branch("mpz", &_mtrack_pz, "Mother z-momentum /D");
377  _tree_rich->Branch("mptot", &_mtrack_ptot, "Mother total momentum /D");
378  _tree_rich->Branch("e", &_track_e, "Track energy /D");
379  _tree_rich->Branch("me", &_mtrack_e, "Mother track energy /D");
380  _tree_rich->Branch("edep", &_edep, "Energy deposited in material /D");
381  _tree_rich->Branch("bankid", &_bankid, "Bank ID /I");
382  _tree_rich->Branch("volumeid", &_volumeid, "Volume ID /I");
383  _tree_rich->Branch("hitid", &_hitid, "Hit ID /I");
384  _tree_rich->Branch("pid", &_pid, "Particle ID /I");
385  _tree_rich->Branch("mpid", &_mpid, "Mother ID /I");
386  _tree_rich->Branch("trackid", &_trackid, "Track ID /I");
387  _tree_rich->Branch("mtrackid", &_mtrackid, "Mother track ID /I");
388  _tree_rich->Branch("otrackid", &_otrackid, "Ordered track ID /I");
389 
390  _tree_rich->Branch("theta_true", &_theta_true, "True emission angle /D");
391  _tree_rich->Branch("theta_reco", &_theta_reco, "Reconstructed emission angle /D");
392 
393  return 0;
394 }
395 
396 
397 int
399 {
400  /* Condensed ROOT tree, 1 entry per track */
401  _tree_rich_small = new TTree("eval_rich_small","RICH Evaluator info condensed");
402 
403  _tree_rich_small->Branch("event", &_ievent, "Event number /I");
404  _tree_rich_small->Branch("otrackid", &_otrackid, "Ordered track ID /I");
405  _tree_rich_small->Branch("mptot", &_mtrack_ptot, "Total momentum /D");
406  _tree_rich_small->Branch("theta_true", &_theta_true, "True emission angle /D");
407  _tree_rich_small->Branch("theta_mean", &_theta_mean, "Reconstructed angle mean /D");
408  _tree_rich_small->Branch("theta_rms", &_theta_rms, "Reconstructed angle spread /D");
409 
410  return 0;
411 }