Back to home page

sPhenix code displayed by LXR

 
 

    


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   //initialize
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   //_outtree = new TNtuple("deadlayers_test","deadlayers_test","x:y:z:pt:pz:eta:phi:charge:nhits:nmaps:nintt:quality:crossing:vtx_x:vtx_y:vtx_z:vtx_ntracks:vtxid:ndead_mvtx:ndead_intt:ndead_tpc:ndead_tpot");
0054 
0055   return 0;
0056 }
0057 
0058 //__________________________________
0059 //Call user instructions for every event
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   //std::string intt_badstrip = CDBInterface::instance()->getUrl("INTT_BadChannelMap");
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   //std::unique_ptr<CDBTTree> intt_badtree = std::make_unique<CDBTTree>(intt_badstrip);
0091 
0092   mvtx_hottree->LoadCalibrations();
0093   mvtx_deadtree->LoadCalibrations();
0094   intt_hottree->LoadCalibrations();
0095   //intt_badtree->LoadCalibrations();
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   //int n_inttbad = intt_badtree->GetSingleIntValue("size");
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   for(int i=0; i<n_inttbad; i++)
0155   {
0156     int layer = intt_badtree->GetIntValue(i,"layer");
0157     MissingSensor badsensor_intt = {
0158       layer,
0159       intt_badtree->GetIntValue(i,"ladder_phi"),
0160       intt_badtree->GetIntValue(i,"ladder_z"),
0161       intt_badtree->GetIntValue(i,"strip_phi"),
0162       intt_badtree->GetIntValue(i,"strip_z")
0163     };
0164     if(layer>=3&&layer<=6)
0165     {
0166       _dead_sensors[layer].push_back(badsensor_intt);
0167     }
0168   }
0169 */
0170   // TODO: figure out how TPC and TPOT work for this
0171 }
0172 
0173 void TrackDeadLayerTagging::get_surfaces()
0174 {
0175   for(int layer=0; layer<57; layer++)
0176   {
0177     if(layer<3) // mvtx
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           //std::cout << "layer " << layer << ", stave " << stave_id << ", chip " << chip_id << ", hskey " << std::to_string(hskey) << std::endl;
0187           //std::cout << "geoId: " << _tGeometry->maps().getSiliconSurface(hskey)->geometryId() << std::endl;
0188           _surface_map.insert(std::make_pair(_tGeometry->maps().getSiliconSurface(hskey)->geometryId(),hskey));
0189         }
0190       }
0191     }
0192     else if(layer<7) // intt
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           //std::cout << "hskey " << std::to_string(hskey) << std::endl;
0204           //std::cout << "gen hitsetkey should have layer " << layer << ", z id " << ladder_z_id << ", phi id " << ladder_phi_id << std::endl;
0205           //std::cout << "actually has layer " << int(TrkrDefs::getLayer(hskey)) << ", z id " << int(InttDefs::getLadderZId(hskey)) << ", phi id " << int(InttDefs::getLadderPhiId(hskey)) << std::endl;
0206           //std::cout << "geoId: " << _tGeometry->maps().getSiliconSurface(hskey)->geometryId() << std::endl;
0207           _surface_map.insert(std::make_pair(_tGeometry->maps().getSiliconSurface(hskey)->geometryId(),hskey));
0208         }
0209       }
0210     }
0211     else if(layer<55) // tpc
0212     {
0213       // TODO: implement TPC surface get
0214     }
0215     else if(layer<57) // tpot
0216     {
0217       // TODO: implement TPOT surface get
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     //propagator.verbosity(10);
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           // [path length (mm), BoundTrackParams]
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           //std::cout << "hskey: " << std::to_string(_surface_map[surf->geometryId()]) << std::endl;
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     // get fit parameters for track; use TPC seed for this unless silicon-only track
0282     std::vector<float> fitpars = tpcseed? getFitParams(tpcseed) : getFitParams(siliconseed);
0283 
0284     // get nearest cluster phi for each layer (necessary to disambiguate multiple compatible surfaces)
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     // for each missing layer, find helix intersection with compatible surface in that layer
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       // disambiguate multiple compatible surfaces on helix
0356       if(compatible_surfaces.size()>1)
0357       {
0358         // find cluster phi of closest on-track layer to space point
0359         float closest_phi = 1e9;
0360         // cover edge cases
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         // determine which space point has most similar phi to closest on-track cluster phi
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) // MVTX
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) // INTT
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