Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
STACalorimeterCharacterization.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file STACalorimeterCharacterization.C
2 
3 #include <phool/getClass.h>
6 
8 //#include <g4hough/PHG4HoughTransform.h> // CAUSES ERRORS DUE TO VertexFinder.h FAILING TO FIND <Eigen/LU>
9 
10 
12 #include <g4main/PHG4Particle.h>
13 #include <g4main/PHG4VtxPoint.h>
14 
15 #include <g4hough/SvtxVertexMap.h>
16 #include <g4hough/SvtxVertex.h>
17 #include <g4hough/SvtxTrackMap.h>
18 #include <g4hough/SvtxTrack.h>
19 
20 #include <g4eval/SvtxEvalStack.h>
21 #include <g4eval/SvtxTrackEval.h>
22 #include <g4eval/SvtxVertexEval.h>
23 #include <g4eval/SvtxTruthEval.h>
24 
25 // --- common to all calorimeters
26 #include <calobase/RawTowerGeomContainer.h>
27 #include <calobase/RawTowerContainer.h>
28 #include <calobase/RawTower.h>
29 #include <calobase/RawCluster.h>
30 #include <calobase/RawClusterContainer.h>
31 #include <g4eval/CaloEvalStack.h>
34 
35 #include <TH1D.h>
36 #include <TH2D.h>
37 #include <TProfile2D.h>
38 
39 #include <iostream>
40 //#include <cassert>
41 
42 using namespace std;
43 
44 
45 
47 {
48  cout << "Class constructor called " << endl;
49  nevents = 0;
50  nerrors = 0;
51  nwarnings = 0;
52  nlayers = 7;
53  verbosity = 0;
54  magneticfield = 1.4; // default is 1.5 but Mike's tracking stuff is using 1.4 for now...
55  //docalocuts = false;
56 }
57 
58 
59 
61 {
62 
63  // --------------------------------------------------------------------------------
64  // --- This is the class initialization method
65  // --- Get a pointer to the Fun4All server to register histograms
66  // --- Histograms are declared in class header file
67  // --- Histograms are instantiated here and then registered with the Fun4All server
68  // --------------------------------------------------------------------------------
69 
70 
71  // --- get instance of
73 
74 
75 
76 
77 
78 
79  // --- some basic calorimeter performance histograms
80 
81  _energy_ratio_emc = new TH2D("energy_ratio_emc", "", 300,0.0,30.0, 100,0.0,2.0);
82  _energy_ratio_hci = new TH2D("energy_ratio_hci", "", 300,0.0,30.0, 100,0.0,2.0);
83  _energy_ratio_hco = new TH2D("energy_ratio_hco", "", 300,0.0,30.0, 100,0.0,2.0);
84  _energy_ratio_hct = new TH2D("energy_ratio_hct", "", 300,0.0,30.0, 100,0.0,2.0);
85  _energy_ratio_tot_dumb = new TH2D("energy_ratio_tot_dumb", "", 300,0.0,30.0, 100,0.0,2.0);
86  _energy_ratio_tot_smart = new TH2D("energy_ratio_tot_smart", "", 300,0.0,30.0, 100,0.0,2.0);
93 
94  _energy_ratio_elb_emc = new TH2D("energy_ratio_elb_emc", "", 300,0.0,30.0, 100,0.0,2.0);
95  _energy_ratio_elb_hci = new TH2D("energy_ratio_elb_hci", "", 300,0.0,30.0, 100,0.0,2.0);
96  _energy_ratio_elb_hco = new TH2D("energy_ratio_elb_hco", "", 300,0.0,30.0, 100,0.0,2.0);
97  _energy_ratio_elb_hct = new TH2D("energy_ratio_elb_hct", "", 300,0.0,30.0, 100,0.0,2.0);
98  _energy_ratio_elb_tot_dumb = new TH2D("energy_ratio_elb_tot_dumb", "", 300,0.0,30.0, 100,0.0,2.0);
99  _energy_ratio_elb_tot_smart = new TH2D("energy_ratio_elb_tot_smart", "", 300,0.0,30.0, 100,0.0,2.0);
106 
107  _energy_ratio_eub_emc = new TH2D("energy_ratio_eub_emc", "", 300,0.0,30.0, 100,0.0,2.0);
108  _energy_ratio_eub_hci = new TH2D("energy_ratio_eub_hci", "", 300,0.0,30.0, 100,0.0,2.0);
109  _energy_ratio_eub_hco = new TH2D("energy_ratio_eub_hco", "", 300,0.0,30.0, 100,0.0,2.0);
110  _energy_ratio_eub_hct = new TH2D("energy_ratio_eub_hct", "", 300,0.0,30.0, 100,0.0,2.0);
111  _energy_ratio_eub_tot_dumb = new TH2D("energy_ratio_eub_tot_dumb", "", 300,0.0,30.0, 100,0.0,2.0);
112  _energy_ratio_eub_tot_smart = new TH2D("energy_ratio_eub_tot_smart", "", 300,0.0,30.0, 100,0.0,2.0);
119 
120  _energy_dphi_emc = new TH2D("energy_dphi_emc", "", 300,0.0,30.0, 100,-1.0,1.0);
121  _energy_dphi_hci = new TH2D("energy_dphi_hci", "", 300,0.0,30.0, 100,-1.0,1.0);
122  _energy_dphi_hco = new TH2D("energy_dphi_hco", "", 300,0.0,30.0, 100,-1.0,1.0);
126 
127  _energy_deta_emc = new TH2D("energy_deta_emc", "", 300,0.0,30.0, 100,-1.0,1.0);
128  _energy_deta_hci = new TH2D("energy_deta_hci", "", 300,0.0,30.0, 100,-1.0,1.0);
129  _energy_deta_hco = new TH2D("energy_deta_hco", "", 300,0.0,30.0, 100,-1.0,1.0);
133 
134 
135 
136  _towers_3x3_emc = new TProfile2D("towers_3x3_emc", "", 3,-1.5,1.5, 3,-1.5,1.5, 0.0,9998.0,"");
137  _towers_5x5_emc = new TProfile2D("towers_5x5_emc", "", 5,-2.5,2.5, 5,-2.5,2.5, 0.0,9998.0,"");
138  _towers_7x7_emc = new TProfile2D("towers_7x7_emc", "", 7,-3.5,3.5, 7,-3.5,3.5, 0.0,9998.0,"");
139  _towers_9x9_emc = new TProfile2D("towers_9x9_emc", "", 9,-4.5,4.5, 9,-4.5,4.5, 0.0,9998.0,"");
144 
145  for ( int i = 0; i < 10; ++i )
146  {
147  _towersum_energy_emc[i] = new TH2D(Form("towersum_energy_emc_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
148  _tower_energy_emc[i] = new TH2D(Form("tower_energy_emc_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
151  }
152 
153  _towers_3x3_hci = new TProfile2D("towers_3x3_hci", "", 3,-1.5,1.5, 3,-1.5,1.5, 0.0,9998.0,"");
154  _towers_5x5_hci = new TProfile2D("towers_5x5_hci", "", 5,-2.5,2.5, 5,-2.5,2.5, 0.0,9998.0,"");
155  _towers_7x7_hci = new TProfile2D("towers_7x7_hci", "", 7,-3.5,3.5, 7,-3.5,3.5, 0.0,9998.0,"");
156  _towers_9x9_hci = new TProfile2D("towers_9x9_hci", "", 9,-4.5,4.5, 9,-4.5,4.5, 0.0,9998.0,"");
161 
162  for ( int i = 0; i < 10; ++i )
163  {
164  _towersum_energy_hci[i] = new TH2D(Form("towersum_energy_hci_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
165  _tower_energy_hci[i] = new TH2D(Form("tower_energy_hci_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
168  }
169 
170  _towers_3x3_hco = new TProfile2D("towers_3x3_hco", "", 3,-1.5,1.5, 3,-1.5,1.5, 0.0,9998.0,"");
171  _towers_5x5_hco = new TProfile2D("towers_5x5_hco", "", 5,-2.5,2.5, 5,-2.5,2.5, 0.0,9998.0,"");
172  _towers_7x7_hco = new TProfile2D("towers_7x7_hco", "", 7,-3.5,3.5, 7,-3.5,3.5, 0.0,9998.0,"");
173  _towers_9x9_hco = new TProfile2D("towers_9x9_hco", "", 9,-4.5,4.5, 9,-4.5,4.5, 0.0,9998.0,"");
174 
175  for ( int i = 0; i < 10; ++i )
176  {
177  _towersum_energy_hco[i] = new TH2D(Form("towersum_energy_hco_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
178  _tower_energy_hco[i] = new TH2D(Form("tower_energy_hco_%d",i), "", 300,0.0,30.0, 100,0.0,2.0);
181  }
186 
187 
188 
189  return 0;
190 
191 }
192 
193 
194 
196 {
197 
198  // --- This is the class process_event method
199  // --- This is where the bulk of the analysis is done
200  // --- Here we get the various data nodes we need to do the analysis
201  // --- Then we use variables (accessed through class methods) to perform calculations
202 
203  if ( verbosity > -1 )
204  {
205  cout << endl;
206  cout << "------------------------------------------------------------------------------------" << endl;
207  cout << "Now processing event number " << nevents << endl; // would be good to add verbosity switch
208  }
209 
210  ++nevents; // You may as youtself, why ++nevents (pre-increment) rather
211  // than nevents++ (post-increment)? The short answer is performance.
212  // For simple types it probably doesn't matter, but it can really help
213  // for complex types (like the iterators below).
214 
215 
216  // --- Truth level information
217  PHG4TruthInfoContainer* truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,"G4TruthInfo");
218  if ( !truthinfo )
219  {
220  cerr << PHWHERE << " ERROR: Can't find G4TruthInfo" << endl;
221  exit(-1);
222  }
223 
224  // --- SvtxTrackMap
225  SvtxTrackMap* trackmap = findNode::getClass<SvtxTrackMap>(topNode,"SvtxTrackMap");
226  if ( !trackmap )
227  {
228  cerr << PHWHERE << " ERROR: Can't find SvtxTrackMap" << endl;
229  exit(-1);
230  }
231 
232  // --- SvtxVertexMap
233  SvtxVertexMap* vertexmap = findNode::getClass<SvtxVertexMap>(topNode,"SvtxVertexMap");
234  if ( !vertexmap )
235  {
236  cerr << PHWHERE << " ERROR: Can't find SvtxVertexMap" << endl;
237  exit(-1);
238  }
239 
240  // --- Raw cluster classes
241  bool clusters_available = true;
242  RawClusterContainer *emc_clustercontainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
243  RawClusterContainer *hci_clustercontainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_HCALIN");
244  RawClusterContainer *hco_clustercontainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_HCALOUT");
245  if ( !emc_clustercontainer || !hci_clustercontainer || !hco_clustercontainer )
246  {
247  if ( verbosity > -1 )
248  {
249  cerr << PHWHERE << " WARNING: Can't find cluster nodes" << endl;
250  cerr << PHWHERE << " emc_clustercontainer " << emc_clustercontainer << endl;
251  cerr << PHWHERE << " hci_clustercontainer " << hci_clustercontainer << endl;
252  cerr << PHWHERE << " hco_clustercontainer " << hco_clustercontainer << endl;
253  }
254  clusters_available = false;
255  ++nwarnings;
256  }
257 
258  // --- Tower geometry
259  RawTowerGeomContainer *emc_towergeo = findNode::getClass<RawTowerGeomContainer>(topNode,"TOWERGEOM_CEMC");
260  RawTowerGeomContainer *hci_towergeo = findNode::getClass<RawTowerGeomContainer>(topNode,"TOWERGEOM_HCALIN");
261  RawTowerGeomContainer *hco_towergeo = findNode::getClass<RawTowerGeomContainer>(topNode,"TOWERGEOM_HCALOUT");
262  if ( !emc_towergeo || !hci_towergeo || !hco_towergeo )
263  {
264  if ( verbosity > -1 )
265  {
266  cerr << PHWHERE << " WARNING: Can't find tower geometry nodes" << endl;
267  cerr << PHWHERE << " emc_towergeo " << emc_towergeo << endl;
268  cerr << PHWHERE << " hci_towergeo " << hci_towergeo << endl;
269  cerr << PHWHERE << " hco_towergeo " << hco_towergeo << endl;
270  }
271  ++nwarnings;
272  }
273 
274  // --- Tower container
275  RawTowerContainer *emc_towercontainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_CEMC");
276  RawTowerContainer *hci_towercontainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_HCALIN");
277  RawTowerContainer *hco_towercontainer = findNode::getClass<RawTowerContainer>(topNode,"TOWER_CALIB_HCALOUT");
278  if ( !emc_towercontainer || !hci_towercontainer || !hco_towercontainer )
279  {
280  if ( verbosity > -1 )
281  {
282  cerr << PHWHERE << " WARNING: Can't find tower container nodes" << endl;
283  cerr << PHWHERE << " emc_towercontainer " << emc_towercontainer << endl;
284  cerr << PHWHERE << " hci_towercontainer " << hci_towercontainer << endl;
285  cerr << PHWHERE << " hco_towercontainer " << hco_towercontainer << endl;
286  }
287  ++nwarnings;
288  }
289 
290 
291 
292 
293  // --- step 1: loop over all possible towers and make a map of energy, tower address
294  // --- step 2: loop over map in reverse order and fill a vector of tower addresses
295  // --- step 3: use vector of tower addresses (which are ordered by energy highest to lowest) as desired
296  // --- note: the vector is not really needed, as one can just get anything that's needed from the map
297  // --- itself, but personally I like vectors
298 
299  //int nphi = emc_towergeo->get_phibins();
300  //int neta = emc_towergeo->get_etabins();
301 
302 
303 
304  vector<RawCluster*> emc_clusters = get_ordered_clusters(emc_clustercontainer);
305  vector<RawCluster*> hci_clusters = get_ordered_clusters(hci_clustercontainer);
306  vector<RawCluster*> hco_clusters = get_ordered_clusters(hco_clustercontainer);
307 
308 
309 
310  // --- Create SVTX eval stack
311  SvtxEvalStack svtxevalstack(topNode);
312  // --- Get evaluator objects from the eval stack
313  //SvtxVertexEval* vertexeval = svtxevalstack.get_vertex_eval();
314  SvtxTrackEval* trackeval = svtxevalstack.get_track_eval();
315  SvtxTruthEval* trutheval = svtxevalstack.get_truth_eval();
316 
317  // --- Create calorimter eval stacks
318  CaloEvalStack emc_caloevalstack(topNode,"CLUSTER_CEMC");
319  CaloEvalStack hci_caloevalstack(topNode,"CLUSTER_HCALIN");
320  CaloEvalStack hco_caloevalstack(topNode,"CLUSTER_HCALOUT");
321  // --- get the evaluator objects
322  CaloRawClusterEval *emc_rawclustereval = emc_caloevalstack.get_rawcluster_eval();
323  CaloRawClusterEval *hci_rawclustereval = hci_caloevalstack.get_rawcluster_eval();
324  CaloRawClusterEval *hco_rawclustereval = hco_caloevalstack.get_rawcluster_eval();
325  emc_rawclustereval->set_verbosity(0); // temp while resolving issues
326  hci_rawclustereval->set_verbosity(0); // temp while resolving issues
327  hco_rawclustereval->set_verbosity(0); // temp while resolving issues
328 
329  if ( verbosity > 0 || ( !clusters_available && verbosity > -1 ) )
330  {
331  cout << "Eval stack memory addresses..." << endl;
332  cout << &svtxevalstack << endl;
333  cout << &emc_caloevalstack << endl;
334  cout << &hci_caloevalstack << endl;
335  cout << &hco_caloevalstack << endl;
336  cout << "Evaluator addresses..." << endl;
337  cout << trackeval << endl;
338  cout << emc_rawclustereval << endl;
339  cout << hci_rawclustereval << endl;
340  cout << hco_rawclustereval << endl;
341  }
342 
343  if ( verbosity > 0 ) cout << "Now going to loop over truth partcles..." << endl; // need verbosity switch
344 
345  // --- Loop over all truth particles
347  for ( PHG4TruthInfoContainer::ConstIterator iter = range.first; iter != range.second; ++iter )
348  {
349  PHG4Particle* g4particle = iter->second; // You may ask yourself, why second?
350  // In C++ the iterator is a map, which has two members
351  // first is the key (analogous the index of an arry),
352  // second is the value (analogous to the value stored for the array index)
353  int particleID = g4particle->get_pid();
354 
355  if ( trutheval->get_embed(g4particle) <= 0 && fabs(particleID) == 11 && verbosity > 0 )
356  {
357  cout << "NON EMBEDDED ELECTRON!!! WHEE!!! " << particleID << " " << iter->first << endl;
358  }
359 
360  if ( trutheval->get_embed(g4particle) <= 0 ) continue; // only look at embedded particles // no good for hits files
361  bool iselectron = fabs(particleID) == 11;
362  bool ispion = fabs(particleID) == 211;
363  if ( verbosity > 0 ) cout << "embedded particle ID is " << particleID << " ispion " << ispion << " iselectron " << iselectron << " " << iter->first << endl;
364 
365  set<PHG4Hit*> g4hits = trutheval->all_truth_hits(g4particle);
366  //float ng4hits = g4hits.size();
367 
368  float truept = sqrt(pow(g4particle->get_px(),2)+pow(g4particle->get_py(),2));
369  float true_energy = g4particle->get_e();
370 
371  // --- Get the reconsructed SvtxTrack based on the best candidate from the truth info
372  SvtxTrack* track = trackeval->best_track_from(g4particle);
373  if (!track) continue;
374  float recopt = track->get_pt();
375  //float recop = track->get_p();
376 
377  if ( verbosity > 0 )
378  {
379  cout << "truept is " << truept << endl;
380  cout << "recopt is " << recopt << endl;
381  cout << "true energy is " << true_energy << endl;
382  }
383 
384  // ----------------------------------------------------------------------
385  // ----------------------------------------------------------------------
386  // ----------------------------------------------------------------------
387 
388  // --- Get the clusters from the best candidate from the truth info using the eval
389  RawCluster* emc_bestcluster = NULL;
390  RawCluster* hci_bestcluster = NULL;
391  RawCluster* hco_bestcluster = NULL;
392  if ( emc_rawclustereval ) emc_bestcluster = emc_rawclustereval->best_cluster_from(g4particle);
393  if ( hci_rawclustereval ) hci_bestcluster = hci_rawclustereval->best_cluster_from(g4particle);
394  if ( hco_rawclustereval ) hco_bestcluster = hco_rawclustereval->best_cluster_from(g4particle);
395 
396  if ( verbosity > 5 )
397  {
398  cout << "Cluster addresses from best cluster " << endl;
399  cout << emc_bestcluster << endl;
400  cout << hci_bestcluster << endl;
401  cout << hco_bestcluster << endl;
402  }
403 
404  // --- If that didn't work, take the largest cluster in the event
405  // --- This is terrible for more than one particle, so I need to
406  // --- develop my own track-cluster association...
407  if ( !emc_bestcluster && emc_clusters.size() ) emc_bestcluster = emc_clusters[0];
408  if ( !hci_bestcluster && hci_clusters.size() ) hci_bestcluster = hci_clusters[0];
409  if ( !hco_bestcluster && hco_clusters.size() ) hco_bestcluster = hco_clusters[0];
410 
411  if ( verbosity > 5 )
412  {
413  cout << "Cluster addresses from my (very bad) association " << endl;
414  cout << emc_bestcluster << endl;
415  cout << hci_bestcluster << endl;
416  cout << hco_bestcluster << endl;
417  }
418 
419  // --- Get a vector of the towers from the cluster
420  vector<RawTower*> emc_towers_from_bestcluster = get_ordered_towers(emc_bestcluster,emc_towercontainer);
421  vector<RawTower*> hci_towers_from_bestcluster = get_ordered_towers(hci_bestcluster,hci_towercontainer);
422  vector<RawTower*> hco_towers_from_bestcluster = get_ordered_towers(hco_bestcluster,hco_towercontainer);
423 
424  // --- Inspect the towers (fills a bunch of histograms, prints to screen if verbose)
425  inspect_ordered_towers(emc_towers_from_bestcluster,true_energy,SvtxTrack::CEMC);
426  inspect_ordered_towers(hci_towers_from_bestcluster,true_energy,SvtxTrack::HCALIN);
427  inspect_ordered_towers(hco_towers_from_bestcluster,true_energy,SvtxTrack::HCALOUT);
428 
429  // ----------------------------------------------------------------------
430  // ----------------------------------------------------------------------
431  // ----------------------------------------------------------------------
432 
433 
434 
435  // --- energy variables from the best candidate clusters
436  float emc_energy_best = -9999;
437  float hci_energy_best = -9999;
438  float hco_energy_best = -9999;
439 
440  // --- energy variables directly from the track object
441  float emc_energy_track = -9999;
442  float hci_energy_track = -9999;
443  float hco_energy_track = -9999;
444 
445  if ( verbosity > 2 ) cout << "Now attempting to get the energies..." << endl;
446 
447  // --- get the energy values directly from the best candidate IF the cluster container exists
448  if ( emc_bestcluster ) emc_energy_best = emc_bestcluster->get_energy();
449  if ( hci_bestcluster ) hci_energy_best = hci_bestcluster->get_energy();
450  if ( hco_bestcluster ) hco_energy_best = hco_bestcluster->get_energy();
451 
452  if ( verbosity > 5 )
453  {
454  cout << "emc_energy_best is " << emc_energy_best << endl;
455  cout << "hci_energy_best is " << hci_energy_best << endl;
456  cout << "hco_energy_best is " << hco_energy_best << endl;
457  }
458 
459  // --- get the energy values directly from the track IF the cluster container exists
460  if ( emc_clustercontainer ) emc_energy_track = track->get_cal_cluster_e(SvtxTrack::CEMC);
461  if ( hci_clustercontainer ) hci_energy_track = track->get_cal_cluster_e(SvtxTrack::HCALIN);
462  if ( hco_clustercontainer ) hco_energy_track = track->get_cal_cluster_e(SvtxTrack::HCALOUT);
463 
464  if ( verbosity > 5 )
465  {
466  cout << "emc_energy_track is " << emc_energy_track << endl;
467  cout << "hci_energy_track is " << hci_energy_track << endl;
468  cout << "hco_energy_track is " << hco_energy_track << endl;
469  }
470 
471  // -------------------------------------------------------------------------------------
472  // --- IMPORTANT NOTE: according to Jin, the clusterizing will gather all towers in the
473  // --- calorimeter, so we need to use the 3x3 instead
474 
475  if ( emc_clustercontainer ) emc_energy_track = track->get_cal_energy_3x3(SvtxTrack::CEMC);
476  if ( hci_clustercontainer ) hci_energy_track = track->get_cal_energy_3x3(SvtxTrack::HCALIN);
477  if ( hco_clustercontainer ) hco_energy_track = track->get_cal_energy_3x3(SvtxTrack::HCALOUT);
478 
479  if ( verbosity > 0 )
480  {
481  cout << "emc_energy_track is " << emc_energy_track << endl;
482  cout << "hci_energy_track is " << hci_energy_track << endl;
483  cout << "hco_energy_track is " << hco_energy_track << endl;
484  }
485 
486  // -------------------------------------------------------------------------------------
487  // --- IMPORTANT NOTE: according to Jin, dphi and deta will not work correctly in HIJING
488 
489  float emc_dphi_track = -9999;
490  float hci_dphi_track = -9999;
491  float hco_dphi_track = -9999;
492  if ( emc_clustercontainer ) emc_dphi_track = track->get_cal_dphi(SvtxTrack::CEMC);
493  if ( hci_clustercontainer ) hci_dphi_track = track->get_cal_dphi(SvtxTrack::HCALIN);
494  if ( hco_clustercontainer ) hco_dphi_track = track->get_cal_dphi(SvtxTrack::HCALOUT);
495 
496  float emc_deta_track = -9999;
497  float hci_deta_track = -9999;
498  float hco_deta_track = -9999;
499  if ( emc_clustercontainer ) emc_deta_track = track->get_cal_deta(SvtxTrack::CEMC);
500  if ( hci_clustercontainer ) hci_deta_track = track->get_cal_deta(SvtxTrack::HCALIN);
501  if ( hco_clustercontainer ) hco_deta_track = track->get_cal_deta(SvtxTrack::HCALOUT);
502 
503  _energy_dphi_emc->Fill(true_energy,emc_dphi_track);
504  _energy_dphi_hci->Fill(true_energy,hci_dphi_track);
505  _energy_dphi_hco->Fill(true_energy,hco_dphi_track);
506 
507  _energy_deta_emc->Fill(true_energy,emc_deta_track);
508  _energy_deta_hci->Fill(true_energy,hci_deta_track);
509  _energy_deta_hco->Fill(true_energy,hco_deta_track);
510 
511  float assoc_dphi = 0.1; // adjust as needed, consider class set method
512  float assoc_deta = 0.1; // adjust as needed, consider class set method
513  bool good_emc_assoc = fabs(emc_dphi_track) < assoc_dphi && fabs(emc_deta_track) < assoc_deta;
514  bool good_hci_assoc = fabs(hci_dphi_track) < assoc_dphi && fabs(hci_deta_track) < assoc_deta;
515  bool good_hco_assoc = fabs(hco_dphi_track) < assoc_dphi && fabs(hco_deta_track) < assoc_deta;
516 
517  // ------------------------------------------------------------------------------------------
518 
519  // --- check the variables
520  if ( verbosity > 3 )
521  {
522  cout << "emc_energy_best is " << emc_energy_best << endl;
523  cout << "hci_energy_best is " << hci_energy_best << endl;
524  cout << "hco_energy_best is " << hco_energy_best << endl;
525  cout << "emc_energy_track is " << emc_energy_track << endl;
526  cout << "hci_energy_track is " << hci_energy_track << endl;
527  cout << "hco_energy_track is " << hco_energy_track << endl;
528  cout << "emc_dphi_track is " << emc_dphi_track << endl;
529  cout << "hci_dphi_track is " << hci_dphi_track << endl;
530  cout << "hco_dphi_track is " << hco_dphi_track << endl;
531  cout << "emc_deta_track is " << emc_deta_track << endl;
532  cout << "hci_deta_track is " << hci_deta_track << endl;
533  cout << "hco_deta_track is " << hco_deta_track << endl;
534  } // check on verbosity
535 
536  float hct_energy_track = 0;
537  if ( hci_energy_track >= 0 ) hct_energy_track += hci_energy_track;
538  if ( hco_energy_track >= 0 ) hct_energy_track += hco_energy_track;
539 
540  float total_energy_dumb = 0;
541  if ( emc_energy_track >= 0 ) total_energy_dumb += emc_energy_track;
542  if ( hci_energy_track >= 0 ) total_energy_dumb += hci_energy_track;
543  if ( hco_energy_track >= 0 ) total_energy_dumb += hco_energy_track;
544 
545  float total_energy_smart = 0;
546  if ( good_emc_assoc ) total_energy_smart += emc_energy_track;
547  if ( good_hci_assoc ) total_energy_smart += hci_energy_track;
548  if ( good_hco_assoc ) total_energy_smart += hco_energy_track;
549 
550 
551 
552  float emc_eratio = emc_energy_track/true_energy;
553  float hci_eratio = hci_energy_track/true_energy;
554  float hco_eratio = hco_energy_track/true_energy;
555  float hct_eratio = hct_energy_track/true_energy;
556  float tot_dumb_eratio = total_energy_dumb/true_energy;
557  float tot_smart_eratio = total_energy_smart/true_energy;
558 
559  _energy_ratio_emc->Fill(true_energy,emc_eratio);
560  _energy_ratio_hci->Fill(true_energy,hci_eratio);
561  _energy_ratio_hco->Fill(true_energy,hco_eratio);
562  _energy_ratio_hct->Fill(true_energy,hct_eratio);
563  _energy_ratio_tot_dumb->Fill(true_energy,tot_dumb_eratio);
564  _energy_ratio_tot_smart->Fill(true_energy,tot_smart_eratio);
565 
566  if ( emc_eratio < 0.1 )
567  {
568  _energy_ratio_elb_emc->Fill(true_energy,emc_eratio);
569  _energy_ratio_elb_hci->Fill(true_energy,hci_eratio);
570  _energy_ratio_elb_hco->Fill(true_energy,hco_eratio);
571  _energy_ratio_elb_hct->Fill(true_energy,hct_eratio);
572  _energy_ratio_elb_tot_dumb->Fill(true_energy,tot_dumb_eratio);
573  _energy_ratio_elb_tot_smart->Fill(true_energy,tot_smart_eratio);
574  }
575 
576  if ( emc_eratio > 0.1 )
577  {
578  _energy_ratio_eub_emc->Fill(true_energy,emc_eratio);
579  _energy_ratio_eub_hci->Fill(true_energy,hci_eratio);
580  _energy_ratio_eub_hco->Fill(true_energy,hco_eratio);
581  _energy_ratio_eub_hct->Fill(true_energy,hct_eratio);
582  _energy_ratio_eub_tot_dumb->Fill(true_energy,tot_dumb_eratio);
583  _energy_ratio_eub_tot_smart->Fill(true_energy,tot_smart_eratio);
584  }
585 
586  // ----------------------------------------------------------------------
587  // ----------------------------------------------------------------------
588  // ----------------------------------------------------------------------
589 
590  //cout << "starting the main part of the truth analysis" << endl;
591 
592  } // end of loop over truth particles
593 
594 
595 
597 
598 }
599 
600 
601 
603 {
604  cout << "End called, " << nevents << " events processed with " << nerrors << " errors and " << nwarnings << " warnings." << endl;
605  return 0;
606 }
607 
608 
609 
610 // --- not sure if it's possible but it'd be nice to do some better function polymorphism here
612 {
613 
614  if ( clusters == NULL ) return vector<RawCluster*>();
615 
616  // getClusters has two options, const and non const, so I use const here
617  auto range = clusters->getClusters();
618 
619  map<double,RawCluster*> cluster_map;
620  for ( auto it = range.first; it != range.second; ++it )
621  {
622  RawCluster* cluster = it->second;
623  double energy = cluster->get_energy();
624  cluster_map.insert(make_pair(energy,cluster));
625  }
626 
627  vector<RawCluster*> cluster_list;
628  for ( auto rit = cluster_map.rbegin(); rit != cluster_map.rend(); ++rit )
629  {
630  RawCluster* cluster = rit->second;
631  cluster_list.push_back(cluster);
632  }
633 
634  return cluster_list;
635 
636 }
637 
638 
639 
640 // --- not sure if it's possible but it'd be nice to do some better function polymorphism here
642 {
643 
644  if ( towers == NULL ) return vector<RawTower*>();
645 
646  // getTowers has two options, const and non const, so I use const here
647  auto range = towers->getTowers();
648 
649  map<double,RawTower*> tower_map;
650  for ( auto it = range.first; it != range.second; ++it )
651  {
652  RawTower* tower = it->second;
653  double energy = tower->get_energy();
654  tower_map.insert(make_pair(energy,tower));
655  }
656 
657  vector<RawTower*> tower_list;
658  for ( auto rit = tower_map.rbegin(); rit != tower_map.rend(); ++rit )
659  {
660  RawTower* tower = rit->second;
661  tower_list.push_back(tower);
662  }
663 
664  return tower_list;
665 
666 }
667 
668 
669 
670 // --- not sure if it's possible but it'd be nice to do some better function polymorphism here
672 {
673 
674  if ( cluster == NULL || towers == NULL ) return vector<RawTower*>();
675 
676  // note that RawCluster* cannot be const, get_towers is not declared as const function in class header
677  auto range = cluster->get_towers();
678 
679  multimap<double,RawTower*> tower_map;
680  for ( auto it = range.first; it != range.second; ++it )
681  {
682  // note that RawTowerContainer cannot be const, getTower is not declared as a const function in class header
683  RawTower* tower = towers->getTower(it->first);
684  double energy = tower->get_energy();
685  tower_map.insert(make_pair(energy,tower));
686  }
687 
688  vector<RawTower*> tower_list;
689  for ( auto rit = tower_map.rbegin(); rit != tower_map.rend(); ++rit )
690  {
691  RawTower* tower = rit->second;
692  tower_list.push_back(tower);
693  }
694 
695  return tower_list;
696 
697 }
698 
699 
700 
701 void STACalorimeterCharacterization::inspect_ordered_towers(const vector<RawTower*>& towers)
702 {
703  inspect_ordered_towers(towers,0,0);
704 }
705 
706 
707 
708 void STACalorimeterCharacterization::inspect_ordered_towers(const vector<RawTower*>& towers, int calo_layer)
709 {
710  inspect_ordered_towers(towers,0,calo_layer);
711 }
712 
713 
714 
715 void STACalorimeterCharacterization::inspect_ordered_towers(const vector<RawTower*>& towers, double true_energy, int calo_layer)
716 {
717 
718  if ( towers.size() == 0 ) return;
719 
720  int nphi = 9999;
721 
722  if ( calo_layer == SvtxTrack::CEMC ) nphi = 256;
723  if ( calo_layer == SvtxTrack::HCALIN ) nphi = 64;
724  if ( calo_layer == SvtxTrack::HCALOUT ) nphi = 64;
725 
726  RawTower* ctower = towers[0]; // central tower
727 
728  for ( unsigned int i = 0; i < towers.size(); ++i )
729  {
730  RawTower* itower = towers[i];
731  double ienergy = itower->get_energy();
732 
733  // if ( verbosity > 5 ) cout << "energy is " << ienergy << " tower address is " << itower << endl;
734 
735  // get the coordinates
736  int etabin_center = ctower->get_bineta();
737  int phibin_center = ctower->get_binphi();
738  int etabin = itower->get_bineta();
739  int phibin = itower->get_binphi();
740  // recenter around central tower
741  etabin -= etabin_center;
742  phibin -= phibin_center;
743  // boundary and periodicity corrections...
744  if ( phibin > nphi/2 ) phibin -= nphi;
745  if ( phibin < -nphi/2 ) phibin += nphi;
746  // if ( verbosity > 6 ) cout << "eta phi coordinates relative to central tower " << etabin << " " << phibin << endl;
747 
748  // fill some 2d coordinate space histograms
749  if ( calo_layer == SvtxTrack::CEMC)
750  {
751  _towers_3x3_emc->Fill(etabin,phibin,ienergy/true_energy);
752  _towers_5x5_emc->Fill(etabin,phibin,ienergy/true_energy);
753  _towers_7x7_emc->Fill(etabin,phibin,ienergy/true_energy);
754  _towers_9x9_emc->Fill(etabin,phibin,ienergy/true_energy);
755  }
756  if ( calo_layer == SvtxTrack::HCALIN)
757  {
758  _towers_3x3_hci->Fill(etabin,phibin,ienergy/true_energy);
759  _towers_5x5_hci->Fill(etabin,phibin,ienergy/true_energy);
760  _towers_7x7_hci->Fill(etabin,phibin,ienergy/true_energy);
761  _towers_9x9_hci->Fill(etabin,phibin,ienergy/true_energy);
762  }
763  if ( calo_layer == SvtxTrack::HCALOUT)
764  {
765  _towers_3x3_hco->Fill(etabin,phibin,ienergy/true_energy);
766  _towers_5x5_hco->Fill(etabin,phibin,ienergy/true_energy);
767  _towers_7x7_hco->Fill(etabin,phibin,ienergy/true_energy);
768  _towers_9x9_hco->Fill(etabin,phibin,ienergy/true_energy);
769  }
770 
771  } // loop over towers
772 
773  // characterize the tower energy with the truth energy
774  double energy_sumtower[10] = {0};
775  double energy_singletower = 0;
776  unsigned int nloop = 10;
777  if ( towers.size() < nloop ) nloop = towers.size();
778  for ( unsigned int i = 0; i < nloop; ++i )
779  {
780  // get the single and summed tower energies
781  energy_singletower = towers[i]->get_energy();
782  energy_sumtower[i] = energy_singletower;
783  for ( unsigned int j = i; j > 0; --j ) energy_sumtower[j] += energy_sumtower[j-1];
784 
785  // if ( verbosity > 5 )
786  // {
787  // cout << "inspecting tower energies" << endl;
788  // cout << "single tower energy is " << energy_singletower << endl;
789  // cout << "sum tower energy is " << energy_sumtower[i] << endl;
790  // }
791 
792  // fill histograms
793  if ( calo_layer == SvtxTrack::CEMC )
794  {
795  _tower_energy_emc[i]->Fill(true_energy,energy_singletower/true_energy);
796  _towersum_energy_emc[i]->Fill(true_energy,energy_sumtower[i]/true_energy);
797  }
798  if ( calo_layer == SvtxTrack::HCALIN )
799  {
800  _tower_energy_hci[i]->Fill(true_energy,energy_singletower/true_energy);
801  _towersum_energy_hci[i]->Fill(true_energy,energy_sumtower[i]/true_energy);
802  }
803  if ( calo_layer == SvtxTrack::HCALOUT )
804  {
805  _tower_energy_hco[i]->Fill(true_energy,energy_singletower/true_energy);
806  _towersum_energy_hco[i]->Fill(true_energy,energy_sumtower[i]/true_energy);
807  }
808  } // fixed size loop
809 
810 } // inspect_ordered_towers