File indexing completed on 2025-08-05 08:18:14
0001
0002
0003 #include "PHG4MvtxHitReco.h"
0004
0005 #include <mvtx/CylinderGeom_Mvtx.h>
0006 #include <mvtx/CylinderGeom_MvtxHelper.h>
0007 #include <mvtx/MvtxHitPruner.h>
0008
0009 #include <trackbase/ActsGeometry.h>
0010 #include <trackbase/MvtxDefs.h>
0011 #include <trackbase/TrkrDefs.h>
0012 #include <trackbase/TrkrHit.h> // // make iwyu happy
0013 #include <trackbase/TrkrHitSet.h>
0014 #include <trackbase/TrkrHitSetContainer.h> // make iwyu happy
0015 #include <trackbase/TrkrHitSetContainerv1.h>
0016 #include <trackbase/TrkrHitTruthAssoc.h> // make iwyu happy
0017 #include <trackbase/TrkrHitTruthAssocv1.h>
0018 #include <trackbase/TrkrHitv2.h> // for TrkrHit
0019
0020 #include <g4tracking/TrkrTruthTrack.h>
0021 #include <g4tracking/TrkrTruthTrackContainer.h>
0022 #include <g4tracking/TrkrTruthTrackContainerv1.h>
0023 #include <trackbase/ClusHitsVerbosev1.h>
0024 #include <trackbase/TrkrClusterContainer.h>
0025 #include <trackbase/TrkrClusterContainerv4.h>
0026 #include <trackbase/TrkrClusterv4.h>
0027
0028 #include <g4detectors/PHG4CylinderGeom.h> // for PHG4CylinderGeom
0029 #include <g4detectors/PHG4CylinderGeomContainer.h>
0030
0031 #include <g4main/PHG4Hit.h>
0032 #include <g4main/PHG4HitContainer.h>
0033 #include <g4main/PHG4TruthInfoContainer.h>
0034 #include <g4main/PHG4Utils.h>
0035
0036 #include <cdbobjects/CDBTTree.h>
0037 #include <ffamodules/CDBInterface.h> // for accessing the MVTX hot pixel file from the CDB
0038 #include <ffarawobjects/MvtxRawEvtHeader.h>
0039
0040 #include <fun4all/Fun4AllReturnCodes.h>
0041 #include <fun4all/SubsysReco.h> // for SubsysReco
0042
0043 #include <phool/PHCompositeNode.h>
0044 #include <phool/PHIODataNode.h>
0045 #include <phool/PHNode.h> // for PHNode
0046 #include <phool/PHNodeIterator.h>
0047 #include <phool/PHObject.h> // for PHObject
0048 #include <phool/PHRandomSeed.h> // for PHRandomSeed
0049 #include <phool/getClass.h>
0050 #include <phool/phool.h> // for PHWHERE
0051
0052 #include <G4SystemOfUnits.hh> // for microsecond
0053
0054 #include <TVector3.h> // for TVector3, ope...
0055
0056 #include <boost/format.hpp>
0057
0058 #include <cassert> // for assert
0059 #include <cmath>
0060 #include <cstdlib>
0061 #include <iostream>
0062 #include <memory> // for allocator_tra...
0063 #include <set> // for vector
0064 #include <vector> // for vector
0065
0066
0067
0068 PHG4MvtxHitReco::PHG4MvtxHitReco(const std::string& name, const std::string& detector)
0069 : SubsysReco(name)
0070 , PHParameterInterface(name)
0071 , m_detector(detector)
0072 , m_tmin(-5000.)
0073 , m_tmax(5000.)
0074 , m_strobe_width(5.)
0075 , m_strobe_separation(0.)
0076 , m_truth_hits{new TrkrHitSetContainerv1}
0077 {
0078 if (Verbosity())
0079 {
0080 std::cout << "Creating PHG4MvtxHitReco for detector = " << detector << std::endl;
0081 }
0082
0083 const uint seed = PHRandomSeed();
0084 m_rng.reset(gsl_rng_alloc(gsl_rng_mt19937));
0085 gsl_rng_set(m_rng.get(), seed);
0086
0087 InitializeParameters();
0088 }
0089
0090 int PHG4MvtxHitReco::InitRun(PHCompositeNode* topNode)
0091 {
0092 UpdateParametersWithMacro();
0093
0094 m_tmin = get_double_param("mvtx_tmin");
0095 m_tmax = get_double_param("mvtx_tmax");
0096 m_strobe_width = get_double_param("mvtx_strobe_width");
0097 m_strobe_separation = get_double_param("mvtx_strobe_separation");
0098 m_in_sphenix_srdo = (bool) get_int_param("mvtx_in_sphenix_srdo");
0099
0100 m_extended_readout_time = m_tmax - m_strobe_width;
0101
0102
0103 std::cout
0104 << "PHG4MvtxHitReco::InitRun\n"
0105 << " m_tmin: " << m_tmin << "ns, m_tmax: " << m_tmax << "ns\n"
0106 << " m_strobe_width: " << m_strobe_width << "\n"
0107 << " m_strobe_separation: " << m_strobe_separation << "\n"
0108 << " m_extended_readout_time: " << m_extended_readout_time << "\n"
0109 << " m_in_sphenix_srdo: " << (m_in_sphenix_srdo ? "true" : "false") << "\n"
0110 << std::endl;
0111
0112
0113 PHNodeIterator iter(topNode);
0114 auto dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0115 assert(dstNode);
0116
0117
0118 auto runNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "RUN"));
0119 assert(runNode);
0120
0121 PHNodeIterator runiter(runNode);
0122 auto runDetNode = dynamic_cast<PHCompositeNode*>(runiter.findFirst("PHCompositeNode", m_detector));
0123 if (!runDetNode)
0124 {
0125 runDetNode = new PHCompositeNode(m_detector);
0126 runNode->addNode(runDetNode);
0127 }
0128 std::string paramNodeName = "G4CELLPARAM_" + m_detector;
0129 SaveToNodeTree(runDetNode, paramNodeName);
0130
0131
0132 auto hitsetcontainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0133 if (!hitsetcontainer)
0134 {
0135 PHNodeIterator dstiter(dstNode);
0136 auto trkrnode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
0137 if (!trkrnode)
0138 {
0139 trkrnode = new PHCompositeNode("TRKR");
0140 dstNode->addNode(trkrnode);
0141 }
0142
0143 hitsetcontainer = new TrkrHitSetContainerv1;
0144 auto newNode = new PHIODataNode<PHObject>(hitsetcontainer, "TRKR_HITSET", "PHObject");
0145 trkrnode->addNode(newNode);
0146 }
0147
0148
0149 auto hittruthassoc = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
0150 if (!hittruthassoc)
0151 {
0152 PHNodeIterator dstiter(dstNode);
0153 auto trkrnode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
0154 if (!trkrnode)
0155 {
0156 trkrnode = new PHCompositeNode("TRKR");
0157 dstNode->addNode(trkrnode);
0158 }
0159
0160 hittruthassoc = new TrkrHitTruthAssocv1;
0161 auto newNode = new PHIODataNode<PHObject>(hittruthassoc, "TRKR_HITTRUTHASSOC", "PHObject");
0162 trkrnode->addNode(newNode);
0163 }
0164
0165
0166 m_truthtracks = findNode::getClass<TrkrTruthTrackContainer>(topNode, "TRKR_TRUTHTRACKCONTAINER");
0167 if (!m_truthtracks)
0168 {
0169 PHNodeIterator dstiter(dstNode);
0170 m_truthtracks = new TrkrTruthTrackContainerv1();
0171 auto newNode = new PHIODataNode<PHObject>(m_truthtracks, "TRKR_TRUTHTRACKCONTAINER", "PHObject");
0172 dstNode->addNode(newNode);
0173 }
0174
0175 m_truthclusters = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_TRUTHCLUSTERCONTAINER");
0176 if (!m_truthclusters)
0177 {
0178 m_truthclusters = new TrkrClusterContainerv4;
0179 auto newNode = new PHIODataNode<PHObject>(m_truthclusters, "TRKR_TRUTHCLUSTERCONTAINER", "PHObject");
0180 dstNode->addNode(newNode);
0181 }
0182
0183 m_truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0184 if (!m_truthinfo)
0185 {
0186 std::cout << PHWHERE << " PHG4TruthInfoContainer node not found on node tree" << std::endl;
0187 assert(m_truthinfo);
0188 }
0189
0190 if (record_ClusHitsVerbose)
0191 {
0192
0193 mClusHitsVerbose = findNode::getClass<ClusHitsVerbosev1>(topNode, "Trkr_TruthClusHitsVerbose");
0194 if (!mClusHitsVerbose)
0195 {
0196 PHNodeIterator dstiter(dstNode);
0197 auto DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
0198 if (!DetNode)
0199 {
0200 DetNode = new PHCompositeNode("TRKR");
0201 dstNode->addNode(DetNode);
0202 }
0203 mClusHitsVerbose = new ClusHitsVerbosev1();
0204 auto newNode = new PHIODataNode<PHObject>(mClusHitsVerbose, "Trkr_TruthClusHitsVerbose", "PHObject");
0205 DetNode->addNode(newNode);
0206 }
0207 }
0208
0209 makePixelMask(m_deadPixelMap, "MVTX_DeadPixelMap", "TotalDeadPixels");
0210 makePixelMask(m_hotPixelMap, "MVTX_HotPixelMap", "TotalHotPixels");
0211
0212 return Fun4AllReturnCodes::EVENT_OK;
0213 }
0214
0215 int PHG4MvtxHitReco::process_event(PHCompositeNode* topNode)
0216 {
0217 ActsGeometry* tgeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0218 if (!tgeometry)
0219 {
0220 std::cout << "Could not locate acts geometry" << std::endl;
0221 exit(1);
0222 }
0223
0224
0225 const std::string g4hitnodename = "G4HIT_" + m_detector;
0226 auto g4hitContainer = findNode::getClass<PHG4HitContainer>(topNode, g4hitnodename);
0227 assert(g4hitContainer);
0228
0229
0230 const std::string geonodename = "CYLINDERGEOM_" + m_detector;
0231 auto geoNode = findNode::getClass<PHG4CylinderGeomContainer>(topNode, geonodename);
0232 assert(geoNode);
0233
0234
0235 auto trkrHitSetContainer = findNode::getClass<TrkrHitSetContainer>(topNode, "TRKR_HITSET");
0236 assert(trkrHitSetContainer);
0237
0238
0239 auto hitTruthAssoc = findNode::getClass<TrkrHitTruthAssoc>(topNode, "TRKR_HITTRUTHASSOC");
0240 assert(hitTruthAssoc);
0241
0242
0243 double strobe_zero_tm_start = generate_strobe_zero_tm_start();
0244
0245
0246 std::pair<double, double> alpide_pulse = generate_alpide_pulse(0.0);
0247 double clearance = 200.0;
0248 m_tmax = m_extended_readout_time + alpide_pulse.first + clearance;
0249 m_tmin = alpide_pulse.second - clearance;
0250
0251
0252
0253
0254
0255 if (Verbosity() > 0)
0256 {
0257 std::cout << " m_strobe_width " << m_strobe_width << " m_strobe_separation " << m_strobe_separation << " strobe_zero_tm_start " << strobe_zero_tm_start << " m_extended_readout_time " << m_extended_readout_time << std::endl;
0258 }
0259
0260
0261 auto layer_range = g4hitContainer->getLayers();
0262 for (auto layer_it = layer_range.first; layer_it != layer_range.second; ++layer_it)
0263 {
0264
0265 const auto layer = *layer_it;
0266 assert(layer < 3);
0267
0268
0269 auto layergeom = dynamic_cast<CylinderGeom_Mvtx*>(geoNode->GetLayerGeom(layer));
0270 assert(layergeom);
0271
0272
0273 const PHG4HitContainer::ConstRange g4hit_range = g4hitContainer->getHits(layer);
0274
0275
0276 double xpixw = layergeom->get_pixel_x();
0277 double xpixw_half = xpixw / 2.0;
0278 double zpixw = layergeom->get_pixel_z();
0279 double zpixw_half = zpixw / 2.0;
0280 int maxNX = layergeom->get_NX();
0281 int maxNZ = layergeom->get_NZ();
0282
0283
0284 for (auto g4hit_it = g4hit_range.first; g4hit_it != g4hit_range.second; ++g4hit_it)
0285 {
0286
0287 auto g4hit = g4hit_it->second;
0288
0289 truthcheck_g4hit(g4hit, topNode);
0290
0291
0292 if (Verbosity() > 4)
0293 {
0294 g4hit->print();
0295 }
0296
0297 unsigned int n_replica = 1;
0298
0299
0300
0301
0302 double lead_edge = g4hit->get_t(0) * ns + alpide_pulse.first;
0303 double fall_edge = g4hit->get_t(1) * ns + alpide_pulse.second;
0304
0305 if (Verbosity() > 0)
0306 {
0307 std::cout << " MvtxHitReco: t0 " << g4hit->get_t(0) << " t1 " << g4hit->get_t(1) << " lead_edge " << lead_edge
0308 << " fall_edge " << fall_edge << " tmin " << m_tmin << " tmax " << m_tmax << std::endl;
0309 }
0310
0311
0312 if (lead_edge > m_tmax or fall_edge < m_tmin)
0313 {
0314 continue;
0315 }
0316
0317 double t0_strobe_frame = get_strobe_frame(lead_edge, strobe_zero_tm_start);
0318 double t1_strobe_frame = get_strobe_frame(fall_edge, strobe_zero_tm_start);
0319 n_replica += t1_strobe_frame - t0_strobe_frame;
0320
0321 if (Verbosity() > 1)
0322 {
0323 std::cout
0324 << "MVTX is in strobed timing mode\n"
0325 << "layer " << layer << " t0(ns) " << g4hit->get_t(0) << " t1(ns) " << g4hit->get_t(1) << "\n"
0326 << "strobe_zero_tm_start(us): " << strobe_zero_tm_start / microsecond << "\n"
0327 << "strobe width(us): " << m_strobe_width / microsecond << "\n"
0328 << "strobe separation(us): " << m_strobe_separation / microsecond << "\n"
0329 << "alpide pulse start(us): " << alpide_pulse.first / microsecond << "\n"
0330 << "alpide pulse end(us): " << alpide_pulse.second / microsecond << "\n"
0331 << "tm_zero_strobe_frame: " << t0_strobe_frame << "\n"
0332 << "tm_one_strobe_frame: " << t1_strobe_frame << "\n"
0333 << "number of hit replica: " << n_replica << "\n"
0334 << std::endl;
0335 }
0336
0337 assert(n_replica >= 1);
0338
0339
0340 int stave_number = g4hit->get_property_int(PHG4Hit::prop_stave_index);
0341 int chip_number = g4hit->get_property_int(PHG4Hit::prop_chip_index);
0342
0343 TVector3 local_in(g4hit->get_local_x(0), g4hit->get_local_y(0), g4hit->get_local_z(0));
0344 TVector3 local_out(g4hit->get_local_x(1), g4hit->get_local_y(1), g4hit->get_local_z(1));
0345 TVector3 midpoint((local_in.X() + local_out.X()) / 2.0, (local_in.Y() + local_out.Y()) / 2.0, (local_in.Z() + local_out.Z()) / 2.0);
0346
0347 if (Verbosity() > 2)
0348 {
0349 std::cout
0350 << " world entry point position: "
0351 << g4hit->get_x(0) << " " << g4hit->get_y(0) << " " << g4hit->get_z(0) << "\n"
0352 << " world exit point position: "
0353 << g4hit->get_x(1) << " " << g4hit->get_y(1) << " " << g4hit->get_z(1) << "\n"
0354 << " local coords of entry point from G4 "
0355 << g4hit->get_local_x(0) << " " << g4hit->get_local_y(0) << " " << g4hit->get_local_z(0)
0356 << std::endl;
0357
0358 TVector3 world_in(g4hit->get_x(0), g4hit->get_y(0), g4hit->get_z(0));
0359 auto hskey = MvtxDefs::genHitSetKey(layer, stave_number, chip_number, 0);
0360 auto surf = tgeometry->maps().getSiliconSurface(hskey);
0361
0362 TVector3 local_in_check = CylinderGeom_MvtxHelper::get_local_from_world_coords(surf, tgeometry, world_in);
0363 std::cout
0364 << " local coords of entry point from geom (a check) "
0365 << local_in_check.X() << " " << local_in_check.Y() << " " << local_in_check.Z() << "\n"
0366 << " local coords of exit point from G4 "
0367 << g4hit->get_local_x(1) << " " << g4hit->get_local_y(1) << " " << g4hit->get_local_z(1)
0368 << "\n"
0369 << " local coords of exit point from geom (a check) "
0370 << local_out.X() << " " << local_out.Y() << " " << local_out.Z()
0371 << std::endl;
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 int pixel_number_in = layergeom->get_pixel_from_local_coords(local_in);
0415
0416 int pixel_number_out = layergeom->get_pixel_from_local_coords(local_out);
0417
0418 if (pixel_number_in < 0 || pixel_number_out < 0)
0419 {
0420 std::cout
0421 << "Oops! got negative pixel number in layer " << layergeom->get_layer()
0422 << " pixel_number_in " << pixel_number_in
0423 << " pixel_number_out " << pixel_number_out
0424 << " local_in = " << local_in.X() << " " << local_in.Y() << " " << local_in.Z()
0425 << " local_out = " << local_out.X() << " " << local_out.Y() << " " << local_out.Z()
0426 << std::endl;
0427 return Fun4AllReturnCodes::ABORTEVENT;
0428 }
0429
0430 if (Verbosity() > 3)
0431 {
0432 std::cout
0433 << "entry pixel number " << pixel_number_in
0434 << " exit pixel number " << pixel_number_out
0435 << std::endl;
0436 }
0437
0438 std::vector<int> vpixel;
0439 std::vector<int> vxbin;
0440 std::vector<int> vzbin;
0441 std::vector<std::pair<double, double> > venergy;
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459 TVector3 pathvec = local_in - local_out;
0460
0461
0462
0463
0464
0465
0466
0467 double diffusion_width_max = 25.0e-04;
0468 double diffusion_width_min = 8.0e-04;
0469
0470 double ydrift_max = pathvec.Y();
0471 int nsegments = 4;
0472
0473
0474
0475
0476
0477 int xbin_in = layergeom->get_pixel_X_from_pixel_number(pixel_number_in);
0478 int zbin_in = layergeom->get_pixel_Z_from_pixel_number(pixel_number_in);
0479 int xbin_out = layergeom->get_pixel_X_from_pixel_number(pixel_number_out);
0480 int zbin_out = layergeom->get_pixel_Z_from_pixel_number(pixel_number_out);
0481
0482 int xbin_max, xbin_min;
0483 int nadd = 2;
0484 if (xbin_in > xbin_out)
0485 {
0486 xbin_max = xbin_in + nadd;
0487 xbin_min = xbin_out - nadd;
0488 }
0489 else
0490 {
0491 xbin_max = xbin_out + nadd;
0492 xbin_min = xbin_in - nadd;
0493 }
0494
0495 int zbin_max, zbin_min;
0496 if (zbin_in > zbin_out)
0497 {
0498 zbin_max = zbin_in + nadd;
0499 zbin_min = zbin_out - nadd;
0500 }
0501 else
0502 {
0503 zbin_max = zbin_out + nadd;
0504 zbin_min = zbin_in - nadd;
0505 }
0506
0507
0508
0509 if (xbin_min < 0)
0510 {
0511 xbin_min = 0;
0512 }
0513 if (zbin_min < 0)
0514 {
0515 zbin_min = 0;
0516 }
0517 if (xbin_max >= maxNX)
0518 {
0519 xbin_max = maxNX - 1;
0520 }
0521 if (zbin_max >= maxNZ)
0522 {
0523 xbin_max = maxNZ - 1;
0524 }
0525
0526 if (Verbosity() > 1)
0527 {
0528 std::cout << " xbin_in " << xbin_in << " xbin_out " << xbin_out << " xbin_min " << xbin_min << " xbin_max " << xbin_max << std::endl;
0529 std::cout << " zbin_in " << zbin_in << " zbin_out " << zbin_out << " zbin_min " << zbin_min << " zbin_max " << zbin_max << std::endl;
0530 }
0531
0532
0533
0534 if (xbin_max - xbin_min > 12 || zbin_max - zbin_min > 12)
0535 {
0536 continue;
0537 }
0538
0539
0540 double pixenergy[12][12] = {};
0541 double pixeion[12][12] = {};
0542
0543
0544 for (int i = 0; i < nsegments; i++)
0545 {
0546
0547
0548
0549 double interval = 2 * (double) i + 1;
0550 double frac = interval / (double) (2 * nsegments);
0551 TVector3 segvec(pathvec.X() * frac, pathvec.Y() * frac, pathvec.Z() * frac);
0552 segvec = segvec + local_out;
0553
0554
0555
0556 double ydrift = segvec.Y() - local_out.Y();
0557
0558
0559
0560 double ydiffusion_radius = diffusion_width_min + (ydrift / ydrift_max) * (diffusion_width_max - diffusion_width_min);
0561
0562 if (Verbosity() > 5)
0563 {
0564 std::cout
0565 << " segment " << i
0566 << " interval " << interval
0567 << " frac " << frac
0568 << " local_in.X " << local_in.X()
0569 << " local_in.Z " << local_in.Z()
0570 << " local_in.Y " << local_in.Y()
0571 << " pathvec.X " << pathvec.X()
0572 << " pathvec.Z " << pathvec.Z()
0573 << " pathvec.Y " << pathvec.Y()
0574 << " segvec.X " << segvec.X()
0575 << " segvec.Z " << segvec.Z()
0576 << " segvec.Y " << segvec.Y()
0577 << " ydrift " << ydrift
0578 << " ydrift_max " << ydrift_max
0579 << " ydiffusion_radius " << ydiffusion_radius
0580 << std::endl;
0581 }
0582
0583 for (int ix = xbin_min; ix <= xbin_max; ix++)
0584 {
0585 for (int iz = zbin_min; iz <= zbin_max; iz++)
0586 {
0587
0588 int pixnum = layergeom->get_pixel_number_from_xbin_zbin(ix, iz);
0589
0590 if (pixnum < 0)
0591 {
0592 std::cout
0593 << " pixnum < 0 , pixnum = " << pixnum << "\n"
0594 << " ix " << ix << " iz " << iz << "\n"
0595 << " xbin_min " << xbin_min << " zbin_min " << zbin_min << "\n"
0596 << " xbin_max " << xbin_max << " zbin_max " << zbin_max << "\n"
0597 << " maxNX " << maxNX << " maxNZ " << maxNZ
0598 << std::endl;
0599 }
0600
0601 TVector3 tmp = layergeom->get_local_coords_from_pixel(pixnum);
0602
0603 double x1 = tmp.X() - xpixw_half;
0604 double z1 = tmp.Z() + zpixw_half;
0605 double x2 = tmp.X() + xpixw_half;
0606 double z2 = tmp.Z() - zpixw_half;
0607
0608
0609
0610 double pixarea_frac = PHG4Utils::circle_rectangle_intersection(x1, z1, x2, z2, segvec.X(), segvec.Z(), ydiffusion_radius) / (M_PI * pow(ydiffusion_radius, 2));
0611
0612 pixenergy[ix - xbin_min][iz - zbin_min] += pixarea_frac * g4hit->get_edep() / (float) nsegments;
0613 if (g4hit->has_property(PHG4Hit::prop_eion))
0614 {
0615 pixeion[ix - xbin_min][iz - zbin_min] += pixarea_frac * g4hit->get_eion() / (float) nsegments;
0616 }
0617 if (Verbosity() > 5)
0618 {
0619 std::cout
0620 << " pixnum " << pixnum << " xbin " << ix << " zbin " << iz
0621 << " pixel_area fraction of circle " << pixarea_frac << " accumulated pixel energy " << pixenergy[ix - xbin_min][iz - zbin_min]
0622 << std::endl;
0623 }
0624 }
0625 }
0626 }
0627
0628
0629 for (int ix = xbin_min; ix <= xbin_max; ix++)
0630 {
0631 for (int iz = zbin_min; iz <= zbin_max; iz++)
0632 {
0633 if (pixenergy[ix - xbin_min][iz - zbin_min] > 0.0)
0634 {
0635 int pixnum = layergeom->get_pixel_number_from_xbin_zbin(ix, iz);
0636 vpixel.push_back(pixnum);
0637 vxbin.push_back(ix);
0638 vzbin.push_back(iz);
0639 std::pair<double, double> tmppair = std::make_pair(pixenergy[ix - xbin_min][iz - zbin_min], pixeion[ix - xbin_min][iz - zbin_min]);
0640 venergy.push_back(tmppair);
0641 if (Verbosity() > 1)
0642 {
0643 std::cout
0644 << " Added pixel number " << pixnum << " xbin " << ix
0645 << " zbin " << iz << " to vectors with energy " << pixenergy[ix - xbin_min][iz - zbin_min]
0646 << std::endl;
0647 }
0648 }
0649 }
0650 }
0651
0652
0653
0654
0655
0656
0657
0658 for (unsigned int i1 = 0; i1 < vpixel.size(); i1++)
0659 {
0660
0661
0662 for (unsigned int i_rep = 0; i_rep < n_replica; i_rep++)
0663 {
0664 int strobe = t0_strobe_frame + i_rep;
0665
0666 if (strobe < -16)
0667 {
0668 strobe = -16;
0669 }
0670 if (strobe >= 16)
0671 {
0672 strobe = 15;
0673 }
0674
0675
0676 TrkrDefs::hitsetkey hitsetkey = MvtxDefs::genHitSetKey(layer, stave_number, chip_number, strobe);
0677
0678 TrkrHitSetContainer::Iterator hitsetit = trkrHitSetContainer->findOrAddHitSet(hitsetkey);
0679
0680
0681 TrkrDefs::hitkey hitkey = MvtxDefs::genHitKey(vzbin[i1], vxbin[i1]);
0682
0683 TrkrHit* hit = nullptr;
0684 hit = hitsetit->second->getHit(hitkey);
0685
0686 if (hit)
0687 {
0688 if (Verbosity() > 0)
0689 {
0690 std::cout << PHWHERE << "::" << __func__
0691 << " - duplicated hit, hitsetkey: " << hitsetkey
0692 << " hitkey: " << hitkey << std::endl;
0693 }
0694 continue;
0695 }
0696 const TrkrDefs::hitsetkey hitsetkeymask = MvtxDefs::genHitSetKey(layer, stave_number, chip_number, 0);
0697
0698
0699 double hitenergy = venergy[i1].first * TrkrDefs::MvtxEnergyScaleup;
0700 addtruthhitset(hitsetkey, hitkey, hitenergy);
0701
0702 if ((std::find(m_deadPixelMap.begin(), m_deadPixelMap.end(), std::make_pair(hitsetkeymask, hitkey)) == m_deadPixelMap.end()) && (std::find(m_hotPixelMap.begin(), m_hotPixelMap.end(), std::make_pair(hitsetkeymask, hitkey)) == m_hotPixelMap.end()))
0703 {
0704
0705 hit = new TrkrHitv2();
0706
0707 hit->addEnergy(hitenergy);
0708 hitsetit->second->addHitSpecificKey(hitkey, hit);
0709 }
0710 else
0711 {
0712 continue;
0713 }
0714
0715 addtruthhitset(hitsetkey, hitkey, hitenergy);
0716
0717 if (Verbosity() > 0)
0718 {
0719 std::cout << "Layer: " << layer << ", Stave: " << (uint16_t) MvtxDefs::getStaveId(hitsetkey) << ", Chip: " << (uint16_t) MvtxDefs::getChipId(hitsetkey) << ", Row: " << (uint16_t) MvtxDefs::getRow(hitkey) << ", Col: " << (uint16_t) MvtxDefs::getCol(hitkey) << ", Strobe: " << (int) MvtxDefs::getStrobeId(hitsetkey) << ", added hit " << hitkey << " to hitset " << hitsetkey << " with energy " << hit->getEnergy() / TrkrDefs::MvtxEnergyScaleup << std::endl;
0720 }
0721
0722
0723
0724
0725
0726
0727
0728 TrkrDefs::hitsetkey bare_hitsetkey = zero_strobe_bits(hitsetkey);
0729 hitTruthAssoc->findOrAddAssoc(bare_hitsetkey, hitkey, g4hit_it->first);
0730 }
0731 }
0732 }
0733
0734 }
0735
0736
0737 if (Verbosity() > 0)
0738 {
0739 std::cout << "From PHG4MvtxHitReco: " << std::endl;
0740 hitTruthAssoc->identify();
0741 }
0742
0743
0744
0745 end_event_truthcluster(topNode);
0746
0747 if (Verbosity() > 3)
0748 {
0749 int nclusprint = -1;
0750 std::cout << PHWHERE << ": content of clusters " << std::endl;
0751 auto& tmap = m_truthtracks->getMap();
0752 std::cout << " Number of tracks: " << tmap.size() << std::endl;
0753 for (auto& _pair : tmap)
0754 {
0755 auto& track = _pair.second;
0756 std::cout << (boost::format("id(%2i) phi:eta:pt(%5.2f:%5.2f:%5.2f) nclusters(") % (int) track->getTrackid() % track->getPhi() % track->getPseudoRapidity() % track->getPt()).str() << track->getClusters().size() << ") " << std::endl;
0757 int nclus = 0;
0758 for (auto cluskey : track->getClusters())
0759 {
0760 std::cout << " "
0761 << ((int) TrkrDefs::getHitSetKeyFromClusKey(cluskey)) << ":index(" << ((int) TrkrDefs::getClusIndex(cluskey)) << ")" << std::endl;
0762 ++nclus;
0763 if (nclusprint > 0 && nclus >= nclusprint)
0764 {
0765 std::cout << " ... ";
0766 break;
0767 }
0768 }
0769 }
0770 std::cout << PHWHERE << " ----- end of clusters " << std::endl;
0771 }
0772
0773 if (m_is_emb)
0774 {
0775 cluster_truthhits(topNode);
0776 prior_g4hit = nullptr;
0777 }
0778
0779 return Fun4AllReturnCodes::EVENT_OK;
0780 }
0781
0782 std::pair<double, double> PHG4MvtxHitReco::generate_alpide_pulse(const double energy_deposited)
0783 {
0784
0785 if (Verbosity() > 2)
0786 {
0787 std::cout << "energy_deposited: " << energy_deposited << std::endl;
0788 }
0789
0790
0791
0792
0793
0794
0795
0796
0797 return std::make_pair<double, double>(1.5 * microsecond, 5.9 * microsecond);
0798 }
0799
0800 double PHG4MvtxHitReco::generate_strobe_zero_tm_start()
0801 {
0802 return -1. * gsl_rng_uniform_pos(m_rng.get()) * (m_strobe_separation + m_strobe_width);
0803 }
0804
0805 int PHG4MvtxHitReco::get_strobe_frame(double alpide_time, double strobe_zero_tm_start)
0806 {
0807 int strobe_frame = int((alpide_time - strobe_zero_tm_start) / (m_strobe_width + m_strobe_separation));
0808 strobe_frame += (alpide_time < strobe_zero_tm_start) ? -1 : 0;
0809 return strobe_frame;
0810 }
0811
0812 void PHG4MvtxHitReco::set_timing_window(const int detid, const double tmin, const double tmax)
0813 {
0814 if (false)
0815 {
0816 std::cout
0817 << "PHG4MvtxHitReco: Set Mvtx timing window parameters from macro for layer = "
0818 << detid << " to tmin = " << tmin << " tmax = " << tmax
0819 << std::endl;
0820 }
0821
0822 return;
0823 }
0824
0825 void PHG4MvtxHitReco::SetDefaultParameters()
0826 {
0827
0828 set_default_double_param("mvtx_tmin", -5000);
0829 set_default_double_param("mvtx_tmax", 5000);
0830 set_default_double_param("mvtx_strobe_width", 5 * microsecond);
0831 set_default_double_param("mvtx_strobe_separation", 0.);
0832 set_default_int_param("mvtx_in_sphenix_srdo", (int) false);
0833 return;
0834 }
0835
0836 TrkrDefs::hitsetkey PHG4MvtxHitReco::zero_strobe_bits(TrkrDefs::hitsetkey hitsetkey)
0837 {
0838 unsigned int layer = TrkrDefs::getLayer(hitsetkey);
0839 unsigned int stave = MvtxDefs::getStaveId(hitsetkey);
0840 unsigned int chip = MvtxDefs::getChipId(hitsetkey);
0841 TrkrDefs::hitsetkey bare_hitsetkey = MvtxDefs::genHitSetKey(layer, stave, chip, 0);
0842
0843 return bare_hitsetkey;
0844 }
0845
0846 PHG4MvtxHitReco::~PHG4MvtxHitReco()
0847 {
0848 delete m_truth_hits;
0849 }
0850
0851 void PHG4MvtxHitReco::truthcheck_g4hit(PHG4Hit* g4hit, PHCompositeNode* topNode)
0852 {
0853 int new_trkid = (g4hit == nullptr) ? -1 : g4hit->get_trkid();
0854 bool is_new_track = (new_trkid != m_trkid);
0855 if (Verbosity() > 5)
0856 {
0857 std::cout << PHWHERE << std::endl
0858 << " -> Checking status of PHG4Hit. Track id(" << new_trkid << ")" << std::endl;
0859 }
0860 if (!is_new_track)
0861 {
0862
0863
0864
0865
0866 if (m_is_emb)
0867 {
0868
0869
0870
0871 if (prior_g4hit != nullptr && (std::abs(prior_g4hit->get_x(0) - g4hit->get_x(0)) > max_g4hitstep || std::abs(prior_g4hit->get_y(0) - g4hit->get_y(0)) > max_g4hitstep))
0872 {
0873
0874 cluster_truthhits(topNode);
0875 }
0876 prior_g4hit = g4hit;
0877 }
0878 return;
0879 }
0880
0881 if (Verbosity() > 2)
0882 {
0883 std::cout << PHWHERE << std::endl
0884 << " -> Found new embedded track with id: " << new_trkid << std::endl;
0885 }
0886 if (m_is_emb)
0887 {
0888 cluster_truthhits(topNode);
0889 m_current_track = nullptr;
0890 prior_g4hit = nullptr;
0891 }
0892 m_trkid = new_trkid;
0893 m_is_emb = m_truthinfo->isEmbeded(m_trkid);
0894 if (m_is_emb)
0895 {
0896 m_current_track = m_truthtracks->getTruthTrack(m_trkid, m_truthinfo);
0897 prior_g4hit = g4hit;
0898 }
0899 }
0900
0901 void PHG4MvtxHitReco::end_event_truthcluster(PHCompositeNode* topNode)
0902 {
0903 if (m_is_emb)
0904 {
0905 cluster_truthhits(topNode);
0906 m_current_track = nullptr;
0907 m_trkid = -1;
0908 m_is_emb = false;
0909 }
0910 m_hitsetkey_cnt.clear();
0911 }
0912
0913 void PHG4MvtxHitReco::addtruthhitset(
0914 TrkrDefs::hitsetkey hitsetkey,
0915 TrkrDefs::hitkey hitkey,
0916 float neffelectrons)
0917 {
0918 if (!m_is_emb)
0919 {
0920 return;
0921 }
0922 TrkrHitSetContainer::Iterator hitsetit = m_truth_hits->findOrAddHitSet(hitsetkey);
0923
0924 TrkrHit* hit = nullptr;
0925 hit = hitsetit->second->getHit(hitkey);
0926 if (!hit)
0927 {
0928
0929 hit = new TrkrHitv2();
0930 hitsetit->second->addHitSpecificKey(hitkey, hit);
0931 }
0932
0933 hit->addEnergy(neffelectrons);
0934 }
0935
0936 void PHG4MvtxHitReco::cluster_truthhits(PHCompositeNode* topNode)
0937 {
0938
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002 std::multimap<TrkrDefs::hitsetkey, TrkrDefs::hitsetkey> hitset_multimap;
1003 std::set<TrkrDefs::hitsetkey> bare_hitset_set;
1004
1005 TrkrHitSetContainer::ConstRange hitsetrange = m_truth_hits->getHitSets(TrkrDefs::TrkrId::mvtxId);
1006 for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first;
1007 hitsetitr != hitsetrange.second;
1008 ++hitsetitr)
1009 {
1010 auto hitsetkey = hitsetitr->first;
1011
1012
1013 unsigned int layer = TrkrDefs::getLayer(hitsetitr->first);
1014 unsigned int stave = MvtxDefs::getStaveId(hitsetitr->first);
1015 unsigned int chip = MvtxDefs::getChipId(hitsetitr->first);
1016 auto bare_hitsetkey = MvtxDefs::genHitSetKey(layer, stave, chip, 0);
1017
1018 hitset_multimap.insert(std::make_pair(bare_hitsetkey, hitsetkey));
1019 bare_hitset_set.insert(bare_hitsetkey);
1020
1021 if (Verbosity() > 0)
1022 {
1023 std::cout << " found hitsetkey " << hitsetkey << " for bare_hitsetkey " << bare_hitsetkey << std::endl;
1024 }
1025 }
1026
1027
1028
1029 for (unsigned int bare_hitsetkey : bare_hitset_set)
1030 {
1031 TrkrHitSet* bare_hitset = (m_truth_hits->findOrAddHitSet(bare_hitsetkey))->second;
1032 if (Verbosity() > 0)
1033 {
1034 std::cout << " bare_hitset " << bare_hitsetkey << " initially has " << bare_hitset->size() << " hits " << std::endl;
1035 }
1036
1037 auto bare_hitsetrange = hitset_multimap.equal_range(bare_hitsetkey);
1038 for (auto it = bare_hitsetrange.first; it != bare_hitsetrange.second; ++it)
1039 {
1040 auto hitsetkey = it->second;
1041
1042 int strobe = MvtxDefs::getStrobeId(hitsetkey);
1043 if (strobe != 0)
1044 {
1045 if (Verbosity() > 0)
1046 {
1047 std::cout << " process hitsetkey " << hitsetkey << " for bare_hitsetkey " << bare_hitsetkey << std::endl;
1048 }
1049
1050
1051 TrkrHitSet* hitset = m_truth_hits->findHitSet(hitsetkey);
1052
1053 if (Verbosity() > 0)
1054 {
1055 std::cout << " hitsetkey " << hitsetkey << " has strobe " << strobe << " and has " << hitset->size() << " hits, so copy it" << std::endl;
1056 }
1057
1058 TrkrHitSet::ConstRange hitrangei = hitset->getHits();
1059 for (TrkrHitSet::ConstIterator hitr = hitrangei.first;
1060 hitr != hitrangei.second;
1061 ++hitr)
1062 {
1063 auto hitkey = hitr->first;
1064 if (Verbosity() > 0)
1065 {
1066 std::cout << " found hitkey " << hitkey << std::endl;
1067 }
1068
1069 auto tmp_hit = bare_hitset->getHit(hitkey);
1070 if (tmp_hit)
1071 {
1072 if (Verbosity() > 0)
1073 {
1074 std::cout << " hitkey " << hitkey << " is already in bare hitsest, do not copy" << std::endl;
1075 }
1076 continue;
1077 }
1078
1079
1080 if (Verbosity() > 0)
1081 {
1082 std::cout << " copying over hitkey " << hitkey << std::endl;
1083 }
1084 auto old_hit = hitr->second;
1085 TrkrHit* new_hit = new TrkrHitv2();
1086 new_hit->setAdc(old_hit->getAdc());
1087 bare_hitset->addHitSpecificKey(hitkey, new_hit);
1088 }
1089
1090
1091 m_truth_hits->removeHitSet(hitsetkey);
1092 }
1093 }
1094 }
1095
1096
1097
1098
1099 PHG4CylinderGeomContainer* geom_container = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MVTX");
1100 if (!geom_container)
1101 {
1102 std::cout << PHWHERE << std::endl;
1103 std::cout << "WARNING: cannot find the geometry CYLINDERGEOM_MVTX" << std::endl;
1104 m_truth_hits->Reset();
1105 return;
1106 }
1107
1108
1109
1110
1111
1112
1113 hitsetrange = m_truth_hits->getHitSets(TrkrDefs::TrkrId::mvtxId);
1114 for (TrkrHitSetContainer::ConstIterator hitsetitr = hitsetrange.first;
1115 hitsetitr != hitsetrange.second;
1116 ++hitsetitr)
1117 {
1118 TrkrHitSet* hitset = hitsetitr->second;
1119
1120
1121 if (Verbosity() > 0)
1122 {
1123 unsigned int layer = TrkrDefs::getLayer(hitsetitr->first);
1124 unsigned int stave = MvtxDefs::getStaveId(hitsetitr->first);
1125 unsigned int chip = MvtxDefs::getChipId(hitsetitr->first);
1126 unsigned int strobe = MvtxDefs::getStrobeId(hitsetitr->first);
1127 std::cout << "MvtxClusterizer found hitsetkey " << hitsetitr->first << " layer " << layer << " stave " << stave << " chip " << chip << " strobe " << strobe << std::endl;
1128 }
1129
1130 if (Verbosity() > 2)
1131 {
1132 hitset->identify();
1133 }
1134
1135 TrkrHitSet::ConstRange hitrangei = hitset->getHits();
1136
1137 auto hitsetkey = hitset->getHitSetKey();
1138 auto ckey = TrkrDefs::genClusKey(hitsetkey, 0);
1139
1140
1141 std::set<int> phibins;
1142 std::set<int> zbins;
1143
1144
1145 double locxsum = 0.;
1146 double loczsum = 0.;
1147
1148 double locclusx = NAN;
1149 double locclusz = NAN;
1150
1151
1152 int layer = TrkrDefs::getLayer(ckey);
1153 auto layergeom = dynamic_cast<CylinderGeom_Mvtx*>(geom_container->GetLayerGeom(layer));
1154 if (!layergeom)
1155 {
1156 exit(1);
1157 }
1158
1159
1160
1161 double sum_adc{0.};
1162 for (auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit)
1163 {
1164 sum_adc += ihit->second->getAdc();
1165 }
1166 const double threshold = sum_adc * m_pixel_thresholdrat;
1167 std::map<int, unsigned int> m_iphi, m_it, m_iphiCut, m_itCut;
1168
1169
1170
1171 double npixels{0.};
1172 for (auto ihit = hitrangei.first; ihit != hitrangei.second; ++ihit)
1173 {
1174 const auto adc = ihit->second->getAdc();
1175 int col = MvtxDefs::getCol(ihit->first);
1176 int row = MvtxDefs::getRow(ihit->first);
1177
1178 if (mClusHitsVerbose)
1179 {
1180 std::map<int, unsigned int>& m_phi = (adc < threshold) ? m_iphiCut : m_iphi;
1181 std::map<int, unsigned int>& m_z = (adc < threshold) ? m_itCut : m_it;
1182
1183 auto pnew = m_phi.try_emplace(row, adc);
1184 if (!pnew.second)
1185 {
1186 pnew.first->second += adc;
1187 }
1188
1189 pnew = m_z.try_emplace(col, adc);
1190 if (!pnew.second)
1191 {
1192 pnew.first->second += adc;
1193 }
1194 }
1195 if (adc < threshold)
1196 {
1197 continue;
1198 }
1199
1200
1201 npixels += 1.;
1202 zbins.insert(col);
1203 phibins.insert(row);
1204
1205
1206 auto local_coords = layergeom->get_local_coords_from_pixel(row, col);
1207
1208
1209
1210
1211
1212
1213 local_coords.SetY(1e-4);
1214
1215
1216 locxsum += local_coords.X();
1217 loczsum += local_coords.Z();
1218
1219 }
1220 if (mClusHitsVerbose)
1221 {
1222 if (Verbosity() > 10)
1223 {
1224 for (auto& hit : m_iphi)
1225 {
1226 std::cout << " m_phi(" << hit.first << " : " << hit.second << ") " << std::endl;
1227 }
1228 }
1229 for (auto& hit : m_iphi)
1230 {
1231 mClusHitsVerbose->addPhiHit(hit.first, (float) hit.second);
1232 }
1233 for (auto& hit : m_it)
1234 {
1235 mClusHitsVerbose->addZHit(hit.first, (float) hit.second);
1236 }
1237 for (auto& hit : m_iphiCut)
1238 {
1239 mClusHitsVerbose->addPhiCutHit(hit.first, (float) hit.second);
1240 }
1241 for (auto& hit : m_itCut)
1242 {
1243 mClusHitsVerbose->addZCutHit(hit.first, (float) hit.second);
1244 }
1245 }
1246
1247
1248 locclusx = locxsum / npixels;
1249 locclusz = loczsum / npixels;
1250
1251 const double pitch = layergeom->get_pixel_x();
1252 const double length = layergeom->get_pixel_z();
1253 const double phisize = phibins.size() * pitch;
1254 const double zsize = zbins.size() * length;
1255
1256
1257 if (Verbosity() > 0)
1258 {
1259 std::cout << " MvtxClusterizer: cluskey " << ckey << " layer " << layer << " rad " << layergeom->get_radius() << " phibins " << phibins.size() << " pitch " << pitch << " phisize " << phisize
1260 << " zbins " << zbins.size() << " length " << length << " zsize " << zsize
1261 << " local x " << locclusx << " local y " << locclusz
1262 << std::endl;
1263 }
1264
1265
1266
1267 if (m_cluster_version == 4)
1268 {
1269 auto clus = std::make_unique<TrkrClusterv4>();
1270 clus->setAdc(npixels);
1271 clus->setLocalX(locclusx);
1272 clus->setLocalY(locclusz);
1273
1274 clus->setPhiSize(phibins.size());
1275 clus->setZSize(zbins.size());
1276
1277
1278 clus->setSubSurfKey(0);
1279
1280 if (Verbosity() > 2)
1281 {
1282 clus->identify();
1283 }
1284
1285
1286 m_hitsetkey_cnt.try_emplace(hitsetkey, 0);
1287 unsigned int& cnt = m_hitsetkey_cnt[hitsetkey];
1288 ckey = TrkrDefs::genClusKey(hitsetkey, cnt);
1289 m_truthclusters->addClusterSpecifyKey(ckey, clus.release());
1290 m_current_track->addCluster(ckey);
1291 if (mClusHitsVerbose)
1292 {
1293 mClusHitsVerbose->push_hits(ckey);
1294 }
1295 ++cnt;
1296 }
1297 else
1298 {
1299 std::cout << PHWHERE << std::endl;
1300 std::cout << "Error: only cluster version 4 allowed." << std::endl;
1301 }
1302 }
1303 m_truth_hits->Reset();
1304 prior_g4hit = nullptr;
1305 return;
1306 }
1307
1308 void PHG4MvtxHitReco::makePixelMask(hitMask& aMask, const std::string& dbName, const std::string& totalPixelsToMask)
1309 {
1310 std::string database = CDBInterface::instance()->getUrl(dbName);
1311 CDBTTree* cdbttree = new CDBTTree(database);
1312
1313 int NPixel = -1;
1314 NPixel = cdbttree->GetSingleIntValue(totalPixelsToMask);
1315
1316 for (int i = 0; i < NPixel; i++)
1317 {
1318 int Layer = cdbttree->GetIntValue(i, "layer");
1319 int Stave = cdbttree->GetIntValue(i, "stave");
1320 int Chip = cdbttree->GetIntValue(i, "chip");
1321 int Col = cdbttree->GetIntValue(i, "col");
1322 int Row = cdbttree->GetIntValue(i, "row");
1323 if (Verbosity() > VERBOSITY_A_LOT)
1324 {
1325 std::cout << dbName << ": Will mask layer: " << Layer << ", stave: " << Stave << ", chip: " << Chip << ", row: " << Row << ", col: " << Col << std::endl;
1326 }
1327
1328 TrkrDefs::hitsetkey DeadPixelHitKey = MvtxDefs::genHitSetKey(Layer, Stave, Chip, 0);
1329 TrkrDefs::hitkey DeadHitKey = MvtxDefs::genHitKey(Col, Row);
1330 aMask.push_back({std::make_pair(DeadPixelHitKey, DeadHitKey)});
1331 }
1332
1333 delete cdbttree;
1334 }