Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4HcalCellReco.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4HcalCellReco.cc
1 #include "PHG4HcalCellReco.h"
2 
3 #include "PHG4Cell.h" // for PHG4Cell
4 #include "PHG4CellContainer.h"
5 #include "PHG4CellDefs.h" // for genkey, keytype
6 #include "PHG4Cellv1.h"
7 
8 #include <phparameter/PHParameterInterface.h> // for PHParameterInterface
9 
10 #include <g4main/PHG4Hit.h>
12 #include <g4main/PHG4HitDefs.h> // for hit_idbits
13 
15 #include <fun4all/SubsysReco.h> // for SubsysReco
16 
17 #include <phool/PHCompositeNode.h>
18 #include <phool/PHIODataNode.h>
19 #include <phool/PHNode.h> // for PHNode
20 #include <phool/PHNodeIterator.h>
21 #include <phool/PHObject.h> // for PHObject
22 #include <phool/getClass.h>
23 #include <phool/phool.h> // for PHWHERE
24 
25 #include <TSystem.h>
26 
27 #include <array> // for array, array<>::value_...
28 #include <cmath>
29 #include <cstdlib>
30 #include <iostream>
31 #include <map> // for _Rb_tree_const_iterator
32 #include <sstream>
33 #include <utility> // for pair
34 
35 // for hcal dimension
36 #define ROWDIM 320
37 #define COLUMNDIM 27
38 
39 static std::array<std::array<PHG4Cell *, COLUMNDIM>, ROWDIM> slatarray = {{{nullptr}}};
40 
42  : SubsysReco(name)
43  , PHParameterInterface(name)
44 {
46 }
47 
49 {
50  PHNodeIterator iter(topNode);
51 
52  // Looking for the DST node
53  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
54  if (!dstNode)
55  {
56  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
57  exit(1);
58  }
59  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
60  PHCompositeNode *parNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "PAR"));
61 
62  std::string paramnodename = "G4CELLPARAM_" + detector;
63  std::string geonodename = "G4CELLGEO_" + detector;
64  hitnodename = "G4HIT_" + detector;
65  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
66  if (!g4hit)
67  {
68  std::cout << Name() << " Could not locate G4HIT node " << hitnodename << std::endl;
69  topNode->print();
70  gSystem->Exit(1);
71  exit(1);
72  }
73  cellnodename = "G4CELL_" + detector;
74  PHG4CellContainer *slats = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
75  if (!slats)
76  {
77  PHNodeIterator dstiter(dstNode);
78  PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", detector));
79  if (!DetNode)
80  {
81  DetNode = new PHCompositeNode(detector);
82  dstNode->addNode(DetNode);
83  }
84  slats = new PHG4CellContainer();
85  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(slats, cellnodename, "PHObject");
86  DetNode->addNode(newNode);
87  }
89  // save this to the run wise tree to store on DST
90  PHNodeIterator runIter(runNode);
91  PHCompositeNode *RunDetNode = dynamic_cast<PHCompositeNode *>(runIter.findFirst("PHCompositeNode", detector));
92  if (!RunDetNode)
93  {
94  RunDetNode = new PHCompositeNode(detector);
95  runNode->addNode(RunDetNode);
96  }
97  SaveToNodeTree(RunDetNode, paramnodename);
98  // save this to the parNode for use
99  PHNodeIterator parIter(parNode);
100  PHCompositeNode *ParDetNode = dynamic_cast<PHCompositeNode *>(parIter.findFirst("PHCompositeNode", detector));
101  if (!ParDetNode)
102  {
103  ParDetNode = new PHCompositeNode(detector);
104  parNode->addNode(ParDetNode);
105  }
106  PutOnParNode(ParDetNode, geonodename);
107  tmin = get_double_param("tmin");
108  tmax = get_double_param("tmax");
109  m_DeltaT = get_double_param("delta_t");
111 }
112 
114 {
115  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
116  if (!g4hit)
117  {
118  std::cout << "Could not locate g4 hit node " << hitnodename << std::endl;
119  exit(1);
120  }
121  PHG4CellContainer *slats = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
122  if (!slats)
123  {
124  std::cout << "could not locate cell node " << cellnodename << std::endl;
125  exit(1);
126  }
127  if (std::isfinite(m_FixedEnergy))
128  {
129  int maxcolumn = 24;
130  int maxrow = 320;
131  if (detector == "HCALIN")
132  {
133  maxrow = 256;
134  }
135  for (int icolumn = 0; icolumn < maxcolumn; icolumn++)
136  {
137  for (int irow = 0; irow < maxrow; irow++)
138  {
140  PHG4Cell *cell = new PHG4Cellv1(key);
141  cell->add_edep(m_FixedEnergy);
142  cell->add_eion(m_FixedEnergy);
145  slats->AddCell(cell);
146  }
147  }
149  }
151  PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits();
152  for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; ++hiter)
153  {
154  if (hiter->second->get_t(0) > tmax) continue;
155  if (hiter->second->get_t(1) < tmin) continue;
156  if (hiter->second->get_t(1) - hiter->second->get_t(0) > m_DeltaT) continue;
157 
158  short icolumn = hiter->second->get_scint_id();
159  int introw = (hiter->second->get_hit_id() >> PHG4HitDefs::hit_idbits);
160  if (introw >= ROWDIM || introw < 0)
161  {
162  std::cout << __PRETTY_FUNCTION__ << " row " << introw
163  << " exceed array size: " << ROWDIM
164  << " adjust ROWDIM and recompile" << std::endl;
165  exit(1);
166  }
167  // after checking for size of introw so we do not run into
168  // overflow issues, put this into the short we want later
169  short irow = introw;
170  if (icolumn >= COLUMNDIM || icolumn < 0)
171  {
172  std::cout << __PRETTY_FUNCTION__ << " column: " << icolumn
173  << " exceed array size: " << COLUMNDIM
174  << " adjust COLUMNDIM and recompile" << std::endl;
175  exit(1);
176  }
177 
178  if (!slatarray[irow][icolumn])
179  {
180  // hcal has no layers so far, I do not want to make an expensive
181  // call to the g4hits to find that out use 0 as layer number
183  slatarray[irow][icolumn] = new PHG4Cellv1(key);
184  }
185  slatarray[irow][icolumn]->add_edep(hiter->second->get_edep());
186  slatarray[irow][icolumn]->add_eion(hiter->second->get_eion());
187  slatarray[irow][icolumn]->add_light_yield(hiter->second->get_light_yield());
188  float raw_light = hiter->second->get_raw_light_yield();
189  if (std::isfinite(raw_light))
190  {
191  slatarray[irow][icolumn]->add_raw_light_yield(raw_light);
192  }
193  slatarray[irow][icolumn]->add_edep(hiter->first, hiter->second->get_edep());
194  slatarray[irow][icolumn]->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep());
195  } // end loop over g4hits
196  int nslathits = 0;
197  for (int irow = 0; irow < ROWDIM; irow++)
198  {
199  for (int icolumn = 0; icolumn < COLUMNDIM; icolumn++)
200  {
201  if (slatarray[irow][icolumn])
202  {
203  slats->AddCell(slatarray[irow][icolumn]);
204  slatarray[irow][icolumn] = nullptr;
205  nslathits++;
206  }
207  }
208  }
209  if (Verbosity() > 0)
210  {
211  std::cout << Name() << ": found " << nslathits << " slats with energy deposition" << std::endl;
212  }
213 
215  {
216  CheckEnergy(topNode);
217  }
219 }
220 
222 {
223  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
224  PHG4CellContainer *slats = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
225  double sum_energy_g4hit = 0.;
226  double sum_energy_cells = 0.;
227  PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits();
229  for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; ++hiter)
230  {
231  sum_energy_g4hit += hiter->second->get_edep();
232  }
233  PHG4CellContainer::ConstRange cell_begin_end = slats->getCells();
235  for (citer = cell_begin_end.first; citer != cell_begin_end.second; ++citer)
236  {
237  sum_energy_cells += citer->second->get_edep();
238  }
239  // the fractional eloss for particles traversing eta bins leads to minute rounding errors
240  if (fabs(sum_energy_cells - sum_energy_g4hit) / sum_energy_g4hit > 1e-6)
241  {
242  std::cout << "hint: timing cuts tmin/tmax will do this to you" << std::endl;
243  std::cout << "energy mismatch between cells: " << sum_energy_cells
244  << " and hits: " << sum_energy_g4hit
245  << " diff sum(cells) - sum(hits): " << sum_energy_cells - sum_energy_g4hit
246  << std::endl;
247  return -1;
248  }
249  else
250  {
251  if (Verbosity() > 0)
252  {
253  std::cout << Name() << ": total energy for this event: " << sum_energy_g4hit << " GeV" << std::endl;
254  }
255  }
256  return 0;
257 }
258 
260 {
261  set_default_double_param("tmax", 60.0);
262  set_default_double_param("tmin", -20.0); // collision has a timing spread around the triggered event. Accepting negative time too.
263  set_default_double_param("delta_t", 100.);
264  return;
265 }
266 
267 void PHG4HcalCellReco::set_timing_window(const double tmi, const double tma)
268 {
269  set_double_param("tmin", tmi);
270  set_double_param("tmax", tma);
271 }