Skip to content

Commit 6612a6f

Browse files
aferrero2707mcoquet642
authored andcommitted
Add filling of mixed event matching candidates
1 parent a8eefb5 commit 6612a6f

1 file changed

Lines changed: 169 additions & 0 deletions

File tree

PWGDQ/Tasks/global-muon-matcher.cxx

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ using SMatrix5 = o2::track::SMatrix5;
119119
constexpr std::array<int, 10> NDetElemCh = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26};
120120
constexpr std::array<int, 11> SNDetElemCh = {0, 4, 8, 12, 16, 34, 52, 78, 104, 130, 156};
121121

122+
// compute minimum difference between azimuthal angles
123+
static float getDeltaPhi(float phi1, float phi2)
124+
{
125+
float dphi = phi1 - phi2;
126+
static constexpr float pi = TMath::Pi();
127+
static constexpr float twopi = pi;
128+
if (dphi > pi) {
129+
dphi -= twopi;
130+
}
131+
if (dphi < pi) {
132+
dphi += twopi;
133+
}
134+
return dphi;
135+
};
136+
137+
122138
struct GlobalMuonMatching {
123139

124140
static constexpr int GlobalTrackTypeMax = 2;
@@ -139,6 +155,15 @@ struct GlobalMuonMatching {
139155
int matchRanking{-1};
140156
};
141157

158+
struct MchTrackInfo {
159+
int64_t index{-1};
160+
int nMatchAttempts{-1};
161+
// vector of MFT-MCH matching candidates
162+
std::vector<MatchingCandidate> matchingCandidates;
163+
// vector of vectors of MFT-MCH matching candidates from mixed events
164+
std::vector<std::vector<MatchingCandidate>> mixedMatchingCandidates;
165+
};
166+
142167
//// Variables for selecting tagged muons
143168
struct : ConfigurableGroup {
144169
Configurable<int> cfgMuonTaggingNCrossedMftPlanesLow{"cfgMuonTaggingNCrossedMftPlanesLow", 5, ""};
@@ -300,6 +325,7 @@ struct GlobalMuonMatching {
300325
std::array<int32_t, 2> mLastMchAmbiguousBcSlice{};
301326

302327
int32_t mMatchCandidateCounter{0};
328+
std::unordered_map<int64_t, MchTrackInfo> mMchTrackInfos;
303329
std::unordered_map<int64_t, std::vector<int32_t>> mMchTrackToCandidateIndices;
304330
std::unordered_map<int64_t, std::vector<MatchingCandidate>> mMchTrackMatchingCandidates;
305331
std::unordered_map<int64_t, int32_t> mFwdTrackToGmmCandTrkIndex;
@@ -1120,6 +1146,41 @@ struct GlobalMuonMatching {
11201146
return std::fabs(deltaTrackTime) <= trackTimeResTot;
11211147
}
11221148

1149+
template <class EVT, class BC, class TMUON, class TMFTS>
1150+
int getMftMchMatchAttempts(EVT const& collisions,
1151+
BC const& bcs,
1152+
TMUON const& mchTrack,
1153+
TMFTS const& mftTracks)
1154+
{
1155+
if (!mchTrack.has_collision()) {
1156+
return 0;
1157+
}
1158+
const auto& collMch = collisions.rawIteratorAt(mchTrack.collisionId());
1159+
const auto& bcMch = bcs.rawIteratorAt(collMch.bcId());
1160+
1161+
int attempts{0};
1162+
for (const auto& mftTrack : mftTracks) {
1163+
if (!mftTrack.has_collision()) {
1164+
continue;
1165+
}
1166+
1167+
const auto& collMft = collisions.rawIteratorAt(mftTrack.collisionId());
1168+
const auto& bcMft = bcs.rawIteratorAt(collMft.bcId());
1169+
1170+
int64_t deltaBc = static_cast<int64_t>(bcMft.globalBC()) - static_cast<int64_t>(bcMch.globalBC());
1171+
double deltaBcNS = o2::constants::lhc::LHCBunchSpacingNS * deltaBc;
1172+
double deltaTrackTime = mftTrack.trackTime() - mchTrack.trackTime() + deltaBcNS;
1173+
double trackTimeResTot = mftTrack.trackTimeRes() + mchTrack.trackTimeRes();
1174+
1175+
if (std::fabs(deltaTrackTime) > trackTimeResTot) {
1176+
continue;
1177+
}
1178+
attempts += 1;
1179+
}
1180+
1181+
return attempts;
1182+
}
1183+
11231184
template <class EVT, class BC, class TMUON, class TMFT>
11241185
void prepareMatchingCandidates(EVT const& collisions,
11251186
BC const& bcs,
@@ -1141,6 +1202,9 @@ struct GlobalMuonMatching {
11411202

11421203
// initialize the MCH track parameters, which will be updated by the realignment if enabled
11431204
mMchTrackPars.try_emplace(mchTrackIndex, TrackParExt(fwdtrackutils::getTrackParCovFwd(muonTrack, muonTrack), muonTrack.nClusters()));
1205+
1206+
auto& mchTrackInfo = mMchTrackInfos[mchTrackIndex];
1207+
mchTrackInfo.index = mchTrackIndex;
11441208
}
11451209

11461210
for (const auto& mftTrack : mftTracks) {
@@ -1171,12 +1235,26 @@ struct GlobalMuonMatching {
11711235
continue;
11721236
}
11731237

1238+
auto& mchTrackInfo = mMchTrackInfos[mchTrackIndex];
1239+
mchTrackInfo.index = mchTrackIndex;
1240+
mchTrackInfo.matchingCandidates.emplace_back(MatchingCandidate{
1241+
.muonTrackId = muonTrack.globalIndex(),
1242+
.mftTrackId = mftTrackIndex,
1243+
.matchScore = muonTrack.matchScoreMCHMFT(),
1244+
.matchChi2 = muonTrack.chi2MatchMCHMFT()});
1245+
11741246
mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{
11751247
.muonTrackId = muonTrack.globalIndex(),
11761248
.mftTrackId = mftTrackIndex,
11771249
.matchScore = muonTrack.matchScoreMCHMFT(),
11781250
.matchChi2 = muonTrack.chi2MatchMCHMFT()});
11791251
}
1252+
1253+
// set the number of match attempts for this track
1254+
for (auto& mchTrackInfo : mMchTrackInfos) {
1255+
const auto& mchTrack = muonTracks.rawIteratorAt(mchTrackInfo.first);
1256+
mchTrackInfo.second.nMatchAttempts = getMftMchMatchAttempts(collisions, bcs, mchTrack, mftTracks);
1257+
}
11801258
} else {
11811259
// build matching candidates from all time-compatible MFT-MCH pairs
11821260
for (const auto& muonTrack : muonTracks) {
@@ -1192,10 +1270,20 @@ struct GlobalMuonMatching {
11921270
continue;
11931271
}
11941272

1273+
auto& mchTrackInfo = mMchTrackInfos[mchTrackIndex];
1274+
mchTrackInfo.index = mchTrackIndex;
1275+
mchTrackInfo.matchingCandidates.emplace_back(MatchingCandidate{
1276+
.mftTrackId = mftTrack.globalIndex()});
1277+
11951278
mMatchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{
11961279
.mftTrackId = mftTrack.globalIndex()});
11971280
}
11981281
}
1282+
1283+
// set the number of match attempts for this track
1284+
for (auto& mchTrackInfo : mMchTrackInfos) {
1285+
mchTrackInfo.second.nMatchAttempts = mchTrackInfo.second.matchingCandidates.size();
1286+
}
11991287
}
12001288

12011289
// sort the vectors of matching candidates in ascending order based on the matching chi2 value
@@ -1208,6 +1296,85 @@ struct GlobalMuonMatching {
12081296
}
12091297
}
12101298

1299+
template <class EVT, class BC, class TMUON, class TMFT>
1300+
void prepareEventMixingMatchingCandidates(EVT const& collisions,
1301+
BC const& bcs,
1302+
TMUON const& muonTracks,
1303+
TMFT const& mftTracks,
1304+
MyMFTCovariances const& mftCovs)
1305+
{
1306+
LOGF(info, "Filling mixed matching candidate tables");
1307+
1308+
constexpr float deltaPhiMax = TMath::Pi() / 10;
1309+
1310+
for (auto& [mchIndex1, mchTrackInfo1] : mMchTrackInfos) {
1311+
const auto& mchTrack1 = muonTracks.rawIteratorAt(mchIndex1);
1312+
1313+
if (!mchTrack1.has_collision()) {
1314+
continue;
1315+
}
1316+
1317+
const auto& collision1 = collisions.rawIteratorAt(mchTrack1.collisionId());
1318+
const auto& bc1 = bcs.rawIteratorAt(collision1.bcId());
1319+
1320+
auto phi1 = std::atan2(mchTrack1.y(), mchTrack1.x());
1321+
auto r1 = std::hypot(mchTrack1.x(), mchTrack1.y());
1322+
1323+
auto nAttempts1 = mchTrackInfo1.nMatchAttempts;
1324+
1325+
auto vz1 = collision1.posZ();
1326+
1327+
for (const auto& [mchIndex2, mchTrackInfo2] : mMchTrackInfos) {
1328+
const auto& mchTrack2 = muonTracks.rawIteratorAt(mchIndex2);
1329+
1330+
if (!mchTrack2.has_collision()) {
1331+
continue;
1332+
}
1333+
1334+
const auto& collision2 = collisions.rawIteratorAt(mchTrack2.collisionId());
1335+
const auto& bc2 = bcs.rawIteratorAt(collision2.bcId());
1336+
1337+
auto deltaBc = std::abs(static_cast<int64_t>(bc2.globalBC()) - static_cast<int64_t>(bc1.globalBC()));
1338+
if (deltaBc < 3564) {
1339+
continue;
1340+
}
1341+
1342+
auto phi2 = std::atan2(mchTrack2.y(), mchTrack2.x());
1343+
auto deltaPhi = std::fabs(getDeltaPhi(phi1, phi2));
1344+
if (deltaPhi > deltaPhiMax) {
1345+
continue;
1346+
}
1347+
1348+
auto r2 = std::hypot(mchTrack2.x(), mchTrack2.y());
1349+
auto deltaR = r2 - r1;
1350+
if (deltaR > 10) {
1351+
continue;
1352+
}
1353+
1354+
auto nAttempts2 = mchTrackInfo2.nMatchAttempts;
1355+
1356+
float deltaAttempts = nAttempts2 - nAttempts1;
1357+
float deltaAttemptsRel = (nAttempts1 > 0) ? deltaAttempts / nAttempts1 : 0;
1358+
if (deltaAttemptsRel > 0.1) {
1359+
continue;
1360+
}
1361+
1362+
auto vz2 = collision2.posZ();
1363+
auto deltaZ = std::fabs(vz2 - vz1);
1364+
if (deltaZ > 1) {
1365+
continue;
1366+
}
1367+
1368+
// add the candidates of MCH track #2 to the list of mixed candidates of track #1
1369+
mchTrackInfo1.mixedMatchingCandidates.push_back(mchTrackInfo2.matchingCandidates);
1370+
// update the muon track index of the mixed candidates to the index of track #1
1371+
for (auto& candidate : mchTrackInfo1.mixedMatchingCandidates.back()) {
1372+
candidate.muonTrackId = mchIndex1;
1373+
}
1374+
}
1375+
}
1376+
}
1377+
12111378
template <typename TMFT, typename TMFTCOV>
12121379
o2::track::TrackParCovFwd transformMft(TMFT& mftTrack, TMFTCOV const& mftTrackCov)
12131380
{
@@ -1654,9 +1821,11 @@ struct GlobalMuonMatching {
16541821
mMchTrackToCandidateIndices.clear();
16551822
mMchTrackMatchingCandidates.clear();
16561823
mFwdTrackToGmmCandTrkIndex.clear();
1824+
mMchTrackInfos.clear();
16571825

16581826
LOGF(info, "Preparing candidates");
16591827
prepareMatchingCandidates(collisions, bcs, muonTracks, mftTracks, mftCovs);
1828+
prepareEventMixingMatchingCandidates(collisions, bcs, muonTracks, mftTracks, mftCovs);
16601829

16611830
LOGF(info, "Processing candidates");
16621831
processMatchingCandidates(collisions, muonTracks, mftTracks, mftCovs, clusters);

0 commit comments

Comments
 (0)