From c62700ad6da4247ec8983e4476cae99ecef4653f Mon Sep 17 00:00:00 2001 From: Maurice Coquet Date: Mon, 22 Jun 2026 21:02:37 +0200 Subject: [PATCH 1/5] [PWGDQ] Bug fixes in global-muon-matcher --- PWGDQ/Tasks/global-muon-matcher.cxx | 206 +++++++++++++--------------- 1 file changed, 94 insertions(+), 112 deletions(-) diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx index 09b68924722..41d4fb9ecc3 100644 --- a/PWGDQ/Tasks/global-muon-matcher.cxx +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -16,30 +16,28 @@ #include "PWGDQ/Core/VarManager.h" #include "Common/Core/fwdtrackUtilities.h" -#include "Common/DataModel/Centrality.h" -#include "Common/DataModel/CollisionAssociationTables.h" #include "Common/DataModel/EventSelection.h" #include "Common/DataModel/FwdTrackReAlignTables.h" -#include "Common/DataModel/Multiplicity.h" -#include "Common/DataModel/TrackSelectionTables.h" #include "Tools/ML/MlResponse.h" #include #include #include #include -#include #include #include #include #include #include #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -47,24 +45,24 @@ #include #include #include +#include #include #include -#include -#include #include #include #include +#include #include #include #include #include -#include #include +#include #include +#include #include -#include #include #include #include @@ -117,8 +115,8 @@ using SMatrix55Sym = o2::track::SMatrix55Sym; using SMatrix55Std = o2::track::SMatrix55Std; using SMatrix5 = o2::track::SMatrix5; -const int fgNDetElemCh[10] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; -const int fgSNDetElemCh[11] = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; +constexpr std::array fgNDetElemCh = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; +constexpr std::array fgSNDetElemCh = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; struct GlobalMuonMatching { @@ -128,11 +126,8 @@ struct GlobalMuonMatching { static constexpr int MchDetElemNumberingBase = 100; static constexpr int NMchDetElems = 156; static constexpr int MinRemovableTrackClusters = 10; - static constexpr double DefaultChamberResolution = 0.04; static constexpr int ThetaAbsBoundaryDeg = 3; static constexpr double SlopeResolutionZ = 535.; - static constexpr int MatchingDegreesOfFreedom = 5; - static constexpr float MatchingScoreChi2Max = 50.f; static constexpr float MatchingPlaneDefaultZ = -77.5; struct MatchingCandidate { @@ -231,7 +226,7 @@ struct GlobalMuonMatching { } configMlOptions; std::vector binsPtMl; - std::array cutValues; + std::array cutValues{}; std::vector cutDirMl; bool hasActiveChi2Matching{false}; std::string activeChi2FunctionName; @@ -243,7 +238,7 @@ struct GlobalMuonMatching { int mRunNumber{0}; // needed to detect if the run changed and trigger update of magnetic field - Service ccdbManager; + Service ccdbManager{}; o2::ccdb::CcdbApi fCCDBApi; // vector of all MFT-MCH(-MID) matching candidates associated to the same MCH(-MID) track, @@ -275,10 +270,10 @@ struct GlobalMuonMatching { } void setNClusters(int n) { nClusters = n; } - int getNClusters() const { return nClusters; } + [[nodiscard]] int getNClusters() const { return nClusters; } void setRemovable() { removable = true; } - bool isRemovable() const { return removable; } + [[nodiscard]] bool isRemovable() const { return removable; } private: int nClusters{-1}; @@ -310,7 +305,7 @@ struct GlobalMuonMatching { mch::geo::TransformationCreator transformation; std::map transformRef; // reference geometry w.r.t track data std::map transformNew; // new geometry - double mImproveCutChi2; // Chi2 cut for track improvement. + double mImproveCutChi2{0.}; // Chi2 cut for track improvement. TGeoManager* geoNew = nullptr; TGeoManager* geoRef = nullptr; globaltracking::MatchGlobalFwd mMatching; @@ -324,18 +319,16 @@ struct GlobalMuonMatching { // MCH track format. // Parameter conversion - double alpha1, alpha3, alpha4, x2, x3, x4; + const double x2 = fwdtrack.getPhi(); + const double x3 = fwdtrack.getTanl(); + const double x4 = fwdtrack.getInvQPt(); - x2 = fwdtrack.getPhi(); - x3 = fwdtrack.getTanl(); - x4 = fwdtrack.getInvQPt(); + const auto sinx2 = TMath::Sin(x2); + const auto cosx2 = TMath::Cos(x2); - auto sinx2 = TMath::Sin(x2); - auto cosx2 = TMath::Cos(x2); - - alpha1 = cosx2 / x3; - alpha3 = sinx2 / x3; - alpha4 = x4 / TMath::Sqrt(x3 * x3 + sinx2 * sinx2); + const double alpha1 = cosx2 / x3; + const double alpha3 = sinx2 / x3; + const double alpha4 = x4 / TMath::Sqrt(x3 * x3 + sinx2 * sinx2); auto K = TMath::Sqrt(x3 * x3 + sinx2 * sinx2); auto K3 = K * K * K; @@ -380,11 +373,11 @@ struct GlobalMuonMatching { // jacobian*covariances*jacobian^T covariances = ROOT::Math::Similarity(jacobian, covariances); - double cov[] = {covariances(0, 0), covariances(1, 0), covariances(1, 1), covariances(2, 0), covariances(2, 1), covariances(2, 2), covariances(3, 0), covariances(3, 1), covariances(3, 2), covariances(3, 3), covariances(4, 0), covariances(4, 1), covariances(4, 2), covariances(4, 3), covariances(4, 4)}; - double param[] = {fwdtrack.getX(), alpha1, fwdtrack.getY(), alpha3, alpha4}; + std::array cov = {covariances(0, 0), covariances(1, 0), covariances(1, 1), covariances(2, 0), covariances(2, 1), covariances(2, 2), covariances(3, 0), covariances(3, 1), covariances(3, 2), covariances(3, 3), covariances(4, 0), covariances(4, 1), covariances(4, 2), covariances(4, 3), covariances(4, 4)}; + std::array param = {fwdtrack.getX(), alpha1, fwdtrack.getY(), alpha3, alpha4}; - o2::mch::TrackParam convertedTrack(fwdtrack.getZ(), param, cov); - return o2::mch::TrackParam(convertedTrack); + o2::mch::TrackParam convertedTrack(fwdtrack.getZ(), param.data(), cov.data()); + return {convertedTrack}; } o2::track::TrackParCovFwd MCHtoFwd(const o2::mch::TrackParam& mchParam) @@ -395,15 +388,13 @@ struct GlobalMuonMatching { o2::track::TrackParCovFwd convertedTrack; // Parameter conversion - double alpha1, alpha3, alpha4, x2, x3, x4; - - alpha1 = mchParam.getNonBendingSlope(); - alpha3 = mchParam.getBendingSlope(); - alpha4 = mchParam.getInverseBendingMomentum(); + const double alpha1 = mchParam.getNonBendingSlope(); + const double alpha3 = mchParam.getBendingSlope(); + const double alpha4 = mchParam.getInverseBendingMomentum(); - x2 = TMath::ATan2(-alpha3, -alpha1); - x3 = -1. / TMath::Sqrt(alpha3 * alpha3 + alpha1 * alpha1); - x4 = alpha4 * -x3 * TMath::Sqrt(1 + alpha3 * alpha3); + const double x2 = TMath::ATan2(-alpha3, -alpha1); + const double x3 = -1. / TMath::Sqrt(alpha3 * alpha3 + alpha1 * alpha1); + const double x4 = alpha4 * -x3 * TMath::Sqrt(1 + alpha3 * alpha3); auto K = alpha1 * alpha1 + alpha3 * alpha3; auto K32 = K * TMath::Sqrt(K); @@ -466,8 +457,8 @@ struct GlobalMuonMatching { int GetDetElemId(int iDetElemNumber) { // make sure detector number is valid - if (!(iDetElemNumber >= fgSNDetElemCh[0] && - iDetElemNumber < fgSNDetElemCh[NMchChambers])) { + if (iDetElemNumber < fgSNDetElemCh[0] || + iDetElemNumber >= fgSNDetElemCh[NMchChambers]) { LOGF(fatal, "Invalid detector element number: %d", iDetElemNumber); } /// get det element number from ID @@ -483,7 +474,7 @@ struct GlobalMuonMatching { } // make sure detector index is valid - if (!(iCh > 0 && iCh <= NMchChambers && iDet < fgNDetElemCh[iCh - 1])) { + if (iCh <= 0 || iCh > NMchChambers || iDet >= fgNDetElemCh[iCh - 1]) { LOGF(fatal, "Invalid detector element id: %d", MchDetElemNumberingBase * iCh + iDet); } @@ -543,14 +534,13 @@ struct GlobalMuonMatching { if (track.getNClusters() < MinRemovableTrackClusters) { removeTrack = true; break; - } else { - while (itNextToNextParam != track.end()) { - if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) { - itStartingParam = std::make_reverse_iterator(++itNextParam); - break; - } - ++itNextToNextParam; + } + while (itNextToNextParam != track.end()) { + if (itNextToNextParam->getClusterPtr()->getChamberId() != itNextParam->getClusterPtr()->getChamberId()) { + itStartingParam = std::make_reverse_iterator(++itNextParam); + break; } + ++itNextToNextParam; } } @@ -567,8 +557,9 @@ struct GlobalMuonMatching { template void initCcdb(BC const& bc) { - if (mRunNumber == bc.runNumber()) + if (mRunNumber == bc.runNumber()) { return; + } mRunNumber = bc.runNumber(); std::map metadata; @@ -614,10 +605,10 @@ struct GlobalMuonMatching { } // Init magnetic field for MFT track extrapolation - auto* fieldB = static_cast(TGeoGlobalMagField::Instance()->GetField()); + auto* fieldB = dynamic_cast(TGeoGlobalMagField::Instance()->GetField()); if (fieldB) { - double centerMft[3] = {0, 0, -61.4}; // Field at center of MFT - mBzAtMftCenter = fieldB->getBz(centerMft); + std::array centerMft{0, 0, -61.4}; // Field at center of MFT + mBzAtMftCenter = fieldB->getBz(centerMft.data()); // std::cout << "fieldB: " << (void*)fieldB << std::endl; } } @@ -642,8 +633,8 @@ struct GlobalMuonMatching { SVector5 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(), mftTrack.getTanl(), mftTrack.getInvQPt()), rKKminus1; - SVector5 globalMuonTrackParameters = mchTrack.getParameters(); - SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances(); + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); vK(0, 0) = mftTrack.getCovariances()(0, 0); vK(1, 1) = mftTrack.getCovariances()(1, 1); vK(2, 2) = mftTrack.getCovariances()(2, 2); @@ -677,8 +668,8 @@ struct GlobalMuonMatching { SVector4 mK(mftTrack.getX(), mftTrack.getY(), mftTrack.getPhi(), mftTrack.getTanl()), rKKminus1; - SVector5 globalMuonTrackParameters = mchTrack.getParameters(); - SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances(); + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); vK(0, 0) = mftTrack.getCovariances()(0, 0); vK(1, 1) = mftTrack.getCovariances()(1, 1); vK(2, 2) = mftTrack.getCovariances()(2, 2); @@ -708,8 +699,8 @@ struct GlobalMuonMatching { SMatrix25 hK; SMatrix22 vK; SVector2 mK(mftTrack.getX(), mftTrack.getY()), rKKminus1; - SVector5 globalMuonTrackParameters = mchTrack.getParameters(); - SMatrix55Sym globalMuonTrackCovariances = mchTrack.getCovariances(); + const auto& globalMuonTrackParameters = mchTrack.getParameters(); + const auto& globalMuonTrackCovariances = mchTrack.getCovariances(); vK(0, 0) = mftTrack.getCovariances()(0, 0); vK(1, 1) = mftTrack.getCovariances()(1, 1); hK(0, 0) = 1.0; @@ -760,7 +751,7 @@ struct GlobalMuonMatching { auto funcName = configChi2MatchingOptions.cfgChi2FunctionName.value; auto matchingPlaneZ = configChi2MatchingOptions.cfgChi2FunctionMatchingPlaneZ.value; - if (label != "" && funcName != "") { + if (!label.empty() && !funcName.empty()) { hasActiveChi2Matching = true; activeChi2FunctionName = funcName; activeChi2MatchingPlaneZ = matchingPlaneZ; @@ -771,7 +762,7 @@ struct GlobalMuonMatching { binsPtMl = {-1e-6, 1000.0}; cutValues = {0.0}; cutDirMl = {cuts_ml::CutNot}; - o2::framework::LabeledArray mycutsMl(cutValues.data(), 1, 1, std::vector{"pT bin 0"}, std::vector{"score"}); + LabeledArray mycutsMl(cutValues.data(), 1, 1, std::vector{"pT bin 0"}, std::vector{"score"}); auto label = configMlOptions.cfgMlModelLabel.value; auto modelPath = configMlOptions.cfgMlModelPathCcdb.value; @@ -779,7 +770,7 @@ struct GlobalMuonMatching { auto modelName = configMlOptions.cfgMlModelName.value; auto matchingPlaneZ = configMlOptions.cfgMlModelMatchingPlaneZ.value; - if (label != "" && modelPath != "" && !inputFeatures.empty() && modelName != "") { + if (!label.empty() && !modelPath.empty() && !inputFeatures.empty() && !modelName.empty()) { activeMlResponse.configure(binsPtMl, mycutsMl, cutDirMl, 1); activeMlResponse.setModelPathsCCDB(std::vector{modelName}, fCCDBApi, std::vector{modelPath}, configCcdb.cfgCcdbNoLaterThan.value); activeMlResponse.cacheInputFeaturesIndices(inputFeatures); @@ -815,11 +806,7 @@ struct GlobalMuonMatching { double pResEffect = sigmaPDCA / (1. - nrp / (1. + nrp)); double slopeResEffect = SlopeResolutionZ * slopeRes * p; double sigmaPDCAWithRes = std::sqrt(pResEffect * pResEffect + slopeResEffect * slopeResEffect); - if (pDCA > nSigmaPDCA * sigmaPDCAWithRes) { - return false; - } - - return true; + return pDCA <= nSigmaPDCA * sigmaPDCAWithRes; } template @@ -832,8 +819,9 @@ struct GlobalMuonMatching { double nSigmaPdcaCut) { // chi2 cut - if (mchTrack.chi2() > chi2Cut) + if (mchTrack.chi2() > chi2Cut) { return false; + } // momentum cut if (mchTrack.p() < pCut) { @@ -858,11 +846,7 @@ struct GlobalMuonMatching { } // pDCA cut - if (!pDcaCut(mchTrack, collision, nSigmaPdcaCut)) { - return false; - } - - return true; + return pDcaCut(mchTrack, collision, nSigmaPdcaCut); } void storeFwdTrackCovariance(const SMatrix55Sym& cov) @@ -931,8 +915,7 @@ struct GlobalMuonMatching { storeFwdTrackCovariance(trackPar.getCovariances()); if (hasBcSlice) { - int32_t bcSliceArray[2] = {bcSlice[0], bcSlice[1]}; - gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSliceArray); + gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSlice.data()); } mGmmCandFwdTrackRowIndex += 1; @@ -965,7 +948,7 @@ struct GlobalMuonMatching { const auto globalMuonRefit = o2::aod::fwdtrackutils::refitGlobalMuonCov(MCHtoFwd(propmuonAtMft), mftPar); - int8_t nClusters = static_cast(std::min(127, static_cast(mchPar.getNClusters()) + static_cast(mftPar.getNClusters()))); + const auto nClusters = static_cast(std::min(127, mchPar.getNClusters() + mftPar.getNClusters())); const float chi2 = static_cast(mchTrack.chi2()); const int32_t collisionId = mchTrack.has_collision() ? mchTrack.collisionId() : -1; @@ -1013,8 +996,7 @@ struct GlobalMuonMatching { storeFwdTrackCovariance(globalMuonRefit.getCovariances()); if (hasBcSlice) { - int32_t bcSliceArray[2] = {bcSlice[0], bcSlice[1]}; - gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSliceArray); + gmAmbiguousFwdTracksReAlign(mGmmCandFwdTrackRowIndex, bcSlice.data()); } mGmmCandFwdTrackRowIndex += 1; } @@ -1073,8 +1055,9 @@ struct GlobalMuonMatching { } // only select MCH-MID tracks associated to a collision - if (!muonTrack.has_collision()) + if (!muonTrack.has_collision()) { continue; + } const auto& collision = collisions.rawIteratorAt(muonTrack.collisionId()); @@ -1095,14 +1078,16 @@ struct GlobalMuonMatching { // propagate the track from the vertex to the first MFT plane const auto& extrapToMFTfirst = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[0]); double rFront = std::sqrt(extrapToMFTfirst.getX() * extrapToMFTfirst.getX() + extrapToMFTfirst.getY() * extrapToMFTfirst.getY()); - if (rFront < configMuonTagging.cfgMuonTaggingRadiusAtMftFrontLow.value || rFront > configMuonTagging.cfgMuonTaggingRadiusAtMftFrontUp.value) + if (rFront < configMuonTagging.cfgMuonTaggingRadiusAtMftFrontLow.value || rFront > configMuonTagging.cfgMuonTaggingRadiusAtMftFrontUp.value) { continue; + } // propagate the track from the vertex to the last MFT plane const auto& extrapToMFTlast = propagateToZMch(mchTrackAtVertex, o2::mft::constants::mft::LayerZCoordinate()[9]); double rBack = std::sqrt(extrapToMFTlast.getX() * extrapToMFTlast.getX() + extrapToMFTlast.getY() * extrapToMFTlast.getY()); - if (rBack < configMuonTagging.cfgMuonTaggingRadiusAtMftBackLow.value || rBack > configMuonTagging.cfgMuonTaggingRadiusAtMftBackUp.value) + if (rBack < configMuonTagging.cfgMuonTaggingRadiusAtMftBackLow.value || rBack > configMuonTagging.cfgMuonTaggingRadiusAtMftBackUp.value) { continue; + } int64_t muonTrackIndex = muonTrack.globalIndex(); taggedMuons.emplace_back(muonTrackIndex); @@ -1152,16 +1137,14 @@ struct GlobalMuonMatching { auto mchTrackIndex = muonTrack.globalIndex(); // initialize the MCH track parameters, which will be updated by the realignment if enabled - if (mMchTrackPars.count(mchTrackIndex) == 0) { - mMchTrackPars.emplace(mchTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(muonTrack, muonTrack), muonTrack.nClusters())); - } + mMchTrackPars.try_emplace(mchTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(muonTrack, muonTrack), muonTrack.nClusters())); } for (const auto& mftTrack : mftTracks) { auto mftTrackIndex = mftTrack.globalIndex(); // initialize the MFT track parameters, which will be updated by the alignment corrections if enabled - if (mftTrackCovs.count(mftTrackIndex) > 0 && mMftTrackPars.count(mftTrackIndex) == 0) { + if (mftTrackCovs.contains(mftTrackIndex) && !mMftTrackPars.contains(mftTrackIndex)) { auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrackIndex]); mMftTrackPars.emplace(mftTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(mftTrack, mftTrackCov), mftTrack.nClusters())); } @@ -1181,15 +1164,15 @@ struct GlobalMuonMatching { auto const& mftTrack = muonTrack.template matchMFTTrack_as(); int64_t mftTrackIndex = mftTrack.globalIndex(); - if (mftTrackCovs.count(mftTrackIndex) < 1) { + if (!mftTrackCovs.contains(mftTrackIndex)) { continue; } mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ - muonTrack.globalIndex(), - mftTrackIndex, - muonTrack.matchScoreMCHMFT(), - muonTrack.chi2MatchMCHMFT()}); + .muonTrackId = muonTrack.globalIndex(), + .mftTrackId = mftTrackIndex, + .matchScore = muonTrack.matchScoreMCHMFT(), + .matchChi2 = muonTrack.chi2MatchMCHMFT()}); } } else { // build matching candidates from all time-compatible MFT-MCH pairs @@ -1202,13 +1185,12 @@ struct GlobalMuonMatching { if (!isMftMchTimeCompatible(collisions, bcs, muonTrack, mftTrack)) { continue; } - if (mftTrackCovs.count(mftTrack.globalIndex()) < 1) { + if (!mftTrackCovs.contains(mftTrack.globalIndex())) { continue; } mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ - -1, - mftTrack.globalIndex()}); + .mftTrackId = mftTrack.globalIndex()}); } } } @@ -1258,7 +1240,7 @@ struct GlobalMuonMatching { { for (const auto& mftTrack : mftTracks) { auto mftTrackIndex = mftTrack.globalIndex(); - if (mftTrackCovs.count(mftTrackIndex) < 0) { + if (!mftTrackCovs.contains(mftTrackIndex)) { continue; } @@ -1293,7 +1275,7 @@ struct GlobalMuonMatching { for (auto const& cluster : clustersSliced) { clIndex += 1; - mch::Cluster* clusterMCH = new mch::Cluster(); + auto* clusterMCH = new mch::Cluster(); math_utils::Point3D local; math_utils::Point3D master; @@ -1339,7 +1321,7 @@ struct GlobalMuonMatching { } } - void runChi2Matching(std::string funcName, + void runChi2Matching(const std::string& funcName, float matchingPlaneZ, const MatchingCandidates& matchingCandidates, MatchingCandidates& newMatchingCandidates) @@ -1353,7 +1335,7 @@ struct GlobalMuonMatching { matchingPlaneZEffective = MatchingPlaneDefaultZ; } - if (mMatchingFunctionMap.count(funcNameEffective) < 1) { + if (!mMatchingFunctionMap.contains(funcNameEffective)) { return; } auto matchingFunc = mMatchingFunctionMap.at(funcNameEffective); @@ -1372,8 +1354,8 @@ struct GlobalMuonMatching { continue; } - o2::track::TrackParCovFwd mftTrackProp = mftTrackParIt->second; - o2::track::TrackParCovFwd mchTrackProp = mchTrackParIt->second; + o2::track::TrackParCovFwd mftTrackProp(static_cast(mftTrackParIt->second)); + o2::track::TrackParCovFwd mchTrackProp(static_cast(mchTrackParIt->second)); if (matchingPlaneZEffective < 0.) { mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ); @@ -1384,10 +1366,10 @@ struct GlobalMuonMatching { float matchChi2 = std::get<0>(matchResult); newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ - candidate.muonTrackId, - candidate.mftTrackId, - -1, - matchChi2}); + .muonTrackId = candidate.muonTrackId, + .mftTrackId = candidate.mftTrackId, + .matchScore = -1, + .matchChi2 = matchChi2}); } } @@ -1438,8 +1420,8 @@ struct GlobalMuonMatching { continue; } - o2::track::TrackParCovFwd mftTrackProp = mftTrackParIt->second; - o2::track::TrackParCovFwd mchTrackProp = mchTrackParIt->second; + o2::track::TrackParCovFwd mftTrackProp(static_cast(mftTrackParIt->second)); + o2::track::TrackParCovFwd mchTrackProp(static_cast(mchTrackParIt->second)); if (matchingPlaneZ < 0.) { mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ); @@ -1452,10 +1434,10 @@ struct GlobalMuonMatching { float matchScore = output[0]; newMatchingCandidates[mchIndex].emplace_back(MatchingCandidate{ - candidate.muonTrackId, - candidate.mftTrackId, - matchScore, - -1}); + .muonTrackId = candidate.muonTrackId, + .mftTrackId = candidate.mftTrackId, + .matchScore = matchScore, + .matchChi2 = -1}); } } @@ -1576,7 +1558,7 @@ struct GlobalMuonMatching { if (trackType > GlobalTrackTypeMax) { mFwdTrackToGmmCandTrkIndex[track.globalIndex()] = nextGmmCandTrkIndex; nextGmmCandTrkIndex += 1 + countStoredCandidatesForMchTrack(track.globalIndex()); - } else if (configMatching.cfgIncludeGlobalMuonsInFwdTracks.value && trackType <= GlobalTrackTypeMax) { + } else if (configMatching.cfgIncludeGlobalMuonsInFwdTracks.value) { nextGmmCandTrkIndex += 1; } } From 2ce87a96edc103141593f020adac2c5d3891dfd7 Mon Sep 17 00:00:00 2001 From: Maurice Coquet Date: Mon, 22 Jun 2026 21:04:31 +0200 Subject: [PATCH 2/5] clang format --- PWGDQ/Tasks/global-muon-matcher.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx index 41d4fb9ecc3..4fc3cdda9ce 100644 --- a/PWGDQ/Tasks/global-muon-matcher.cxx +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -305,7 +305,7 @@ struct GlobalMuonMatching { mch::geo::TransformationCreator transformation; std::map transformRef; // reference geometry w.r.t track data std::map transformNew; // new geometry - double mImproveCutChi2{0.}; // Chi2 cut for track improvement. + double mImproveCutChi2{0.}; // Chi2 cut for track improvement. TGeoManager* geoNew = nullptr; TGeoManager* geoRef = nullptr; globaltracking::MatchGlobalFwd mMatching; From 3082ea8ae2dcd16416c13c745f23018caa7ce2ad Mon Sep 17 00:00:00 2001 From: Maurice Coquet Date: Mon, 22 Jun 2026 22:04:22 +0200 Subject: [PATCH 3/5] fixing linter issues --- PWGDQ/Tasks/global-muon-matcher.cxx | 140 ++++++++++++++-------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx index 4fc3cdda9ce..bf683348c46 100644 --- a/PWGDQ/Tasks/global-muon-matcher.cxx +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -9,9 +9,10 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. // -/// \file globalMuonMatching.cxx -/// \brief Global muon matching -// +/// \file global-muon-matcher.cxx +/// \brief Task for analysis MFT-MCH muon matching +/// \author Andrea Ferrero +/// #include "PWGDQ/Core/MuonMatchingMlResponse.h" #include "PWGDQ/Core/VarManager.h" @@ -52,7 +53,6 @@ #include #include #include -#include #include #include @@ -96,14 +96,14 @@ namespace globalmuonmatching { DECLARE_SOA_ARRAY_INDEX_COLUMN(GlobalMuonMatchCandidate, globalMuonMatchCandidate); //! Array of GlobalMuonMatchCandidates indices DECLARE_SOA_INDEX_COLUMN_FULL(FwdTrackRealign, fwdTrackRealign, int, FwdTracksReAlign, ""); //! Index of ambiguous FwdTracksReAlign entry -DECLARE_SOA_SLICE_INDEX_COLUMN(BC, bc); //! BC index slice compatible with the track time window +DECLARE_SOA_SLICE_INDEX_COLUMN(Bc, bc); //! BC index slice compatible with the track time window } // namespace globalmuonmatching DECLARE_SOA_TABLE(FwdTrkMatchCands, "AOD", "FWDTRKMATCHCAND", //! Vectors of match-candidate indices stored per fwdtrack globalmuonmatching::GlobalMuonMatchCandidateIds, o2::soa::Marker<3>); DECLARE_SOA_TABLE(AmbiguousFwdTracksReAlign, "AOD", "AMBIGFWDREALIGN", //! FwdTracksReAlign entries without a unique collision association - o2::soa::Index<>, globalmuonmatching::FwdTrackRealignId, globalmuonmatching::BCIdSlice); + o2::soa::Index<>, globalmuonmatching::FwdTrackRealignId, globalmuonmatching::BcIdSlice); } // namespace o2::aod using MyEvents = soa::Join; @@ -115,8 +115,8 @@ using SMatrix55Sym = o2::track::SMatrix55Sym; using SMatrix55Std = o2::track::SMatrix55Std; using SMatrix5 = o2::track::SMatrix5; -constexpr std::array fgNDetElemCh = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; -constexpr std::array fgSNDetElemCh = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; +constexpr std::array NDetElemCh = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26}; +constexpr std::array SNDetElemCh = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156}; struct GlobalMuonMatching { @@ -313,7 +313,7 @@ struct GlobalMuonMatching { Preslice perMuon = aod::fwdtrkcl::fwdtrackId; template - o2::mch::TrackParam FwdtoMCH(const T& fwdtrack) + o2::mch::TrackParam fwdToMch(const T& fwdtrack) { // Convert Forward Track parameters and covariances matrix to the // MCH track format. @@ -323,15 +323,15 @@ struct GlobalMuonMatching { const double x3 = fwdtrack.getTanl(); const double x4 = fwdtrack.getInvQPt(); - const auto sinx2 = TMath::Sin(x2); - const auto cosx2 = TMath::Cos(x2); + const auto sinX2 = std::sin(x2); + const auto cosX2 = std::cos(x2); - const double alpha1 = cosx2 / x3; - const double alpha3 = sinx2 / x3; - const double alpha4 = x4 / TMath::Sqrt(x3 * x3 + sinx2 * sinx2); + const double alpha1 = cosX2 / x3; + const double alpha3 = sinX2 / x3; + const double alpha4 = x4 / std::sqrt(x3 * x3 + sinX2 * sinX2); - auto K = TMath::Sqrt(x3 * x3 + sinx2 * sinx2); - auto K3 = K * K * K; + const auto kNorm = std::sqrt(x3 * x3 + sinX2 * sinX2); + const auto kNorm3 = kNorm * kNorm * kNorm; // Covariances matrix conversion SMatrix55Std jacobian; @@ -359,17 +359,17 @@ struct GlobalMuonMatching { jacobian(0, 0) = 1; - jacobian(1, 2) = -sinx2 / x3; - jacobian(1, 3) = -cosx2 / (x3 * x3); + jacobian(1, 2) = -sinX2 / x3; + jacobian(1, 3) = -cosX2 / (x3 * x3); jacobian(2, 1) = 1; - jacobian(3, 2) = cosx2 / x3; - jacobian(3, 3) = -sinx2 / (x3 * x3); + jacobian(3, 2) = cosX2 / x3; + jacobian(3, 3) = -sinX2 / (x3 * x3); - jacobian(4, 2) = -x4 * sinx2 * cosx2 / K3; - jacobian(4, 3) = -x3 * x4 / K3; - jacobian(4, 4) = 1 / K; + jacobian(4, 2) = -x4 * sinX2 * cosX2 / kNorm3; + jacobian(4, 3) = -x3 * x4 / kNorm3; + jacobian(4, 4) = 1 / kNorm; // jacobian*covariances*jacobian^T covariances = ROOT::Math::Similarity(jacobian, covariances); @@ -380,7 +380,7 @@ struct GlobalMuonMatching { return {convertedTrack}; } - o2::track::TrackParCovFwd MCHtoFwd(const o2::mch::TrackParam& mchParam) + o2::track::TrackParCovFwd mchToFwd(const o2::mch::TrackParam& mchParam) { // Convert a MCH Track parameters and covariances matrix to the // Forward track format. Must be called after propagation though the absorber @@ -392,13 +392,13 @@ struct GlobalMuonMatching { const double alpha3 = mchParam.getBendingSlope(); const double alpha4 = mchParam.getInverseBendingMomentum(); - const double x2 = TMath::ATan2(-alpha3, -alpha1); - const double x3 = -1. / TMath::Sqrt(alpha3 * alpha3 + alpha1 * alpha1); - const double x4 = alpha4 * -x3 * TMath::Sqrt(1 + alpha3 * alpha3); + const double x2 = std::atan2(-alpha3, -alpha1); + const double x3 = -1. / std::sqrt(alpha3 * alpha3 + alpha1 * alpha1); + const double x4 = alpha4 * -x3 * std::sqrt(1 + alpha3 * alpha3); - auto K = alpha1 * alpha1 + alpha3 * alpha3; - auto K32 = K * TMath::Sqrt(K); - auto L = TMath::Sqrt(alpha3 * alpha3 + 1); + const auto kNorm = alpha1 * alpha1 + alpha3 * alpha3; + const auto kNorm32 = kNorm * std::sqrt(kNorm); + const auto slopeLen = std::sqrt(alpha3 * alpha3 + 1); // Covariances matrix conversion SMatrix55Std jacobian; @@ -428,15 +428,15 @@ struct GlobalMuonMatching { jacobian(1, 2) = 1; - jacobian(2, 1) = -alpha3 / K; - jacobian(2, 3) = alpha1 / K; + jacobian(2, 1) = -alpha3 / kNorm; + jacobian(2, 3) = alpha1 / kNorm; - jacobian(3, 1) = alpha1 / K32; - jacobian(3, 3) = alpha3 / K32; + jacobian(3, 1) = alpha1 / kNorm32; + jacobian(3, 3) = alpha3 / kNorm32; - jacobian(4, 1) = -alpha1 * alpha4 * L / K32; - jacobian(4, 3) = alpha3 * alpha4 * (1 / (TMath::Sqrt(K) * L) - L / K32); - jacobian(4, 4) = L / TMath::Sqrt(K); + jacobian(4, 1) = -alpha1 * alpha4 * slopeLen / kNorm32; + jacobian(4, 3) = alpha3 * alpha4 * (1 / (std::sqrt(kNorm) * slopeLen) - slopeLen / kNorm32); + jacobian(4, 4) = slopeLen / std::sqrt(kNorm); // jacobian*covariances*jacobian^T covariances = ROOT::Math::Similarity(jacobian, covariances); @@ -454,11 +454,11 @@ struct GlobalMuonMatching { return convertedTrack; } - int GetDetElemId(int iDetElemNumber) + int getDetElemId(int iDetElemNumber) { // make sure detector number is valid - if (iDetElemNumber < fgSNDetElemCh[0] || - iDetElemNumber >= fgSNDetElemCh[NMchChambers]) { + if (iDetElemNumber < SNDetElemCh[0] || + iDetElemNumber >= SNDetElemCh[NMchChambers]) { LOGF(fatal, "Invalid detector element number: %d", iDetElemNumber); } /// get det element number from ID @@ -466,15 +466,15 @@ struct GlobalMuonMatching { int iCh = 0; int iDet = 0; for (int i = 1; i <= NMchChambers; i++) { - if (iDetElemNumber < fgSNDetElemCh[i]) { + if (iDetElemNumber < SNDetElemCh[i]) { iCh = i; - iDet = iDetElemNumber - fgSNDetElemCh[i - 1]; + iDet = iDetElemNumber - SNDetElemCh[i - 1]; break; } } // make sure detector index is valid - if (iCh <= 0 || iCh > NMchChambers || iDet >= fgNDetElemCh[iCh - 1]) { + if (iCh <= 0 || iCh > NMchChambers || iDet >= NDetElemCh[iCh - 1]) { LOGF(fatal, "Invalid detector element id: %d", MchDetElemNumberingBase * iCh + iDet); } @@ -482,15 +482,15 @@ struct GlobalMuonMatching { return MchDetElemNumberingBase * iCh + iDet; } - bool RemoveTrack(mch::Track& track) + bool removeTrack(mch::Track& track) { // Refit track with re-aligned clusters - bool removeTrack = false; + bool shouldRemoveTrack = false; try { trackFitter.fit(track, false); } catch (std::exception const& e) { - removeTrack = true; - return removeTrack; + shouldRemoveTrack = true; + return shouldRemoveTrack; } auto itStartingParam = std::prev(track.rend()); @@ -500,7 +500,7 @@ struct GlobalMuonMatching { try { trackFitter.fit(track, true, false, (itStartingParam == track.rbegin()) ? nullptr : &itStartingParam); } catch (std::exception const&) { - removeTrack = true; + shouldRemoveTrack = true; break; } @@ -522,7 +522,7 @@ struct GlobalMuonMatching { } if (!itWorstParam->isRemovable()) { - removeTrack = true; + shouldRemoveTrack = true; track.removable(); break; } @@ -532,7 +532,7 @@ struct GlobalMuonMatching { itStartingParam = track.rbegin(); if (track.getNClusters() < MinRemovableTrackClusters) { - removeTrack = true; + shouldRemoveTrack = true; break; } while (itNextToNextParam != track.end()) { @@ -544,14 +544,14 @@ struct GlobalMuonMatching { } } - if (!removeTrack) { + if (!shouldRemoveTrack) { for (auto& param : track) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop) param.setParameters(param.getSmoothParameters()); param.setCovariances(param.getSmoothCovariances()); } } - return removeTrack; + return shouldRemoveTrack; } template @@ -586,7 +586,7 @@ struct GlobalMuonMatching { LOGF(fatal, "Reference aligned geometry object is not available in CCDB at timestamp=%llu", bc.timestamp()); } for (int i = 0; i < NMchDetElems; i++) { - int iDEN = GetDetElemId(i); + int iDEN = getDetElemId(i); transformRef[iDEN] = transformation(iDEN); } @@ -600,7 +600,7 @@ struct GlobalMuonMatching { LOGF(fatal, "New aligned geometry object is not available in CCDB at timestamp=%llu", bc.timestamp()); } for (int i = 0; i < NMchDetElems; i++) { - int iDEN = GetDetElemId(i); + int iDEN = getDetElemId(i); transformNew[iDEN] = transformation(iDEN); } @@ -936,9 +936,9 @@ struct GlobalMuonMatching { using o2::aod::fwdtrack::ForwardTrackTypeEnum; using o2::aod::fwdtrackutils::propagationPoint; - constexpr uint8_t candidateTrackType = static_cast(ForwardTrackTypeEnum::GlobalForwardTrack); + constexpr uint8_t CandidateTrackType = static_cast(ForwardTrackTypeEnum::GlobalForwardTrack); - auto propmuonAtMft = FwdtoMCH(mchPar); + auto propmuonAtMft = fwdToMch(mchPar); o2::mch::TrackExtrap::extrapToVertex(propmuonAtMft, mftPar.getX(), mftPar.getY(), @@ -946,7 +946,7 @@ struct GlobalMuonMatching { mftPar.getSigma2X(), mftPar.getSigma2Y()); - const auto globalMuonRefit = o2::aod::fwdtrackutils::refitGlobalMuonCov(MCHtoFwd(propmuonAtMft), mftPar); + const auto globalMuonRefit = o2::aod::fwdtrackutils::refitGlobalMuonCov(mchToFwd(propmuonAtMft), mftPar); const auto nClusters = static_cast(std::min(127, mchPar.getNClusters() + mftPar.getNClusters())); @@ -971,7 +971,7 @@ struct GlobalMuonMatching { gmCandidateFwdTracks( collisionId, - candidateTrackType, + CandidateTrackType, globalMuonRefit.getX(), globalMuonRefit.getY(), globalMuonRefit.getZ(), @@ -1003,7 +1003,7 @@ struct GlobalMuonMatching { o2::track::TrackParCovFwd propagateToZMch(const o2::track::TrackParCovFwd& muon, const double z) { - auto mchTrack = FwdtoMCH(muon); + auto mchTrack = fwdToMch(muon); float absFront = -90.f; float absBack = -505.f; @@ -1016,7 +1016,7 @@ struct GlobalMuonMatching { o2::mch::TrackExtrap::extrapToZCov(mchTrack, z); } - return MCHtoFwd(mchTrack); + return mchToFwd(mchTrack); } o2::track::TrackParCovFwd propagateToZMft(const o2::track::TrackParCovFwd& mftTrack, const double z) @@ -1030,14 +1030,14 @@ struct GlobalMuonMatching { o2::track::TrackParCovFwd propagateToVertexMch(const TMCH& muon, const C& collision) { - auto mchTrack = FwdtoMCH(fwdtrackutils::getTrackParCovFwd(muon, muon)); + auto mchTrack = fwdToMch(fwdtrackutils::getTrackParCovFwd(muon, muon)); o2::mch::TrackExtrap::extrapToVertex(mchTrack, collision.posX(), collision.posY(), collision.posZ(), collision.covXX(), collision.covYY()); - return MCHtoFwd(mchTrack); + return mchToFwd(mchTrack); } // tag muons based on the track quality and the track position at the front and back MFT planes @@ -1206,9 +1206,9 @@ struct GlobalMuonMatching { } template - o2::track::TrackParCovFwd TransformMFT(TMFT& mftTrack, TMFTCOV const& mftTrackCov) + o2::track::TrackParCovFwd transformMft(TMFT& mftTrack, TMFTCOV const& mftTrackCov) { - auto track = FwdtoMCH(fwdtrackutils::getTrackParCovFwd(mftTrack, mftTrackCov)); + auto track = fwdToMch(fwdtrackutils::getTrackParCovFwd(mftTrack, mftTrackCov)); double z = track.getZ(); // double dZ = zMCH - z; @@ -1232,7 +1232,7 @@ struct GlobalMuonMatching { track.setBendingCoor(y + yCorrection); track.setBendingSlope(ySlope + ySlopeCorrection); - return MCHtoFwd(track); + return mchToFwd(track); } template @@ -1245,7 +1245,7 @@ struct GlobalMuonMatching { } auto const& mftTrackCov = mftCovs.rawIteratorAt(mftTrackCovs[mftTrackIndex]); - mMftTrackPars[mftTrackIndex] = TransformMFT(mftTrack, mftTrackCov); + mMftTrackPars[mftTrackIndex] = transformMft(mftTrack, mftTrackCov); } } @@ -1289,8 +1289,8 @@ struct GlobalMuonMatching { clusterMCH->y = master.y(); clusterMCH->z = master.z(); - uint32_t ClUId = mch::Cluster::buildUniqueId(static_cast(cluster.deId() / 100) - 1, cluster.deId(), clIndex); - clusterMCH->uid = ClUId; + const uint32_t clUid = mch::Cluster::buildUniqueId(static_cast(cluster.deId() / 100) - 1, cluster.deId(), clIndex); + clusterMCH->uid = clUid; clusterMCH->ex = cluster.isGoodX() ? 0.2 : 10.0; clusterMCH->ey = cluster.isGoodY() ? 0.2 : 10.0; @@ -1303,7 +1303,7 @@ struct GlobalMuonMatching { // Refit the re-aligned track int removable = 0; if (convertedTrack.getNClusters() != 0) { - removable = RemoveTrack(convertedTrack); + removable = removeTrack(convertedTrack); } else { LOGF(fatal, "Muon track %d has no associated clusters.", muon.globalIndex()); } @@ -1312,7 +1312,7 @@ struct GlobalMuonMatching { mch::TrackParam trackParam = mch::TrackParam(convertedTrack.first()); // Convert MCH track to FWD track and store new parameters after realignment - mchTrackParIt->second = MCHtoFwd(mch::TrackParam(convertedTrack.first())); + mchTrackParIt->second = mchToFwd(mch::TrackParam(convertedTrack.first())); mchTrackParIt->second.setTrackChi2(trackParam.getTrackChi2() / convertedTrack.getNDF()); mchTrackParIt->second.setNClusters(convertedTrack.getNClusters()); if (removable) { From 38744b18d49a86d5d30e3ff55ab98b5f997fe23a Mon Sep 17 00:00:00 2001 From: Maurice Coquet Date: Mon, 22 Jun 2026 22:13:09 +0200 Subject: [PATCH 4/5] fixing issues --- PWGDQ/Tasks/global-muon-matcher.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx index bf683348c46..02733d21c41 100644 --- a/PWGDQ/Tasks/global-muon-matcher.cxx +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -96,7 +96,7 @@ namespace globalmuonmatching { DECLARE_SOA_ARRAY_INDEX_COLUMN(GlobalMuonMatchCandidate, globalMuonMatchCandidate); //! Array of GlobalMuonMatchCandidates indices DECLARE_SOA_INDEX_COLUMN_FULL(FwdTrackRealign, fwdTrackRealign, int, FwdTracksReAlign, ""); //! Index of ambiguous FwdTracksReAlign entry -DECLARE_SOA_SLICE_INDEX_COLUMN(Bc, bc); //! BC index slice compatible with the track time window +DECLARE_SOA_SLICE_INDEX_COLUMN_FULL(Bc, bc, int32_t, BCs, ""); //! BC index slice compatible with the track time window } // namespace globalmuonmatching DECLARE_SOA_TABLE(FwdTrkMatchCands, "AOD", "FWDTRKMATCHCAND", //! Vectors of match-candidate indices stored per fwdtrack From a63091b40ed7643011be5e17de038dd7f2398467 Mon Sep 17 00:00:00 2001 From: Maurice Coquet Date: Tue, 23 Jun 2026 11:20:21 +0200 Subject: [PATCH 5/5] further fix --- PWGDQ/Tasks/global-muon-matcher.cxx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/PWGDQ/Tasks/global-muon-matcher.cxx b/PWGDQ/Tasks/global-muon-matcher.cxx index 02733d21c41..99873fd115a 100644 --- a/PWGDQ/Tasks/global-muon-matcher.cxx +++ b/PWGDQ/Tasks/global-muon-matcher.cxx @@ -275,6 +275,8 @@ struct GlobalMuonMatching { void setRemovable() { removable = true; } [[nodiscard]] bool isRemovable() const { return removable; } + [[nodiscard]] o2::track::TrackParCovFwd asTrackParCovFwd() const { return *this; } + private: int nClusters{-1}; bool removable{false}; @@ -1354,8 +1356,8 @@ struct GlobalMuonMatching { continue; } - o2::track::TrackParCovFwd mftTrackProp(static_cast(mftTrackParIt->second)); - o2::track::TrackParCovFwd mchTrackProp(static_cast(mchTrackParIt->second)); + auto mftTrackProp = mftTrackParIt->second.asTrackParCovFwd(); + auto mchTrackProp = mchTrackParIt->second.asTrackParCovFwd(); if (matchingPlaneZEffective < 0.) { mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ); @@ -1420,8 +1422,8 @@ struct GlobalMuonMatching { continue; } - o2::track::TrackParCovFwd mftTrackProp(static_cast(mftTrackParIt->second)); - o2::track::TrackParCovFwd mchTrackProp(static_cast(mchTrackParIt->second)); + auto mftTrackProp = mftTrackParIt->second.asTrackParCovFwd(); + auto mchTrackProp = mchTrackParIt->second.asTrackParCovFwd(); if (matchingPlaneZ < 0.) { mftTrackProp = propagateToZMft(mftTrackProp, matchingPlaneZ);