File indexing completed on 2025-12-17 09:20:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include "KFParticle_Tools.h"
0029
0030 #include <trackbase_historic/SvtxTrack.h>
0031 #include <trackbase_historic/SvtxTrackMap.h>
0032 #include <trackbase_historic/TrackAnalysisUtils.h>
0033
0034 #include <trackbase/TrkrClusterContainer.h>
0035 #include <trackbase/TrkrCluster.h>
0036 #include <trackbase/TrkrDefs.h>
0037 #include <g4detectors/PHG4TpcGeom.h>
0038 #include <g4detectors/PHG4TpcGeomContainer.h>
0039
0040 #include <globalvertex/GlobalVertex.h>
0041 #include <globalvertex/GlobalVertexMap.h>
0042 #include <globalvertex/SvtxVertex.h>
0043 #include <globalvertex/SvtxVertexMap.h>
0044
0045 #include <phool/getClass.h>
0046
0047 #include <ffamodules/CDBInterface.h>
0048
0049
0050 #include <KFParticle.h>
0051 #include <KFVertex.h>
0052
0053 #include <Rtypes.h>
0054 #include <TDatabasePDG.h>
0055 #include <TMatrixD.h>
0056 #include "KFParticle_truthAndDetTools.h"
0057
0058 #include <TFile.h>
0059 #include <TMatrixDfwd.h> // for TMatrixD
0060 #include <TMatrixT.h> // for TMatrixT, operator*
0061
0062 #include <Eigen/Dense>
0063
0064 #include <algorithm> // for max, remove, minmax_el...
0065 #include <cmath> // for sqrt, pow, M_PI
0066 #include <cstdlib> // for abs, NULL
0067 #include <iostream> // for operator<<, basic_ostream
0068 #include <iterator> // for end
0069 #include <map> // for _Rb_tree_iterator, map
0070 #include <memory> // for allocator_traits<>::va...
0071
0072 KFParticle_truthAndDetTools toolSet;
0073
0074
0075 KFParticle_Tools::KFParticle_Tools()
0076 : m_has_intermediates(false)
0077 , m_min_mass(0)
0078 , m_max_mass(0)
0079 , m_min_decayTime(-1 * FLT_MAX)
0080 , m_max_decayTime(FLT_MAX)
0081 , m_min_decayLength(-1 * FLT_MAX)
0082 , m_max_decayLength(FLT_MAX)
0083 , m_track_min_pt(0.)
0084 , m_track_max_pt(5e3)
0085 , m_track_ptchi2(FLT_MAX)
0086 , m_track_ip_xy(-100.)
0087 , m_track_ipchi2_xy(-1)
0088 , m_track_ip(-1.)
0089 , m_track_ipchi2(-1)
0090 , m_track_chi2ndof(100.)
0091 , m_nMVTXStates(3)
0092 , m_nINTTStates(1)
0093 , m_nTPCStates(20)
0094 , m_nTPOTStates(0)
0095 , m_comb_DCA_xy(1)
0096 , m_comb_DCA(0.5)
0097 , m_vertex_chi2ndof(20.)
0098 , m_fdchi2(0.)
0099 , m_dira_min(-1.01)
0100 , m_dira_max(1.01)
0101 , m_mother_pt(0.)
0102 , m_mother_ipchi2(FLT_MAX)
0103 , m_get_charge_conjugate(false)
0104 , m_extrapolateTracksToSV(true)
0105 , m_vtx_map_node_name("SvtxVertexMap")
0106 , m_trk_map_node_name("SvtxTrackMap")
0107 , m_dst_mbdvertexmap()
0108 , m_dst_mbdvertex()
0109 , m_dst_trackmap()
0110 , m_dst_track()
0111 , m_dst_vertexmap()
0112 , m_dst_vertex()
0113 , m_cluster_map()
0114 , m_geom_container()
0115 {
0116 }
0117
0118 KFParticle KFParticle_Tools::makeVertex(PHCompositeNode * )
0119 {
0120 float vtxX = m_use_mbd_vertex ? 0 : m_dst_vertex->get_x();
0121 float vtxY = m_use_mbd_vertex ? 0 : m_dst_vertex->get_y();
0122 float vtxZ = m_use_mbd_vertex ? m_dst_mbdvertex->get_z() : m_dst_vertex->get_z();
0123
0124 float f_vertexParameters[6] = {vtxX, vtxY, vtxZ, 0, 0, 0};
0125
0126 float f_vertexCovariance[21] = {0};
0127 unsigned int iterate = 0;
0128 if (m_use_mbd_vertex)
0129 {
0130 f_vertexCovariance[5] = m_dst_mbdvertex->get_z_err();
0131 }
0132 else
0133 {
0134 for (unsigned int i = 0; i < 3; ++i)
0135 {
0136 for (unsigned int j = 0; j <= i; ++j)
0137 {
0138 f_vertexCovariance[iterate] = m_dst_vertex->get_error(i, j);
0139 ++iterate;
0140 }
0141 }
0142 }
0143
0144 KFParticle kfp_vertex;
0145 kfp_vertex.Create(f_vertexParameters, f_vertexCovariance, 0, -1);
0146 kfp_vertex.NDF() = m_use_mbd_vertex ? 0 : m_dst_vertex->get_ndof();
0147 kfp_vertex.Chi2() = m_use_mbd_vertex ? 0 : m_dst_vertex->get_chisq();
0148
0149 return kfp_vertex;
0150 }
0151
0152 std::vector<KFParticle> KFParticle_Tools::makeAllPrimaryVertices(PHCompositeNode *topNode, const std::string &vertexMapName)
0153 {
0154 std::string vtxMN;
0155
0156 unsigned int vertexID = 0;
0157
0158 if (vertexMapName.empty())
0159 {
0160 vtxMN = m_vtx_map_node_name;
0161 }
0162 else
0163 {
0164 vtxMN = vertexMapName;
0165 }
0166
0167 std::vector<KFParticle> primaryVertices;
0168
0169 if (m_use_mbd_vertex)
0170 {
0171 m_dst_mbdvertexmap = findNode::getClass<MbdVertexMap>(topNode, "MbdVertexMap");
0172 }
0173 else
0174 {
0175 m_dst_vertexmap = findNode::getClass<SvtxVertexMap>(topNode, vtxMN);
0176 }
0177
0178 if (m_dont_use_global_vertex)
0179 {
0180 if (m_use_mbd_vertex)
0181 {
0182 for (MbdVertexMap::ConstIter iter = m_dst_mbdvertexmap->begin(); iter != m_dst_mbdvertexmap->end(); ++iter)
0183 {
0184 m_dst_mbdvertex = iter->second;
0185 primaryVertices.push_back(makeVertex(topNode));
0186 primaryVertices[vertexID].SetId(iter->first);
0187 ++vertexID;
0188 }
0189 }
0190 else
0191 {
0192 for (SvtxVertexMap::ConstIter iter = m_dst_vertexmap->begin(); iter != m_dst_vertexmap->end(); ++iter)
0193 {
0194 m_dst_vertex = iter->second;
0195 primaryVertices.push_back(makeVertex(topNode));
0196 primaryVertices[vertexID].SetId(iter->first);
0197 ++vertexID;
0198 }
0199 }
0200
0201 return primaryVertices;
0202 }
0203
0204 m_dst_globalvertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0205 if (!m_dst_globalvertexmap)
0206 {
0207 std::cout << "Can't continue in KFParticle_Tools::makeAllPrimaryVertices" << std::endl;
0208 return primaryVertices;
0209 }
0210
0211 for (GlobalVertexMap::ConstIter iter = m_dst_globalvertexmap->begin(); iter != m_dst_globalvertexmap->end(); ++iter)
0212 {
0213 m_dst_globalvertex = iter->second;
0214
0215 GlobalVertex::VTXTYPE whichVtx = m_use_mbd_vertex ? GlobalVertex::MBD : GlobalVertex::SVTX;
0216
0217 auto svtxiter = m_dst_globalvertex->find_vertexes(whichVtx);
0218
0219 if (svtxiter == m_dst_globalvertex->end_vertexes())
0220 {
0221 continue;
0222 }
0223
0224 auto svtxvertexvector = svtxiter->second;
0225
0226 for (auto &vertex : svtxvertexvector)
0227 {
0228 if (m_use_mbd_vertex)
0229 {
0230 m_dst_mbdvertex = m_dst_mbdvertexmap->find(vertex->get_id())->second;
0231 }
0232 else
0233 {
0234 m_dst_vertex = m_dst_vertexmap->find(vertex->get_id())->second;
0235 }
0236
0237 primaryVertices.push_back(makeVertex(topNode));
0238 primaryVertices[vertexID].SetId(m_dst_globalvertex->get_id());
0239 ++vertexID;
0240 }
0241 }
0242
0243 return primaryVertices;
0244 }
0245
0246 KFParticle KFParticle_Tools::makeParticle(PHCompositeNode * )
0247 {
0248 KFParticle kfp_particle;
0249
0250 float f_trackParameters[6] = {m_dst_track->get_x(),
0251 m_dst_track->get_y(),
0252 m_dst_track->get_z(),
0253 m_dst_track->get_px(),
0254 m_dst_track->get_py(),
0255 m_dst_track->get_pz()};
0256
0257 float f_trackCovariance[21];
0258 unsigned int iterate = 0;
0259 for (unsigned int i = 0; i < 6; ++i)
0260 {
0261 for (unsigned int j = 0; j <= i; ++j)
0262 {
0263 f_trackCovariance[iterate] = m_dst_track->get_error(i, j);
0264 ++iterate;
0265 }
0266 }
0267
0268 kfp_particle.Create(f_trackParameters, f_trackCovariance, (Int_t) m_dst_track->get_charge(), -1);
0269 kfp_particle.NDF() = m_dst_track->get_ndf();
0270 kfp_particle.Chi2() = m_dst_track->get_chisq();
0271 kfp_particle.SetId(m_dst_track->get_id());
0272
0273 return kfp_particle;
0274 }
0275
0276 std::vector<KFParticle> KFParticle_Tools::makeAllDaughterParticles(PHCompositeNode *topNode)
0277 {
0278 std::vector<KFParticle> daughterParticles;
0279 m_dst_trackmap = findNode::getClass<SvtxTrackMap>(topNode, m_trk_map_node_name.c_str());
0280 unsigned int trackID = 0;
0281
0282 for (auto &iter : *m_dst_trackmap)
0283 {
0284 m_dst_track = iter.second;
0285
0286 if (m_bunch_crossing_zero_only && (m_dst_track->get_crossing() != 0))
0287 {
0288 continue;
0289 }
0290
0291
0292 int MVTX_states = 0;
0293 int INTT_states = 0;
0294 int TPC_states = 0;
0295 int TPOT_states = 0;
0296
0297 for (auto state_iter = m_dst_track->begin_states();
0298 state_iter != m_dst_track->end_states();
0299 ++state_iter)
0300 {
0301 SvtxTrackState* tstate = state_iter->second;
0302 if (tstate->get_pathlength() != 0)
0303 {
0304 auto stateckey = tstate->get_cluskey();
0305 uint8_t id = TrkrDefs::getTrkrId(stateckey);
0306
0307 switch (id)
0308 {
0309 case TrkrDefs::mvtxId:
0310 ++MVTX_states;
0311 break;
0312 case TrkrDefs::inttId:
0313 ++INTT_states;
0314 break;
0315 case TrkrDefs::tpcId:
0316 ++TPC_states;
0317 break;
0318 case TrkrDefs::micromegasId:
0319 ++TPOT_states;
0320 break;
0321 default:
0322
0323 break;
0324 }
0325 }
0326 }
0327
0328 if (MVTX_states < m_nMVTXStates)
0329 {
0330 continue;
0331 }
0332 if (INTT_states < m_nINTTStates)
0333 {
0334 continue;
0335 }
0336 if (TPC_states < m_nTPCStates)
0337 {
0338 continue;
0339 }
0340 if (TPOT_states < m_nTPOTStates)
0341 {
0342 continue;
0343 }
0344
0345 daughterParticles.push_back(makeParticle(topNode));
0346 daughterParticles[trackID].SetId(iter.first);
0347 ++trackID;
0348 }
0349
0350 return daughterParticles;
0351 }
0352
0353 void KFParticle_Tools::getTracksFromBC(PHCompositeNode *topNode, const int &bunch_crossing, const std::string &vertexMapName, int &nTracks, int &nPVs)
0354 {
0355 if (m_use_mbd_vertex)
0356 {
0357 return;
0358 }
0359
0360 std::string vtxMN;
0361 if (vertexMapName.empty())
0362 {
0363 vtxMN = m_vtx_map_node_name;
0364 }
0365 else
0366 {
0367 vtxMN = vertexMapName;
0368 }
0369
0370 nTracks = 0;
0371 nPVs = 0;
0372 m_dst_vertexmap = findNode::getClass<SvtxVertexMap>(topNode, vtxMN);
0373 for (SvtxVertexMap::ConstIter iter = m_dst_vertexmap->begin(); iter != m_dst_vertexmap->end(); ++iter)
0374 {
0375 m_dst_vertex = iter->second;
0376 if ((int) m_dst_vertex->get_beam_crossing() == bunch_crossing)
0377 {
0378 nTracks += m_dst_vertex->size_tracks();
0379 ++nPVs;
0380 }
0381 }
0382 }
0383
0384 int KFParticle_Tools::getTracksFromVertex(PHCompositeNode *topNode, const KFParticle &vertex, const std::string &vertexMapName)
0385 {
0386 if (m_use_mbd_vertex)
0387 {
0388 return 0;
0389 }
0390
0391 std::string vtxMN;
0392 if (vertexMapName.empty())
0393 {
0394 vtxMN = m_vtx_map_node_name;
0395 }
0396 else
0397 {
0398 vtxMN = vertexMapName;
0399 }
0400
0401 SvtxVertex* associated_vertex = nullptr;
0402 if (m_dont_use_global_vertex)
0403 {
0404 m_dst_vertexmap = findNode::getClass<SvtxVertexMap>(topNode, vtxMN);
0405 associated_vertex = m_dst_vertexmap->get(vertex.Id());
0406 }
0407 else
0408 {
0409 m_dst_globalvertexmap = findNode::getClass<GlobalVertexMap>(topNode, "GlobalVertexMap");
0410 if (!m_dst_globalvertexmap)
0411 {
0412 std::cout << "Can't continue in KFParticle_Tools::makeAllPrimaryVertices" << std::endl;
0413 return 0;
0414 }
0415 auto associated_gvertex = m_dst_globalvertexmap->get(vertex.Id());
0416
0417 auto svtxiter = associated_gvertex->find_vertexes(GlobalVertex::SVTX);
0418 auto svtxvertexvector = svtxiter->second;
0419
0420 for (auto &gvertex : svtxvertexvector)
0421 {
0422 associated_vertex = m_dst_vertexmap->find(gvertex->get_id())->second;
0423 }
0424 }
0425 if (associated_vertex)
0426 {
0427 return associated_vertex->size_tracks();
0428 }
0429 else
0430 {
0431 return 0;
0432 }
0433 }
0434
0435 bool KFParticle_Tools::isGoodTrack(const KFParticle &particle, const std::vector<KFParticle> &primaryVertices)
0436 {
0437 bool goodTrack = false;
0438
0439 float min_ip = 0;
0440 float min_ipchi2 = 0;
0441 float min_ip_xy = 0;
0442 float min_ipchi2_xy = 0;
0443
0444 float pt = particle.GetPt();
0445 float pterr = particle.GetErrPt();
0446 float ptchi2 = pow(pterr / pt, 2);
0447 float trackchi2ndof = particle.GetChi2() / particle.GetNDF();
0448 calcMinIP(particle, primaryVertices, min_ip, min_ipchi2);
0449 calcMinIP(particle, primaryVertices, min_ip_xy, min_ipchi2_xy, false);
0450
0451 if (isInRange(m_track_min_pt, pt, m_track_max_pt)
0452 && ptchi2 <= m_track_ptchi2
0453 && min_ip >= m_track_ip
0454 && min_ipchi2 >= m_track_ipchi2
0455 && min_ip_xy >= m_track_ip_xy
0456 && min_ipchi2_xy >= m_track_ipchi2_xy
0457 && trackchi2ndof <= m_track_chi2ndof)
0458 {
0459 goodTrack = true;
0460 }
0461 return goodTrack;
0462 }
0463
0464 int KFParticle_Tools::calcMinIP(const KFParticle &track, const std::vector<KFParticle> &PVs,
0465 float &minimumIP, float &minimumIPchi2, bool do3D)
0466 {
0467 std::vector<float> ip, ipchi2;
0468
0469 for (const auto &PV : PVs)
0470 {
0471 float thisIPchi2 = 0;
0472
0473 if (do3D)
0474 {
0475 ip.push_back(track.GetDistanceFromVertex(PV));
0476 track.GetDeviationFromVertex(PV);
0477 }
0478 else
0479 {
0480 ip.push_back(abs(track.GetDistanceFromVertexXY(PV)));
0481 track.GetDeviationFromVertexXY(PV);
0482 }
0483
0484 if (thisIPchi2 < 0)
0485 {
0486 thisIPchi2 = 0;
0487 }
0488 ipchi2.push_back(thisIPchi2);
0489 }
0490
0491 auto minmax_ip = minmax_element(ip.begin(), ip.end());
0492 minimumIP = *minmax_ip.first;
0493 auto minmax_ipchi2 = minmax_element(ipchi2.begin(), ipchi2.end());
0494 minimumIPchi2 = *minmax_ipchi2.first;
0495
0496 return 0;
0497 }
0498
0499 std::vector<int> KFParticle_Tools::findAllGoodTracks(const std::vector<KFParticle> &daughterParticles, const std::vector<KFParticle> &primaryVertices)
0500 {
0501 std::vector<int> goodTrackIndex;
0502
0503 for (unsigned int i_parts = 0; i_parts < daughterParticles.size(); ++i_parts)
0504 {
0505 if (isGoodTrack(daughterParticles[i_parts], primaryVertices))
0506 {
0507 goodTrackIndex.push_back(i_parts);
0508 }
0509 }
0510
0511 removeDuplicates(goodTrackIndex);
0512
0513 return goodTrackIndex;
0514 }
0515
0516 std::vector<std::vector<int>> KFParticle_Tools::findTwoProngs(std::vector<KFParticle> daughterParticles, std::vector<int> goodTrackIndex, int nTracks)
0517 {
0518 std::vector<std::vector<int>> goodTracksThatMeet;
0519
0520 for (std::vector<int>::iterator i_it = goodTrackIndex.begin(); i_it != goodTrackIndex.end(); ++i_it)
0521 {
0522 for (std::vector<int>::iterator j_it = goodTrackIndex.begin(); j_it != goodTrackIndex.end(); ++j_it)
0523 {
0524 if (i_it < j_it)
0525 {
0526 float dca = daughterParticles[*i_it].GetDistanceFromParticle(daughterParticles[*j_it]);
0527 float dca_xy = abs(daughterParticles[*i_it].GetDistanceFromParticleXY(daughterParticles[*j_it]));
0528
0529 if (dca <= m_comb_DCA && dca_xy <= m_comb_DCA_xy)
0530 {
0531 KFVertex twoParticleVertex;
0532 twoParticleVertex += daughterParticles[*i_it];
0533 twoParticleVertex += daughterParticles[*j_it];
0534 float vertexchi2ndof = twoParticleVertex.GetChi2() / twoParticleVertex.GetNDF();
0535 float sv_radial_position = sqrt(pow(twoParticleVertex.GetX(), 2) + pow(twoParticleVertex.GetY(), 2));
0536 std::vector<int> combination = {*i_it, *j_it};
0537
0538 if (nTracks == 2 && vertexchi2ndof > m_vertex_chi2ndof)
0539 {
0540 continue;
0541 }
0542 else
0543 {
0544 if (nTracks == 2 && sv_radial_position < m_min_radial_SV)
0545 {
0546 continue;
0547 }
0548 else
0549 {
0550 goodTracksThatMeet.push_back(combination);
0551 }
0552 }
0553 }
0554 }
0555 }
0556 }
0557
0558 return goodTracksThatMeet;
0559 }
0560
0561 std::vector<std::vector<int>> KFParticle_Tools::findNProngs(std::vector<KFParticle> daughterParticles,
0562 const std::vector<int> &goodTrackIndex,
0563 std::vector<std::vector<int>> goodTracksThatMeet,
0564 int nRequiredTracks, unsigned int nProngs)
0565 {
0566 unsigned int nGoodProngs = goodTracksThatMeet.size();
0567
0568 for (auto &i_it : goodTrackIndex)
0569 {
0570 for (unsigned int i_prongs = 0; i_prongs < nGoodProngs; ++i_prongs)
0571 {
0572 bool trackNotUsedAlready = true;
0573 for (unsigned int i_trackCheck = 0; i_trackCheck < nProngs - 1; ++i_trackCheck)
0574 {
0575 if (i_it == goodTracksThatMeet[i_prongs][i_trackCheck])
0576 {
0577 trackNotUsedAlready = false;
0578 }
0579 }
0580 if (trackNotUsedAlready)
0581 {
0582 bool dcaMet = true;
0583 for (unsigned int i = 0; i < nProngs - 1; ++i)
0584 {
0585 float dca = daughterParticles[i_it].GetDistanceFromParticle(daughterParticles[goodTracksThatMeet[i_prongs][i]]);
0586 float dca_xy = abs(daughterParticles[i_it].GetDistanceFromParticleXY(daughterParticles[goodTracksThatMeet[i_prongs][i]]));
0587
0588 if (dca > m_comb_DCA || dca_xy > m_comb_DCA_xy)
0589 {
0590 dcaMet = false;
0591 }
0592 }
0593
0594 if (dcaMet)
0595 {
0596 KFVertex particleVertex;
0597 particleVertex += daughterParticles[i_it];
0598 std::vector<int> combination;
0599 combination.push_back(i_it);
0600 for (unsigned int i = 0; i < nProngs - 1; ++i)
0601 {
0602 particleVertex += daughterParticles[goodTracksThatMeet[i_prongs][i]];
0603 combination.push_back(goodTracksThatMeet[i_prongs][i]);
0604 }
0605 float vertexchi2ndof = particleVertex.GetChi2() / particleVertex.GetNDF();
0606 float sv_radial_position = sqrt(pow(particleVertex.GetX(), 2) + pow(particleVertex.GetY(), 2));
0607
0608 if ((unsigned int) nRequiredTracks == nProngs && vertexchi2ndof > m_vertex_chi2ndof)
0609 {
0610 continue;
0611 }
0612 else
0613 {
0614 if ((unsigned int) nRequiredTracks == nProngs && sv_radial_position < m_min_radial_SV)
0615 {
0616 continue;
0617 }
0618 else
0619 {
0620 goodTracksThatMeet.push_back(combination);
0621 }
0622 }
0623 }
0624 }
0625 }
0626 }
0627
0628 goodTracksThatMeet.erase(goodTracksThatMeet.begin(), goodTracksThatMeet.begin() + nGoodProngs);
0629 for (auto &i : goodTracksThatMeet)
0630 {
0631 sort(i.begin(), i.end());
0632 }
0633 removeDuplicates(goodTracksThatMeet);
0634
0635 return goodTracksThatMeet;
0636 }
0637
0638 std::vector<std::vector<int>> KFParticle_Tools::appendTracksToIntermediates(KFParticle intermediateResonances[], const std::vector<KFParticle> &daughterParticles, const std::vector<int> &goodTrackIndex, int num_remaining_tracks)
0639 {
0640 std::vector<std::vector<int>> goodTracksThatMeet, goodTracksThatMeetIntermediates;
0641 if (num_remaining_tracks == 1)
0642 {
0643 for (auto &i_it : goodTrackIndex)
0644 {
0645 std::vector<KFParticle> v_intermediateResonances(intermediateResonances, intermediateResonances + m_num_intermediate_states);
0646 std::vector<std::vector<int>> dummyTrackList;
0647 std::vector<int> dummyTrackID;
0648 v_intermediateResonances.insert(end(v_intermediateResonances), daughterParticles[i_it]);
0649 for (unsigned int k = 0; k < v_intermediateResonances.size(); ++k)
0650 {
0651 dummyTrackID.push_back(k);
0652 }
0653 dummyTrackList = findTwoProngs(v_intermediateResonances, dummyTrackID, (int) v_intermediateResonances.size());
0654 if (v_intermediateResonances.size() > 2)
0655 {
0656 for (unsigned int p = 3; p <= v_intermediateResonances.size(); ++p)
0657 {
0658 dummyTrackList = findNProngs(v_intermediateResonances,
0659 dummyTrackID, dummyTrackList,
0660 (int) v_intermediateResonances.size(), (int) p);
0661 }
0662 }
0663
0664 if (dummyTrackList.size() != 0)
0665 {
0666 std::vector<int> goodTrack{i_it};
0667 goodTracksThatMeetIntermediates.push_back(goodTrack);
0668 }
0669 }
0670 }
0671 else
0672 {
0673 goodTracksThatMeet = findTwoProngs(daughterParticles, goodTrackIndex, num_remaining_tracks);
0674
0675 for (int p = 3; p <= num_remaining_tracks; ++p)
0676 {
0677 goodTracksThatMeet = findNProngs(daughterParticles, goodTrackIndex, goodTracksThatMeet, num_remaining_tracks, p);
0678 }
0679
0680 for (auto &i : goodTracksThatMeet)
0681 {
0682 std::vector<KFParticle> v_intermediateResonances(intermediateResonances, intermediateResonances + m_num_intermediate_states);
0683 std::vector<std::vector<int>> dummyTrackList;
0684 std::vector<int> dummyTrackID;
0685 for (int j : i)
0686 {
0687 v_intermediateResonances.push_back(daughterParticles[i[j]]);
0688 }
0689 for (unsigned int k = 0; k < v_intermediateResonances.size(); ++k)
0690 {
0691 dummyTrackID.push_back(k);
0692 }
0693 dummyTrackList = findTwoProngs(v_intermediateResonances, dummyTrackID, (int) v_intermediateResonances.size());
0694 for (unsigned int p = 3; p <= v_intermediateResonances.size(); ++p)
0695 {
0696 dummyTrackList = findNProngs(v_intermediateResonances, dummyTrackID, dummyTrackList, (int) v_intermediateResonances.size(), (int) p);
0697 }
0698
0699 if (dummyTrackList.size() != 0)
0700 {
0701 goodTracksThatMeetIntermediates.push_back(i);
0702 }
0703 }
0704 }
0705
0706 return goodTracksThatMeetIntermediates;
0707 }
0708
0709 float KFParticle_Tools::eventDIRA(const KFParticle &particle, const KFParticle &vertex, bool do3D)
0710 {
0711 const int nDimensions = do3D ? 3 : 2;
0712 TMatrixD flightVector(nDimensions, 1);
0713 TMatrixD momVector(nDimensions, 1);
0714 flightVector(0, 0) = particle.GetX() - vertex.GetX();
0715 flightVector(1, 0) = particle.GetY() - vertex.GetY();
0716
0717 momVector(0, 0) = particle.GetPx();
0718 momVector(1, 0) = particle.GetPy();
0719
0720 if (do3D)
0721 {
0722 flightVector(2, 0) = particle.GetZ() - vertex.GetZ();
0723 momVector(2, 0) = particle.GetPz();
0724 }
0725
0726 TMatrixD momDotFD(1, 1);
0727 momDotFD = TMatrixD(momVector, TMatrixD::kTransposeMult, flightVector);
0728 float f_momDotFD = momDotFD(0, 0);
0729
0730 TMatrixD sizeOfMom(1, 1);
0731 sizeOfMom = TMatrixD(momVector, TMatrixD::kTransposeMult, momVector);
0732 float f_sizeOfMom = sqrt(sizeOfMom(0, 0));
0733
0734 TMatrixD sizeOfFD(1, 1);
0735 sizeOfFD = TMatrixD(flightVector, TMatrixD::kTransposeMult, flightVector);
0736 float f_sizeOfFD = sqrt(sizeOfFD(0, 0));
0737
0738 return f_momDotFD / (f_sizeOfMom * f_sizeOfFD);
0739 }
0740
0741 float KFParticle_Tools::flightDistanceChi2(const KFParticle &particle, const KFParticle &vertex)
0742 {
0743 TMatrixD flightVector(3, 1);
0744 TMatrixD flightDistanceCovariance(3, 3);
0745
0746 const KFParticle &kfp_vertex(vertex);
0747
0748 flightVector(0, 0) = particle.GetX() - kfp_vertex.GetX();
0749 flightVector(1, 0) = particle.GetY() - kfp_vertex.GetY();
0750 flightVector(2, 0) = particle.GetZ() - kfp_vertex.GetZ();
0751
0752 for (int i = 0; i < 3; i++)
0753 {
0754 for (int j = 0; j < 3; j++)
0755 {
0756 flightDistanceCovariance(i, j) = particle.GetCovariance(i, j) + kfp_vertex.GetCovariance(i, j);
0757 }
0758 }
0759
0760 TMatrixD anInverseMatrix(3, 3);
0761 anInverseMatrix = flightDistanceCovariance.Invert();
0762 TMatrixD m_chi2Value(1, 1);
0763 m_chi2Value = TMatrixD(flightVector, TMatrixD::kTransposeMult, anInverseMatrix * flightVector);
0764 return m_chi2Value(0, 0);
0765 }
0766
0767 std::tuple<KFParticle, bool> KFParticle_Tools::buildMother(KFParticle vDaughters[], int daughterOrder[],
0768 bool isIntermediate, int intermediateNumber, int nTracks,
0769 bool constrainMass, float required_vertexID, PHCompositeNode* topNode)
0770 {
0771 KFParticle mother;
0772 KFParticle *inputTracks = new KFParticle[nTracks];
0773
0774 mother.SetConstructMethod(2);
0775
0776 bool daughterMassCheck = true;
0777 int particlesWithPID[] = {11, 211, 321, 2212};
0778 float unique_vertexID = 0;
0779
0780
0781 int num_tracks_used_by_intermediates = 0;
0782 for (int i = 0; i < m_num_intermediate_states; ++i)
0783 {
0784 num_tracks_used_by_intermediates += m_num_tracks_from_intermediate[i];
0785 }
0786 int num_remaining_tracks = m_num_tracks - num_tracks_used_by_intermediates;
0787
0788 for (int i = 0; i < nTracks; ++i)
0789 {
0790 float daughterMass = 0;
0791
0792 if ((Int_t) vDaughters[i].GetQ() != 0)
0793 {
0794
0795
0796
0797
0798 daughterMass = constrainMass ? getParticleMass((Int_t) vDaughters[i].GetQ() * daughterOrder[i]) : vDaughters[i].GetMass();
0799 }
0800 else if ((Int_t) vDaughters[i].GetQ() == 0)
0801 {
0802
0803
0804
0805 daughterMass = constrainMass ? getParticleMass(daughterOrder[i]) : vDaughters[i].GetMass();
0806 }
0807
0808 if ((num_remaining_tracks > 0 && i >= m_num_intermediate_states) || isIntermediate)
0809 {
0810 if ((Int_t) vDaughters[i].GetQ() != 0)
0811 {
0812 daughterMass = getParticleMass((Int_t) vDaughters[i].GetQ() * daughterOrder[i]);
0813 }
0814 else if ((Int_t) vDaughters[i].GetQ() == 0)
0815 {
0816 daughterMass = getParticleMass(daughterOrder[i]);
0817 }
0818
0819 }
0820 inputTracks[i].Create(vDaughters[i].Parameters(),
0821 vDaughters[i].CovarianceMatrix(),
0822 (Int_t) vDaughters[i].GetQ(),
0823 daughterMass);
0824
0825
0826 if (m_use_PID)
0827 {
0828 int track_PDG_ID = (Int_t) vDaughters[i].GetQ()*daughterOrder[i];
0829 if (std::find(std::begin(particlesWithPID), std::end(particlesWithPID), std::abs(track_PDG_ID)) != std::end(particlesWithPID))
0830 {
0831 float calculated_dEdx_value = get_dEdx(topNode, vDaughters[i]);
0832 double expected_dEdx_value = get_dEdx_fitValue((Int_t) vDaughters[i].GetQ() * vDaughters[i].GetP(), track_PDG_ID);
0833 bool accept_dEdx = isInRange((1-m_dEdx_band_width)*expected_dEdx_value, calculated_dEdx_value, (1+m_dEdx_band_width)*expected_dEdx_value);
0834 if(!accept_dEdx)
0835 {
0836 delete [] inputTracks;
0837 return std::make_tuple(mother, false);
0838 }
0839 }
0840 }
0841
0842 mother.AddDaughter(inputTracks[i]);
0843 mother.AddDaughterId(vDaughters[i].Id());
0844 unique_vertexID += (Int_t) vDaughters[i].GetQ() * getParticleMass(daughterOrder[i]);
0845 }
0846
0847 if (isIntermediate)
0848 {
0849 mother.SetPDG(getParticleID(m_intermediate_name[intermediateNumber].c_str()));
0850 }
0851 if (!isIntermediate && !m_mother_name_Tools.empty())
0852 {
0853 mother.SetPDG(getParticleID(m_mother_name_Tools));
0854 }
0855
0856 bool chargeCheck;
0857 if (m_get_charge_conjugate)
0858 {
0859 chargeCheck = std::abs(unique_vertexID) == std::abs(required_vertexID) ? true : false;
0860 }
0861 else
0862 {
0863 chargeCheck = unique_vertexID == required_vertexID ? true : false;
0864 }
0865
0866 for (int j = 0; j < nTracks; ++j)
0867 {
0868 if (m_extrapolateTracksToSV)
0869 {
0870 inputTracks[j].SetProductionVertex(mother);
0871 }
0872 if (!m_allowZeroMassTracks)
0873 {
0874 if (inputTracks[j].GetMass() == 0)
0875 {
0876 daughterMassCheck = false;
0877 }
0878 }
0879 }
0880
0881
0882 float calculated_mass, calculated_mass_err;
0883 mother.GetMass(calculated_mass, calculated_mass_err);
0884 float calculated_pt = mother.GetPt();
0885
0886 float min_mass = isIntermediate ? m_intermediate_mass_range[intermediateNumber].first : m_min_mass;
0887 float max_mass = isIntermediate ? m_intermediate_mass_range[intermediateNumber].second : m_max_mass;
0888 float min_pt = isIntermediate ? m_intermediate_min_pt[intermediateNumber] : m_mother_pt;
0889
0890 float max_vertex_volume = isIntermediate ? m_intermediate_vertex_volume[intermediateNumber] : m_mother_vertex_volume;
0891
0892 bool goodCandidate = false;
0893
0894 if (calculated_mass >= min_mass && calculated_mass <= max_mass &&
0895 calculated_pt >= min_pt && daughterMassCheck && chargeCheck && calculateEllipsoidVolume(mother) <= max_vertex_volume)
0896 {
0897 goodCandidate = true;
0898 }
0899
0900 if (goodCandidate && m_require_bunch_crossing_match)
0901 {
0902 std::vector<int> crossings;
0903 for (int i = 0; i < nTracks; ++i)
0904 {
0905 SvtxTrack *thisTrack = toolSet.getTrack(vDaughters[i].Id(), m_dst_trackmap);
0906 if (thisTrack)
0907 {
0908 crossings.push_back(thisTrack->get_crossing());
0909 }
0910 }
0911
0912 removeDuplicates(crossings);
0913
0914 if (crossings.size() != 1)
0915 {
0916 goodCandidate = false;
0917 }
0918 }
0919
0920
0921 if (goodCandidate && m_has_intermediates && !isIntermediate)
0922 {
0923 for (int k = 0; k < m_num_intermediate_states; ++k)
0924 {
0925 float intermediate_DIRA = eventDIRA(vDaughters[k], mother);
0926 float intermediate_FDchi2 = flightDistanceChi2(vDaughters[k], mother);
0927 if (intermediate_DIRA < m_intermediate_min_dira[k] ||
0928 intermediate_FDchi2 < m_intermediate_min_fdchi2[k])
0929 {
0930 goodCandidate = false;
0931 }
0932 }
0933 }
0934 delete [] inputTracks;
0935 return std::make_tuple(mother, goodCandidate);
0936 }
0937
0938 void KFParticle_Tools::constrainToVertex(KFParticle &particle, bool &goodCandidate, KFParticle &vertex)
0939 {
0940 KFParticle particleCopy = particle;
0941 particleCopy.SetProductionVertex(vertex);
0942 particleCopy.TransportToDecayVertex();
0943
0944 float calculated_decayTime;
0945 float calculated_decayTimeErr;
0946 float calculated_decayLength;
0947 float calculated_decayLengthErr;
0948 float calculated_decayLength_xy;
0949 float calculated_decayLengthErr_xy;
0950
0951 particleCopy.GetLifeTime(calculated_decayTime, calculated_decayTimeErr);
0952 particleCopy.GetDecayLength(calculated_decayLength, calculated_decayLengthErr);
0953 particleCopy.GetDecayLengthXY(calculated_decayLength_xy, calculated_decayLengthErr_xy);
0954
0955 float calculated_decayTime_xy = particleCopy.GetPseudoProperDecayTime(vertex, particleCopy.GetMass());
0956
0957 float calculated_fdchi2 = flightDistanceChi2(particle, vertex);
0958
0959 float calculated_ip_xy = abs(particle.GetDistanceFromVertexXY(vertex));
0960 float calculated_ipchi2_xy = particle.GetDeviationFromVertexXY(vertex);
0961 float calculated_dira_xy = eventDIRA(particle, vertex, false);
0962 float calculated_ip = particle.GetDistanceFromVertex(vertex);
0963 float calculated_ipchi2 = particle.GetDeviationFromVertex(vertex);
0964 float calculated_dira = eventDIRA(particle, vertex);
0965
0966 float calculated_decay_time_significance = calculated_decayTime/calculated_decayTimeErr;
0967 float calculated_decay_length_significance = calculated_decayLength/calculated_decayLengthErr;
0968 float calculated_decay_length_xy_significance = calculated_decayLength_xy/calculated_decayLengthErr_xy;
0969
0970 goodCandidate = false;
0971
0972 const float speed = 2.99792458e-2;
0973 calculated_decayTime /= speed;
0974
0975 if (calculated_fdchi2 >= m_fdchi2
0976 && calculated_ip <= m_mother_ip
0977 && calculated_ipchi2 <= m_mother_ipchi2
0978 && calculated_ip_xy <= m_mother_ip_xy
0979 && calculated_ipchi2_xy <= m_mother_ipchi2_xy
0980 && calculated_decay_time_significance >= m_mother_min_decay_time_significance
0981 && calculated_decay_length_significance >= m_mother_min_decay_length_significance
0982 && calculated_decay_length_xy_significance >= m_mother_min_decay_length_xy_significance
0983 && isInRange(m_dira_min, calculated_dira, m_dira_max)
0984 && isInRange(m_dira_xy_min, calculated_dira_xy, m_dira_xy_max)
0985 && isInRange(m_min_decayTime, calculated_decayTime, m_max_decayTime)
0986 && isInRange(m_min_decayTime_xy, calculated_decayTime_xy, m_max_decayTime_xy)
0987 && isInRange(m_min_decayLength, calculated_decayLength, m_max_decayLength)
0988 && isInRange(m_min_decayLength_xy, calculated_decayLength_xy, m_max_decayLength_xy))
0989 {
0990 goodCandidate = true;
0991 }
0992 }
0993
0994 std::tuple<KFParticle, bool> KFParticle_Tools::getCombination(KFParticle vDaughters[], int daughterOrder[], KFParticle vertex, bool constrain_to_vertex, bool isIntermediate, int intermediateNumber, int nTracks, bool constrainMass, float required_vertexID, PHCompositeNode* topNode)
0995 {
0996 KFParticle candidate;
0997 bool isGoodCandidate;
0998
0999 std::tie(candidate, isGoodCandidate) = buildMother(vDaughters, daughterOrder, isIntermediate, intermediateNumber, nTracks, constrainMass, required_vertexID, topNode);
1000
1001 if (constrain_to_vertex && isGoodCandidate && !isIntermediate)
1002 {
1003 if (m_require_track_and_vertex_match)
1004 {
1005 isGoodCandidate = checkTrackAndVertexMatch(vDaughters, nTracks, vertex);
1006 }
1007
1008 if (isGoodCandidate)
1009 {
1010 constrainToVertex(candidate, isGoodCandidate, vertex);
1011 }
1012 }
1013 return std::make_tuple(candidate, isGoodCandidate);
1014 }
1015
1016 std::vector<std::vector<int>> KFParticle_Tools::findUniqueDaughterCombinations(int start, int end)
1017 {
1018 std::vector<int> vect_permutations;
1019 std::vector<std::vector<int>> uniqueCombinations;
1020 std::map<int, int> daughterMap;
1021 for (int i = start; i < end; i++)
1022 {
1023 daughterMap.insert(std::pair<int, int>(i, abs(getParticleID(m_daughter_name[i].c_str()))));
1024 vect_permutations.push_back(i);
1025 }
1026 int *permutations = &vect_permutations[0];
1027
1028 do
1029 {
1030 std::vector<int> combination;
1031 combination.reserve((end - start));
1032 for (int i = 0; i < (end - start); i++)
1033 {
1034 combination.push_back(daughterMap.find(permutations[i])->second);
1035 }
1036 uniqueCombinations.push_back(combination);
1037 } while (std::next_permutation(permutations, permutations + vect_permutations.size()));
1038
1039 removeDuplicates(uniqueCombinations);
1040
1041 return uniqueCombinations;
1042 }
1043
1044 double KFParticle_Tools::calculateEllipsoidRadius(int posOrNeg, double sigma_ii, double sigma_jj, double sigma_ij)
1045 {
1046 if (std::abs(posOrNeg) != 1)
1047 {
1048 std::cout << "You have set posOrNeg to " << posOrNeg << ". This value must be +/- 1! Skipping" << std::endl;
1049 return 0;
1050 }
1051
1052 double r_ij = sqrt((sigma_ii + sigma_jj) / 2 + posOrNeg * (sqrt(pow((sigma_ii - sigma_jj) / 2, 2) + pow(sigma_ij, 2))));
1053
1054 return r_ij;
1055 }
1056
1057 float KFParticle_Tools::calculateEllipsoidVolume(const KFParticle &particle)
1058 {
1059 TMatrixD cov_matrix(3, 3);
1060
1061 for (int i = 0; i < 3; ++i)
1062 {
1063 for (int j = 0; j < 3; ++j)
1064 {
1065 cov_matrix(i, j) = particle.GetCovariance(i, j);
1066 }
1067 }
1068
1069 float volume;
1070 if (cov_matrix(0, 0) * cov_matrix(1, 1) * cov_matrix(2, 2) == 0)
1071 {
1072 volume = 0;
1073 }
1074 else
1075 {
1076 volume = (4. / 3.) * M_PI * sqrt((std::abs(cov_matrix.Determinant())));
1077 }
1078
1079 return volume;
1080 }
1081
1082 float KFParticle_Tools::calculateJT(const KFParticle &mother, const KFParticle &daughter)
1083 {
1084 Eigen::Vector3f motherP = Eigen::Vector3f(mother.GetPx(), mother.GetPy(), mother.GetPz());
1085 Eigen::Vector3f daughterP = Eigen::Vector3f(daughter.GetPx(), daughter.GetPy(), daughter.GetPz());
1086
1087 Eigen::Vector3f motherP_X_daughterP = motherP.cross(daughterP);
1088
1089 float jT = (motherP_X_daughterP.norm()) / motherP.norm();
1090
1091 return jT;
1092 }
1093
1094 bool KFParticle_Tools::isInRange(float min, float value, float max)
1095 {
1096 return min <= value && value <= max;
1097 }
1098
1099 void KFParticle_Tools::removeDuplicates(std::vector<double> &v)
1100 {
1101 auto end = v.end();
1102 for (auto it = v.begin(); it != end; ++it)
1103 {
1104 end = remove(it + 1, end, *it);
1105 }
1106 v.erase(end, v.end());
1107 }
1108
1109 void KFParticle_Tools::removeDuplicates(std::vector<int> &v)
1110 {
1111 auto end = v.end();
1112 for (auto it = v.begin(); it != end; ++it)
1113 {
1114 end = remove(it + 1, end, *it);
1115 }
1116 v.erase(end, v.end());
1117 }
1118
1119 void KFParticle_Tools::removeDuplicates(std::vector<std::vector<int>> &v)
1120 {
1121 auto end = v.end();
1122 for (auto it = v.begin(); it != end; ++it)
1123 {
1124 end = remove(it + 1, end, *it);
1125 }
1126 v.erase(end, v.end());
1127 }
1128
1129 void KFParticle_Tools::removeDuplicates(std::vector<std::vector<std::string>> &v)
1130 {
1131 auto end = v.end();
1132 for (auto it = v.begin(); it != end; ++it)
1133 {
1134 end = remove(it + 1, end, *it);
1135 }
1136 v.erase(end, v.end());
1137 }
1138
1139 bool KFParticle_Tools::findParticle(const std::string &particle)
1140 {
1141 bool particleFound = true;
1142 if (!TDatabasePDG::Instance()->GetParticle(particle.c_str()))
1143 {
1144 std::cout << "The particle, " << particle << " is not recognized" << std::endl;
1145 std::cout << "Check TDatabasePDG for a list of available particles" << std::endl;
1146 particleFound = false;
1147 }
1148
1149 return particleFound;
1150 }
1151
1152 int KFParticle_Tools::getParticleID(const std::string &particle)
1153 {
1154 return TDatabasePDG::Instance()->GetParticle(particle.c_str())->PdgCode();
1155 }
1156
1157 float KFParticle_Tools::getParticleMass(const std::string &particle)
1158 {
1159 return TDatabasePDG::Instance()->GetParticle(particle.c_str())->Mass();
1160 }
1161
1162 float KFParticle_Tools::getParticleMass(const int PDGID)
1163 {
1164 return TDatabasePDG::Instance()->GetParticle(PDGID)->Mass();
1165 }
1166
1167 void KFParticle_Tools::identify(const KFParticle &particle)
1168 {
1169 std::cout << "Track ID: " << particle.Id() << std::endl;
1170 std::cout << "PDG ID: " << particle.GetPDG() << ", charge: " << (int) particle.GetQ() << ", mass: " << particle.GetMass() << " GeV" << std::endl;
1171 std::cout << "(px,py,pz) = (" << particle.GetPx() << " +/- " << std::sqrt(particle.GetCovariance(3, 3)) << ", ";
1172 std::cout << particle.GetPy() << " +/- " << std::sqrt(particle.GetCovariance(4, 4)) << ", ";
1173 std::cout << particle.GetPz() << " +/- " << std::sqrt(particle.GetCovariance(5, 5)) << ") GeV" << std::endl;
1174 std::cout << "(x,y,z) = (" << particle.GetX() << " +/- " << std::sqrt(particle.GetCovariance(0, 0)) << ", ";
1175 std::cout << particle.GetY() << " +/- " << std::sqrt(particle.GetCovariance(1, 1)) << ", ";
1176 std::cout << particle.GetZ() << " +/- " << std::sqrt(particle.GetCovariance(2, 2)) << ") cm\n"
1177 << std::endl;
1178 }
1179
1180 float KFParticle_Tools::get_dEdx(PHCompositeNode *topNode, const KFParticle &daughter)
1181 {
1182 m_dst_trackmap = findNode::getClass<SvtxTrackMap>(topNode, m_trk_map_node_name.c_str());
1183 m_cluster_map = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
1184 m_geom_container = findNode::getClass<PHG4TpcGeomContainer>(topNode, "TPCGEOMCONTAINER");
1185 auto geometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
1186 if(!m_cluster_map || !m_geom_container || !geometry)
1187 {
1188 return -1.0;
1189 }
1190
1191 SvtxTrack *daughter_track = toolSet.getTrack(daughter.Id(), m_dst_trackmap);
1192 TrackSeed *tpcseed = daughter_track->get_tpc_seed();
1193 float layerThicknesses[4] = {0.0, 0.0, 0.0, 0.0};
1194
1195
1196 layerThicknesses[0] = m_geom_container->GetLayerCellGeom(7)->get_thickness();
1197 layerThicknesses[1] = m_geom_container->GetLayerCellGeom(8)->get_thickness();
1198 layerThicknesses[2] = m_geom_container->GetLayerCellGeom(27)->get_thickness();
1199 layerThicknesses[3] = m_geom_container->GetLayerCellGeom(50)->get_thickness();
1200
1201 return TrackAnalysisUtils::calc_dedx(tpcseed, m_cluster_map, geometry, layerThicknesses);
1202
1203 }
1204
1205 void KFParticle_Tools::init_dEdx_fits()
1206 {
1207 std::string dedx_fitparams = CDBInterface::instance()->getUrl("TPC_DEDX_FITPARAM");
1208 TFile *filefit = TFile::Open(dedx_fitparams.c_str());
1209
1210 if (!filefit->IsOpen())
1211 {
1212 std::cerr << "Error opening filefit!" << std::endl;
1213 return;
1214 }
1215
1216 filefit->GetObject("f_piband", f_pion_plus);
1217 filefit->GetObject("f_Kband", f_kaon_plus);
1218 filefit->GetObject("f_pband", f_proton_plus);
1219 filefit->GetObject("f_piminus_band", f_pion_minus);
1220 filefit->GetObject("f_Kminus_band", f_kaon_minus);
1221 filefit->GetObject("f_pbar_band", f_proton_minus);
1222
1223 pidMap.insert(std::pair<int, TF1*>( -11, f_pion_plus));
1224 pidMap.insert(std::pair<int, TF1*>( 211, f_pion_plus));
1225 pidMap.insert(std::pair<int, TF1*>( 321, f_kaon_plus));
1226 pidMap.insert(std::pair<int, TF1*>( 2212, f_proton_plus));
1227 pidMap.insert(std::pair<int, TF1*>( 11, f_pion_minus));
1228 pidMap.insert(std::pair<int, TF1*>(-211, f_pion_minus));
1229 pidMap.insert(std::pair<int, TF1*>(-321, f_kaon_minus));
1230 pidMap.insert(std::pair<int, TF1*>(-2212, f_proton_minus));
1231 }
1232
1233 double KFParticle_Tools::get_dEdx_fitValue(float momentum, int PID)
1234 {
1235 return pidMap[PID]->Eval(momentum);
1236 }
1237
1238 bool KFParticle_Tools::checkTrackAndVertexMatch(KFParticle vDaughters[], int nTracks, KFParticle vertex)
1239 {
1240 bool vertexAndTrackMatch = true;
1241
1242 int vertexCrossing = 1e5;
1243
1244 if (m_dont_use_global_vertex)
1245 {
1246 if (m_use_mbd_vertex)
1247 {
1248 m_dst_mbdvertex = m_dst_mbdvertexmap->get(vertex.Id());
1249 vertexCrossing = m_dst_mbdvertex->get_beam_crossing();
1250 }
1251 else
1252 {
1253 m_dst_vertex = m_dst_vertexmap->get(vertex.Id());
1254 vertexCrossing = m_dst_vertex->get_beam_crossing();
1255 }
1256 }
1257 else
1258 {
1259 m_dst_globalvertex = m_dst_globalvertexmap->get(vertex.Id());
1260
1261 GlobalVertex::VTXTYPE whichVtx = m_use_mbd_vertex ? GlobalVertex::MBD : GlobalVertex::SVTX;
1262
1263 auto svtxiter = m_dst_globalvertex->find_vertexes(whichVtx);
1264 auto svtxvertexvector = svtxiter->second;
1265
1266 for (auto &gvertex : svtxvertexvector)
1267 {
1268 if (m_use_mbd_vertex)
1269 {
1270 m_dst_mbdvertex = m_dst_mbdvertexmap->find(gvertex->get_id())->second;
1271 vertexCrossing = m_dst_mbdvertex->get_beam_crossing();
1272 }
1273 else
1274 {
1275 m_dst_vertex = m_dst_vertexmap->find(gvertex->get_id())->second;
1276 vertexCrossing = m_dst_vertex->get_beam_crossing();
1277 }
1278 }
1279 }
1280
1281 for (int i = 0; i < nTracks; ++i)
1282 {
1283 SvtxTrack *thisTrack = toolSet.getTrack(vDaughters[i].Id(), m_dst_trackmap);
1284 if (thisTrack)
1285 {
1286 int trackCrossing = thisTrack->get_crossing();
1287 vertexAndTrackMatch = trackCrossing != vertexCrossing ? false : vertexAndTrackMatch;
1288 }
1289 }
1290
1291 return vertexAndTrackMatch;
1292 }