File indexing completed on 2025-12-17 09:21:06
0001
0002
0003
0004
0005
0006
0007 #include "PHSimpleKFProp.h"
0008 #include "ALICEKF.h"
0009 #include "GPUTPCTrackLinearisation.h"
0010 #include "GPUTPCTrackParam.h"
0011 #include "PHGhostRejection.h"
0012 #include "nanoflann.hpp"
0013
0014 #include <ffamodules/CDBInterface.h>
0015
0016 #include <g4detectors/PHG4TpcGeom.h>
0017 #include <g4detectors/PHG4TpcGeomContainer.h>
0018
0019 #include <phfield/PHFieldUtility.h>
0020 #include <phfield/PHFieldConfig.h>
0021
0022
0023 #include <tpc/TpcDistortionCorrectionContainer.h>
0024
0025 #include <trackbase/ActsGeometry.h>
0026 #include <trackbase/TrackFitUtils.h>
0027 #include <trackbase/TrkrCluster.h>
0028 #include <trackbase/TrkrClusterContainer.h>
0029 #include <trackbase/TrkrClusterIterationMapv1.h>
0030 #include <trackbase/TrkrDefs.h>
0031
0032 #include <trackbase_historic/ActsTransformations.h>
0033 #include <trackbase_historic/TrackSeedContainer.h>
0034 #include <trackbase_historic/TrackSeed_v2.h>
0035 #include <trackbase_historic/TrackSeedHelper.h>
0036
0037 #include <fun4all/Fun4AllReturnCodes.h>
0038
0039 #include <phool/PHTimer.h>
0040 #include <phool/getClass.h>
0041 #include <phool/phool.h> // for PHWHERE
0042
0043 #include <TSystem.h>
0044
0045 #include <Geant4/G4SystemOfUnits.hh>
0046
0047 #include <Eigen/Core>
0048 #include <Eigen/Dense>
0049
0050 #include <omp.h>
0051
0052 #include <cmath>
0053 #include <filesystem>
0054 #include <iostream>
0055 #include <syncstream>
0056 #include <vector>
0057
0058
0059 namespace
0060 {
0061
0062 template <class T>
0063 inline constexpr T square(const T& x)
0064 {
0065 return x * x;
0066 }
0067 }
0068
0069 using keylist = std::vector<TrkrDefs::cluskey>;
0070
0071 PHSimpleKFProp::PHSimpleKFProp(const std::string& name)
0072 : SubsysReco(name)
0073 {}
0074
0075
0076 int PHSimpleKFProp::End(PHCompositeNode* )
0077 {
0078 return Fun4AllReturnCodes::EVENT_OK;
0079 }
0080
0081
0082 int PHSimpleKFProp::InitRun(PHCompositeNode* topNode)
0083 {
0084 int ret = get_nodes(topNode);
0085 if (ret != Fun4AllReturnCodes::EVENT_OK)
0086 {
0087 return ret;
0088 }
0089
0090
0091
0092 const auto field_map = PHFieldUtility::GetFieldMapNode(nullptr, topNode);
0093
0094
0095 fitter = std::make_unique<ALICEKF>(_cluster_map, field_map, _min_clusters_per_track, _max_sin_phi, Verbosity());
0096 fitter->setNeonFraction(Ne_frac);
0097 fitter->setArgonFraction(Ar_frac);
0098 fitter->setCF4Fraction(CF4_frac);
0099 fitter->setNitrogenFraction(N2_frac);
0100 fitter->setIsobutaneFraction(isobutane_frac);
0101 fitter->useFixedClusterError(_use_fixed_clus_err);
0102 fitter->setFixedClusterError(0, _fixed_clus_err.at(0));
0103 fitter->setFixedClusterError(1, _fixed_clus_err.at(1));
0104 fitter->setFixedClusterError(2, _fixed_clus_err.at(2));
0105
0106
0107 const auto field_config = PHFieldUtility::GetFieldConfigNode(nullptr, topNode);
0108 if( field_config->get_field_config() == PHFieldConfig::kFieldUniform )
0109 { fitter->setConstBField(field_config->get_field_mag_z()); }
0110
0111
0112 std::cout << "PHSimpleKFProp::InitRun - m_num_threads: " << m_num_threads << std::endl;
0113 if( m_num_threads >= 1 ) { omp_set_num_threads( m_num_threads ); }
0114
0115 return Fun4AllReturnCodes::EVENT_OK;
0116 }
0117
0118
0119 int PHSimpleKFProp::get_nodes(PHCompositeNode* topNode)
0120 {
0121
0122
0123 m_tgeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0124 if (!m_tgeometry)
0125 {
0126 std::cout << "No Acts tracking geometry, exiting." << std::endl;
0127 return Fun4AllReturnCodes::ABORTEVENT;
0128 }
0129
0130
0131 m_globalPositionWrapper.loadNodes(topNode);
0132
0133
0134 if (_use_truth_clusters)
0135 {
0136 _cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER_TRUTH");
0137 }
0138 else
0139 {
0140 _cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0141 }
0142 if (!_cluster_map)
0143 {
0144 std::cerr << PHWHERE << " ERROR: Can't find node TRKR_CLUSTER" << std::endl;
0145 return Fun4AllReturnCodes::ABORTEVENT;
0146 }
0147
0148
0149 _track_map = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
0150 if (!_track_map)
0151 {
0152 std::cerr << PHWHERE << " ERROR: Can't find TrackSeedContainer " << std::endl;
0153 return Fun4AllReturnCodes::ABORTEVENT;
0154 }
0155
0156
0157 auto geom_container = findNode::getClass<PHG4TpcGeomContainer>(topNode, "TPCGEOMCONTAINER");
0158 if (!geom_container)
0159 {
0160 std::cerr << PHWHERE << "ERROR: Can't find node TPCGEOMCONTAINER" << std::endl;
0161 return Fun4AllReturnCodes::ABORTRUN;
0162 }
0163
0164 for (int i = 7; i <= 54; i++)
0165 {
0166 radii.push_back(geom_container->GetLayerCellGeom(i)->get_radius());
0167 }
0168
0169 return Fun4AllReturnCodes::EVENT_OK;
0170 }
0171
0172 int PHSimpleKFProp::process_event(PHCompositeNode* topNode)
0173 {
0174 if (_n_iteration != 0)
0175 {
0176 _iteration_map = findNode::getClass<TrkrClusterIterationMapv1>(topNode, "CLUSTER_ITERATION_MAP");
0177 if (!_iteration_map)
0178 {
0179 std::cerr << PHWHERE << "Cluster Iteration Map missing, aborting." << std::endl;
0180 return Fun4AllReturnCodes::ABORTEVENT;
0181 }
0182 }
0183
0184 PHTimer timer("KFPropTimer");
0185 timer.restart();
0186
0187
0188 if(_max_seeds > 0 && _track_map->size() > _max_seeds)
0189 {
0190 std::cout << "number of TPC seeds: " << _track_map->size() << std::endl;
0191 std::cout << PHWHERE << "number of TPC seeds > " << _max_seeds << " aborting event." << std::endl;
0192 return Fun4AllReturnCodes::ABORTEVENT;
0193 }
0194
0195 const auto globalPositions = PrepareKDTrees();
0196 if (Verbosity())
0197 { std::cout << "PHSimpleKFProp::process_event - PrepareKDTrees time: " << timer.elapsed() << " ms" << std::endl; }
0198
0199
0200 std::vector<std::vector<TrkrDefs::cluskey>> new_chains;
0201 std::vector<TrackSeed_v2> unused_tracks;
0202
0203 timer.restart();
0204 #pragma omp parallel
0205 {
0206 if (Verbosity())
0207 {
0208 std::osyncstream(std::cout)
0209 << "PHSimpleKFProp -"
0210 << " num_threads: " << omp_get_num_threads()
0211 << " this thread: " << omp_get_thread_num()
0212 << std::endl;
0213 }
0214
0215 PHTimer timer_mp("KFPropTimer_parallel");
0216
0217 std::vector<std::vector<TrkrDefs::cluskey>> local_chains;
0218 std::vector<TrackSeed_v2> local_unused;
0219
0220 #pragma omp for schedule(static)
0221 for (size_t track_it = 0; track_it != _track_map->size(); ++track_it)
0222 {
0223 if (Verbosity())
0224 {
0225 std::osyncstream(std::cout)
0226 << "PHSimpleKFProp -"
0227 << " num_threads: " << omp_get_num_threads()
0228 << " this thread: " << omp_get_thread_num()
0229 << " processing seed " << track_it << std::endl;
0230 }
0231
0232
0233 auto track = _track_map->get(track_it);
0234 const bool is_tpc = std::any_of(
0235 track->begin_cluster_keys(),
0236 track->end_cluster_keys(),
0237 [](const TrkrDefs::cluskey& key)
0238 { return TrkrDefs::getTrkrId(key) == TrkrDefs::tpcId; });
0239
0240 if (is_tpc)
0241 {
0242
0243
0244 std::vector<std::vector<TrkrDefs::cluskey>> keylist_A(1);
0245 std::copy(track->begin_cluster_keys(), track->end_cluster_keys(), std::back_inserter(keylist_A[0]));
0246
0247
0248 std::map<TrkrDefs::cluskey, Acts::Vector3> trackClusPositions;
0249 std::transform(track->begin_cluster_keys(), track->end_cluster_keys(), std::inserter(trackClusPositions, trackClusPositions.end()),
0250 [globalPositions](const auto& key)
0251 { return std::make_pair(key, globalPositions.at(key)); });
0252
0253
0254 if (keylist_A[0].size() < 3)
0255 {
0256 continue;
0257 }
0258
0259
0260
0261 std::vector<float> trackChi2;
0262
0263 timer_mp.restart();
0264 auto seedpair = fitter->ALICEKalmanFilter(keylist_A, false, trackClusPositions, trackChi2);
0265
0266 if (Verbosity() > 3)
0267 {
0268 std::cout << "PHSimpleKFProp::process_event - single track ALICEKF time " << timer_mp.elapsed() << " ms" << std::endl;
0269 }
0270
0271 timer_mp.restart();
0272
0273
0274 TrackSeedHelper::circleFitByTaubin(track, trackClusPositions, 7, 55);
0275 TrackSeedHelper::lineFit(track, trackClusPositions, 7, 55);
0276 track->set_phi(TrackSeedHelper::get_phi(track, trackClusPositions));
0277 if (Verbosity() > 3)
0278 {
0279 std::cout << "PHSimpleKFProp::process_event - single track circle fit time " << timer_mp.elapsed() << " ms" << std::endl;
0280 }
0281
0282 if (seedpair.first.empty()|| seedpair.second.empty())
0283 {
0284 continue;
0285 }
0286
0287 if (Verbosity())
0288 {
0289 std::cout << "is tpc track" << std::endl;
0290 }
0291
0292 timer_mp.restart();
0293
0294 if (Verbosity())
0295 {
0296 std::cout << "propagate first round" << std::endl;
0297 }
0298
0299 auto preseed = PropagateTrack(track, PropagationDirection::Inward, seedpair.second.at(0), globalPositions);
0300 if (Verbosity())
0301 {
0302 std::cout << "preseed size " << preseed.size() << std::endl;
0303 }
0304
0305 std::vector<std::vector<TrkrDefs::cluskey>> kl = {preseed};
0306 if (Verbosity())
0307 {
0308 std::cout << "kl size " << kl.size() << std::endl;
0309 }
0310 std::vector<float> pretrackChi2;
0311
0312 auto prepair = fitter->ALICEKalmanFilter(kl, false, globalPositions, pretrackChi2);
0313 if (prepair.first.empty() || prepair.second.empty())
0314 {
0315 continue;
0316 }
0317
0318 std::reverse(kl.at(0).begin(), kl.at(0).end());
0319
0320 auto pretrack = prepair.first.at(0);
0321
0322
0323 std::map<TrkrDefs::cluskey, Acts::Vector3> pretrackClusPositions;
0324 std::transform(pretrack.begin_cluster_keys(), pretrack.end_cluster_keys(), std::inserter(pretrackClusPositions, pretrackClusPositions.end()),
0325 [globalPositions](const auto& key)
0326 { return std::make_pair(key, globalPositions.at(key)); });
0327
0328
0329 TrackSeedHelper::circleFitByTaubin(&pretrack,pretrackClusPositions, 7, 55);
0330 TrackSeedHelper::lineFit(&pretrack, pretrackClusPositions, 7, 55);
0331 pretrack.set_phi(TrackSeedHelper::get_phi(&pretrack, pretrackClusPositions));
0332
0333 prepair.second.at(0).SetDzDs(-prepair.second.at(0).GetDzDs());
0334 const auto finalchain = PropagateTrack(&pretrack, kl.at(0), PropagationDirection::Outward, prepair.second.at(0), globalPositions);
0335
0336 if (finalchain.size() > kl.at(0).size())
0337 {
0338 local_chains.push_back(std::move(finalchain));
0339 }
0340 else
0341 {
0342 local_chains.push_back(std::move(kl.at(0)));
0343 }
0344
0345 if (Verbosity() > 3)
0346 {
0347 std::cout << "PHSimpleKFProp::process_event - propagate track time " << timer_mp.elapsed() << " ms" << std::endl;
0348 }
0349 }
0350 else
0351 {
0352 if (Verbosity())
0353 {
0354 std::cout << "is NOT tpc track" << std::endl;
0355 }
0356 local_unused.emplace_back(*track);
0357 }
0358 }
0359
0360
0361 std::sort(local_chains.begin(),local_chains.end());
0362 local_chains.erase(std::unique(local_chains.begin(),local_chains.end()),local_chains.end());
0363
0364
0365 #pragma omp critical
0366 {
0367 new_chains.reserve(new_chains.size()+local_chains.size());
0368 new_chains.insert(new_chains.end(), std::make_move_iterator(local_chains.begin()), std::make_move_iterator(local_chains.end()));
0369
0370 unused_tracks.reserve(unused_tracks.size()+local_unused.size());
0371 unused_tracks.insert(unused_tracks.end(), std::make_move_iterator(local_unused.begin()), std::make_move_iterator(local_unused.end()));
0372 }
0373 }
0374 if (Verbosity())
0375 { std::cout << "PHSimpleKFProp::process_event - first seed loop time: " << timer.elapsed() << " ms" << std::endl; }
0376
0377
0378 timer.restart();
0379 std::sort(new_chains.begin(),new_chains.end());
0380 new_chains.erase(std::unique(new_chains.begin(),new_chains.end()),new_chains.end());
0381
0382 if (Verbosity())
0383 { std::cout << "PHSimpleKFProp::process_event - first cleanup time: " << timer.elapsed() << " ms" << std::endl; }
0384
0385 if( Verbosity() )
0386 {
0387
0388 std::cout << "PHSimpleKFProp::process_event - new_chains size: " << new_chains.size() << std::endl;
0389 for( const auto& chain:new_chains )
0390 {
0391 std::cout << "PHSimpleKFProp::process_event - { ";
0392 for( const auto& key:chain )
0393 {
0394 std::cout << key << " ";
0395 }
0396 std::cout << "}" << std::endl << std::endl;
0397 }
0398 }
0399
0400
0401 new_chains.erase( std::remove_if( new_chains.begin(), new_chains.end(),
0402 [](const auto& chain) { return chain.size()<3; } ),
0403 new_chains.end() );
0404
0405
0406 timer.restart();
0407 std::vector<float> trackChi2;
0408 auto seeds = fitter->ALICEKalmanFilter(new_chains, true, globalPositions, trackChi2);
0409 if (Verbosity())
0410 { std::cout << "PHSimpleKFProp::process_event - ALICEKalmanFilter time: " << timer.elapsed() << " ms" << std::endl; }
0411
0412
0413 _track_map->Reset();
0414
0415
0416 timer.restart();
0417 if (m_ghostrejection)
0418 {
0419 rejectAndPublishSeeds(seeds.first, globalPositions, trackChi2);
0420 }
0421 else
0422 {
0423 publishSeeds(seeds.first);
0424 }
0425
0426
0427 publishSeeds(unused_tracks);
0428
0429 if (Verbosity())
0430 { std::cout << "PHSimpleKFProp::process_event - publishSeeds time: " << timer.elapsed() << " ms" << std::endl; }
0431
0432 return Fun4AllReturnCodes::EVENT_OK;
0433 }
0434
0435 Acts::Vector3 PHSimpleKFProp::getGlobalPosition(TrkrDefs::cluskey key, TrkrCluster* cluster) const
0436 {
0437
0438 return _pp_mode ?
0439 m_tgeometry->getGlobalPosition(key, cluster):
0440 m_globalPositionWrapper.getGlobalPositionDistortionCorrected( key, cluster, 0 );
0441 }
0442
0443 PositionMap PHSimpleKFProp::PrepareKDTrees()
0444 {
0445 PositionMap globalPositions;
0446
0447 std::vector<std::vector<std::vector<double>>> kdhits;
0448 kdhits.resize(58);
0449 if (!_cluster_map)
0450 {
0451 std::cout << "WARNING: (tracking.PHTpcTrackerUtil.convert_clusters_to_hits) cluster map is not provided" << std::endl;
0452 return globalPositions;
0453 }
0454
0455 for (const auto& hitsetkey : _cluster_map->getHitSetKeys(TrkrDefs::TrkrId::tpcId))
0456 {
0457 auto range = _cluster_map->getClusters(hitsetkey);
0458 for (TrkrClusterContainer::ConstIterator it = range.first; it != range.second; ++it)
0459 {
0460 const auto& [cluskey,cluster] = *it;
0461 if (!cluster)
0462 {
0463 continue;
0464 }
0465
0466
0467 if (_n_iteration && _iteration_map && _iteration_map->getIteration(cluskey) > 0)
0468 {
0469 continue;
0470 }
0471
0472 const auto globalpos = getGlobalPosition(cluskey, cluster);
0473 globalPositions.emplace(cluskey, globalpos);
0474
0475 const int layer = TrkrDefs::getLayer(cluskey);
0476 std::vector<double> kdhit{ globalpos.x(), globalpos.y(), globalpos.z(), 0 };
0477 const uint64_t key = cluskey;
0478 std::memcpy(&kdhit[3], &key, sizeof(key));
0479
0480
0481
0482
0483
0484
0485 kdhits[layer].push_back(std::move(kdhit));
0486 }
0487 }
0488 _ptclouds.resize(kdhits.size());
0489 _kdtrees.resize(kdhits.size());
0490 for (size_t l = 0; l < kdhits.size(); ++l)
0491 {
0492 if (Verbosity() > 1)
0493 {
0494 std::cout << "l: " << l << std::endl;
0495 }
0496 _ptclouds[l] = std::make_shared<KDPointCloud<double>>();
0497 _ptclouds[l]->pts = std::move(kdhits[l]);
0498
0499 _kdtrees[l] = std::make_shared<nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<double, KDPointCloud<double>>, KDPointCloud<double>, 3>>(3, *(_ptclouds[l]), nanoflann::KDTreeSingleIndexAdaptorParams(10));
0500 _kdtrees[l]->buildIndex();
0501 }
0502
0503 return globalPositions;
0504 }
0505
0506 bool PHSimpleKFProp::TransportAndRotate(
0507 double old_radius,
0508 double new_radius,
0509 double& phi,
0510 GPUTPCTrackParam& kftrack,
0511 GPUTPCTrackParam::GPUTPCTrackFitParam& fp) const
0512 {
0513 if (Verbosity() > 2)
0514 {
0515 std::cout << "old_radius " << old_radius << ", new_radius " << new_radius << std::endl;
0516 }
0517 const float transport_spacing = .05;
0518 const int Ndivisions = floor(std::abs(new_radius - old_radius) / transport_spacing);
0519 if (Verbosity() > 2)
0520 {
0521 std::cout << "Ndivisions: " << Ndivisions << std::endl;
0522 }
0523 for (int i = 1; i <= Ndivisions + 1; i++)
0524 {
0525 if (std::isnan(kftrack.GetX()) ||
0526 std::isnan(kftrack.GetY()) ||
0527 std::isnan(kftrack.GetZ()))
0528 {
0529 if (Verbosity() > 1)
0530 {
0531 std::cout << "position is NaN, exiting" << std::endl;
0532 }
0533 return false;
0534 }
0535
0536 if (new_radius > 78.)
0537 {
0538 if (Verbosity() > 1)
0539 {
0540 std::cout << "outside TPC, exiting" << std::endl;
0541 }
0542 return false;
0543 }
0544
0545 double r_div;
0546 if (i == Ndivisions + 1)
0547 {
0548 r_div = new_radius;
0549 }
0550 else if (old_radius < new_radius)
0551 {
0552 r_div = old_radius + transport_spacing * i;
0553 }
0554 else
0555 {
0556 r_div = old_radius - transport_spacing * i;
0557 }
0558
0559 if (Verbosity() > 2)
0560 {
0561 std::cout << "transporting to intermediate radius " << r_div << std::endl;
0562 }
0563
0564
0565 const double tX = kftrack.GetX();
0566 const double tY = kftrack.GetY();
0567 const double tz = kftrack.GetZ();
0568
0569
0570 const double tx = tX * cos(phi) - tY * sin(phi);
0571 const double ty = tX * sin(phi) + tY * cos(phi);
0572
0573 const double Bz = _Bzconst * fitter->get_Bz(tx, ty, tz);
0574
0575 kftrack.CalculateFitParameters(fp);
0576
0577
0578 if (!kftrack.TransportToXWithMaterial(r_div, fp, Bz, 1.))
0579 {
0580 if (Verbosity() > 1)
0581 {
0582 std::cout << "transport failed" << std::endl;
0583 }
0584 return false;
0585 }
0586
0587 const double new_tX = kftrack.GetX();
0588 const double new_tY = kftrack.GetY();
0589
0590 const double new_tx = new_tX * cos(phi) - new_tY * sin(phi);
0591 const double new_ty = new_tX * sin(phi) + new_tY * cos(phi);
0592 const double new_phi = atan2(new_ty, new_tx);
0593 const double alpha = new_phi - phi;
0594
0595 if (!kftrack.Rotate(alpha, 1.))
0596 {
0597 if (Verbosity() > 1)
0598 {
0599 std::cout << "rotate failed" << std::endl;
0600 }
0601 return false;
0602 }
0603 phi = new_phi;
0604 }
0605
0606 if (Verbosity() > 1)
0607 {
0608 const double final_tX = kftrack.GetX();
0609 const double final_tY = kftrack.GetY();
0610 const double final_tx = final_tX * cos(phi) - final_tY * sin(phi);
0611 const double final_ty = final_tX * sin(phi) + final_tY * cos(phi);
0612 const double final_tz = kftrack.GetZ();
0613 std::cout << "track position after transport: (" << final_tx << ", " << final_ty << ", " << final_tz << ")" << std::endl;
0614 }
0615 return true;
0616 }
0617
0618
0619 bool PHSimpleKFProp::PropagateStep(
0620 unsigned int& current_layer,
0621 double& current_phi,
0622 PropagationDirection& direction,
0623 std::vector<TrkrDefs::cluskey>& propagated_track,
0624 const std::vector<TrkrDefs::cluskey>& ckeys,
0625 GPUTPCTrackParam& kftrack,
0626 GPUTPCTrackParam::GPUTPCTrackFitParam& fp,
0627 const PositionMap& globalPositions) const
0628 {
0629
0630 if (std::isnan(kftrack.GetX()) ||
0631 std::isnan(kftrack.GetY()) ||
0632 std::isnan(kftrack.GetZ()))
0633 {
0634 if (Verbosity() > 1)
0635 {
0636 std::cout << "position is NaN, exiting loop" << std::endl;
0637 }
0638 return false;
0639 }
0640
0641 if (Verbosity() > 1)
0642 {
0643 std::cout << "current layer: " << current_layer << std::endl;
0644 }
0645 if (Verbosity() > 5)
0646 {
0647 std::cout << "original seed size: " << ckeys.size() << std::endl;
0648 }
0649
0650
0651
0652 int next_layer;
0653 if (direction == PropagationDirection::Outward)
0654 {
0655 next_layer = current_layer + 1;
0656 }
0657 else
0658 {
0659 next_layer = current_layer - 1;
0660 }
0661
0662 if (Verbosity() > 1)
0663 {
0664 std::cout << "next layer: " << next_layer << std::endl;
0665 }
0666
0667
0668 if (next_layer < 7 || next_layer > 54)
0669 {
0670 if (Verbosity() > 1)
0671 {
0672 std::cout << "reached end of TPC, exiting loop" << std::endl;
0673 }
0674 return false;
0675 }
0676
0677
0678 const double tX = kftrack.GetX();
0679 const double tY = kftrack.GetY();
0680 const double tz = kftrack.GetZ();
0681
0682
0683 const double tx = tX * cos(current_phi) - tY * sin(current_phi);
0684 const double ty = tX * sin(current_phi) + tY * cos(current_phi);
0685
0686 if (Verbosity() > 1)
0687 {
0688 std::cout << std::endl;
0689 std::cout << "track position: (" << tx << ", " << ty << ", " << tz << ")" << std::endl;
0690 }
0691
0692 if (Verbosity() > 1)
0693 {
0694 std::cout << "transporting to radius: " << radii[next_layer - 7] << std::endl;
0695 }
0696
0697 if (!TransportAndRotate(kftrack.GetX(), radii[next_layer - 7], current_phi, kftrack, fp))
0698 {
0699 if (std::isnan(kftrack.GetX()) ||
0700 std::isnan(kftrack.GetY()) ||
0701 std::isnan(kftrack.GetZ()))
0702 {
0703 return false;
0704 }
0705
0706 if (Verbosity() > 1)
0707 {
0708 std::cout << "track turned around near X=" << kftrack.GetX() << std::endl;
0709 }
0710
0711
0712
0713
0714
0715
0716 double pt = 1. / std::abs(kftrack.GetQPt());
0717 double end_tx = kftrack.GetX() * cos(current_phi) - kftrack.GetY() * sin(current_phi);
0718 double end_ty = kftrack.GetX() * sin(current_phi) + kftrack.GetY() * cos(current_phi);
0719 double end_tz = kftrack.GetZ();
0720 if (Verbosity() > 1)
0721 {
0722 std::cout << "current parameters: pt=" << pt << ", (x, y, z) = (" << end_tx << ", " << end_ty << ", " << end_tz << ")" << std::endl;
0723 }
0724
0725 double R = 100. * pt / (0.3 * fitter->get_Bz(end_tx, end_ty, end_tz));
0726 if (Verbosity() > 1)
0727 {
0728 std::cout << "R=" << R << std::endl;
0729 }
0730 double pX = pt * kftrack.GetCosPhi();
0731 double pY = pt * kftrack.GetSinPhi();
0732 if (Verbosity() > 1)
0733 {
0734 std::cout << "(pX, pY) = (" << pX << ", " << pY << ")" << std::endl;
0735 }
0736 double px = pX * cos(current_phi) - pY * sin(current_phi);
0737 double py = pX * sin(current_phi) + pY * cos(current_phi);
0738 double tangent_phi = std::atan2(py, px);
0739 double center_phi = 0;
0740 if (kftrack.GetQPt() > 0)
0741 {
0742 center_phi = tangent_phi + M_PI / 2.;
0743 }
0744 else
0745 {
0746 center_phi = tangent_phi - M_PI / 2.;
0747 }
0748 if (center_phi > M_PI)
0749 {
0750 center_phi -= 2. * M_PI;
0751 }
0752 if (center_phi < -M_PI)
0753 {
0754 center_phi += 2. * M_PI;
0755 }
0756 double xc = end_tx - R * cos(center_phi);
0757 double yc = end_ty - R * sin(center_phi);
0758 if (Verbosity() > 1)
0759 {
0760 std::cout << "(xc, yc) = (" << xc << ", " << yc << ")" << std::endl;
0761 }
0762 auto circle_output = TrackFitUtils::circle_circle_intersection(
0763 std::sqrt(square(kftrack.GetX()) + square(kftrack.GetY())), R, xc, yc);
0764
0765 double new_tx;
0766 double new_ty;
0767 double xplus = std::get<0>(circle_output);
0768 double yplus = std::get<1>(circle_output);
0769 double xminus = std::get<2>(circle_output);
0770 double yminus = std::get<3>(circle_output);
0771 if (Verbosity() > 1)
0772 {
0773 std::cout << "circle-circle intersection: (" << xplus << ", " << yplus << "), (" << xminus << ", " << yminus << ")" << std::endl;
0774 }
0775
0776 if (std::sqrt(square(end_tx - xplus) + square(end_ty - yplus)) > std::sqrt(square(end_tx - xminus) + square(end_ty - yminus)))
0777 {
0778 new_tx = xplus;
0779 new_ty = yplus;
0780 }
0781 else
0782 {
0783 new_tx = xminus;
0784 new_ty = yminus;
0785 }
0786
0787 if (Verbosity() > 1)
0788 {
0789 std::cout << "track now at (" << new_tx << ", " << new_ty << ")" << std::endl;
0790 }
0791 const double rot_phi = atan2(new_ty, new_tx);
0792
0793
0794
0795 const double new_tX = new_tx * cos(rot_phi) + new_ty * sin(rot_phi);
0796 const double new_tY = -new_tx * sin(rot_phi) + new_ty * cos(rot_phi);
0797 const double new_centerphi = atan2(new_ty - yc, new_tx - xc);
0798 double dcenterphi = new_centerphi - center_phi;
0799 if (dcenterphi > M_PI)
0800 {
0801 dcenterphi = 2. * M_PI - dcenterphi;
0802 }
0803 if (dcenterphi < -M_PI)
0804 {
0805 dcenterphi = 2. * M_PI + dcenterphi;
0806 }
0807 const double ds = R * std::abs(dcenterphi);
0808 const double dz = kftrack.GetDzDs() * ds;
0809
0810 current_phi = rot_phi;
0811 kftrack.SetX(new_tX);
0812 kftrack.SetY(new_tY);
0813 kftrack.SetZ(end_tz + dz);
0814
0815 kftrack.SetSignCosPhi(-kftrack.GetSignCosPhi());
0816
0817
0818 if (!TransportAndRotate(kftrack.GetX(), radii[current_layer - 7], current_phi, kftrack, fp))
0819 {
0820 return false;
0821 }
0822
0823 if (direction == PropagationDirection::Outward)
0824 {
0825 direction = PropagationDirection::Inward;
0826 }
0827 else
0828 {
0829 direction = PropagationDirection::Outward;
0830 }
0831
0832
0833 next_layer = current_layer;
0834 }
0835
0836
0837 if(!_pp_mode)
0838 {
0839 if (Verbosity() > 1)
0840 {
0841 std::cout << "doing distortion correction" << std::endl;
0842 }
0843
0844
0845
0846
0847
0848 const double uncorr_tX = kftrack.GetX();
0849 const double uncorr_tY = kftrack.GetY();
0850 const double uncorr_tx = uncorr_tX * cos(current_phi) - uncorr_tY * sin(current_phi);
0851 const double uncorr_ty = uncorr_tX * sin(current_phi) + uncorr_tY * cos(current_phi);
0852 const double uncorr_tz = kftrack.GetZ();
0853
0854 Acts::Vector3 proj_pt(uncorr_tx, uncorr_ty, uncorr_tz);
0855
0856 const double proj_radius = sqrt(square(uncorr_tx) + square(uncorr_ty));
0857 if (proj_radius > 78.0)
0858 {
0859
0860 return false;
0861 }
0862
0863 if (Verbosity() > 2)
0864 {
0865 std::cout << "distortion correction for (" << tx << ", " << ty << ", " << tz << "), layer " << next_layer << ", radius " << proj_radius << std::endl;
0866 }
0867
0868
0869 proj_pt = m_globalPositionWrapper.applyDistortionCorrections(proj_pt);
0870
0871
0872 const double dist_radius = sqrt(square(proj_pt[0]) + square(proj_pt[1]));
0873
0874 if (Verbosity() > 2)
0875 {
0876 std::cout << "after correction: (" << proj_pt[0] << ", " << proj_pt[1] << ", " << proj_pt[2] << "), radius " << dist_radius << std::endl;
0877 }
0878
0879 if (!TransportAndRotate(kftrack.GetX(), dist_radius, current_phi, kftrack, fp))
0880 {
0881 return false;
0882 }
0883
0884 if (std::isnan(kftrack.GetX()) ||
0885 std::isnan(kftrack.GetY()) ||
0886 std::isnan(kftrack.GetZ()))
0887 {
0888 return false;
0889 }
0890 }
0891
0892 const double new_tX = kftrack.GetX();
0893 const double new_tY = kftrack.GetY();
0894 const double new_tx = new_tX * cos(current_phi) - new_tY * sin(current_phi);
0895 const double new_ty = new_tX * sin(current_phi) + new_tY * cos(current_phi);
0896 const double new_tz = kftrack.GetZ();
0897
0898
0899 double query_pt[3] = {new_tx, new_ty, new_tz};
0900 std::vector<long unsigned int> index_out(1);
0901 std::vector<double> distance_out(1);
0902 int n_results = _kdtrees[next_layer]->knnSearch(&query_pt[0], 1, &index_out[0], &distance_out[0]);
0903
0904
0905 if (!n_results)
0906 {
0907 if (Verbosity() > 1)
0908 {
0909 std::cout << "no clusters found in search window, moving on" << std::endl;
0910 }
0911 current_layer = next_layer;
0912 return true;
0913 }
0914 const std::vector<double>& point = _ptclouds[next_layer]->pts[index_out[0]];
0915 TrkrDefs::cluskey closest_ckey = (*((int64_t*) &point[3]));
0916 TrkrCluster* clusterCandidate = _cluster_map->findCluster(closest_ckey);
0917 const auto candidate_globalpos = globalPositions.at(closest_ckey);
0918 const double cand_x = candidate_globalpos(0);
0919 const double cand_y = candidate_globalpos(1);
0920 const double cand_z = candidate_globalpos(2);
0921
0922 if (Verbosity() > 1)
0923 {
0924 std::cout << "found closest cluster candidate at (" << cand_x << ", " << cand_y << ", " << cand_z << ")" << std::endl;
0925 }
0926
0927
0928 const double tYerr = std::sqrt(kftrack.GetCov(0));
0929 const double txerr = std::abs(tYerr * sin(current_phi));
0930 const double tyerr = std::abs(tYerr * cos(current_phi));
0931 const double tzerr = sqrt(kftrack.GetCov(5));
0932
0933 if (Verbosity() > 1)
0934 {
0935 std::cout << "track state position errors: (" << txerr << ", " << tyerr << ", " << tzerr << ")" << std::endl;
0936 }
0937
0938 const double cand_xerr = sqrt(fitter->getClusterError(clusterCandidate, closest_ckey, candidate_globalpos, 0, 0));
0939 const double cand_yerr = sqrt(fitter->getClusterError(clusterCandidate, closest_ckey, candidate_globalpos, 1, 1));
0940 const double cand_zerr = sqrt(fitter->getClusterError(clusterCandidate, closest_ckey, candidate_globalpos, 2, 2));
0941
0942 if (Verbosity() > 1)
0943 {
0944 std::cout << "cluster position errors: (" << cand_xerr << ", " << cand_yerr << ", " << cand_zerr << ")" << std::endl;
0945 }
0946
0947
0948 if (std::abs(new_tx - cand_x) < _max_dist * std::sqrt(square(txerr) + square(cand_xerr)) &&
0949 std::abs(new_ty - cand_y) < _max_dist * std::sqrt(square(tyerr) + square(cand_yerr)) &&
0950 std::abs(new_tz - cand_z) < _max_dist * std::sqrt(square(tzerr) + square(cand_zerr)))
0951 {
0952 if (Verbosity() > 1)
0953 {
0954 std::cout << "added cluster" << std::endl;
0955 }
0956 propagated_track.push_back(closest_ckey);
0957
0958
0959 if (std::find(ckeys.begin(), ckeys.end(), closest_ckey) == ckeys.end())
0960 {
0961 const double cand_Y = -cand_x * std::sin(current_phi) + cand_y * std::cos(current_phi);
0962 const double cand_xycov2 = fitter->getClusterError(clusterCandidate, closest_ckey, candidate_globalpos, 0, 1);
0963 const double cand_Yerr2 = cand_xerr * cand_xerr * sin(current_phi) * sin(current_phi) + cand_xycov2 * sin(current_phi) * cos(current_phi) + cand_yerr * cand_yerr * cos(current_phi) * cos(current_phi);
0964 const double cand_zerr2 = cand_zerr * cand_zerr;
0965
0966 if (Verbosity() > 1)
0967 {
0968 std::cout << "Filtering cluster with Y=" << cand_Y << ", z=" << cand_z << ", Yerr2=" << cand_Yerr2 << ", zerr2=" << cand_zerr2 << std::endl;
0969 }
0970
0971 kftrack.Filter(cand_Y, cand_z, cand_Yerr2, cand_zerr2, _max_sin_phi);
0972 }
0973 }
0974
0975
0976 current_layer = next_layer;
0977
0978 if (Verbosity() > 1)
0979 {
0980 std::cout << "track current parameters:" << std::endl;
0981 std::cout << "(X, Y, Z) = (" << kftrack.GetX() << ", " << kftrack.GetY() << ", " << kftrack.GetZ() << ")" << std::endl;
0982 std::cout << "pt = " << 1. / fabs(kftrack.GetQPt()) << std::endl;
0983 std::cout << "sinPhi = " << kftrack.GetSinPhi() << std::endl;
0984 std::cout << "cosPhi = " << kftrack.GetCosPhi() << std::endl;
0985 std::cout << "dzds = " << kftrack.GetDzDs() << std::endl;
0986 }
0987
0988
0989 return true;
0990 }
0991
0992
0993 std::vector<TrkrDefs::cluskey> PHSimpleKFProp::PropagateTrack(TrackSeed* track, PropagationDirection direction, GPUTPCTrackParam& aliceSeed, const PositionMap& globalPositions) const
0994 {
0995
0996 std::vector<TrkrDefs::cluskey> ckeys;
0997 if (direction == PropagationDirection::Inward)
0998 {
0999 std::reverse_copy(track->begin_cluster_keys(), track->end_cluster_keys(), std::back_inserter(ckeys));
1000 } else {
1001 std::copy(track->begin_cluster_keys(), track->end_cluster_keys(), std::back_inserter(ckeys));
1002 }
1003 return PropagateTrack(track, ckeys, direction, aliceSeed, globalPositions);
1004 }
1005
1006
1007 std::vector<TrkrDefs::cluskey> PHSimpleKFProp::PropagateTrack(TrackSeed* track, std::vector<TrkrDefs::cluskey>& ckeys, PropagationDirection direction, GPUTPCTrackParam& aliceSeed, const PositionMap& globalPositions) const
1008 {
1009 if (direction == PropagationDirection::Inward)
1010 {
1011 aliceSeed.SetDzDs(-aliceSeed.GetDzDs());
1012 }
1013
1014 const auto track_pos = TrackSeedHelper::get_xyz(track);
1015 double track_x = track_pos.x();
1016 double track_y = track_pos.y();
1017 double track_z = track_pos.z();
1018
1019 if (Verbosity() > 1)
1020 {
1021 std::cout << "layers:" << std::endl;
1022 for (auto& c : ckeys)
1023 {
1024 std::cout << (int) TrkrDefs::getLayer(c) << ", ";
1025 }
1026 std::cout << std::endl;
1027 }
1028
1029 if (Verbosity() > 1)
1030 {
1031 std::cout << "track (x,y,z) = (" << track_x << ", " << track_y << ", " << track_z << ")" << std::endl;
1032 }
1033
1034 double track_px = track->get_px();
1035 double track_py = track->get_py();
1036 double track_pz = track->get_pz();
1037
1038 if (Verbosity() > 1)
1039 {
1040 std::cout << "track (px,py,pz) = (" << track_px << ", " << track_py << ", " << track_pz << ")" << std::endl;
1041 }
1042
1043 std::vector<Acts::Vector3> trkGlobPos;
1044 for (const auto& ckey : ckeys)
1045 {
1046 if (TrkrDefs::getTrkrId(ckey) == TrkrDefs::tpcId)
1047 {
1048 trkGlobPos.push_back(globalPositions.at(ckey));
1049 }
1050 }
1051
1052
1053 size_t inner_index;
1054 size_t second_index;
1055 if (TrkrDefs::getLayer(ckeys[0]) > TrkrDefs::getLayer(ckeys.back()))
1056 {
1057 inner_index = ckeys.size() - 1;
1058 second_index = ckeys.size() - 2;
1059 }
1060 else
1061 {
1062 inner_index = 0;
1063 second_index = 1;
1064 }
1065
1066 const double xc = track->get_X0();
1067 const double yc = track->get_Y0();
1068 const double cluster_x = trkGlobPos.at(inner_index)(0);
1069 const double cluster_y = trkGlobPos.at(inner_index)(1);
1070 const double dy = cluster_y - yc;
1071 const double dx = cluster_x - xc;
1072
1073 double phi = std::atan2(dy, dx);
1074 const double second_dx = trkGlobPos.at(second_index)(0) - xc;
1075 const double second_dy = trkGlobPos.at(second_index)(1) - yc;
1076 const double second_phi = std::atan2(second_dy, second_dx);
1077 const double dphi = second_phi - phi;
1078
1079 if (dphi > 0)
1080 {
1081 phi += M_PI / 2.0;
1082 }
1083 else
1084 {
1085 phi -= M_PI / 2.0;
1086 }
1087
1088 const double pt = std::sqrt(square(track_px)+square(track_py));
1089
1090
1091 track_px = pt * cos(phi);
1092 track_py = pt * sin(phi);
1093 track_x = trkGlobPos.at(0)(0);
1094 track_y = trkGlobPos.at(0)(1);
1095 track_z = trkGlobPos.at(0)(2);
1096
1097 if (Verbosity() > 1)
1098 {
1099 std::cout << "new track (x,y,z) = " << track_x << ", " << track_y << ", " << track_z << ")" << std::endl;
1100 }
1101 if (Verbosity() > 1)
1102 {
1103 std::cout << "new track (px,py,pz) = " << track_px << ", " << track_py << ", " << track_pz << ")" << std::endl;
1104 }
1105
1106
1107
1108 double track_pt = sqrt(track_px * track_px + track_py * track_py);
1109 if (Verbosity() > 1)
1110 {
1111 std::cout << "track pt: " << track_pt << std::endl;
1112 }
1113
1114
1115 GPUTPCTrackParam kftrack{};
1116 kftrack.InitParam();
1117 kftrack.setNeonFraction(Ne_frac);
1118 kftrack.setArgonFraction(Ar_frac);
1119 kftrack.setCF4Fraction(CF4_frac);
1120 kftrack.setNitrogenFraction(N2_frac);
1121 kftrack.setIsobutaneFraction(isobutane_frac);
1122
1123 float track_phi = atan2(track_y, track_x);
1124 if (Verbosity() > 1)
1125 {
1126 std::cout << "track phi: " << track_phi << std::endl;
1127 std::cout << "track charge: " << track->get_charge() << std::endl;
1128 }
1129 kftrack.SetQPt(track->get_charge() / track_pt);
1130
1131 float track_pX = track_px * std::cos(track_phi) + track_py * std::sin(track_phi);
1132 float track_pY = -track_px * std::sin(track_phi) + track_py * std::cos(track_phi);
1133
1134 kftrack.SetSignCosPhi(track_pX / track_pt);
1135 kftrack.SetSinPhi(track_pY / track_pt);
1136 kftrack.SetDzDs(track_pz / sqrt(track_pt * track_pt + track_pz * track_pz));
1137
1138 if (Verbosity() > 1)
1139 {
1140 std::cout << "track pX = " << track_pX << ", pY = " << track_pY << ", CosPhi = " << track_pX / track_pt << ", signCosPhi = " << kftrack.GetSignCosPhi() << std::endl;
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202 std::vector<TrkrDefs::cluskey> propagated_track;
1203
1204 kftrack.SetX(track_x * std::cos(track_phi) + track_y * std::sin(track_phi));
1205 kftrack.SetY(-track_x * std::sin(track_phi) + track_y * std::cos(track_phi));
1206 kftrack.SetZ(track_z);
1207
1208 if (kftrack.GetSignCosPhi() < 0)
1209 {
1210 kftrack.SetSinPhi(-kftrack.GetSinPhi());
1211 kftrack.SetDzDs(-kftrack.GetDzDs());
1212
1213 kftrack.SetCov(3, -kftrack.GetCov(3));
1214 kftrack.SetCov(4, -kftrack.GetCov(4));
1215 kftrack.SetCov(6, -kftrack.GetCov(6));
1216 kftrack.SetCov(7, -kftrack.GetCov(7));
1217 kftrack.SetCov(10, -kftrack.GetCov(10));
1218 kftrack.SetCov(11, -kftrack.GetCov(11));
1219 }
1220
1221 if (Verbosity() > 1)
1222 {
1223 std::cout << "initial track params:" << std::endl;
1224 std::cout << "X: " << kftrack.GetX() << std::endl;
1225 std::cout << "Y: " << kftrack.GetY() << std::endl;
1226 std::cout << "Z: " << kftrack.GetZ() << std::endl;
1227 std::cout << "SinPhi: " << kftrack.GetSinPhi() << std::endl;
1228 std::cout << "DzDs: " << kftrack.GetDzDs() << std::endl;
1229 std::cout << "QPt: " << kftrack.GetQPt() << std::endl;
1230 std::cout << "cov: " << std::endl;
1231 for (int i = 0; i < 15; i++)
1232 {
1233 std::cout << kftrack.GetCov(i) << ", ";
1234 }
1235 std::cout << std::endl;
1236 }
1237
1238
1239 std::vector<unsigned int> layers;
1240 std::transform(ckeys.begin(), ckeys.end(), std::back_inserter(layers), [](const TrkrDefs::cluskey& key)
1241 { return TrkrDefs::getLayer(key); });
1242
1243 double old_phi = track_phi;
1244 unsigned int old_layer = TrkrDefs::getLayer(ckeys[0]);
1245 if (Verbosity() > 1)
1246 {
1247 std::cout << "first layer: " << old_layer << std::endl;
1248 std::cout << "cluster (x,y,z) = (" << globalPositions.at(ckeys[0])(0) << ", " << globalPositions.at(ckeys[0])(1) << ", " << globalPositions.at(ckeys[0])(2) << ")" << std::endl;
1249 }
1250
1251 propagated_track.push_back(ckeys[0]);
1252
1253 GPUTPCTrackLinearisation kfline(aliceSeed);
1254 GPUTPCTrackParam::GPUTPCTrackFitParam fp{};
1255 aliceSeed.CalculateFitParameters(fp);
1256
1257 for (int step = 0; step <= _max_propagation_steps; ++step)
1258 {
1259 if (Verbosity() > 1)
1260 {
1261 std::cout << std::endl
1262 << "------------------------" << std::endl
1263 << "step " << step << std::endl;
1264 }
1265 if (!PropagateStep(old_layer, old_phi, direction, propagated_track, ckeys, aliceSeed, fp, globalPositions))
1266 {
1267 break;
1268 }
1269 }
1270
1271 if (Verbosity() > 1)
1272 {
1273 std::cout << "propagated track has " << propagated_track.size() << " clusters, at layers: ";
1274 for (auto c : propagated_track)
1275 {
1276 std::cout << (int) TrkrDefs::getLayer(c) << ", ";
1277 }
1278 std::cout << std::endl;
1279 }
1280 return propagated_track;
1281 }
1282
1283 std::vector<keylist> PHSimpleKFProp::RemoveBadClusters(const std::vector<keylist>& chains, const PositionMap& ) const
1284 {
1285 if (Verbosity())
1286 {
1287 std::cout << "removing bad clusters" << std::endl;
1288 }
1289 std::vector<keylist> clean_chains;
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332 std::copy_if(chains.begin(), chains.end(), std::back_inserter(clean_chains),
1333 [](const keylist& chain)
1334 { return chain.size() >= 3; });
1335
1336 return clean_chains;
1337 }
1338
1339 void PHSimpleKFProp::rejectAndPublishSeeds(std::vector<TrackSeed_v2>& seeds, const PositionMap& positions, std::vector<float>& trackChi2)
1340 {
1341
1342 PHTimer timer("KFPropTimer");
1343
1344
1345 timer.restart();
1346
1347
1348 PHGhostRejection rejector(Verbosity(), seeds);
1349 rejector.set_phi_cut(_ghost_phi_cut);
1350 rejector.set_eta_cut(_ghost_eta_cut);
1351 rejector.set_x_cut(_ghost_x_cut);
1352 rejector.set_y_cut(_ghost_y_cut);
1353 rejector.set_z_cut(_ghost_z_cut);
1354
1355
1356
1357
1358
1359
1360 for (unsigned int itrack = 0; itrack < seeds.size(); ++itrack)
1361 { rejector.cut_from_clusters(itrack); }
1362
1363 #pragma omp parallel
1364 {
1365
1366 #pragma omp for schedule(static)
1367 for (unsigned int itrack = 0; itrack < seeds.size(); ++itrack)
1368 {
1369
1370 if (rejector.is_rejected(itrack))
1371 { continue; }
1372
1373 auto& seed = seeds[itrack];
1374
1375 const int q = seed.get_charge();
1376
1377 PositionMap local;
1378 std::transform(seed.begin_cluster_keys(), seed.end_cluster_keys(), std::inserter(local, local.end()),
1379 [positions](const auto& key)
1380 { return std::make_pair(key, positions.at(key)); });
1381 TrackSeedHelper::circleFitByTaubin(&seed,local, 7, 55);
1382 TrackSeedHelper::lineFit(&seed,local, 7, 55);
1383 seed.set_phi(TrackSeedHelper::get_phi(&seed,local));
1384 seed.set_qOverR(std::abs(seed.get_qOverR()) * q);
1385 }
1386
1387 }
1388
1389 if (Verbosity())
1390 { std::cout << "PHSimpleKFProp::rejectAndPublishSeeds - circle fit: " << timer.elapsed() << " ms" << std::endl; }
1391
1392
1393 timer.restart();
1394 rejector.find_ghosts(trackChi2);
1395 if (Verbosity())
1396 { std::cout << "PHSimpleKFProp::rejectAndPublishSeeds - ghost rejection: " << timer.elapsed() << " ms" << std::endl; }
1397
1398 timer.restart();
1399 for (unsigned int itrack = 0; itrack < seeds.size(); ++itrack)
1400 {
1401 if (rejector.is_rejected(itrack))
1402 {
1403 if (Verbosity() > 0)
1404 {
1405 std::cout << " Seed " << ((int) itrack) << " rejected. Not getting published." << std::endl;
1406 }
1407 continue;
1408 }
1409 auto& seed = seeds[itrack];
1410 _track_map->insert(&seed);
1411
1412 int q = seed.get_charge();
1413 if (Verbosity() > 0)
1414 {
1415 std::cout << "Publishing seed " << ((int) itrack)
1416 << " q " << q
1417 << " qOverR " << std::abs(seed.get_qOverR()) * q
1418 << " x " << TrackSeedHelper::get_x(&seed)
1419 << " y " << TrackSeedHelper::get_y(&seed)
1420 << " z " << TrackSeedHelper::get_z(&seed)
1421 << " pT " << seed.get_pt()
1422 << " eta " << seed.get_eta()
1423 << " phi " << seed.get_phi()
1424 << std::endl;
1425 }
1426 }
1427 if (Verbosity())
1428 { std::cout << "PHSimpleKFProp::rejectAndPublishSeeds - publication: " << timer.elapsed() << " ms" << std::endl; }
1429
1430 }
1431
1432 void PHSimpleKFProp::publishSeeds(const std::vector<TrackSeed_v2>& seeds)
1433 {
1434 for (const auto& seed : seeds)
1435 {
1436 _track_map->insert(&seed);
1437 }
1438 }