Back to home page

sPhenix code displayed by LXR

 
 

    


Warning, /coresoftware/offline/packages/trackreco/PHActsVertexFinder.cc.outdated is written in an unsupported language. File is not indexed.

0001 #include "PHActsVertexFinder.h"
0002 #include <trackbase_historic/ActsTransformations.h>
0003 
0004 #include <fun4all/Fun4AllReturnCodes.h>
0005 #include <phool/PHCompositeNode.h>
0006 #include <phool/PHIODataNode.h>
0007 #include <phool/PHObject.h>
0008 #include <phool/getClass.h>
0009 #include <phool/phool.h>
0010 
0011 #if __cplusplus < 201402L
0012 #include <boost/make_unique.hpp>
0013 #endif
0014 
0015 #include <trackbase_historic/SvtxTrackMap.h>
0016 #include <trackbase_historic/SvtxTrack.h>
0017 #include <trackbase_historic/SvtxVertexMap.h>
0018 #include <trackbase_historic/SvtxVertex.h>
0019 #include <trackbase_historic/SvtxVertex_v1.h>
0020 #include <trackbase_historic/SvtxVertexMap_v1.h>
0021 
0022 #include <ActsExamples/Plugins/BField/BFieldOptions.hpp>
0023 #include <ActsExamples/Plugins/BField/ScalableBField.hpp>
0024 
0025 #include <Acts/EventData/TrackParameters.hpp>
0026 #include <Acts/MagneticField/ConstantBField.hpp>
0027 #include <Acts/MagneticField/InterpolatedBFieldMap.hpp>
0028 #include <Acts/MagneticField/SharedBField.hpp>
0029 #include <Acts/Propagator/EigenStepper.hpp>
0030 #include <Acts/Propagator/Propagator.hpp>
0031 #include <Acts/Surfaces/PerigeeSurface.hpp>
0032 #include <Acts/Utilities/Definitions.hpp>
0033 #include <Acts/Utilities/Helpers.hpp>
0034 #include <Acts/Utilities/Logger.hpp>
0035 #include <Acts/Utilities/Units.hpp>
0036 #include <Acts/Vertexing/FullBilloirVertexFitter.hpp>
0037 #include <Acts/Vertexing/HelicalTrackLinearizer.hpp>
0038 #include <Acts/Vertexing/ImpactPointEstimator.hpp>
0039 #include <Acts/Vertexing/IterativeVertexFinder.hpp>
0040 #include <Acts/Vertexing/LinearizedTrack.hpp>
0041 #include <Acts/Vertexing/Vertex.hpp>
0042 #include <Acts/Vertexing/VertexFinderConcept.hpp>
0043 #include <Acts/Vertexing/VertexingOptions.hpp>
0044 #include <Acts/Vertexing/ZScanVertexFinder.hpp>
0045 
0046 #include <Acts/Geometry/GeometryContext.hpp>
0047 #include <Acts/MagneticField/MagneticFieldContext.hpp>
0048 
0049 #include <memory>
0050 #include <iostream>
0051 
0052 PHActsVertexFinder::PHActsVertexFinder(const std::string &name)
0053   : PHInitVertexing(name)
0054   , m_actsVertexMap(nullptr)
0055   , m_trajectories(nullptr)
0056 {
0057 }
0058 
0059 int PHActsVertexFinder::Setup(PHCompositeNode *topNode)
0060 {
0061   int ret = getNodes(topNode);
0062   if(ret != Fun4AllReturnCodes::EVENT_OK)
0063     return ret;
0064 
0065   ret = createNodes(topNode);
0066   if(ret != Fun4AllReturnCodes::EVENT_OK)
0067     return ret;
0068   
0069   return Fun4AllReturnCodes::EVENT_OK;
0070 }
0071 
0072 int PHActsVertexFinder::Process(PHCompositeNode*)
0073 {
0074   if(Verbosity() > 0)
0075     {
0076       std::cout << "Starting event " << m_event << " in PHActsVertexFinder"
0077                 << std::endl;
0078     }
0079 
0080   /// Create a map that correlates the track momentum to the track key
0081   KeyMap keyMap;
0082 
0083   /// Get the list of tracks in Acts form
0084   auto trackPointers = getTracks(keyMap);
0085 
0086   auto vertices = findVertices(trackPointers);
0087 
0088   fillVertexMap(vertices, keyMap);
0089   
0090   checkTrackVertexAssociation();
0091 
0092   /// Clean up the track pointer vector memory
0093   for(auto track : trackPointers)
0094     {
0095       delete track;
0096     }
0097 
0098   for(auto [key, svtxVertex] : *m_svtxVertexMap)
0099     { 
0100       m_svtxVertexMapActs->insert(dynamic_cast<SvtxVertex*>(svtxVertex->CloneMe()));
0101     }
0102 
0103   if(Verbosity() > 0)
0104     std::cout << "Finished PHActsVertexFinder::process_event" << std::endl;
0105 
0106   m_event++;
0107 
0108   return Fun4AllReturnCodes::EVENT_OK;
0109 }
0110 
0111 int PHActsVertexFinder::ResetEvent(PHCompositeNode */*topNode*/)
0112 {
0113   m_actsVertexMap->clear();
0114   m_svtxVertexMap->clear();
0115 
0116   return Fun4AllReturnCodes::EVENT_OK;
0117 
0118 }
0119 
0120   int PHActsVertexFinder::End(PHCompositeNode */*topNode*/)
0121 {
0122   std::cout << "Acts Final vertex finder succeeeded " << m_goodFits
0123             << " out of " << m_totalFits << " events processed"
0124             << std::endl;
0125 
0126   return Fun4AllReturnCodes::EVENT_OK;
0127 }
0128 
0129 void PHActsVertexFinder::checkTrackVertexAssociation()
0130 {
0131   for(auto& [key, track] : *m_svtxTrackMap)
0132     {
0133       auto vertId = track->get_vertex_id();
0134       if(!m_svtxVertexMap->get(vertId)) 
0135         {
0136           /// Secondary not used in Acts vertex fitting. Assign
0137           /// closest vertex based on z position
0138 
0139           const auto trackZ = track->get_z();
0140           double closestVertZ = 9999;
0141           vertId = UINT_MAX;
0142 
0143           for(auto& [vertexKey, vertex] : *m_svtxVertexMap)
0144             {
0145               double dz = fabs(trackZ - vertex->get_z());
0146               if(dz < closestVertZ)
0147                 {
0148                   vertId = vertexKey;
0149                   closestVertZ = dz;
0150                 }
0151             }
0152           
0153           auto vertex = m_svtxVertexMap->get(vertId);
0154           vertex->insert_track(key);
0155           track->set_vertex_id(vertId);
0156         }
0157     }
0158 
0159 }
0160 
0161 TrackPtrVector PHActsVertexFinder::getTracks(KeyMap& keyMap)
0162 {
0163   std::vector<const Acts::BoundTrackParameters*> trackPtrs;
0164   
0165   for(const auto& [key, traj] : *m_trajectories)
0166     {
0167       const auto svtxTrack = m_svtxTrackMap->get(key);
0168       
0169       // Track was removed by the track cleaner, skip it
0170       if(!svtxTrack)
0171         { continue; }
0172 
0173       int nmaps = 0;
0174       int nintt = 0;
0175       int ntpc = 0;
0176       
0177       for(SvtxTrack::ConstClusterKeyIter clusIter = svtxTrack->begin_cluster_keys();
0178           clusIter != svtxTrack->end_cluster_keys();
0179           ++clusIter)
0180         {
0181           auto key = *clusIter;
0182           auto trkrId = TrkrDefs::getTrkrId(key);
0183           if(trkrId == TrkrDefs::TrkrId::mvtxId)
0184             { nmaps++; }
0185           if(trkrId == TrkrDefs::TrkrId::inttId)
0186             { nintt++; }
0187           if(trkrId == TrkrDefs::TrkrId::tpcId)
0188             { ntpc++; }
0189         }
0190 
0191       if((nmaps + nintt + ntpc) < 35)
0192         { continue; }
0193       if(svtxTrack->get_pt() < 0.5)
0194         { continue; }
0195       if(nmaps < 1)
0196         { continue; }
0197       
0198       const auto& [trackTips, mj] = traj.trajectory();
0199       for(const auto& trackTip : trackTips)
0200         {
0201           const Acts::BoundTrackParameters* params =
0202             new Acts::BoundTrackParameters(traj.trackParameters(trackTip));
0203           trackPtrs.push_back(params);
0204           
0205           keyMap.insert(std::make_pair(params, key));
0206 
0207         }
0208     }
0209   
0210   if(Verbosity() > 3)
0211     {
0212       std::cout << "Finding vertices for the following number of tracks "
0213                 << trackPtrs.size() << std::endl;
0214      
0215       for(const auto& [param, key] : keyMap)
0216         {
0217           std::cout << "Track ID : " << key << " Track position: (" 
0218                     << param->position(m_tGeometry->getGeoContext()).transpose()
0219                     << std::endl;
0220         }
0221     }
0222 
0223   return trackPtrs;
0224 
0225 }
0226 
0227 VertexVector PHActsVertexFinder::findVertices(TrackPtrVector& tracks)
0228 {
0229   m_totalFits++;
0230   
0231   auto field = m_tGeometry->magField;
0232 
0233   /// Determine the input mag field type from the initial geometry
0234   /// and run the vertex finding with the determined mag field
0235   return std::visit([tracks, this](auto &inputField) {
0236       /// Setup aliases
0237       using InputMagneticField = 
0238         typename std::decay_t<decltype(inputField)>::element_type;
0239       using MagneticField = Acts::SharedBField<InputMagneticField>;
0240       
0241       using Stepper = Acts::EigenStepper<MagneticField>;
0242       using Propagator = Acts::Propagator<Stepper>;
0243       using PropagatorOptions = Acts::PropagatorOptions<>;
0244       using TrackParameters = Acts::BoundTrackParameters;
0245       using Linearizer = Acts::HelicalTrackLinearizer<Propagator>;
0246       using VertexFitter = 
0247         Acts::FullBilloirVertexFitter<TrackParameters,Linearizer>;
0248       using ImpactPointEstimator = 
0249         Acts::ImpactPointEstimator<TrackParameters, Propagator>;
0250       using VertexSeeder = Acts::ZScanVertexFinder<VertexFitter>;
0251       using VertexFinder = 
0252         Acts::IterativeVertexFinder<VertexFitter, VertexSeeder>;
0253       using VertexFinderOptions = Acts::VertexingOptions<TrackParameters>;
0254 
0255       static_assert(Acts::VertexFinderConcept<VertexSeeder>,
0256                     "VertexSeeder does not fulfill vertex finder concept.");
0257       static_assert(Acts::VertexFinderConcept<VertexFinder>,
0258                     "VertexFinder does not fulfill vertex finder concept.");
0259 
0260       auto logLevel = Acts::Logging::FATAL;
0261       if(Verbosity() > 4)
0262         logLevel = Acts::Logging::VERBOSE;
0263       auto logger = Acts::getDefaultLogger("PHActsVertexFinder", logLevel);
0264 
0265       MagneticField bField(inputField);
0266       auto propagator = std::make_shared<Propagator>(Stepper(bField));
0267       
0268       /// Setup vertex finder now
0269       typename VertexFitter::Config vertexFitterConfig;
0270       VertexFitter vertexFitter(std::move(vertexFitterConfig));
0271       
0272       typename Linearizer::Config linearizerConfig(bField, propagator);
0273       Linearizer linearizer(std::move(linearizerConfig));
0274       
0275       typename ImpactPointEstimator::Config ipEstConfig(bField, propagator);
0276       ImpactPointEstimator ipEst(std::move(ipEstConfig));
0277       
0278       typename VertexSeeder::Config seederConfig(ipEst);
0279       VertexSeeder seeder(std::move(seederConfig));
0280       
0281       typename VertexFinder::Config finderConfig(std::move(vertexFitter), 
0282                                                  std::move(linearizer),
0283                                                  std::move(seeder), ipEst);
0284       finderConfig.maxVertices = m_maxVertices;
0285       finderConfig.reassignTracksAfterFirstFit = true;
0286       VertexFinder finder(finderConfig, std::move(logger));
0287       
0288       typename VertexFinder::State state(m_tGeometry->magFieldContext);
0289       VertexFinderOptions finderOptions(m_tGeometry->getGeoContext(),
0290                                         m_tGeometry->magFieldContext);
0291       
0292       auto result = finder.find(tracks, finderOptions, state);
0293     
0294       VertexVector vertexVector;
0295 
0296       if(result.ok())
0297         {
0298           auto vertexCollection = *result;
0299           m_goodFits++;
0300           
0301           if(Verbosity() > 1)
0302             {
0303               std::cout << "Acts IVF found " << vertexCollection.size()
0304                         << " vertices in event" << std::endl;
0305             }
0306           
0307           for(const auto& vertex : vertexCollection) 
0308             {
0309               vertexVector.push_back(vertex);
0310             }
0311         }
0312       else
0313         {
0314           if(Verbosity() > 1)
0315             {
0316               std::cout << "Acts vertex finder returned error: " 
0317                         << result.error().message() << std::endl;
0318             }     
0319         }
0320 
0321       return vertexVector;
0322       
0323     } /// end lambda
0324     , field
0325     ); /// end std::visit call
0326 }
0327 
0328 
0329 
0330 
0331 void PHActsVertexFinder::fillVertexMap(VertexVector& vertices,
0332                                        KeyMap& keyMap)
0333 {
0334   unsigned int key = 0;
0335 
0336   if(vertices.size() > 0)
0337     m_svtxVertexMap->clear();
0338   
0339   else if (vertices.size() == 0)
0340     {
0341       auto svtxVertex = std::make_unique<SvtxVertex_v1>();
0342       svtxVertex->set_x(0);
0343       svtxVertex->set_y(0);
0344       svtxVertex->set_z(0);
0345        for(int i = 0; i < 3; ++i) 
0346         {
0347           for(int j = 0; j < 3; ++j)
0348             {
0349               svtxVertex->set_error(i, j, 100.); 
0350             }
0351         }
0352        m_svtxVertexMap->insert(svtxVertex.release());
0353     }
0354 
0355   for(auto& vertex : vertices)
0356     {
0357       const auto &[chi2, ndf] = vertex.fitQuality();
0358       const auto numTracks = vertex.tracks().size();
0359       
0360       if(Verbosity() > 1)
0361         {
0362           std::cout << "Found vertex at (" << vertex.position().x()
0363                     << ", " << vertex.position().y() << ", " 
0364                     << vertex.position().z() << ")" << std::endl;
0365           std::cout << "Vertex has ntracks = " << numTracks
0366                     << " with chi2/ndf " << chi2 / ndf << std::endl;
0367         }
0368 
0369 
0370       /// Fill Acts vertex map
0371       auto pair = std::make_pair(key, vertex);
0372       m_actsVertexMap->insert(pair);
0373 
0374       /// Fill SvtxVertexMap
0375       #if __cplusplus < 201402L
0376       auto svtxVertex = boost::make_unique<SvtxVertex_v1>();
0377       #else
0378       auto svtxVertex = std::make_unique<SvtxVertex_v1>();
0379       #endif
0380 
0381       const auto vertexX = vertex.position().x() / Acts::UnitConstants::cm;
0382       const auto vertexY = vertex.position().y() / Acts::UnitConstants::cm;
0383       const auto vertexZ = vertex.position().z() / Acts::UnitConstants::cm;
0384       
0385       svtxVertex->set_x(vertexX);  
0386       svtxVertex->set_y(vertexY);
0387       svtxVertex->set_z(vertexZ);
0388       for(int i = 0; i < 3; ++i) 
0389         {
0390           for(int j = 0; j < 3; ++j)
0391             {
0392               svtxVertex->set_error(i, j,
0393                vertex.covariance()(i,j) / Acts::UnitConstants::cm2); 
0394             }
0395         }
0396 
0397       for(const auto& track : vertex.tracks())
0398         {
0399           const auto originalParams = track.originalParams;
0400           const auto trackKey = keyMap.find(originalParams)->second;
0401           svtxVertex->insert_track(trackKey);
0402 
0403           const auto svtxTrack = m_svtxTrackMap->find(trackKey)->second;
0404           svtxTrack->set_vertex_id(key);
0405           updateTrackDCA(trackKey, Acts::Vector3D(vertexX,
0406                                                   vertexY,
0407                                                   vertexZ));
0408         }
0409 
0410       svtxVertex->set_chisq(chi2);
0411       svtxVertex->set_ndof(ndf);
0412       svtxVertex->set_t0(vertex.time());
0413       svtxVertex->set_id(key);
0414 
0415       m_svtxVertexMap->insert(svtxVertex.release());
0416 
0417       ++key;
0418     }
0419 
0420   if(Verbosity() > 2)
0421     {
0422       std::cout << "Identify vertices in vertex map" << std::endl;
0423       for(auto& [key, vert] : *m_svtxVertexMap)
0424         {
0425           vert->identify();
0426         }
0427     }
0428 
0429   return;
0430 }
0431 
0432 void PHActsVertexFinder::updateTrackDCA(const unsigned int trackKey,
0433                                         const Acts::Vector3D vertex)
0434 {
0435   
0436   auto svtxTrack = m_svtxTrackMap->find(trackKey)->second;
0437   
0438   Acts::Vector3D pos(svtxTrack->get_x(),
0439                      svtxTrack->get_y(),
0440                      svtxTrack->get_z());
0441   Acts::Vector3D mom(svtxTrack->get_px(),
0442                      svtxTrack->get_py(),
0443                      svtxTrack->get_pz());
0444   
0445   pos -= vertex;
0446 
0447   Acts::ActsSymMatrixD<3> posCov;
0448   for(int i = 0; i < 3; ++i)
0449     {
0450       for(int j = 0; j < 3; ++j)
0451         {
0452           posCov(i, j) = svtxTrack->get_error(i, j);
0453         } 
0454     }
0455   
0456   Acts::Vector3D r = mom.cross(Acts::Vector3D(0.,0.,1.));
0457   float phi = atan2(r(1), r(0));
0458 
0459   Acts::RotationMatrix3D rot;
0460   Acts::RotationMatrix3D rot_T;
0461   rot(0,0) = cos(phi);
0462   rot(0,1) = -sin(phi);
0463   rot(0,2) = 0;
0464   rot(1,0) = sin(phi);
0465   rot(1,1) = cos(phi);
0466   rot(1,2) = 0;
0467   rot(2,0) = 0;
0468   rot(2,1) = 0;
0469   rot(2,2) = 1;
0470   
0471   rot_T = rot.transpose();
0472 
0473   Acts::Vector3D pos_R = rot * pos;
0474   Acts::ActsSymMatrixD<3> rotCov = rot * posCov * rot_T;
0475 
0476   const auto dca3Dxy = pos_R(0);
0477   const auto dca3Dz = pos_R(2);
0478   const auto dca3DxyCov = rotCov(0,0);
0479   const auto dca3DzCov = rotCov(2,2);
0480 
0481   svtxTrack->set_dca3d_xy(dca3Dxy);
0482   svtxTrack->set_dca3d_z(dca3Dz);
0483   svtxTrack->set_dca3d_xy_error(sqrt(dca3DxyCov));
0484   svtxTrack->set_dca3d_z_error(sqrt(dca3DzCov));
0485 
0486 }
0487 
0488 int PHActsVertexFinder::createNodes(PHCompositeNode *topNode)
0489 {
0490   PHNodeIterator iter(topNode);
0491   
0492   PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0493 
0494   if (!dstNode)
0495     {
0496       std::cerr << "DST node is missing, quitting" << std::endl;
0497       throw std::runtime_error("Failed to find DST node in PHActsTracks::createNodes");
0498     }
0499   
0500   PHCompositeNode *svtxNode = 
0501     dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "SVTX"));
0502   
0503   if (!svtxNode)
0504     {
0505       svtxNode = new PHCompositeNode("SVTX");
0506       dstNode->addNode(svtxNode);
0507     }
0508  
0509   m_actsVertexMap = 
0510     findNode::getClass<VertexMap>(topNode, "ActsVertexMap");
0511   if(!m_actsVertexMap)
0512     {
0513       m_actsVertexMap = new VertexMap;
0514       
0515       PHDataNode<VertexMap> *node = 
0516         new PHDataNode<VertexMap>(m_actsVertexMap,
0517                                   "ActsVertexMap");
0518    
0519       svtxNode->addNode(node);
0520     }
0521 
0522   m_svtxVertexMapActs = 
0523     findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMapActs");
0524   if(!m_svtxVertexMapActs)
0525     {
0526       m_svtxVertexMapActs = new SvtxVertexMap_v1;
0527       PHIODataNode<PHObject> *node = 
0528         new PHIODataNode<PHObject>(m_svtxVertexMapActs,
0529                                    "SvtxVertexMapActs", "PHObject");
0530       svtxNode->addNode(node);
0531     }
0532 
0533   m_svtxVertexMap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0534   if(!m_svtxVertexMap)
0535     {
0536       m_svtxVertexMap = new SvtxVertexMap_v1;
0537       PHIODataNode<PHObject> *node = new PHIODataNode<PHObject>(m_svtxVertexMap,
0538                                                                 "SvtxVertexMap",
0539                                                                 "PHObject");
0540       svtxNode->addNode(node);
0541     }
0542 
0543   return Fun4AllReturnCodes::EVENT_OK;
0544 }
0545 
0546 int PHActsVertexFinder::getNodes(PHCompositeNode *topNode)
0547 {
0548   m_trajectories = findNode::getClass<std::map<const unsigned int, Trajectory>>(topNode, "ActsTrajectories");
0549   if(!m_trajectories)
0550     {
0551       std::cout << PHWHERE << "No trajectories on node tree, bailing."
0552                 << std::endl;
0553       return Fun4AllReturnCodes::ABORTEVENT;
0554     }
0555 
0556   m_tGeometry = findNode::getClass<ActsTrackingGeometry>(topNode, 
0557                                                          "ActsTrackingGeometry");
0558   if(!m_tGeometry)
0559     {
0560       std::cout << PHWHERE << "ActsTrackingGeometry not on node tree. Exiting"
0561                 << std::endl;
0562       return Fun4AllReturnCodes::ABORTEVENT;
0563     }
0564 
0565   m_svtxTrackMap = findNode::getClass<SvtxTrackMap>(topNode,
0566                                                     "SvtxTrackMap");
0567   if(!m_svtxTrackMap)
0568     {
0569       std::cout << PHWHERE << "No SvtxTrackMap on node tree, exiting."
0570                 << std::endl;
0571       return Fun4AllReturnCodes::ABORTEVENT;
0572     }
0573 
0574   return Fun4AllReturnCodes::EVENT_OK;
0575 }