File indexing completed on 2025-12-16 09:18:30
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/TpcDefs.h>
0017 #include <trackbase/TrackFitUtils.h>
0018
0019 #include <g4detectors/PHG4TpcGeom.h>
0020
0021 #include <mvtx/SegmentationAlpide.h>
0022 #include <intt/CylinderGeomIntt.h>
0023 #include <intt/InttMapping.h>
0024 #include <micromegas/MicromegasDefs.h>
0025 #include <micromegas/CylinderGeomMicromegas.h>
0026
0027 #include <TNtuple.h>
0028 #include <TH1.h>
0029
0030 #include <iostream>
0031
0032
0033 TrackDeadLayerTagging::TrackDeadLayerTagging(const std::string &name):
0034 SubsysReco(name)
0035 {
0036
0037 _event = 0;
0038 _outfile = "dead_layers.root";
0039 }
0040
0041
0042 int TrackDeadLayerTagging::InitRun(PHCompositeNode *topNode)
0043 {
0044 std::cout << PHWHERE << " Opening file " << _outfile << std::endl;
0045 PHTFileServer::get().open( _outfile, "RECREATE");
0046
0047 _missing_sensors = new TTree("missing_sensors","Sensors missing from track");
0048 _missing_sensors->Branch("event",&_event);
0049 _missing_sensors->Branch("trackID",&_trackID);
0050 _missing_sensors->Branch("layer",&_layer);
0051 _missing_sensors->Branch("phiID",&_phiID);
0052 _missing_sensors->Branch("zID",&_zID);
0053 _missing_sensors->Branch("localindX",&_localindX);
0054 _missing_sensors->Branch("localindY",&_localindY);
0055 _missing_sensors->Branch("isDead",&_isDead);
0056 _missing_sensors->Branch("global_x",&_global_x);
0057 _missing_sensors->Branch("global_y",&_global_y);
0058 _missing_sensors->Branch("global_z",&_global_z);
0059
0060 std::cout << "loading nodes" << std::endl;
0061 tpcglobal.set_verbosity(5);
0062 tpcglobal.loadNodes(topNode);
0063 std::cout << "nodes loaded" << std::endl;
0064
0065
0066 return 0;
0067 }
0068
0069
0070
0071 int TrackDeadLayerTagging::process_event(PHCompositeNode *topNode)
0072 {
0073 _event++;
0074 if(_event%1000==0) std::cout << PHWHERE << "Events processed: " << _event << std::endl;
0075
0076 _surface_maps.clear();
0077 GetNodes(topNode);
0078 for(auto& v : _dead_sensors) v.clear();
0079 get_surfaces();
0080 get_dead_sensor_maps();
0081
0082 if(Verbosity()>0)
0083 {
0084 std::cout << "--------------------------------" << std::endl;
0085 std::cout << "event " << _event << std::endl;
0086 }
0087
0088 find_dead_layers(topNode);
0089
0090 return 0;
0091 }
0092
0093 void TrackDeadLayerTagging::get_dead_sensor_maps()
0094 {
0095 std::string mvtx_hotpixel = CDBInterface::instance()->getUrl("MVTX_HotPixelMap");
0096 std::string mvtx_deadpixel = CDBInterface::instance()->getUrl("MVTX_DeadPixelMap");
0097 std::string intt_hotstrip = CDBInterface::instance()->getUrl("INTT_HotMap");
0098 std::string tpc_hotchannel = CDBInterface::instance()->getUrl("TPC_HOTCHANNELMAP");
0099 std::string tpc_deadchannel = CDBInterface::instance()->getUrl("TPC_DEADCHANNELMAP");
0100
0101 std::unique_ptr<CDBTTree> mvtx_hottree = std::make_unique<CDBTTree>(mvtx_hotpixel);
0102 std::unique_ptr<CDBTTree> mvtx_deadtree = std::make_unique<CDBTTree>(mvtx_deadpixel);
0103 std::unique_ptr<CDBTTree> intt_hottree = std::make_unique<CDBTTree>(intt_hotstrip);
0104 std::unique_ptr<CDBTTree> tpc_hottree;
0105 std::unique_ptr<CDBTTree> tpc_deadtree;
0106 if(!tpc_hotchannel.empty())
0107 {
0108 tpc_hottree = std::make_unique<CDBTTree>(tpc_hotchannel);
0109 }
0110 if(!tpc_deadchannel.empty())
0111 {
0112 tpc_deadtree = std::make_unique<CDBTTree>(tpc_deadchannel);
0113 }
0114
0115 std::cout << "Verbosity is " << Verbosity() << std::endl;
0116
0117 mvtx_hottree->LoadCalibrations();
0118 mvtx_deadtree->LoadCalibrations();
0119 intt_hottree->LoadCalibrations();
0120 if(!tpc_hotchannel.empty()) tpc_hottree->LoadCalibrations();
0121 if(!tpc_deadchannel.empty()) tpc_deadtree->LoadCalibrations();
0122
0123 int n_mvtxhot = mvtx_hottree->GetSingleIntValue("TotalHotPixels");
0124 int n_mvtxdead = mvtx_deadtree->GetSingleIntValue("TotalDeadPixels");
0125 int n_intthot = intt_hottree->GetSingleIntValue("size");
0126 int n_tpchot = (!tpc_hotchannel.empty())? tpc_hottree->GetSingleIntValue("TotalHotChannels") : 0;
0127 int n_tpcdead = (!tpc_deadchannel.empty())? tpc_deadtree->GetSingleIntValue("TotalDeadChannels") : 0;
0128
0129 if(Verbosity()>0)
0130 {
0131 std::cout << "MVTX has " << n_mvtxhot << " hot pixels" << std::endl;
0132 std::cout << "MVTX has " << n_mvtxdead << " dead pixels" << std::endl;
0133 std::cout << "INTT has " << n_intthot << " hot pixels" << std::endl;
0134 std::cout << "TPC has " << n_tpchot << " hot pixels" << std::endl;
0135 std::cout << "TPC has " << n_tpcdead << " dead pixels" << std::endl;
0136 }
0137
0138 if(Verbosity()>2) std::cout << "MVTX hot sensors:" << std::endl;
0139 for(int i=0; i<n_mvtxhot; i++)
0140 {
0141 int layer = mvtx_hottree->GetIntValue(i,"layer");
0142 MissingSensor hotsensor_mvtx = {
0143 .layer = layer,
0144 .phi_id = mvtx_hottree->GetIntValue(i,"stave"),
0145 .z_id = mvtx_hottree->GetIntValue(i,"chip"),
0146 .local_x = mvtx_hottree->GetIntValue(i,"row"),
0147 .local_y = mvtx_hottree->GetIntValue(i,"col")
0148 };
0149 if(Verbosity()>2)
0150 {
0151 std::cout << "layer " << hotsensor_mvtx.layer << " stave " << hotsensor_mvtx.phi_id << " chip " << hotsensor_mvtx.z_id << " row " << hotsensor_mvtx.local_x << " col " << hotsensor_mvtx.local_y << std::endl;
0152 }
0153 if(layer>=0&&layer<=2)
0154 {
0155 _dead_sensors[layer].push_back(hotsensor_mvtx);
0156 }
0157 }
0158
0159 if(Verbosity()>2) std::cout << "MVTX dead sensors:" << std::endl;
0160 for(int i=0; i<n_mvtxdead; i++)
0161 {
0162 int layer = mvtx_deadtree->GetIntValue(i,"layer");
0163 MissingSensor deadsensor_mvtx = {
0164 .layer = layer,
0165 .phi_id = mvtx_deadtree->GetIntValue(i,"stave"),
0166 .z_id = mvtx_deadtree->GetIntValue(i,"chip"),
0167 .local_x = mvtx_deadtree->GetIntValue(i,"row"),
0168 .local_y = mvtx_deadtree->GetIntValue(i,"col")
0169 };
0170 if(layer>=0&&layer<=2)
0171 {
0172 _dead_sensors[layer].push_back(deadsensor_mvtx);
0173 }
0174 if(Verbosity()>2)
0175 {
0176 std::cout << "layer " << deadsensor_mvtx.layer << " stave " << deadsensor_mvtx.phi_id << " chip " << deadsensor_mvtx.z_id << " row " << deadsensor_mvtx.local_x << " col " << deadsensor_mvtx.local_y << std::endl;
0177 }
0178 }
0179
0180 if(Verbosity()>2) std::cout << "INTT hot sensors:" << std::endl;
0181 for(int i=0; i<n_intthot; i++)
0182 {
0183 InttNameSpace::RawData_s raw_sensor;
0184 raw_sensor.felix_server = intt_hottree->GetIntValue(i,"felix_server");
0185 raw_sensor.felix_channel = intt_hottree->GetIntValue(i,"felix_channel");
0186 raw_sensor.chip = intt_hottree->GetIntValue(i,"chip");
0187 raw_sensor.channel = intt_hottree->GetIntValue(i,"channel");
0188 InttNameSpace::Offline_s offline_sensor = InttNameSpace::ToOffline(raw_sensor);
0189 MissingSensor hotsensor_intt = {
0190 .layer = offline_sensor.layer,
0191 .phi_id = offline_sensor.ladder_phi,
0192 .z_id = offline_sensor.ladder_z,
0193 .local_x = offline_sensor.strip_y,
0194 .local_y = offline_sensor.strip_x
0195 };
0196 if(offline_sensor.layer>=3&&offline_sensor.layer<=6)
0197 {
0198 _dead_sensors[offline_sensor.layer].push_back(hotsensor_intt);
0199 }
0200 if(Verbosity()>2)
0201 {
0202 std::cout << "layer " << offline_sensor.layer << " ladder phi " << offline_sensor.ladder_phi << " ladder z " << offline_sensor.ladder_z << " strip y " << offline_sensor.strip_y << " strip x " << offline_sensor.strip_x << std::endl;
0203 }
0204 }
0205
0206 if(Verbosity()>2) std::cout << "TPC hot sensors:" << std::endl;
0207 for(int i=0; i<n_tpchot; i++)
0208 {
0209 int layer = tpc_hottree->GetIntValue(i,"layer");
0210 MissingSensor hotsensor_tpc = {
0211 .layer = layer,
0212 .phi_id = tpc_hottree->GetIntValue(i,"sector"),
0213 .z_id = tpc_hottree->GetIntValue(i,"side"),
0214 .local_x = tpc_hottree->GetIntValue(i,"pad")
0215 };
0216 if(layer>=7&&layer<=54)
0217 {
0218 _dead_sensors[layer].push_back(hotsensor_tpc);
0219 }
0220 if(Verbosity()>2)
0221 {
0222 std::cout << "layer " << layer << " sector " << hotsensor_tpc.phi_id << " side " << hotsensor_tpc.z_id << " phibin " << hotsensor_tpc.local_x << std::endl;
0223 }
0224 }
0225
0226 if(Verbosity()>2) std::cout << "TPC dead sensors:" << std::endl;
0227 for(int i=0; i<n_tpcdead; i++)
0228 {
0229 int layer = tpc_deadtree->GetIntValue(i,"layer");
0230 MissingSensor deadsensor_tpc = {
0231 .layer = layer,
0232 .phi_id = tpc_deadtree->GetIntValue(i,"sector"),
0233 .z_id = tpc_deadtree->GetIntValue(i,"side"),
0234 .local_x = tpc_deadtree->GetIntValue(i,"pad")
0235 };
0236 if(layer>=7&&layer<=54)
0237 {
0238 _dead_sensors[layer].push_back(deadsensor_tpc);
0239 }
0240 if(Verbosity()>2)
0241 {
0242 std::cout << "layer " << layer << " sector " << deadsensor_tpc.phi_id << " side " << deadsensor_tpc.z_id << " phibin " << deadsensor_tpc.local_x << std::endl;
0243 }
0244 }
0245
0246 }
0247
0248 void TrackDeadLayerTagging::get_surfaces()
0249 {
0250 for(int layer=0; layer<57; layer++)
0251 {
0252 _surface_maps.emplace_back();
0253 if(layer<3)
0254 {
0255 const int n_staves = 12 + 4*layer;
0256 const int n_chips = 9;
0257 for(int stave_id=0;stave_id<n_staves;stave_id++)
0258 {
0259 for(int chip_id=0;chip_id<n_chips;chip_id++)
0260 {
0261
0262 TrkrDefs::hitsetkey hskey = MvtxDefs::genHitSetKey(layer,stave_id,chip_id,0);
0263
0264
0265 const auto& surface = _tGeometry->maps().getSiliconSurface(hskey);
0266 if(!surface)
0267 {
0268 std::cout << PHWHERE << " cannot find MVTX surface with layer " << layer << " stave " << stave_id << " chip " << chip_id << std::endl;
0269 }
0270 else
0271 {
0272
0273 _surface_maps[layer].insert(std::make_pair(surface->geometryId(),hskey));
0274 }
0275 }
0276 }
0277 }
0278 else if(layer<7)
0279 {
0280 int n_ladders;
0281 if(layer<5) n_ladders = 12;
0282 else n_ladders = 16;
0283 const int n_zsegments = 4;
0284 for(int ladder_phi_id=0;ladder_phi_id<n_ladders;ladder_phi_id++)
0285 {
0286 for(int ladder_z_id=0;ladder_z_id<n_zsegments;ladder_z_id++)
0287 {
0288
0289 TrkrDefs::hitsetkey hskey = InttDefs::genHitSetKey(layer,ladder_z_id,ladder_phi_id,0);
0290
0291
0292
0293
0294 const auto& surface = _tGeometry->maps().getSiliconSurface(hskey);
0295 if(!surface)
0296 {
0297 std::cout << PHWHERE << " cannot find INTT surface with layer " << layer << " ladder_z " << ladder_z_id << " ladder_phi " << ladder_phi_id << std::endl;
0298 }
0299 else
0300 {
0301
0302 _surface_maps[layer].insert(std::make_pair(surface->geometryId(),hskey));
0303 }
0304 }
0305 }
0306 }
0307 else if(layer<55)
0308 {
0309
0310
0311
0312 const int n_subsurf = 288;
0313
0314 TrkrDefs::hitsetkey hskey = TpcDefs::genHitSetKey(layer,0,0);
0315 for(int subsurf_id = 0; subsurf_id < n_subsurf; subsurf_id++)
0316 {
0317
0318 const auto& surface = _tGeometry->maps().getTpcSurface(hskey,subsurf_id);
0319 if(!surface)
0320 {
0321 std::cout << PHWHERE << " cannot find TPC surface with layer " << layer << " subsurface " << subsurf_id << std::endl;
0322 }
0323 else
0324 {
0325
0326
0327 _surface_maps[layer].insert(std::make_pair(surface->geometryId(),subsurf_id));
0328 }
0329 }
0330 }
0331 else if(layer<57)
0332 {
0333 const int n_tiles = 8;
0334 for(int tile_id = 0; tile_id < n_tiles; tile_id++)
0335 {
0336 TrkrDefs::hitsetkey hskey_phi = MicromegasDefs::genHitSetKey(layer,MicromegasDefs::SegmentationType::SEGMENTATION_PHI,tile_id);
0337 TrkrDefs::hitsetkey hskey_z = MicromegasDefs::genHitSetKey(layer,MicromegasDefs::SegmentationType::SEGMENTATION_Z,tile_id);
0338
0339 const auto& surface_phi = _tGeometry->maps().getMMSurface(hskey_phi);
0340 const auto& surface_z = _tGeometry->maps().getMMSurface(hskey_z);
0341
0342 if(!surface_phi)
0343 {
0344 std::cout << PHWHERE << " cannot find TPOT surface with layer " << layer << " phi segmentation, tile " << tile_id << std::endl;
0345 }
0346 else
0347 {
0348
0349 _surface_maps[layer].insert(std::make_pair(surface_phi->geometryId(),hskey_phi));
0350 }
0351 if(!surface_z)
0352 {
0353 std::cout << PHWHERE << " cannot find TPOT surface with layer " << layer << " z segmentation, tile " << tile_id << std::endl;
0354 }
0355 else
0356 {
0357
0358 _surface_maps[layer].insert(std::make_pair(surface_z->geometryId(),hskey_z));
0359 }
0360 }
0361 }
0362 }
0363 }
0364
0365 std::vector<float> TrackDeadLayerTagging::getFitParams(TrackSeed* seed)
0366 {
0367 std::vector<float> fitpars;
0368 fitpars.push_back(1./fabs(seed->get_qOverR()));
0369 fitpars.push_back(seed->get_X0());
0370 fitpars.push_back(seed->get_Y0());
0371 fitpars.push_back(seed->get_slope());
0372 fitpars.push_back(seed->get_Z0());
0373 return fitpars;
0374 }
0375
0376 std::vector<MissingSpacePoint> TrackDeadLayerTagging::get_missing_space_points(SvtxTrack* track, std::vector<int> missing_layers)
0377 {
0378 std::vector<MissingSpacePoint> missing_space_points;
0379 if(useActsPropagator)
0380 {
0381 ActsPropagator propagator(_tGeometry);
0382 propagator.verbosity(0);
0383 ActsPropagator::BoundTrackParamResult result_trackparams = propagator.makeTrackParams(track,_vertexmap);
0384 if(result_trackparams.ok())
0385 {
0386 Acts::BoundTrackParameters trackparams = result_trackparams.value();
0387 for(int layer : missing_layers)
0388 {
0389 ActsPropagator::BTPPairResult result_propagated_params = propagator.propagateTrack(trackparams,layer);
0390 if(result_propagated_params.ok())
0391 {
0392
0393 Acts::BoundTrackParameters updated_params = result_propagated_params.value().second;
0394
0395
0396 Acts::Vector3 global_intersection = updated_params.position(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
0397 Acts::Vector3 tangent = updated_params.direction();
0398
0399 int nCompatibleSurfaces = 0;
0400 for(auto& [geoId, hskey] : _surface_maps[layer])
0401 {
0402 Surface surface = _tGeometry->geometry().tGeometry->findSurface(geoId)->getSharedPtr();
0403 auto local_result = surface->globalToLocal(_tGeometry->geometry().getGeoContext(),global_intersection * Acts::UnitConstants::cm,tangent);
0404 if(local_result.ok())
0405 {
0406 Acts::Vector2 local_intersection = local_result.value() / Acts::UnitConstants::cm;
0407
0408 if(surface->insideBounds(local_intersection * Acts::UnitConstants::cm))
0409 {
0410 MissingSpacePoint missingpoint = { layer, surface, local_intersection, global_intersection };
0411 missing_space_points.push_back(missingpoint);
0412 nCompatibleSurfaces++;
0413 }
0414 }
0415 }
0416 if(nCompatibleSurfaces>1 && Verbosity()>0) std::cout << PHWHERE << "NOTE: More than one compatible surface found!" << std::endl;
0417 }
0418 else
0419 {
0420 if(Verbosity()>0) std::cout << PHWHERE << "ActsPropagator returned error " << result_propagated_params.error().message() << " on propagating to layer " << layer << std::endl;
0421 }
0422 }
0423 }
0424 else
0425 {
0426 if(Verbosity()>0) std::cout << PHWHERE << "ActsPropagator returned error " << result_trackparams.error().message() << " on formation of track params" << std::endl;
0427 }
0428 }
0429 else
0430 {
0431 TrackSeed* siliconseed = track->get_silicon_seed();
0432 TrackSeed* tpcseed = track->get_tpc_seed();
0433
0434
0435 std::vector<float> fitpars = tpcseed? getFitParams(tpcseed) : getFitParams(siliconseed);
0436
0437
0438 std::vector<std::pair<float,float>> filledlayer_pairs;
0439 if(siliconseed)
0440 {
0441 for(auto si_ckey = siliconseed->begin_cluster_keys(); si_ckey != siliconseed->end_cluster_keys(); si_ckey++)
0442 {
0443 TrkrCluster* c = _clustermap->findCluster(*si_ckey);
0444 Acts::Vector3 globalpos = _tGeometry->getGlobalPosition(*si_ckey,c);
0445 float phi = atan2(globalpos.y(),globalpos.x());
0446 filledlayer_pairs.push_back(std::make_pair(TrkrDefs::getLayer(*si_ckey),phi));
0447 }
0448 }
0449 if(tpcseed)
0450 {
0451 for(auto tpc_ckey = tpcseed->begin_cluster_keys(); tpc_ckey != tpcseed->end_cluster_keys(); tpc_ckey++)
0452 {
0453 TrkrCluster* c = _clustermap->findCluster(*tpc_ckey);
0454 Acts::Vector3 globalpos = tpcglobal.getGlobalPositionDistortionCorrected(*tpc_ckey,c,track->get_crossing());
0455 float phi = atan2(globalpos.y(),globalpos.x());
0456 filledlayer_pairs.push_back(std::make_pair(TrkrDefs::getLayer(*tpc_ckey),phi));
0457 }
0458 }
0459
0460
0461 for(int missing_layer : missing_layers)
0462 {
0463 if(Verbosity()>1)
0464 {
0465 std::cout << "layer " << missing_layer << ":" << std::endl;
0466 }
0467 std::vector<MissingSpacePoint> compatible_surfaces;
0468
0469 for(auto& [geoId, hskey] : _surface_maps[missing_layer])
0470 {
0471 Surface surface = _tGeometry->geometry().tGeometry->findSurface(geoId)->getSharedPtr();
0472 Acts::Vector3 surface_center = surface->center(_tGeometry->geometry().getGeoContext()) / Acts::UnitConstants::cm;
0473 Acts::Vector3 intersection = TrackFitUtils::get_helix_surface_intersection(surface,fitpars,surface_center,_tGeometry);
0474 Acts::Vector3 tangent = TrackFitUtils::get_helix_tangent(fitpars,intersection).second;
0475 if(Verbosity()>2)
0476 {
0477 std::cout << "surface center: (" << surface_center.x() << ", " << surface_center.y() << ", " << surface_center.z() << ")" << std::endl;
0478 std::cout << "intersection with surface: (" << intersection.x() << ", " << intersection.y() << ", " << intersection.z() << ")" << std::endl;
0479 std::cout << "tangent vector: (" << tangent.x() << ", " << tangent.y() << ", " << tangent.z() << ")" << std::endl;
0480 }
0481 auto intersection_local_result = surface->globalToLocal(_tGeometry->geometry().getGeoContext(),intersection * Acts::UnitConstants::cm,tangent * Acts::UnitConstants::cm);
0482 if(!intersection_local_result.ok())
0483 {
0484 if(Verbosity()>2)
0485 {
0486 std::cout << "local coordinate conversion failed..." << std::endl;
0487 }
0488 continue;
0489 }
0490 Acts::Vector2 intersection_local = intersection_local_result.value() / Acts::UnitConstants::cm;
0491 if(Verbosity()>2)
0492 {
0493 std::cout << "local intersection: (" << intersection_local.x() << ", " << intersection_local.y() << ")" << std::endl;
0494 }
0495 if(surface->insideBounds(intersection_local * Acts::UnitConstants::cm))
0496 {
0497 if(Verbosity()>1)
0498 {
0499 std::cout << "missing track state within bounds" << std::endl;
0500 }
0501 MissingSpacePoint missingpoint = { missing_layer, surface, intersection_local, intersection };
0502 compatible_surfaces.push_back(missingpoint);
0503 }
0504 }
0505
0506
0507 if(compatible_surfaces.size()>1)
0508 {
0509
0510 float closest_phi = 1e9;
0511
0512 if(missing_layer < filledlayer_pairs[0].first) closest_phi = filledlayer_pairs[0].second;
0513 else if(missing_layer > filledlayer_pairs.back().first) closest_phi = filledlayer_pairs.back().second;
0514 for(size_t i=0; i<filledlayer_pairs.size(); i++)
0515 {
0516 if(filledlayer_pairs[i].first < missing_layer) continue;
0517 closest_phi = filledlayer_pairs[i].second;
0518 int abovelayer_difference = (filledlayer_pairs[i].first - missing_layer);
0519 int belowlayer_difference = filledlayer_pairs[i-1].first - missing_layer;
0520 if(abovelayer_difference < belowlayer_difference) closest_phi = filledlayer_pairs[i].second;
0521 else closest_phi = filledlayer_pairs[i-1].second;
0522 break;
0523 }
0524
0525 int mostcompatible_index = -1;
0526 float best_dphi = 1e9;
0527 for(size_t i=0; i < compatible_surfaces.size(); i++)
0528 {
0529 Acts::Vector3 globalpos = compatible_surfaces[i].global_intersection;
0530 float phi = atan2(globalpos.y(),globalpos.x());
0531 if(fabs(phi-closest_phi)<best_dphi)
0532 {
0533 mostcompatible_index = i;
0534 best_dphi = fabs(phi-closest_phi);
0535 }
0536 }
0537 missing_space_points.push_back(compatible_surfaces[mostcompatible_index]);
0538 }
0539 else if(compatible_surfaces.size()==1)
0540 {
0541 missing_space_points.push_back(compatible_surfaces[0]);
0542 }
0543 }
0544 }
0545 return missing_space_points;
0546 }
0547
0548 std::vector<int> TrackDeadLayerTagging::get_missing_layers(SvtxTrack* track)
0549 {
0550 std::vector<TrkrDefs::cluskey> ckeys;
0551 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));
0552 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));
0553
0554 int start_layer = 0;
0555 int end_layer = 56;
0556 if(ignoreSilicon) start_layer = 7;
0557 if(ignoreTpc) end_layer = 6;
0558
0559 std::vector<int> missing_layers;
0560 for(int l=start_layer; l<=end_layer; l++)
0561 {
0562 if(std::find_if(ckeys.begin(),ckeys.end(),[&](TrkrDefs::cluskey ckey){ return (TrkrDefs::getLayer(ckey) == l); }) == ckeys.end())
0563 {
0564 missing_layers.push_back(l);
0565 }
0566 }
0567
0568 if(missing_layers.size()>0)
0569 {
0570 if(Verbosity()>2)
0571 {
0572 std::cout << "missing layers found: ";
0573 for(auto& l : missing_layers) std::cout << l << ", ";
0574 std::cout << std::endl;
0575 }
0576 }
0577 return missing_layers;
0578 }
0579
0580 std::vector<MissingSensor> TrackDeadLayerTagging::find_sensors(std::vector<MissingSpacePoint> &spacepoints)
0581 {
0582 std::vector<MissingSensor> missing_sensors;
0583 for(auto& spacepoint : spacepoints)
0584 {
0585 if(Verbosity()>1) std::cout << "sensor layer: " << spacepoint.layer << std::endl;
0586 if(spacepoint.layer<3)
0587 {
0588 int row;
0589 int col;
0590 SegmentationAlpide::localToDetector(spacepoint.local_intersection.x(),spacepoint.local_intersection.y(),row,col);
0591 TrkrDefs::hitsetkey hskey = _surface_maps[spacepoint.layer][spacepoint.surface->geometryId()];
0592 int phi_id = MvtxDefs::getStaveId(hskey);
0593 int z_id = MvtxDefs::getChipId(hskey);
0594 if(Verbosity()>1)
0595 {
0596 std::cout << "stave: " << phi_id << ", chip: " << z_id << std::endl;
0597 std::cout << "pixel: " << row << ", " << col << std::endl;
0598 }
0599 if(row >= 0 && row <= 511 && col>=0 && col<=1023)
0600 {
0601 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, phi_id, z_id, row, col };
0602 missing_sensors.push_back(missing_sensor);
0603 }
0604 }
0605 else if(spacepoint.layer<7)
0606 {
0607 int strip_y;
0608 int strip_z;
0609 CylinderGeomIntt* intt_cylinder = dynamic_cast<CylinderGeomIntt*>(_inttGeom->GetLayerGeom(spacepoint.layer));
0610 TrkrDefs::hitsetkey hskey = _surface_maps[spacepoint.layer][spacepoint.surface->geometryId()];
0611 int phi_id = InttDefs::getLadderPhiId(hskey);
0612 int z_id = InttDefs::getLadderZId(hskey);
0613 int layer = TrkrDefs::getLayer(hskey);
0614 intt_cylinder->find_strip_index_values(z_id,spacepoint.local_intersection.x(),spacepoint.local_intersection.y(),strip_y,strip_z);
0615 if(Verbosity()>1)
0616 {
0617 std::cout << "layer: " << layer << std::endl;
0618 std::cout << "ladder: " << phi_id << ", " << z_id << std::endl;
0619 std::cout << "strip: " << strip_y << ", " << strip_z << std::endl;
0620 }
0621 if(strip_y >= 0 && strip_y <= 255 && strip_z>=0 && ((z_id == 0 && strip_z<=7) || (z_id == 1 && strip_z<=4)))
0622 {
0623 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, phi_id, z_id, strip_y, strip_z };
0624 missing_sensors.push_back(missing_sensor);
0625 }
0626 }
0627 else if(spacepoint.layer<55)
0628 {
0629 int side = (spacepoint.global_intersection.z()>0)? 1 : 0;
0630 double phi = atan2(spacepoint.global_intersection.y(),spacepoint.global_intersection.x());
0631 PHG4TpcGeom* layergeom = _tpcGeom->GetLayerCellGeom(spacepoint.layer);
0632 int phibin = layergeom->get_phibin(phi,side);
0633 int zbin = layergeom->get_zbin(spacepoint.global_intersection.z());
0634
0635
0636 const int sector_step = layergeom->get_phibins() / 12;
0637 int sector_id = phibin / sector_step;
0638
0639 if(Verbosity()>1)
0640 {
0641 std::cout << "layer: " << spacepoint.layer << std::endl;
0642 std::cout << "sector: " << sector_id << ", side " << side << std::endl;
0643 std::cout << "phibin: " << phibin << ", zbin: " << zbin << std::endl;
0644 }
0645 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, sector_id, side, phibin, zbin };
0646 missing_sensors.push_back(missing_sensor);
0647 }
0648 else if(spacepoint.layer<57)
0649 {
0650 int strip_z = 0;
0651 CylinderGeomMicromegas* tpotlayergeom = dynamic_cast<CylinderGeomMicromegas*>(_tpotGeom->GetLayerGeom(spacepoint.layer));
0652
0653 TrkrDefs::hitsetkey hskey = _surface_maps[spacepoint.layer][spacepoint.surface->geometryId()];
0654 int tile_id = MicromegasDefs::getTileId(hskey);
0655 int seg_id = (MicromegasDefs::getSegmentationType(hskey) == MicromegasDefs::SegmentationType::SEGMENTATION_Z)? 0 : 1;
0656 TVector2 local_tvector(spacepoint.local_intersection.x(),spacepoint.local_intersection.y());
0657
0658 int strip_id = tpotlayergeom->find_strip_from_local_coords(tile_id,_tGeometry,local_tvector);
0659
0660 if(Verbosity()>1)
0661 {
0662 std::cout << "layer: " << spacepoint.layer << std::endl;
0663 std::cout << "tile ID: " << tile_id << ", segmentation " << seg_id << std::endl;
0664 std::cout << "strip_id " << strip_id << std::endl;
0665 }
0666 MissingSensor missing_sensor = { _event, _trackID, spacepoint.layer, tile_id, seg_id, strip_id, strip_z };
0667 missing_sensors.push_back(missing_sensor);
0668 }
0669 }
0670 return missing_sensors;
0671 }
0672
0673 bool TrackDeadLayerTagging::is_dead(MissingSensor& sensor)
0674 {
0675 std::vector<MissingSensor> dead_thislayer = _dead_sensors.at(sensor.layer);
0676 return (std::find_if(dead_thislayer.begin(),dead_thislayer.end(),
0677 [&sensor](const MissingSensor& candidate) { return sensor.isSameSensor(candidate); })
0678 != dead_thislayer.end());
0679 }
0680
0681
0682 void TrackDeadLayerTagging::find_dead_layers(PHCompositeNode *topNode)
0683 {
0684
0685 for(const auto &[key, track] : *_trackmap)
0686 {
0687 if(!track) continue;
0688
0689 _trackID = track->get_id();
0690 if(Verbosity()>0) std::cout << "track ID " << _trackID << std::endl;
0691 if(std::isnan(track->get_x()) ||
0692 std::isnan(track->get_y()) ||
0693 std::isnan(track->get_z()) ||
0694 std::isnan(track->get_px()) ||
0695 std::isnan(track->get_py()) ||
0696 std::isnan(track->get_pz()))
0697 {
0698 std::cout << "malformed track:" << std::endl;
0699 track->identify();
0700 std::cout << "skipping..." << std::endl;
0701 continue;
0702 }
0703
0704 std::vector<int> missing_layers = get_missing_layers(track);
0705 std::vector<MissingSpacePoint> missing_space_points = get_missing_space_points(track,missing_layers);
0706 std::vector<MissingSensor> missing_sensors = find_sensors(missing_space_points);
0707
0708 if(Verbosity()>0 && missing_sensors.size()>0)
0709 {
0710 std::cout << "missing sensors: " << std::endl;
0711 for(auto& sensor : missing_sensors)
0712 {
0713 if(!(ignoreSilicon && sensor.layer<7) && !(ignoreTpc && sensor.layer>=7))
0714 {
0715 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;
0716 }
0717 }
0718 }
0719
0720 for(size_t i=0; i<missing_sensors.size(); i++)
0721 {
0722 MissingSensor& sensor = missing_sensors[i];
0723 MissingSpacePoint& point = missing_space_points[i];
0724 if(!(ignoreSilicon && sensor.layer<7) && !(ignoreTpc && sensor.layer>=7))
0725 {
0726 _layer = sensor.layer;
0727 _phiID = sensor.phi_id;
0728 _zID = sensor.z_id;
0729 _localindX = sensor.local_x;
0730 _localindY = sensor.local_y;
0731 _isDead = is_dead(sensor)? 1 : 0;
0732 _global_x = point.global_intersection.x();
0733 _global_y = point.global_intersection.y();
0734 _global_z = point.global_intersection.z();
0735 _missing_sensors->Fill();
0736 }
0737 }
0738 }
0739 }
0740
0741
0742 void TrackDeadLayerTagging::GetNodes(PHCompositeNode *topNode)
0743 {
0744
0745 _clustermap = findNode::getClass<TrkrClusterContainer>(topNode,"TRKR_CLUSTER");
0746 if(!_clustermap && _event<2)
0747 {
0748 std::cout << PHWHERE << " cannot find TrkrClusterContainer" << std::endl;
0749 }
0750
0751 _trackmap = findNode::getClass<SvtxTrackMap>(topNode,"SvtxTrackMap");
0752 if(!_trackmap && _event<2)
0753 {
0754 std::cout << PHWHERE << " cannot find SvtxTrackMap" << std::endl;
0755 }
0756
0757 _vertexmap = findNode::getClass<SvtxVertexMap>(topNode,"SvtxVertexMap");
0758 if(!_vertexmap && _event<2)
0759 {
0760 std::cout << PHWHERE << " cannot find SvtxVertexMap" << std::endl;
0761 }
0762
0763 _tGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0764 if(!_tGeometry && _event<2)
0765 {
0766 std::cout << PHWHERE << " cannot find ActsGeometry" << std::endl;
0767 }
0768
0769 _inttGeom = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_INTT");
0770 if(!_inttGeom && _event<2)
0771 {
0772 std::cout << PHWHERE << " cannot find CYLINDERGEOM_INTT" << std::endl;
0773 }
0774
0775 _tpcGeom = findNode::getClass<PHG4TpcGeomContainer>(topNode,"TPCGEOMCONTAINER");
0776 if(!_tpcGeom && _event<2)
0777 {
0778 std::cout << PHWHERE << " cannot find CYLINDERCELLGEOM_SVTX" << std::endl;
0779 }
0780
0781 _tpotGeom = findNode::getClass<PHG4CylinderGeomContainer>(topNode, "CYLINDERGEOM_MICROMEGAS_FULL");
0782 if(!_tpotGeom && _event<2)
0783 {
0784 std::cout << PHWHERE << " cannot find CYLINDERGEOM_MICROMEGAS_FULL" << std::endl;
0785 }
0786
0787 }
0788
0789
0790 int TrackDeadLayerTagging::End(PHCompositeNode *topNode)
0791 {
0792 PHTFileServer::get().cd( _outfile );
0793 _missing_sensors->Write();
0794 return 0;
0795 }
0796