Skip to content

Commit 36ea19a

Browse files
committed
[PWGDQ] added derived AO2D tables for matching QA
The derived tables provide the track parameters at the matching planes, the information of the MC truth for the matched tracks, and global event features relevant for the matching performances evaluation.
1 parent c90afcd commit 36ea19a

1 file changed

Lines changed: 235 additions & 0 deletions

File tree

PWGDQ/Tasks/qaMatching.cxx

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,77 @@ using namespace o2;
8484
using namespace o2::framework;
8585
using namespace o2::aod;
8686

87+
namespace qamatching
88+
{
89+
DECLARE_SOA_COLUMN(P, p, float);
90+
DECLARE_SOA_COLUMN(Pt, pt, float);
91+
DECLARE_SOA_COLUMN(Eta, eta, float);
92+
DECLARE_SOA_COLUMN(Phi, phi, float);
93+
DECLARE_SOA_COLUMN(MatchLabel, matchLabel, int8_t);
94+
DECLARE_SOA_COLUMN(TrackId, trackId, int64_t);
95+
DECLARE_SOA_COLUMN(MatchType, matchType, int8_t);
96+
DECLARE_SOA_COLUMN(MatchScore, matchScore, float);
97+
DECLARE_SOA_COLUMN(MatchRanking, matchRanking, int32_t);
98+
DECLARE_SOA_COLUMN(MftMultiplicity, mftMultiplicity, int32_t);
99+
DECLARE_SOA_COLUMN(TrackType, trackType, int8_t);
100+
DECLARE_SOA_COLUMN(MftMatchAttempts, mftMatchAttempts, int32_t);
101+
DECLARE_SOA_COLUMN(XAtVtx, xAtVtx, float);
102+
DECLARE_SOA_COLUMN(YAtVtx, yAtVtx, float);
103+
DECLARE_SOA_COLUMN(ZAtVtx, zAtVtx, float);
104+
DECLARE_SOA_COLUMN(PxAtVtx, pxAtVtx, float);
105+
DECLARE_SOA_COLUMN(PyAtVtx, pyAtVtx, float);
106+
DECLARE_SOA_COLUMN(PzAtVtx, pzAtVtx, float);
107+
DECLARE_SOA_COLUMN(ColX, colX, float);
108+
DECLARE_SOA_COLUMN(ColY, colY, float);
109+
DECLARE_SOA_COLUMN(ColZ, colZ, float);
110+
} // namespace qamatching
111+
112+
namespace o2::aod
113+
{
114+
DECLARE_SOA_TABLE(QaMatchingEvents, "AOD", "QAMEVT",
115+
o2::soa::Index<>,
116+
qamatching::MftMultiplicity,
117+
qamatching::ColX,
118+
qamatching::ColY,
119+
qamatching::ColZ);
120+
} // namespace o2::aod
121+
122+
namespace qamatching
123+
{
124+
DECLARE_SOA_INDEX_COLUMN_FULL(ReducedEvent, reducedEvent, int32_t, o2::aod::QaMatchingEvents, "");
125+
} // namespace qamatching
126+
127+
namespace o2::aod
128+
{
129+
DECLARE_SOA_TABLE(QaMatchingMCHTrack, "AOD", "QAMCHTRK",
130+
qamatching::ReducedEventId,
131+
qamatching::TrackId,
132+
qamatching::TrackType,
133+
qamatching::P,
134+
qamatching::Pt,
135+
qamatching::Eta,
136+
qamatching::Phi,
137+
qamatching::MftMatchAttempts,
138+
qamatching::XAtVtx,
139+
qamatching::YAtVtx,
140+
qamatching::ZAtVtx,
141+
qamatching::PxAtVtx,
142+
qamatching::PyAtVtx,
143+
qamatching::PzAtVtx);
144+
DECLARE_SOA_TABLE(QaMatchingCandidates, "AOD", "QAMCAND",
145+
qamatching::ReducedEventId,
146+
qamatching::MatchLabel,
147+
qamatching::TrackId,
148+
qamatching::P, qamatching::Pt, qamatching::Eta, qamatching::Phi,
149+
qamatching::MatchType, qamatching::MatchScore, qamatching::MatchRanking,
150+
qamatching::XAtVtx,
151+
qamatching::YAtVtx,
152+
qamatching::ZAtVtx,
153+
qamatching::PxAtVtx,
154+
qamatching::PyAtVtx,
155+
qamatching::PzAtVtx);
156+
} // namespace o2::aod
157+
87158
using MyEvents = soa::Join<aod::Collisions, aod::EvSels>;
88159
using MyMuons = soa::Join<aod::FwdTracks, aod::FwdTracksCov>;
89160
using MyMuonsMC = soa::Join<aod::FwdTracks, aod::FwdTracksCov, aod::McFwdTrackLabels>;
@@ -210,6 +281,8 @@ struct QaMatching {
210281
Configurable<int> cfgNCandidatesMax{"cfgNCandidatesMax", 5, "Number of matching candidates stored for each muon track"};
211282
Configurable<int> cfgMftTrackMultiplicityMax{"cfgMftTrackMultiplicityMax", 1000, "Maximum number of MFT tracks per collision"};
212283

284+
Configurable<int> cfgQaMatchingAodDebug{"cfgQaMatchingAodDebug", 0, "If >0, print AO2D filling debug (0=off, N=max collisions)"};
285+
213286
double mBzAtMftCenter{0};
214287

215288
o2::globaltracking::MatchGlobalFwd mExtrap;
@@ -399,6 +472,10 @@ struct QaMatching {
399472
std::unordered_map<std::string, o2::framework::HistPtr> matchingHistos;
400473
Matrix<o2::framework::HistPtr, 4, 4> dimuonHistos;
401474

475+
Produces<o2::aod::QaMatchingEvents> qaMatchingEvents;
476+
Produces<o2::aod::QaMatchingMCHTrack> qaMatchingMCHTrack;
477+
Produces<o2::aod::QaMatchingCandidates> qaMatchingCandidates;
478+
402479
struct EfficiencyPlotter {
403480
o2::framework::HistPtr pNum;
404481
o2::framework::HistPtr pDen;
@@ -2329,6 +2406,17 @@ struct QaMatching {
23292406
}
23302407
}
23312408

2409+
if (cfgQaMatchingAodDebug > 0 && goodMatchFound && isTrueMatch) {
2410+
LOGF(info,
2411+
"[good&true] mchId=%lld trackType=%d p=%.3f pt=%.3f eta=%.3f phi=%.3f",
2412+
static_cast<int64_t>(mchTrack.globalIndex()),
2413+
static_cast<int>(mchTrack.trackType()),
2414+
mchTrack.p(),
2415+
mchTrack.pt(),
2416+
mchTrack.eta(),
2417+
mchTrack.phi());
2418+
}
2419+
23322420
// ---- MC ancestry ----
23332421
auto motherParticles = getMotherParticles(mchTrack);
23342422
int motherPDG = 0;
@@ -2790,6 +2878,110 @@ struct QaMatching {
27902878
fillDimuonPlotsMc(collisionInfo, collisions, muonTracks, mftTracks);
27912879
}
27922880

2881+
template <class TCOLLISION, class TMUON>
2882+
void fillQaMatchingAodTablesForCollision(TCOLLISION const& collision,
2883+
TMUON const& muonTracks,
2884+
const MatchingCandidates& matchingCandidates,
2885+
int8_t matchLabel,
2886+
int32_t reducedEventId)
2887+
{
2888+
for (const auto& [mchIndex, candidates] : matchingCandidates) {
2889+
if (candidates.empty()) {
2890+
continue;
2891+
}
2892+
2893+
const auto& mchTrack = muonTracks.rawIteratorAt(mchIndex);
2894+
if (!isGoodGlobalMuon(mchTrack, collision)) {
2895+
continue;
2896+
}
2897+
2898+
for (const auto& candidate : candidates) {
2899+
const auto& candidateTrack = muonTracks.rawIteratorAt(candidate.globalTrackId);
2900+
auto candidateTrackAtVertex = VarManager::PropagateMuon(candidateTrack, collision, VarManager::kToVertex);
2901+
qaMatchingCandidates(
2902+
reducedEventId,
2903+
matchLabel,
2904+
mchIndex,
2905+
static_cast<float>(candidateTrack.p()),
2906+
static_cast<float>(candidateTrack.pt()),
2907+
static_cast<float>(candidateTrack.eta()),
2908+
static_cast<float>(candidateTrack.phi()),
2909+
static_cast<int8_t>(candidate.matchType),
2910+
static_cast<float>(candidate.matchScore),
2911+
static_cast<int32_t>(candidate.matchRanking),
2912+
static_cast<float>(candidateTrackAtVertex.getX()),
2913+
static_cast<float>(candidateTrackAtVertex.getY()),
2914+
static_cast<float>(candidateTrackAtVertex.getZ()),
2915+
static_cast<float>(candidateTrackAtVertex.getPx()),
2916+
static_cast<float>(candidateTrackAtVertex.getPy()),
2917+
static_cast<float>(candidateTrackAtVertex.getPz()));
2918+
}
2919+
}
2920+
}
2921+
2922+
template <class TCOLLISION>
2923+
void fillQaMatchingAodEventForCollision(const CollisionInfo& collisionInfo,
2924+
TCOLLISION const& collision,
2925+
int32_t reducedEventId,
2926+
int& debugCounter)
2927+
{
2928+
int32_t mftMultiplicity = static_cast<int32_t>(collisionInfo.mftTracks.size());
2929+
qaMatchingEvents(
2930+
mftMultiplicity,
2931+
static_cast<float>(collision.posX()),
2932+
static_cast<float>(collision.posY()),
2933+
static_cast<float>(collision.posZ()));
2934+
2935+
if (cfgQaMatchingAodDebug > 0 && debugCounter < cfgQaMatchingAodDebug) {
2936+
LOGF(info, "[AO2D] reducedEvent=%", reducedEventId);
2937+
debugCounter += 1;
2938+
}
2939+
}
2940+
2941+
template <class TCOLLISIONS, class TCOLLISION, class TMUON, class TMFT, class TBC>
2942+
void fillQaMatchingMchTracksForCollision(const CollisionInfo& collisionInfo,
2943+
TCOLLISIONS const& collisions,
2944+
TCOLLISION const& collision,
2945+
TMUON const& muonTracks,
2946+
TMFT const& mftTracks,
2947+
TBC const& bcs,
2948+
int32_t reducedEventId)
2949+
{
2950+
std::vector<int64_t> mchIds;
2951+
for (const auto& mchIndex : collisionInfo.mchTracks) {
2952+
if (std::find(mchIds.begin(), mchIds.end(), mchIndex) == mchIds.end()) {
2953+
mchIds.emplace_back(mchIndex);
2954+
}
2955+
}
2956+
for (const auto& [mchIndex, candidates] : collisionInfo.matchingCandidates) {
2957+
(void)candidates;
2958+
if (std::find(mchIds.begin(), mchIds.end(), mchIndex) == mchIds.end()) {
2959+
mchIds.emplace_back(mchIndex);
2960+
}
2961+
}
2962+
2963+
for (const auto& mchIndex : mchIds) {
2964+
auto const& mchTrack = muonTracks.rawIteratorAt(mchIndex);
2965+
int mftMchMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks);
2966+
auto mchTrackAtVertex = VarManager::PropagateMuon(mchTrack, collision, VarManager::kToVertex);
2967+
qaMatchingMCHTrack(
2968+
reducedEventId,
2969+
mchIndex,
2970+
static_cast<int8_t>(mchTrack.trackType()),
2971+
static_cast<float>(mchTrack.p()),
2972+
static_cast<float>(mchTrack.pt()),
2973+
static_cast<float>(mchTrack.eta()),
2974+
static_cast<float>(mchTrack.phi()),
2975+
static_cast<int32_t>(mftMchMatchAttempts),
2976+
static_cast<float>(mchTrackAtVertex.getX()),
2977+
static_cast<float>(mchTrackAtVertex.getY()),
2978+
static_cast<float>(mchTrackAtVertex.getZ()),
2979+
static_cast<float>(mchTrackAtVertex.getPx()),
2980+
static_cast<float>(mchTrackAtVertex.getPy()),
2981+
static_cast<float>(mchTrackAtVertex.getPz()));
2982+
}
2983+
}
2984+
27932985
void processQAMC(MyEvents const& collisions,
27942986
aod::BCsWithTimestamps const& bcs,
27952987
MyMuonsMC const& muonTracks,
@@ -2811,6 +3003,49 @@ struct QaMatching {
28113003
mftTrackCovs[mftTrackCov.matchMFTTrackId()] = mftTrackCov.globalIndex();
28123004
}
28133005

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

0 commit comments

Comments
 (0)