File indexing completed on 2025-08-06 08:18:30
0001
0002
0003
0004
0005
0006
0007
0008 #include "PHGenFitTrkFitter.h"
0009
0010 #include <fun4all/Fun4AllReturnCodes.h>
0011 #include <fun4all/PHTFileServer.h>
0012 #include <fun4all/SubsysReco.h> // for SubsysReco
0013
0014 #include <g4detectors/PHG4CylinderGeom.h> // for PHG4CylinderGeom
0015 #include <g4detectors/PHG4CylinderGeomContainer.h>
0016
0017 #include <intt/CylinderGeomIntt.h>
0018 #include <intt/CylinderGeomInttHelper.h>
0019
0020 #include <micromegas/CylinderGeomMicromegas.h>
0021 #include <micromegas/MicromegasDefs.h>
0022
0023 #include <mvtx/CylinderGeom_Mvtx.h>
0024 #include <mvtx/CylinderGeom_MvtxHelper.h>
0025
0026 #include <phfield/PHFieldUtility.h>
0027
0028 #include <phgenfit/Fitter.h>
0029 #include <phgenfit/Measurement.h> // for Measurement
0030 #include <phgenfit/PlanarMeasurement.h>
0031 #include <phgenfit/SpacepointMeasurement.h>
0032 #include <phgenfit/Track.h>
0033
0034 #include <phgeom/PHGeomUtility.h>
0035
0036 #include <phool/PHCompositeNode.h>
0037 #include <phool/PHIODataNode.h>
0038 #include <phool/PHNode.h> // for PHNode
0039 #include <phool/PHNodeIterator.h>
0040 #include <phool/PHObject.h> // for PHObject
0041 #include <phool/getClass.h>
0042 #include <phool/phool.h>
0043
0044 #include <trackbase/ActsGeometry.h>
0045 #include <trackbase/InttDefs.h>
0046 #include <trackbase/MvtxDefs.h>
0047 #include <trackbase/TpcDefs.h>
0048 #include <trackbase/TrkrCluster.h> // for TrkrCluster
0049 #include <trackbase/TrkrClusterContainer.h>
0050 #include <trackbase/TrkrDefs.h>
0051
0052 #include <trackbase_historic/SvtxTrack.h>
0053 #include <trackbase_historic/SvtxTrackMap.h>
0054 #include <trackbase_historic/SvtxTrackMap_v2.h>
0055 #include <trackbase_historic/SvtxTrackState.h> // for SvtxTrackState
0056 #include <trackbase_historic/SvtxTrackState_v2.h>
0057 #include <trackbase_historic/SvtxTrack_v4.h>
0058 #include <trackbase_historic/TrackSeed.h>
0059 #include <trackbase_historic/TrackSeedContainer.h>
0060 #include <trackbase_historic/TrackSeedHelper.h>
0061
0062 #include <GenFit/AbsMeasurement.h> // for AbsMeasurement
0063 #include <GenFit/Exception.h> // for Exception
0064 #include <GenFit/KalmanFitterInfo.h>
0065 #include <GenFit/MeasuredStateOnPlane.h>
0066 #include <GenFit/RKTrackRep.h>
0067 #include <GenFit/Track.h>
0068 #include <GenFit/TrackPoint.h> // for TrackPoint
0069
0070 #include <TMatrixDSymfwd.h> // for TMatrixDSym
0071 #include <TMatrixFfwd.h> // for TMatrixF
0072 #include <TMatrixT.h> // for TMatrixT, operator*
0073 #include <TMatrixTSym.h> // for TMatrixTSym
0074 #include <TMatrixTUtils.h> // for TMatrixTRow
0075 #include <TRotation.h>
0076 #include <TTree.h>
0077 #include <TVector3.h>
0078 #include <TVectorDfwd.h> // for TVectorD
0079 #include <TVectorT.h> // for TVectorT
0080
0081 #include <cmath> // for sqrt, NAN
0082 #include <iostream>
0083 #include <map>
0084 #include <memory>
0085 #include <utility>
0086 #include <vector>
0087
0088 class PHField;
0089 class TGeoManager;
0090 namespace genfit
0091 {
0092 class AbsTrackRep;
0093 }
0094
0095 #define LogDebug(exp) std::cout << "DEBUG: " << __FILE__ << ": " << __LINE__ << ": " << (exp) << std::endl
0096 #define LogError(exp) std::cout << "ERROR: " << __FILE__ << ": " << __LINE__ << ": " << (exp) << std::endl
0097 #define LogWarning(exp) std::cout << "WARNING: " << __FILE__ << ": " << __LINE__ << ": " << (exp) << std::endl
0098
0099 using namespace std;
0100
0101
0102 namespace
0103 {
0104
0105
0106 template <class T>
0107 inline static constexpr T square(const T& x)
0108 {
0109 return x * x;
0110 }
0111
0112
0113 template <class T>
0114 inline static T get_r(const T& x, const T& y)
0115 {
0116 return std::sqrt( square(x)+square(y));
0117 }
0118
0119
0120 SvtxTrackState_v2 create_track_state(float pathlength, const genfit::MeasuredStateOnPlane* gf_state)
0121 {
0122 SvtxTrackState_v2 out(pathlength);
0123 out.set_x(gf_state->getPos().x());
0124 out.set_y(gf_state->getPos().y());
0125 out.set_z(gf_state->getPos().z());
0126
0127 out.set_px(gf_state->getMom().x());
0128 out.set_py(gf_state->getMom().y());
0129 out.set_pz(gf_state->getMom().z());
0130
0131 for (int i = 0; i < 6; i++)
0132 {
0133 for (int j = i; j < 6; j++)
0134 {
0135 out.set_error(i, j, gf_state->get6DCov()[i][j]);
0136 }
0137 }
0138
0139 return out;
0140 }
0141
0142
0143 std::vector<TrkrDefs::cluskey> get_cluster_keys(const SvtxTrack* track)
0144 {
0145 std::vector<TrkrDefs::cluskey> out;
0146 for (const auto& seed : {track->get_silicon_seed(), track->get_tpc_seed()})
0147 {
0148 if (seed)
0149 {
0150 std::copy(seed->begin_cluster_keys(), seed->end_cluster_keys(), std::back_inserter(out));
0151 }
0152 }
0153 return out;
0154 }
0155
0156 [[maybe_unused]] std::ostream& operator<<(std::ostream& out, const Acts::Vector3& vector)
0157 {
0158 out << "(" << vector.x() << ", " << vector.y() << ", " << vector.z() << ")";
0159 return out;
0160 }
0161
0162 TVector3 get_world_from_local_vect( ActsGeometry* geometry, Surface surface, const TVector3& local_vect )
0163 {
0164
0165
0166 Acts::Vector3 local(
0167 local_vect.x()*Acts::UnitConstants::cm,
0168 local_vect.y()*Acts::UnitConstants::cm,
0169 local_vect.z()*Acts::UnitConstants::cm );
0170
0171
0172 const Acts::Vector3 global = surface->referenceFrame(geometry->geometry().getGeoContext(), {0,0,0}, {0,0,0})*local;
0173 return TVector3(
0174 global.x()/Acts::UnitConstants::cm,
0175 global.y()/Acts::UnitConstants::cm,
0176 global.z()/Acts::UnitConstants::cm );
0177 }
0178
0179 }
0180
0181
0182
0183
0184 PHGenFitTrkFitter::PHGenFitTrkFitter(const string& name)
0185 : SubsysReco(name)
0186 {
0187 }
0188
0189
0190
0191
0192 int PHGenFitTrkFitter::Init(PHCompositeNode* )
0193 {
0194 return Fun4AllReturnCodes::EVENT_OK;
0195 }
0196
0197
0198
0199
0200 int PHGenFitTrkFitter::InitRun(PHCompositeNode* topNode)
0201 {
0202 CreateNodes(topNode);
0203
0204 auto tgeo_manager = PHGeomUtility::GetTGeoManager(topNode);
0205 auto field = PHFieldUtility::GetFieldMapNode(nullptr, topNode);
0206
0207 _fitter.reset(PHGenFit::Fitter::getInstance(tgeo_manager, field, _track_fitting_alg_name, "RKTrackRep", false));
0208 _fitter->set_verbosity(Verbosity());
0209
0210 std::cout << "PHGenFitTrkFitter::InitRun - m_fit_silicon_mms: " << m_fit_silicon_mms << std::endl;
0211 std::cout << "PHGenFitTrkFitter::InitRun - m_use_micromegas: " << m_use_micromegas << std::endl;
0212
0213
0214
0215 {
0216 for (const auto& layer : _disabled_layers)
0217 {
0218 std::cout << PHWHERE << " Layer " << layer << " is disabled." << std::endl;
0219 }
0220 }
0221
0222 return Fun4AllReturnCodes::EVENT_OK;
0223 }
0224
0225
0226
0227
0228
0229
0230
0231 int PHGenFitTrkFitter::process_event(PHCompositeNode* topNode)
0232 {
0233 ++_event;
0234
0235 if (Verbosity() > 1)
0236 {
0237 std::cout << PHWHERE << "Events processed: " << _event << std::endl;
0238 }
0239
0240
0241 GetNodes(topNode);
0242
0243
0244 m_trackMap->Reset();
0245
0246 unsigned int trackid = 0;
0247 for (const auto& track : *m_seedMap)
0248 {
0249 if (!track) continue;
0250
0251
0252 const auto siid = track->get_silicon_seed_index();
0253 if (siid == std::numeric_limits<unsigned int>::max()) continue;
0254 const auto siseed = m_siliconSeeds->get(siid);
0255 if (!siseed) continue;
0256
0257
0258 const auto crossing = siseed->get_crossing();
0259 if (crossing == SHRT_MAX) continue;
0260
0261
0262 const auto tpcid = track->get_tpc_seed_index();
0263 const auto tpcseed = m_tpcSeeds->get(tpcid);
0264 if (!tpcseed) continue;
0265
0266
0267 auto svtxtrack = std::make_unique<SvtxTrack_v4>();
0268 svtxtrack->set_id(trackid++);
0269 svtxtrack->set_silicon_seed(siseed);
0270 svtxtrack->set_tpc_seed(tpcseed);
0271 svtxtrack->set_crossing(crossing);
0272
0273
0274 const auto position = TrackSeedHelper::get_xyz(siseed);
0275 svtxtrack->set_x(position.x());
0276 svtxtrack->set_y(position.y());
0277 svtxtrack->set_z(position.z());
0278
0279
0280 svtxtrack->set_charge(tpcseed->get_qOverR() > 0 ? 1 : -1);
0281 svtxtrack->set_px(tpcseed->get_px());
0282 svtxtrack->set_py(tpcseed->get_py());
0283 svtxtrack->set_pz(tpcseed->get_pz());
0284
0285
0286 m_trackMap->insert(svtxtrack.get());
0287 }
0288
0289
0290 vector<genfit::Track*> rf_gf_tracks;
0291 vector<std::shared_ptr<PHGenFit::Track> > rf_phgf_tracks;
0292
0293 map<unsigned int, unsigned int> svtxtrack_genfittrack_map;
0294
0295 for (const auto& [key, svtx_track] : *m_trackMap)
0296 {
0297 if (!svtx_track) continue;
0298
0299 if (Verbosity() > 10)
0300 {
0301 cout << " process SVTXTrack " << key << endl;
0302 svtx_track->identify();
0303 }
0304
0305 if (!(svtx_track->get_pt() > _fit_min_pT)) continue;
0306
0307
0308
0309 const auto rf_phgf_track = ReFitTrack(topNode, svtx_track);
0310 if (rf_phgf_track)
0311 {
0312 svtxtrack_genfittrack_map[svtx_track->get_id()] = rf_phgf_tracks.size();
0313 rf_phgf_tracks.push_back(rf_phgf_track);
0314 if (rf_phgf_track->get_ndf() > _vertex_min_ndf)
0315 {
0316 rf_gf_tracks.push_back(rf_phgf_track->getGenFitTrack());
0317 }
0318
0319 if (Verbosity() > 10) cout << "Done refitting input track" << svtx_track->get_id() << " or rf_phgf_track " << rf_phgf_tracks.size() << endl;
0320 }
0321 else if (Verbosity() >= 1)
0322 {
0323 cout << "failed refitting input track# " << key << endl;
0324 }
0325 }
0326
0327
0328
0329
0330
0331
0332 for (SvtxTrackMap::Iter iter = m_trackMap->begin(); iter != m_trackMap->end();)
0333 {
0334 std::shared_ptr<PHGenFit::Track> rf_phgf_track;
0335
0336
0337 unsigned int itrack = 0;
0338 if (svtxtrack_genfittrack_map.find(iter->second->get_id()) != svtxtrack_genfittrack_map.end())
0339 {
0340 itrack = svtxtrack_genfittrack_map[iter->second->get_id()];
0341 rf_phgf_track = rf_phgf_tracks[itrack];
0342 }
0343
0344 if (rf_phgf_track)
0345 {
0346 const auto rf_track = MakeSvtxTrack(iter->second, rf_phgf_track);
0347 if (rf_track)
0348 {
0349
0350 iter->second->CopyFrom(rf_track.get());
0351 }
0352 else
0353 {
0354
0355 auto key = iter->first;
0356 ++iter;
0357 m_trackMap->erase(key);
0358 continue;
0359 }
0360 }
0361 else
0362 {
0363
0364 auto key = iter->first;
0365 ++iter;
0366 m_trackMap->erase(key);
0367 continue;
0368 }
0369
0370 ++iter;
0371 }
0372
0373
0374 rf_phgf_tracks.clear();
0375
0376 return Fun4AllReturnCodes::EVENT_OK;
0377 }
0378
0379
0380
0381
0382 int PHGenFitTrkFitter::End(PHCompositeNode* )
0383 {
0384 return Fun4AllReturnCodes::EVENT_OK;
0385 }
0386
0387 int PHGenFitTrkFitter::CreateNodes(PHCompositeNode* topNode)
0388 {
0389
0390 PHNodeIterator iter(topNode);
0391
0392 auto dstNode = static_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0393 if (!dstNode)
0394 {
0395 cerr << PHWHERE << "DST Node missing, doing nothing." << endl;
0396 return Fun4AllReturnCodes::ABORTEVENT;
0397 }
0398 PHNodeIterator iter_dst(dstNode);
0399
0400
0401 auto svtx_node = dynamic_cast<PHCompositeNode*>(iter_dst.findFirst("PHCompositeNode", "SVTX"));
0402 if (!svtx_node)
0403 {
0404 svtx_node = new PHCompositeNode("SVTX");
0405 dstNode->addNode(svtx_node);
0406 if (Verbosity())
0407 {
0408 cout << "SVTX node added" << endl;
0409 }
0410 }
0411
0412
0413 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, _trackMap_name);
0414 if (!m_trackMap)
0415 {
0416 m_trackMap = new SvtxTrackMap_v2;
0417 auto node = new PHIODataNode<PHObject>(m_trackMap, _trackMap_name, "PHObject");
0418 svtx_node->addNode(node);
0419 }
0420
0421 return Fun4AllReturnCodes::EVENT_OK;
0422 }
0423
0424
0425 void PHGenFitTrkFitter::disable_layer(int layer, bool disabled)
0426 {
0427 if (disabled)
0428 _disabled_layers.insert(layer);
0429 else
0430 _disabled_layers.erase(layer);
0431 }
0432
0433
0434 void PHGenFitTrkFitter::set_disabled_layers(const std::set<int>& layers)
0435 {
0436 _disabled_layers = layers;
0437 }
0438
0439
0440 void PHGenFitTrkFitter::clear_disabled_layers()
0441 {
0442 _disabled_layers.clear();
0443 }
0444
0445
0446 const std::set<int>& PHGenFitTrkFitter::get_disabled_layers() const
0447 {
0448 return _disabled_layers;
0449 }
0450
0451
0452 void PHGenFitTrkFitter::set_fit_silicon_mms(bool value)
0453 {
0454
0455 m_fit_silicon_mms = value;
0456
0457
0458 for (int layer = 7; layer < 23; ++layer)
0459 {
0460 disable_layer(layer, value);
0461 }
0462 for (int layer = 23; layer < 39; ++layer)
0463 {
0464 disable_layer(layer, value);
0465 }
0466 for (int layer = 39; layer < 55; ++layer)
0467 {
0468 disable_layer(layer, value);
0469 }
0470 }
0471
0472
0473
0474
0475
0476 int PHGenFitTrkFitter::GetNodes(PHCompositeNode* topNode)
0477 {
0478
0479 m_tgeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0480 if (!m_tgeometry)
0481 {
0482 std::cout << "PHGenFitTrkFitter::GetNodes - No acts tracking geometry, can't proceed" << std::endl;
0483 return Fun4AllReturnCodes::ABORTEVENT;
0484 }
0485
0486
0487
0488 m_clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "CORRECTED_TRKR_CLUSTER");
0489 if (m_clustermap)
0490 {
0491 if (_event < 2)
0492 {
0493 std::cout << "PHGenFitTrkFitter::GetNodes - Using CORRECTED_TRKR_CLUSTER node " << std::endl;
0494 }
0495 }
0496 else
0497 {
0498 if (_event < 2)
0499 {
0500 std::cout << "PHGenFitTrkFitter::GetNodes - CORRECTED_TRKR_CLUSTER node not found, using TRKR_CLUSTER" << std::endl;
0501 }
0502 m_clustermap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0503 }
0504
0505 if (!m_clustermap)
0506 {
0507 cout << PHWHERE << "PHGenFitTrkFitter::GetNodes - TRKR_CLUSTER node not found on node tree" << endl;
0508 return Fun4AllReturnCodes::ABORTEVENT;
0509 }
0510
0511
0512 m_seedMap = findNode::getClass<TrackSeedContainer>(topNode, _seedMap_name);
0513 if (!m_seedMap)
0514 {
0515 std::cout << "PHGenFitTrkFitter::GetNodes - No Svtx seed map on node tree. Exiting." << std::endl;
0516 return Fun4AllReturnCodes::ABORTEVENT;
0517 }
0518
0519 m_tpcSeeds = findNode::getClass<TrackSeedContainer>(topNode, "TpcTrackSeedContainer");
0520 if (!m_tpcSeeds)
0521 {
0522 std::cout << "PHGenFitTrkFitter::GetNodes - TpcTrackSeedContainer not on node tree. Bailing"
0523 << std::endl;
0524 return Fun4AllReturnCodes::ABORTEVENT;
0525 }
0526
0527 m_siliconSeeds = findNode::getClass<TrackSeedContainer>(topNode, "SiliconTrackSeedContainer");
0528 if (!m_siliconSeeds)
0529 {
0530 std::cout << "PHGenFitTrkFitter::GetNodes - SiliconTrackSeedContainer not on node tree. Bailing"
0531 << std::endl;
0532 return Fun4AllReturnCodes::ABORTEVENT;
0533 }
0534
0535
0536 m_trackMap = findNode::getClass<SvtxTrackMap>(topNode, _trackMap_name);
0537 if (!m_trackMap && _event < 2)
0538 {
0539 cout << "PHGenFitTrkFitter::GetNodes - SvtxTrackMap node not found on node tree" << endl;
0540 return Fun4AllReturnCodes::ABORTEVENT;
0541 }
0542
0543
0544 m_globalPositionWrapper.loadNodes(topNode);
0545 if (m_disable_module_edge_corr) { m_globalPositionWrapper.set_enable_module_edge_corr(false); }
0546 if (m_disable_static_corr) { m_globalPositionWrapper.set_enable_static_corr(false); }
0547 if (m_disable_average_corr) { m_globalPositionWrapper.set_enable_average_corr(false); }
0548 if (m_disable_fluctuation_corr) { m_globalPositionWrapper.set_enable_fluctuation_corr(false); }
0549
0550 return Fun4AllReturnCodes::EVENT_OK;
0551 }
0552
0553
0554
0555
0556
0557 std::shared_ptr<PHGenFit::Track> PHGenFitTrkFitter::ReFitTrack(PHCompositeNode* , const SvtxTrack* intrack)
0558 {
0559
0560 if (!intrack)
0561 {
0562 cerr << PHWHERE << " Input SvtxTrack is nullptr!" << endl;
0563 return nullptr;
0564 }
0565
0566
0567 const auto crossing = intrack->get_crossing();
0568 assert(crossing != SHRT_MAX);
0569
0570
0571 TVector3 seed_mom(100, 0, 0);
0572 TVector3 seed_pos(0, 0, 0);
0573 TMatrixDSym seed_cov(6);
0574 for (int i = 0; i < 6; i++)
0575 {
0576 for (int j = 0; j < 6; j++)
0577 {
0578 seed_cov[i][j] = 100.;
0579 }
0580 }
0581
0582
0583 std::vector<PHGenFit::Measurement*> measurements;
0584
0585
0586 if (Verbosity() > 10)
0587 {
0588 intrack->identify();
0589 }
0590 std::map<float, TrkrDefs::cluskey> m_r_cluster_id;
0591
0592 unsigned int n_silicon_clusters = 0;
0593 unsigned int n_micromegas_clusters = 0;
0594
0595 for (const auto& cluster_key : get_cluster_keys(intrack))
0596 {
0597
0598 switch (TrkrDefs::getTrkrId(cluster_key))
0599 {
0600 case TrkrDefs::mvtxId:
0601 case TrkrDefs::inttId:
0602 ++n_silicon_clusters;
0603 break;
0604
0605 case TrkrDefs::micromegasId:
0606 ++n_micromegas_clusters;
0607 break;
0608
0609 default:
0610 break;
0611 }
0612
0613 const auto cluster = m_clustermap->findCluster(cluster_key);
0614 const auto globalPosition = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(cluster_key, cluster, crossing);
0615 const float r = get_r(globalPosition.x(), globalPosition.y());
0616 m_r_cluster_id.emplace(r, cluster_key);
0617 if (Verbosity() > 10)
0618 {
0619 const int layer_out = TrkrDefs::getLayer(cluster_key);
0620 cout << " Layer " << layer_out << " cluster " << cluster_key << " radius " << r << endl;
0621 }
0622 }
0623
0624
0625 if (m_fit_silicon_mms)
0626 {
0627 if (n_silicon_clusters == 0)
0628 {
0629 return nullptr;
0630 }
0631 if (m_use_micromegas && n_micromegas_clusters == 0)
0632 {
0633 return nullptr;
0634 }
0635 }
0636
0637 for (const auto& [r, cluster_key] : m_r_cluster_id)
0638 {
0639 const int layer = TrkrDefs::getLayer(cluster_key);
0640
0641
0642 if (_disabled_layers.find(layer) != _disabled_layers.end())
0643 {
0644 continue;
0645 }
0646
0647 auto cluster = m_clustermap->findCluster(cluster_key);
0648 if (!cluster)
0649 {
0650 LogError("No cluster Found!");
0651 continue;
0652 }
0653
0654 const auto globalPosition_acts = m_globalPositionWrapper.getGlobalPositionDistortionCorrected(cluster_key, cluster, crossing);
0655 const TVector3 pos(globalPosition_acts.x(), globalPosition_acts.y(), globalPosition_acts.z());
0656
0657 const double cluster_rphi_error = cluster->getRPhiError();
0658 const double cluster_z_error = cluster->getZError();
0659
0660 seed_mom.SetPhi(pos.Phi());
0661 seed_mom.SetTheta(pos.Theta());
0662
0663 std::unique_ptr<PHGenFit::PlanarMeasurement> meas;
0664 switch (TrkrDefs::getTrkrId(cluster_key))
0665 {
0666 case TrkrDefs::mvtxId:
0667 {
0668 auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluster_key);
0669 auto surface = m_tgeometry->maps().getSiliconSurface(hitsetkey);
0670 const auto u = get_world_from_local_vect(m_tgeometry, surface, {1, 0, 0});
0671 const auto v = get_world_from_local_vect(m_tgeometry, surface, {0, 1, 0});
0672 meas.reset( new PHGenFit::PlanarMeasurement(pos, u, v, cluster_rphi_error, cluster_z_error) );
0673
0674 break;
0675 }
0676
0677 case TrkrDefs::inttId:
0678 {
0679 auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluster_key);
0680 auto surface = m_tgeometry->maps().getSiliconSurface(hitsetkey);
0681 const auto u = get_world_from_local_vect(m_tgeometry, surface, {1, 0, 0});
0682 const auto v = get_world_from_local_vect(m_tgeometry, surface, {0, 1, 0});
0683 meas.reset( new PHGenFit::PlanarMeasurement(pos, u, v, cluster_rphi_error, cluster_z_error) );
0684 break;
0685 }
0686
0687 case TrkrDefs::micromegasId:
0688 {
0689
0690
0691
0692 auto hitsetkey = TrkrDefs::getHitSetKeyFromClusKey(cluster_key);
0693 auto surface = m_tgeometry->maps().getMMSurface(hitsetkey);
0694 const auto u = get_world_from_local_vect(m_tgeometry, surface, {1, 0, 0});
0695 const auto v = get_world_from_local_vect(m_tgeometry, surface, {0, 1, 0});
0696 meas.reset( new PHGenFit::PlanarMeasurement(pos, u, v, cluster_rphi_error, cluster_z_error) );
0697 break;
0698 }
0699
0700 case TrkrDefs::tpcId:
0701 {
0702
0703 const TVector3 n(globalPosition_acts.x(), globalPosition_acts.y(), 0);
0704 meas.reset( new PHGenFit::PlanarMeasurement(pos, n, cluster_rphi_error, cluster_z_error) );
0705 break;
0706 }
0707
0708 }
0709
0710
0711 meas->set_cluster_key( cluster_key );
0712
0713
0714 measurements.push_back(meas.release());
0715 }
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725
0726
0727 auto rep = new genfit::RKTrackRep(_primary_pid_guess);
0728 std::shared_ptr<PHGenFit::Track> track(new PHGenFit::Track(rep, seed_pos, seed_mom, seed_cov));
0729
0730
0731 track->addMeasurements(measurements);
0732
0733
0734
0735
0736
0737
0738 if (_fitter->processTrack(track.get(), false) != 0)
0739 {
0740
0741 {
0742 LogWarning("Track fitting failed");
0743 }
0744
0745 return nullptr;
0746 }
0747
0748 if (Verbosity() > 10)
0749 cout << " track->getChisq() " << track->get_chi2() << " get_ndf " << track->get_ndf()
0750 << " mom.X " << track->get_mom().X()
0751 << " mom.Y " << track->get_mom().Y()
0752 << " mom.Z " << track->get_mom().Z()
0753 << endl;
0754
0755 return track;
0756 }
0757
0758
0759
0760
0761
0762 std::shared_ptr<SvtxTrack> PHGenFitTrkFitter::MakeSvtxTrack(const SvtxTrack* svtx_track, const std::shared_ptr<PHGenFit::Track>& phgf_track)
0763 {
0764 double chi2 = phgf_track->get_chi2();
0765 double ndf = phgf_track->get_ndf();
0766
0767 TVector3 vertex_position(0, 0, 0);
0768 TMatrixF vertex_cov(3, 3);
0769 double dvr2 = 0;
0770 double dvz2 = 0;
0771
0772 std::unique_ptr<genfit::MeasuredStateOnPlane> gf_state_beam_line_ca;
0773 try
0774 {
0775 gf_state_beam_line_ca.reset(phgf_track->extrapolateToLine(vertex_position, TVector3(0., 0., 1.)));
0776 }
0777 catch (...)
0778 {
0779 if (Verbosity() >= 2)
0780 {
0781 LogWarning("extrapolateToLine failed!");
0782 }
0783 }
0784 if (!gf_state_beam_line_ca)
0785 {
0786 return nullptr;
0787 }
0788
0789
0790
0791
0792
0793
0794
0795
0796 double u = gf_state_beam_line_ca->getState()[3];
0797 double v = gf_state_beam_line_ca->getState()[4];
0798
0799 double du2 = gf_state_beam_line_ca->getCov()[3][3];
0800 double dv2 = gf_state_beam_line_ca->getCov()[4][4];
0801
0802
0803
0804
0805 auto out_track = std::make_shared<SvtxTrack_v4>(*svtx_track);
0806
0807
0808 out_track->clear_states();
0809 {
0810
0811
0812
0813
0814
0815 SvtxTrackState_v2 first(0.0);
0816 out_track->insert_state(&first);
0817 }
0818
0819 out_track->set_dca2d(u);
0820 out_track->set_dca2d_error(sqrt(du2 + dvr2));
0821
0822 std::unique_ptr<genfit::MeasuredStateOnPlane> gf_state_vertex_ca;
0823 try
0824 {
0825 gf_state_vertex_ca.reset(phgf_track->extrapolateToPoint(vertex_position));
0826 }
0827 catch (...)
0828 {
0829 if (Verbosity() >= 2)
0830 {
0831 LogWarning("extrapolateToPoint failed!");
0832 }
0833 }
0834 if (!gf_state_vertex_ca)
0835 {
0836
0837 return nullptr;
0838 }
0839
0840 const auto mom = gf_state_vertex_ca->getMom();
0841 const auto pos = gf_state_vertex_ca->getPos();
0842 const auto cov = gf_state_vertex_ca->get6DCov();
0843
0844
0845
0846
0847
0848 u = gf_state_vertex_ca->getState()[3];
0849 v = gf_state_vertex_ca->getState()[4];
0850
0851 du2 = gf_state_vertex_ca->getCov()[3][3];
0852 dv2 = gf_state_vertex_ca->getCov()[4][4];
0853
0854 double dca3d = sqrt(square(u) + square(v));
0855 double dca3d_error = sqrt(du2 + dv2 + dvr2 + dvz2);
0856
0857 out_track->set_dca(dca3d);
0858 out_track->set_dca_error(dca3d_error);
0859
0860
0861
0862
0863 float dca3d_xy = NAN;
0864 float dca3d_z = NAN;
0865 float dca3d_xy_error = NAN;
0866 float dca3d_z_error = NAN;
0867
0868 try
0869 {
0870 TMatrixF pos_in(3, 1);
0871 TMatrixF cov_in(3, 3);
0872 TMatrixF pos_out(3, 1);
0873 TMatrixF cov_out(3, 3);
0874
0875 TVectorD state6(6);
0876 TMatrixDSym cov6(6, 6);
0877
0878 gf_state_vertex_ca->get6DStateCov(state6, cov6);
0879
0880 TVector3 vn(state6[3], state6[4], state6[5]);
0881
0882
0883 pos_in[0][0] = state6[0] - vertex_position.X();
0884 pos_in[1][0] = state6[1] - vertex_position.Y();
0885 pos_in[2][0] = state6[2] - vertex_position.Z();
0886
0887 for (int i = 0; i < 3; ++i)
0888 {
0889 for (int j = 0; j < 3; ++j)
0890 {
0891 cov_in[i][j] = cov6[i][j] + vertex_cov[i][j];
0892 }
0893 }
0894
0895
0896 pos_cov_XYZ_to_RZ(vn, pos_in, cov_in, pos_out, cov_out);
0897
0898 if (Verbosity() > 30)
0899 {
0900 cout << " vn.X " << vn.X() << " vn.Y " << vn.Y() << " vn.Z " << vn.Z() << endl;
0901 cout << " pos_in.X " << pos_in[0][0] << " pos_in.Y " << pos_in[1][0] << " pos_in.Z " << pos_in[2][0] << endl;
0902 cout << " pos_out.X " << pos_out[0][0] << " pos_out.Y " << pos_out[1][0] << " pos_out.Z " << pos_out[2][0] << endl;
0903 }
0904
0905 dca3d_xy = pos_out[0][0];
0906 dca3d_z = pos_out[2][0];
0907 dca3d_xy_error = sqrt(cov_out[0][0]);
0908 dca3d_z_error = sqrt(cov_out[2][2]);
0909
0910 #ifdef _DEBUG_
0911 cout << __LINE__ << ": Vertex: ----------------" << endl;
0912 vertex_position.Print();
0913 vertex_cov.Print();
0914
0915 cout << __LINE__ << ": State: ----------------" << endl;
0916 state6.Print();
0917 cov6.Print();
0918
0919 cout << __LINE__ << ": Mean: ----------------" << endl;
0920 pos_in.Print();
0921 cout << "===>" << endl;
0922 pos_out.Print();
0923
0924 cout << __LINE__ << ": Cov: ----------------" << endl;
0925 cov_in.Print();
0926 cout << "===>" << endl;
0927 cov_out.Print();
0928
0929 cout << endl;
0930 #endif
0931 }
0932 catch (...)
0933 {
0934 if (Verbosity())
0935 {
0936 LogWarning("DCA calculationfailed!");
0937 }
0938 }
0939
0940 out_track->set_dca3d_xy(dca3d_xy);
0941 out_track->set_dca3d_z(dca3d_z);
0942 out_track->set_dca3d_xy_error(dca3d_xy_error);
0943 out_track->set_dca3d_z_error(dca3d_z_error);
0944
0945
0946
0947 out_track->set_chisq(chi2);
0948 out_track->set_ndf(ndf);
0949 out_track->set_charge(phgf_track->get_charge());
0950
0951 out_track->set_px(mom.Px());
0952 out_track->set_py(mom.Py());
0953 out_track->set_pz(mom.Pz());
0954
0955 out_track->set_x(pos.X());
0956 out_track->set_y(pos.Y());
0957 out_track->set_z(pos.Z());
0958
0959 for (int i = 0; i < 6; i++)
0960 {
0961 for (int j = i; j < 6; j++)
0962 {
0963 out_track->set_error(i, j, cov[i][j]);
0964 }
0965 }
0966
0967 #ifdef _DEBUG_
0968 cout << __LINE__ << endl;
0969 #endif
0970
0971 const auto gftrack = phgf_track->getGenFitTrack();
0972 const auto rep = gftrack->getCardinalRep();
0973 for (unsigned int id = 0; id < gftrack->getNumPointsWithMeasurement(); ++id)
0974 {
0975 genfit::TrackPoint* trpoint = gftrack->getPointWithMeasurementAndFitterInfo(id, gftrack->getCardinalRep());
0976
0977 if (!trpoint)
0978 {
0979 if (Verbosity() > 1) LogWarning("!trpoint");
0980 continue;
0981 }
0982
0983 auto kfi = static_cast<genfit::KalmanFitterInfo*>(trpoint->getFitterInfo(rep));
0984 if (!kfi)
0985 {
0986 if (Verbosity() > 1) LogWarning("!kfi");
0987 continue;
0988 }
0989
0990 const genfit::MeasuredStateOnPlane* gf_state = nullptr;
0991 try
0992 {
0993
0994 gf_state = &kfi->getFittedState(true);
0995 }
0996 catch (...)
0997 {
0998 if (Verbosity() >= 1)
0999 LogWarning("Exrapolation failed!");
1000 }
1001 if (!gf_state)
1002 {
1003 if (Verbosity() >= 1)
1004 LogWarning("Exrapolation failed!");
1005 continue;
1006 }
1007 genfit::MeasuredStateOnPlane temp;
1008 float pathlength = -phgf_track->extrapolateToPoint(temp, vertex_position, id);
1009
1010
1011 auto state = create_track_state(pathlength, gf_state);
1012
1013
1014 state.set_cluskey(phgf_track->get_cluster_keys()[id]);
1015
1016 out_track->insert_state(&state);
1017
1018 #ifdef _DEBUG_
1019 cout
1020 << __LINE__
1021 << ": " << id
1022 << ": " << pathlength << " => "
1023 << sqrt(square(state->get_x()) + square(state->get_y()))
1024 << endl;
1025 #endif
1026 }
1027
1028
1029 if (!_disabled_layers.empty())
1030 {
1031
1032 const auto crossing = svtx_track->get_crossing();
1033 assert(crossing != SHRT_MAX);
1034
1035 unsigned int id_min = 0;
1036 for (const auto& cluster_key : get_cluster_keys(svtx_track))
1037 {
1038 const auto cluster = m_clustermap->findCluster(cluster_key);
1039 const auto layer = TrkrDefs::getLayer(cluster_key);
1040
1041
1042 if (_disabled_layers.find(layer) == _disabled_layers.end())
1043 {
1044 continue;
1045 }
1046
1047
1048 const auto globalPosition = m_globalPositionWrapper.getGlobalPositionDistortionCorrected( cluster_key, cluster, crossing );
1049 const TVector3 pos_A(globalPosition.x(), globalPosition.y(), globalPosition.z() );
1050 const float r_cluster = std::sqrt( square(globalPosition.x()) + square(globalPosition.y()) );
1051
1052
1053
1054 unsigned int id = id_min;
1055 for (; id < gftrack->getNumPointsWithMeasurement(); ++id)
1056 {
1057 auto trpoint = gftrack->getPointWithMeasurementAndFitterInfo(id, rep);
1058 if (!trpoint) continue;
1059
1060 auto kfi = static_cast<genfit::KalmanFitterInfo*>(trpoint->getFitterInfo(rep));
1061 if (!kfi) continue;
1062
1063 const genfit::MeasuredStateOnPlane* gf_state = nullptr;
1064 try
1065 {
1066 gf_state = &kfi->getFittedState(true);
1067 }
1068 catch (...)
1069 {
1070 if (Verbosity())
1071 {
1072 LogWarning("Failed to get kf fitted state");
1073 }
1074 }
1075
1076 if (!gf_state) continue;
1077
1078 float r_track = std::sqrt(square(gf_state->getPos().x()) + square(gf_state->getPos().y()));
1079 if (r_track > r_cluster) break;
1080 }
1081
1082
1083 genfit::MeasuredStateOnPlane gf_state;
1084 float pathlength = 0;
1085
1086
1087 if (id > 0) id_min = id - 1;
1088
1089
1090 try
1091 {
1092 auto trpoint = gftrack->getPointWithMeasurementAndFitterInfo(id_min, rep);
1093 if (!trpoint) continue;
1094
1095 auto kfi = static_cast<genfit::KalmanFitterInfo*>(trpoint->getFitterInfo(rep));
1096 gf_state = *kfi->getForwardUpdate();
1097 pathlength = gf_state.extrapolateToPoint( pos_A );
1098 auto tmp = *kfi->getBackwardUpdate();
1099 pathlength -= tmp.extrapolateToPoint(vertex_position);
1100 }
1101 catch (...)
1102 {
1103 if (Verbosity())
1104 {
1105 std::cerr << PHWHERE << "Failed to forward extrapolate from id " << id_min << " to disabled layer " << layer << std::endl;
1106 }
1107 continue;
1108 }
1109
1110
1111
1112 if (id > 0 && id < gftrack->getNumPointsWithMeasurement())
1113 try
1114 {
1115 auto trpoint = gftrack->getPointWithMeasurementAndFitterInfo(id, rep);
1116 if (!trpoint) continue;
1117
1118 auto kfi = static_cast<genfit::KalmanFitterInfo*>(trpoint->getFitterInfo(rep));
1119 genfit::KalmanFittedStateOnPlane gf_state_backward = *kfi->getBackwardUpdate();
1120 gf_state_backward.extrapolateToPlane(gf_state.getPlane());
1121 gf_state = genfit::calcAverageState(gf_state, gf_state_backward);
1122 }
1123 catch (...)
1124 {
1125 if (Verbosity())
1126 {
1127 std::cerr << PHWHERE << "Failed to backward extrapolate from id " << id << " to disabled layer " << layer << std::endl;
1128 }
1129 continue;
1130 }
1131
1132
1133 auto state = create_track_state(pathlength, &gf_state);
1134 state.set_cluskey(cluster_key);
1135 out_track->insert_state(&state);
1136 }
1137 }
1138
1139
1140 if (Verbosity())
1141 {
1142 for (auto&& iter = out_track->begin_states(); iter != out_track->end_states(); ++iter)
1143 {
1144 const auto& [pathlength, state] = *iter;
1145 const auto r = std::sqrt(square(state->get_x()) + square(state->get_y()));
1146 const auto phi = std::atan2(state->get_y(), state->get_x());
1147 std::cout << "PHGenFitTrkFitter::MakeSvtxTrack -"
1148 << " pathlength: " << pathlength
1149 << " radius: " << r
1150 << " phi: " << phi
1151 << " z: " << state->get_z()
1152 << std::endl;
1153 }
1154
1155 std::cout << std::endl;
1156 }
1157 return out_track;
1158 }
1159
1160
1161 bool PHGenFitTrkFitter::pos_cov_XYZ_to_RZ(
1162 const TVector3& n, const TMatrixF& pos_in, const TMatrixF& cov_in,
1163 TMatrixF& pos_out, TMatrixF& cov_out) const
1164 {
1165 if (pos_in.GetNcols() != 1 || pos_in.GetNrows() != 3)
1166 {
1167 if (Verbosity())
1168 {
1169 LogWarning("pos_in.GetNcols() != 1 || pos_in.GetNrows() != 3");
1170 }
1171 return false;
1172 }
1173
1174 if (cov_in.GetNcols() != 3 || cov_in.GetNrows() != 3)
1175 {
1176 if (Verbosity())
1177 {
1178 LogWarning("cov_in.GetNcols() != 3 || cov_in.GetNrows() != 3");
1179 }
1180 return false;
1181 }
1182
1183
1184
1185 TVector3 r = n.Cross(TVector3(0., 0., 1.));
1186 if (r.Mag() < 0.00001)
1187 {
1188 if (Verbosity())
1189 {
1190 LogWarning("n is parallel to z");
1191 }
1192 return false;
1193 }
1194
1195
1196 TMatrixF R(3, 3);
1197 TMatrixF R_T(3, 3);
1198
1199 try
1200 {
1201
1202 float phi = -TMath::ATan2(r.Y(), r.X());
1203 R[0][0] = cos(phi);
1204 R[0][1] = -sin(phi);
1205 R[0][2] = 0;
1206 R[1][0] = sin(phi);
1207 R[1][1] = cos(phi);
1208 R[1][2] = 0;
1209 R[2][0] = 0;
1210 R[2][1] = 0;
1211 R[2][2] = 1;
1212
1213 R_T.Transpose(R);
1214 }
1215 catch (...)
1216 {
1217 if (Verbosity())
1218 {
1219 LogWarning("Can't get rotation matrix");
1220 }
1221
1222 return false;
1223 }
1224
1225 pos_out.ResizeTo(3, 1);
1226 cov_out.ResizeTo(3, 3);
1227
1228 pos_out = R * pos_in;
1229 cov_out = R * cov_in * R_T;
1230
1231 return true;
1232 }