Belle II Software development
NDFinderPeakFinder.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include "trg/cdc/NDFinderPeakFinder.h"
10
11#include <vector>
12#include <utility>
13#include <array>
14#include <cmath>
15
16using namespace Belle2;
17
18// Find all the peaks in the Hough space sections
19std::vector<HoughPeak> NDFinderPeakFinder::findPeaks()
20{
21 std::vector<HoughPeak> candidatePeaks;
22 c3array houghSpaceBackup = *m_houghSpace;
23 for (unsigned short quadrant = 0; quadrant < 4; ++quadrant) {
24 for (unsigned short section = 0; section < 4; ++section) {
25 std::array<c3index, 2> sectionBounds = getSectionBounds(quadrant, section);
26 iterateOverSection(sectionBounds, candidatePeaks);
27 if (m_peakFindingParams.iterations > 1) *m_houghSpace = houghSpaceBackup;
28 }
29 }
30 return candidatePeaks;
31}
32
33// Get the phi bounds of one quadrant section
34std::array<c3index, 2> NDFinderPeakFinder::getSectionBounds(const unsigned short quadrant, const unsigned section)
35{
36 c3index quadrantSize = m_peakFindingParams.nPhi / 4;
37 c3index quadrantOffset = m_peakFindingParams.nPhi / 8;
38 c3index sectionSize = quadrantSize / 4;
39
40 c3index quadrantStart = quadrant * quadrantSize + quadrantOffset;
41 c3index sectionStart = quadrantStart + section * sectionSize;
42 c3index sectionEnd = sectionStart + sectionSize;
43
44 return {sectionStart, sectionEnd};
45}
46
47// Iterate m_peakFindingParams.iterations times over one section
48void NDFinderPeakFinder::iterateOverSection(const std::array<c3index, 2>& sectionBounds,
49 std::vector<HoughPeak>& candidatePeaks)
50{
51 for (unsigned short _ = 0; _ < m_peakFindingParams.iterations; ++_) {
52 HoughPeak sectionPeak = getSectionPeak(sectionBounds);
53 if (sectionPeak.weight > 0) candidatePeaks.push_back(sectionPeak);
54 if (m_peakFindingParams.iterations > 1) deletePeakSurroundings(sectionPeak);
55 }
56}
57
58// Returns the global section peak index and weight
59HoughPeak NDFinderPeakFinder::getSectionPeak(const std::array<c3index, 2>& sectionBounds)
60{
61 unsigned int peakValue = 0;
62 cell_index peakCell = {0, 0, 0};
63 for (c3index omegaIdx = 0; omegaIdx < m_peakFindingParams.nOmega; ++omegaIdx) {
64 for (c3index phiIdx = sectionBounds[0]; phiIdx < sectionBounds[1]; ++phiIdx) {
65 c3index phiIdxMod = phiIdx % m_peakFindingParams.nPhi;
66 for (c3index cotIdx = 0; cotIdx < m_peakFindingParams.nCot; ++cotIdx) {
67 if ((*m_houghSpace)[omegaIdx][phiIdxMod][cotIdx] > peakValue) {
68 peakValue = (*m_houghSpace)[omegaIdx][phiIdxMod][cotIdx];
69 peakCell = {omegaIdx, phiIdxMod, cotIdx};
70 }
71 }
72 }
73 }
74 HoughPeak peak;
75 peak.cell = peakCell;
76 peak.weight = peakValue;
77 return peak;
78}
79
80// Deletes the surroundings of the peak index with a butterfly cutout
81void NDFinderPeakFinder::deletePeakSurroundings(const HoughPeak& peak)
82{
83 c3index omegaPeak = peak.cell[0];
84 c3index phiPeak = peak.cell[1];
85
86 c3index omegaLowerBound = std::max<unsigned short>(0, omegaPeak - m_peakFindingParams.omegaTrim);
87 c3index omegaUpperBound = std::min<unsigned short>(m_peakFindingParams.nOmega, omegaPeak + m_peakFindingParams.omegaTrim + 1);
88
89 for (c3index cotIdx = 0; cotIdx < m_peakFindingParams.nCot; ++cotIdx) {
90 for (c3index omegaIdx = omegaLowerBound; omegaIdx < omegaUpperBound; ++omegaIdx) {
91 c3index phiCell = phiPeak + omegaPeak - omegaIdx;
92 c3index relativePhi = phiCell - phiPeak;
93
94 if (relativePhi > 0) {
95 DeletionBounds firstBounds = {
96 phiCell - m_peakFindingParams.phiTrim,
97 static_cast<c3index>(phiCell + m_peakFindingParams.phiTrim + std::floor(2.4 * relativePhi)),
98 omegaIdx,
99 cotIdx
100 };
101 clearHoughSpaceRow(firstBounds);
102 } else if (relativePhi < 0) {
103 DeletionBounds secondBounds = {
104 static_cast<c3index>(phiCell - m_peakFindingParams.phiTrim + std::ceil(2.4 * relativePhi)),
105 phiCell + m_peakFindingParams.phiTrim + 1,
106 omegaIdx,
107 cotIdx
108 };
109 clearHoughSpaceRow(secondBounds);
110 } else {
111 DeletionBounds thirdBounds = {
112 phiCell - m_peakFindingParams.phiTrim,
113 phiCell + m_peakFindingParams.phiTrim + 1,
114 omegaIdx,
115 cotIdx
116 };
117 clearHoughSpaceRow(thirdBounds);
118 }
119 }
120 }
121}
122
123// Clears a single omega row
124void NDFinderPeakFinder::clearHoughSpaceRow(const DeletionBounds& bounds)
125{
126 for (c3index phiIdx = bounds.phiLowerBound; phiIdx < bounds.phiUpperBound; ++phiIdx) {
127 c3index phiIdxMod = (phiIdx + m_peakFindingParams.nPhi) % m_peakFindingParams.nPhi;
128 (*m_houghSpace)[bounds.omega][phiIdxMod][bounds.cot] = 0;
129 }
130}
Abstract base class for different kinds of events.