18#include <oneapi/tbb/blocked_range.h>
19#include <oneapi/tbb/parallel_for.h>
33template <TrackletMode Mode,
bool EvalRun>
34static void trackleterKernelHost(
35 const gsl::span<const Cluster>& clustersNextLayer,
36 const gsl::span<const Cluster>& clustersCurrentLayer,
37 const gsl::span<uint8_t>& usedClustersNextLayer,
41 gsl::span<int> foundTracklets,
44 const short targetRof,
45 gsl::span<int> rofFoundTrackletsOffsets,
46 const int maxTrackletsPerCluster =
static_cast<int>(2e3))
48 const int PhiBins{
utils.getNphiBins()};
49 const int ZBins{
utils.getNzBins()};
51 for (
int iCurrentLayerClusterIndex = 0; iCurrentLayerClusterIndex < clustersCurrentLayer.size(); ++iCurrentLayerClusterIndex) {
52 int storedTracklets{0};
53 const Cluster& currentCluster{clustersCurrentLayer[iCurrentLayerClusterIndex]};
54 const int4 selectedBinsRect{VertexerTraits::getBinsRect(currentCluster, (
int)
Mode, 0.f, 50.f, phiCut / 2,
utils)};
55 if (selectedBinsRect.x != 0 || selectedBinsRect.y != 0 || selectedBinsRect.z != 0 || selectedBinsRect.w != 0) {
56 int phiBinsNum{selectedBinsRect.
w - selectedBinsRect.y + 1};
58 phiBinsNum += PhiBins;
61 for (
int iPhiBin{selectedBinsRect.y}, iPhiCount{0}; iPhiCount < phiBinsNum; iPhiBin = ++iPhiBin == PhiBins ? 0 : iPhiBin, iPhiCount++) {
62 const int firstBinIndex{
utils.getBinIndex(selectedBinsRect.x, iPhiBin)};
63 const int firstRowClusterIndex{indexTableNext[firstBinIndex]};
64 const int maxRowClusterIndex{indexTableNext[firstBinIndex + ZBins]};
66 for (
int iNextLayerClusterIndex{firstRowClusterIndex}; iNextLayerClusterIndex < maxRowClusterIndex && iNextLayerClusterIndex < static_cast<int>(clustersNextLayer.size()); ++iNextLayerClusterIndex) {
67 if (usedClustersNextLayer[iNextLayerClusterIndex]) {
70 const Cluster& nextCluster{clustersNextLayer[iNextLayerClusterIndex]};
71 if (o2::gpu::GPUCommonMath::Abs(math_utils::smallestAngleDifference(currentCluster.phi, nextCluster.phi)) < phiCut) {
72 if (storedTracklets < maxTrackletsPerCluster) {
73 if constexpr (!EvalRun) {
74 if constexpr (
Mode == TrackletMode::Layer0Layer1) {
75 tracklets[rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] + storedTracklets] =
Tracklet{iNextLayerClusterIndex, iCurrentLayerClusterIndex, nextCluster, currentCluster, targetRof, pivotRof};
77 tracklets[rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] + storedTracklets] =
Tracklet{iCurrentLayerClusterIndex, iNextLayerClusterIndex, currentCluster, nextCluster, pivotRof, targetRof};
86 if constexpr (EvalRun) {
87 foundTracklets[iCurrentLayerClusterIndex] += storedTracklets;
89 rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] += storedTracklets;
94static void trackletSelectionKernelHost(
95 const gsl::span<const Cluster> clusters0,
96 const gsl::span<const Cluster> clusters1,
97 gsl::span<unsigned char> usedClusters0,
98 gsl::span<unsigned char> usedClusters2,
99 const gsl::span<const Tracklet>& tracklets01,
100 const gsl::span<const Tracklet>& tracklets12,
102 const gsl::span<int> foundTracklets01,
103 const gsl::span<int> foundTracklets12,
105 const gsl::span<const o2::MCCompLabel>& trackletLabels,
107 const short targetRofId0,
108 const short targetRofId2,
109 bool safeWrites =
false,
110 const float tanLambdaCut = 0.025f,
111 const float phiCut = 0.005f,
112 const int maxTracklets =
static_cast<int>(1e2))
114 int offset01{0}, offset12{0};
115 for (
unsigned int iCurrentLayerClusterIndex{0}; iCurrentLayerClusterIndex < clusters1.size(); ++iCurrentLayerClusterIndex) {
116 int validTracklets{0};
117 for (
int iTracklet12{offset12}; iTracklet12 < offset12 + foundTracklets12[iCurrentLayerClusterIndex]; ++iTracklet12) {
118 for (
int iTracklet01{offset01}; iTracklet01 < offset01 + foundTracklets01[iCurrentLayerClusterIndex]; ++iTracklet01) {
119 if (usedTracklets[iTracklet01]) {
123 const auto& tracklet01{tracklets01[iTracklet01]};
124 const auto& tracklet12{tracklets12[iTracklet12]};
126 if (tracklet01.rof[0] != targetRofId0 || tracklet12.rof[1] != targetRofId2) {
130 const float deltaTanLambda{o2::gpu::GPUCommonMath::Abs(tracklet01.tanLambda - tracklet12.tanLambda)};
131 const float deltaPhi{o2::gpu::GPUCommonMath::Abs(math_utils::smallestAngleDifference(tracklet01.phi, tracklet12.phi))};
132 if (deltaTanLambda < tanLambdaCut && deltaPhi < phiCut && validTracklets != maxTracklets) {
134 __atomic_store_n(&usedClusters0[tracklet01.firstClusterIndex], 1, __ATOMIC_RELAXED);
135 __atomic_store_n(&usedClusters2[tracklet12.secondClusterIndex], 1, __ATOMIC_RELAXED);
137 usedClusters0[tracklet01.firstClusterIndex] = 1;
138 usedClusters2[tracklet12.secondClusterIndex] = 1;
140 usedTracklets[iTracklet01] =
true;
141 lines.emplace_back(tracklet01, clusters0.data(), clusters1.data());
142 if (!trackletLabels.empty()) {
143 linesLabels.emplace_back(trackletLabels[iTracklet01]);
149 offset01 += foundTracklets01[iCurrentLayerClusterIndex];
150 offset12 += foundTracklets12[iCurrentLayerClusterIndex];
167 mTaskArena->execute([&] {
170 [&](
const tbb::blocked_range<short>& Rofs) {
171 for (short pivotRofId = Rofs.begin(); pivotRofId < Rofs.end(); ++pivotRofId) {
172 bool skipROF = iteration && (int)mTimeFrame->getPrimaryVertices(pivotRofId).size() > mVrtParams[iteration].vertPerRofThreshold;
173 short startROF{std::max((short)0, static_cast<short>(pivotRofId - mVrtParams[iteration].deltaRof))};
174 short endROF{std::min(static_cast<short>(mTimeFrame->getNrof()), static_cast<short>(pivotRofId + mVrtParams[iteration].deltaRof + 1))};
175 for (auto targetRofId = startROF; targetRofId < endROF; ++targetRofId) {
176 trackleterKernelHost<TrackletMode::Layer0Layer1, true>(
177 !skipROF ? mTimeFrame->getClustersOnLayer(targetRofId, 0) : gsl::span<Cluster>(),
178 !skipROF ? mTimeFrame->getClustersOnLayer(pivotRofId, 1) : gsl::span<Cluster>(),
179 mTimeFrame->getUsedClustersROF(targetRofId, 0),
180 mTimeFrame->getIndexTable(targetRofId, 0).data(),
181 mVrtParams[iteration].phiCut,
182 mTimeFrame->getTracklets()[0],
183 mTimeFrame->getNTrackletsCluster(pivotRofId, 0),
188 mVrtParams[iteration].maxTrackletsPerCluster);
189 trackleterKernelHost<TrackletMode::Layer1Layer2, true>(
190 !skipROF ? mTimeFrame->getClustersOnLayer(targetRofId, 2) : gsl::span<Cluster>(),
191 !skipROF ? mTimeFrame->getClustersOnLayer(pivotRofId, 1) : gsl::span<Cluster>(),
192 mTimeFrame->getUsedClustersROF(targetRofId, 2),
193 mTimeFrame->getIndexTable(targetRofId, 2).data(),
194 mVrtParams[iteration].phiCut,
195 mTimeFrame->getTracklets()[1],
196 mTimeFrame->getNTrackletsCluster(pivotRofId, 1),
201 mVrtParams[iteration].maxTrackletsPerCluster);
203 mTimeFrame->getNTrackletsROF(pivotRofId, 0) = std::accumulate(mTimeFrame->getNTrackletsCluster(pivotRofId, 0).begin(), mTimeFrame->getNTrackletsCluster(pivotRofId, 0).end(), 0);
204 mTimeFrame->getNTrackletsROF(pivotRofId, 1) = std::accumulate(mTimeFrame->getNTrackletsCluster(pivotRofId, 1).begin(), mTimeFrame->getNTrackletsCluster(pivotRofId, 1).end(), 0);
210 tot0 == 0 || tot1 == 0) {
219 [&](
const tbb::blocked_range<short>& Rofs) {
220 for (short pivotRofId = Rofs.begin(); pivotRofId < Rofs.end(); ++pivotRofId) {
221 bool skipROF = iteration && (int)mTimeFrame->getPrimaryVertices(pivotRofId).size() > mVrtParams[iteration].vertPerRofThreshold;
222 short startROF{std::max((short)0, static_cast<short>(pivotRofId - mVrtParams[iteration].deltaRof))};
223 short endROF{std::min(static_cast<short>(mTimeFrame->getNrof()), static_cast<short>(pivotRofId + mVrtParams[iteration].deltaRof + 1))};
224 auto mobileOffset0 = mTimeFrame->getNTrackletsROF(pivotRofId, 0);
225 auto mobileOffset1 = mTimeFrame->getNTrackletsROF(pivotRofId, 1);
226 for (auto targetRofId = startROF; targetRofId < endROF; ++targetRofId) {
227 trackleterKernelHost<TrackletMode::Layer0Layer1, false>(
228 !skipROF ? mTimeFrame->getClustersOnLayer(targetRofId, 0) : gsl::span<Cluster>(),
229 !skipROF ? mTimeFrame->getClustersOnLayer(pivotRofId, 1) : gsl::span<Cluster>(),
230 mTimeFrame->getUsedClustersROF(targetRofId, 0),
231 mTimeFrame->getIndexTable(targetRofId, 0).data(),
232 mVrtParams[iteration].phiCut,
233 mTimeFrame->getTracklets()[0],
234 mTimeFrame->getNTrackletsCluster(pivotRofId, 0),
238 mTimeFrame->getExclusiveNTrackletsCluster(pivotRofId, 0),
239 mVrtParams[iteration].maxTrackletsPerCluster);
240 trackleterKernelHost<TrackletMode::Layer1Layer2, false>(
241 !skipROF ? mTimeFrame->getClustersOnLayer(targetRofId, 2) : gsl::span<Cluster>(),
242 !skipROF ? mTimeFrame->getClustersOnLayer(pivotRofId, 1) : gsl::span<Cluster>(),
243 mTimeFrame->getUsedClustersROF(targetRofId, 2),
244 mTimeFrame->getIndexTable(targetRofId, 2).data(),
245 mVrtParams[iteration].phiCut,
246 mTimeFrame->getTracklets()[1],
247 mTimeFrame->getNTrackletsCluster(pivotRofId, 1),
251 mTimeFrame->getExclusiveNTrackletsCluster(pivotRofId, 1),
252 mVrtParams[iteration].maxTrackletsPerCluster);
259 if (mTimeFrame->hasMCinformation()) {
260 for (
const auto& trk : mTimeFrame->getTracklets()[0]) {
262 if (!trk.isEmpty()) {
263 int sortedId0{mTimeFrame->getSortedIndex(trk.rof[0], 0, trk.firstClusterIndex)};
264 int sortedId1{mTimeFrame->getSortedIndex(trk.rof[1], 1, trk.secondClusterIndex)};
265 for (
const auto& lab0 : mTimeFrame->getClusterLabels(0, mTimeFrame->
getClusters()[0][sortedId0].clusterId)) {
266 for (
const auto& lab1 : mTimeFrame->getClusterLabels(1, mTimeFrame->
getClusters()[1][sortedId1].clusterId)) {
267 if (lab0 == lab1 && lab0.isValid()) {
272 if (
label.isValid()) {
277 mTimeFrame->getTrackletsLabel(0).emplace_back(
label);
282 debugComputeTracklets(iteration);
288 mTaskArena->execute([&] {
291 [&](
const tbb::blocked_range<short>& Rofs) {
292 for (short pivotRofId = Rofs.begin(); pivotRofId < Rofs.end(); ++pivotRofId) {
293 if (iteration && (int)mTimeFrame->getPrimaryVertices(pivotRofId).size() > mVrtParams[iteration].vertPerRofThreshold) {
296 if (mTimeFrame->getFoundTracklets(pivotRofId, 0).empty()) {
299 mTimeFrame->getLines(pivotRofId).reserve(mTimeFrame->getNTrackletsCluster(pivotRofId, 0).size());
300 bounded_vector<bool> usedTracklets(mTimeFrame->getFoundTracklets(pivotRofId, 0).size(), false, mMemoryPool.get());
301 short startROF{std::max((short)0, static_cast<short>(pivotRofId - mVrtParams[iteration].deltaRof))};
302 short endROF{std::min(static_cast<short>(mTimeFrame->getNrof()), static_cast<short>(pivotRofId + mVrtParams[iteration].deltaRof + 1))};
305 bool safeWrite = mTaskArena->max_concurrency() > 1 && mVrtParams[iteration].deltaRof != 0 && ((Rofs.begin() - startROF < 0) || (endROF - Rofs.end() > 0));
307 for (short targetRofId0 = startROF; targetRofId0 < endROF; ++targetRofId0) {
308 for (short targetRofId2 = startROF; targetRofId2 < endROF; ++targetRofId2) {
309 if (std::abs(targetRofId0 - targetRofId2) > mVrtParams[iteration].deltaRof) {
312 trackletSelectionKernelHost(
313 mTimeFrame->getClustersOnLayer(targetRofId0, 0),
314 mTimeFrame->getClustersOnLayer(pivotRofId, 1),
315 mTimeFrame->getUsedClustersROF(targetRofId0, 0),
316 mTimeFrame->getUsedClustersROF(targetRofId2, 2),
317 mTimeFrame->getFoundTracklets(pivotRofId, 0),
318 mTimeFrame->getFoundTracklets(pivotRofId, 1),
320 mTimeFrame->getNTrackletsCluster(pivotRofId, 0),
321 mTimeFrame->getNTrackletsCluster(pivotRofId, 1),
322 mTimeFrame->getLines(pivotRofId),
323 mTimeFrame->getLabelsFoundTracklets(pivotRofId, 0),
324 mTimeFrame->getLinesLabel(pivotRofId),
328 mVrtParams[iteration].tanLambdaCut,
329 mVrtParams[iteration].phiCut);
337 debugComputeTrackletMatching(iteration);
358 for (
int line1{0}; line1 < numTracklets; ++line1) {
359 if (usedTracklets[line1]) {
362 for (
int line2{line1 + 1}; line2 < numTracklets; ++line2) {
363 if (usedTracklets[line2]) {
370 if (tmpVertex[0] * tmpVertex[0] + tmpVertex[1] * tmpVertex[1] > 4.f) {
374 usedTracklets[line1] =
true;
375 usedTracklets[line2] =
true;
376 for (
int tracklet3{0}; tracklet3 < numTracklets; ++tracklet3) {
377 if (usedTracklets[tracklet3]) {
382 usedTracklets[tracklet3] =
true;
390 if (
mVrtParams[iteration].allowSingleContribClusters) {
392 for (
size_t iLine{0}; iLine < numTracklets; ++iLine) {
393 if (!usedTracklets[iLine]) {
404 [](ClusterLines& cluster1, ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
406 for (
int iCluster1{0}; iCluster1 < noClustersVec[rofId]; ++iCluster1) {
408 std::array<float, 3> vertex2{};
409 for (
int iCluster2{iCluster1 + 1}; iCluster2 < noClustersVec[rofId]; ++iCluster2) {
411 if (o2::gpu::GPUCommonMath::Abs(vertex1[2] - vertex2[2]) <
mVrtParams[iteration].clusterCut) {
412 float distance{(vertex1[0] - vertex2[0]) * (vertex1[0] - vertex2[0]) +
413 (vertex1[1] - vertex2[1]) * (vertex1[1] - vertex2[1]) +
414 (vertex1[2] - vertex2[2]) * (vertex1[2] - vertex2[2])};
422 --noClustersVec[rofId];
430 [](
const ClusterLines& cluster1,
const ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
431 bool atLeastOneFound{
false};
432 for (
int iCluster{0}; iCluster < noClustersVec[rofId]; ++iCluster) {
433 bool lowMultCandidate{
false};
437 lowMultCandidate &= (beamDistance2 <
mVrtParams[iteration].lowMultBeamDistCut *
mVrtParams[iteration].lowMultBeamDistCut);
438 if (!lowMultCandidate) {
440 noClustersVec[rofId]--;
446 atLeastOneFound =
true;
466 contLabels.insert(contLabels.end(), labels.begin(), labels.end());
496 debugComputeVertices(iteration);
502 LOGP(info,
"Using truth seeds as vertices; will skip computations");
505 const auto irs = dc->getEventRecords();
514 std::map<int, VertInfo> vertices;
515 for (
int iSrc{0}; iSrc < mcReader.
getNSources(); ++iSrc) {
516 auto eveId2colId = dc->getCollisionIndicesForSource(iSrc);
517 for (
int iEve{0}; iEve < mcReader.
getNEvents(iSrc); ++iEve) {
518 const auto&
ir = irs[eveId2colId[iEve]];
522 if (!vertices.contains(rofId)) {
530 vert.setTimeStamp(rofId);
531 vert.setNContributors(std::ranges::count_if(mcReader.
getTracks(iSrc, iEve), [](
const auto& trk) {
532 return trk.isPrimary() && trk.GetPt() > 0.2 && std::abs(trk.GetEta()) < 1.3;
534 vert.setXYZ((
float)eve.GetX(), (
float)eve.GetY(), (
float)eve.GetZ());
536 constexpr float cov = 50e-9;
537 vert.setCov(cov, cov, cov, cov, cov, cov);
538 vertices[rofId].vertices.push_back(vert);
539 vertices[rofId].srcs.push_back(iSrc);
540 vertices[rofId].events.push_back(iEve);
548 if (vertices.contains(iROF)) {
549 const auto& vertInfo = vertices[iROF];
550 verts = vertInfo.vertices;
551 nVerts += verts.size();
552 for (
size_t i{0};
i < verts.size(); ++
i) {
554 polls.emplace_back(lbl, 1.f);
562 LOGP(info,
"Found {}/{} ROFs with {} vertices -> <NV>={:.2f}", vertices.size(),
mTimeFrame->
getNrof(), nVerts, (
float)nVerts / (
float)vertices.size());
567#if defined(VTX_DEBUG)
568 LOGP(info,
"Vertexer with debug output forcing single thread");
569 mTaskArena = std::make_shared<tbb::task_arena>(1);
571 if (arena ==
nullptr) {
572 mTaskArena = std::make_shared<tbb::task_arena>(std::abs(
n));
573 LOGP(info,
"Setting seeding vertexer with {} threads.",
n);
576 LOGP(info,
"Attaching vertexer to calling thread's arena");
581void VertexerTraits::debugComputeTracklets(
int iteration)
584 LOGP(info,
"writing debug output for computeTracklets");
587 std::vector<Tracklet> trk0(strk0.begin(), strk0.end());
589 std::vector<Tracklet> trk1(strk1.begin(), strk1.end());
590 (*stream) <<
"tracklets"
591 <<
"Tracklets0=" << trk0
592 <<
"Tracklets1=" << trk1
593 <<
"iteration=" << iteration
600void VertexerTraits::debugComputeTrackletMatching(
int iteration)
603 LOGP(info,
"writing debug output for computeTrackletMatching");
609 <<
"iteration=" << iteration
614 LOGP(info,
"\tdumping also MC information");
616 const auto irs = dc->getEventRecords();
621 std::map<int, int> eve2BcInROF, bcInRofNEve;
622 for (
int iSrc{0}; iSrc < mcReader.getNSources(); ++iSrc) {
623 auto eveId2colId = dc->getCollisionIndicesForSource(iSrc);
624 for (
int iEve{0}; iEve < mcReader.getNEvents(iSrc); ++iEve) {
625 const auto&
ir = irs[eveId2colId[iEve]];
627 const auto& eve = mcReader.getMCEventHeader(iSrc, iEve);
629 eve2BcInROF[iEve] = bcInROF;
630 ++bcInRofNEve[bcInROF];
635 std::unordered_map<int, int> bcROFNTracklets01, bcROFNTracklets12;
636 std::vector<std::vector<int>> tracklet01BC, tracklet12BC;
641 auto& trkls01 = tracklet01BC.emplace_back();
642 for (
int iTrklt{0}; iTrklt < (
int)tracklet01.size(); ++iTrklt) {
643 const auto& tracklet = tracklet01[iTrklt];
644 const auto& lbl = lbls01[iTrklt];
645 if (lbl.isCorrect()) {
646 ++bcROFNTracklets01[eve2BcInROF[lbl.getEventID()]];
647 trkls01.push_back(eve2BcInROF[lbl.getEventID()]);
649 trkls01.push_back(-1);
655 auto& trkls12 = tracklet12BC.emplace_back();
656 for (
int iTrklt{0}; iTrklt < (
int)tracklet12.size(); ++iTrklt) {
657 const auto& tracklet = tracklet12[iTrklt];
664 if (lab1 == lab2 && lab1.isValid()) {
669 if (
label.isValid()) {
674 if (
label.isCorrect()) {
675 ++bcROFNTracklets12[eve2BcInROF[
label.getEventID()]];
676 trkls12.push_back(eve2BcInROF[
label.getEventID()]);
678 trkls12.push_back(-1);
683 LOGP(info,
"\tdumping ntracklets/RofBC ({})", bcInRofNEve.size());
684 for (
const auto& [bcInRof, neve] : bcInRofNEve) {
685 (*stream) <<
"ntracklets"
686 <<
"bcInROF=" << bcInRof
687 <<
"ntrkl01=" << bcROFNTracklets01[bcInRof]
688 <<
"ntrkl12=" << bcROFNTracklets12[bcInRof]
690 <<
"iteration=" << iteration
694 std::unordered_map<int, int> bcROFNLines;
698 for (
int iLine{0}; iLine < (
int)lines.size(); ++iLine) {
699 const auto&
line = lines[iLine];
700 const auto& lbl = lbls[iLine];
701 if (lbl.isCorrect()) {
702 ++bcROFNLines[eve2BcInROF[lbl.getEventID()]];
707 LOGP(info,
"\tdumping nlines/RofBC");
708 for (
const auto& [bcInRof, neve] : bcInRofNEve) {
709 (*stream) <<
"nlines"
710 <<
"bcInROF=" << bcInRof
711 <<
"nline=" << bcROFNLines[bcInRof]
713 <<
"iteration=" << iteration
721void VertexerTraits::debugComputeVertices(
int iteration)
724 LOGP(info,
"writing debug output for computeVertices");
726 (*stream) <<
"clusterlines"
728 <<
"iteration=" << iteration
733 LOGP(info,
"\tdumping also MC information");
735 const auto irs = dc->getEventRecords();
740 std::map<int, int> eve2BcInROF, bcInRofNEve;
741 for (
int iSrc{0}; iSrc < mcReader.getNSources(); ++iSrc) {
742 auto eveId2colId = dc->getCollisionIndicesForSource(iSrc);
743 for (
int iEve{0}; iEve < mcReader.getNEvents(iSrc); ++iEve) {
744 const auto&
ir = irs[eveId2colId[iEve]];
746 const auto& eve = mcReader.getMCEventHeader(iSrc, iEve);
748 eve2BcInROF[iEve] = bcInROF;
749 ++bcInRofNEve[bcInROF];
754 std::unordered_map<int, int> bcROFNVtx;
755 std::unordered_map<int, float> bcROFNPur;
756 std::unordered_map<o2::MCCompLabel, size_t> uniqueVertices;
760 for (
int i{0};
i < (
int)pvs.size(); ++
i) {
761 const auto& pv = pvs[
i];
762 const auto& [lbl, pur] = lblspv[
i];
763 if (lbl.isCorrect()) {
764 ++uniqueVertices[lbl];
765 ++bcROFNVtx[eve2BcInROF[lbl.getEventID()]];
766 bcROFNPur[eve2BcInROF[lbl.getEventID()]] += pur;
771 std::unordered_map<int, int> bcROFNUVtx, bcROFNCVtx;
772 for (
const auto& [k, _] : eve2BcInROF) {
773 bcROFNUVtx[k] = bcROFNCVtx[k] = 0;
776 for (
const auto& [lbl,
c] : uniqueVertices) {
778 ++bcROFNUVtx[eve2BcInROF[lbl.getEventID()]];
780 ++bcROFNCVtx[eve2BcInROF[lbl.getEventID()]];
784 LOGP(info,
"\tdumping nvtx/RofBC");
785 for (
const auto& [bcInRof, neve] : bcInRofNEve) {
787 <<
"bcInROF=" << bcInRof
788 <<
"nvtx=" << bcROFNVtx[bcInRof]
789 <<
"nuvtx=" << bcROFNUVtx[bcInRof]
790 <<
"ncvtx=" << bcROFNCVtx[bcInRof]
791 <<
"npur=" << bcROFNPur[bcInRof]
793 <<
"iteration=" << iteration
798 std::unordered_map<o2::MCCompLabel, std::vector<Vertex>> cVtx;
802 for (
int i{0};
i < (
int)pvs.size(); ++
i) {
803 const auto& pv = pvs[
i];
804 const auto& [lbl, pur] = lblspv[
i];
805 if (lbl.isCorrect() && uniqueVertices.contains(lbl) && uniqueVertices[lbl] > 1) {
806 if (!cVtx.contains(lbl)) {
807 cVtx[lbl] = std::vector<Vertex>();
809 cVtx[lbl].push_back(pv);
814 for (
auto& [_, vertices] : cVtx) {
815 std::sort(vertices.begin(), vertices.end(), [](
const Vertex&
a,
const Vertex&
b) { return a.getNContributors() > b.getNContributors(); });
816 for (
int i{0};
i < (
int)vertices.size(); ++
i) {
817 const auto vtx = vertices[
i];
821 <<
"dx=" << vertices[0].getX() - vtx.getX()
822 <<
"dy=" << vertices[0].getY() - vtx.getY()
823 <<
"dz=" << vertices[0].getZ() - vtx.getZ()
824 <<
"drof=" << vertices[0].getTimeStamp().getTimeStamp() - vtx.getTimeStamp().getTimeStamp()
825 <<
"dnc=" << vertices[0].getNContributors() - vtx.getNContributors()
826 <<
"iteration=" << iteration
Class to compute the primary vertex in ITS from tracklets.
static constexpr int maxTrackID()
static const DPLAlpideParam< N > & Instance()
void setTrackingParameters(const T ¶ms)
float getInverseZCoordinate(const int layerIndex) const
virtual void computeTrackletMatching(const int iteration=0)
void addTruthSeedingVertices()
virtual void computeTracklets(const int iteration=0)
void setNThreads(int n, std::shared_ptr< tbb::task_arena > &arena)
virtual void computeVertices(const int iteration=0)
std::vector< VertexingParameters > mVrtParams
IndexTableUtils mIndexTableUtils
virtual void updateVertexingParameters(const std::vector< VertexingParameters > &vrtPar, const TimeFrameGPUParameters &gpuTfPar)
static std::pair< o2::MCCompLabel, float > computeMain(const bounded_vector< o2::MCCompLabel > &elements)
static DigitizationContext * loadFromFile(std::string_view filename="")
size_t getNEvents(int source) const
Get number of events.
o2::dataformats::MCEventHeader const & getMCEventHeader(int source, int event) const
retrieves the MCEventHeader for a given eventID and sourceID
size_t getNSources() const
Get number of sources.
std::vector< MCTrack > const & getTracks(int source, int event) const
variant returning all tracks for source and event at once
GLboolean GLboolean GLboolean b
GLsizei GLsizei GLfloat distance
GLuint GLsizei const GLchar * label
GLboolean GLboolean GLboolean GLboolean a
int32_t const char int32_t line
void deepVectorClear(std::vector< T > &vec)
std::pmr::vector< T > bounded_vector
std::vector< T > toSTDVector(const bounded_vector< T > &b)
std::vector< Cluster > getClusters(int event)
Common utility functions.
const Cluster const Cluster *static float getDistanceFromPoint(const Line &line, const std::array< float, 3 > &point)
gsl::span< const Tracklet > getFoundTracklets(int rofId, int combId) const
void addPrimaryVertices(const bounded_vector< Vertex > &vertices, const int iteration)
bool hasMCinformation() const
unsigned int & getNoVertexROF()
gsl::span< const std::pair< MCCompLabel, float > > getPrimaryVerticesMCRecInfo(const int rofId) const
void addPrimaryVerticesInROF(const bounded_vector< Vertex > &vertices, const int rofId, const int iteration)
auto & getTrackletClusters(int rofId)
void computeTrackletsPerROFScans()
void addPrimaryVerticesLabelsInROF(const bounded_vector< std::pair< MCCompLabel, float > > &labels, const int rofId)
void addPrimaryVerticesContributorLabelsInROF(const bounded_vector< MCCompLabel > &labels, const int rofId)
void addPrimaryVerticesLabels(bounded_vector< std::pair< MCCompLabel, float > > &labels)
gsl::span< const MCCompLabel > getLabelsFoundTracklets(int rofId, int combId) const
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
auto & getLinesLabel(const int rofId)
gsl::span< int > getNTrackletsCluster(int rofId, int combId)
uint32_t getTotalTrackletsTF(const int iLayer)
void addPrimaryVerticesContributorLabels(bounded_vector< MCCompLabel > &labels)
auto & getLines(int rofId)
int getSortedIndex(int rofId, int layer, int idx) const
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
o2::InteractionRecord ir(0, 0)
std::vector< Tracklet64 > tracklets