File indexing completed on 2025-08-05 08:17:45
0001 #include "PHG4CylinderCellReco.h"
0002 #include "PHG4CylinderCellGeom.h"
0003 #include "PHG4CylinderCellGeomContainer.h"
0004 #include "PHG4CylinderGeom.h"
0005 #include "PHG4CylinderGeomContainer.h"
0006
0007 #include "PHG4Cell.h" // for PHG4Cell, PHG...
0008 #include "PHG4CellContainer.h"
0009 #include "PHG4CellDefs.h"
0010 #include "PHG4Cellv1.h"
0011
0012 #include <phparameter/PHParameterContainerInterface.h> // for PHParameterCo...
0013 #include <phparameter/PHParametersContainer.h>
0014
0015 #include <g4main/PHG4Hit.h>
0016 #include <g4main/PHG4HitContainer.h>
0017 #include <g4main/PHG4Utils.h>
0018
0019 #include <fun4all/Fun4AllReturnCodes.h>
0020 #include <fun4all/SubsysReco.h> // for SubsysReco
0021
0022 #include <phool/PHCompositeNode.h>
0023 #include <phool/PHIODataNode.h>
0024 #include <phool/PHNode.h> // for PHNode
0025 #include <phool/PHNodeIterator.h>
0026 #include <phool/PHObject.h> // for PHObject
0027 #include <phool/getClass.h>
0028 #include <phool/phool.h> // for PHWHERE
0029
0030 #include <cmath>
0031 #include <cstdlib>
0032 #include <cstring> // for memset
0033 #include <iostream>
0034 #include <iterator> // for reverse_iterator
0035 #include <sstream>
0036 #include <vector> // for vector
0037
0038 PHG4CylinderCellReco::PHG4CylinderCellReco(const std::string &name)
0039 : SubsysReco(name)
0040 , PHParameterContainerInterface(name)
0041 {
0042 SetDefaultParameters();
0043 }
0044
0045 int PHG4CylinderCellReco::ResetEvent(PHCompositeNode * )
0046 {
0047 sum_energy_before_cuts = 0.;
0048 sum_energy_g4hit = 0.;
0049 return Fun4AllReturnCodes::EVENT_OK;
0050 }
0051
0052 int PHG4CylinderCellReco::InitRun(PHCompositeNode *topNode)
0053 {
0054 PHNodeIterator nodeiter(topNode);
0055
0056
0057 PHCompositeNode *dstNode;
0058 dstNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "DST"));
0059 if (!dstNode)
0060 {
0061 std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
0062 exit(1);
0063 }
0064 PHCompositeNode *runNode;
0065 runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
0066 if (!runNode)
0067 {
0068 std::cout << Name() << "DST Node missing, doing nothing." << std::endl;
0069 exit(1);
0070 }
0071 PHNodeIterator runiter(runNode);
0072 PHCompositeNode *RunDetNode = dynamic_cast<PHCompositeNode *>(runiter.findFirst("PHCompositeNode", detector));
0073 if (!RunDetNode)
0074 {
0075 RunDetNode = new PHCompositeNode(detector);
0076 runNode->addNode(RunDetNode);
0077 }
0078
0079 hitnodename = "G4HIT_" + detector;
0080 PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
0081 if (!g4hit)
0082 {
0083 std::cout << "Could not locate g4 hit node " << hitnodename << std::endl;
0084 exit(1);
0085 }
0086 cellnodename = "G4CELL_" + outdetector;
0087 PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
0088 if (!cells)
0089 {
0090 PHNodeIterator dstiter(dstNode);
0091 PHCompositeNode *DetNode = dynamic_cast<PHCompositeNode *>(dstiter.findFirst("PHCompositeNode", detector));
0092 if (!DetNode)
0093 {
0094 DetNode = new PHCompositeNode(detector);
0095 dstNode->addNode(DetNode);
0096 }
0097 cells = new PHG4CellContainer();
0098 PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(cells, cellnodename, "PHObject");
0099 DetNode->addNode(newNode);
0100 }
0101
0102 geonodename = "CYLINDERGEOM_" + detector;
0103 PHG4CylinderGeomContainer *geo = findNode::getClass<PHG4CylinderGeomContainer>(topNode, geonodename);
0104 if (!geo)
0105 {
0106 std::cout << "Could not locate geometry node " << geonodename << std::endl;
0107 exit(1);
0108 }
0109 if (Verbosity() > 0)
0110 {
0111 geo->identify();
0112 }
0113 seggeonodename = "CYLINDERCELLGEOM_" + outdetector;
0114 PHG4CylinderCellGeomContainer *seggeo = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode, seggeonodename);
0115 if (!seggeo)
0116 {
0117 seggeo = new PHG4CylinderCellGeomContainer();
0118 PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(seggeo, seggeonodename, "PHObject");
0119 runNode->addNode(newNode);
0120 }
0121
0122 GetParamsContainerModify()->set_name(detector);
0123
0124 UpdateParametersWithMacro();
0125
0126 std::map<int, PHG4CylinderGeom *>::const_iterator miter;
0127 std::pair<std::map<int, PHG4CylinderGeom *>::const_iterator, std::map<int, PHG4CylinderGeom *>::const_iterator> begin_end = geo->get_begin_end();
0128 std::map<int, std::pair<double, double> >::iterator sizeiter;
0129 for (miter = begin_end.first; miter != begin_end.second; ++miter)
0130 {
0131 PHG4CylinderGeom *layergeom = miter->second;
0132 int layer = layergeom->get_layer();
0133 if (!ExistDetid(layer))
0134 {
0135 std::cout << Name() << ": No parameters for detid/layer " << layer
0136 << ", hits from this detid/layer will not be accumulated into cells" << std::endl;
0137 continue;
0138 }
0139 implemented_detid.insert(layer);
0140 set_size(layer, get_double_param(layer, "size_long"), get_double_param(layer, "size_perp"));
0141 tmin_max.insert(std::make_pair(layer, std::make_pair(get_double_param(layer, "tmin"), get_double_param(layer, "tmax"))));
0142 m_DeltaTMap.insert(std::make_pair(layer, get_double_param(layer, "delta_t")));
0143 double circumference = layergeom->get_radius() * 2 * M_PI;
0144 double length_in_z = layergeom->get_zmax() - layergeom->get_zmin();
0145 sizeiter = cell_size.find(layer);
0146 if (sizeiter == cell_size.end())
0147 {
0148 std::cout << "no cell sizes for layer " << layer << std::endl;
0149 exit(1);
0150 }
0151
0152 PHG4CylinderCellGeom *layerseggeo = new PHG4CylinderCellGeom();
0153 layerseggeo->set_layer(layergeom->get_layer());
0154 layerseggeo->set_radius(layergeom->get_radius());
0155 layerseggeo->set_thickness(layergeom->get_thickness());
0156 if (binning[layer] == PHG4CellDefs::etaphibinning)
0157 {
0158
0159
0160 double etamin = PHG4Utils::get_eta(layergeom->get_radius() + layergeom->get_thickness(), layergeom->get_zmin());
0161 double etamax = PHG4Utils::get_eta(layergeom->get_radius() + layergeom->get_thickness(), layergeom->get_zmax());
0162 zmin_max[layer] = std::make_pair(etamin, etamax);
0163 double etastepsize = (sizeiter->second).first;
0164 double d_etabins;
0165
0166 if (etastepsize > etamax - etamin)
0167 {
0168 d_etabins = 1;
0169 }
0170 else
0171 {
0172
0173
0174
0175 double fract = modf((etamax - etamin) / etastepsize, &d_etabins);
0176 if (fract != 0)
0177 {
0178 d_etabins++;
0179 }
0180 }
0181 etastepsize = (etamax - etamin) / d_etabins;
0182 (sizeiter->second).first = etastepsize;
0183 int etabins = d_etabins;
0184 double etalow = etamin;
0185 double etahi = etalow + etastepsize;
0186 for (int i = 0; i < etabins; i++)
0187 {
0188 if (etahi > (etamax + 1.e-6))
0189 {
0190 std::cout << "etahi: " << etahi << ", etamax: " << etamax << std::endl;
0191 }
0192 etahi += etastepsize;
0193 }
0194
0195 double phimin = -M_PI;
0196 double phimax = M_PI;
0197 double phistepsize = (sizeiter->second).second;
0198 double d_phibins;
0199 if (phistepsize >= phimax - phimin)
0200 {
0201 d_phibins = 1;
0202 }
0203 else
0204 {
0205
0206
0207
0208 double fract = modf((phimax - phimin) / phistepsize, &d_phibins);
0209 if (fract != 0)
0210 {
0211 d_phibins++;
0212 }
0213 }
0214 phistepsize = (phimax - phimin) / d_phibins;
0215 (sizeiter->second).second = phistepsize;
0216 int phibins = d_phibins;
0217 double philow = phimin;
0218 double phihi = philow + phistepsize;
0219 for (int i = 0; i < phibins; i++)
0220 {
0221 if (phihi > phimax)
0222 {
0223 std::cout << "phihi: " << phihi << ", phimax: " << phimax << std::endl;
0224 }
0225 phihi += phistepsize;
0226 }
0227 std::pair<int, int> phi_z_bin = std::make_pair(phibins, etabins);
0228 n_phi_z_bins[layer] = phi_z_bin;
0229 layerseggeo->set_binning(PHG4CellDefs::etaphibinning);
0230 layerseggeo->set_etabins(etabins);
0231 layerseggeo->set_etamin(etamin);
0232 layerseggeo->set_etastep(etastepsize);
0233 layerseggeo->set_phimin(phimin);
0234 layerseggeo->set_phibins(phibins);
0235 layerseggeo->set_phistep(phistepsize);
0236 phistep[layer] = phistepsize;
0237 etastep[layer] = etastepsize;
0238 }
0239 else if (binning[layer] == PHG4CellDefs::sizebinning)
0240 {
0241 zmin_max[layer] = std::make_pair(layergeom->get_zmin(), layergeom->get_zmax());
0242 double size_z = (sizeiter->second).second;
0243 double size_r = (sizeiter->second).first;
0244 double bins_r;
0245
0246 if (size_r >= circumference)
0247 {
0248 bins_r = 1;
0249 }
0250 else
0251 {
0252
0253
0254
0255 double fract = modf(circumference / size_r, &bins_r);
0256 if (fract != 0)
0257 {
0258 bins_r++;
0259 }
0260 }
0261 nbins[0] = bins_r;
0262 size_r = circumference / bins_r;
0263 (sizeiter->second).first = size_r;
0264 double phistepsize = 2 * M_PI / bins_r;
0265 double phimin = -M_PI;
0266 double phimax = phimin + phistepsize;
0267 phistep[layer] = phistepsize;
0268 for (int i = 0; i < nbins[0]; i++)
0269 {
0270 if (phimax > (M_PI + 1e-9))
0271 {
0272 std::cout << "phimax: " << phimax << ", M_PI: " << M_PI
0273 << "phimax-M_PI: " << phimax - M_PI << std::endl;
0274 }
0275 phimax += phistepsize;
0276 }
0277
0278 if (size_z >= length_in_z)
0279 {
0280 bins_r = 1;
0281 }
0282 else
0283 {
0284
0285
0286
0287 double fract = modf(length_in_z / size_z, &bins_r);
0288 if (fract != 0)
0289 {
0290 bins_r++;
0291 }
0292 }
0293 nbins[1] = bins_r;
0294 std::pair<int, int> phi_z_bin = std::make_pair(nbins[0], nbins[1]);
0295 n_phi_z_bins[layer] = phi_z_bin;
0296
0297 size_z = length_in_z / bins_r;
0298 (sizeiter->second).second = size_z;
0299 double zlow = layergeom->get_zmin();
0300 double zhigh = zlow + size_z;
0301 ;
0302 for (int i = 0; i < nbins[1]; i++)
0303 {
0304 if (zhigh > (layergeom->get_zmax() + 1e-9))
0305 {
0306 std::cout << "zhigh: " << zhigh << ", zmax "
0307 << layergeom->get_zmax()
0308 << ", zhigh-zmax: " << zhigh - layergeom->get_zmax()
0309 << std::endl;
0310 }
0311 zhigh += size_z;
0312 }
0313 layerseggeo->set_binning(PHG4CellDefs::sizebinning);
0314 layerseggeo->set_zbins(nbins[1]);
0315 layerseggeo->set_zmin(layergeom->get_zmin());
0316 layerseggeo->set_zstep(size_z);
0317 layerseggeo->set_phibins(nbins[0]);
0318 layerseggeo->set_phistep(phistepsize);
0319 }
0320
0321 seggeo->AddLayerCellGeom(layerseggeo);
0322 if (Verbosity() > 1)
0323 {
0324 layerseggeo->identify();
0325 }
0326 }
0327
0328
0329 if (Verbosity() > 0)
0330 {
0331 std::cout << "===================== PHG4CylinderCellReco::InitRun() =====================" << std::endl;
0332 std::cout << " " << outdetector << " Segmentation Description: " << std::endl;
0333 for (std::map<int, int>::iterator iter = binning.begin();
0334 iter != binning.end(); ++iter)
0335 {
0336 int layer = iter->first;
0337
0338 if (binning[layer] == PHG4CellDefs::etaphibinning)
0339 {
0340
0341
0342 std::cout << " Layer #" << binning.begin()->first << "-" << binning.rbegin()->first << std::endl;
0343 std::cout << " Nbins (phi,eta): (" << n_phi_z_bins[layer].first << ", " << n_phi_z_bins[layer].second << ")" << std::endl;
0344 std::cout << " Cell Size (phi,eta): (" << cell_size[layer].first << " rad, " << cell_size[layer].second << " units)" << std::endl;
0345 break;
0346 }
0347 else if (binning[layer] == PHG4CellDefs::sizebinning)
0348 {
0349 std::cout << " Layer #" << layer << std::endl;
0350 std::cout << " Nbins (phi,z): (" << n_phi_z_bins[layer].first << ", " << n_phi_z_bins[layer].second << ")" << std::endl;
0351 std::cout << " Cell Size (phi,z): (" << cell_size[layer].first << " cm, " << cell_size[layer].second << " cm)" << std::endl;
0352 }
0353 }
0354 std::cout << "===========================================================================" << std::endl;
0355 }
0356 std::string nodename = "G4CELLPARAM_" + GetParamsContainer()->Name();
0357 SaveToNodeTree(RunDetNode, nodename);
0358 return Fun4AllReturnCodes::EVENT_OK;
0359 }
0360
0361 int PHG4CylinderCellReco::process_event(PHCompositeNode *topNode)
0362 {
0363 PHG4HitContainer *g4hit = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
0364 if (!g4hit)
0365 {
0366 std::cout << "Could not locate g4 hit node " << hitnodename << std::endl;
0367 exit(1);
0368 }
0369 PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
0370 if (!cells)
0371 {
0372 std::cout << "could not locate cell node " << cellnodename << std::endl;
0373 exit(1);
0374 }
0375
0376 PHG4CylinderCellGeomContainer *seggeo = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode, seggeonodename);
0377 if (!seggeo)
0378 {
0379 std::cout << "could not locate geo node " << seggeonodename << std::endl;
0380 exit(1);
0381 }
0382
0383 std::map<int, std::pair<double, double> >::iterator sizeiter;
0384 PHG4HitContainer::LayerIter layer;
0385 std::pair<PHG4HitContainer::LayerIter, PHG4HitContainer::LayerIter> layer_begin_end = g4hit->getLayers();
0386
0387
0388
0389
0390
0391
0392 for (layer = layer_begin_end.first; layer != layer_begin_end.second; layer++)
0393 {
0394
0395 if (implemented_detid.find(*layer) == implemented_detid.end())
0396 {
0397 continue;
0398 }
0399 PHG4HitContainer::ConstIterator hiter;
0400 PHG4HitContainer::ConstRange hit_begin_end = g4hit->getHits(*layer);
0401 PHG4CylinderCellGeom *geo = seggeo->GetLayerCellGeom(*layer);
0402 int nphibins = n_phi_z_bins[*layer].first;
0403 int nzbins = n_phi_z_bins[*layer].second;
0404
0405
0406 if (binning[*layer] == PHG4CellDefs::etaphibinning)
0407 {
0408 for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; hiter++)
0409 {
0410 sum_energy_before_cuts += hiter->second->get_edep();
0411
0412 if (hiter->second->get_t(0) > tmin_max[*layer].second)
0413 {
0414 continue;
0415 }
0416 if (hiter->second->get_t(1) < tmin_max[*layer].first)
0417 {
0418 continue;
0419 }
0420 if (hiter->second->get_t(1) - hiter->second->get_t(0) > m_DeltaTMap[*layer])
0421 {
0422 continue;
0423 }
0424
0425 std::pair<double, double> etaphi[2];
0426 double phibin[2];
0427 double etabin[2];
0428 for (int i = 0; i < 2; i++)
0429 {
0430 etaphi[i] = PHG4Utils::get_etaphi(hiter->second->get_x(i), hiter->second->get_y(i), hiter->second->get_z(i));
0431 etabin[i] = geo->get_etabin(etaphi[i].first);
0432 phibin[i] = geo->get_phibin(etaphi[i].second);
0433 }
0434
0435 if (phibin[0] < 0 || phibin[0] >= nphibins || phibin[1] < 0 || phibin[1] >= nphibins)
0436 {
0437 continue;
0438 }
0439 if (etabin[0] < 0 || etabin[0] >= nzbins || etabin[1] < 0 || etabin[1] >= nzbins)
0440 {
0441 continue;
0442 }
0443
0444 if (etabin[0] < 0)
0445 {
0446 if (Verbosity() > 0)
0447 {
0448 hiter->second->identify();
0449 }
0450 continue;
0451 }
0452 sum_energy_g4hit += hiter->second->get_edep();
0453 int intphibin = phibin[0];
0454 int intetabin = etabin[0];
0455 int intphibinout = phibin[1];
0456 int intetabinout = etabin[1];
0457
0458
0459
0460 double ax = (etaphi[0]).second;
0461 double ay = (etaphi[0]).first;
0462 double bx = (etaphi[1]).second;
0463 double by = (etaphi[1]).first;
0464 if (intphibin > intphibinout)
0465 {
0466 int tmp = intphibin;
0467 intphibin = intphibinout;
0468 intphibinout = tmp;
0469 }
0470 if (intetabin > intetabinout)
0471 {
0472 int tmp = intetabin;
0473 intetabin = intetabinout;
0474 intetabinout = tmp;
0475 }
0476
0477 double trklen = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
0478
0479
0480
0481
0482
0483
0484 if (trklen == 0)
0485 {
0486 trklen = -1.;
0487 }
0488 std::vector<int> vphi;
0489 std::vector<int> veta;
0490 std::vector<double> vdedx;
0491
0492 if (intphibin == intphibinout && intetabin == intetabinout)
0493 {
0494 if (Verbosity() > 0)
0495 {
0496 std::cout << "SINGLE CELL FIRED: " << intphibin << " " << intetabin << std::endl;
0497 }
0498 vphi.push_back(intphibin);
0499 veta.push_back(intetabin);
0500 vdedx.push_back(trklen);
0501 }
0502 else
0503 {
0504 double phistep_half = geo->get_phistep() / 2.;
0505 double etastep_half = geo->get_etastep() / 2.;
0506 for (int ibp = intphibin; ibp <= intphibinout; ibp++)
0507 {
0508 double cx = geo->get_phicenter(ibp) - phistep_half;
0509 double dx = geo->get_phicenter(ibp) + phistep_half;
0510 for (int ibz = intetabin; ibz <= intetabinout; ibz++)
0511 {
0512 double cy = geo->get_etacenter(ibz) - etastep_half;
0513 double dy = geo->get_etacenter(ibz) + etastep_half;
0514
0515
0516
0517 std::pair<bool, double> intersect = PHG4Utils::line_and_rectangle_intersect(ax, ay, bx, by, cx, cy, dx, dy);
0518 if (intersect.first)
0519 {
0520 if (Verbosity() > 0)
0521 {
0522 std::cout << "CELL FIRED: " << ibp << " " << ibz << " " << intersect.second << std::endl;
0523 }
0524 vphi.push_back(ibp);
0525 veta.push_back(ibz);
0526 vdedx.push_back(intersect.second);
0527 }
0528 }
0529 }
0530 }
0531 if (Verbosity() > 0)
0532 {
0533 std::cout << "NUMBER OF FIRED CELLS = " << vphi.size() << std::endl;
0534 }
0535
0536 double tmpsum = 0.;
0537 for (unsigned int ii = 0; ii < vphi.size(); ii++)
0538 {
0539 tmpsum += vdedx[ii];
0540 vdedx[ii] = vdedx[ii] / trklen;
0541 if (Verbosity() > 0)
0542 {
0543 std::cout << " CELL " << ii << " dE/dX = " << vdedx[ii] << std::endl;
0544 }
0545 }
0546 if (Verbosity() > 0)
0547 {
0548 std::cout << " TOTAL TRACK LENGTH = " << tmpsum << " " << trklen << std::endl;
0549 }
0550
0551 for (unsigned int i1 = 0; i1 < vphi.size(); i1++)
0552 {
0553 int iphibin = vphi[i1];
0554 int ietabin = veta[i1];
0555
0556
0557
0558
0559 unsigned long long tmp = iphibin;
0560 unsigned long long key = tmp << 32U;
0561 key += ietabin;
0562 if (Verbosity() > 1)
0563 {
0564 std::cout << " iphibin " << iphibin << " ietabin " << ietabin << " key 0x" << std::hex << key << std::dec << std::endl;
0565 }
0566 PHG4Cell *cell = nullptr;
0567 it = cellptmap.find(key);
0568 if (it != cellptmap.end())
0569 {
0570 cell = it->second;
0571 }
0572 else
0573 {
0574 PHG4CellDefs::keytype cellkey = PHG4CellDefs::EtaPhiBinning::genkey(*layer, ietabin, iphibin);
0575 cell = new PHG4Cellv1(cellkey);
0576 cellptmap[key] = cell;
0577 }
0578 if (!std::isfinite(hiter->second->get_edep() * vdedx[i1]))
0579 {
0580 std::cout << "hit 0x" << std::hex << hiter->first << std::dec << " not finite, edep: "
0581 << hiter->second->get_edep() << " weight " << vdedx[i1] << std::endl;
0582 }
0583 cell->add_edep(hiter->first, hiter->second->get_edep() * vdedx[i1]);
0584 cell->add_edep(hiter->second->get_edep() * vdedx[i1]);
0585 if (hiter->second->has_property(PHG4Hit::prop_light_yield))
0586 {
0587 cell->add_light_yield(hiter->second->get_light_yield() * vdedx[i1]);
0588 }
0589 cell->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep() * vdedx[i1]);
0590
0591 if (!std::isfinite(hiter->second->get_edep() * vdedx[i1]))
0592 {
0593 std::cout << PHWHERE << " invalid energy dep " << hiter->second->get_edep()
0594 << " or path length: " << vdedx[i1] << std::endl;
0595 }
0596 }
0597 vphi.clear();
0598 veta.clear();
0599
0600 }
0601
0602 int numcells = 0;
0603
0604 for (it = cellptmap.begin(); it != cellptmap.end(); ++it)
0605 {
0606 cells->AddCell(it->second);
0607 numcells++;
0608 if (Verbosity() > 1)
0609 {
0610 std::cout << "Adding cell in bin phi: " << PHG4CellDefs::EtaPhiBinning::get_phibin(it->second->get_cellid())
0611 << " phi: " << geo->get_phicenter(PHG4CellDefs::EtaPhiBinning::get_phibin(it->second->get_cellid())) * 180. / M_PI
0612 << ", eta bin: " << PHG4CellDefs::EtaPhiBinning::get_etabin(it->second->get_cellid())
0613 << ", eta: " << geo->get_etacenter(PHG4CellDefs::EtaPhiBinning::get_etabin(it->second->get_cellid()))
0614 << ", energy dep: " << it->second->get_edep()
0615 << std::endl;
0616 }
0617 }
0618
0619 if (Verbosity() > 0)
0620 {
0621 std::cout << Name() << ": found " << numcells << " eta/phi cells with energy deposition" << std::endl;
0622 }
0623 }
0624
0625 else
0626 {
0627 sizeiter = cell_size.find(*layer);
0628 if (sizeiter == cell_size.end())
0629 {
0630 std::cout << "logical screwup!!! no sizes for layer " << *layer << std::endl;
0631 exit(1);
0632 }
0633 double zstepsize = (sizeiter->second).second;
0634 double phistepsize = phistep[*layer];
0635
0636 for (hiter = hit_begin_end.first; hiter != hit_begin_end.second; hiter++)
0637 {
0638 sum_energy_before_cuts += hiter->second->get_edep();
0639
0640 if (hiter->second->get_t(0) > tmin_max[*layer].second)
0641 {
0642 continue;
0643 }
0644 if (hiter->second->get_t(1) < tmin_max[*layer].first)
0645 {
0646 continue;
0647 }
0648 if (hiter->second->get_t(1) - hiter->second->get_t(0) > 100)
0649 {
0650 continue;
0651 }
0652
0653 double xinout[2];
0654 double yinout[2];
0655 double px[2];
0656 double py[2];
0657 double phi[2];
0658 double z[2];
0659 double phibin[2];
0660 double zbin[2];
0661 if (Verbosity() > 0)
0662 {
0663 std::cout << "--------- new hit in layer # " << *layer << std::endl;
0664 }
0665
0666 for (int i = 0; i < 2; i++)
0667 {
0668 xinout[i] = hiter->second->get_x(i);
0669 yinout[i] = hiter->second->get_y(i);
0670 px[i] = hiter->second->get_px(i);
0671 py[i] = hiter->second->get_py(i);
0672 phi[i] = std::atan2(hiter->second->get_y(i), hiter->second->get_x(i));
0673 z[i] = hiter->second->get_z(i);
0674 phibin[i] = geo->get_phibin(phi[i]);
0675 zbin[i] = geo->get_zbin(hiter->second->get_z(i));
0676
0677 if (Verbosity() > 0)
0678 {
0679 std::cout << " " << i << " phibin: " << phibin[i] << ", phi: " << phi[i] << ", stepsize: " << phistepsize << std::endl;
0680 }
0681 if (Verbosity() > 0)
0682 {
0683 std::cout << " " << i << " zbin: " << zbin[i] << ", z = " << hiter->second->get_z(i) << ", stepsize: " << zstepsize << " offset: " << zmin_max[*layer].first << std::endl;
0684 }
0685 }
0686
0687 if (phibin[0] < 0 || phibin[0] >= nphibins || phibin[1] < 0 || phibin[1] >= nphibins)
0688 {
0689 continue;
0690 }
0691 if (zbin[0] < 0 || zbin[0] >= nzbins || zbin[1] < 0 || zbin[1] >= nzbins)
0692 {
0693 continue;
0694 }
0695
0696 if (zbin[0] < 0)
0697 {
0698 hiter->second->identify();
0699 continue;
0700 }
0701 sum_energy_g4hit += hiter->second->get_edep();
0702
0703 int intphibin = phibin[0];
0704 int intzbin = zbin[0];
0705 int intphibinout = phibin[1];
0706 int intzbinout = zbin[1];
0707
0708 if (Verbosity() > 0)
0709 {
0710 std::cout << " phi bin range: " << intphibin << " to " << intphibinout << " phi: " << phi[0] << " to " << phi[1] << std::endl;
0711 std::cout << " Z bin range: " << intzbin << " to " << intzbinout << " Z: " << z[0] << " to " << z[1] << std::endl;
0712 std::cout << " phi difference: " << (phi[1] - phi[0]) * 1000. << " milliradians." << std::endl;
0713 std::cout << " phi difference: " << 2.5 * (phi[1] - phi[0]) * 10000. << " microns." << std::endl;
0714 std::cout << " path length = " << sqrt((xinout[1] - xinout[0]) * (xinout[1] - xinout[0]) + (yinout[1] - yinout[0]) * (yinout[1] - yinout[0])) << std::endl;
0715 std::cout << " px = " << px[0] << " " << px[1] << std::endl;
0716 std::cout << " py = " << py[0] << " " << py[1] << std::endl;
0717 std::cout << " x = " << xinout[0] << " " << xinout[1] << std::endl;
0718 std::cout << " y = " << yinout[0] << " " << yinout[1] << std::endl;
0719 }
0720
0721
0722
0723 double ax = phi[0];
0724 double ay = z[0];
0725 double bx = phi[1];
0726 double by = z[1];
0727 if (intphibin > intphibinout)
0728 {
0729 int tmp = intphibin;
0730 intphibin = intphibinout;
0731 intphibinout = tmp;
0732 }
0733 if (intzbin > intzbinout)
0734 {
0735 int tmp = intzbin;
0736 intzbin = intzbinout;
0737 intzbinout = tmp;
0738 }
0739
0740 double trklen = sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
0741
0742
0743
0744
0745
0746
0747 if (trklen == 0)
0748 {
0749 trklen = -1.;
0750 }
0751 std::vector<int> vphi;
0752 std::vector<int> vz;
0753 std::vector<double> vdedx;
0754
0755 if (intphibin == intphibinout && intzbin == intzbinout)
0756 {
0757 if (Verbosity() > 0)
0758 {
0759 std::cout << "SINGLE CELL FIRED: " << intphibin << " " << intzbin << std::endl;
0760 }
0761 vphi.push_back(intphibin);
0762 vz.push_back(intzbin);
0763 vdedx.push_back(trklen);
0764 }
0765 else
0766 {
0767 double phistep_half = geo->get_phistep() / 2.;
0768 double zstep_half = geo->get_zstep() / 2.;
0769 for (int ibp = intphibin; ibp <= intphibinout; ibp++)
0770 {
0771 double cx = geo->get_phicenter(ibp) - phistep_half;
0772 double dx = geo->get_phicenter(ibp) + phistep_half;
0773 for (int ibz = intzbin; ibz <= intzbinout; ibz++)
0774 {
0775 double cy = geo->get_zcenter(ibz) - zstep_half;
0776 double dy = geo->get_zcenter(ibz) + zstep_half;
0777
0778
0779 std::pair<bool, double> intersect = PHG4Utils::line_and_rectangle_intersect(ax, ay, bx, by, cx, cy, dx, dy);
0780 if (intersect.first)
0781 {
0782 if (Verbosity() > 0)
0783 {
0784 std::cout << "CELL FIRED: " << ibp << " " << ibz << " " << intersect.second << std::endl;
0785 }
0786 vphi.push_back(ibp);
0787 vz.push_back(ibz);
0788 vdedx.push_back(intersect.second);
0789 }
0790 }
0791 }
0792 }
0793 if (Verbosity() > 0)
0794 {
0795 std::cout << "NUMBER OF FIRED CELLS = " << vz.size() << std::endl;
0796 }
0797
0798 double tmpsum = 0.;
0799 for (unsigned int ii = 0; ii < vz.size(); ii++)
0800 {
0801 tmpsum += vdedx[ii];
0802 vdedx[ii] = vdedx[ii] / trklen;
0803 if (Verbosity() > 0)
0804 {
0805 std::cout << " CELL " << ii << " dE/dX = " << vdedx[ii] << std::endl;
0806 }
0807 }
0808 if (Verbosity() > 0)
0809 {
0810 std::cout << " TOTAL TRACK LENGTH = " << tmpsum << " " << trklen << std::endl;
0811 }
0812
0813 for (unsigned int i1 = 0; i1 < vphi.size(); i1++)
0814 {
0815 int iphibin = vphi[i1];
0816 int izbin = vz[i1];
0817
0818 unsigned long long tmp = iphibin;
0819 unsigned long long key = tmp << 32U;
0820 key += izbin;
0821 if (Verbosity() > 1)
0822 {
0823 std::cout << " iphibin " << iphibin << " izbin " << izbin << " key 0x" << std::hex << key << std::dec << std::endl;
0824 }
0825
0826 PHG4Cell *cell = nullptr;
0827 it = cellptmap.find(key);
0828
0829 if (it != cellptmap.end())
0830 {
0831 cell = it->second;
0832 if (Verbosity() > 1)
0833 {
0834 std::cout << " add energy to existing cell for key = " << cellptmap.find(key)->first << std::endl;
0835 }
0836
0837 if (Verbosity() > 1 && hiter->second->has_property(PHG4Hit::prop_light_yield) && std::isnan(hiter->second->get_light_yield() * vdedx[i1]))
0838 {
0839 std::cout << " NAN lighy yield with vdedx[i1] = " << vdedx[i1]
0840 << " and hiter->second->get_light_yield() = " << hiter->second->get_light_yield() << std::endl;
0841 }
0842 }
0843 else
0844 {
0845 if (Verbosity() > 1)
0846 {
0847 std::cout << " did not find a previous entry for key = 0x" << std::hex << key << std::dec << " create a new one" << std::endl;
0848 }
0849 PHG4CellDefs::keytype cellkey = PHG4CellDefs::SizeBinning::genkey(*layer, izbin, iphibin);
0850 cell = new PHG4Cellv1(cellkey);
0851 cellptmap[key] = cell;
0852 }
0853 if (!std::isfinite(hiter->second->get_edep() * vdedx[i1]))
0854 {
0855 std::cout << "hit 0x" << std::hex << hiter->first << std::dec << " not finite, edep: "
0856 << hiter->second->get_edep() << " weight " << vdedx[i1] << std::endl;
0857 }
0858 cell->add_edep(hiter->first, hiter->second->get_edep() * vdedx[i1]);
0859 cell->add_edep(hiter->second->get_edep() * vdedx[i1]);
0860 if (hiter->second->has_property(PHG4Hit::prop_light_yield))
0861 {
0862 cell->add_light_yield(hiter->second->get_light_yield() * vdedx[i1]);
0863 if (Verbosity() > 1 && !std::isfinite(hiter->second->get_light_yield() * vdedx[i1]))
0864 {
0865 std::cout << " NAN lighy yield with vdedx[i1] = " << vdedx[i1]
0866 << " and hiter->second->get_light_yield() = " << hiter->second->get_light_yield() << std::endl;
0867 }
0868 }
0869 cell->add_shower_edep(hiter->second->get_shower_id(), hiter->second->get_edep() * vdedx[i1]);
0870 }
0871 vphi.clear();
0872 vz.clear();
0873
0874 }
0875
0876 int numcells = 0;
0877
0878 for (it = cellptmap.begin(); it != cellptmap.end(); ++it)
0879 {
0880 cells->AddCell(it->second);
0881 numcells++;
0882 if (Verbosity() > 1)
0883 {
0884 std::cout << "Adding cell for key " << std::hex << it->first << std::dec << " in bin phi: " << PHG4CellDefs::SizeBinning::get_phibin(it->second->get_cellid())
0885 << " phi: " << geo->get_phicenter(PHG4CellDefs::SizeBinning::get_phibin(it->second->get_cellid())) * 180. / M_PI
0886 << ", z bin: " << PHG4CellDefs::SizeBinning::get_zbin(it->second->get_cellid())
0887 << ", z: " << geo->get_zcenter(PHG4CellDefs::SizeBinning::get_zbin(it->second->get_cellid()))
0888 << ", energy dep: " << it->second->get_edep()
0889 << std::endl;
0890 }
0891 }
0892
0893 if (Verbosity() > 0)
0894 {
0895 std::cout << "found " << numcells << " z/phi cells with energy deposition" << std::endl;
0896 }
0897 }
0898
0899
0900
0901 if (Verbosity() > 1)
0902 {
0903 std::cout << "cellptmap for layer " << *layer << " has final length " << cellptmap.size();
0904 }
0905 while (cellptmap.begin() != cellptmap.end())
0906 {
0907
0908 cellptmap.erase(cellptmap.begin());
0909 }
0910 if (Verbosity() > 1)
0911 {
0912 std::cout << " reset it to " << cellptmap.size() << std::endl;
0913 }
0914 }
0915 if (chkenergyconservation)
0916 {
0917 CheckEnergy(topNode);
0918 }
0919
0920 return Fun4AllReturnCodes::EVENT_OK;
0921 }
0922
0923 void PHG4CylinderCellReco::cellsize(const int detid, const double sr, const double sz)
0924 {
0925 if (binning.find(detid) != binning.end())
0926 {
0927 std::cout << "size for layer " << detid << " already set" << std::endl;
0928 return;
0929 }
0930 binning[detid] = PHG4CellDefs::sizebinning;
0931 set_double_param(detid, "size_long", sz);
0932 set_double_param(detid, "size_perp", sr);
0933 }
0934
0935 void PHG4CylinderCellReco::etaphisize(const int detid, const double deltaeta, const double deltaphi)
0936 {
0937 if (binning.find(detid) != binning.end())
0938 {
0939 std::cout << "size for layer " << detid << " already set" << std::endl;
0940 return;
0941 }
0942 binning[detid] = PHG4CellDefs::etaphibinning;
0943 set_double_param(detid, "size_long", deltaeta);
0944 set_double_param(detid, "size_perp", deltaphi);
0945 return;
0946 }
0947
0948 void PHG4CylinderCellReco::set_size(const int i, const double sizeA, const double sizeB)
0949 {
0950 cell_size[i] = std::make_pair(sizeA, sizeB);
0951 return;
0952 }
0953
0954 void PHG4CylinderCellReco::set_timing_window(const int detid, const double tmin, const double tmax)
0955 {
0956 set_double_param(detid, "tmin", tmin);
0957 set_double_param(detid, "tmax", tmax);
0958 return;
0959 }
0960
0961 int PHG4CylinderCellReco::CheckEnergy(PHCompositeNode *topNode)
0962 {
0963 PHG4CellContainer *cells = findNode::getClass<PHG4CellContainer>(topNode, cellnodename);
0964 double sum_energy_cells = 0.;
0965 double sum_energy_stored_hits = 0.;
0966 double sum_energy_stored_showers = 0.;
0967 PHG4CellContainer::ConstRange cell_begin_end = cells->getCells();
0968 PHG4CellContainer::ConstIterator citer;
0969 for (citer = cell_begin_end.first; citer != cell_begin_end.second; ++citer)
0970 {
0971 sum_energy_cells += citer->second->get_edep();
0972 PHG4Cell::EdepConstRange cellrange = citer->second->get_g4hits();
0973 for (PHG4Cell::EdepConstIterator iter = cellrange.first; iter != cellrange.second; ++iter)
0974 {
0975 sum_energy_stored_hits += iter->second;
0976 }
0977 PHG4Cell::ShowerEdepConstRange shwrrange = citer->second->get_g4showers();
0978 for (PHG4Cell::ShowerEdepConstIterator iter = shwrrange.first; iter != shwrrange.second; ++iter)
0979 {
0980 sum_energy_stored_showers += iter->second;
0981 }
0982 }
0983
0984 if (sum_energy_stored_hits > 0)
0985 {
0986 if (fabs(sum_energy_cells - sum_energy_stored_hits) / sum_energy_cells > 1e-6)
0987 {
0988 std::cout << "energy mismatch between cell energy " << sum_energy_cells
0989 << " and stored hit energies " << sum_energy_stored_hits
0990 << std::endl;
0991 }
0992 }
0993 if (sum_energy_stored_showers > 0)
0994 {
0995 if (fabs(sum_energy_cells - sum_energy_stored_showers) / sum_energy_cells > 1e-6)
0996 {
0997 std::cout << "energy mismatch between cell energy " << sum_energy_cells
0998 << " and stored shower energies " << sum_energy_stored_showers
0999 << std::endl;
1000 }
1001 }
1002 if (fabs(sum_energy_cells - sum_energy_g4hit) / sum_energy_g4hit > 1e-6)
1003 {
1004 std::cout << "energy mismatch between cells: " << sum_energy_cells
1005 << " and hits: " << sum_energy_g4hit
1006 << " diff sum(cells) - sum(hits): " << sum_energy_cells - sum_energy_g4hit
1007 << " cut val " << fabs(sum_energy_cells - sum_energy_g4hit) / sum_energy_g4hit
1008 << std::endl;
1009 std::cout << Name() << ":total energy for this event: " << sum_energy_g4hit << " GeV" << std::endl;
1010 std::cout << Name() << ": sum cell energy: " << sum_energy_cells << " GeV" << std::endl;
1011 std::cout << Name() << ": sum shower energy: " << sum_energy_stored_showers << " GeV" << std::endl;
1012 std::cout << Name() << ": sum stored hit energy: " << sum_energy_stored_hits << " GeV" << std::endl;
1013 std::cout << Name() << ": hit energy before cuts: " << sum_energy_before_cuts << " GeV" << std::endl;
1014 return -1;
1015 }
1016 else
1017 {
1018 if (Verbosity() > 0)
1019 {
1020 std::cout << Name() << ":total energy for this event: " << sum_energy_g4hit << " GeV" << std::endl;
1021 std::cout << Name() << ": sum cell energy: " << sum_energy_cells << " GeV" << std::endl;
1022 std::cout << Name() << ": sum shower energy: " << sum_energy_stored_showers << " GeV" << std::endl;
1023 std::cout << Name() << ": sum stored hit energy: " << sum_energy_stored_hits << " GeV" << std::endl;
1024 std::cout << Name() << ": hit energy before cuts: " << sum_energy_before_cuts << " GeV" << std::endl;
1025 }
1026 }
1027 return 0;
1028 }
1029
1030 void PHG4CylinderCellReco::Detector(const std::string &d)
1031 {
1032 detector = d;
1033
1034
1035 if (outdetector.size() == 0)
1036 {
1037 OutputDetector(d);
1038 }
1039 return;
1040 }
1041
1042 void PHG4CylinderCellReco::SetDefaultParameters()
1043 {
1044 set_default_double_param("size_long", NAN);
1045 set_default_double_param("size_perp", NAN);
1046 set_default_double_param("tmax", 60.0);
1047 set_default_double_param("tmin", -20.0);
1048 set_default_double_param("delta_t", 100.);
1049 return;
1050 }