Warning, /coresoftware/offline/packages/trackreco/PHActsInitialVertexFinder.cc.outdated is written in an unsupported language. File is not indexed.
0001 #include "PHActsInitialVertexFinder.h"
0002
0003 #include <trackbase_historic/ActsTransformations.h>
0004
0005 #include <fun4all/Fun4AllReturnCodes.h>
0006 #include <phool/PHCompositeNode.h>
0007 #include <phool/PHIODataNode.h>
0008 #include <phool/PHObject.h>
0009 #include <phool/getClass.h>
0010 #include <phool/phool.h>
0011 #include <phool/PHRandomSeed.h>
0012
0013 #if __cplusplus < 201402L
0014 #include <boost/make_unique.hpp>
0015 #endif
0016
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 #include <trackbase_historic/SvtxTrackMap.h>
0022
0023 #include <ActsExamples/Plugins/BField/BFieldOptions.hpp>
0024 #include <ActsExamples/Plugins/BField/ScalableBField.hpp>
0025
0026 #include <Acts/EventData/TrackParameters.hpp>
0027 #include <Acts/MagneticField/ConstantBField.hpp>
0028 #include <Acts/MagneticField/InterpolatedBFieldMap.hpp>
0029 #include <Acts/MagneticField/SharedBField.hpp>
0030 #include <Acts/Propagator/EigenStepper.hpp>
0031 #include <Acts/Propagator/Propagator.hpp>
0032 #include <Acts/Surfaces/PerigeeSurface.hpp>
0033 #include <Acts/Utilities/Definitions.hpp>
0034 #include <Acts/Utilities/Helpers.hpp>
0035 #include <Acts/Utilities/Logger.hpp>
0036 #include <Acts/Utilities/Units.hpp>
0037 #include <Acts/Vertexing/FullBilloirVertexFitter.hpp>
0038 #include <Acts/Vertexing/HelicalTrackLinearizer.hpp>
0039 #include <Acts/Vertexing/ImpactPointEstimator.hpp>
0040 #include <Acts/Vertexing/IterativeVertexFinder.hpp>
0041 #include <Acts/Vertexing/LinearizedTrack.hpp>
0042 #include <Acts/Vertexing/Vertex.hpp>
0043 #include <Acts/Vertexing/VertexFinderConcept.hpp>
0044 #include <Acts/Vertexing/VertexingOptions.hpp>
0045 #include <Acts/Vertexing/ZScanVertexFinder.hpp>
0046
0047 #include <Acts/Geometry/GeometryContext.hpp>
0048 #include <Acts/MagneticField/MagneticFieldContext.hpp>
0049
0050 #include <memory>
0051
0052 PHActsInitialVertexFinder::PHActsInitialVertexFinder(const std::string& name)
0053 : PHInitVertexing(name)
0054 {}
0055
0056 int PHActsInitialVertexFinder::Setup(PHCompositeNode *topNode)
0057 {
0058 if(getNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0059 return Fun4AllReturnCodes::ABORTEVENT;
0060
0061 if(createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0062 return Fun4AllReturnCodes::ABORTEVENT;
0063
0064 m_seed = PHRandomSeed();
0065 m_random_number_generator.seed(m_seed);
0066
0067 return Fun4AllReturnCodes::EVENT_OK;
0068 }
0069
0070 int PHActsInitialVertexFinder::Process(PHCompositeNode */*topNode*/)
0071 {
0072 if(Verbosity() > 0)
0073 std::cout << "PHActsInitialVertexFinder processing event "
0074 << m_event << std::endl;
0075
0076 if(m_trackMap->size() == 0)
0077 {
0078 std::cout << PHWHERE
0079 << "No silicon track seeds found. Can't run initial vertexing, setting dummy vertex of (0,0,0)"
0080 << std::endl;
0081 createDummyVertex(0,0,0);
0082 }
0083 else if(m_trackMap->size() == 1)
0084 {
0085 auto track = m_trackMap->get(0);
0086 createDummyVertex(track->get_x(),
0087 track->get_y(),
0088 track->get_z());
0089 }
0090 else
0091 {
0092 InitKeyMap keyMap;
0093 auto trackPointers = getTrackPointers(keyMap);
0094
0095 auto vertices = findVertices(trackPointers);
0096
0097 fillVertexMap(vertices, keyMap);
0098
0099 /// Need to check that silicon stubs which may have been
0100 /// skipped over still have a vertex association
0101 checkTrackVertexAssociation();
0102
0103 for(auto track : trackPointers)
0104 {
0105 delete track;
0106 }
0107 }
0108
0109 if(Verbosity() > 0)
0110 std::cout << "PHActsInitialVertexFinder processed event "
0111 << m_event << std::endl;
0112
0113 m_event++;
0114
0115 return Fun4AllReturnCodes::EVENT_OK;
0116 }
0117
0118 int PHActsInitialVertexFinder::ResetEvent(PHCompositeNode */*topNode*/)
0119 {
0120 return Fun4AllReturnCodes::EVENT_OK;
0121 }
0122
0123 int PHActsInitialVertexFinder::End(PHCompositeNode */*topNode*/)
0124 {
0125
0126 std::cout << "Acts IVF succeeded " << m_successFits
0127 << " out of " << m_totVertexFits << " total fits"
0128 << std::endl;
0129
0130 return Fun4AllReturnCodes::EVENT_OK;
0131 }
0132
0133 void PHActsInitialVertexFinder::checkTrackVertexAssociation()
0134 {
0135
0136 for(auto& [trackKey, track] : *m_trackMap)
0137 {
0138 /// If the track wasn't already given a vertex ID, it wasn't
0139 /// included in the initial vertex finding due to Acts not liking
0140 /// tracks with large transverse position. So find the closest
0141 /// z vertex to it and assign it
0142 if(track->get_vertex_id() != UINT_MAX)
0143 continue;
0144
0145 const auto trackZ = track->get_z();
0146
0147 double closestVertZ = 9999;
0148 int vertId = -1;
0149 for(auto& [vertexKey, vertex] : *m_vertexMap)
0150 {
0151 double dz = fabs(trackZ - vertex->get_z());
0152
0153 if(dz < closestVertZ)
0154 {
0155 vertId = vertexKey;
0156 closestVertZ = dz;
0157 }
0158
0159 }
0160
0161 auto vertex = m_vertexMap->get(vertId);
0162 vertex->insert_track(trackKey);
0163 track->set_vertex_id(vertId);
0164 }
0165
0166 }
0167 void PHActsInitialVertexFinder::fillVertexMap(VertexVector& vertices,
0168 InitKeyMap& keyMap)
0169 {
0170 unsigned int vertexId = 0;
0171 if(vertices.size() != 0)
0172 m_vertexMap->clear();
0173
0174 /// Create a fail safe for (e.g.) single particle events which
0175 /// don't return a vertex
0176 if(vertices.size() == 0)
0177 {
0178 createDummyVertex(0,0,0);
0179 if(Verbosity() > 1)
0180 std::cout << "No vertices found. Adding a dummy vertex"
0181 << std::endl;
0182 return;
0183 }
0184
0185 for(auto vertex : vertices)
0186 {
0187 const auto &[chi2, ndf] = vertex.fitQuality();
0188 const auto numTracks = vertex.tracks().size();
0189
0190 if(Verbosity() > 1)
0191 {
0192 std::cout << "Found vertex at (" << vertex.position().x()
0193 << ", " << vertex.position().y() << ", "
0194 << vertex.position().z() << ")" << std::endl;
0195 std::cout << "Vertex has ntracks = " << numTracks
0196 << " with chi2/ndf " << chi2 / ndf << std::endl;
0197 }
0198
0199 /// Fill SvtxVertexMap
0200 #if __cplusplus < 201402L
0201 auto svtxVertex = boost::make_unique<SvtxVertex_v1>();
0202 #else
0203 auto svtxVertex = std::make_unique<SvtxVertex_v1>();
0204 #endif
0205
0206 svtxVertex->set_x(vertex.position().x() / Acts::UnitConstants::cm);
0207 svtxVertex->set_y(vertex.position().y() / Acts::UnitConstants::cm);
0208 svtxVertex->set_z(vertex.position().z() / Acts::UnitConstants::cm);
0209 for(int i = 0; i < 3; ++i)
0210 for(int j = 0; j < 3; ++j)
0211 svtxVertex->set_error(i, j,
0212 vertex.covariance()(i,j)
0213 / Acts::UnitConstants::cm2);
0214
0215 svtxVertex->set_chisq(chi2);
0216 svtxVertex->set_ndof(ndf);
0217 svtxVertex->set_t0(vertex.time());
0218 svtxVertex->set_id(vertexId);
0219
0220 for(const auto& track : vertex.tracks())
0221 {
0222 const auto originalParams = track.originalParams;
0223
0224 const auto trackKey = keyMap.find(originalParams)->second;
0225 svtxVertex->insert_track(trackKey);
0226
0227 /// Give the track the appropriate vertex id
0228 const auto svtxTrack = m_trackMap->find(trackKey)->second;
0229
0230 if(Verbosity() > 3)
0231 {
0232 svtxTrack->identify();
0233 std::cout << "Updating track key " << trackKey << " with vertex "
0234 << vertexId << std::endl;
0235 }
0236
0237 svtxTrack->set_vertex_id(vertexId);
0238 }
0239
0240 m_vertexMap->insert(svtxVertex.release());
0241
0242 ++vertexId;
0243 }
0244
0245 return;
0246 }
0247
0248 void PHActsInitialVertexFinder::createDummyVertex(const float x,
0249 const float y,
0250 const float z)
0251 {
0252
0253 /// If the Acts IVF finds 0 vertices or there weren't enough tracks
0254 /// for it to properly identify a good vertex. So just create
0255 /// a dummy vertex with large covariance for rest of track
0256 /// reconstruction to avoid seg faults
0257
0258 #if __cplusplus < 201402L
0259 auto svtxVertex = boost::make_unique<SvtxVertex_v1>();
0260 #else
0261 auto svtxVertex = std::make_unique<SvtxVertex_v1>();
0262 #endif
0263
0264 svtxVertex->set_x(x);
0265 svtxVertex->set_y(y);
0266 svtxVertex->set_z(z);
0267
0268 for(int i = 0; i < 3; ++i)
0269 for(int j = 0; j < 3; ++j)
0270 {
0271 if( i == j)
0272 svtxVertex->set_error(i, j, 10.);
0273 else
0274 svtxVertex->set_error(i,j, 0);
0275 }
0276
0277 float nan = NAN;
0278 svtxVertex->set_chisq(nan);
0279 svtxVertex->set_ndof(nan);
0280 svtxVertex->set_t0(nan);
0281 svtxVertex->set_id(0);
0282
0283 m_vertexMap->insert(svtxVertex.release());
0284 std::cout << "Created dummy vertex at " << x << ", " << y << ", " << z
0285 << std::endl;
0286 for(auto& [key, track] : *m_trackMap)
0287 track->set_vertex_id(0);
0288
0289 }
0290
0291 VertexVector PHActsInitialVertexFinder::findVertices(TrackParamVec& tracks)
0292 {
0293
0294 m_totVertexFits++;
0295
0296 auto field = m_tGeometry->magField;
0297
0298 /// Determine the input mag field type from the initial geometry
0299 /// and run the vertex finding with the determined mag field
0300 return std::visit([tracks, this](auto &inputField) {
0301 /// Setup aliases
0302 using InputMagneticField =
0303 typename std::decay_t<decltype(inputField)>::element_type;
0304 using MagneticField = Acts::SharedBField<InputMagneticField>;
0305
0306 using Stepper = Acts::EigenStepper<MagneticField>;
0307 using Propagator = Acts::Propagator<Stepper>;
0308 using TrackParameters = Acts::BoundTrackParameters;
0309 using Linearizer = Acts::HelicalTrackLinearizer<Propagator>;
0310 using VertexFitter =
0311 Acts::FullBilloirVertexFitter<TrackParameters,Linearizer>;
0312 using ImpactPointEstimator =
0313 Acts::ImpactPointEstimator<TrackParameters, Propagator>;
0314 using VertexSeeder = Acts::ZScanVertexFinder<VertexFitter>;
0315 using VertexFinder =
0316 Acts::IterativeVertexFinder<VertexFitter, VertexSeeder>;
0317 using VertexFinderOptions = Acts::VertexingOptions<TrackParameters>;
0318
0319 static_assert(Acts::VertexFinderConcept<VertexSeeder>,
0320 "VertexSeeder does not fulfill vertex finder concept.");
0321 static_assert(Acts::VertexFinderConcept<VertexFinder>,
0322 "VertexFinder does not fulfill vertex finder concept.");
0323
0324 auto logLevel = Acts::Logging::FATAL;
0325 if(Verbosity() > 4)
0326 logLevel = Acts::Logging::VERBOSE;
0327 auto logger = Acts::getDefaultLogger("PHActsInitialVertexFinder",
0328 logLevel);
0329
0330 MagneticField bField(inputField);
0331 auto propagator = std::make_shared<Propagator>(Stepper(bField));
0332
0333 /// Setup vertex finder now
0334 typename VertexFitter::Config vertexFitterConfig;
0335
0336 /// Vertex fitter seems to have no performance difference when
0337 /// iterating once vs. default of 5 times. Additionally, iterating
0338 /// more than once causes vertices with low numbers of tracks to
0339 /// fail fitting, causing an error to be thrown and 0 vertices
0340 /// returned
0341 vertexFitterConfig.maxIterations = 1;
0342
0343 VertexFitter vertexFitter(std::move(vertexFitterConfig));
0344
0345 typename Linearizer::Config linearizerConfig(bField, propagator);
0346 Linearizer linearizer(std::move(linearizerConfig));
0347
0348 typename ImpactPointEstimator::Config ipEstConfig(bField, propagator);
0349 ImpactPointEstimator ipEst(std::move(ipEstConfig));
0350
0351 typename VertexSeeder::Config seederConfig(ipEst);
0352
0353 /// Don't weight track contribution by pT, since the momentum
0354 /// resolution of the silicon seeds is poor
0355 if(m_disableWeights)
0356 seederConfig.disableAllWeights = true;
0357 VertexSeeder seeder(std::move(seederConfig));
0358
0359 typename VertexFinder::Config finderConfig(std::move(vertexFitter),
0360 std::move(linearizer),
0361 std::move(seeder), ipEst);
0362 finderConfig.maxVertices = m_maxVertices;
0363 finderConfig.reassignTracksAfterFirstFit = true;
0364 VertexFinder finder(finderConfig, std::move(logger));
0365
0366 typename VertexFinder::State state(m_tGeometry->magFieldContext);
0367 VertexFinderOptions finderOptions(m_tGeometry->getGeoContext(),
0368 m_tGeometry->magFieldContext);
0369
0370 auto result = finder.find(tracks, finderOptions, state);
0371
0372 VertexVector vertexVector;
0373
0374 if(result.ok())
0375 {
0376 m_successFits++;
0377
0378 auto vertexCollection = *result;
0379
0380 if(Verbosity() > 1)
0381 {
0382 std::cout << "Acts IVF found " << vertexCollection.size()
0383 << " vertices in event" << std::endl;
0384 }
0385
0386 for(const auto& vertex : vertexCollection)
0387 {
0388 vertexVector.push_back(vertex);
0389 }
0390 }
0391 else
0392 {
0393 if(Verbosity() > 0)
0394 {
0395 std::cout << "Acts initial vertex finder returned error: "
0396 << result.error().message() << std::endl;
0397 std::cout << "Track positions IVF used are : " << std::endl;
0398 for(const auto track : tracks)
0399 {
0400 const auto position = track->position(m_tGeometry->getGeoContext());
0401 std::cout << "(" << position(0) << ", " << position(1)
0402 << ", " << position(2) << std::endl;
0403 }
0404 }
0405 }
0406
0407 return vertexVector;
0408
0409 } /// end lambda
0410 , field
0411 ); /// end std::visit call
0412
0413 }
0414
0415 std::vector<SvtxTrack*> PHActsInitialVertexFinder::sortTracks()
0416 {
0417
0418 /// Implement a simple k-means clustering algorithm. Randomly select
0419 /// m_nCentroid track z PCAs (centroids), assign all tracks to
0420 /// a centroid based on which they are closest to, and then iterate
0421 /// to update clusters and centroids
0422
0423 std::vector<Acts::Vector3D> centroids(m_nCentroids);
0424 std::uniform_int_distribution<int> indices(0,m_trackMap->size() - 1);
0425 std::vector<int> usedIndices;
0426
0427 /// Get the original centroids
0428 for(auto& centroid : centroids)
0429 {
0430 auto index = indices(m_random_number_generator);
0431 for(const auto used : usedIndices)
0432 if(index == used)
0433 index = indices(m_random_number_generator);
0434
0435 usedIndices.push_back(index);
0436
0437 centroid = Acts::Vector3D(m_trackMap->get(index)->get_x(),
0438 m_trackMap->get(index)->get_y(),
0439 m_trackMap->get(index)->get_z());
0440
0441 if(Verbosity() > 3)
0442 {
0443 std::cout << "Centroid is (" << centroid(0)
0444 << ", " << centroid(1) << ", "
0445 << centroid(2) << ")" << std::endl;
0446 }
0447 }
0448
0449 /// This map holds the centroid index as the key and a
0450 /// vector of SvtxTracks that correspond to that centroid
0451 auto clusters = createCentroidMap(centroids);
0452
0453 /// Take the map and identified centroids and remove tracks
0454 /// that aren't compatible
0455 auto sortedTracks = getIVFTracks(clusters, centroids);
0456
0457 return sortedTracks;
0458 }
0459
0460 std::vector<SvtxTrack*> PHActsInitialVertexFinder::getIVFTracks(
0461 CentroidMap& clusters,
0462 std::vector<Acts::Vector3D>& centroids)
0463 {
0464
0465 std::vector<SvtxTrack*> sortedTracks;
0466
0467 if(Verbosity() > 2)
0468 {
0469 std::cout << "Final centroids are : " << std::endl;
0470 for(const auto& [centroidIndex, trackVec] : clusters)
0471 {
0472 std::cout << "Centroid: " << centroids.at(centroidIndex).transpose()
0473 << " has tracks " << std::endl;
0474 for(const auto& track : trackVec)
0475 {
0476 std::cout << "(" << track->get_x() << ", "
0477 << track->get_y() << ", " << track->get_z()
0478 << ")" << std::endl;
0479 }
0480 }
0481 }
0482
0483 /// Note the centroid that has the most tracks
0484 int maxTrackCentroid = 0;
0485 std::vector<Acts::Vector3D> stddev(m_nCentroids);
0486
0487 for(const auto& [centroidIndex, trackVec] : clusters)
0488 {
0489 Acts::Vector3D sum = Acts::Vector3D::Zero();
0490 if(trackVec.size() > maxTrackCentroid)
0491 {
0492 maxTrackCentroid = trackVec.size();
0493 }
0494
0495 for(const auto& track : trackVec)
0496 {
0497 for(int i = 0; i < sum.rows(); i++)
0498 {
0499 sum(i) += pow(track->get_pos(i) - centroids.at(centroidIndex)(i), 2);
0500 }
0501 }
0502 for(int i = 0; i < 3; i++)
0503 {
0504 stddev.at(centroidIndex)(i) = sqrt(sum(i) / trackVec.size());
0505 }
0506 }
0507
0508 for(const auto& [centroidIndex, trackVec] : clusters)
0509 {
0510 /// skip centroids that have a very small number of tracks
0511 /// compared to the largest centroid, as these are most likely
0512 /// composed of only a few (bad) stubs
0513 if(trackVec.size() < 0.2 * maxTrackCentroid)
0514 continue;
0515
0516 /// Skip large transverse PCA centroids
0517 float centroidR = sqrt(pow(centroids.at(centroidIndex)(0), 2) +
0518 pow(centroids.at(centroidIndex)(1), 2));
0519
0520 if(Verbosity() > 2)
0521 {
0522 std::cout << "Checking to add tracks from centroid "
0523 << centroids.at(centroidIndex).transpose() << std::endl;
0524 }
0525
0526 if(centroidR > m_pcaCut)
0527 {
0528 continue;
0529 }
0530
0531 for(const auto& track : trackVec)
0532 {
0533 Acts::Vector3D pulls = Acts::Vector3D::Zero();
0534 for(int i = 0; i < 3; i++)
0535 {
0536 pulls(i) = fabs(track->get_pos(i) - centroids.at(centroidIndex)(i)) / stddev.at(centroidIndex)(i);
0537 }
0538
0539 if(Verbosity() > 3)
0540 {
0541 std::cout << "Track pos is (" << track->get_x() << ", "
0542 << track->get_y() << ", " << track->get_z()
0543 << ") and pull is " << pulls.transpose() << std::endl;
0544 }
0545
0546 if ((pulls(0) < 2 and pulls(1) < 2 and pulls(2) < 2))
0547 {
0548 sortedTracks.push_back(track);
0549 }
0550 else
0551 {
0552 if(m_removeSeeds)
0553 {
0554 m_trackMap->erase(track->get_id());
0555 }
0556
0557 if(Verbosity() > 3)
0558 {
0559 std::cout << "Not adding track with pos (" << track->get_x()
0560 << ", " << track->get_y() << ", " << track->get_z()
0561 << ") as it is incompatible with centroid "
0562 << centroids.at(centroidIndex).transpose()
0563 << " with std dev "
0564 << stddev.at(centroidIndex).transpose() << std::endl;
0565 }
0566 }
0567 }
0568 }
0569
0570 return sortedTracks;
0571
0572 }
0573
0574 CentroidMap PHActsInitialVertexFinder::createCentroidMap(std::vector<Acts::Vector3D>& centroids)
0575 {
0576 CentroidMap clusters;
0577
0578 for(int niter = 0; niter < m_nIterations; niter++)
0579 {
0580 /// reset the centroid-track map
0581 clusters.clear();
0582 for(unsigned int i = 0; i<m_nCentroids; i++)
0583 {
0584 std::vector<SvtxTrack*> vec;
0585 clusters.insert(std::make_pair(i, vec));
0586 }
0587
0588 if(Verbosity() > 3)
0589 {
0590 for(int i =0; i< m_nCentroids; i++)
0591 std::cout << "Starting centroid is : "
0592 << centroids.at(i).transpose() << std::endl;
0593 }
0594 for(const auto& [key, track] : *m_trackMap)
0595 {
0596 Acts::Vector3D trackPos(track->get_x(),
0597 track->get_y(),
0598 track->get_z());
0599
0600 double minDist = std::numeric_limits<double>::max();
0601 unsigned int centKey = std::numeric_limits<unsigned int>::max();
0602 for(int i = 0; i < centroids.size(); i++)
0603 {
0604 double dist = sqrt(pow(trackPos(0) - centroids.at(i)(0), 2) +
0605 pow(trackPos(1) - centroids.at(i)(1), 2) +
0606 pow(trackPos(2) - centroids.at(i)(2), 2));
0607 if(dist < minDist)
0608 {
0609 minDist = dist;
0610 centKey = i;
0611 if(Verbosity() > 3)
0612 {
0613 std::cout << "mindist and centkey are "
0614 << minDist << ", " << centKey
0615 << std::endl;
0616 }
0617 }
0618 }
0619
0620 /// Add this track to the map that associates centroids with tracks
0621 if(Verbosity() > 3)
0622 {
0623 std::cout << "adding track with " << trackPos.transpose()
0624 << " to centroid "
0625 << centroids.at(centKey).transpose() << std::endl;
0626 }
0627
0628 clusters.find(centKey)->second.push_back(track);
0629 }
0630
0631 /// Update pos centroids
0632 std::vector<Acts::Vector3D> newCentroids(m_nCentroids);
0633 for(auto& centroid : newCentroids)
0634 centroid = Acts::Vector3D(0,0,0);
0635
0636 for(const auto& [centroidVal, trackVec] : clusters)
0637 {
0638 for(const auto& track : trackVec)
0639 {
0640 for(int i = 0; i < 3; i++)
0641 newCentroids.at(centroidVal)(i) += track->get_pos(i);
0642 }
0643
0644 /// Sets the centroid as the average value
0645 centroids.at(centroidVal) =
0646 newCentroids.at(centroidVal) / trackVec.size();
0647 }
0648
0649 if(Verbosity() > 3)
0650 {
0651 for(int i = 0; i < m_nCentroids; i++)
0652 std::cout << "new centroids " << centroids.at(i).transpose()
0653 << std::endl;
0654
0655 for(const auto& [centKey, trackVec] : clusters)
0656 {
0657 std::cout << "cent key : " << centKey << " has " << trackVec.size()
0658 << "tracks" << std::endl;
0659 for(const auto track : trackVec)
0660 {
0661 std::cout << "track id : " << track->get_id()
0662 << " with pos (" << track->get_x() << ", "
0663 << track->get_y() << ", " << track->get_z()
0664 << ")" << std::endl;
0665
0666 }
0667 }
0668 }
0669 }
0670
0671 return clusters;
0672
0673 }
0674
0675 TrackParamVec PHActsInitialVertexFinder::getTrackPointers(InitKeyMap& keyMap)
0676 {
0677 TrackParamVec tracks;
0678
0679 /// If there are fewer tracks than centroids, just one with 1 centroid
0680 /// Otherwise algorithm does not converge. nCentroids should only be
0681 /// a handful, so this only affects small nTrack events.
0682 if(m_trackMap->size() < m_nCentroids)
0683 {
0684 m_nCentroids = 1;
0685 }
0686
0687 std::vector<SvtxTrack*> sortedTracks;
0688 if(m_svtxTrackMapName.find("Silicon") != std::string::npos)
0689 {
0690 sortedTracks = sortTracks();
0691 }
0692 else
0693 {
0694 for(const auto& [key, track] : *m_trackMap)
0695 sortedTracks.push_back(track);
0696 }
0697
0698 for(const auto& track : sortedTracks)
0699 {
0700 if(Verbosity() > 3)
0701 {
0702 std::cout << "Adding track seed to vertex finder "
0703 << std::endl;
0704 track->identify();
0705 }
0706
0707 /// Only vertex with stubs that have five clusters
0708 if(m_svtxTrackMapName.find("Silicon") != std::string::npos)
0709 {
0710 if(track->size_cluster_keys() < 5)
0711 {
0712 continue;
0713 }
0714 }
0715
0716 const Acts::Vector4D stubVec(
0717 track->get_x() * Acts::UnitConstants::cm,
0718 track->get_y() * Acts::UnitConstants::cm,
0719 track->get_z() * Acts::UnitConstants::cm,
0720 10 * Acts::UnitConstants::ns);
0721
0722 const Acts::Vector3D stubMom(track->get_px(),
0723 track->get_py(),
0724 track->get_pz());
0725 int trackQ = track->get_charge() * Acts::UnitConstants::e;
0726
0727 /// The vertexing has an expectation about the field direction
0728 /// and associated charge. For the 3D map, to work with the
0729 /// required swap of the field for the silicon seeds, we need
0730 /// to flip the charge
0731 if(m_magField.find("3d") != std::string::npos)
0732 trackQ *= -1;
0733
0734 const double p = track->get_p();
0735
0736 /// Make a dummy covariance matrix for Acts that corresponds
0737 /// to the resolutions of the silicon seeds
0738 Acts::BoundSymMatrix cov;
0739 if(m_resetTrackCovariance)
0740 cov << 50 * Acts::UnitConstants::um, 0., 0., 0., 0., 0.,
0741 0., 30 * Acts::UnitConstants::um, 0., 0., 0., 0.,
0742 0., 0., 0.005, 0., 0., 0.,
0743 0., 0., 0., 0.001, 0., 0.,
0744 0., 0., 0., 0., 0.3 , 0.,
0745 0., 0., 0., 0., 0., 1.;
0746
0747 else
0748 {
0749 ActsTransformations transform;
0750 transform.setVerbosity(Verbosity());
0751 cov = transform.rotateSvtxTrackCovToActs(track,
0752 m_tGeometry->getGeoContext());
0753 }
0754
0755 /// Make a dummy perigee surface to bound the track to
0756 auto perigee = Acts::Surface::makeShared<Acts::PerigeeSurface>(
0757 Acts::Vector3D(stubVec(0),
0758 stubVec(1),
0759 stubVec(2)));
0760
0761
0762 const auto param = new Acts::BoundTrackParameters(
0763 perigee,
0764 m_tGeometry->getGeoContext(),
0765 stubVec, stubMom,
0766 p, trackQ, cov);
0767
0768 tracks.push_back(param);
0769 keyMap.insert(std::make_pair(param, track->get_id()));
0770 }
0771
0772 return tracks;
0773 }
0774
0775 int PHActsInitialVertexFinder::getNodes(PHCompositeNode *topNode)
0776 {
0777
0778 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, m_svtxTrackMapName.c_str());
0779 if(!m_trackMap)
0780 {
0781 std::cout << PHWHERE << "No " << m_svtxTrackMapName.c_str()
0782 << " on node tree, bailing."
0783 << std::endl;
0784 return Fun4AllReturnCodes::ABORTEVENT;
0785 }
0786
0787 m_tGeometry = findNode::getClass<ActsTrackingGeometry>(topNode,
0788 "ActsTrackingGeometry");
0789 if(!m_tGeometry)
0790 {
0791 std::cout << PHWHERE << "ActsTrackingGeometry not on node tree. Exiting"
0792 << std::endl;
0793 return Fun4AllReturnCodes::ABORTEVENT;
0794 }
0795
0796
0797 return Fun4AllReturnCodes::EVENT_OK;
0798 }
0799
0800 int PHActsInitialVertexFinder::createNodes(PHCompositeNode *topNode)
0801 {
0802
0803 PHNodeIterator iter(topNode);
0804
0805 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0806
0807 /// Check that it is there
0808 if (!dstNode)
0809 {
0810 std::cerr << "DST Node missing, quitting" << std::endl;
0811 throw std::runtime_error("failed to find DST node in PHActsInitialVertexFinder::createNodes");
0812 }
0813
0814 /// Get the tracking subnode
0815 PHCompositeNode *svtxNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "SVTX"));
0816
0817 if (!svtxNode)
0818 {
0819 svtxNode = new PHCompositeNode("SVTX");
0820 dstNode->addNode(svtxNode);
0821 }
0822
0823 m_vertexMap = findNode::getClass<SvtxVertexMap>(topNode,
0824 m_svtxVertexMapName.c_str());
0825
0826 if(!m_vertexMap)
0827 {
0828 m_vertexMap = new SvtxVertexMap_v1;
0829 PHIODataNode<PHObject>* vertexNode = new PHIODataNode<PHObject>(
0830 m_vertexMap, m_svtxVertexMapName.c_str(),"PHObject");
0831
0832 svtxNode->addNode(vertexNode);
0833
0834 }
0835
0836
0837 return Fun4AllReturnCodes::EVENT_OK;
0838 }