File indexing completed on 2025-08-06 08:18:31
0001
0002
0003
0004
0005
0006
0007
0008 #include "PHRaveVertexing.h"
0009
0010 #include <trackbase_historic/SvtxTrack.h>
0011 #include <trackbase_historic/SvtxTrackMap.h>
0012 #include <trackbase_historic/SvtxTrackState.h> // for SvtxTrackState
0013 #include <globalvertex/SvtxVertexMap_v1.h>
0014 #include <globalvertex/SvtxVertex_v1.h>
0015
0016 #include <g4main/PHG4TruthInfoContainer.h>
0017
0018 #include <phgenfit/Fitter.h>
0019
0020 #include <phfield/PHFieldUtility.h>
0021
0022 #include <phgeom/PHGeomUtility.h>
0023
0024 #include <fun4all/Fun4AllReturnCodes.h>
0025 #include <fun4all/SubsysReco.h> // for SubsysReco
0026
0027 #include <phool/PHCompositeNode.h>
0028 #include <phool/PHIODataNode.h>
0029 #include <phool/PHNode.h> // for PHNode
0030 #include <phool/PHNodeIterator.h>
0031 #include <phool/PHObject.h> // for PHObject
0032 #include <phool/PHTimer.h>
0033 #include <phool/getClass.h>
0034 #include <phool/phool.h>
0035
0036 #include <GenFit/FitStatus.h> // for FitStatus
0037 #include <GenFit/GFRaveTrackParameters.h> // for GFRaveTrackParameters
0038 #include <GenFit/GFRaveVertex.h>
0039 #include <GenFit/GFRaveVertexFactory.h>
0040 #include <GenFit/KalmanFittedStateOnPlane.h> // for KalmanFittedStateOn...
0041 #include <GenFit/KalmanFitterInfo.h>
0042 #include <GenFit/MeasuredStateOnPlane.h>
0043 #include <GenFit/RKTrackRep.h>
0044 #include <GenFit/Track.h>
0045 #include <GenFit/TrackPoint.h> // for TrackPoint
0046
0047 #include <TMatrixDSymfwd.h> // for TMatrixDSym
0048 #include <TMatrixTSym.h> // for TMatrixTSym
0049 #include <TMatrixTUtils.h> // for TMatrixTRow
0050 #include <TVector3.h>
0051
0052 #include <iostream>
0053 #include <map>
0054 #include <memory>
0055 #include <utility>
0056 #include <vector>
0057
0058 class PHField;
0059 class TGeoManager;
0060 namespace genfit { class AbsTrackRep; }
0061
0062 #define LogDebug(exp) std::cout << "DEBUG: " << __FILE__ << ": " << __LINE__ << ": " << exp << std::endl
0063 #define LogError(exp) std::cout << "ERROR: " << __FILE__ << ": " << __LINE__ << ": " << exp << std::endl
0064 #define LogWarning(exp) std::cout << "WARNING: " << __FILE__ << ": " << __LINE__ << ": " << exp << std::endl
0065
0066
0067
0068 using namespace std;
0069
0070
0071
0072
0073 PHRaveVertexing::PHRaveVertexing(const string& name)
0074 : SubsysReco(name)
0075 , _over_write_svtxvertexmap(false)
0076 , _svtxvertexmaprefit_node_name("SvtxVertexMapRefit")
0077 , _fitter(nullptr)
0078 , _primary_pid_guess(211)
0079 , _vertex_min_ndf(20)
0080 , _vertex_finder(nullptr)
0081 , _vertexing_method("avf-smoothing:1")
0082 , _trackmap(nullptr)
0083 , _vertexmap(nullptr)
0084 , _vertexmap_refit(nullptr)
0085 , _t_translate(nullptr)
0086 , _t_rave(nullptr)
0087 {
0088 Verbosity(0);
0089
0090 _event = 0;
0091 }
0092
0093
0094
0095
0096 int PHRaveVertexing::Init(PHCompositeNode* )
0097 {
0098 return Fun4AllReturnCodes::EVENT_OK;
0099 }
0100
0101
0102
0103
0104 int PHRaveVertexing::InitRun(PHCompositeNode* topNode)
0105 {
0106 CreateNodes(topNode);
0107
0108 TGeoManager* tgeo_manager = PHGeomUtility::GetTGeoManager(topNode);
0109 PHField* field = PHFieldUtility::GetFieldMapNode(nullptr, topNode);
0110
0111
0112 _fitter = PHGenFit::Fitter::getInstance(tgeo_manager,
0113 field, "DafRef",
0114 "RKTrackRep", false);
0115 if (!_fitter)
0116 {
0117 std::cout << PHWHERE << " PHGenFit::Fitter::getInstance returned nullptr"
0118 << std::endl;
0119 return Fun4AllReturnCodes::ABORTRUN;
0120 }
0121 _fitter->set_verbosity(Verbosity());
0122
0123 if (!_fitter)
0124 {
0125 cerr << PHWHERE << endl;
0126 return Fun4AllReturnCodes::ABORTRUN;
0127 }
0128
0129 _vertex_finder = new genfit::GFRaveVertexFactory(Verbosity());
0130 if (!_vertex_finder)
0131 {
0132 std::cout << PHWHERE << " genfit::GFRaveVertexFactory returned null ptr" << std::endl;
0133 return Fun4AllReturnCodes::ABORTRUN;
0134 }
0135 _vertex_finder->setMethod(_vertexing_method.data());
0136
0137
0138
0139 _t_translate = new PHTimer("_t_translate");
0140 _t_translate->stop();
0141
0142 _t_rave = new PHTimer("_t_rave");
0143 _t_rave->stop();
0144
0145 return Fun4AllReturnCodes::EVENT_OK;
0146 }
0147
0148
0149
0150
0151
0152
0153 int PHRaveVertexing::process_event(PHCompositeNode* topNode)
0154 {
0155 _event++;
0156
0157 if (Verbosity() > 1)
0158 std::cout << PHWHERE << "Events processed: " << _event << std::endl;
0159
0160 GetNodes(topNode);
0161
0162
0163 GenFitTrackMap gf_track_map;
0164 vector<genfit::Track*> gf_tracks;
0165 if (Verbosity() > 1) _t_translate->restart();
0166 for (SvtxTrackMap::Iter iter = _trackmap->begin(); iter != _trackmap->end();
0167 ++iter)
0168 {
0169 SvtxTrack* svtx_track = iter->second;
0170 if (!svtx_track)
0171 continue;
0172
0173 if (!(svtx_track->get_ndf() >= _vertex_min_ndf))
0174 continue;
0175
0176
0177 if(_nmvtx_required > 0)
0178 {
0179 unsigned int nmvtx = 0;
0180 for(auto clusit = svtx_track->begin_cluster_keys(); clusit != svtx_track->end_cluster_keys(); ++clusit)
0181 {
0182 if(TrkrDefs::getTrkrId(*clusit) == TrkrDefs::mvtxId )
0183 {
0184 nmvtx++;
0185 }
0186 if(nmvtx >= _nmvtx_required) break;
0187 }
0188 if(nmvtx < _nmvtx_required) continue;
0189 if(Verbosity() > 1) std::cout << " track " << iter->first << " has nmvtx at least " << nmvtx << std::endl;
0190 }
0191
0192
0193 auto genfit_track = TranslateSvtxToGenFitTrack(svtx_track);
0194 if (!genfit_track)
0195 continue;
0196 gf_track_map.insert({genfit_track, iter->first});
0197 gf_tracks.push_back(const_cast<genfit::Track*>(genfit_track));
0198 }
0199 if (Verbosity() > 1) _t_translate->stop();
0200
0201 if (Verbosity() > 1) _t_rave->restart();
0202 vector<genfit::GFRaveVertex*> rave_vertices;
0203 if (gf_tracks.size() >= 2)
0204 {
0205 try
0206 {
0207 _vertex_finder->findVertices(&rave_vertices, gf_tracks);
0208 }
0209 catch (...)
0210 {
0211 if (Verbosity() > 1)
0212 std::cout << PHWHERE << "GFRaveVertexFactory::findVertices failed!";
0213 }
0214 }
0215 if (Verbosity() > 1) _t_rave->stop();
0216 FillSvtxVertexMap(rave_vertices, gf_track_map);
0217
0218 for (auto iter : gf_track_map) delete iter.first;
0219
0220 if (Verbosity() > 1)
0221 {
0222 _vertexmap->identify();
0223
0224 std::cout << "=============== Timers: ===============" << std::endl;
0225 std::cout << "Event: " << _event << std::endl;
0226 std::cout << "Translate: " << _t_translate->get_accumulated_time() / 1000. << " sec" << std::endl;
0227 std::cout << "RAVE: " << _t_rave->get_accumulated_time() / 1000. << " sec" << std::endl;
0228 std::cout << "=======================================" << std::endl;
0229 }
0230
0231 return Fun4AllReturnCodes::EVENT_OK;
0232 }
0233
0234
0235
0236
0237 int PHRaveVertexing::End(PHCompositeNode* )
0238 {
0239 return Fun4AllReturnCodes::EVENT_OK;
0240 }
0241
0242
0243
0244
0245 PHRaveVertexing::~PHRaveVertexing()
0246 {
0247 delete _fitter;
0248 delete _vertex_finder;
0249 }
0250
0251 int PHRaveVertexing::CreateNodes(PHCompositeNode* topNode)
0252 {
0253
0254 PHNodeIterator iter(topNode);
0255
0256 PHCompositeNode* dstNode = static_cast<PHCompositeNode*>(iter.findFirst(
0257 "PHCompositeNode", "DST"));
0258 if (!dstNode)
0259 {
0260 cerr << PHWHERE << "DST Node missing, doing nothing." << endl;
0261 return Fun4AllReturnCodes::ABORTEVENT;
0262 }
0263 PHNodeIterator iter_dst(dstNode);
0264
0265
0266 PHCompositeNode* tb_node = dynamic_cast<PHCompositeNode*>(iter_dst.findFirst(
0267 "PHCompositeNode", "SVTX"));
0268 if (!tb_node)
0269 {
0270 tb_node = new PHCompositeNode("SVTX");
0271 dstNode->addNode(tb_node);
0272 if (Verbosity() > 0)
0273 cout << "SVTX node added" << endl;
0274 }
0275
0276 if (!(_over_write_svtxvertexmap))
0277 {
0278 _vertexmap_refit = new SvtxVertexMap_v1;
0279 PHIODataNode<PHObject>* vertexes_node = new PHIODataNode<PHObject>(
0280 _vertexmap_refit, _svtxvertexmaprefit_node_name.c_str(), "PHObject");
0281 tb_node->addNode(vertexes_node);
0282 if (Verbosity() > 0)
0283 cout << "Svtx/SvtxVertexMapRefit node added" << endl;
0284 }
0285 else if (!findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap"))
0286 {
0287 _vertexmap = new SvtxVertexMap_v1;
0288 PHIODataNode<PHObject>* vertexes_node = new PHIODataNode<PHObject>(
0289 _vertexmap, "SvtxVertexMap", "PHObject");
0290 tb_node->addNode(vertexes_node);
0291 if (Verbosity() > 0)
0292 cout << "Svtx/SvtxVertexMap node added" << endl;
0293 }
0294
0295 return Fun4AllReturnCodes::EVENT_OK;
0296 }
0297
0298
0299
0300
0301
0302 int PHRaveVertexing::GetNodes(PHCompositeNode* topNode)
0303 {
0304
0305
0306 _trackmap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0307 if (!_trackmap && _event < 2)
0308 {
0309 cout << PHWHERE << " SvtxTrackMap node not found on node tree"
0310 << endl;
0311 return Fun4AllReturnCodes::ABORTEVENT;
0312 }
0313
0314
0315 _vertexmap = findNode::getClass<SvtxVertexMap>(topNode, "SvtxVertexMap");
0316 if (!_vertexmap && _event < 2)
0317 {
0318 cout << PHWHERE << " SvtxVertexrMap node not found on node tree"
0319 << endl;
0320 return Fun4AllReturnCodes::ABORTEVENT;
0321 }
0322
0323
0324 if (!(_over_write_svtxvertexmap))
0325 {
0326 _vertexmap_refit = findNode::getClass<SvtxVertexMap>(topNode,
0327 _svtxvertexmaprefit_node_name.c_str());
0328 if (!_vertexmap_refit && _event < 2)
0329 {
0330 cout << PHWHERE << " SvtxVertexMapRefit node not found on node tree"
0331 << endl;
0332 return Fun4AllReturnCodes::ABORTEVENT;
0333 }
0334 }
0335
0336 return Fun4AllReturnCodes::EVENT_OK;
0337 }
0338
0339
0340
0341
0342 bool PHRaveVertexing::FillSvtxVertexMap(
0343 const std::vector<genfit::GFRaveVertex*>& rave_vertices,
0344 const GenFitTrackMap& gf_track_map)
0345 {
0346 if (_over_write_svtxvertexmap)
0347 {
0348 _vertexmap->clear();
0349 }
0350
0351
0352
0353
0354 for (genfit::GFRaveVertex* rave_vtx : rave_vertices)
0355 {
0356 if (!rave_vtx)
0357 {
0358 cerr << PHWHERE << endl;
0359 return false;
0360 }
0361
0362 std::shared_ptr<SvtxVertex> svtx_vtx(new SvtxVertex_v1());
0363
0364 svtx_vtx->set_chisq(rave_vtx->getChi2());
0365 svtx_vtx->set_ndof(rave_vtx->getNdf());
0366 svtx_vtx->set_position(0, rave_vtx->getPos().X());
0367 svtx_vtx->set_position(1, rave_vtx->getPos().Y());
0368 svtx_vtx->set_position(2, rave_vtx->getPos().Z());
0369
0370 for (int i = 0; i < 3; i++)
0371 for (int j = 0; j < 3; j++)
0372 svtx_vtx->set_error(i, j, rave_vtx->getCov()[i][j]);
0373
0374 for (unsigned int i = 0; i < rave_vtx->getNTracks(); i++)
0375 {
0376
0377 const genfit::Track* rave_track =
0378 rave_vtx->getParameters(i)->getTrack();
0379
0380
0381
0382
0383 auto iter = gf_track_map.find(rave_track);
0384 if (iter != gf_track_map.end())
0385 svtx_vtx->insert_track(iter->second);
0386 }
0387
0388 if (_over_write_svtxvertexmap)
0389 {
0390 if (_vertexmap)
0391 {
0392 _vertexmap->insert_clone(svtx_vtx.get());
0393 }
0394 else
0395 {
0396 LogError("!_vertexmap");
0397 }
0398 }
0399 else
0400 {
0401 if (_vertexmap_refit)
0402 {
0403 _vertexmap_refit->insert_clone(svtx_vtx.get());
0404 }
0405 else
0406 {
0407 LogError("!_vertexmap_refit");
0408 }
0409 }
0410
0411 #ifdef _DEBUG_
0412 cout << __LINE__ << endl;
0413 svtx_vtx->identify();
0414 #endif
0415
0416 }
0417
0418 return true;
0419 }
0420
0421 genfit::Track* PHRaveVertexing::TranslateSvtxToGenFitTrack(SvtxTrack* svtx_track)
0422 {
0423 try
0424 {
0425
0426 SvtxTrackState* svtx_state(nullptr);
0427
0428
0429 if (svtx_track->begin_states() == svtx_track->end_states())
0430 {
0431 LogDebug("TranslateSvtxToGenFitTrack no state in track!");
0432 return nullptr;
0433 }
0434 else if (++(svtx_track->begin_states()) == svtx_track->end_states())
0435 {
0436
0437 svtx_state = (svtx_track->begin_states())->second;
0438 }
0439 else
0440 {
0441
0442
0443 svtx_state = (++(svtx_track->begin_states()))->second;
0444 }
0445
0446 if (!svtx_state)
0447 {
0448 LogDebug("TranslateSvtxToGenFitTrack invalid state found on track!");
0449 return nullptr;
0450 }
0451
0452 TVector3 pos(svtx_state->get_x(), svtx_state->get_y(), svtx_state->get_z());
0453 TVector3 mom(svtx_state->get_px(), svtx_state->get_py(), svtx_state->get_pz());
0454 TMatrixDSym cov(6);
0455 for (int i = 0; i < 6; ++i)
0456 {
0457 for (int j = 0; j < 6; ++j)
0458 {
0459 cov[i][j] = svtx_state->get_error(i, j);
0460 }
0461 }
0462
0463 #ifdef _DEBUG_
0464 {
0465 cout << "DEBUG" << __LINE__ << endl;
0466 cout << "path length: " << svtx_state->get_pathlength() << endl;
0467 cout << "radius: " << pos.Perp() << endl;
0468 cout << "DEBUG: " << __LINE__ << endl;
0469 for (int i = 0; i < 6; ++i)
0470 {
0471 for (int j = 0; j < 6; ++j)
0472 {
0473 cout << svtx_state->get_error(i, j) << "\t";
0474 }
0475 cout << endl;
0476 }
0477
0478 cov.Print();
0479 }
0480
0481 #endif
0482
0483 genfit::AbsTrackRep* rep = new genfit::RKTrackRep(_primary_pid_guess);
0484 genfit::Track* genfit_track = new genfit::Track(rep, TVector3(0, 0, 0), TVector3(0, 0, 0));
0485
0486 genfit::FitStatus* fs = new genfit::FitStatus();
0487 fs->setCharge(svtx_track->get_charge());
0488 fs->setChi2(svtx_track->get_chisq());
0489 fs->setNdf(svtx_track->get_ndf());
0490 fs->setIsFitted(true);
0491 fs->setIsFitConvergedFully(true);
0492
0493 genfit_track->setFitStatus(fs, rep);
0494
0495 genfit::TrackPoint* tp = new genfit::TrackPoint(genfit_track);
0496
0497 genfit::KalmanFitterInfo* fi = new genfit::KalmanFitterInfo(tp, rep);
0498 tp->setFitterInfo(fi);
0499
0500 genfit::MeasuredStateOnPlane* ms = new genfit::MeasuredStateOnPlane(rep);
0501 ms->setPosMomCov(pos, mom, cov);
0502 #ifdef _DEBUG_
0503 {
0504 cout << "DEBUG: " << __LINE__ << endl;
0505 ms->Print();
0506 cout << "Orig: " << __LINE__ << endl;
0507 cov.Print();
0508 cout << "Translate: " << __LINE__ << endl;
0509 ms->get6DCov().Print();
0510 }
0511 #endif
0512 genfit::KalmanFittedStateOnPlane* kfs = new genfit::KalmanFittedStateOnPlane(*ms, 1., 1.);
0513
0514
0515 fi->setForwardUpdate(kfs);
0516
0517 genfit_track->insertPoint(tp);
0518
0519 #ifdef _DEBUG_
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529 #endif
0530
0531 return genfit_track;
0532 }
0533 catch (...)
0534 {
0535 LogDebug("TranslateSvtxToGenFitTrack failed!");
0536 }
0537
0538 return nullptr;
0539 }