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})",
343 (track->p4()).Px(), (track->p4()).Py(), (track->p4()).Pz(),
344 track->d0(), track->z0(), track->phi0(), track->theta(),
354 const std::string&
prefix) {
360 if ( !ostr.empty() ) ostr +=
"\n";
368 const std::string&
n,
371 m_tvaTool(
"CP::TrackVertexAssociationTool"),
385 declareProperty(
"TrackParticleContainerName",
403 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::initialize() -- begin");
420 <<
") and RefPVContainerNames ("
427 <<
") and BranchPrefixes ("
443 const std::string tvaWp =
455 m_mttc = std::make_unique<TrackTypeCounter>(*
this,
name());
478 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::addBranches() -- begin");
542 svtxContainer->
begin(); vtxItr!=svtxContainer->
end();
561 return StatusCode::SUCCESS;
568 return StatusCode::SUCCESS;
575 return StatusCode::SUCCESS;
584 ATH_MSG_DEBUG(
"addBranchesVCSetupHook: Vertex container index " << ivc
588 return StatusCode::SUCCESS;
599 return StatusCode::SUCCESS;
607 const unsigned int ipv,
608 const unsigned int its,
609 const unsigned int itt)
const {
612 ATH_MSG_DEBUG(
"calcIsolationOpti: vtx: " << vtx <<
", ipv: " << ipv
613 <<
", its: " << its <<
", itt: " << itt);
615 return StatusCode::SUCCESS;
622 const int ipv)
const {
625 ATH_MSG_DEBUG(
"fastIsoFill: vtx: " << vtx <<
", ipv: " << ipv);
639 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::calculateValues -- begin");
648 for (
unsigned int ipv = 0; ipv < nPvAssocs; ++ipv) {
650 for (
unsigned int its = 0; its < nTrackSels; ++its) {
651 for (
unsigned int itt = 0; itt < nTrackTypes; ++itt) {
653 <<
", its: " << its <<
", itt: " << itt);
661 <<
" -- cached ipv: " << ipv);
665 return StatusCode::SUCCESS;
672 const int ipv)
const {
724 int chi2DefToUse)
const {
726 std::vector<double>
res = {-999., -99., -999., -99., -100., -100., -1.,
730 const AmgSymMatrix(3) poscov = vtx->covariancePosition();
731 auto ctx = Gaudi::Hive::currentContext();
732 if ( track != NULL ) {
733 if ( chi2DefToUse < 2 || (chi2DefToUse > 5 && chi2DefToUse < 8) ) {
735 std::unique_ptr<const Trk::Perigee>
737 if ( trkPerigee != NULL ) {
740 const AmgSymMatrix(5)* locError = trkPerigee->covariance();
741 if ( locError != NULL ) {
745 if ( chi2DefToUse == 1 ) {
747 Amg::Vector3D perppt(trkPerigee->momentum().y()/trkPerigee->pT(),
748 -trkPerigee->momentum().x()/trkPerigee->pT(),
750 double vtxD0Err2 = perppt.transpose()*poscov*perppt;
751 res[1] = sqrt(
pow(
res[1], 2.) + vtxD0Err2 );
752 res[3] = sqrt(
pow(
res[3], 2.) + poscov(2,2) );
754 if ( chi2DefToUse < 2 ) {
755 if ( fabs(
res[1]) > 0. && fabs(
res[3]) > 0. ) {
761 <<
" d0 = " <<
res[0] <<
", d0Err = "
762 <<
res[1] <<
", z0 = " <<
res[2]
763 <<
", z0Err = " <<
res[3]);
767 if ( chi2DefToUse > 5 && chi2DefToUse < 8 ) {
772 if ( chi2DefToUse == 6 ) {
779 AmgSymMatrix(3) mCovTrk3D = dmat.transpose()*(*locError)*dmat;
784 res[4] =
log( dvec.transpose() * (poscov+mCovTrk3D).inverse()
786 res[7] = duvec.transpose()*poscov*duvec;
787 res[8] = duvec.transpose()*mCovTrk3D*duvec;
790 if ( chi2DefToUse == 7 ) {
798 AmgSymMatrix(2) mCovVtx2D = dmat.transpose()*poscov*dmat;
807 res[4] =
log( dvec.transpose()*(mCovVtx2D+mCovTrk2D).inverse()
809 res[7] = duvec.transpose()*mCovVtx2D*duvec;
810 res[8] = duvec.transpose()*mCovTrk2D*duvec;
823 " locError pointer is NULL!");
827 " trkPerigee pointer is NULL!");
830 }
else if ( chi2DefToUse == 2
831 || (chi2DefToUse > 7 && chi2DefToUse < 10 )) {
836 TVector3 SV_def(vtx->
x(), vtx->
y(), vtx->
z());
840 double px = ( track->p4() ).Px();
841 double py = ( track->p4() ).Py();
842 double pt = ( track->p4() ).
Pt();
843 double d0 = track->d0();
844 double d0Err2 = track->definingParametersCovMatrixVec()[0];
845 double z0 = track->z0();
846 double z0Err2 = track->definingParametersCovMatrixVec()[2];
847 double theta = track->theta();
848 double d0z0Cov = track->definingParametersCovMatrixVec()[1];
849 double phi = track->phi();
851 TVector3 trk_origin( track->vx(), track->vy(), track->vz() );
852 TVector3 SV = SV_def - trk_origin;
857 double d0toSV =
d0 + (SV[0]*upx + SV[1]*upy);
858 double d0toSVErr2 = upx*SV_cov(0, 0)*upx + 2*upx*SV_cov(1, 0)*upy
859 + upy*SV_cov(1, 1)*upy + d0Err2;
863 double cot_theta =
cos(theta)/
sin(theta);
864 double z0corr = (SV[0]*upx + SV[1]*upy)*cot_theta;
865 double z0toSV =
z0 + z0corr - SV[2];
866 double z0toSVErr2 = SV_cov(2, 2) + z0Err2;
868 double docaSV = sqrt(
pow(d0toSV, 2) +
pow(z0toSV, 2) );
870 double chi2testSV(999.);
871 if ( chi2DefToUse == 2 ) {
872 if (d0toSVErr2 !=0 && z0toSVErr2 != 0)
873 chi2testSV =
log(
pow( d0toSV, 2)/d0toSVErr2
874 +
pow( z0toSV, 2)/z0toSVErr2);
876 res = {d0toSV, sqrt(d0toSVErr2), z0toSV, sqrt(z0toSVErr2),
877 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 4,
880 if ( chi2DefToUse > 7 && chi2DefToUse < 10 ) {
882 if ( chi2DefToUse == 8 ) {
884 dmat(0,0) = -
sin(phi);
885 dmat(0,1) =
cos(phi);
887 dmat(2,0) = -d0toSV*
cos(phi);
888 dmat(2,1) = -d0toSV*
sin(phi);
890 track->definingParametersCovMatrix();
891 AmgSymMatrix(3) mCovTrk3D = dmat.transpose()*mCovTrk5D*dmat;
896 double chi2testSV =
log( dvec.transpose()
897 * (poscov+mCovTrk3D).inverse()
899 double vtx3DErr2 = duvec.transpose()*poscov*duvec;
900 double trk3DErr2 = duvec.transpose()*mCovTrk3D*duvec;
902 res = {d0toSV, sqrt(d0Err2), z0toSV, sqrt(z0Err2),
903 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 5,
904 vtx3DErr2, trk3DErr2, phi};
906 if ( chi2DefToUse == 9 ) {
908 dmat(0,0) = -
sin(phi);
909 dmat(1,0) =
cos(phi);
914 AmgSymMatrix(2) mCovVtx2D = dmat.transpose()*SV_cov*dmat;
916 mCovTrk2D(0,0) = d0Err2;
917 mCovTrk2D(0,1) = d0z0Cov;
918 mCovTrk2D(1,0) = d0z0Cov;
919 mCovTrk2D(1,1) = z0Err2;
923 chi2testSV =
log( dvec.transpose()*(mCovVtx2D+mCovTrk2D).inverse()
925 double vtx2DErr2 = duvec.transpose()*mCovVtx2D*duvec;
926 double trk2DErr2 = duvec.transpose()*mCovTrk2D*duvec;
928 if ( vtx2DErr2 < 0. || trk2DErr2 < 0. ) {
930 "getTrackLogChi2DCA(): "
931 <<
"vtx2DErr2 = " << vtx2DErr2
932 <<
" trk2DErr2 = " << trk2DErr2
933 <<
" chi2testSV = " << chi2testSV);
943 <<
" z0toSV = " << z0toSV
945 <<
" docaSV = " << docaSV);
949 res = {d0toSV, sqrt(d0Err2), z0toSV, sqrt(z0Err2),
950 chi2testSV, (doDCAin3D ? docaSV : d0toSV), 6,
951 vtx2DErr2, trk2DErr2, phi};
955 <<
" docaSV == 0 !");
959 }
else if ( chi2DefToUse > 2 && chi2DefToUse < 5 ) {
965 if (chi2DefToUse == 4) {
978 double z0toPV = track->z0() + track->vz() - vtx->
z();
979 double z0Err2 = track->definingParametersCovMatrixVec()[2];
980 if (chi2DefToUse == 4) z0Err2+= vtx->covariancePosition()(2,2);
981 double z0sign = z0toPV / sqrt( z0Err2 );
984 res = {-999., -99., z0toPV, sqrt(z0Err2),
chi2, -100., 4, -99., -99.,
990 " track pointer is NULL!");
1006 ATH_MSG_ERROR(
"BPhysVertexTrackBase::detTrackTypes must be adjusted due to changes in TrackParticle");
1009 if ( candPV != NULL ) {
1022 bool useRefittedPvs = (
i%2 == 1 );
1023 bool doDCAin3D = ( (
i-7)%4 > 1 );
1024 int chi2DefToUse = (
i-7)/4;
1028 chi2DefToUse = (
i-13)/2;
1031 if ( chi2DefToUse == 5 ) {
1039 doDCAin3D, chi2DefToUse).first;
1041 if ( candPV == minChi2PV
1042 || (candRefPV !=
nullptr && candRefPV == minChi2PV) ) {
1074 for (
unsigned int i=0;
i < vtx.
vtx()->nTrackParticles(); ++
i) {
1076 if (
std::find(tracks.begin(),tracks.end(),track) == tracks.end() ) {
1077 tracks.push_back(track);
1111 if (
std::find(muons.begin(),muons.end(),vtx.
muon(
i)) == muons.end() ) {
1112 muons.push_back(vtx.
muon(
i));
1136 for (MuonBag::const_iterator muItr = muons.begin(); muItr != muons.end();
1139 (*muItr)->trackParticle(xAOD::Muon::InnerDetectorTrackParticle);
1140 tracks.push_back(track);
1150 std::vector<TVector3>
1154 std::vector<TVector3> refMuTracks;
1158 muons = vtx.
muons();
1159 for (
auto refMuTrack : vtx.
refTrks() ) {
1160 refMuTracks.push_back(refMuTrack);
1168 if ( otp != NULL ) {
1169 if (
std::find(muonIdTracks.begin(), muonIdTracks.end(), otp)
1170 != muonIdTracks.end() ) {
1171 refMuTracks.push_back(vtx.
refTrk(
i));
1175 " refTrkOrigin == NULL for refTrk # "
1181 " size mismatch #refTrks = " << vtx.
nRefTrks()
1189 std::vector<TVector3> precRefMuTracks =
1192 for (
auto precRefMuTrack : precRefMuTracks ) {
1193 if (
std::find(refMuTracks.begin(), refMuTracks.end(),
1194 precRefMuTrack) == refMuTracks.end() ) {
1195 refMuTracks.push_back(precRefMuTrack);
1204 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::findMuonRefTrackMomenta():"
1205 <<
" #muons: " << muons.size()
1206 <<
" #refMuTrks: " << refMuTracks.size());
1207 TString
str = Form(
">> refMuTracks(%d):\n", (
int)refMuTracks.size());
1208 for (
unsigned int i=0;
i < refMuTracks.size(); ++
i) {
1209 str += Form(
"(%10.4f,%10.4f,%10.4f) ",
1210 refMuTracks[
i].
x(), refMuTracks[
i].
y(),
1211 refMuTracks[
i].
z());
1228 const unsigned int ipv,
1229 const unsigned int its,
1230 const unsigned int itt)
const {
1245 const unsigned int ipv,
1246 const unsigned int its,
1247 const unsigned int itt)
const {
1253 <<
" " << exclTracks
1254 <<
" for decay candidate " << cand.
vtx()
1255 <<
"; candPV: " << candPV <<
" candRefPV: " << candRefPV);
1262 inpTracks->
begin(); trkItr != inpTracks->
end(); ++trkItr) {
1267 trackTypesForTrack =
detTrackTypes(track, candPV, candRefPV);
1268 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"all");
1274 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"ats");
1282 if ( trackTypesForTrack == 0x0 ) {
1283 trackTypesForTrack =
detTrackTypes(track, candPV, candRefPV);
1291 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"att");
1294 if (
std::find(exclTracks.begin(), exclTracks.end(), track)
1295 != exclTracks.end() )
continue;
1298 m_mttc->addToCounter(trackTypesForTrack, itt, bname,
"fin");
1301 tracks.push_back(track);
1313 const std::string& preSuffix)
1316 ATH_MSG_DEBUG(
"BPhysVertexTrackBase::buildBranchBaseName -- begin");
1322 std::size_t ipos = tsName.find_last_of(
"_");
1323 if ( ipos != std::string::npos ) tsName = tsName.substr(ipos+1);
1328 (preSuffix.length() > 0 ?
"_" + preSuffix :
""),
1331 ATH_MSG_DEBUG(
"BPhysVertexBaseTrackBase::buildBranchBaseName: " <<
f);
1357 std::pair<const xAOD::Vertex*, double>
1361 const std::vector<uint64_t>& pvtypes,
1362 const int minNTracksInPV,
1363 const bool useRefittedPvs,
1364 const bool doDCAin3D,
1365 const int chi2DefToUse)
const {
1371 if ( pvtx !=
nullptr ) {
1372 if (
std::find(pvtypes.begin(),pvtypes.end(),pvtx->vertexType())
1373 != pvtypes.end() ) {
1376 if ( useRefittedPvs && pvtx == candPV ) {
1377 if ( candRefPV !=
nullptr ) {
1381 <<
" candRefPV == NULL!");
1388 if (
chi2 < minChi2 ) {
1397 return std::make_pair(minChi2PV, minChi2);
1413 const std::vector<uint64_t>& pvtypes,
1414 const int minNTracksInPV,
1415 const bool useRefittedPvs)
const {
1418 std::vector<const xAOD::Vertex*> vpvtx;
1420 if ( pvtx !=
nullptr ) {
1421 if (
std::find(pvtypes.begin(),pvtypes.end(),pvtx->vertexType())
1422 != pvtypes.end() ) {
1425 if ( useRefittedPvs && pvtx == candPV ) {
1426 if ( candRefPV !=
nullptr ) {
1430 <<
" candRefPV == NULL!");
1435 vpvtx.push_back(cvtx);
1448 if ( *
tp == track ) {
1450 assocPV = candRefPV;
1455 if ( assocPV ==
nullptr ) {
1456 assocPV =
m_tvaTool->getUniqueMatchVertex(*track, vpvtx);
1459 assocPV =
m_tvaTool->getUniqueMatchVertex(*track, vpvtx);
1461 if ( assocPV ==
nullptr ) {
1463 <<
" assocPV == NULL for track!"
1464 <<
" len(vpvtx) = " << vpvtx.size()
1465 <<
" useRefittedPvs = " << useRefittedPvs
1466 <<
" minNTracksInPV = " << minNTracksInPV);