Skip to content

Commit ae1ffb8

Browse files
committed
[PWGDQ] make matching QA table filling more flexible
Instead of using an hard-coded list of matching methods and corresponding indexes when filling the derived tables, the filling is done using a dynamic list of methods and correspoding indexes that is based on what is actually requested in the configuration. The horizontal bin labels of a dedicated TH1 histogram provide the correspondance between method labels and their indexes, to be used when reading back the derived tables to generate final histograms.
1 parent 43dfb1c commit ae1ffb8

1 file changed

Lines changed: 70 additions & 87 deletions

File tree

PWGDQ/Tasks/qaMatching.cxx

Lines changed: 70 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ struct QaMatching {
422422

423423
struct CollisionInfo {
424424
int64_t index{0};
425+
// internal index of this collision in the derived table
426+
int64_t reducedEventId{0};
425427
uint64_t bc{0};
426428
// z position of the collision
427429
double zVertex{0};
@@ -778,7 +780,7 @@ struct QaMatching {
778780
AxisSpec chi2Axis = {100, 0, 100, "matching #chi^{2}/NDF"};
779781
AxisSpec scoreAxis = {100, 0, 1, "matching score"};
780782
int matchTypeMax = static_cast<int>(kMatchTypeUndefined) + 1;
781-
AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast<double>(matchTypeMax), "match type"};
783+
AxisSpec matchTypeAxis = {matchTypeMax, 0, static_cast<double>(matchTypeMax), ""};
782784
histName = path + "matchType";
783785
histTitle = "Match type";
784786
fMatchType = registry->add(histName.c_str(), histTitle.c_str(), {HistType::kTH1F, {matchTypeAxis}});
@@ -1127,6 +1129,8 @@ struct QaMatching {
11271129
ccdbManager->get<TGeoManager>(geoPath);
11281130
}
11291131

1132+
std::vector<std::string> matchMethodLabels{"Prod", "Tagged"};
1133+
11301134
// Matching functions
11311135
initMatchingFunctions();
11321136
for (size_t funcId = 0; funcId < Chi2FunctionsNum; funcId++) {
@@ -1137,13 +1141,15 @@ struct QaMatching {
11371141
auto extrapMethod = configChi2MatchingOptions.matchingExtrapMethods[funcId]->value;
11381142

11391143
if (label == "" || funcName == "")
1140-
break;
1144+
continue;
11411145

11421146
matchingChi2Functions[label] = funcName;
11431147

11441148
matchingScoreCuts[label] = scoreMin;
11451149
matchingPlanesZ[label] = matchingPlaneZ;
11461150
matchingExtrapMethod[label] = extrapMethod;
1151+
1152+
matchMethodLabels.push_back(label);
11471153
}
11481154

11491155
// Matching ML models
@@ -1163,7 +1169,7 @@ struct QaMatching {
11631169
auto extrapMethod = configMlOptions.matchingExtrapMethods[modelId]->value;
11641170

11651171
if (label == "" || modelPath == "" || inputFeatures.empty() || modelName == "")
1166-
break;
1172+
continue;
11671173

11681174
matchingMlResponses[label].configure(binsPtMl, mycutsMl, cutDirMl, 1);
11691175
matchingMlResponses[label].setModelPathsCCDB(std::vector<std::string>{modelName}, fCCDBApi, std::vector<std::string>{modelPath}, configCcdb.cfgCcdbNoLaterThan.value);
@@ -1173,6 +1179,8 @@ struct QaMatching {
11731179
matchingScoreCuts[label] = scoreMin;
11741180
matchingPlanesZ[label] = matchingPlaneZ;
11751181
matchingExtrapMethod[label] = extrapMethod;
1182+
1183+
matchMethodLabels.push_back(label);
11761184
}
11771185

11781186
int nTrackTypes = static_cast<int>(o2::aod::fwdtrack::ForwardTrackTypeEnum::MCHStandaloneTrack) + 1;
@@ -1183,6 +1191,14 @@ struct QaMatching {
11831191
registry.add("tracksMultiplicityMFT", "MFT tracks multiplicity", {HistType::kTH1F, {tracksMultiplicityAxis}});
11841192
registry.add("tracksMultiplicityMCH", "MCH tracks multiplicity", {HistType::kTH1F, {tracksMultiplicityAxis}});
11851193

1194+
// Histogram for storing the index and label of the matching methods in the horizontal axis.
1195+
// This is needed in order to associate the proper label to the match method index in the derived tables.
1196+
AxisSpec matchMethodAxis = {static_cast<int>(matchMethodLabels.size()), 0.0, static_cast<double>(matchMethodLabels.size()), ""};
1197+
auto matchMethodsHist = registry.add("matchMethods", "Match methods", {HistType::kTH1F, {matchMethodAxis}});
1198+
for (size_t iLabel = 0; iLabel <= matchMethodLabels.size(); iLabel++) {
1199+
std::get<std::shared_ptr<TH1>>(matchMethodsHist)->GetXaxis()->SetBinLabel(iLabel + 1, matchMethodLabels[iLabel].c_str());
1200+
}
1201+
11861202
createMatchingHistosMc();
11871203
createDimuonHistos();
11881204
}
@@ -1726,7 +1742,7 @@ struct QaMatching {
17261742
}
17271743

17281744
template <class TMCH, class TMFT>
1729-
bool IsMuon(const TMCH& mchTrack,
1745+
bool isMuon(const TMCH& mchTrack,
17301746
const TMFT& mftTrack)
17311747
{
17321748
// skip tracks that do not have an associated MC particle
@@ -1748,7 +1764,7 @@ struct QaMatching {
17481764
}
17491765

17501766
template <class TMUON, class TMUONS, class TMFTS>
1751-
bool IsMuon(const TMUON& muonTrack,
1767+
bool isMuon(const TMUON& muonTrack,
17521768
TMUONS const& /*muonTracks*/,
17531769
TMFTS const& /*mftTracks*/)
17541770
{
@@ -1758,7 +1774,7 @@ struct QaMatching {
17581774
auto const& mchTrack = muonTrack.template matchMCHTrack_as<TMUONS>();
17591775
auto const& mftTrack = muonTrack.template matchMFTTrack_as<TMFTS>();
17601776

1761-
return IsMuon(mchTrack, mftTrack);
1777+
return isMuon(mchTrack, mftTrack);
17621778
}
17631779

17641780
template <class TMUON, class TMUONS, class TMFTS>
@@ -2103,18 +2119,18 @@ struct QaMatching {
21032119
return (track1.matchChi2 < track2.matchChi2);
21042120
};
21052121

2106-
for (auto collisionInfoIt = collisionInfos.begin(); collisionInfoIt != collisionInfos.end(); ++collisionInfoIt) {
2107-
auto& collisionInfo = collisionInfoIt->second;
2108-
for (auto matchingCandidatesIt = collisionInfo.matchingCandidates.begin(); matchingCandidatesIt != collisionInfo.matchingCandidates.end(); ++matchingCandidatesIt) {
2109-
auto& mchIndex = matchingCandidatesIt->first;
2110-
auto& globalTracksVector = matchingCandidatesIt->second;
2122+
int64_t reducedEventCounter{0};
2123+
for (auto& [collisionIndex, collisionInfo] : collisionInfos) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
2124+
// set the internal collision index
2125+
collisionInfo.reducedEventId = reducedEventCounter;
2126+
reducedEventCounter += 1;
2127+
for (auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
21112128
std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2);
21122129

21132130
const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex);
21142131
auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks);
21152132
int ranking = 1;
2116-
for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) {
2117-
auto& candidate = *candidateIt;
2133+
for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
21182134
const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId);
21192135

21202136
candidate.matchRanking = ranking;
@@ -2635,16 +2651,13 @@ struct QaMatching {
26352651
return (track1.matchChi2 < track2.matchChi2);
26362652
};
26372653

2638-
for (auto matchingCandidatesIt = newMatchingCandidates.begin(); matchingCandidatesIt != newMatchingCandidates.end(); ++matchingCandidatesIt) {
2639-
auto& mchIndex = matchingCandidatesIt->first;
2640-
auto& globalTracksVector = matchingCandidatesIt->second;
2654+
for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
26412655
std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingChi2);
26422656

26432657
const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex);
26442658
auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks);
26452659
int ranking = 1;
2646-
for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) {
2647-
auto& candidate = *candidateIt;
2660+
for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
26482661
const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId);
26492662

26502663
candidate.matchRanking = ranking;
@@ -2783,16 +2796,13 @@ struct QaMatching {
27832796
return (track1.matchScore > track2.matchScore);
27842797
};
27852798

2786-
for (auto matchingCandidatesIt = newMatchingCandidates.begin(); matchingCandidatesIt != newMatchingCandidates.end(); ++matchingCandidatesIt) {
2787-
auto& mchIndex = matchingCandidatesIt->first;
2788-
auto& globalTracksVector = matchingCandidatesIt->second;
2799+
for (auto& [mchIndex, globalTracksVector] : newMatchingCandidates) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
27892800
std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore);
27902801

27912802
const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex);
27922803
auto mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks);
27932804
int ranking = 1;
2794-
for (auto candidateIt = globalTracksVector.begin(); candidateIt != globalTracksVector.end(); ++candidateIt) {
2795-
auto& candidate = *candidateIt;
2805+
for (auto& candidate : globalTracksVector) { // o2-linter: disable=const-ref-in-for-loop (object is modified in loop)
27962806
const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId);
27972807

27982808
candidate.matchRanking = ranking;
@@ -2813,31 +2823,17 @@ struct QaMatching {
28132823
{
28142824
auto collision = collisions.rawIteratorAt(collisionInfo.index);
28152825

2826+
int debugCounter{0};
2827+
fillQaMatchingAodEventForCollision(collisionInfo, collision, collisionInfo.reducedEventId, debugCounter);
2828+
fillQaMatchingMchTracksForCollision(collisionInfo, collisions, collision, muonTracks, mftTracks, bcs, collisionInfo.reducedEventId);
2829+
28162830
registry.get<TH1>(HIST("tracksMultiplicityMFT"))->Fill(collisionInfo.mftTracks.size());
28172831
registry.get<TH1>(HIST("tracksMultiplicityMCH"))->Fill(collisionInfo.mchTracks.size());
28182832

2833+
int matchingMethodCounter{0};
28192834
// Chi2-based matching analysis
2835+
fillQaMatchingAodTablesForCollision(collision, muonTracks, collisionInfo.matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId);
28202836
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, collisionInfo.matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fChi2MatchingPlotter.get(), false);
2821-
for (const auto& [label, func] : matchingChi2Functions) {
2822-
MatchingCandidates matchingCandidates;
2823-
runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates);
2824-
2825-
auto* plotter = fMatchingPlotters.at(label).get();
2826-
double matchingScoreCut = matchingScoreCuts.at(label);
2827-
2828-
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false);
2829-
}
2830-
2831-
// ML-based matching analysis
2832-
for (const auto& [label, mlResponse] : matchingMlResponses) {
2833-
MatchingCandidates matchingCandidates;
2834-
runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates);
2835-
2836-
auto* plotter = fMatchingPlotters.at(label).get();
2837-
double matchingScoreCut = matchingScoreCuts.at(label);
2838-
2839-
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter);
2840-
}
28412837

28422838
// Muons tagging
28432839
for (const auto& [mchIndex, mftIndex] : collisionInfo.matchablePairs) {
@@ -2883,8 +2879,38 @@ struct QaMatching {
28832879
taggedMatchingCandidates[mchIndex] = globalTracksVector;
28842880
}
28852881
}
2882+
matchingMethodCounter += 1;
2883+
fillQaMatchingAodTablesForCollision(collision, muonTracks, collisionInfo.matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId);
28862884
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, taggedMatchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, cfgMatchingChi2ScoreMftMchLow, fTaggedMuonsMatchingPlotter.get());
28872885

2886+
//-------------------------------
2887+
// Custom chi2-based matching methods
2888+
for (const auto& [label, func] : matchingChi2Functions) {
2889+
MatchingCandidates matchingCandidates;
2890+
runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates);
2891+
2892+
auto* plotter = fMatchingPlotters.at(label).get();
2893+
double matchingScoreCut = matchingScoreCuts.at(label);
2894+
2895+
matchingMethodCounter += 1;
2896+
fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId);
2897+
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter, false);
2898+
}
2899+
2900+
// ML-based matching analysis
2901+
for (const auto& [label, mlResponse] : matchingMlResponses) {
2902+
MatchingCandidates matchingCandidates;
2903+
runMlMatching(collisions, bcs, muonTracks, mftTracks, mftCovs, label, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates);
2904+
2905+
auto* plotter = fMatchingPlotters.at(label).get();
2906+
double matchingScoreCut = matchingScoreCuts.at(label);
2907+
2908+
matchingMethodCounter += 1;
2909+
fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, matchingMethodCounter, collisionInfo.reducedEventId);
2910+
fillMatchingPlotsMc(collision, collisionInfo, muonTracks, mftTracks, matchingCandidates, collisionInfo.matchingCandidates, collisionInfo.matchablePairs, matchingScoreCut, plotter);
2911+
}
2912+
2913+
//-------------------------------
28882914
// Di-muon analysis
28892915
fillDimuonPlotsMc(collisionInfo, collisions, muonTracks, mftTracks);
28902916
}
@@ -3007,55 +3033,12 @@ struct QaMatching {
30073033
registry.get<TH1>(HIST("nTracksPerType"))->Fill(static_cast<int>(muon.trackType()));
30083034
}
30093035

3010-
fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos);
3011-
30123036
mftTrackCovs.clear();
30133037
for (const auto& mftTrackCov : mftCovs) {
30143038
mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex();
30153039
}
30163040

3017-
std::unordered_map<int64_t, int32_t> reducedEventIds;
3018-
int32_t reducedEventCounter = 0;
3019-
for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) {
3020-
reducedEventIds.emplace(collisionInfo.index, reducedEventCounter);
3021-
reducedEventCounter += 1;
3022-
}
3023-
3024-
int debugCounter = 0;
3025-
for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) {
3026-
auto it = reducedEventIds.find(collisionInfo.index);
3027-
if (it == reducedEventIds.end()) {
3028-
continue;
3029-
}
3030-
int32_t reducedEventId = it->second;
3031-
auto collision = collisions.rawIteratorAt(collisionInfo.index);
3032-
fillQaMatchingAodEventForCollision(collisionInfo, collision, reducedEventId, debugCounter);
3033-
fillQaMatchingMchTracksForCollision(collisionInfo, collisions, collision, muonTracks, mftTracks, bcs, reducedEventId);
3034-
}
3035-
3036-
struct AodLabel {
3037-
const char* name;
3038-
int8_t id;
3039-
};
3040-
std::array<AodLabel, 3> aodLabels{{{"ProdAll", 0}, {"MatchXYPhiTanl", 1}, {"MatchXYPhiTanlMom", 2}}};
3041-
for (const auto& aodLabel : aodLabels) {
3042-
if (matchingChi2Functions.find(aodLabel.name) == matchingChi2Functions.end()) {
3043-
LOGF(warn, "[AO2D] Chi2 label not found: %s", aodLabel.name);
3044-
continue;
3045-
}
3046-
debugCounter = 0;
3047-
for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) {
3048-
auto it = reducedEventIds.find(collisionInfo.index);
3049-
if (it == reducedEventIds.end()) {
3050-
continue;
3051-
}
3052-
int32_t reducedEventId = it->second;
3053-
MatchingCandidates matchingCandidates;
3054-
runChi2Matching(collisions, bcs, muonTracks, mftTracks, mftCovs, aodLabel.name, collisionInfo.matchablePairs, collisionInfo.matchingCandidates, matchingCandidates);
3055-
auto collision = collisions.rawIteratorAt(collisionInfo.index);
3056-
fillQaMatchingAodTablesForCollision(collision, muonTracks, matchingCandidates, aodLabel.id, reducedEventId);
3057-
}
3058-
}
3041+
fillCollisions(collisions, bcs, muonTracks, mftTracks, fCollisionInfos);
30593042

30603043
for (auto const& [collisionIndex, collisionInfo] : fCollisionInfos) {
30613044
processCollisionMc(collisionInfo, collisions, bcs, muonTracks, mftTracks, mftCovs);

0 commit comments

Comments
 (0)