Class Reference for E1039 Core & Analysis Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PHG4BlockCellReco.cc
Go to the documentation of this file.
1 #include "PHG4BlockCellReco.h"
3 #include "PHG4BlockGeom.h"
5 #include "PHG4BlockCellGeom.h"
6 #include "PHG4Cellv1.h"
7 #include "PHG4CellContainer.h"
8 #include "PHG4CellDefs.h"
10 #include "PHG4Parameters.h"
11 
12 #include <g4main/PHG4Hit.h>
15 #include <fun4all/Fun4AllServer.h>
16 #include <phool/PHNodeIterator.h>
17 #include <phool/PHCompositeNode.h>
18 #include <phool/PHIODataNode.h>
19 #include <phool/getClass.h>
20 
21 #include<TROOT.h>
22 
23 #include <cmath>
24 #include <cstdlib>
25 #include <iostream>
26 #include <sstream>
27 #include <limits> // std::numeric_limits
28 
29 using namespace std;
30 
31 static vector<PHG4Cell*> cellptarray;
32 
34  SubsysReco(name),
36  sum_energy_g4hit(0),
37  _timer(PHTimeServer::get()->insert_new(name)),
38  chkenergyconservation(0)
39 {
41 }
42 
43 int
45 {
46  sum_energy_g4hit = 0.;
48 }
49 
51 {
52  PHNodeIterator iter(topNode);
53 
54  // Looking for the DST node
55  PHCompositeNode *dstNode;
56  dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
57  if (!dstNode)
58  {
59  cout << Name() << " DST Node missing, doing nothing." << std::endl;
60  exit(1);
61  }
62  PHNodeIterator dstiter(dstNode);
63  PHCompositeNode *DetNode =
64  dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode",
65  detector));
66  if (!DetNode)
67  {
68  DetNode = new PHCompositeNode(detector);
69  dstNode->addNode(DetNode);
70  }
71 
72  PHCompositeNode *runNode;
73  runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN"));
74  if (!runNode)
75  {
76  cout << Name() << "DST Node missing, doing nothing." << endl;
77  exit(1);
78  }
79  PHNodeIterator runiter(runNode);
80  PHCompositeNode *RunDetNode =
81  dynamic_cast<PHCompositeNode*>(runiter.findFirst("PHCompositeNode",
82  detector));
83  if (!RunDetNode)
84  {
85  RunDetNode = new PHCompositeNode(detector);
86  runNode->addNode(RunDetNode);
87  }
88 
89 
90  hitnodename = "G4HIT_" + detector;
91  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
92  if (!g4hit)
93  {
94  cout << Name() << " Could not locate g4 hit node " << hitnodename << endl;
95  exit(1);
96  }
97 
98  cellnodename = "G4CELL_" + detector;
99  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode , cellnodename);
100  if (!cells)
101  {
102  cells = new PHG4CellContainer();
103  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(cells, cellnodename.c_str() , "PHObject");
104  DetNode->addNode(newNode);
105  }
106 
107  geonodename = "BLOCKGEOM_" + detector;
108  PHG4BlockGeomContainer *geo = findNode::getClass<PHG4BlockGeomContainer>(topNode , geonodename.c_str());
109  if (!geo)
110  {
111  cout << Name() << " Could not locate geometry node " << geonodename << endl;
112  exit(1);
113 
114  }
115 
116  if (verbosity > 0)
117  {
118  geo->identify();
119  }
120 
121  seggeonodename = "BLOCKCELLGEOM_" + detector;
122  PHG4BlockCellGeomContainer *seggeo = findNode::getClass<PHG4BlockCellGeomContainer>(topNode , seggeonodename.c_str());
123  if (!seggeo)
124  {
125  seggeo = new PHG4BlockCellGeomContainer();
126  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN" ));
127  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(seggeo, seggeonodename.c_str() , "PHObject");
128  runNode->addNode(newNode);
129  }
131 
133 
134  map<int, PHG4BlockGeom *>::const_iterator miter;
135  pair <map<int, PHG4BlockGeom *>::const_iterator, map<int, PHG4BlockGeom *>::const_iterator> begin_end = geo->get_begin_end();
136  map<int, std::pair <double, double> >::iterator sizeiter;
137  for (miter = begin_end.first; miter != begin_end.second; ++miter)
138  {
139  PHG4BlockGeom *layergeom = miter->second;
140  int layer = layergeom->get_layer();
141  if (!ExistDetid(layer))
142  {
143  cout << Name() << ": No parameters for detid/layer " << layer
144  << ", hits from this detid/layer will not be accumulated into cells" << endl;
145  continue;
146  }
147  implemented_detid.insert(layer);
148  double radius = sqrt(pow(layergeom->get_center_x(),2) + pow(layergeom->get_center_y(),2));
149  double width = layergeom->get_size_x();
150  double length_in_z = layergeom->get_size_z();
151  double zmin = layergeom->get_center_z() - length_in_z/2.;
152  double zmax = zmin + length_in_z;
153  set_size(layer,get_double_param(layer,"deltaeta"),get_double_param(layer,"deltax"),PHG4CellDefs::etaphibinning);
154  tmin_max.insert(std::make_pair(layer, std::make_pair(get_double_param(layer, "tmin"), get_double_param(layer, "tmax"))));
155  sizeiter = cell_size.find(layer);
156  if (sizeiter == cell_size.end())
157  {
158  cout << Name() << "no cell sizes for layer " << layer << endl;
159  exit(1);
160  }
161 
162  // create geo object and fill with variables common to all binning methods
163  PHG4BlockCellGeom *layerseggeo = new PHG4BlockCellGeom();
164  layerseggeo->set_layer(layergeom->get_layer());
165  // layerseggeo->set_radius(layergeom->get_radius());
166  // layerseggeo->set_thickness(layergeom->get_thickness());
167 
168  if (binning[layer] == PHG4CellDefs::etaphibinning)
169  {
170  // calculate eta at radius+ thickness (outer radius)
171  // length via eta coverage is calculated using the outer radius
172  double etamin = get_eta(radius + 0.5*layergeom->get_size_y(), zmin);
173  double etamax = get_eta(radius + 0.5*layergeom->get_size_y(), zmax);
174  zmin_max[layer] = make_pair(etamin, etamax);
175  double etastepsize = (sizeiter->second).first;
176  double d_etabins;
177  double fract = modf((etamax - etamin) / etastepsize, &d_etabins);
178  if (fract != 0)
179  {
180  d_etabins++;
181  }
182  etastepsize = (etamax - etamin) / d_etabins;
183  (sizeiter->second).first = etastepsize;
184  int etabins = d_etabins;
185  double etahi = etamin + etastepsize;
186  for (int i = 0; i < etabins; i++)
187  {
188  if (etahi > (etamax + 1.e-6)) // etahi is a tiny bit larger due to numerical uncertainties
189  {
190  cout << "etahi: " << etahi << ", etamax: " << etamax << endl;
191  }
192  etahi += etastepsize;
193  }
194 
195  double xmin = -layergeom->get_width()/2.;
196  //double xmax = -xmin;
197  double xstepsize = (sizeiter->second).second;
198  double d_xbins;
199  fract = modf(width / xstepsize, &d_xbins);
200  if (fract != 0)
201  {
202  d_xbins++;
203  }
204 
205  xstepsize = width / d_xbins;
206  (sizeiter->second).second = xstepsize;
207  int xbins = d_xbins;
208  // double xlow = xmin;
209  // double xhi = xlow + xstepsize;
210 
211  // for (int i = 0; i < xbins; i++)
212  // {
213  // if (xhi > xmax)
214  // {
215  // cout << "xhi: " << xhi << ", xmax: " << xmax << endl;
216  // }
217  // xlow = xhi;
218  // xhi += xstepsize;
219  // }
220 
221  pair<int, int> x_z_bin = make_pair(xbins, etabins);
222  n_x_z_bins[layer] = x_z_bin;
224  layerseggeo->set_etabins(etabins);
225  layerseggeo->set_etamin(etamin);
226  layerseggeo->set_etastep(etastepsize);
227  layerseggeo->set_xmin(xmin);
228  layerseggeo->set_xbins(xbins);
229  layerseggeo->set_xstep(xstepsize);
230  xstep[layer] = xstepsize;
231  etastep[layer] = etastepsize;
232  }
233 
234  // add geo object filled by different binning methods
235  seggeo->AddLayerCellGeom(layerseggeo);
236  if (verbosity > 1)
237  {
238  layerseggeo->identify();
239  }
240  }
241  string nodename = "G4CELLPARAM_" + GetParamsContainer()->Name();
242  SaveToNodeTree(RunDetNode,nodename);
244 }
245 
246 
247 int
249 {
250  _timer.get()->restart();
251 
252  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
253  if (!g4hit)
254  {
255  cout << "Could not locate g4 hit node " << hitnodename << endl;
256  exit(1);
257  }
258  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
259  if (! cells)
260  {
261  cout << "could not locate cell node " << cellnodename << endl;
262  exit(1);
263  }
264 
265  PHG4BlockCellGeomContainer *seggeo = findNode::getClass<PHG4BlockCellGeomContainer>(topNode , seggeonodename.c_str());
266  if (! seggeo)
267  {
268  cout << "could not locate geo node " << seggeonodename << endl;
269  exit(1);
270  }
271 
273  pair<PHG4HitContainer::LayerIter, PHG4HitContainer::LayerIter> layer_begin_end = g4hit->getLayers();
274  // cout << "number of layers: " << g4hit->num_layers() << endl;
275  // cout << "number of hits: " << g4hit->size() << endl;
276  // for (layer = layer_begin_end.first; layer != layer_begin_end.second; layer++)
277  // {
278  // cout << "layer number: " << *layer << endl;
279  // }
280 
281  for (layer = layer_begin_end.first; layer != layer_begin_end.second; layer++)
282  {
283  // only handle layers/detector ids which have parameters set
284  if (implemented_detid.find(*layer) == implemented_detid.end())
285  {
286  continue;
287  }
289  PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits(*layer);
290  PHG4BlockCellGeom *geo = seggeo->GetLayerCellGeom(*layer);
291  int nxbins = n_x_z_bins[*layer].first;
292  int nzbins = n_x_z_bins[*layer].second;
293  unsigned int nbins = nxbins*nzbins;
294 
295  if(cellptarray.size() < nbins)
296  {
297  cellptarray.resize(nbins, 0);
298  }
299 
300  // ------- eta/x binning ------------------------------------------------------------------------
301  if (binning[*layer] == PHG4CellDefs::etaphibinning)
302  {
303  for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; hiter++)
304  {
305  // checking ADC timing integration window cut
306  if (hiter->second->get_t(0)>tmin_max[*layer].second) continue;
307  if (hiter->second->get_t(1)<tmin_max[*layer].first) continue;
308 
309  pair<double, double> etax[2];
310  double xbin[2];
311  double etabin[2];
312  for (int i = 0; i < 2; i++)
313  {
314  etax[i] = get_etaphi(hiter->second->get_x(i), hiter->second->get_y(i), hiter->second->get_z(i));
315  etabin[i] = geo->get_etabin( etax[i].first );
316  xbin[i] = geo->get_xbin( etax[i].second );
317  }
318 
319  // check bin range
320  if (xbin[0] < 0 || xbin[0] >= nxbins || xbin[1] < 0 || xbin[1] >= nxbins)
321  {
322  continue;
323  }
324  if (etabin[0] < 0 || etabin[0] >= nzbins || etabin[1] < 0 || etabin[1] >= nzbins)
325  {
326  continue;
327  }
328 
329  if (etabin[0] < 0)
330  {
331  if (verbosity > 0)
332  {
333  hiter->second->identify();
334  }
335  continue;
336  }
337 
338  sum_energy_g4hit += hiter->second->get_edep();
339  int intxbin = xbin[0];
340  int intetabin = etabin[0];
341  int intxbinout = xbin[1];
342  int intetabinout = etabin[1];
343 
344  // Determine all fired cells
345 
346  double ax = (etax[0]).second; // x
347  double ay = (etax[0]).first; // eta
348  double bx = (etax[1]).second;
349  double by = (etax[1]).first;
350  if (intxbin > intxbinout)
351  {
352  int tmp = intxbin;
353  intxbin = intxbinout;
354  intxbinout = tmp;
355  }
356 
357  if (intetabin > intetabinout)
358  {
359  int tmp = intetabin;
360  intetabin = intetabinout;
361  intetabinout = tmp;
362  }
363 
364  double trklen = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
365  // if entry and exit hit are the same (seems to happen rarely), trklen = 0
366  // which leads to a 0/0 and an NaN in edep later on
367  // this code does for particles in the same cell a trklen/trklen (vdedx[ii]/trklen)
368  // so setting this to any non zero number will do just fine
369  // I just pick -1 here to flag those strange hits in case I want t oanalyze them
370  // later on
371  if (trklen == 0)
372  {
373  trklen = -1.;
374  }
375  vector<int> vx;
376  vector<int> veta;
377  vector<double> vdedx;
378 
379  if (intxbin == intxbinout && intetabin == intetabinout) // single cell fired
380  {
381  if (verbosity > 0) cout << "SINGLE CELL FIRED: " << intxbin << " " << intetabin << endl;
382  vx.push_back(intxbin);
383  veta.push_back(intetabin);
384  vdedx.push_back(trklen);
385  }
386  else
387  {
388  for (int ibp = intxbin; ibp <= intxbinout; ibp++)
389  {
390  for (int ibz = intetabin; ibz <= intetabinout; ibz++)
391  {
392  double cx = geo->get_xcenter(ibp) - geo->get_xstep() / 2.;
393  double dx = geo->get_xcenter(ibp) + geo->get_xstep() / 2.;
394  double cy = geo->get_etacenter(ibz) - geo->get_etastep() / 2.;
395  double dy = geo->get_etacenter(ibz) + geo->get_etastep() / 2.;
396  double rr = 0.;
397  //cout << "##### line: " << ax << " " << ay << " " << bx << " " << by << endl;
398  //cout << "####### cell: " << cx << " " << cy << " " << dx << " " << dy << endl;
399  bool yesno = line_and_rectangle_intersect(ax, ay, bx, by, cx, cy, dx, dy, &rr);
400  if (yesno)
401  {
402  if (verbosity > 0) cout << "CELL FIRED: " << ibp << " " << ibz << " " << rr << endl;
403  vx.push_back(ibp);
404  veta.push_back(ibz);
405  vdedx.push_back(rr);
406  }
407  }
408  }
409  }
410  if (verbosity > 0) cout << "NUMBER OF FIRED CELLS = " << vx.size() << endl;
411 
412  double tmpsum = 0.;
413  for (unsigned int ii = 0; ii < vx.size(); ii++)
414  {
415  tmpsum += vdedx[ii];
416  vdedx[ii] = vdedx[ii] / trklen;
417  if (verbosity > 0) cout << " CELL " << ii << " dE/dX = " << vdedx[ii] << endl;
418  }
419  if (verbosity > 0) cout << " TOTAL TRACK LENGTH = " << tmpsum << " " << trklen << endl;
420 
421 
422  for (unsigned int i1 = 0; i1 < vx.size(); i1++) // loop over all fired cells
423  {
424 
425  int ixbin = vx[i1];
426  int ietabin = veta[i1];
427  int ibin = ixbin*nzbins+ietabin;
428  if (!cellptarray[ibin])
429  {
430  PHG4CellDefs::keytype key = PHG4CellDefs::EtaXsizeBinning::genkey(*layer, ixbin, ietabin);
431  cellptarray[ibin] = new PHG4Cellv1(key);
432  }
433  cellptarray[ibin]->add_edep(hiter->first, hiter->second->get_edep()*vdedx[i1]);
434  cellptarray[ibin]->add_edep(hiter->second->get_edep()*vdedx[i1]);
435  if (hiter->second->has_property(PHG4Hit::prop_light_yield))
436  {
437  cellptarray[ibin]->add_light_yield(hiter->second->get_light_yield()*vdedx[i1]);
438  }
439  cellptarray[ibin]->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep()*vdedx[i1]);
440 
441  // just a sanity check - we don't want to mess up by having Nan's or Infs in our energy deposition
442  if (! isfinite(hiter->second->get_edep()*vdedx[i1]))
443  {
444  cout << PHWHERE << " invalid energy dep " << hiter->second->get_edep()
445  << " or path length: " << vdedx[i1] << endl;
446  }
447  }
448 
449  vx.clear();
450  veta.clear();
451  } // end loop over g4hits
452 
453  int numcells = 0;
454  for (int ix = 0; ix < nxbins; ix++)
455  {
456  for (int iz = 0; iz < nzbins; iz++)
457  {
458  int ibin = ix*nzbins + iz;
459 
460  if (cellptarray[ibin])
461  {
462  cells->AddCell(cellptarray[ibin]);
463  numcells++;
464  if (verbosity > 1)
465  {
466  cout << "Adding cell in bin x: " << ix
467  << " x: " << geo->get_xcenter(ix) * 180./M_PI
468  << ", eta bin: " << iz
469  << ", eta: " << geo->get_etacenter(iz)
470  << ", energy dep: " << cellptarray[ibin]->get_edep()
471  << endl;
472  }
473 
474  cellptarray[ibin] = nullptr;
475  }
476  }
477  }
478 
479  if (verbosity > 0)
480  {
481  cout << Name() << ": found " << numcells << " eta/x cells with energy deposition" << endl;
482  }
483  }
484 
485  }
486 
488  {
489  CheckEnergy(topNode);
490  }
491 
492  _timer.get()->stop();
494 }
495 
496 void
497 PHG4BlockCellReco::etaxsize(const int detid, const double deltaeta, const double deltax)
498 {
499  set_double_param(detid,"deltaeta",deltaeta);
500  set_double_param(detid,"deltax",deltax);
501  return;
502 }
503 
504 void
505 PHG4BlockCellReco::set_timing_window(const int detid, const double tmin, const double tmax)
506 {
507  set_double_param(detid,"tmin",tmin);
508  set_double_param(detid,"tmax",tmax);
509  return;
510 }
511 
512 void
513 PHG4BlockCellReco::set_size(const int i, const double sizeA, const double sizeB, const int what)
514 {
515  if (binning.find(i) != binning.end())
516  {
517  cout << "size for layer " << i << " already set" << endl;
518  return;
519  }
520 
521  binning[i] = what;
522  cell_size[i] = std::make_pair(sizeA, sizeB);
523 
524  return;
525 }
526 
527 pair<double, double>
528 PHG4BlockCellReco::get_etaphi(const double x, const double y, const double z)
529 {
530  double radius = sqrt(x * x + y * y);
531  double phi = atan2(y, x);
532  double theta = atan2(radius, z);
533  double eta = -log(tan(theta / 2.));
534  return make_pair(eta, phi);
535 }
536 
537 double
538 PHG4BlockCellReco::get_eta(const double radius, const double z)
539 {
540  double eta;
541  double theta;
542  theta = atan2(radius, fabs(z));
543  eta = -log(tan(theta / 2.));
544  if (z < 0)
545  {
546  eta = -eta;
547  }
548  return eta;
549 }
550 
551 //---------------------------------------------------------------
552 
554  double ay,
555  double bx,
556  double by,
557  double cx,
558  double cy,
559  double dx,
560  double dy,
561  double* rx, // intersection point (output)
562  double* ry
563  )
564 {
565 
566  // Find if a line segment limited by points A and B
567  // intersects line segment limited by points C and D.
568  // First check if an infinite line defined by A and B intersects
569  // segment (C,D). If h is from 0 to 1 line and line segment intersect
570  // Then check in intersection point is between C and D
571 
572  double ex = bx - ax; // E=B-A
573  double ey = by - ay;
574  double fx = dx - cx; // F=D-C
575  double fy = dy - cy;
576  double px = -ey; // P
577  double py = ex;
578 
579  double bottom = fx * px + fy * py; // F*P
580  double gx = ax - cx; // A-C
581  double gy = ay - cy;
582  double top = gx * px + gy * py; // G*P
583 
584  double h = 99999.;
585  if (bottom != 0.)
586  {
587  h = top / bottom;
588  }
589 
590  //intersection point R = C + F*h
591  if (h > 0. && h < 1.)
592  {
593  *rx = cx + fx * h;
594  *ry = cy + fy * h;
595  //cout << " line/segment intersection coordinates: " << *rx << " " << *ry << endl;
596  if ((*rx > ax && *rx > bx) || (*rx < ax && *rx < bx) || (*ry < ay && *ry < by) || (*ry > ay && *ry > by))
597  {
598  //cout << " NO segment/segment intersection!" << endl;
599  return false;
600  }
601  else
602  {
603  //cout << " segment/segment intersection!" << endl;
604  return true;
605  }
606  }
607 
608  return false;
609 }
610 
611 //---------------------------------------------------------------
612 
614  double ay,
615  double bx,
616  double by,
617  double cx,
618  double cy,
619  double dx,
620  double dy,
621  double* rr // length of the line segment inside the rectangle (output)
622  )
623 {
624 
625  // find if a line isegment limited by points (A,B)
626  // intersects with a rectangle defined by two
627  // corner points (C,D) two other points are E and F
628  // E--------D
629  // | |
630  // | |
631  // C--------F
632 
633  if (cx > dx || cy > dy)
634  {
635  cerr << "ERROR: Bad rectangle definition!" << endl;
636  return false;
637  }
638 
639  double ex = cx;
640  double ey = dy;
641  double fx = dx;
642  double fy = cy;
643  double rx = 99999.;
644  double ry = 99999.;
645 
646  vector<double> vx;
647  vector<double> vy;
648 
649  bool i1 = lines_intersect(ax, ay, bx, by, cx, cy, fx, fy, &rx, &ry);
650  if (i1)
651  {
652  vx.push_back(rx);
653  vy.push_back(ry);
654  }
655  bool i2 = lines_intersect(ax, ay, bx, by, fx, fy, dx, dy, &rx, &ry);
656  if (i2)
657  {
658  vx.push_back(rx);
659  vy.push_back(ry);
660  }
661  bool i3 = lines_intersect(ax, ay, bx, by, ex, ey, dx, dy, &rx, &ry);
662  if (i3)
663  {
664  vx.push_back(rx);
665  vy.push_back(ry);
666  }
667  bool i4 = lines_intersect(ax, ay, bx, by, cx, cy, ex, ey, &rx, &ry);
668  if (i4)
669  {
670  vx.push_back(rx);
671  vy.push_back(ry);
672  }
673 
674  //cout << "Rectangle intersections: " << i1 << " " << i2 << " " << i3 << " " << i4 << endl;
675  //cout << "Number of intersections = " << vx.size() << endl;
676 
677  *rr = 0.;
678  if (vx.size() == 2)
679  {
680  *rr = sqrt( (vx[0] - vx[1]) * (vx[0] - vx[1]) + (vy[0] - vy[1]) * (vy[0] - vy[1]) );
681  // cout << "Length of intersection = " << *rr << endl;
682  }
683 
684  if (vx.size() == 1)
685  {
686  // find which point (A or B) is within the rectangle
687  if (ax > cx && ay > cy && ax < dx && ay < dy) // point A is inside the rectangle
688  {
689  //cout << "Point A is inside the rectangle." << endl;
690  *rr = sqrt((vx[0] - ax) * (vx[0] - ax) + (vy[0] - ay) * (vy[0] - ay));
691  }
692  if (bx > cx && by > cy && bx < dx && by < dy) // point B is inside the rectangle
693  {
694  //cout << "Point B is inside the rectangle." << endl;
695  *rr = sqrt((vx[0] - bx) * (vx[0] - bx) + (vy[0] - by) * (vy[0] - by));
696  }
697  }
698 
699  if (i1 || i2 || i3 || i4)
700  {
701  return true;
702  }
703 
704  return false;
705 }
706 
707 
708 int
710 {
711  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
712  double sum_energy_cells = 0.;
713  double sum_energy_stored_hits = 0.;
714  double sum_energy_stored_showers = 0.;
715 
716  PHG4CellContainer::ConstRange cell_begin_end = cells->getCells();
718  for (citer = cell_begin_end.first; citer != cell_begin_end.second; ++citer)
719  {
720  sum_energy_cells += citer->second->get_edep();
721  PHG4Cell::EdepConstRange cellrange = citer->second->get_g4hits();
722  for (PHG4Cell::EdepConstIterator iter = cellrange.first; iter != cellrange.second; ++iter)
723  {
724  sum_energy_stored_hits += iter->second;
725  }
726  PHG4Cell::ShowerEdepConstRange shwrrange = citer->second->get_g4showers();
727  for (PHG4Cell::ShowerEdepConstIterator iter = shwrrange.first; iter != shwrrange.second; ++iter)
728  {
729  sum_energy_stored_showers += iter->second;
730  }
731  }
732 
733  // the fractional eloss for particles traversing eta bins leads to minute rounding errors
734  if (sum_energy_stored_hits > 0)
735  {
736  if (fabs(sum_energy_cells-sum_energy_stored_hits)/sum_energy_cells > 1e-6)
737  {
738  cout << "energy mismatch between cell energy " << sum_energy_cells
739  << " and stored hit energies " << sum_energy_stored_hits
740  << endl;
741  }
742  }
743  if (sum_energy_stored_showers > 0)
744  {
745  if (fabs(sum_energy_cells-sum_energy_stored_showers)/sum_energy_cells > 1e-6)
746  {
747  cout << "energy mismatch between cell energy " << sum_energy_cells
748  << " and stored shower energies " << sum_energy_stored_showers
749  << endl;
750  }
751  }
752 
753  if (fabs(sum_energy_cells - sum_energy_g4hit)/sum_energy_g4hit > 1e-6)
754  {
755  cout << "energy mismatch between cells: " << sum_energy_cells
756  << " and hits: " << sum_energy_g4hit
757  << " diff sum(cells) - sum(hits): " << sum_energy_cells - sum_energy_g4hit
758  << endl;
759  return -1;
760  }
761 
762  else
763  {
764  if (verbosity > 0)
765  {
766  cout << Name() << ": sum hit energy: " << sum_energy_g4hit << " GeV" << endl;
767  cout << Name() << ": sum cell energy: " << sum_energy_cells << " GeV" << endl;
768  cout << Name() << ": sum shower energy: " << sum_energy_stored_showers << " GeV" << endl;
769  cout << Name() << ": sum stored hit energy: " << sum_energy_stored_hits << " GeV" << endl;
770  }
771  }
772 
773  return 0;
774 }
775 
776 void
778 {
779  set_default_double_param("deltaeta",NAN);
780  set_default_double_param("deltax",NAN);
781  set_default_double_param("tmax",60.0);
782  set_default_double_param("tmin",0.0);
783  return;
784 }
static vector< PHG4Cell * > cellptarray
int verbosity
The verbosity level. 0 means not verbose at all.
Definition: Fun4AllBase.h:75
virtual const std::string Name() const
Returns the name of this module.
Definition: Fun4AllBase.h:23
PHBoolean addNode(PHNode *)
int AddLayerCellGeom(const int i, PHG4BlockCellGeom *mygeom)
PHG4BlockCellGeom * GetLayerCellGeom(const int i)
double get_xcenter(const int ibin) const
void set_xstep(const double x)
void set_etabins(const int i)
void identify(std::ostream &os=std::cout) const
void set_etastep(const double z)
void set_etamin(const double z)
double get_etacenter(const int ibin) const
void set_binning(const int i)
void set_layer(const int i)
int get_etabin(const double eta) const
void set_xmin(const double x)
void set_xbins(const int i)
int get_xbin(const double x) const
double get_xstep() const
double get_etastep() const
int CheckEnergy(PHCompositeNode *topNode)
std::string seggeonodename
std::map< int, std::pair< double, double > > cell_size
std::string hitnodename
static std::pair< double, double > get_etaphi(const double x, const double y, const double z)
void set_size(const int i, const double sizeA, const double sizeB, const int what)
PHG4BlockCellReco(const std::string &name="BLOCKRECO")
std::set< int > implemented_detid
std::map< int, double > etastep
void etaxsize(const int i, const double deltaeta, const double deltax)
std::map< int, std::pair< double, double > > zmin_max
std::map< int, double > xstep
int process_event(PHCompositeNode *topNode)
event processing
void set_timing_window(const int detid, const double tmin, const double tmax)
std::string cellnodename
bool lines_intersect(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double *rx, double *ry)
std::map< int, std::pair< double, double > > tmin_max
bool line_and_rectangle_intersect(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double *rr)
int InitRun(PHCompositeNode *topNode)
module initialization
std::string geonodename
std::map< int, std::pair< int, int > > n_x_z_bins
std::map< int, int > binning
static double get_eta(const double radius, const double z)
PHTimeServer::timer _timer
int ResetEvent(PHCompositeNode *topNode)
Clean up after each event.
std::pair< std::map< int, PHG4BlockGeom * >::const_iterator, std::map< int, PHG4BlockGeom * >::const_iterator > get_begin_end() const
void identify(std::ostream &os=std::cout) const
virtual double get_center_z() const
Definition: PHG4BlockGeom.h:23
virtual double get_size_x() const
Definition: PHG4BlockGeom.h:18
virtual double get_center_x() const
Definition: PHG4BlockGeom.h:21
virtual double get_width() const
Definition: PHG4BlockGeom.h:26
virtual double get_size_y() const
Definition: PHG4BlockGeom.h:19
virtual double get_center_y() const
Definition: PHG4BlockGeom.h:22
virtual double get_size_z() const
Definition: PHG4BlockGeom.h:20
virtual int get_layer() const
Definition: PHG4BlockGeom.h:17
std::pair< ConstIterator, ConstIterator > ConstRange
Map::const_iterator ConstIterator
ConstRange getCells(const unsigned short int detid) const
return all Cells matching a given detid
ConstIterator AddCell(PHG4Cell *newCell)
std::pair< ShowerEdepConstIterator, ShowerEdepConstIterator > ShowerEdepConstRange
Definition: PHG4Cell.h:25
EdepMap::const_iterator EdepConstIterator
Definition: PHG4Cell.h:17
std::pair< EdepConstIterator, EdepConstIterator > EdepConstRange
Definition: PHG4Cell.h:19
ShowerEdepMap::const_iterator ShowerEdepConstIterator
Definition: PHG4Cell.h:23
Map::const_iterator ConstIterator
std::set< unsigned int >::const_iterator LayerIter
std::pair< LayerIter, LayerIter > getLayers() const
ConstRange getHits(const unsigned int detid) const
return all hits matching a given detid
std::pair< ConstIterator, ConstIterator > ConstRange
@ prop_light_yield
for scintillation detectors, the amount of light produced
Definition: PHG4Hit.h:101
const PHG4ParametersContainer * GetParamsContainer()
void set_default_double_param(const std::string &name, const double dval)
double get_double_param(const int id, const std::string &name) const
void SaveToNodeTree(PHCompositeNode *runNode, const std::string &nodename)
PHG4ParametersContainer * GetParamsContainerModify()
void set_double_param(const int id, const std::string &name, const double dval)
void set_name(const std::string &name)
PHNode * findFirst(const std::string &, const std::string &)
PHTimer * get(void)
Definition: PHTimeServer.h:43
PHTimer server for accessing external information.
Definition: PHTimeServer.h:29
void restart()
Restart timer.
Definition: PHTimer.h:70
void stop()
stops the counter
Definition: PHTimer.h:61
keytype genkey(const unsigned short layer, const unsigned short etabin, const unsigned short xbin)
unsigned long long keytype
Definition: PHG4CellDefs.h:7
#define PHWHERE
Definition: phool.h:23