File indexing completed on 2025-08-05 08:15:18
0001 #include "TrackDeadLayerTagging.h"
0002
0003 #include <phool/phool.h>
0004 #include <phool/getClass.h>
0005 #include <fun4all/PHTFileServer.h>
0006 #include <fun4all/Fun4AllServer.h>
0007
0008 #include <cdbobjects/CDBTTree.h>
0009 #include <ffamodules/CDBInterface.h>
0010
0011 #include <trackreco/ActsPropagator.h>
0012
0013 #include <trackbase/TrkrCluster.h>
0014 #include <trackbase/MvtxDefs.h>
0015 #include <trackbase/InttDefs.h>
0016 #include <trackbase/TrackFitUtils.h>
0017
0018 #include <mvtx/SegmentationAlpide.h>
0019 #include <intt/CylinderGeomIntt.h>
0020 #include <intt/InttMapping.h>
0021 #include <tpc/TpcGlobalPositionWrapper.h>
0022
0023 #include <TNtuple.h>
0024 #include <TH1.h>
0025
0026 #include <iostream>
0027
0028
0029 TrackDeadLayerTagging::TrackDeadLayerTagging(const std::string &name):
0030 SubsysReco(name)
0031 {
0032
0033 _event = 0;
0034 _outfile = "dead_layers.root";
0035 }
0036
0037
0038 int TrackDeadLayerTagging::Init(PHCompositeNode *topNode)
0039 {
0040 std::cout << PHWHERE << " Opening file " << _outfile << std::endl;
0041 PHTFileServer::get().open( _outfile, "RECREATE");
0042
0043 _missing_sensors = new TTree("missing_sensors","Sensors missing from track");
0044 _missing_sensors->Branch("event",&_event);
0045 _missing_sensors->Branch("trackID",&_trackID);
0046 _missing_sensors->Branch("layer",&_layer);
0047 _missing_sensors->Branch("phiID",&_phiID);
0048 _missing_sensors->Branch("zID",&_zID);
0049 _missing_sensors->Branch("localindX",&_localindX);
0050 _missing_sensors->Branch("localindY",&_localindY);
0051 _missing_sensors->Branch("isDead",&_isDead);
0052
0053
0054
0055 return 0;
0056 }
0057
0058
0059
0060 int TrackDeadLayerTagging::process_event(PHCompositeNode *topNode)
0061 {
0062 _event++;
0063 if(_event%1000==0) std::cout << PHWHERE << "Events processed: " << _event << std::endl;
0064
0065 GetNodes(topNode);
0066 get_surfaces();
0067 get_dead_sensor_maps();
0068
0069 if(Verbosity()>0)
0070 {
0071 std::cout << "--------------------------------" << std::endl;
0072 std::cout << "event " << _event << std::endl;
0073 }
0074
0075 find_dead_layers(topNode);
0076
0077 return 0;
0078 }
0079
0080 void TrackDeadLayerTagging::get_dead_sensor_maps()
0081 {
0082 std::string mvtx_hotpixel = CDBInterface::instance()->getUrl("MVTX_HotPixelMap");
0083 std::string mvtx_deadpixel = CDBInterface::instance()->getUrl("MVTX_DeadPixelMap");
0084 std::string intt_hotstrip = CDBInterface::instance()->getUrl("INTT_HotMap");
0085
0086
0087 std::unique_ptr<CDBTTree> mvtx_hottree = std::make_unique<CDBTTree>(mvtx_hotpixel);
0088 std::unique_ptr<CDBTTree> mvtx_deadtree = std::make_unique<CDBTTree>(mvtx_deadpixel);
0089 std::unique_ptr<CDBTTree> intt_hottree = std::make_unique<CDBTTree>(intt_hotstrip);
0090
0091
0092 mvtx_hottree->LoadCalibrations();
0093 mvtx_deadtree->LoadCalibrations();
0094 intt_hottree->LoadCalibrations();
0095
0096
0097 int n_mvtxhot = mvtx_hottree->GetSingleIntValue("TotalHotPixels");
0098 int n_mvtxdead = mvtx_deadtree->GetSingleIntValue("TotalDeadPixels");
0099 int n_intthot = intt_hottree->GetSingleIntValue("size");
0100
0101
0102 for(int i=0; i<n_mvtxhot; i++)
0103 {
0104 int layer = mvtx_hottree->GetIntValue(i,"layer");
0105 MissingSensor hotsensor_mvtx = {
0106 layer,
0107 mvtx_hottree->GetIntValue(i,"stave"),
0108 mvtx_hottree->GetIntValue(i,"chip"),
0109 mvtx_hottree->GetIntValue(i,"row"),
0110 mvtx_hottree->GetIntValue(i,"col")
0111 };
0112 if(layer>=0&&layer<=2)
0113 {
0114 _dead_sensors[layer].push_back(hotsensor_mvtx);
0115 }
0116 }
0117 for(int i=0; i<n_mvtxdead; i++)
0118 {
0119 int layer = mvtx_hottree->GetIntValue(i,"layer");
0120 MissingSensor deadsensor_mvtx = {
0121 layer,
0122 mvtx_deadtree->GetIntValue(i,"stave"),
0123 mvtx_deadtree->GetIntValue(i,"chip"),
0124 mvtx_deadtree->GetIntValue(i,"row"),
0125 mvtx_deadtree->GetIntValue(i,"col")
0126 };
0127 if(layer>=0&&layer<=2)
0128 {
0129 _dead_sensors[layer].push_back(deadsensor_mvtx);
0130 }
0131 }
0132
0133 for(int i=0; i<n_intthot; i++)
0134 {
0135 InttNameSpace::RawData_s raw_sensor;
0136 raw_sensor.felix_server = intt_hottree->GetIntValue(i,"felix_server");
0137 raw_sensor.felix_channel = intt_hottree->GetIntValue(i,"felix_channel");
0138 raw_sensor.chip = intt_hottree->GetIntValue(i,"chip");
0139 raw_sensor.channel = intt_hottree->GetIntValue(i,"channel");
0140 InttNameSpace::Offline_s offline_sensor = InttNameSpace::ToOffline(raw_sensor);
0141 MissingSensor hotsensor_intt = {
0142 offline_sensor.layer,
0143 offline_sensor.ladder_phi,
0144 offline_sensor.ladder_z,
0145 offline_sensor.strip_y,
0146 offline_sensor.strip_x
0147 };
0148 if(offline_sensor.layer>=3&&offline_sensor.layer<=6)
0149 {
0150 _dead_sensors[offline_sensor.layer].push_back(hotsensor_intt);
0151 }
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 }
0172
0173 void TrackDeadLayerTagging::get_surfaces()
0174 {
0175 for(int layer=0; layer<57; layer++)
0176 {
0177 if(layer<3)
0178 {
0179 int n_staves = 12 + 4*layer;
0180 int n_chips = 9;
0181 for(int stave_id=0;stave_id<n_staves;stave_id++)
0182 {
0183 for(int chip_id=0;chip_id<n_chips;chip_id++)
0184 {
0185 TrkrDefs::hitsetkey hskey = MvtxDefs::genHitSetKey(layer,stave_id,chip_id,0);
0186
0187
0188 _surface_map.insert(std::make_pair(_tGeometry->maps().getSiliconSurface(hskey)->geometryId(),hskey));
0189 }
0190 }
0191 }
0192 else if(layer<7)
0193 {
0194 int n_ladders;
0195 if(layer<5) n_ladders = 12;
0196 else n_ladders = 16;
0197 int n_zsegments = 4;
0198 for(int ladder_phi_id=0;ladder_phi_id<n_ladders;ladder_phi_id++)
0199 {
0200 for(int ladder_z_id=0;ladder_z_id<n_zsegments;ladder_z_id++)
0201 {
0202 TrkrDefs::hitsetkey hskey = InttDefs::genHitSetKey(layer,ladder_z_id,ladder_phi_id,0);
0203
0204
0205
0206
0207 _surface_map.insert(std::make_pair(_tGeometry->maps().getSiliconSurface(hskey)->geometryId(),hskey));
0208 }
0209 }
0210 }
0211 else if(layer<55)
0212 {
0213
0214 }
0215 else if(layer<57)
0216 {
0217
0218 }
0219 }
0220 }
0221
0222 std::vector<float> TrackDeadLayerTagging::getFitParams(TrackSeed* seed)
0223 {
0224 std::vector<float> fitpars;
0225 fitpars.push_back(1./fabs(seed->get_qOverR()));
0226 fitpars.push_back(seed->get_X0());
0227 fitpars.push_back(seed->get_Y0());
0228 fitpars.push_back(seed->get_slope());
0229 fitpars.push_back(seed->get_Z0());
0230 return fitpars;
0231 }
0232
0233 std::vector<MissingSpacePoint> TrackDeadLayerTagging::get_missing_space_points(SvtxTrack* track, std::vector<int> missing_layers)
0234 {
0235 std::vector<MissingSpacePoint> missing_space_points;
0236 if(useActsPropagator)
0237 {
0238 ActsPropagator propagator(_tGeometry);
0239
0240 ActsPropagator::BoundTrackParamResult result_trackparams = propagator.makeTrackParams(track,_vertexmap);
0241 if(result_trackparams.ok())
0242 {
0243 Acts::BoundTrackParameters trackparams = result_trackparams.value();
0244 for(int layer : missing_layers)
0245 {
0246 std::cout << "propagating track to layer " << layer << std::endl;
0247 ActsPropagator::BTPPairResult result_propagated_params = propagator.propagateTrack(trackparams,layer);
0248 if(result_propagated_params.ok())
0249 {
0250
0251 Acts::BoundTrackParameters updated_params = result_propagated_params.value().second;
0252 Surface surf = updated_params.referenceSurface().getSharedPtr();
0253
0254 Acts::Vector2 local_intersection = updated_params.localPosition() / Acts::UnitConstants::cm;
0255 Acts::Vector3 global_intersection = updated_params.position(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
0256 std::cout << "global coordinates: (" << global_intersection.x() << ", " << global_intersection.y() << ", " << global_intersection.z() << ")" << std::endl;
0257 std::cout << "propagated surface geometryId: " << surf->geometryId() << std::endl;
0258 std::cout << "local coordinates: (" << local_intersection.x() << ", " << local_intersection.y() << ")" << std::endl;
0259
0260
0261 trackparams = updated_params;
0262 MissingSpacePoint missingpoint = { layer, surf, local_intersection, global_intersection };
0263 missing_space_points.push_back(missingpoint);
0264 }
0265 else
0266 {
0267 std::cout << PHWHERE << "ActsPropagator returned error " << result_propagated_params.error().message() << " on propagating to layer " << layer << std::endl;
0268 }
0269 }
0270 }
0271 else
0272 {
0273 std::cout << PHWHERE << "ActsPropagator returned error " << result_trackparams.error().message() << " on formation of track params" << std::endl;
0274 }
0275 }
0276 else
0277 {
0278 TrackSeed* siliconseed = track->get_silicon_seed();
0279 TrackSeed* tpcseed = track->get_tpc_seed();
0280
0281
0282 std::vector<float> fitpars = tpcseed? getFitParams(tpcseed) : getFitParams(siliconseed);
0283
0284
0285 std::vector<std::pair<float,float>> filledlayer_pairs;
0286 if(siliconseed)
0287 {
0288 for(auto si_ckey = siliconseed->begin_cluster_keys(); si_ckey != siliconseed->end_cluster_keys(); si_ckey++)
0289 {
0290 TrkrCluster* c = _clustermap->findCluster(*si_ckey);
0291 Acts::Vector3 globalpos = _tGeometry->getGlobalPosition(*si_ckey,c);
0292 float phi = atan2(globalpos.y(),globalpos.x());
0293 filledlayer_pairs.push_back(std::make_pair(TrkrDefs::getLayer(*si_ckey),phi));
0294 }
0295 }
0296 if(tpcseed)
0297 {
0298 for(auto tpc_ckey = tpcseed->begin_cluster_keys(); tpc_ckey != tpcseed->end_cluster_keys(); tpc_ckey++)
0299 {
0300 TrkrCluster* c = _clustermap->findCluster(*tpc_ckey);
0301 TpcGlobalPositionWrapper glw;
0302 Acts::Vector3 globalpos = glw.getGlobalPositionDistortionCorrected(*tpc_ckey,c,track->get_crossing());
0303 float phi = atan2(globalpos.y(),globalpos.x());
0304 filledlayer_pairs.push_back(std::make_pair(TrkrDefs::getLayer(*tpc_ckey),phi));
0305 }
0306 }
0307
0308
0309 for(int missing_layer : missing_layers)
0310 {
0311 if(Verbosity()>1)
0312 {
0313 std::cout << "layer " << missing_layer << ":" << std::endl;
0314 }
0315 std::vector<MissingSpacePoint> compatible_surfaces;
0316
0317 for(auto& [geoId, hskey] : _surface_map)
0318 {
0319 if(TrkrDefs::getLayer(hskey)!=missing_layer) continue;
0320 Surface surface = _tGeometry->geometry().tGeometry->findSurface(geoId)->getSharedPtr();
0321 Acts::Vector3 surface_center = surface->center(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
0322 Acts::Vector3 intersection = TrackFitUtils::get_helix_surface_intersection(surface,fitpars,surface_center,_tGeometry);
0323 Acts::Vector3 tangent = TrackFitUtils::get_helix_tangent(fitpars,intersection).second;
0324 if(Verbosity()>2)
0325 {
0326 std::cout << "surface center: (" << surface_center.x() << ", " << surface_center.y() << ", " << surface_center.z() << ")" << std::endl;
0327 std::cout << "intersection with surface: (" << intersection.x() << ", " << intersection.y() << ", " << intersection.z() << ")" << std::endl;
0328 std::cout << "tangent vector: (" << tangent.x() << ", " << tangent.y() << ", " << tangent.z() << ")" << std::endl;
0329 }
0330 auto intersection_local_result = surface->globalToLocal(_tGeometry->geometry().getGeoContext(),intersection * Acts::UnitConstants::cm,tangent * Acts::UnitConstants::cm);
0331 if(!intersection_local_result.ok())
0332 {
0333 if(Verbosity()>2)
0334 {
0335 std::cout << "local coordinate conversion failed..." << std::endl;
0336 }
0337 continue;
0338 }
0339 Acts::Vector2 intersection_local = intersection_local_result.value() / Acts::UnitConstants::cm;
0340 if(Verbosity()>2)
0341 {
0342 std::cout << "local intersection: (" << intersection_local.x() << ", " << intersection_local.y() << ")" << std::endl;
0343 }
0344 if(surface->insideBounds(intersection_local * Acts::UnitConstants::cm))
0345 {
0346 if(Verbosity()>1)
0347 {
0348 std::cout << "missing track state within bounds" << std::endl;
0349 }
0350 MissingSpacePoint missingpoint = { missing_layer, surface, intersection_local, intersection };
0351 compatible_surfaces.push_back(missingpoint);
0352 }
0353 }
0354
0355
0356 if(compatible_surfaces.size()>1)
0357 {
0358
0359 float closest_phi = 1e9;
0360
0361 if(missing_layer < filledlayer_pairs[0].first) closest_phi = filledlayer_pairs[0].second;
0362 else if(missing_layer > filledlayer_pairs.back().first) closest_phi = filledlayer_pairs.back().second;
0363 for(size_t i=0; i<filledlayer_pairs.size(); i++)
0364 {
0365 if(filledlayer_pairs[i].first < missing_layer) continue;
0366 closest_phi = filledlayer_pairs[i].second;
0367 int abovelayer_difference = (filledlayer_pairs[i].first - missing_layer);
0368 int belowlayer_difference = filledlayer_pairs[i-1].first - missing_layer;
0369 if(abovelayer_difference < belowlayer_difference) closest_phi = filledlayer_pairs[i].second;
0370 else closest_phi = filledlayer_pairs[i-1].second;
0371 break;
0372 }
0373
0374 int mostcompatible_index = -1;
0375 float best_dphi = 1e9;
0376 for(size_t i=0; i < compatible_surfaces.size(); i++)
0377 {
0378 Acts::Vector3 globalpos = compatible_surfaces[i].global_intersection;
0379 float phi = atan2(globalpos.y(),globalpos.x());
0380 if(fabs(phi-closest_phi)<best_dphi)
0381 {
0382 mostcompatible_index = i;
0383 best_dphi = fabs(phi-closest_phi);
0384 }
0385 }
0386 missing_space_points.push_back(compatible_surfaces[mostcompatible_index]);
0387 }
0388 else if(compatible_surfaces.size()==1)
0389 {
0390 missing_space_points.push_back(compatible_surfaces[0]);
0391 }
0392 }
0393 }
0394 return missing_space_points;
0395 }
0396
0397 std::vector<int> TrackDeadLayerTagging::get_missing_layers(SvtxTrack* track)
0398 {
0399 std::vector<TrkrDefs::cluskey> ckeys;
0400 if(track->get_silicon_seed()) std::copy(track->get_silicon_seed()->begin_cluster_keys(),track->get_silicon_seed()->end_cluster_keys(),std::back_inserter(ckeys));
0401 if(track->get_tpc_seed()) std::copy(track->get_tpc_seed()->begin_cluster_keys(),track->get_tpc_seed()->end_cluster_keys(),std::back_inserter(ckeys));
0402
0403 int start_layer = 0;
0404 int end_layer = 56;
0405 if(ignoreSilicon) start_layer = 7;
0406 if(ignoreTpc) end_layer = 6;
0407
0408 std::vector<int> missing_layers;
0409 for(int l=start_layer; l<=end_layer; l++)
0410 {
0411 if(std::find_if(ckeys.begin(),ckeys.end(),[&](TrkrDefs::cluskey ckey){ return (TrkrDefs::getLayer(ckey) == l); }) == ckeys.end())
0412 {
0413 missing_layers.push_back(l);
0414 }
0415 }
0416
0417 if(missing_layers.size()>0)
0418 {
0419 if(Verbosity()>2)
0420 {
0421 std::cout << "missing layers found: ";
0422 for(auto& l : missing_layers) std::cout << l << ", ";
0423 std::cout << std::endl;
0424 }
0425 }
0426 return missing_layers;
0427 }
0428
0429 std::vector<MissingSensor> TrackDeadLayerTagging::find_sensors(std::vector<MissingSpacePoint> &spacepoints)
0430 {
0431 std::vector<MissingSensor> missing_sensors;
0432 for(auto& spacepoint : spacepoints)
0433 {
0434 if(spacepoint.layer<3)
0435 {
0436 int row;
0437 int col;
0438 SegmentationAlpide::localToDetector(spacepoint.local_intersection.x(),spacepoint.local_intersection.y(),row,col);
0439 TrkrDefs::hitsetkey hskey = _surface_map[spacepoint.surface->geometryId()];
0440 int phi_id = MvtxDefs::getStaveId(hskey);
0441 int z_id = MvtxDefs::getChipId(hskey);
0442 if(Verbosity()>1)
0443 {
0444 std::cout << "stave: " << phi_id << ", chip: " << z_id << std::endl;
0445 std::cout << "pixel: " << row << ", " << col << std::endl;
0446 }
0447 if(row >= 0 && row <= 511 && col>=0 && col<=1023)
0448 {
0449 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, phi_id, z_id, row, col };
0450 missing_sensors.push_back(missing_sensor);
0451 }
0452 }
0453 else if(spacepoint.layer<7)
0454 {
0455 int strip_y;
0456 int strip_z;
0457 CylinderGeomIntt* intt_cylinder = dynamic_cast<CylinderGeomIntt*>(_inttGeom->GetLayerGeom(spacepoint.layer));
0458 TrkrDefs::hitsetkey hskey = _surface_map[spacepoint.surface->geometryId()];
0459 int phi_id = InttDefs::getLadderPhiId(hskey);
0460 int z_id = InttDefs::getLadderZId(hskey);
0461 int layer = TrkrDefs::getLayer(hskey);
0462 intt_cylinder->find_strip_index_values(z_id,spacepoint.local_intersection.x(),spacepoint.local_intersection.y(),strip_y,strip_z);
0463 if(Verbosity()>1)
0464 {
0465 std::cout << "layer: " << layer << std::endl;
0466 std::cout << "ladder: " << phi_id << ", " << z_id << std::endl;
0467 std::cout << "strip: " << strip_y << ", " << strip_z << std::endl;
0468 }
0469 if(strip_y >= 0 && strip_y <= 255 && strip_z>=0 && ((z_id == 0 && strip_z<=7) || (z_id == 1 && strip_z<=4)))
0470 {
0471 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, phi_id, z_id, strip_y, strip_z };
0472 missing_sensors.push_back(missing_sensor);
0473 }
0474 }
0475 }
0476 return missing_sensors;
0477 }
0478
0479 bool TrackDeadLayerTagging::is_dead(MissingSensor& sensor)
0480 {
0481 std::vector<MissingSensor> dead_thislayer = _dead_sensors.at(sensor.layer);
0482 return (std::find(dead_thislayer.begin(),dead_thislayer.end(),sensor) != dead_thislayer.end());
0483 }
0484
0485
0486 void TrackDeadLayerTagging::find_dead_layers(PHCompositeNode *topNode)
0487 {
0488
0489 for(const auto &[key, track] : *_trackmap)
0490 {
0491 if(!track) continue;
0492
0493 _trackID = track->get_id();
0494 std::cout << "track ID " << _trackID << std::endl;
0495
0496 std::vector<int> missing_layers = get_missing_layers(track);
0497 std::vector<MissingSpacePoint> missing_space_points = get_missing_space_points(track,missing_layers);
0498 std::vector<MissingSensor> missing_sensors = find_sensors(missing_space_points);
0499
0500 if(Verbosity()>0 && missing_sensors.size()>0)
0501 {
0502 std::cout << "missing sensors: " << std::endl;
0503 for(auto& sensor : missing_sensors)
0504 {
0505 if(!(ignoreSilicon && sensor.layer<7) && !(ignoreTpc && sensor.layer>=7))
0506 {
0507 std::cout << "layer: " << sensor.layer << " phi_id: " << sensor.phi_id << " z_id: " << sensor.z_id << " local_x: " << sensor.local_x << " local_y: " << sensor.local_y << std::endl;
0508 }
0509 }
0510 }
0511
0512 for(MissingSensor& sensor : missing_sensors)
0513 {
0514 if(!(ignoreSilicon && sensor.layer<7) && !(ignoreTpc && sensor.layer>=7))
0515 {
0516 _layer = sensor.layer;
0517 _phiID = sensor.phi_id;
0518 _zID = sensor.z_id;
0519 _localindX = sensor.local_x;
0520 _localindY = sensor.local_y;
0521 _isDead = is_dead(sensor)? 1 : 0;
0522 _missing_sensors->Fill();
0523 }
0524 }
0525 }
0526 }
0527
0528
0529 void TrackDeadLayerTagging::GetNodes(PHCompositeNode *topNode)
0530 {
0531
0532 _clustermap = findNode::getClass<TrkrClusterContainer>(topNode,"TRKR_CLUSTER");
0533 if(!_clustermap && _event<2)
0534 {
0535 std::cout << PHWHERE << " cannot find TrkrClusterContainer" << std::endl;
0536 }
0537
0538 _trackmap = findNode::getClass<SvtxTrackMap>(topNode,"SvtxTrackMap");
0539 if(!_trackmap && _event<2)
0540 {
0541 std::cout << PHWHERE << " cannot find SvtxTrackMap" << std::endl;
0542 }
0543
0544 _vertexmap = findNode::getClass<SvtxVertexMap>(topNode,"SvtxVertexMap");
0545 if(!_vertexmap && _event<2)
0546 {
0547 std::cout << PHWHERE << " cannot find SvtxVertexMap" << std::endl;
0548 }
0549
0550 _tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0551 if(!_tGeometry && _event<2)
0552 {
0553 std::cout << PHWHERE << " cannot find ActsGeometry" << std::endl;
0554 }
0555
0556 _inttGeom = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_INTT");
0557 if(!_inttGeom && _event<2)
0558 {
0559 std::cout << PHWHERE << " cannot find CYLINDERGEOM_INTT" << std::endl;
0560 }
0561
0562 }
0563
0564
0565 int TrackDeadLayerTagging::End(PHCompositeNode *topNode)
0566 {
0567 PHTFileServer::get().cd( _outfile );
0568 _missing_sensors->Write();
0569 return 0;
0570 }
0571