49 const gsl::span<const Cluster>& clustersNextLayer,
50 const gsl::span<const Cluster>& clustersCurrentLayer,
51 const gsl::span<unsigned char>& usedClustersNextLayer,
55 gsl::span<int> foundTracklets,
58 const short targetRof,
59 gsl::span<int> rofFoundTrackletsOffsets,
60 const int maxTrackletsPerCluster =
static_cast<int>(2e3))
62 const int PhiBins{
utils.getNphiBins()};
63 const int ZBins{
utils.getNzBins()};
65 for (
int iCurrentLayerClusterIndex = 0; iCurrentLayerClusterIndex < clustersCurrentLayer.size(); ++iCurrentLayerClusterIndex) {
66 int storedTracklets{0};
67 const Cluster& currentCluster{clustersCurrentLayer[iCurrentLayerClusterIndex]};
68 const int4 selectedBinsRect{VertexerTraits::getBinsRect(currentCluster, (
int)
Mode, 0.f, 50.f, phiCut / 2,
utils)};
69 if (selectedBinsRect.x != 0 || selectedBinsRect.y != 0 || selectedBinsRect.z != 0 || selectedBinsRect.w != 0) {
70 int phiBinsNum{selectedBinsRect.
w - selectedBinsRect.y + 1};
72 phiBinsNum += PhiBins;
75 for (
int iPhiBin{selectedBinsRect.y}, iPhiCount{0}; iPhiCount < phiBinsNum; iPhiBin = ++iPhiBin == PhiBins ? 0 : iPhiBin, iPhiCount++) {
76 const int firstBinIndex{
utils.getBinIndex(selectedBinsRect.x, iPhiBin)};
77 const int firstRowClusterIndex{indexTableNext[firstBinIndex]};
78 const int maxRowClusterIndex{indexTableNext[firstBinIndex + ZBins]};
80 for (
int iNextLayerClusterIndex{firstRowClusterIndex}; iNextLayerClusterIndex < maxRowClusterIndex && iNextLayerClusterIndex < static_cast<int>(clustersNextLayer.size()); ++iNextLayerClusterIndex) {
81 if (usedClustersNextLayer[iNextLayerClusterIndex]) {
84 const Cluster& nextCluster{clustersNextLayer[iNextLayerClusterIndex]};
86 if (storedTracklets < maxTrackletsPerCluster) {
87 if constexpr (!EvalRun) {
89 tracklets[rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] + storedTracklets] =
Tracklet{iNextLayerClusterIndex, iCurrentLayerClusterIndex, nextCluster, currentCluster, targetRof, pivotRof};
91 tracklets[rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] + storedTracklets] =
Tracklet{iCurrentLayerClusterIndex, iNextLayerClusterIndex, currentCluster, nextCluster, pivotRof, targetRof};
100 if constexpr (EvalRun) {
101 foundTracklets[iCurrentLayerClusterIndex] += storedTracklets;
103 rofFoundTrackletsOffsets[iCurrentLayerClusterIndex] += storedTracklets;
109 const gsl::span<const Cluster> clusters0,
110 const gsl::span<const Cluster> clusters1,
111 gsl::span<unsigned char> usedClusters0,
112 gsl::span<unsigned char> usedClusters2,
113 const gsl::span<const Tracklet>& tracklets01,
114 const gsl::span<const Tracklet>& tracklets12,
115 std::vector<bool>& usedTracklets,
116 const gsl::span<int> foundTracklets01,
117 const gsl::span<int> foundTracklets12,
118 std::vector<Line>& lines,
119 const gsl::span<const MCCompLabel>& trackletLabels,
120 std::vector<MCCompLabel>& linesLabels,
121 const short pivotRofId,
122 const short targetRofId,
123 const float tanLambdaCut = 0.025f,
124 const float phiCut = 0.005f,
125 const int maxTracklets =
static_cast<int>(1e2))
127 int offset01{0}, offset12{0};
128 for (
unsigned int iCurrentLayerClusterIndex{0}; iCurrentLayerClusterIndex < clusters1.size(); ++iCurrentLayerClusterIndex) {
129 int validTracklets{0};
130 for (
int iTracklet12{offset12}; iTracklet12 < offset12 + foundTracklets12[iCurrentLayerClusterIndex]; ++iTracklet12) {
131 for (
int iTracklet01{offset01}; iTracklet01 < offset01 + foundTracklets01[iCurrentLayerClusterIndex]; ++iTracklet01) {
132 const auto& tracklet01{tracklets01[iTracklet01]};
133 const auto& tracklet12{tracklets12[iTracklet12]};
134 if (tracklet01.rof[0] != targetRofId || tracklet12.rof[1] != targetRofId) {
137 const float deltaTanLambda{o2::gpu::GPUCommonMath::Abs(tracklet01.tanLambda - tracklet12.tanLambda)};
139 if (!usedTracklets[iTracklet01] && deltaTanLambda < tanLambdaCut && deltaPhi < phiCut && validTracklets != maxTracklets) {
140 usedClusters0[tracklet01.firstClusterIndex] =
true;
141 usedClusters2[tracklet12.secondClusterIndex] =
true;
142 usedTracklets[iTracklet01] =
true;
143 lines.emplace_back(tracklet01, clusters0.data(), clusters1.data());
144 if (trackletLabels.size()) {
145 linesLabels.emplace_back(trackletLabels[iTracklet01]);
151 offset01 += foundTracklets01[iCurrentLayerClusterIndex];
152 offset12 += foundTracklets12[iCurrentLayerClusterIndex];
157 const std::array<int, 4>& selectedBinsRect,
160 std::vector<std::pair<int, int>> filteredBins{};
161 int phiBinsNum{selectedBinsRect[3] - selectedBinsRect[1] + 1};
162 if (phiBinsNum < 0) {
163 phiBinsNum +=
utils.getNphiBins();
165 filteredBins.reserve(phiBinsNum);
166 for (
int iPhiBin{selectedBinsRect[1]}, iPhiCount{0}; iPhiCount < phiBinsNum;
167 iPhiBin = ++iPhiBin ==
utils.getNphiBins() ? 0 : iPhiBin, iPhiCount++) {
168 const int firstBinIndex{
utils.getBinIndex(selectedBinsRect[0], iPhiBin)};
169 filteredBins.emplace_back(
170 indexTable[firstBinIndex],
171 utils.countRowSelectedBins(indexTable, iPhiBin, selectedBinsRect[0], selectedBinsRect[2]));
190#pragma omp parallel num_threads(mNThreads)
192#pragma omp for schedule(dynamic)
195 short startROF{std::max((
short)0,
static_cast<short>(pivotRofId -
mVrtParams[iteration].deltaRof))};
196 short endROF{std::min(
static_cast<short>(
mTimeFrame->
getNrof()),
static_cast<short>(pivotRofId +
mVrtParams[iteration].deltaRof + 1))};
197 for (
auto targetRofId = startROF; targetRofId < endROF; ++targetRofId) {
198 trackleterKernelHost<TrackletMode::Layer0Layer1, true>(
210 mVrtParams[iteration].maxTrackletsPerCluster);
211 trackleterKernelHost<TrackletMode::Layer1Layer2, true>(
223 mVrtParams[iteration].maxTrackletsPerCluster);
235#pragma omp for schedule(dynamic)
238 short startROF{std::max((
short)0,
static_cast<short>(pivotRofId -
mVrtParams[iteration].deltaRof))};
239 short endROF{std::min(
static_cast<short>(
mTimeFrame->
getNrof()),
static_cast<short>(pivotRofId +
mVrtParams[iteration].deltaRof + 1))};
242 for (
auto targetRofId = startROF; targetRofId < endROF; ++targetRofId) {
243 trackleterKernelHost<TrackletMode::Layer0Layer1, false>(
255 mVrtParams[iteration].maxTrackletsPerCluster);
256 trackleterKernelHost<TrackletMode::Layer1Layer2, false>(
268 mVrtParams[iteration].maxTrackletsPerCluster);
281 if (lab0 == lab1 && lab0.isValid()) {
286 if (
label.isValid()) {
296 TFile* trackletFile = TFile::Open(
"artefacts_tf.root",
"recreate");
297 TTree* tr_tre =
new TTree(
"tracklets",
"tf");
298 std::vector<o2::its::Tracklet> trkl_vec_0(0);
299 std::vector<o2::its::Tracklet> trkl_vec_1(0);
300 std::vector<o2::its::Cluster> clus0(0);
301 std::vector<o2::its::Cluster> clus1(0);
302 std::vector<o2::its::Cluster> clus2(0);
303 tr_tre->Branch(
"Tracklets0", &trkl_vec_0);
304 tr_tre->Branch(
"Tracklets1", &trkl_vec_1);
309 trkl_vec_0.push_back(tr);
312 trkl_vec_1.push_back(tr);
318 trackletFile->Close();
320 std::ofstream out01(
"NTC01_cpu.txt"), out12(
"NTC12_cpu.txt");
322 out01 <<
"ROF: " << iRof << std::endl;
323 out12 <<
"ROF: " << iRof << std::endl;
404 std::vector<Vertex> vertices;
405 std::vector<std::pair<o2::MCCompLabel, float>> polls;
416 std::vector<bool> usedTracklets(numTracklets,
false);
417 for (
int line1{0}; line1 < numTracklets; ++line1) {
418 if (usedTracklets[line1]) {
421 for (
int line2{line1 + 1}; line2 < numTracklets; ++line2) {
422 if (usedTracklets[line2]) {
429 if (tmpVertex[0] * tmpVertex[0] + tmpVertex[1] * tmpVertex[1] > 4.f) {
433 usedTracklets[line1] =
true;
434 usedTracklets[line2] =
true;
435 for (
int tracklet3{0}; tracklet3 < numTracklets; ++tracklet3) {
436 if (usedTracklets[tracklet3]) {
441 usedTracklets[tracklet3] =
true;
449 if (
mVrtParams[iteration].allowSingleContribClusters) {
451 for (
size_t iLine{0}; iLine < numTracklets; ++iLine) {
452 if (!usedTracklets[iLine]) {
463 [](ClusterLines& cluster1, ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
465 for (
int iCluster1{0}; iCluster1 < noClustersVec[rofId]; ++iCluster1) {
467 std::array<float, 3> vertex2{};
468 for (
int iCluster2{iCluster1 + 1}; iCluster2 < noClustersVec[rofId]; ++iCluster2) {
470 if (o2::gpu::GPUCommonMath::Abs(vertex1[2] - vertex2[2]) <
mVrtParams[iteration].clusterCut) {
471 float distance{(vertex1[0] - vertex2[0]) * (vertex1[0] - vertex2[0]) +
472 (vertex1[1] - vertex2[1]) * (vertex1[1] - vertex2[1]) +
473 (vertex1[2] - vertex2[2]) * (vertex1[2] - vertex2[2])};
481 --noClustersVec[rofId];
490 [](ClusterLines& cluster1, ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
493 dbg_clusLines[rofId].push_back(cl);
496 bool atLeastOneFound{
false};
497 for (
int iCluster{0}; iCluster < noClustersVec[rofId]; ++iCluster) {
498 bool lowMultCandidate{
false};
502 lowMultCandidate &= (beamDistance2 <
mVrtParams[iteration].lowMultBeamDistCut *
mVrtParams[iteration].lowMultBeamDistCut);
503 if (!lowMultCandidate) {
505 noClustersVec[rofId]--;
511 atLeastOneFound =
true;
525 std::vector<o2::MCCompLabel> labels;
549 TFile* dbg_file = TFile::Open(
"artefacts_tf.root",
"update");
550 TTree* ln_clus_lines_tree =
new TTree(
"clusterlines",
"tf");
551 std::vector<o2::its::ClusterLines> cl_lines_vec_pre(0);
552 std::vector<o2::its::ClusterLines> cl_lines_vec_post(0);
553 ln_clus_lines_tree->Branch(
"cllines_pre", &cl_lines_vec_pre);
554 ln_clus_lines_tree->Branch(
"cllines_post", &cl_lines_vec_post);
556 cl_lines_vec_pre.clear();
557 cl_lines_vec_post.clear();
559 cl_lines_vec_post.push_back(clln);
561 for (
auto& cl : dbg_clusLines[rofId]) {
562 cl_lines_vec_pre.push_back(cl);
564 ln_clus_lines_tree->Fill();
567 ln_clus_lines_tree->Write();
583 gsl::span<const o2::its::Line>& lines,
584 std::vector<bool>& usedLines,
585 std::vector<o2::its::ClusterLines>& clusterLines,
586 std::array<float, 2>& beamPosXY,
587 std::vector<Vertex>& vertices,
588 std::vector<int>& verticesInRof,
590 std::vector<o2::MCCompLabel>* labels,
593 int foundVertices{0};
595 const int numTracklets{
static_cast<int>(lines.size())};
596 for (
int line1{0}; line1 < numTracklets; ++line1) {
597 if (usedLines[line1]) {
600 for (
int line2{line1 + 1}; line2 < numTracklets; ++line2) {
601 if (usedLines[line2]) {
604 auto dca{Line::getDCA(lines[line1], lines[line2])};
606 clusterLines.emplace_back(line1, lines[line1], line2, lines[line2]);
607 std::array<float, 3> tmpVertex{clusterLines.back().getVertex()};
608 if (tmpVertex[0] * tmpVertex[0] + tmpVertex[1] * tmpVertex[1] > 4.f) {
609 clusterLines.pop_back();
612 usedLines[line1] =
true;
613 usedLines[line2] =
true;
614 for (
int tracklet3{0}; tracklet3 < numTracklets; ++tracklet3) {
615 if (usedLines[tracklet3]) {
619 clusterLines.back().add(tracklet3, lines[tracklet3]);
620 usedLines[tracklet3] =
true;
621 tmpVertex = clusterLines.back().getVertex();
629 if (
mVrtParams[iteration].allowSingleContribClusters) {
630 auto beamLine =
Line{{
tf->getBeamX(),
tf->getBeamY(), -50.f}, {
tf->getBeamX(),
tf->getBeamY(), 50.f}};
631 for (
size_t iLine{0}; iLine < numTracklets; ++iLine) {
632 if (!usedLines[iLine]) {
633 auto dca = Line::getDCA(lines[iLine], beamLine);
635 clusterLines.emplace_back(iLine, lines[iLine], -1, beamLine);
642 std::sort(clusterLines.begin(), clusterLines.end(), [](ClusterLines& cluster1, ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
644 for (
int iCluster1{0}; iCluster1 <
nClusters; ++iCluster1) {
645 std::array<float, 3> vertex1{clusterLines[iCluster1].getVertex()};
646 std::array<float, 3> vertex2{};
647 for (
int iCluster2{iCluster1 + 1}; iCluster2 <
nClusters; ++iCluster2) {
648 vertex2 = clusterLines[iCluster2].getVertex();
649 if (o2::gpu::GPUCommonMath::Abs(vertex1[2] - vertex2[2]) <
mVrtParams[iteration].clusterCut) {
650 float distance{(vertex1[0] - vertex2[0]) * (vertex1[0] - vertex2[0]) +
651 (vertex1[1] - vertex2[1]) * (vertex1[1] - vertex2[1]) +
652 (vertex1[2] - vertex2[2]) * (vertex1[2] - vertex2[2])};
654 for (
auto label : clusterLines[iCluster2].getLabels()) {
655 clusterLines[iCluster1].add(
label, lines[
label]);
656 vertex1 = clusterLines[iCluster1].getVertex();
658 clusterLines.erase(clusterLines.begin() + iCluster2);
666 std::sort(clusterLines.begin(), clusterLines.end(),
667 [](ClusterLines& cluster1, ClusterLines& cluster2) { return cluster1.getSize() > cluster2.getSize(); });
668 bool atLeastOneFound{
false};
669 for (
int iCluster{0}; iCluster <
nClusters; ++iCluster) {
670 bool lowMultCandidate{
false};
671 double beamDistance2{(
tf->getBeamX() - clusterLines[iCluster].getVertex()[0]) * (
tf->getBeamX() - clusterLines[iCluster].getVertex()[0]) +
672 (
tf->getBeamY() - clusterLines[iCluster].getVertex()[1]) * (
tf->getBeamY() - clusterLines[iCluster].getVertex()[1])};
674 if (atLeastOneFound && (lowMultCandidate = clusterLines[iCluster].getSize() <
mVrtParams[iteration].clusterContributorsCut)) {
675 lowMultCandidate &= (beamDistance2 <
mVrtParams[iteration].lowMultBeamDistCut *
mVrtParams[iteration].lowMultBeamDistCut);
676 if (!lowMultCandidate) {
677 clusterLines.erase(clusterLines.begin() + iCluster);
682 if (beamDistance2 < nsigmaCut && o2::gpu::GPUCommonMath::Abs(clusterLines[iCluster].getVertex()[2]) <
mVrtParams[iteration].maxZPositionAllowed) {
683 atLeastOneFound =
true;
686 clusterLines[iCluster].getVertex()[1],
687 clusterLines[iCluster].getVertex()[2]),
688 clusterLines[iCluster].getRMS2(),
690 clusterLines[iCluster].getSize(),
691 clusterLines[iCluster].getAvgDistance2());
692 vertices.back().setTimeStamp(clusterLines[iCluster].getROF());
694 for (
auto&
index : clusterLines[iCluster].getLabels()) {
695 labels->push_back(
tf->getLinesLabel(rofId)[
index]);
700 verticesInRof.push_back(foundVertices);
void trackletSelectionKernelHost(const gsl::span< const Cluster > clusters0, const gsl::span< const Cluster > clusters1, gsl::span< unsigned char > usedClusters0, gsl::span< unsigned char > usedClusters2, const gsl::span< const Tracklet > &tracklets01, const gsl::span< const Tracklet > &tracklets12, std::vector< bool > &usedTracklets, const gsl::span< int > foundTracklets01, const gsl::span< int > foundTracklets12, std::vector< Line > &lines, const gsl::span< const MCCompLabel > &trackletLabels, std::vector< MCCompLabel > &linesLabels, const short pivotRofId, const short targetRofId, const float tanLambdaCut=0.025f, const float phiCut=0.005f, const int maxTracklets=static_cast< int >(1e2))
void trackleterKernelHost(const gsl::span< const Cluster > &clustersNextLayer, const gsl::span< const Cluster > &clustersCurrentLayer, const gsl::span< unsigned char > &usedClustersNextLayer, int *indexTableNext, const float phiCut, std::vector< Tracklet > &tracklets, gsl::span< int > foundTracklets, const IndexTableUtils &utils, const short pivotRof, const short targetRof, gsl::span< int > rofFoundTrackletsOffsets, const int maxTrackletsPerCluster=static_cast< int >(2e3))