Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PHG4CylinderCellReco.cc
Go to the documentation of this file.
1 #include "PHG4CylinderCellReco.h"
3 #include "PHG4CylinderGeom.h"
5 #include "PHG4CylinderCellGeom.h"
6 
7 #include "PHG4Cellv1.h"
8 #include "PHG4CellContainer.h"
9 #include "PHG4CellDefs.h"
10 
12 
13 #include <g4main/PHG4Hit.h>
16 #include <fun4all/Fun4AllServer.h>
17 #include <phool/PHNodeIterator.h>
18 #include <phool/PHCompositeNode.h>
19 #include <phool/PHIODataNode.h>
20 #include <phool/getClass.h>
21 
22 #include <TROOT.h>
23 
24 #include <cmath>
25 #include <cstdlib>
26 #include <iostream>
27 #include <sstream>
28 #include <limits> // std::numeric_limits
29 
30 using namespace std;
31 
33  SubsysReco(name),
35  _timer(PHTimeServer::get()->insert_new(name)),
36  chkenergyconservation(0),
37  sum_energy_before_cuts(0.),
38  sum_energy_g4hit(0.)
39 {
41  memset(nbins, 0, sizeof(nbins));
42 }
43 
44 int
46 {
48  sum_energy_g4hit = 0.;
50 }
51 
53 {
54  PHNodeIterator iter(topNode);
55 
56  // Looking for the DST node
57  PHCompositeNode *dstNode;
58  dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
59  if (!dstNode)
60  {
61  std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
62  exit(1);
63  }
64  PHCompositeNode *runNode;
65  runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN"));
66  if (!runNode)
67  {
68  cout << Name() << "DST Node missing, doing nothing." << endl;
69  exit(1);
70  }
71  PHNodeIterator runiter(runNode);
72  PHCompositeNode *RunDetNode =
73  dynamic_cast<PHCompositeNode*>(runiter.findFirst("PHCompositeNode",
74  detector));
75  if (!RunDetNode)
76  {
77  RunDetNode = new PHCompositeNode(detector);
78  runNode->addNode(RunDetNode);
79  }
80 
81  hitnodename = "G4HIT_" + detector;
82  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
83  if (!g4hit)
84  {
85  cout << "Could not locate g4 hit node " << hitnodename << endl;
86  exit(1);
87  }
88  cellnodename = "G4CELL_" + outdetector;
89  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode , cellnodename);
90  if (!cells)
91  {
92  PHNodeIterator dstiter(dstNode);
93  PHCompositeNode *DetNode =
94  dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode",
95  detector));
96  if (!DetNode)
97  {
98  DetNode = new PHCompositeNode(detector);
99  dstNode->addNode(DetNode);
100  }
101  cells = new PHG4CellContainer();
102  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(cells, cellnodename.c_str() , "PHObject");
103  DetNode->addNode(newNode);
104  }
105 
106  geonodename = "CYLINDERGEOM_" + detector;
107  PHG4CylinderGeomContainer *geo = findNode::getClass<PHG4CylinderGeomContainer>(topNode , geonodename.c_str());
108  if (!geo)
109  {
110  cout << "Could not locate geometry node " << geonodename << endl;
111  exit(1);
112 
113  }
114  if (verbosity > 0)
115  {
116  geo->identify();
117  }
118  seggeonodename = "CYLINDERCELLGEOM_" + outdetector;
119  PHG4CylinderCellGeomContainer *seggeo = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode , seggeonodename.c_str());
120  if (!seggeo)
121  {
122  seggeo = new PHG4CylinderCellGeomContainer();
123  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN" ));
124  PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(seggeo, seggeonodename.c_str() , "PHObject");
125  runNode->addNode(newNode);
126  }
127 
129 
131 
132  map<int, PHG4CylinderGeom *>::const_iterator miter;
133  pair <map<int, PHG4CylinderGeom *>::const_iterator, map<int, PHG4CylinderGeom *>::const_iterator> begin_end = geo->get_begin_end();
134  map<int, std::pair <double, double> >::iterator sizeiter;
135  for (miter = begin_end.first; miter != begin_end.second; ++miter)
136  {
137  PHG4CylinderGeom *layergeom = miter->second;
138  int layer = layergeom->get_layer();
139  if (!ExistDetid(layer))
140  {
141  cout << Name() << ": No parameters for detid/layer " << layer
142  << ", hits from this detid/layer will not be accumulated into cells" << endl;
143  continue;
144  }
145  implemented_detid.insert(layer);
146  set_size(layer,get_double_param(layer,"size_long"),get_double_param(layer,"size_perp"));
147  tmin_max.insert(std::make_pair(layer, std::make_pair(get_double_param(layer, "tmin"), get_double_param(layer, "tmax"))));
148  double circumference = layergeom->get_radius() * 2 * M_PI;
149  double length_in_z = layergeom->get_zmax() - layergeom->get_zmin();
150  sizeiter = cell_size.find(layer);
151  if (sizeiter == cell_size.end())
152  {
153  cout << "no cell sizes for layer " << layer << endl;
154  exit(1);
155  }
156  // create geo object and fill with variables common to all binning methods
157  PHG4CylinderCellGeom *layerseggeo = new PHG4CylinderCellGeom();
158  layerseggeo->set_layer(layergeom->get_layer());
159  layerseggeo->set_radius(layergeom->get_radius());
160  layerseggeo->set_thickness(layergeom->get_thickness());
161  if (binning[layer] == PHG4CellDefs::etaphibinning)
162  {
163  // calculate eta at radius+ thickness (outer radius)
164  // length via eta coverage is calculated using the outer radius
165  double etamin = get_eta(layergeom->get_radius() + layergeom->get_thickness(), layergeom->get_zmin());
166  double etamax = get_eta(layergeom->get_radius() + layergeom->get_thickness(), layergeom->get_zmax());
167  zmin_max[layer] = make_pair(etamin, etamax);
168  double etastepsize = (sizeiter->second).first;
169  double d_etabins;
170  double fract = modf((etamax - etamin) / etastepsize, &d_etabins);
171  if (fract != 0)
172  {
173  d_etabins++;
174  }
175  etastepsize = (etamax - etamin) / d_etabins;
176  (sizeiter->second).first = etastepsize;
177  int etabins = d_etabins;
178  double etalow = etamin;
179  double etahi = etalow + etastepsize;
180  for (int i = 0; i < etabins; i++)
181  {
182  if (etahi > (etamax + 1.e-6)) // etahi is a tiny bit larger due to numerical uncertainties
183  {
184  cout << "etahi: " << etahi << ", etamax: " << etamax << endl;
185  }
186  etahi += etastepsize;
187  }
188 
189  double phimin = -M_PI;
190  double phimax = M_PI;
191  double phistepsize = (sizeiter->second).second;
192  double d_phibins;
193  fract = modf((phimax - phimin) / phistepsize, &d_phibins);
194  if (fract != 0)
195  {
196  d_phibins++;
197  }
198  phistepsize = (phimax - phimin) / d_phibins;
199  (sizeiter->second).second = phistepsize;
200  int phibins = d_phibins;
201  double philow = phimin;
202  double phihi = philow + phistepsize;
203  for (int i = 0; i < phibins; i++)
204  {
205  if (phihi > phimax)
206  {
207  cout << "phihi: " << phihi << ", phimax: " << phimax << endl;
208  }
209  phihi += phistepsize;
210  }
211  pair<int, int> phi_z_bin = make_pair(phibins, etabins);
212  n_phi_z_bins[layer] = phi_z_bin;
214  layerseggeo->set_etabins(etabins);
215  layerseggeo->set_etamin(etamin);
216  layerseggeo->set_etastep(etastepsize);
217  layerseggeo->set_phimin(phimin);
218  layerseggeo->set_phibins(phibins);
219  layerseggeo->set_phistep(phistepsize);
220  phistep[layer] = phistepsize;
221  etastep[layer] = etastepsize;
222  }
223  else if (binning[layer] == PHG4CellDefs::sizebinning)
224  {
225  zmin_max[layer] = make_pair(layergeom->get_zmin(), layergeom->get_zmax());
226  double size_z = (sizeiter->second).second;
227  double size_r = (sizeiter->second).first;
228  double bins_r;
229  // unlikely but if the circumference is a multiple of the cell size
230  // use result of division, if not - add 1 bin which makes the
231  // cells a tiny bit smaller but makes them fit
232  double fract = modf(circumference / size_r, &bins_r);
233  if (fract != 0)
234  {
235  bins_r++;
236  }
237  nbins[0] = bins_r;
238  size_r = circumference / bins_r;
239  (sizeiter->second).first = size_r;
240  double phistepsize = 2 * M_PI / bins_r;
241  double phimin = -M_PI;
242  double phimax = phimin + phistepsize;
243  phistep[layer] = phistepsize;
244  for (int i = 0 ; i < nbins[0]; i++)
245  {
246  if (phimax > (M_PI + 1e-9))
247  {
248  cout << "phimax: " << phimax << ", M_PI: " << M_PI
249  << "phimax-M_PI: " << phimax - M_PI << endl;
250  }
251  phimax += phistepsize;
252  }
253  // unlikely but if the length is a multiple of the cell size
254  // use result of division, if not - add 1 bin which makes the
255  // cells a tiny bit smaller but makes them fit
256  fract = modf(length_in_z / size_z, &bins_r);
257  if (fract != 0)
258  {
259  bins_r++;
260  }
261  nbins[1] = bins_r;
262  pair<int, int> phi_z_bin = make_pair(nbins[0], nbins[1]);
263  n_phi_z_bins[layer] = phi_z_bin;
264  // update our map with the new sizes
265  size_z = length_in_z / bins_r;
266  (sizeiter->second).second = size_z;
267  double zlow = layergeom->get_zmin();
268  double zhigh = zlow + size_z;;
269  for (int i = 0 ; i < nbins[1]; i++)
270  {
271  if (zhigh > (layergeom->get_zmax() + 1e-9))
272  {
273  cout << "zhigh: " << zhigh << ", zmax "
274  << layergeom->get_zmax()
275  << ", zhigh-zmax: " << zhigh - layergeom->get_zmax()
276  << endl;
277  }
278  zhigh += size_z;
279  }
281  layerseggeo->set_zbins(nbins[1]);
282  layerseggeo->set_zmin(layergeom->get_zmin());
283  layerseggeo->set_zstep(size_z);
284  layerseggeo->set_phibins(nbins[0]);
285  layerseggeo->set_phistep(phistepsize);
286  }
287  // add geo object filled by different binning methods
288  seggeo->AddLayerCellGeom(layerseggeo);
289  if (verbosity > 1)
290  {
291  layerseggeo->identify();
292  }
293  }
294 
295  // print out settings
296  if (verbosity > 0)
297  {
298  cout << "===================== PHG4CylinderCellReco::InitRun() =====================" << endl;
299  cout << " " << outdetector << " Segmentation Description: " << endl;
300  for (std::map<int, int>::iterator iter = binning.begin();
301  iter != binning.end(); ++iter)
302  {
303  int layer = iter->first;
304 
305  if (binning[layer] == PHG4CellDefs::etaphibinning)
306  {
307  // phi & eta bin is usually used to make projective towers
308  // so just print the first layer
309  cout << " Layer #" << binning.begin()->first << "-" << binning.rbegin()->first << endl;
310  cout << " Nbins (phi,eta): (" << n_phi_z_bins[layer].first << ", " << n_phi_z_bins[layer].second << ")" << endl;
311  cout << " Cell Size (phi,eta): (" << cell_size[layer].first << " rad, " << cell_size[layer].second << " units)" << endl;
312  break;
313  }
314  else if (binning[layer] == PHG4CellDefs::sizebinning)
315  {
316  cout << " Layer #" << layer << endl;
317  cout << " Nbins (phi,z): (" << n_phi_z_bins[layer].first << ", " << n_phi_z_bins[layer].second << ")" << endl;
318  cout << " Cell Size (phi,z): (" << cell_size[layer].first << " cm, " << cell_size[layer].second << " cm)" << endl;
319  }
320  }
321  cout << "===========================================================================" << endl;
322  }
323  string nodename = "G4CELLPARAM_" + GetParamsContainer()->Name();
324  SaveToNodeTree(RunDetNode,nodename);
326 }
327 
328 
329 int
331 {
332  _timer.get()->restart();
333 
334  PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
335  if (!g4hit)
336  {
337  cout << "Could not locate g4 hit node " << hitnodename << endl;
338  exit(1);
339  }
340  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
341  if (! cells)
342  {
343  cout << "could not locate cell node " << cellnodename << endl;
344  exit(1);
345  }
346 
347  PHG4CylinderCellGeomContainer *seggeo = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode , seggeonodename.c_str());
348  if (! seggeo)
349  {
350  cout << "could not locate geo node " << seggeonodename << endl;
351  exit(1);
352  }
353 
354  map<int, std::pair <double, double> >::iterator sizeiter;
356  pair<PHG4HitContainer::LayerIter, PHG4HitContainer::LayerIter> layer_begin_end = g4hit->getLayers();
357  // cout << "number of layers: " << g4hit->num_layers() << endl;
358  // cout << "number of hits: " << g4hit->size() << endl;
359  // for (layer = layer_begin_end.first; layer != layer_begin_end.second; layer++)
360  // {
361  // cout << "layer number: " << *layer << endl;
362  // }
363  for (layer = layer_begin_end.first; layer != layer_begin_end.second; layer++)
364  {
365  // only handle layers/detector ids which have parameters set
366  if (implemented_detid.find(*layer) == implemented_detid.end())
367  {
368  continue;
369  }
371  PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits(*layer);
372  PHG4CylinderCellGeom *geo = seggeo->GetLayerCellGeom(*layer);
373  int nphibins = n_phi_z_bins[*layer].first;
374  int nzbins = n_phi_z_bins[*layer].second;
375 
376  // ------- eta/phi binning ------------------------------------------------------------------------
377  if (binning[*layer] == PHG4CellDefs::etaphibinning)
378  {
379  for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; hiter++)
380  {
381  sum_energy_before_cuts += hiter->second->get_edep();
382  // checking ADC timing integration window cut
383  if (hiter->second->get_t(0) > tmin_max[*layer].second) continue;
384  if (hiter->second->get_t(1) < tmin_max[*layer].first) continue;
385 
386  pair<double, double> etaphi[2];
387  double phibin[2];
388  double etabin[2];
389  for (int i = 0; i < 2; i++)
390  {
391  etaphi[i] = get_etaphi(hiter->second->get_x(i), hiter->second->get_y(i), hiter->second->get_z(i));
392  etabin[i] = geo->get_etabin( etaphi[i].first );
393  phibin[i] = geo->get_phibin( etaphi[i].second );
394  }
395  // check bin range
396  if (phibin[0] < 0 || phibin[0] >= nphibins || phibin[1] < 0 || phibin[1] >= nphibins)
397  {
398  continue;
399  }
400  if (etabin[0] < 0 || etabin[0] >= nzbins || etabin[1] < 0 || etabin[1] >= nzbins)
401  {
402  continue;
403  }
404 
405  if (etabin[0] < 0)
406  {
407  if (verbosity > 0)
408  {
409  hiter->second->identify();
410  }
411  continue;
412  }
413  sum_energy_g4hit += hiter->second->get_edep();
414  int intphibin = phibin[0];
415  int intetabin = etabin[0];
416  int intphibinout = phibin[1];
417  int intetabinout = etabin[1];
418 
419  // Determine all fired cells
420 
421  double ax = (etaphi[0]).second; // phi
422  double ay = (etaphi[0]).first; // eta
423  double bx = (etaphi[1]).second;
424  double by = (etaphi[1]).first;
425  if (intphibin > intphibinout)
426  {
427  int tmp = intphibin;
428  intphibin = intphibinout;
429  intphibinout = tmp;
430  }
431  if (intetabin > intetabinout)
432  {
433  int tmp = intetabin;
434  intetabin = intetabinout;
435  intetabinout = tmp;
436  }
437 
438  double trklen = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
439  // if entry and exit hit are the same (seems to happen rarely), trklen = 0
440  // which leads to a 0/0 and an NaN in edep later on
441  // this code does for particles in the same cell a trklen/trklen (vdedx[ii]/trklen)
442  // so setting this to any non zero number will do just fine
443  // I just pick -1 here to flag those strange hits in case I want t oanalyze them
444  // later on
445  if (trklen == 0)
446  {
447  trklen = -1.;
448  }
449  vector<int> vphi;
450  vector<int> veta;
451  vector<double> vdedx;
452 
453  if (intphibin == intphibinout && intetabin == intetabinout) // single cell fired
454  {
455  if (verbosity > 0) cout << "SINGLE CELL FIRED: " << intphibin << " " << intetabin << endl;
456  vphi.push_back(intphibin);
457  veta.push_back(intetabin);
458  vdedx.push_back(trklen);
459  }
460  else
461  {
462  double phistep_half = geo->get_phistep() / 2.;
463  double etastep_half = geo->get_etastep() / 2.;
464  for (int ibp = intphibin; ibp <= intphibinout; ibp++)
465  {
466  double cx = geo->get_phicenter(ibp) - phistep_half;
467  double dx = geo->get_phicenter(ibp) + phistep_half;
468  for (int ibz = intetabin; ibz <= intetabinout; ibz++)
469  {
470  double cy = geo->get_etacenter(ibz) - etastep_half;
471  double dy = geo->get_etacenter(ibz) + etastep_half;
472  double rr = 0.;
473  //cout << "##### line: " << ax << " " << ay << " " << bx << " " << by << endl;
474  //cout << "####### cell: " << cx << " " << cy << " " << dx << " " << dy << endl;
475  bool yesno = line_and_rectangle_intersect(ax, ay, bx, by, cx, cy, dx, dy, &rr);
476  if (yesno)
477  {
478  if (verbosity > 0) cout << "CELL FIRED: " << ibp << " " << ibz << " " << rr << endl;
479  vphi.push_back(ibp);
480  veta.push_back(ibz);
481  vdedx.push_back(rr);
482  }
483  }
484  }
485  }
486  if (verbosity > 0) cout << "NUMBER OF FIRED CELLS = " << vphi.size() << endl;
487 
488  double tmpsum = 0.;
489  for (unsigned int ii = 0; ii < vphi.size(); ii++)
490  {
491  tmpsum += vdedx[ii];
492  vdedx[ii] = vdedx[ii] / trklen;
493  if (verbosity > 0) cout << " CELL " << ii << " dE/dX = " << vdedx[ii] << endl;
494  }
495  if (verbosity > 0) cout << " TOTAL TRACK LENGTH = " << tmpsum << " " << trklen << endl;
496 
497  for (unsigned int i1 = 0; i1 < vphi.size(); i1++) // loop over all fired cells
498  {
499 
500  int iphibin = vphi[i1];
501  int ietabin = veta[i1];
502 
503  // This is the key for cellptmap
504  // It is constructed using the phi and z (or eta) bin index values
505  // It will be unique for a given phi and z (or eta) bin combination
506  unsigned long long tmp = iphibin;
507  unsigned long long key = tmp << 32;
508  key += ietabin;
509  if(verbosity > 1)
510  {
511  cout << " iphibin " << iphibin << " ietabin " << ietabin << " key 0x" << hex << key << dec << endl;
512  }
513  PHG4Cell *cell = nullptr;
514  it = cellptmap.find(key);
515  if (it != cellptmap.end())
516  {
517  cell = it->second;
518  }
519  else
520  {
521  PHG4CellDefs::keytype cellkey = PHG4CellDefs::EtaPhiBinning::genkey(*layer, ietabin, iphibin);
522  cell = new PHG4Cellv1(cellkey);
523  cellptmap[key] = cell;
524  }
525  if (! isfinite(hiter->second->get_edep()*vdedx[i1]))
526  {
527  cout << "hit 0x" << hex << hiter->first << dec << " not finite, edep: "
528  << hiter->second->get_edep() << " weight " << vdedx[i1] << endl;
529  }
530  cell->add_edep(hiter->first, hiter->second->get_edep()*vdedx[i1]); // add hit with edep to g4hit list
531  cell->add_edep(hiter->second->get_edep()*vdedx[i1]); // add edep to cell
532  if (hiter->second->has_property(PHG4Hit::prop_light_yield))
533  {
534  cell->add_light_yield(hiter->second->get_light_yield()*vdedx[i1]);
535  }
536  cell->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep()*vdedx[i1]);
537  // just a sanity check - we don't want to mess up by having Nan's or Infs in our energy deposition
538  if (! isfinite(hiter->second->get_edep()*vdedx[i1]))
539  {
540  cout << PHWHERE << " invalid energy dep " << hiter->second->get_edep()
541  << " or path length: " << vdedx[i1] << endl;
542  }
543  }
544  vphi.clear();
545  veta.clear();
546 
547  } // end loop over g4hits
548 
549  int numcells = 0;
550 
551  for(it = cellptmap.begin(); it != cellptmap.end(); ++it)
552  {
553  cells->AddCell(it->second);
554  numcells++;
555  if (verbosity > 1)
556  {
557  cout << "Adding cell in bin phi: " << PHG4CellDefs::EtaPhiBinning::get_phibin(it->second->get_cellid())
558  << " phi: " << geo->get_phicenter(PHG4CellDefs::EtaPhiBinning::get_phibin(it->second->get_cellid())) * 180. / M_PI
559  << ", eta bin: " << PHG4CellDefs::EtaPhiBinning::get_etabin(it->second->get_cellid())
560  << ", eta: " << geo->get_etacenter(PHG4CellDefs::EtaPhiBinning::get_etabin(it->second->get_cellid()))
561  << ", energy dep: " << it->second->get_edep()
562  << endl;
563  }
564  }
565 
566  if (verbosity > 0)
567  {
568  cout << Name() << ": found " << numcells << " eta/phi cells with energy deposition" << endl;
569  }
570  }
571 
572 
573 
574  else // ------ size binning ---------------------------------------------------------------
575  {
576  sizeiter = cell_size.find(*layer);
577  if (sizeiter == cell_size.end())
578  {
579  cout << "logical screwup!!! no sizes for layer " << *layer << endl;
580  exit(1);
581  }
582  double zstepsize = (sizeiter->second).second;
583  double phistepsize = phistep[*layer];
584 
585  for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; hiter++)
586  {
587  sum_energy_before_cuts += hiter->second->get_edep();
588  // checking ADC timing integration window cut
589  if (hiter->second->get_t(0) > tmin_max[*layer].second) continue;
590  if (hiter->second->get_t(1) < tmin_max[*layer].first) continue;
591 
592  double xinout[2];
593  double yinout[2];
594  double px[2];
595  double py[2];
596  double phi[2];
597  double z[2];
598  double phibin[2];
599  double zbin[2];
600  if (verbosity > 0) cout << "--------- new hit in layer # " << *layer << endl;
601 
602  for (int i = 0; i < 2; i++)
603  {
604  xinout[i] = hiter->second->get_x(i);
605  yinout[i] = hiter->second->get_y(i);
606  px[i] = hiter->second->get_px(i);
607  py[i] = hiter->second->get_py(i);
608  phi[i] = atan2(hiter->second->get_y(i), hiter->second->get_x(i));
609  z[i] = hiter->second->get_z(i);
610  phibin[i] = geo->get_phibin( phi[i] );
611  zbin[i] = geo->get_zbin( hiter->second->get_z(i) );
612 
613  if (verbosity > 0) cout << " " << i << " phibin: " << phibin[i] << ", phi: " << phi[i] << ", stepsize: " << phistepsize << endl;
614  if (verbosity > 0) cout << " " << i << " zbin: " << zbin[i] << ", z = " << hiter->second->get_z(i) << ", stepsize: " << zstepsize << " offset: " << zmin_max[*layer].first << endl;
615  }
616  // check bin range
617  if (phibin[0] < 0 || phibin[0] >= nphibins || phibin[1] < 0 || phibin[1] >= nphibins)
618  {
619  continue;
620  }
621  if (zbin[0] < 0 || zbin[0] >= nzbins || zbin[1] < 0 || zbin[1] >= nzbins)
622  {
623  continue;
624  }
625 
626 
627  if (zbin[0] < 0)
628  {
629  hiter->second->identify();
630  continue;
631  }
632  sum_energy_g4hit += hiter->second->get_edep();
633 
634  int intphibin = phibin[0];
635  int intzbin = zbin[0];
636  int intphibinout = phibin[1];
637  int intzbinout = zbin[1];
638 
639  if (verbosity > 0)
640  {
641  cout << " phi bin range: " << intphibin << " to " << intphibinout << " phi: " << phi[0] << " to " << phi[1] << endl;
642  cout << " Z bin range: " << intzbin << " to " << intzbinout << " Z: " << z[0] << " to " << z[1] << endl;
643  cout << " phi difference: " << (phi[1] - phi[0]) * 1000. << " milliradians." << endl;
644  cout << " phi difference: " << 2.5 * (phi[1] - phi[0]) * 10000. << " microns." << endl;
645  cout << " path length = " << sqrt((xinout[1] - xinout[0]) * (xinout[1] - xinout[0]) + (yinout[1] - yinout[0]) * (yinout[1] - yinout[0])) << endl;
646  cout << " px = " << px[0] << " " << px[1] << endl;
647  cout << " py = " << py[0] << " " << py[1] << endl;
648  cout << " x = " << xinout[0] << " " << xinout[1] << endl;
649  cout << " y = " << yinout[0] << " " << yinout[1] << endl;
650  }
651 
652  // Determine all fired cells
653 
654  double ax = phi[0];
655  double ay = z[0];
656  double bx = phi[1];
657  double by = z[1];
658  if (intphibin > intphibinout)
659  {
660  int tmp = intphibin;
661  intphibin = intphibinout;
662  intphibinout = tmp;
663  }
664  if (intzbin > intzbinout)
665  {
666  int tmp = intzbin;
667  intzbin = intzbinout;
668  intzbinout = tmp;
669  }
670 
671  double trklen = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
672  // if entry and exit hit are the same (seems to happen rarely), trklen = 0
673  // which leads to a 0/0 and an NaN in edep later on
674  // this code does for particles in the same cell a trklen/trklen (vdedx[ii]/trklen)
675  // so setting this to any non zero number will do just fine
676  // I just pick -1 here to flag those strange hits in case I want to analyze them
677  // later on
678  if (trklen == 0)
679  {
680  trklen = -1.;
681  }
682  vector<int> vphi;
683  vector<int> vz;
684  vector<double> vdedx;
685 
686  if (intphibin == intphibinout && intzbin == intzbinout) // single cell fired
687  {
688  if (verbosity > 0)
689  {
690  cout << "SINGLE CELL FIRED: " << intphibin << " " << intzbin << endl;
691  }
692  vphi.push_back(intphibin);
693  vz.push_back(intzbin);
694  vdedx.push_back(trklen);
695  }
696  else
697  {
698  double phistep_half = geo->get_phistep() / 2.;
699  double zstep_half = geo->get_zstep() / 2.;
700  for (int ibp = intphibin; ibp <= intphibinout; ibp++)
701  {
702  double cx = geo->get_phicenter(ibp) - phistep_half;
703  double dx = geo->get_phicenter(ibp) + phistep_half;
704  for (int ibz = intzbin; ibz <= intzbinout; ibz++)
705  {
706  double cy = geo->get_zcenter(ibz) - zstep_half;
707  double dy = geo->get_zcenter(ibz) + zstep_half;
708  double rr = 0.;
709  //cout << "##### line: " << ax << " " << ay << " " << bx << " " << by << endl;
710  //cout << "####### cell: " << cx << " " << cy << " " << dx << " " << dy << endl;
711  bool yesno = line_and_rectangle_intersect(ax, ay, bx, by, cx, cy, dx, dy, &rr);
712  if (yesno)
713  {
714  if (verbosity > 0) cout << "CELL FIRED: " << ibp << " " << ibz << " " << rr << endl;
715  vphi.push_back(ibp);
716  vz.push_back(ibz);
717  vdedx.push_back(rr);
718  }
719  }
720  }
721  }
722  if (verbosity > 0) cout << "NUMBER OF FIRED CELLS = " << vz.size() << endl;
723 
724  double tmpsum = 0.;
725  for (unsigned int ii = 0; ii < vz.size(); ii++)
726  {
727  tmpsum += vdedx[ii];
728  vdedx[ii] = vdedx[ii] / trklen;
729  if (verbosity > 0) cout << " CELL " << ii << " dE/dX = " << vdedx[ii] << endl;
730  }
731  if (verbosity > 0) cout << " TOTAL TRACK LENGTH = " << tmpsum << " " << trklen << endl;
732 
733  for (unsigned int i1 = 0; i1 < vphi.size(); i1++) // loop over all fired cells
734  {
735  int iphibin = vphi[i1];
736  int izbin = vz[i1];
737 
738  unsigned long long tmp = iphibin;
739  unsigned long long key = tmp << 32;
740  key += izbin;
741  if(verbosity > 1)
742  {
743  cout << " iphibin " << iphibin << " izbin " << izbin << " key 0x" << hex << key << dec << endl;
744  }
745  // check to see if there is already an entry for this cell
746  PHG4Cell *cell = nullptr;
747  it = cellptmap.find(key);
748 
749  if(it != cellptmap.end())
750  {
751  cell = it->second;
752  if(verbosity > 1)
753  {
754  cout << " add energy to existing cell for key = " << cellptmap.find(key)->first << endl;
755  }
756 
757  if(verbosity > 1 && hiter->second->has_property(PHG4Hit::prop_light_yield) && std::isnan(hiter->second->get_light_yield()*vdedx[i1]))
758  {
759 
760  cout << " NAN lighy yield with vdedx[i1] = " << vdedx[i1]
761  << " and hiter->second->get_light_yield() = " << hiter->second->get_light_yield() << endl;
762 
763  }
764  }
765  else
766  {
767  if(verbosity > 1)
768  {
769  cout << " did not find a previous entry for key = " << key << " create a new one" << endl;
770  }
771  PHG4CellDefs::keytype cellkey = PHG4CellDefs::SizeBinning::genkey(*layer, izbin, iphibin);
772  cell = new PHG4Cellv1(cellkey);
773  cellptmap[key] = cell;
774  }
775  if (! isfinite(hiter->second->get_edep()*vdedx[i1]))
776  {
777  cout << "hit 0x" << hex << hiter->first << dec << " not finite, edep: "
778  << hiter->second->get_edep() << " weight " << vdedx[i1] << endl;
779  }
780  cell->add_edep(hiter->first, hiter->second->get_edep()*vdedx[i1]);
781  cell->add_edep(hiter->second->get_edep()*vdedx[i1]); // add edep to cell
782  if (hiter->second->has_property(PHG4Hit::prop_light_yield))
783  {
784  cell->add_light_yield(hiter->second->get_light_yield()*vdedx[i1]);
785  if(verbosity > 1 && !std::isfinite(hiter->second->get_light_yield()*vdedx[i1]))
786  {
787  cout << " NAN lighy yield with vdedx[i1] = " << vdedx[i1]
788  << " and hiter->second->get_light_yield() = " << hiter->second->get_light_yield() << endl;
789  }
790  }
791  cell->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep()*vdedx[i1]);
792 
793  }
794  vphi.clear();
795  vz.clear();
796 
797  } // end loop over hits
798 
799  int numcells = 0;
800 
801  for(it = cellptmap.begin(); it != cellptmap.end(); ++it)
802  {
803  cells->AddCell(it->second);
804  numcells++;
805  if (verbosity > 1)
806  {
807  cout << "Adding cell for key " << it->first << " in bin phi: " << PHG4CellDefs::SizeBinning::get_phibin(it->second->get_cellid())
808  << " phi: " << geo->get_phicenter(PHG4CellDefs::SizeBinning::get_phibin(it->second->get_cellid())) * 180. / M_PI
809  << ", z bin: " << PHG4CellDefs::SizeBinning::get_zbin(it->second->get_cellid())
810  << ", z: " << geo->get_zcenter(PHG4CellDefs::SizeBinning::get_zbin(it->second->get_cellid()))
811  << ", energy dep: " << it->second->get_edep()
812  << endl;
813  }
814  }
815 
816  if (verbosity > 0)
817  {
818  cout << "found " << numcells << " z/phi cells with energy deposition" << endl;
819  }
820  }
821 
822  //==========================================================
823  // now reset the cell map before moving on to the next layer
824  if(verbosity > 1)
825  {
826  cout << "cellptmap for layer " << *layer << " has final length " << cellptmap.size();
827  }
828  while(cellptmap.begin() != cellptmap.end())
829  {
830  // Assumes that memmory is freed by the cylinder cell container when it is destroyed
831  cellptmap.erase(cellptmap.begin());
832  }
833  if(verbosity > 1)
834  {
835  cout << " reset it to " << cellptmap.size() << endl;
836  }
837  }
839  {
840  CheckEnergy(topNode);
841  }
842  _timer.get()->stop();
843 
845 }
846 
847 void
848 PHG4CylinderCellReco::cellsize(const int detid, const double sr, const double sz)
849 {
850  if (binning.find(detid) != binning.end())
851  {
852  cout << "size for layer " << detid << " already set" << endl;
853  return;
854  }
856  set_double_param(detid,"size_long",sz);
857  set_double_param(detid,"size_perp",sr);
858 }
859 
860 void
861 PHG4CylinderCellReco::etaphisize(const int detid, const double deltaeta, const double deltaphi)
862 {
863  if (binning.find(detid) != binning.end())
864  {
865  cout << "size for layer " << detid << " already set" << endl;
866  return;
867  }
869  set_double_param(detid,"size_long",deltaeta);
870  set_double_param(detid,"size_perp",deltaphi);
871  return;
872 }
873 
874 void
875 PHG4CylinderCellReco::set_size(const int i, const double sizeA, const double sizeB)
876 {
877  cell_size[i] = std::make_pair(sizeA, sizeB);
878  return;
879 }
880 
881 void
882 PHG4CylinderCellReco::set_timing_window(const int detid, const double tmin, const double tmax)
883 {
884  set_double_param(detid,"tmin",tmin);
885  set_double_param(detid,"tmax",tmax);
886  return;
887 }
888 
889 pair<double, double>
890 PHG4CylinderCellReco::get_etaphi(const double x, const double y, const double z)
891 {
892  double eta;
893  double phi;
894  double radius;
895  double theta;
896  radius = sqrt(x * x + y * y);
897  phi = atan2(y, x);
898  theta = atan2(radius, z);
899  eta = -log(tan(theta / 2.));
900  return make_pair(eta, phi);
901 }
902 
903 double
904 PHG4CylinderCellReco::get_eta(const double radius, const double z)
905 {
906  double eta;
907  double theta;
908  theta = atan2(radius, fabs(z));
909  eta = -log(tan(theta / 2.));
910  if (z < 0)
911  {
912  eta = -eta;
913  }
914  return eta;
915 }
916 
917 //---------------------------------------------------------------
918 
920  double ax,
921  double ay,
922  double bx,
923  double by,
924  double cx,
925  double cy,
926  double dx,
927  double dy,
928  double* rx, // intersection point (output)
929  double* ry
930  )
931 {
932 
933  // Find if a line segment limited by points A and B
934  // intersects line segment limited by points C and D.
935  // First check if an infinite line defined by A and B intersects
936  // segment (C,D). If h is from 0 to 1 line and line segment intersect
937  // Then check in intersection point is between C and D
938 
939  double ex = bx - ax; // E=B-A
940  double ey = by - ay;
941  double fx = dx - cx; // F=D-C
942  double fy = dy - cy;
943  double px = -ey; // P
944  double py = ex;
945 
946  double bottom = fx * px + fy * py; // F*P
947  double gx = ax - cx; // A-C
948  double gy = ay - cy;
949  double top = gx * px + gy * py; // G*P
950 
951  double h = 99999.;
952  if (bottom != 0.)
953  {
954  h = top / bottom;
955  }
956 
957  //intersection point R = C + F*h
958  if (h > 0. && h < 1.)
959  {
960  *rx = cx + fx * h;
961  *ry = cy + fy * h;
962  //cout << " line/segment intersection coordinates: " << *rx << " " << *ry << endl;
963  if ((*rx > ax && *rx > bx) || (*rx < ax && *rx < bx) || (*ry < ay && *ry < by) || (*ry > ay && *ry > by))
964  {
965  //cout << " NO segment/segment intersection!" << endl;
966  return false;
967  }
968  else
969  {
970  //cout << " segment/segment intersection!" << endl;
971  return true;
972  }
973  }
974 
975  return false;
976 }
977 
978 //---------------------------------------------------------------
979 
981  double ax,
982  double ay,
983  double bx,
984  double by,
985  double cx,
986  double cy,
987  double dx,
988  double dy,
989  double* rr // length of the line segment inside the rectangle (output)
990  )
991 {
992 
993  // find if a line isegment limited by points (A,B)
994  // intersects with a rectangle defined by two
995  // corner points (C,D) two other points are E and F
996  // E--------D
997  // | |
998  // | |
999  // C--------F
1000 
1001  if (cx > dx || cy > dy)
1002  {
1003  cerr << "ERROR: Bad rectangle definition!" << endl;
1004  return false;
1005  }
1006 
1007  double ex = cx;
1008  double ey = dy;
1009  double fx = dx;
1010  double fy = cy;
1011  double rx = 99999.;
1012  double ry = 99999.;
1013 
1014  vector<double> vx;
1015  vector<double> vy;
1016 
1017  bool i1 = lines_intersect(ax, ay, bx, by, cx, cy, fx, fy, &rx, &ry);
1018  if (i1)
1019  {
1020  vx.push_back(rx);
1021  vy.push_back(ry);
1022  }
1023  bool i2 = lines_intersect(ax, ay, bx, by, fx, fy, dx, dy, &rx, &ry);
1024  if (i2)
1025  {
1026  vx.push_back(rx);
1027  vy.push_back(ry);
1028  }
1029  bool i3 = lines_intersect(ax, ay, bx, by, ex, ey, dx, dy, &rx, &ry);
1030  if (i3)
1031  {
1032  vx.push_back(rx);
1033  vy.push_back(ry);
1034  }
1035  bool i4 = lines_intersect(ax, ay, bx, by, cx, cy, ex, ey, &rx, &ry);
1036  if (i4)
1037  {
1038  vx.push_back(rx);
1039  vy.push_back(ry);
1040  }
1041 
1042  //cout << "Rectangle intersections: " << i1 << " " << i2 << " " << i3 << " " << i4 << endl;
1043  //cout << "Number of intersections = " << vx.size() << endl;
1044 
1045  *rr = 0.;
1046  if (vx.size() == 2)
1047  {
1048  *rr = sqrt( (vx[0] - vx[1]) * (vx[0] - vx[1]) + (vy[0] - vy[1]) * (vy[0] - vy[1]) );
1049  // cout << "Length of intersection = " << *rr << endl;
1050  }
1051  if (vx.size() == 1)
1052  {
1053  // find which point (A or B) is within the rectangle
1054  if (ax > cx && ay > cy && ax < dx && ay < dy) // point A is inside the rectangle
1055  {
1056  //cout << "Point A is inside the rectangle." << endl;
1057  *rr = sqrt((vx[0] - ax) * (vx[0] - ax) + (vy[0] - ay) * (vy[0] - ay));
1058  }
1059  if (bx > cx && by > cy && bx < dx && by < dy) // point B is inside the rectangle
1060  {
1061  //cout << "Point B is inside the rectangle." << endl;
1062  *rr = sqrt((vx[0] - bx) * (vx[0] - bx) + (vy[0] - by) * (vy[0] - by));
1063  }
1064  }
1065 
1066  if (i1 || i2 || i3 || i4)
1067  {
1068  return true;
1069  }
1070  return false;
1071 }
1072 
1073 
1074 int
1076 {
1077  PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
1078  double sum_energy_cells = 0.;
1079  double sum_energy_stored_hits = 0.;
1080  double sum_energy_stored_showers = 0.;
1081  PHG4CellContainer::ConstRange cell_begin_end = cells->getCells();
1083  for (citer = cell_begin_end.first; citer != cell_begin_end.second; ++citer)
1084  {
1085  sum_energy_cells += citer->second->get_edep();
1086  PHG4Cell::EdepConstRange cellrange = citer->second->get_g4hits();
1087  for (PHG4Cell::EdepConstIterator iter = cellrange.first; iter != cellrange.second; ++iter)
1088  {
1089  sum_energy_stored_hits += iter->second;
1090  }
1091  PHG4Cell::ShowerEdepConstRange shwrrange = citer->second->get_g4showers();
1092  for (PHG4Cell::ShowerEdepConstIterator iter = shwrrange.first; iter != shwrrange.second; ++iter)
1093  {
1094  sum_energy_stored_showers += iter->second;
1095  }
1096  }
1097  // the fractional eloss for particles traversing eta bins leads to minute rounding errors
1098  if (sum_energy_stored_hits > 0)
1099  {
1100  if (fabs(sum_energy_cells-sum_energy_stored_hits)/sum_energy_cells > 1e-6)
1101  {
1102  cout << "energy mismatch between cell energy " << sum_energy_cells
1103  << " and stored hit energies " << sum_energy_stored_hits
1104  << endl;
1105  }
1106  }
1107  if (sum_energy_stored_showers > 0)
1108  {
1109  if (fabs(sum_energy_cells-sum_energy_stored_showers)/sum_energy_cells > 1e-6)
1110  {
1111  cout << "energy mismatch between cell energy " << sum_energy_cells
1112  << " and stored shower energies " << sum_energy_stored_showers
1113  << endl;
1114  }
1115  }
1116  if (fabs(sum_energy_cells - sum_energy_g4hit) / sum_energy_g4hit > 1e-6)
1117  {
1118  cout << "energy mismatch between cells: " << sum_energy_cells
1119  << " and hits: " << sum_energy_g4hit
1120  << " diff sum(cells) - sum(hits): " << sum_energy_cells - sum_energy_g4hit
1121  << " cut val " << fabs(sum_energy_cells - sum_energy_g4hit) / sum_energy_g4hit
1122  << endl;
1123  cout << Name() << ":total energy for this event: " << sum_energy_g4hit << " GeV" << endl;
1124  cout << Name() << ": sum cell energy: " << sum_energy_cells << " GeV" << endl;
1125  cout << Name() << ": sum shower energy: " << sum_energy_stored_showers << " GeV" << endl;
1126  cout << Name() << ": sum stored hit energy: " << sum_energy_stored_hits << " GeV" << endl;
1127  cout << Name() << ": hit energy before cuts: " <<sum_energy_before_cuts << " GeV" << endl;
1128  return -1;
1129  }
1130  else
1131  {
1132  if (verbosity > 0)
1133  {
1134  cout << Name() << ":total energy for this event: " << sum_energy_g4hit << " GeV" << endl;
1135  cout << Name() << ": sum cell energy: " << sum_energy_cells << " GeV" << endl;
1136  cout << Name() << ": sum shower energy: " << sum_energy_stored_showers << " GeV" << endl;
1137  cout << Name() << ": sum stored hit energy: " << sum_energy_stored_hits << " GeV" << endl;
1138  cout << Name() << ": hit energy before cuts: " <<sum_energy_before_cuts << " GeV" << endl;
1139  }
1140  }
1141  return 0;
1142 }
1143 
1144 void
1145 PHG4CylinderCellReco::Detector(const std::string &d)
1146 {
1147  detector = d;
1148  // only set the outdetector nodename if it wasn't set already
1149  // in case the order in the macro is outdetector(); detector();
1150  if (outdetector.size() == 0)
1151  {
1152  OutputDetector(d);
1153  }
1154  return;
1155 }
1156 
1157 void
1159 {
1160  set_default_double_param("size_long",NAN);
1161  set_default_double_param("size_perp",NAN);
1162  set_default_double_param("tmax",60.0);
1163  set_default_double_param("tmin",-20.0); // collision has a timing spread around the triggered event. Accepting negative time too.
1164  return;
1165 }
virtual int get_layer() const
std::pair< LayerIter, LayerIter > getLayers() const
int verbosity
The verbosity level. 0 means not verbose at all.
Definition: Fun4AllBase.h:75
Map::const_iterator ConstIterator
std::map< unsigned long long, PHG4Cell * > cellptmap
float phimax
Definition: plot_matscan.C:2
void Detector(const std::string &d)
void set_zstep(const double z)
void set_double_param(const int id, const std::string &name, const double dval)
PHTimer server for accessing external information.
Definition: PHTimeServer.h:28
PHG4ParametersContainer * GetParamsContainerModify()
PHNode * findFirst(const std::string &, const std::string &)
std::pair< ShowerEdepConstIterator, ShowerEdepConstIterator > ShowerEdepConstRange
Definition: PHG4Cell.h:25
void set_thickness(const double t)
#define PHWHERE
Definition: phool.h:23
int ResetEvent(PHCompositeNode *topNode)
Clean up after each event.
unsigned short int get_phibin(const PHG4CellDefs::keytype key)
Definition: PHG4CellDefs.cc:57
std::map< int, std::pair< double, double > > cell_size
virtual double get_thickness() const
unsigned short int get_phibin(const PHG4CellDefs::keytype key)
Definition: PHG4CellDefs.cc:29
int phibins
Definition: matscan.C:10
unsigned long long keytype
Definition: PHG4CellDefs.h:7
PHBoolean addNode(PHNode *)
void set_phibins(const int i)
PHTimeServer::timer _timer
virtual void add_edep(const PHG4HitDefs::keytype g4hitid, const float edep)
Definition: PHG4Cell.h:45
ConstIterator AddCell(PHG4Cell *newCell)
unsigned short int get_etabin(const PHG4CellDefs::keytype key)
Definition: PHG4CellDefs.cc:50
void OutputDetector(const std::string &d)
std::map< int, std::pair< double, double > > zmin_max
void set_etamin(const double z)
void set_binning(const int i)
std::set< unsigned int >::const_iterator LayerIter
PHG4CylinderCellReco(const std::string &name="CYLINDERRECO")
static double get_eta(const double radius, const double z)
std::map< int, double > etastep
std::map< unsigned long long, PHG4Cell * >::iterator it
double get_double_param(const int id, const std::string &name) const
void set_layer(const int i)
ConstRange getCells(const unsigned short int detid) const
return all Cells matching a given detid
keytype genkey(const unsigned short layer, const unsigned short etabin, const unsigned short phibin)
Definition: PHG4CellDefs.cc:43
void set_size(const int i, const double sizeA, const double sizeB)
void set_etastep(const double z)
static std::pair< double, double > get_etaphi(const double x, const double y, const double z)
virtual const std::string Name() const
Returns the name of this module.
Definition: Fun4AllBase.h:23
void stop()
stops the counter
Definition: PHTimer.h:61
const PHG4ParametersContainer * GetParamsContainer()
void set_etabins(const int i)
void set_phistep(const double phi)
keytype genkey(const unsigned short layer, const unsigned short zbin, const unsigned short iphibin)
Definition: PHG4CellDefs.cc:22
int InitRun(PHCompositeNode *topNode)
module initialization
virtual void add_light_yield(const float lightYield)
Definition: PHG4Cell.h:70
ConstRange getHits(const unsigned int detid) const
return all hits matching a given detid
void identify(std::ostream &os=std::cout) const
virtual int get_etabin(const double eta) const
void restart()
Restart timer.
Definition: PHTimer.h:70
virtual double get_zmax() const
void SaveToNodeTree(PHCompositeNode *runNode, const std::string &nodename)
PHTimer * get(void)
Definition: PHTimeServer.h:43
std::pair< ConstIterator, ConstIterator > ConstRange
std::pair< ConstIterator, ConstIterator > ConstRange
Map::const_iterator ConstIterator
bool lines_intersect(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double *rx, double *ry)
virtual int get_phibin(const double phi) const
virtual double get_phicenter(const int ibin) const
virtual int get_zbin(const double z) const
std::map< int, int > binning
void identify(std::ostream &os=std::cout) const
std::map< int, std::pair< double, double > > tmin_max
PHG4CylinderCellGeom * GetLayerCellGeom(const int i)
void set_phimin(const double phi)
std::map< int, std::pair< int, int > > n_phi_z_bins
virtual void add_shower_edep(const int g4showerid, const float edep)
Definition: PHG4Cell.h:48
void set_zbins(const int i)
void set_radius(const double r)
void set_default_double_param(const std::string &name, const double dval)
void set_zmin(const double z)
void etaphisize(const int i, const double deltaeta, const double deltaphi)
std::pair< EdepConstIterator, EdepConstIterator > EdepConstRange
Definition: PHG4Cell.h:19
for scintillation detectors, the amount of light produced
Definition: PHG4Hit.h:101
void set_timing_window(const int detid, const double tmin, const double tmax)
bool line_and_rectangle_intersect(double ax, double ay, double bx, double by, double cx, double cy, double dx, double dy, double *rr)
virtual double get_etacenter(const int ibin) const
unsigned short int get_zbin(const PHG4CellDefs::keytype key)
Definition: PHG4CellDefs.cc:36
void cellsize(const int i, const double sr, const double sz)
ShowerEdepMap::const_iterator ShowerEdepConstIterator
Definition: PHG4Cell.h:23
std::map< int, double > phistep
virtual double get_radius() const
int process_event(PHCompositeNode *topNode)
event processing
virtual double get_zcenter(const int ibin) const
int AddLayerCellGeom(const int i, PHG4CylinderCellGeom *mygeom)
std::pair< std::map< int, PHG4CylinderGeom * >::const_iterator, std::map< int, PHG4CylinderGeom * >::const_iterator > get_begin_end() const
void set_name(const std::string &name)
float phimin
Definition: matscan.C:8
EdepMap::const_iterator EdepConstIterator
Definition: PHG4Cell.h:17
int CheckEnergy(PHCompositeNode *topNode)
std::set< int > implemented_detid
virtual double get_zmin() const
virtual double get_edep() const
Definition: PHG4Cell.h:65