|
37 | 37 | #include <unordered_map> |
38 | 38 | #include <utility> |
39 | 39 | #include <vector> |
| 40 | +#include <tuple> |
| 41 | +#include <iostream> |
40 | 42 |
|
41 | 43 | using namespace o2; |
42 | 44 | using namespace o2::framework; |
@@ -1166,144 +1168,6 @@ struct qaMatching { |
1166 | 1168 | return PropagateToZMFT(fwdtrack, z); |
1167 | 1169 | } |
1168 | 1170 |
|
1169 | | - template <class EVT, class BC, class TMUON, class TMFT> |
1170 | | - void FillCollisions(EVT const& collisions, |
1171 | | - BC const& bcs, |
1172 | | - TMUON const& muonTracks, |
1173 | | - TMFT const& mftTracks, |
1174 | | - CollisionInfos& collisionInfos) |
1175 | | - { |
1176 | | - collisionInfos.clear(); |
1177 | | - |
1178 | | - std::vector<int64_t> collisionIds; |
1179 | | - for (const auto& collision : collisions) { |
1180 | | - collisionIds.push_back(collision.globalIndex()); |
1181 | | - } |
1182 | | - |
1183 | | - for (size_t cid = 1; cid < collisionIds.size() - 1; cid++) { |
1184 | | - const auto& collision = collisions.rawIteratorAt(collisionIds[cid]); |
1185 | | - int64_t collisionIndex = collision.globalIndex(); |
1186 | | - auto bc = bcs.rawIteratorAt(collision.bcId()); |
1187 | | - |
1188 | | - /*// require a minimum BC gap between the current conllision and the previous/next ones |
1189 | | - const auto& collisionPrev = collisions.rawIteratorAt(collisionIds[cid-1]); |
1190 | | - const auto& collisionNext = collisions.rawIteratorAt(collisionIds[cid+1]); |
1191 | | - auto bcPrev = bcs.rawIteratorAt(collisionPrev.bcId()); |
1192 | | - auto bcNext = bcs.rawIteratorAt(collisionNext.bcId()); |
1193 | | - int64_t deltaPrev = bc.globalBC() - bcPrev.globalBC(); |
1194 | | - int64_t deltaNext = bcNext.globalBC() - bc.globalBC(); |
1195 | | - if (deltaPrev < 50 || deltaNext < 50) { |
1196 | | - continue; |
1197 | | - }*/ |
1198 | | - |
1199 | | - // fill collision information for global muon tracks (MFT-MCH-MID matches) |
1200 | | - for (auto muonTrack : muonTracks) { |
1201 | | - if (!muonTrack.has_collision()) |
1202 | | - continue; |
1203 | | - |
1204 | | - if (collisionIndex != muonTrack.collisionId()) { |
1205 | | - continue; |
1206 | | - } |
1207 | | - |
1208 | | - auto& collisionInfo = collisionInfos[collisionIndex]; |
1209 | | - collisionInfo.index = collisionIndex; |
1210 | | - collisionInfo.bc = bc.globalBC(); |
1211 | | - collisionInfo.zVertex = collision.posZ(); |
1212 | | - |
1213 | | - if (collisionInfo.matchablePairs.empty()) { |
1214 | | - FillMatchablePairs(collisionInfo, muonTracks, mftTracks); |
1215 | | - } |
1216 | | - |
1217 | | - if (static_cast<int>(muonTrack.trackType()) > 2) { |
1218 | | - // standalone MCH or MCH-MID tracks |
1219 | | - int64_t mchTrackIndex = muonTrack.globalIndex(); |
1220 | | - collisionInfo.mchTracks.push_back(mchTrackIndex); |
1221 | | - } else { |
1222 | | - // global muon tracks (MFT-MCH or MFT-MCH-MID) |
1223 | | - int64_t muonTrackIndex = muonTrack.globalIndex(); |
1224 | | - double matchChi2 = muonTrack.chi2MatchMCHMFT() / 5.f; |
1225 | | - double matchScore = chi2ToScore(muonTrack.chi2MatchMCHMFT(), 5, 50.f); |
1226 | | - auto const& mchTrack = muonTrack.template matchMCHTrack_as<TMUON>(); |
1227 | | - int64_t mchTrackIndex = mchTrack.globalIndex(); |
1228 | | - auto const& mftTrack = muonTrack.template matchMFTTrack_as<TMFT>(); |
1229 | | - int64_t mftTrackIndex = mftTrack.globalIndex(); |
1230 | | - |
1231 | | - // check if a vector of global muon candidates is already available for the current MCH index |
1232 | | - // if not, initialize a new one and add the current global muon track |
1233 | | - // bool globalMuonTrackFound = false; |
1234 | | - auto matchingCandidateIterator = collisionInfo.matchingCandidates.find(mchTrackIndex); |
1235 | | - if (matchingCandidateIterator != collisionInfo.matchingCandidates.end()) { |
1236 | | - matchingCandidateIterator->second.emplace_back(MatchingCandidate{ |
1237 | | - collisionIndex, |
1238 | | - muonTrackIndex, |
1239 | | - mchTrackIndex, |
1240 | | - mftTrackIndex, |
1241 | | - matchScore, |
1242 | | - matchChi2, |
1243 | | - -1, |
1244 | | - matchScore, |
1245 | | - matchChi2, |
1246 | | - -1, |
1247 | | - kMatchTypeUndefined}); |
1248 | | - } else { |
1249 | | - collisionInfo.matchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ |
1250 | | - collisionIndex, |
1251 | | - muonTrackIndex, |
1252 | | - mchTrackIndex, |
1253 | | - mftTrackIndex, |
1254 | | - matchScore, |
1255 | | - matchChi2, |
1256 | | - -1, |
1257 | | - matchScore, |
1258 | | - matchChi2, |
1259 | | - -1, |
1260 | | - kMatchTypeUndefined}); |
1261 | | - } |
1262 | | - } |
1263 | | - } |
1264 | | - |
1265 | | - // fill collision information for MFT standalone tracks |
1266 | | - for (auto mftTrack : mftTracks) { |
1267 | | - if (!mftTrack.has_collision()) |
1268 | | - continue; |
1269 | | - |
1270 | | - if (collisionIndex != mftTrack.collisionId()) { |
1271 | | - continue; |
1272 | | - } |
1273 | | - |
1274 | | - int64_t mftTrackIndex = mftTrack.globalIndex(); |
1275 | | - |
1276 | | - auto& collisionInfo = collisionInfos[collisionIndex]; |
1277 | | - collisionInfo.index = collisionIndex; |
1278 | | - collisionInfo.bc = bc.globalBC(); |
1279 | | - collisionInfo.zVertex = collision.posZ(); |
1280 | | - |
1281 | | - collisionInfo.mftTracks.push_back(mftTrackIndex); |
1282 | | - } |
1283 | | - } |
1284 | | - |
1285 | | - // sort the vectors of matching candidates in ascending order based on the matching score value |
1286 | | - auto compareMatchingScore = [](const MatchingCandidate& track1, const MatchingCandidate& track2) -> bool { |
1287 | | - return (track1.matchScore > track2.matchScore); |
1288 | | - }; |
1289 | | - |
1290 | | - for (auto& [collisionIndex, collisionInfo] : collisionInfos) { |
1291 | | - for (auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { |
1292 | | - std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore); |
1293 | | - |
1294 | | - int ranking = 1; |
1295 | | - for (auto& candidate : globalTracksVector) { |
1296 | | - const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); |
1297 | | - |
1298 | | - candidate.matchRanking = ranking; |
1299 | | - candidate.matchRankingProd = ranking; |
1300 | | - candidate.matchType = GetMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); |
1301 | | - ranking += 1; |
1302 | | - } |
1303 | | - } |
1304 | | - } |
1305 | | - } |
1306 | | - |
1307 | 1171 | // method 0: standard extrapolation |
1308 | 1172 | // method 1: MFT extrapolation using MCH momentum |
1309 | 1173 | // method 2: MCH track extrapolation constrained to the first MFT track point, MFT extrapolation using MCH momentum |
@@ -1824,6 +1688,144 @@ struct qaMatching { |
1824 | 1688 | return dimuon.M(); |
1825 | 1689 | } |
1826 | 1690 |
|
| 1691 | + template <class EVT, class BC, class TMUON, class TMFT> |
| 1692 | + void FillCollisions(EVT const& collisions, |
| 1693 | + BC const& bcs, |
| 1694 | + TMUON const& muonTracks, |
| 1695 | + TMFT const& mftTracks, |
| 1696 | + CollisionInfos& collisionInfos) |
| 1697 | + { |
| 1698 | + collisionInfos.clear(); |
| 1699 | + |
| 1700 | + std::vector<int64_t> collisionIds; |
| 1701 | + for (const auto& collision : collisions) { |
| 1702 | + collisionIds.push_back(collision.globalIndex()); |
| 1703 | + } |
| 1704 | + |
| 1705 | + for (size_t cid = 1; cid < collisionIds.size() - 1; cid++) { |
| 1706 | + const auto& collision = collisions.rawIteratorAt(collisionIds[cid]); |
| 1707 | + int64_t collisionIndex = collision.globalIndex(); |
| 1708 | + auto bc = bcs.rawIteratorAt(collision.bcId()); |
| 1709 | + |
| 1710 | + /*// require a minimum BC gap between the current conllision and the previous/next ones |
| 1711 | + const auto& collisionPrev = collisions.rawIteratorAt(collisionIds[cid-1]); |
| 1712 | + const auto& collisionNext = collisions.rawIteratorAt(collisionIds[cid+1]); |
| 1713 | + auto bcPrev = bcs.rawIteratorAt(collisionPrev.bcId()); |
| 1714 | + auto bcNext = bcs.rawIteratorAt(collisionNext.bcId()); |
| 1715 | + int64_t deltaPrev = bc.globalBC() - bcPrev.globalBC(); |
| 1716 | + int64_t deltaNext = bcNext.globalBC() - bc.globalBC(); |
| 1717 | + if (deltaPrev < 50 || deltaNext < 50) { |
| 1718 | + continue; |
| 1719 | + }*/ |
| 1720 | + |
| 1721 | + // fill collision information for global muon tracks (MFT-MCH-MID matches) |
| 1722 | + for (auto muonTrack : muonTracks) { |
| 1723 | + if (!muonTrack.has_collision()) |
| 1724 | + continue; |
| 1725 | + |
| 1726 | + if (collisionIndex != muonTrack.collisionId()) { |
| 1727 | + continue; |
| 1728 | + } |
| 1729 | + |
| 1730 | + auto& collisionInfo = collisionInfos[collisionIndex]; |
| 1731 | + collisionInfo.index = collisionIndex; |
| 1732 | + collisionInfo.bc = bc.globalBC(); |
| 1733 | + collisionInfo.zVertex = collision.posZ(); |
| 1734 | + |
| 1735 | + if (collisionInfo.matchablePairs.empty()) { |
| 1736 | + FillMatchablePairs(collisionInfo, muonTracks, mftTracks); |
| 1737 | + } |
| 1738 | + |
| 1739 | + if (static_cast<int>(muonTrack.trackType()) > 2) { |
| 1740 | + // standalone MCH or MCH-MID tracks |
| 1741 | + int64_t mchTrackIndex = muonTrack.globalIndex(); |
| 1742 | + collisionInfo.mchTracks.push_back(mchTrackIndex); |
| 1743 | + } else { |
| 1744 | + // global muon tracks (MFT-MCH or MFT-MCH-MID) |
| 1745 | + int64_t muonTrackIndex = muonTrack.globalIndex(); |
| 1746 | + double matchChi2 = muonTrack.chi2MatchMCHMFT() / 5.f; |
| 1747 | + double matchScore = chi2ToScore(muonTrack.chi2MatchMCHMFT(), 5, 50.f); |
| 1748 | + auto const& mchTrack = muonTrack.template matchMCHTrack_as<TMUON>(); |
| 1749 | + int64_t mchTrackIndex = mchTrack.globalIndex(); |
| 1750 | + auto const& mftTrack = muonTrack.template matchMFTTrack_as<TMFT>(); |
| 1751 | + int64_t mftTrackIndex = mftTrack.globalIndex(); |
| 1752 | + |
| 1753 | + // check if a vector of global muon candidates is already available for the current MCH index |
| 1754 | + // if not, initialize a new one and add the current global muon track |
| 1755 | + // bool globalMuonTrackFound = false; |
| 1756 | + auto matchingCandidateIterator = collisionInfo.matchingCandidates.find(mchTrackIndex); |
| 1757 | + if (matchingCandidateIterator != collisionInfo.matchingCandidates.end()) { |
| 1758 | + matchingCandidateIterator->second.emplace_back(MatchingCandidate{ |
| 1759 | + collisionIndex, |
| 1760 | + muonTrackIndex, |
| 1761 | + mchTrackIndex, |
| 1762 | + mftTrackIndex, |
| 1763 | + matchScore, |
| 1764 | + matchChi2, |
| 1765 | + -1, |
| 1766 | + matchScore, |
| 1767 | + matchChi2, |
| 1768 | + -1, |
| 1769 | + kMatchTypeUndefined}); |
| 1770 | + } else { |
| 1771 | + collisionInfo.matchingCandidates[mchTrackIndex].emplace_back(MatchingCandidate{ |
| 1772 | + collisionIndex, |
| 1773 | + muonTrackIndex, |
| 1774 | + mchTrackIndex, |
| 1775 | + mftTrackIndex, |
| 1776 | + matchScore, |
| 1777 | + matchChi2, |
| 1778 | + -1, |
| 1779 | + matchScore, |
| 1780 | + matchChi2, |
| 1781 | + -1, |
| 1782 | + kMatchTypeUndefined}); |
| 1783 | + } |
| 1784 | + } |
| 1785 | + } |
| 1786 | + |
| 1787 | + // fill collision information for MFT standalone tracks |
| 1788 | + for (auto mftTrack : mftTracks) { |
| 1789 | + if (!mftTrack.has_collision()) |
| 1790 | + continue; |
| 1791 | + |
| 1792 | + if (collisionIndex != mftTrack.collisionId()) { |
| 1793 | + continue; |
| 1794 | + } |
| 1795 | + |
| 1796 | + int64_t mftTrackIndex = mftTrack.globalIndex(); |
| 1797 | + |
| 1798 | + auto& collisionInfo = collisionInfos[collisionIndex]; |
| 1799 | + collisionInfo.index = collisionIndex; |
| 1800 | + collisionInfo.bc = bc.globalBC(); |
| 1801 | + collisionInfo.zVertex = collision.posZ(); |
| 1802 | + |
| 1803 | + collisionInfo.mftTracks.push_back(mftTrackIndex); |
| 1804 | + } |
| 1805 | + } |
| 1806 | + |
| 1807 | + // sort the vectors of matching candidates in ascending order based on the matching score value |
| 1808 | + auto compareMatchingScore = [](const MatchingCandidate& track1, const MatchingCandidate& track2) -> bool { |
| 1809 | + return (track1.matchScore > track2.matchScore); |
| 1810 | + }; |
| 1811 | + |
| 1812 | + for (auto& [collisionIndex, collisionInfo] : collisionInfos) { |
| 1813 | + for (auto& [mchIndex, globalTracksVector] : collisionInfo.matchingCandidates) { |
| 1814 | + std::sort(globalTracksVector.begin(), globalTracksVector.end(), compareMatchingScore); |
| 1815 | + |
| 1816 | + int ranking = 1; |
| 1817 | + for (auto& candidate : globalTracksVector) { |
| 1818 | + const auto& muonTrack = muonTracks.rawIteratorAt(candidate.globalTrackId); |
| 1819 | + |
| 1820 | + candidate.matchRanking = ranking; |
| 1821 | + candidate.matchRankingProd = ranking; |
| 1822 | + candidate.matchType = GetMatchType(muonTrack, muonTracks, mftTracks, collisionInfo.matchablePairs, ranking); |
| 1823 | + ranking += 1; |
| 1824 | + } |
| 1825 | + } |
| 1826 | + } |
| 1827 | + } |
| 1828 | + |
1827 | 1829 | template <class C, class TMUON, class TMFT> |
1828 | 1830 | void FillMatchingPlotsMC(C const& collision, |
1829 | 1831 | const CollisionInfo& collisionInfo, |
|
0 commit comments