164 #include "TVector3.h"
177 const std::string& Bname,
178 const std::string& Prefix) :
179 name(std::move(
Name)), bname(std::move(Bname)),
prefix(std::move(Prefix)) {
186 const std::string& Bname,
187 const std::string& Prefix) {
189 bname = std::move(Bname);
190 prefix = std::move(Prefix);
194 prefix = std::move(Prefix);
202 const std::string&
suffix)
const {
205 (bname.length() > 0 ? bname +
"_" :
""),
206 (qualifier.length() > 0 ? qualifier +
"_" :
""),
222 :
name(std::move(
Name)), m_parent(Parent) {
229 const std::string &
prefix,
230 const std::string &
suffix,
235 m_parent.m_useTrackTypes[rtype],
238 addToCounter(
f, atype, counts);
245 NameCountMap_t::const_iterator
it = m_cnts.find(
name);
247 if (
it != m_cnts.end() ) {
248 m_cnts[
name].first += counts;
250 m_cnts[
name] = std::make_pair(counts, atype);
260 for (NameCountMap_t::const_iterator
it = m_cnts.begin();
261 it != m_cnts.end(); ++
it) {
262 lmax =
std::max(lmax, (
int)(
it->first).length());
265 for (NameCountMap_t::const_iterator
it = m_cnts.begin();
266 it != m_cnts.end(); ++
it) {
267 std::string
f =
std::format(
"{:>{}}{:<{}} : {:>10} {:>33}",
271 std::bitset<33>((
it->second).second).to_string());
275 str.erase(
str.length()-1);
284 {
"ASSOCPV",
"PVTYPE0",
"PVTYPE1",
"PVTYPE2",
"PVTYPE3",
"NONE",
"NULLVP",
285 "CAPVRFN3U0",
"CAPVNRN3U0",
"CAPVRF3DU0",
"CAPVNR3DU0",
286 "CAPVRFN3U1",
"CAPVNRN3U1",
"CAPVRF3DU1",
"CAPVNR3DU1",
287 "CAPVRFN3U2",
"CAPVNRN3U2",
"CAPVRF3DU2",
"CAPVNR3DU2",
288 "CAPVRFNNU3",
"CAPVNRNNU3",
"CAPVRFNNU4",
"CAPVNRNNU4",
289 "CAPVRFNNU5",
"CAPVNRNNU5",
"CAPVRFNNU6",
"CAPVNRNNU6",
290 "CAPVRFNNU7",
"CAPVNRNNU7",
"CAPVRFNNU8",
"CAPVNRNNU8",
291 "CAPVRFNNU9",
"CAPVNRNNU9"};
293 {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40,
294 0x80, 0x100, 0x200, 0x400,
295 0x800, 0x1000, 0x2000, 0x4000,
296 0x8000, 0x10000, 0x20000, 0x40000,
297 0x80000, 0x100000, 0x200000, 0x400000,
298 0x800000, 0x1000000, 0x2000000, 0x4000000,
299 0x8000000, 0x10000000, 0x20000000, 0x40000000,
300 0x80000000, 0x100000000};
330 for (
size_t i=0;
i<vtypes.size(); ++
i) {
340 if (
track !=
nullptr) {
342 "d:({:10.5f},{:10.5f},{:10.5f},{:10.5f},{:10.6f})",
354 const std::string&
prefix) {
360 if ( !ostr.empty() ) ostr +=
"\n";
368 const std::string&
n,
371 m_tvaTool(
"CP::TrackVertexAssociationTool"),
377 declareInterface<DerivationFramework::IAugmentationTool>(
this);
404 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::initialize() -- begin");
421 <<
") and RefPVContainerNames ("
428 <<
") and BranchPrefixes ("
444 const std::string tvaWp =
456 m_mttc = std::make_unique<TrackTypeCounter>(*
this,
name());
479 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::addBranches() -- begin");
543 svtxContainer->
begin(); vtxItr!=svtxContainer->
end();
562 return StatusCode::SUCCESS;
569 return StatusCode::SUCCESS;
576 return StatusCode::SUCCESS;
585 ATH_MSG_DEBUG(
"addBranchesVCSetupHook: Vertex container index " << ivc
589 return StatusCode::SUCCESS;
600 return StatusCode::SUCCESS;
608 const unsigned int ipv,
609 const unsigned int its,
610 const unsigned int itt)
const {
613 ATH_MSG_DEBUG(
"calcIsolationOpti: vtx: " << vtx <<
", ipv: " << ipv
614 <<
", its: " << its <<
", itt: " << itt);
616 return StatusCode::SUCCESS;
623 const int ipv)
const {
626 ATH_MSG_DEBUG(
"fastIsoFill: vtx: " << vtx <<
", ipv: " << ipv);
640 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::calculateValues -- begin");
649 for (
unsigned int ipv = 0; ipv < nPvAssocs; ++ipv) {
651 for (
unsigned int its = 0; its < nTrackSels; ++its) {
652 for (
unsigned int itt = 0; itt < nTrackTypes; ++itt) {
654 <<
", its: " << its <<
", itt: " << itt);
662 <<
" -- cached ipv: " << ipv);
666 return StatusCode::SUCCESS;
673 const int ipv)
const {
725 int chi2DefToUse)
const {
727 std::vector<double>
res = {-999., -99., -999., -99., -100., -100., -1.,
731 const AmgSymMatrix(3) poscov = vtx->covariancePosition();
732 auto ctx = Gaudi::Hive::currentContext();
733 if (
track != NULL ) {
734 if ( chi2DefToUse < 2 || (chi2DefToUse > 5 && chi2DefToUse < 8) ) {
736 std::unique_ptr<const Trk::Perigee>
738 if ( trkPerigee != NULL ) {
741 const AmgSymMatrix(5)* locError = trkPerigee->covariance();
742 if ( locError != NULL ) {
746 if ( chi2DefToUse == 1 ) {
748 Amg::Vector3D perppt(trkPerigee->momentum().y()/trkPerigee->pT(),
749 -trkPerigee->momentum().x()/trkPerigee->pT(),
751 double vtxD0Err2 = perppt.transpose()*poscov*perppt;
752 res[1] = sqrt(
pow(
res[1], 2.) + vtxD0Err2 );
753 res[3] = sqrt(
pow(
res[3], 2.) + poscov(2,2) );
755 if ( chi2DefToUse < 2 ) {
756 if ( fabs(
res[1]) > 0. && fabs(
res[3]) > 0. ) {
762 <<
" d0 = " <<
res[0] <<
", d0Err = "
763 <<
res[1] <<
", z0 = " <<
res[2]
764 <<
", z0Err = " <<
res[3]);
768 if ( chi2DefToUse > 5 && chi2DefToUse < 8 ) {
773 if ( chi2DefToUse == 6 ) {
780 AmgSymMatrix(3) mCovTrk3D = dmat.transpose()*(*locError)*dmat;
785 res[4] =
log( dvec.transpose() * (poscov+mCovTrk3D).inverse()
787 res[7] = duvec.transpose()*poscov*duvec;
788 res[8] = duvec.transpose()*mCovTrk3D*duvec;
791 if ( chi2DefToUse == 7 ) {
799 AmgSymMatrix(2) mCovVtx2D = dmat.transpose()*poscov*dmat;
808 res[4] =
log( dvec.transpose()*(mCovVtx2D+mCovTrk2D).inverse()
810 res[7] = duvec.transpose()*mCovVtx2D*duvec;
811 res[8] = duvec.transpose()*mCovTrk2D*duvec;
824 " locError pointer is NULL!");
828 " trkPerigee pointer is NULL!");
831 }
else if ( chi2DefToUse == 2
832 || (chi2DefToUse > 7 && chi2DefToUse < 10 )) {
837 TVector3 SV_def(vtx->
x(), vtx->
y(), vtx->
z());
841 double px = (
track->p4() ).Px();
842 double py = (
track->p4() ).Py();
845 double d0Err2 =
track->definingParametersCovMatrixVec()[0];
847 double z0Err2 =
track->definingParametersCovMatrixVec()[2];
848 double theta =
track->theta();
849 double d0z0Cov =
track->definingParametersCovMatrixVec()[1];
850 double phi =
track->phi();
853 TVector3 SV = SV_def - trk_origin;
858 double d0toSV =
d0 + (SV[0]*upx + SV[1]*upy);
859 double d0toSVErr2 = upx*SV_cov(0, 0)*upx + 2*upx*SV_cov(1, 0)*upy
860 + upy*SV_cov(1, 1)*upy + d0Err2;
864 double cot_theta =
cos(theta)/
sin(theta);
865 double z0corr = (SV[0]*upx + SV[1]*upy)*cot_theta;
866 double z0toSV =
z0 + z0corr - SV[2];
867 double z0toSVErr2 = SV_cov(2, 2) + z0Err2;
869 double docaSV = sqrt(
pow(d0toSV, 2) +
pow(z0toSV, 2) );
871 double chi2testSV(999.);
872 if ( chi2DefToUse == 2 ) {
873 if (d0toSVErr2 !=0 && z0toSVErr2 != 0)
874 chi2testSV =
log(
pow( d0toSV, 2)/d0toSVErr2
875 +
pow( z0toSV, 2)/z0toSVErr2);
877 res = {d0toSV, sqrt(d0toSVErr2), z0toSV, sqrt(z0toSVErr2),
878 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 4,
881 if ( chi2DefToUse > 7 && chi2DefToUse < 10 ) {
883 if ( chi2DefToUse == 8 ) {
885 dmat(0,0) = -
sin(phi);
886 dmat(0,1) =
cos(phi);
888 dmat(2,0) = -d0toSV*
cos(phi);
889 dmat(2,1) = -d0toSV*
sin(phi);
891 track->definingParametersCovMatrix();
892 AmgSymMatrix(3) mCovTrk3D = dmat.transpose()*mCovTrk5D*dmat;
897 double chi2testSV =
log( dvec.transpose()
898 * (poscov+mCovTrk3D).inverse()
900 double vtx3DErr2 = duvec.transpose()*poscov*duvec;
901 double trk3DErr2 = duvec.transpose()*mCovTrk3D*duvec;
903 res = {d0toSV, sqrt(d0Err2), z0toSV, sqrt(z0Err2),
904 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 5,
905 vtx3DErr2, trk3DErr2, phi};
907 if ( chi2DefToUse == 9 ) {
909 dmat(0,0) = -
sin(phi);
910 dmat(1,0) =
cos(phi);
915 AmgSymMatrix(2) mCovVtx2D = dmat.transpose()*SV_cov*dmat;
917 mCovTrk2D(0,0) = d0Err2;
918 mCovTrk2D(0,1) = d0z0Cov;
919 mCovTrk2D(1,0) = d0z0Cov;
920 mCovTrk2D(1,1) = z0Err2;
924 chi2testSV =
log( dvec.transpose()*(mCovVtx2D+mCovTrk2D).inverse()
926 double vtx2DErr2 = duvec.transpose()*mCovVtx2D*duvec;
927 double trk2DErr2 = duvec.transpose()*mCovTrk2D*duvec;
929 if ( vtx2DErr2 < 0. || trk2DErr2 < 0. ) {
931 "getTrackLogChi2DCA(): "
932 <<
"vtx2DErr2 = " << vtx2DErr2
933 <<
" trk2DErr2 = " << trk2DErr2
934 <<
" chi2testSV = " << chi2testSV);
944 <<
" z0toSV = " << z0toSV
946 <<
" docaSV = " << docaSV);
950 res = {d0toSV, sqrt(d0Err2), z0toSV, sqrt(z0Err2),
951 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 6,
952 vtx2DErr2, trk2DErr2, phi};
956 <<
" docaSV == 0 !");
960 }
else if ( chi2DefToUse > 2 && chi2DefToUse < 5 ) {
966 if (chi2DefToUse == 4) {
979 double z0toPV =
track->z0() +
track->vz() - vtx->
z();
980 double z0Err2 =
track->definingParametersCovMatrixVec()[2];
981 if (chi2DefToUse == 4) z0Err2+= vtx->covariancePosition()(2,2);
982 double z0sign = z0toPV / sqrt( z0Err2 );
985 res = {-999., -99., z0toPV, sqrt(z0Err2),
chi2, -100., 4, -99., -99.,
991 " track pointer is NULL!");
1007 ATH_MSG_ERROR(
"BPhysVertexTrackBase::detTrackTypes must be adjusted due to changes in TrackParticle");
1010 if ( candPV != NULL ) {
1023 bool useRefittedPvs = (
i%2 == 1 );
1024 bool doDCAin3D = ( (
i-7)%4 > 1 );
1025 int chi2DefToUse = (
i-7)/4;
1029 chi2DefToUse = (
i-13)/2;
1032 if ( chi2DefToUse == 5 ) {
1040 doDCAin3D, chi2DefToUse).first;
1042 if ( candPV == minChi2PV
1043 || (candRefPV !=
nullptr && candRefPV == minChi2PV) ) {
1075 for (
unsigned int i=0;
i < vtx.
vtx()->nTrackParticles(); ++
i) {
1077 if (
std::find(tracks.begin(),tracks.end(),
track) == tracks.end() ) {
1078 tracks.push_back(
track);
1112 if (
std::find(muons.begin(),muons.end(),vtx.
muon(
i)) == muons.end() ) {
1113 muons.push_back(vtx.
muon(
i));
1137 for (MuonBag::const_iterator muItr = muons.begin(); muItr != muons.end();
1140 (*muItr)->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
1141 tracks.push_back(
track);
1151 std::vector<TVector3>
1155 std::vector<TVector3> refMuTracks;
1159 muons = vtx.
muons();
1160 for (
auto refMuTrack : vtx.
refTrks() ) {
1161 refMuTracks.push_back(refMuTrack);
1169 if ( otp != NULL ) {
1170 if (
std::find(muonIdTracks.begin(), muonIdTracks.end(), otp)
1171 != muonIdTracks.end() ) {
1172 refMuTracks.push_back(vtx.
refTrk(
i));
1176 " refTrkOrigin == NULL for refTrk # "
1182 " size mismatch #refTrks = " << vtx.
nRefTrks()
1190 std::vector<TVector3> precRefMuTracks =
1193 for (
auto precRefMuTrack : precRefMuTracks ) {
1194 if (
std::find(refMuTracks.begin(), refMuTracks.end(),
1195 precRefMuTrack) == refMuTracks.end() ) {
1196 refMuTracks.push_back(precRefMuTrack);
1205 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::findMuonRefTrackMomenta():"
1206 <<
" #muons: " << muons.size()
1207 <<
" #refMuTrks: " << refMuTracks.size());
1208 TString
str = Form(
">> refMuTracks(%d):\n", (
int)refMuTracks.size());
1209 for (
unsigned int i=0;
i < refMuTracks.size(); ++
i) {
1210 str += Form(
"(%10.4f,%10.4f,%10.4f) ",
1211 refMuTracks[
i].
x(), refMuTracks[
i].
y(),
1212 refMuTracks[
i].
z());
1229 const unsigned int ipv,
1230 const unsigned int its,
1231 const unsigned int itt)
const {
1246 const unsigned int ipv,
1247 const unsigned int its,
1248 const unsigned int itt)
const {
1254 <<
" " << exclTracks
1255 <<
" for decay candidate " << cand.
vtx()
1256 <<
"; candPV: " << candPV <<
" candRefPV: " << candRefPV);
1263 inpTracks->
begin(); trkItr != inpTracks->
end(); ++trkItr) {
1269 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"all");
1275 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"ats");
1283 if ( trackTypesForTrack == 0x0 ) {
1292 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"att");
1296 != exclTracks.end() )
continue;
1299 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"fin");
1302 tracks.push_back(
track);
1314 const std::string& preSuffix)
1317 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::buildBranchBaseName -- begin");
1323 std::size_t ipos = tsName.find_last_of(
"_");
1324 if ( ipos != std::string::npos ) tsName = tsName.substr(ipos+1);
1329 (preSuffix.length() > 0 ?
"_" + preSuffix :
""),
1332 ATH_MSG_DEBUG(
"BPhysVertexBaseTrackBase::buildBranchBaseName: " <<
f);
1358 std::pair<const xAOD::Vertex*, double>
1362 const std::vector<uint64_t>& pvtypes,
1363 const int minNTracksInPV,
1364 const bool useRefittedPvs,
1365 const bool doDCAin3D,
1366 const int chi2DefToUse)
const {
1372 if ( pvtx !=
nullptr ) {
1373 if (
std::find(pvtypes.begin(),pvtypes.end(),pvtx->vertexType())
1374 != pvtypes.end() ) {
1377 if ( useRefittedPvs && pvtx == candPV ) {
1378 if ( candRefPV !=
nullptr ) {
1382 <<
" candRefPV == NULL!");
1389 if (
chi2 < minChi2 ) {
1398 return std::make_pair(minChi2PV, minChi2);
1414 const std::vector<uint64_t>& pvtypes,
1415 const int minNTracksInPV,
1416 const bool useRefittedPvs)
const {
1419 std::vector<const xAOD::Vertex*> vpvtx;
1421 if ( pvtx !=
nullptr ) {
1422 if (
std::find(pvtypes.begin(),pvtypes.end(),pvtx->vertexType())
1423 != pvtypes.end() ) {
1426 if ( useRefittedPvs && pvtx == candPV ) {
1427 if ( candRefPV !=
nullptr ) {
1431 <<
" candRefPV == NULL!");
1436 vpvtx.push_back(cvtx);
1451 assocPV = candRefPV;
1456 if ( assocPV ==
nullptr ) {
1462 if ( assocPV ==
nullptr ) {
1464 <<
" assocPV == NULL for track!"
1465 <<
" len(vpvtx) = " << vpvtx.size()
1466 <<
" useRefittedPvs = " << useRefittedPvs
1467 <<
" minNTracksInPV = " << minNTracksInPV);