Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RawTowerBuilder.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RawTowerBuilder.cc
1 #include "RawTowerBuilder.h"
2 
3 #include <calobase/RawTower.h> // for RawTower
4 #include <calobase/RawTowerContainer.h>
5 #include <calobase/RawTowerDefs.h> // for encode_towerid
6 #include <calobase/RawTowerGeom.h> // for RawTowerGeom
7 #include <calobase/RawTowerGeomContainer.h> // for RawTowerGeomC...
8 #include <calobase/RawTowerGeomContainer_Cylinderv1.h>
9 #include <calobase/RawTowerGeomv1.h>
10 #include <calobase/RawTowerv1.h>
11 #include <calobase/TowerInfoContainer.h>
12 #include <calobase/TowerInfoContainerv1.h>
13 #include <calobase/TowerInfo.h>
14 
17 #include <g4detectors/PHG4Cell.h>
20 
21 #include <g4main/PHG4Utils.h>
22 
24 #include <fun4all/SubsysReco.h> // for SubsysReco
25 
26 #include <phool/PHCompositeNode.h>
27 #include <phool/PHIODataNode.h>
28 #include <phool/PHNode.h> // for PHNode
29 #include <phool/PHNodeIterator.h>
30 #include <phool/PHObject.h> // for PHObject
31 #include <phool/getClass.h>
32 #include <phool/phool.h> // for PHWHERE
33 
34 #include <boost/io/ios_state.hpp>
35 
36 #include <cmath> // for fabs, tan, atan2
37 #include <cstdlib> // for exit
38 #include <exception> // for exception
39 #include <iostream>
40 #include <map>
41 #include <stdexcept>
42 #include <utility> // for pair, make_pair
43 
45  : SubsysReco(name)
46 {
47 }
48 
50 {
51  std::string geonodename = "CYLINDERCELLGEOM_" + m_Detector;
52  PHG4CylinderCellGeomContainer *cellgeos = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode, geonodename);
53  if (!cellgeos)
54  {
55  std::cout << PHWHERE << " " << geonodename
56  << " Node missing, doing nothing." << std::endl;
57  throw std::runtime_error(
58  "Failed to find " + geonodename + " node in RawTowerBuilder::CreateNodes");
59  }
60 
61  // fill the number of layers in the calorimeter
62  m_NumLayers = cellgeos->get_NLayers();
63 
64  PHNodeIterator iter(topNode);
65 
66  // Looking for the DST node
67  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
68  if (!dstNode)
69  {
70  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
71  exit(1);
72  }
73 
74  try
75  {
76  CreateNodes(topNode);
77  }
78  catch (std::exception &e)
79  {
80  std::cout << e.what() << std::endl;
81  //exit(1);
82  }
83 
84  if (Verbosity() >= 1)
85  {
86  std::cout << "RawTowerBuilder::InitRun :";
88  {
89  std::cout << "save Geant4 energy deposition as the weight of the cells"
90  << std::endl;
91  }
93  {
94  std::cout << "save light yield as the weight of the cells" << std::endl;
95  }
96  }
98 }
99 
101 {
102  if (Verbosity())
103  {
104  std::cout << PHWHERE << "Process event entered" << std::endl;
105  }
106 
107  //load get TowerInfoContainer node from node tree:
108  TowerInfoContainer* m_TowerInfoContainer = findNode::getClass<TowerInfoContainer>(topNode,m_TowerInfoNodeName);
109  if (!m_TowerInfoContainer && m_UseTowerInfo > 0)
110  {
111  std::cout << PHWHERE << "TowerInfoContainer Node missing, doing nothing." << std::endl;
112  exit(1);
113  }
114 
115  // get cells
116  std::string cellnodename = "G4CELL_" + m_Detector;
117  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
118  if (!cells)
119  {
120  std::cout << PHWHERE << " " << cellnodename
121  << " Node missing, doing nothing." << std::endl;
123  }
124 
125  // loop over all cells in an event
127  PHG4CellContainer::ConstRange cell_range = cells->getCells();
128  for (cell_iter = cell_range.first; cell_iter != cell_range.second; ++cell_iter)
129  {
130  PHG4Cell *cell = cell_iter->second;
131 
132  if (Verbosity() > 2)
133  {
134  std::cout << PHWHERE << " print out the cell:" << std::endl;
135  cell->identify();
136  }
137 
138 
139  //Calculate the cell weight
140  float cell_weight = 0;
142  {
143  cell_weight = cell->get_edep();
144  }
145  else if (m_TowerEnergySrcEnum == kLightYield)
146  {
147  cell_weight = cell->get_light_yield();
148  }
149 
150 
151  // add the energy to the corresponding tower
152  if (m_UseTowerInfo != 1)
153  {
154  RawTower *tower = nullptr;
155  short int firstpar;
156  short int secondpar;
158  {
161  }
163  {
166  }
167  else
168  {
169  boost::io::ios_flags_saver ifs(std::cout);
170  std::cout << "unknown cell binning, implement 0x" << std::hex << PHG4CellDefs::get_binning(cell->get_cellid()) << std::dec << std::endl;
171  exit(1);
172  }
173  tower = m_TowerContainer->getTower(firstpar, secondpar);
174  if (!tower)
175  {
176  tower = new RawTowerv1();
177  tower->set_energy(0);
178  m_TowerContainer->AddTower(firstpar, secondpar, tower);
179  }
180 
181  tower->add_ecell(cell->get_cellid(), cell_weight);
182 
184  for (PHG4Cell::ShowerEdepConstIterator shower_iter = range.first;
185  shower_iter != range.second;
186  ++shower_iter)
187  {
188  tower->add_eshower(shower_iter->first, shower_iter->second);
189  }
190 
191  tower->set_energy(tower->get_energy() + cell_weight);
192 
193  if (Verbosity() > 2)
194  {
195  m_RawTowerGeomContainer = findNode::getClass<RawTowerGeomContainer>(topNode, m_TowerGeomNodeName);
196  tower->identify();
197  }
198  }
199  if (m_UseTowerInfo > 0)
200  {
201  TowerInfo *towerinfo;
202  unsigned int etabin;
203  unsigned int phibin;
205  {
208  }
209  else
210  {
211  boost::io::ios_flags_saver ifs(std::cout);
212  std::cout << "unknown cell binning, implement 0x" << std::hex << PHG4CellDefs::get_binning(cell->get_cellid()) << std::dec << std::endl;
213  exit(1);
214  }
215  unsigned int towerkey = (etabin << 16U) + phibin;
216  // unsigned int towerindex = m_TowerInfoContainer->decode_key(towerkey);
217  towerinfo = m_TowerInfoContainer->get_tower_at_key(towerkey);
218  if (!towerinfo)
219  {
220  std::cout << __PRETTY_FUNCTION__ << ": missing towerkey = " << towerkey << " in m_TowerInfoContainer!";
221  exit(1);
222  }
223  else
224  {
225  towerinfo->set_energy(towerinfo->get_energy() + cell_weight);
226  }
227  }
228  }
229 
230  if (m_UseTowerInfo != 1 )
231  {
232  double towerE = 0;
234  {
235  double cellE = cells->getTotalEdep();
236  towerE = m_TowerContainer->getTotalEdep();
237  if (fabs(cellE - towerE) / cellE > 1e-5)
238  {
239  std::cout << "towerE: " << towerE << ", cellE: " << cellE << ", delta: "
240  << cellE - towerE << std::endl;
241  }
242  }
243  if (Verbosity())
244  {
245  towerE = m_TowerContainer->getTotalEdep();
246  }
247 
249  if (Verbosity())
250  {
251  std::cout << "Energy lost by dropping towers with less than " << m_Emin
252  << " GeV energy, lost energy: " << towerE - m_TowerContainer->getTotalEdep()
253  << std::endl;
257  for (iter = begin_end.first; iter != begin_end.second; ++iter)
258  {
259  iter->second->identify();
260  }
261  }
262  }
264 }
265 
267 {
268  PHNodeIterator iter(topNode);
269  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "RUN"));
270  if (!runNode)
271  {
272  std::cout << PHWHERE << "Run Node missing, doing nothing." << std::endl;
273  throw std::runtime_error("Failed to find Run node in RawTowerBuilder::CreateNodes");
274  }
275 
276  PHNodeIterator runIter(runNode);
277  PHCompositeNode *RunDetNode = dynamic_cast<PHCompositeNode *>(runIter.findFirst("PHCompositeNode", m_Detector));
278  if (!RunDetNode)
279  {
280  RunDetNode = new PHCompositeNode(m_Detector);
281  runNode->addNode(RunDetNode);
282  }
283 
285 
286  // get the cell geometry and build up the tower geometry object
287  std::string geonodename = "CYLINDERCELLGEOM_" + m_Detector;
288  PHG4CylinderCellGeomContainer *cellgeos = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode, geonodename);
289  if (!cellgeos)
290  {
291  std::cout << PHWHERE << " " << geonodename
292  << " Node missing, doing nothing." << std::endl;
293  throw std::runtime_error(
294  "Failed to find " + geonodename + " node in RawTowerBuilder::CreateNodes");
295  }
296  m_TowerGeomNodeName = "TOWERGEOM_" + m_Detector;
297  m_RawTowerGeomContainer = findNode::getClass<RawTowerGeomContainer>(topNode, m_TowerGeomNodeName);
299  {
302  RunDetNode->addNode(newNode);
303  }
304  // fill the number of layers in the calorimeter
305  m_NumLayers = cellgeos->get_NLayers();
306 
307  // Create the tower nodes on the tree
310  cellgeos->get_begin_end();
311  int ifirst = 1;
312  int first_layer = -1;
313  PHG4CylinderCellGeom *first_cellgeo = nullptr;
314  double inner_radius = 0;
315  double thickness = 0;
316  for (miter = begin_end.first; miter != begin_end.second; ++miter)
317  {
318  PHG4CylinderCellGeom *cellgeo = miter->second;
319 
320  if (Verbosity())
321  {
322  cellgeo->identify();
323  }
324  thickness += cellgeo->get_thickness();
325  if (ifirst)
326  {
327  first_cellgeo = miter->second;
328  m_CellBinning = cellgeo->get_binning();
329  m_NumPhiBins = cellgeo->get_phibins();
330  m_PhiMin = cellgeo->get_phimin();
331  m_PhiStep = cellgeo->get_phistep();
333  {
334  m_NumEtaBins = cellgeo->get_etabins();
335  m_EtaMin = cellgeo->get_etamin();
336  m_EtaStep = cellgeo->get_etastep();
337  }
339  {
340  m_NumEtaBins = cellgeo->get_zbins(); // bin eta in the same number of z bins
341  }
343  {
344  // use eta definiton for each row of towers
345  m_NumEtaBins = cellgeo->get_etabins();
346  }
347  else
348  {
349  std::cout << "RawTowerBuilder::CreateNodes::" << Name()
350  << " - Fatal Error - unsupported cell binning method "
351  << m_CellBinning << std::endl;
352  }
353  inner_radius = cellgeo->get_radius();
354  first_layer = cellgeo->get_layer();
355  ifirst = 0;
356  }
357  else
358  {
359  if (m_CellBinning != cellgeo->get_binning())
360  {
361  std::cout << "inconsistent binning method from " << m_CellBinning
362  << " layer " << cellgeo->get_layer() << ": "
363  << cellgeo->get_binning() << std::endl;
364  exit(1);
365  }
366  if (inner_radius > cellgeo->get_radius())
367  {
368  std::cout << "radius of layer " << cellgeo->get_layer() << " is "
369  << cellgeo->get_radius() << " which smaller than radius "
370  << inner_radius << " of first layer in list " << first_layer
371  << std::endl;
372  }
373  if (m_NumPhiBins != cellgeo->get_phibins())
374  {
375  std::cout << "mixing number of phibins, fisrt layer: " << m_NumPhiBins
376  << " layer " << cellgeo->get_layer() << ": "
377  << cellgeo->get_phibins() << std::endl;
378  exit(1);
379  }
380  if (m_PhiMin != cellgeo->get_phimin())
381  {
382  std::cout << "mixing number of phimin, fisrt layer: " << m_PhiMin
383  << " layer " << cellgeo->get_layer() << ": "
384  << cellgeo->get_phimin() << std::endl;
385  exit(1);
386  }
387  if (m_PhiStep != cellgeo->get_phistep())
388  {
389  std::cout << "mixing phisteps first layer: " << m_PhiStep << " layer "
390  << cellgeo->get_layer() << ": " << cellgeo->get_phistep()
391  << " diff: " << m_PhiStep - cellgeo->get_phistep() << std::endl;
392  exit(1);
393  }
395  {
396  if (m_NumEtaBins != cellgeo->get_etabins())
397  {
398  std::cout << "mixing number of EtaBins , first layer: "
399  << m_NumEtaBins << " layer " << cellgeo->get_layer() << ": "
400  << cellgeo->get_etabins() << std::endl;
401  exit(1);
402  }
403  if (fabs(m_EtaMin - cellgeo->get_etamin()) > 1e-9)
404  {
405  std::cout << "mixing etamin, fisrt layer: " << m_EtaMin << " layer "
406  << cellgeo->get_layer() << ": " << cellgeo->get_etamin()
407  << " diff: " << m_EtaMin - cellgeo->get_etamin() << std::endl;
408  exit(1);
409  }
410  if (fabs(m_EtaStep - cellgeo->get_etastep()) > 1e-9)
411  {
412  std::cout << "mixing eta steps first layer: " << m_EtaStep
413  << " layer " << cellgeo->get_layer() << ": "
414  << cellgeo->get_etastep() << " diff: "
415  << m_EtaStep - cellgeo->get_etastep() << std::endl;
416  exit(1);
417  }
418  }
419 
421  {
422  if (m_NumEtaBins != cellgeo->get_zbins())
423  {
424  std::cout << "mixing number of z bins , first layer: " << m_NumEtaBins
425  << " layer " << cellgeo->get_layer() << ": "
426  << cellgeo->get_zbins() << std::endl;
427  exit(1);
428  }
429  }
430  }
431  }
432  m_RawTowerGeomContainer->set_radius(inner_radius);
435  // m_RawTowerGeomContainer->set_phistep(m_PhiStep);
436  // m_RawTowerGeomContainer->set_phimin(m_PhiMin);
438 
439  if (!first_cellgeo)
440  {
441  std::cout << "RawTowerBuilder::CreateNodes - ERROR - can not find first layer of cells "
442  << std::endl;
443 
444  exit(1);
445  }
446 
447  for (int ibin = 0; ibin < first_cellgeo->get_phibins(); ibin++)
448  {
449  const std::pair<double, double> range = first_cellgeo->get_phibounds(ibin);
450 
452  }
453 
455  {
456  const double r = inner_radius;
457 
458  for (int ibin = 0; ibin < first_cellgeo->get_etabins(); ibin++)
459  {
460  const std::pair<double, double> range = first_cellgeo->get_etabounds(ibin);
461 
463  }
464 
465  // setup location of all towers
466  for (int iphi = 0; iphi < m_RawTowerGeomContainer->get_phibins(); iphi++)
467  {
468  for (int ieta = 0; ieta < m_RawTowerGeomContainer->get_etabins(); ieta++)
469  {
470  const RawTowerDefs::keytype key =
471  RawTowerDefs::encode_towerid(caloid, ieta, iphi);
472 
473  const double x(r * cos(m_RawTowerGeomContainer->get_phicenter(iphi)));
474  const double y(r * sin(m_RawTowerGeomContainer->get_phicenter(iphi)));
475  const double z(r / tan(PHG4Utils::get_theta(m_RawTowerGeomContainer->get_etacenter(ieta))));
476 
478  if (tg)
479  {
480  if (Verbosity() > 0)
481  {
482  std::cout << "RawTowerBuilder::CreateNodes - Tower geometry " << key << " already exists" << std::endl;
483  }
484 
485  if (fabs(tg->get_center_x() - x) > 1e-4)
486  {
487  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x
488  << std::endl;
489 
490  exit(1);
491  }
492  if (fabs(tg->get_center_y() - y) > 1e-4)
493  {
494  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y
495  << std::endl;
496  exit(1);
497  }
498  if (fabs(tg->get_center_z() - z) > 1e-4)
499  {
500  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z
501  << std::endl;
502  exit(1);
503  }
504  }
505  else
506  {
507  if (Verbosity() > 0)
508  {
509  std::cout << "RawTowerBuilder::CreateNodes - building tower geometry " << key << "" << std::endl;
510  }
511 
512  tg = new RawTowerGeomv1(key);
513 
514  tg->set_center_x(x);
515  tg->set_center_y(y);
516  tg->set_center_z(z);
518  }
519  }
520  }
521  }
523  {
524  const double r = inner_radius;
525 
526  for (int ibin = 0; ibin < first_cellgeo->get_zbins(); ibin++)
527  {
528  const std::pair<double, double> z_range = first_cellgeo->get_zbounds(ibin);
529  // const double r = first_cellgeo->get_radius();
530  const double eta1 = -log(tan(atan2(r, z_range.first) / 2.));
531  const double eta2 = -log(tan(atan2(r, z_range.second) / 2.));
532  m_RawTowerGeomContainer->set_etabounds(ibin, std::make_pair(eta1, eta2));
533  }
534 
535  // setup location of all towers
536  for (int iphi = 0; iphi < m_RawTowerGeomContainer->get_phibins(); iphi++)
537  {
538  for (int ibin = 0; ibin < first_cellgeo->get_zbins(); ibin++)
539  {
540  const RawTowerDefs::keytype key = RawTowerDefs::encode_towerid(caloid, ibin, iphi);
541 
542  const double x(r * cos(m_RawTowerGeomContainer->get_phicenter(iphi)));
543  const double y(r * sin(m_RawTowerGeomContainer->get_phicenter(iphi)));
544  const double z(first_cellgeo->get_zcenter(ibin));
545 
547  if (tg)
548  {
549  if (Verbosity() > 0)
550  {
551  std::cout << "RawTowerBuilder::CreateNodes - Tower geometry " << key << " already exists" << std::endl;
552  }
553 
554  if (fabs(tg->get_center_x() - x) > 1e-4)
555  {
556  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing x = " << tg->get_center_x() << " and expected x = " << x
557  << std::endl;
558 
559  exit(1);
560  }
561  if (fabs(tg->get_center_y() - y) > 1e-4)
562  {
563  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing y = " << tg->get_center_y() << " and expected y = " << y
564  << std::endl;
565  exit(1);
566  }
567  if (fabs(tg->get_center_z() - z) > 1e-4)
568  {
569  std::cout << "RawTowerBuilder::CreateNodes - Fatal Error - duplicated Tower geometry " << key << " with existing z= " << tg->get_center_z() << " and expected z = " << z
570  << std::endl;
571  exit(1);
572  }
573  }
574  else
575  {
576  if (Verbosity() > 0)
577  {
578  std::cout << "RawTowerBuilder::CreateNodes - building tower geometry " << key << "" << std::endl;
579  }
580 
581  tg = new RawTowerGeomv1(key);
582 
583  tg->set_center_x(x);
584  tg->set_center_y(y);
585  tg->set_center_z(z);
587  }
588  }
589  }
590  }
591  else
592  {
593  std::cout << "RawTowerBuilder::CreateNodes - ERROR - unsupported cell geometry "
594  << m_CellBinning << std::endl;
595  exit(1);
596  }
597 
598  if (Verbosity() >= 1)
599  {
601  }
602 
603  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
604  if (!dstNode)
605  {
606  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
607  throw std::runtime_error(
608  "Failed to find DST node in RawTowerBuilder::CreateNodes");
609  }
610 
611  PHNodeIterator dstiter(dstNode);
612  PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", m_Detector));
613  if (!DetNode)
614  {
615  DetNode = new PHCompositeNode(m_Detector);
616  dstNode->addNode(DetNode);
617  }
618 
619 
620  if (m_UseTowerInfo != 1)
621  {
622  // Create the tower nodes on the tree
623  if (m_SimTowerNodePrefix.empty())
624  {
625  // no prefix, consistent with older convention
626  m_TowerNodeName = "TOWER_" + m_Detector;
627  }
628  else
629  {
630  m_TowerNodeName = "TOWER_" + m_SimTowerNodePrefix + "_" + m_Detector;
631  }
632  m_TowerContainer = findNode::getClass<RawTowerContainer>(DetNode, m_TowerNodeName.c_str());
633  if (m_TowerContainer == nullptr)
634  {
635  m_TowerContainer = new RawTowerContainer(caloid);
636 
638  DetNode->addNode(towerNode);
639  }
640  }
641 
642 
643 
644  if (m_UseTowerInfo > 0 )
645  {
646  if (m_SimTowerNodePrefix.empty())
647  {
648  m_TowerInfoNodeName = "TOWERINFO_" + m_Detector;
649  }
650  else
651  {
652  m_TowerInfoNodeName = "TOWERINFO_" + m_SimTowerNodePrefix + "_" + m_Detector;
653  }
654  TowerInfoContainer* m_TowerInfoContainer = findNode::getClass<TowerInfoContainer>(DetNode,m_TowerInfoNodeName);
655  if (m_TowerInfoContainer == nullptr)
656  {
658  if (caloid == RawTowerDefs::CalorimeterId::CEMC)
659  {
660  detec = TowerInfoContainer::DETECTOR::EMCAL;
661  }
663  {
664  detec = TowerInfoContainer::DETECTOR::HCAL;
665  }
666  else
667  {
668  std::cout << PHWHERE << "Detector not implemented into the TowerInfoContainer object, defaulting to HCal implementation." << std::endl;
669  detec = TowerInfoContainer::DETECTOR::HCAL;
670  }
671  m_TowerInfoContainer = new TowerInfoContainerv1(detec);
672  PHIODataNode<PHObject> *TowerInfoNode = new PHIODataNode<PHObject>(m_TowerInfoContainer, m_TowerInfoNodeName, "PHObject");
673  DetNode->addNode(TowerInfoNode);
674  }
675  }
676 
677  return;
678 }