Belle II Software development
NDFinder Class Reference

Classes

struct  ContributionInfo
 
struct  SectorBinning
 
struct  WireInfo
 

Public Member Functions

void init (const NDFinderParameters &ndFinderParameters)
 
void reset ()
 
void addHit (const HitInfo &hitInfo)
 
void findTracks ()
 
std::vector< NDFinderTrack > * getFinderTracks ()
 

Protected Member Functions

void initLookUpArrays ()
 
void initHitToSectorMap ()
 
void loadCompressedHitReps (const std::string &fileName, const SectorBinning &compBins, c5array &compHitsToWeights)
 
void fillExpandedHitReps (const SectorBinning &compBins, const c5array &compHitsToWeights, c5array &expHitsToWeights)
 
void processHitForHoughSpace (const unsigned short hitIdx)
 
void writeHitToHoughSpace (const WireInfo &hitInfo, const c5array &expHitsToWeights)
 
void runTrackFinding ()
 
std::vector< SimpleClusterrelateHitsToClusters (std::vector< SimpleCluster > &clusters)
 
std::vector< std::vector< unsigned short > > getHitsVsClustersTable (const std::vector< SimpleCluster > &clusters)
 
unsigned short getHitContribution (const cell_index &peakCell, const unsigned short hitIdx)
 
std::vector< ContributionInfoextractContributionInfos (const std::vector< unsigned short > &clusterHits)
 
int getMaximumHitInSuperLayer (const std::vector< ContributionInfo > &contributionInfos, unsigned short superLayer)
 
bool checkHitSuperLayers (const SimpleCluster &cluster)
 
std::array< double, 3 > calculateCenterOfGravity (const SimpleCluster &cluster)
 
std::array< double, 3 > getTrackParameterEstimate (const std::array< double, 3 > &centerOfGravity)
 
std::array< double, 3 > transformTrackParameters (const std::array< double, 3 > &estimatedParameters)
 

Static Protected Member Functions

static double getTrackRadius (double transverseMomentum)
 

Private Attributes

std::vector< NDFinderTrackm_ndFinderTracks
 
std::vector< unsigned short > m_hitIDs
 
std::vector< unsigned short > m_hitSLIDs
 
std::vector< unsigned short > m_priorityWirePos
 
std::vector< short > m_priorityWireTime
 
unsigned short m_nHits {0}
 
NDFinderParameters m_ndFinderParams
 
Clusterizend m_clusterer
 
c2array * m_hitToSectorIDs = nullptr
 
c5array * m_compAxialHitReps = nullptr
 
c5array * m_compStereoHitReps = nullptr
 
c5array * m_expAxialHitReps = nullptr
 
c5array * m_expStereoHitReps = nullptr
 
c3array * m_houghSpace = nullptr
 

Static Private Attributes

static constexpr unsigned short m_nTS = 2336
 
static constexpr unsigned short m_nSL = 9
 
static constexpr unsigned short m_nAxial = 41
 
static constexpr unsigned short m_nStereo = 32
 
static constexpr unsigned short m_nPrio = 3
 
static constexpr unsigned short m_nOmega = 40
 
static constexpr unsigned short m_nPhi = 384
 
static constexpr unsigned short m_nCot = 9
 
static constexpr unsigned short m_phiGeo = 32
 
static constexpr unsigned short m_nPhiSector = m_nPhi / m_phiGeo
 
static constexpr unsigned short m_nPhiComp = 15
 
static constexpr SectorBinning m_compAxialBins = {m_nOmega, m_nPhiComp, 1, m_nAxial, m_nPrio}
 
static constexpr SectorBinning m_compStereoBins = {m_nOmega, m_nPhiComp, m_nCot, m_nStereo, m_nPrio}
 
static constexpr std::array< double, 2 > m_omegaRange = {-4., 4.}
 
static constexpr std::array< double, 2 > m_phiRange = {0., 11.25}
 
static constexpr std::array< double, 2 > m_cotRange = {2.3849627654510415, -1.0061730449796316}
 
static constexpr double m_binSizeOmega = (m_omegaRange[1] - m_omegaRange[0]) / m_nOmega
 
static constexpr double m_binSizePhi = (m_phiRange[1] - m_phiRange[0]) / m_nPhiSector
 
static constexpr double m_binSizeCot = (m_cotRange[1] - m_cotRange[0]) / m_nCot
 
static constexpr std::array< std::array< double, 2 >, 3 > m_acceptanceRanges = {m_omegaRange, m_phiRange, m_cotRange}
 
static constexpr std::array< double, 3 > m_binSizes = {m_binSizeOmega, m_binSizePhi, m_binSizeCot}
 

Detailed Description

Definition at line 96 of file NDFinder.h.

Constructor & Destructor Documentation

◆ ~NDFinder()

virtual ~NDFinder ( )
inlinevirtual

Definition at line 126 of file NDFinder.h.

127 {
128 delete m_hitToSectorIDs;
129 delete m_compAxialHitReps;
130 delete m_compStereoHitReps;
131 delete m_expAxialHitReps;
132 delete m_expStereoHitReps;
133 delete m_houghSpace;
134 }

Member Function Documentation

◆ addHit()

void addHit ( const HitInfo & hitInfo)

Definition at line 59 of file NDFinder.cc.

60{
61 // Priority position from the track segment finder: 0 = no hit, 3 = 1st priority, 1 = 2nd right, 2 = 2nd left
62 if (hitInfo.hitPrioPos > 0) { // Skip "no hit" case
63 m_hitIDs.push_back(hitInfo.hitID);
64 m_hitSLIDs.push_back(hitInfo.hitSLID);
65 m_priorityWirePos.push_back(3 - hitInfo.hitPrioPos); // 0 = 1st priority, 1 = 2nd left, 2 = 2nd right
66 m_priorityWireTime.push_back(hitInfo.hitPrioTime);
67 ++m_nHits;
68 }
69}

◆ calculateCenterOfGravity()

std::array< double, 3 > calculateCenterOfGravity ( const SimpleCluster & cluster)
protected

Definition at line 430 of file NDFinder.cc.

431{
432 double weightedSumOmega = 0.;
433 double weightedSumPhi = 0.;
434 double weightedSumCot = 0.;
435 unsigned int weightSum = 0;
436 std::vector<cell_index> clusterCells = cluster.getCells();
437 const int peakPhi = clusterCells.front()[1];
438 for (const cell_index& cellIdx : clusterCells) {
439 const unsigned short cellWeight = (*m_houghSpace)[cellIdx[0]][cellIdx[1]][cellIdx[2]];
440 weightedSumOmega += cellIdx[0] * cellWeight;
441 weightedSumCot += cellIdx[2] * cellWeight;
442 // Calculate relative phi position to peak
443 int phi = cellIdx[1];
444 int delta = phi - peakPhi;
445 // Wrap-around correction to stay within [-m_nPhi/2, +m_nPhi/2]
446 if (delta > m_nPhi / 2) {
447 delta -= m_nPhi;
448 } else if (delta < -m_nPhi / 2) {
449 delta += m_nPhi;
450 }
451 double unwrappedPhi = peakPhi + delta;
452 weightedSumPhi += unwrappedPhi * cellWeight;
453 weightSum += cellWeight;
454 }
455 weightedSumOmega /= weightSum;
456 weightedSumCot /= weightSum;
457 weightedSumPhi /= weightSum;
458 if (weightedSumPhi >= m_nPhi) weightedSumPhi -= m_nPhi;
459 if (weightedSumPhi < 0) weightedSumPhi += m_nPhi;
460 std::array<double, 3> centerOfGravity = {weightedSumOmega, weightedSumPhi, weightedSumCot};
461 return centerOfGravity;
462}

◆ checkHitSuperLayers()

bool checkHitSuperLayers ( const SimpleCluster & cluster)
protected

Definition at line 410 of file NDFinder.cc.

411{
412 std::vector<unsigned short> clusterHits = cluster.getClusterHits();
413 std::set<unsigned short> uniqueSLNumbers;
414 // Add all hit super layers
415 for (unsigned short hitIdx : clusterHits) {
416 uniqueSLNumbers.insert(m_hitSLIDs[hitIdx]);
417 }
418 // Calculate the number of hit axial and stereo super layers
419 unsigned short nSL = uniqueSLNumbers.size();
420 uniqueSLNumbers.insert({0, 2, 4, 6, 8});
421 unsigned short withAxialSLs = uniqueSLNumbers.size();
422 unsigned short axialNumber = 5 - (withAxialSLs - nSL);
423 unsigned short stereoNumber = nSL - axialNumber;
424 // Cut away all clusters that do have enough hit super layers
425 bool isValid = axialNumber >= m_ndFinderParams.minSuperAxial && stereoNumber >= m_ndFinderParams.minSuperStereo;
426 return isValid;
427}
bool isValid(EForwardBackward eForwardBackward)
Check whether the given enum instance is one of the valid values.

◆ extractContributionInfos()

std::vector< NDFinder::ContributionInfo > extractContributionInfos ( const std::vector< unsigned short > & clusterHits)
protected

Definition at line 363 of file NDFinder.cc.

364{
365 std::vector<ContributionInfo> contributionInfos;
366 for (unsigned short hitIdx = 0; hitIdx < m_hitIDs.size(); ++hitIdx) {
367 unsigned short contribution = clusterHits[hitIdx];
368 if (contribution > 0) {
369 ContributionInfo contributionInfo = {
370 hitIdx,
371 contribution,
372 m_hitSLIDs[hitIdx],
373 m_priorityWireTime[hitIdx]
374 };
375 contributionInfos.push_back(contributionInfo);
376 }
377 }
378 return contributionInfos;
379}

◆ fillExpandedHitReps()

void fillExpandedHitReps ( const SectorBinning & compBins,
const c5array & compHitsToWeights,
c5array & expHitsToWeights )
protected

Definition at line 159 of file NDFinder.cc.

160{
161 for (c5index hitID = 0; hitID < compBins.nHitIDs; ++hitID) {
162 for (c5index priorityWire = 0; priorityWire < compBins.nPriorityWires; ++priorityWire) {
163 for (c5index omegaIdx = 0; omegaIdx < compBins.omega; ++omegaIdx) {
164 for (c5index cotIdx = 0; cotIdx < compBins.cot; ++cotIdx) {
165 unsigned short phiStart = compHitsToWeights[hitID][priorityWire][omegaIdx][0][cotIdx];
166 unsigned short nPhiEntries = compHitsToWeights[hitID][priorityWire][omegaIdx][1][cotIdx];
167 for (c5index phiEntry = 0; phiEntry < nPhiEntries; ++phiEntry) {
168 unsigned short houghPhiIdx = (phiStart + phiEntry) % m_nPhi; // houghPhiIdx goes now over the complete Hough space
169 expHitsToWeights[hitID][priorityWire][omegaIdx][houghPhiIdx][cotIdx] =
170 compHitsToWeights[hitID][priorityWire][omegaIdx][phiEntry + 2][cotIdx];
171 if (compBins.cot == 1) { // Axial case: expand the same curve in all cot bins
172 for (c5index axialCotIdx = 1; axialCotIdx < m_nCot; ++axialCotIdx) {
173 expHitsToWeights[hitID][priorityWire][omegaIdx][houghPhiIdx][axialCotIdx] =
174 compHitsToWeights[hitID][priorityWire][omegaIdx][phiEntry + 2][cotIdx];
175 }
176 }
177 }
178 }
179 }
180 }
181 }
182}

◆ findTracks()

void findTracks ( )

Definition at line 204 of file NDFinder.cc.

205{
206 // Build the Hough plane by summing up all single hit contributions
207 for (unsigned short hitIdx = 0; hitIdx < m_nHits; ++hitIdx) {
208 processHitForHoughSpace(hitIdx);
209 }
210 runTrackFinding();
211}

◆ getFinderTracks()

std::vector< NDFinderTrack > * getFinderTracks ( )
inline

Definition at line 145 of file NDFinder.h.

145{ return &m_ndFinderTracks; }

◆ getHitContribution()

unsigned short getHitContribution ( const cell_index & peakCell,
const unsigned short hitIdx )
protected

Definition at line 336 of file NDFinder.cc.

337{
338 unsigned short contribution = 0;
339 unsigned short omegaIdx = peakCell[0];
340 unsigned short houghPhiIdx = peakCell[1];
341 unsigned short cotIdx = peakCell[2];
342
343 const c2array& hitToSectorIDs = *m_hitToSectorIDs;
344 unsigned short orientation = hitToSectorIDs[m_hitIDs[hitIdx]][0];
345 unsigned short relativeWireID = hitToSectorIDs[m_hitIDs[hitIdx]][1];
346 unsigned short relativeSectorID = hitToSectorIDs[m_hitIDs[hitIdx]][2];
347 unsigned short phiSectorStart = relativeSectorID * m_nPhiSector;
348 unsigned short priorityWire = m_priorityWirePos[hitIdx];
349
350 // Inverse Hough transformation (inverse of writeHitToHoughSpace method)
351 unsigned short phiIdx = (houghPhiIdx - phiSectorStart + m_nPhi) % m_nPhi;
352
353 if (orientation == 1) { // Axial TS
354 contribution = (*m_expAxialHitReps)[relativeWireID][priorityWire][omegaIdx][phiIdx][cotIdx];
355 } else { // Stereo TS
356 contribution = (*m_expStereoHitReps)[relativeWireID][priorityWire][omegaIdx][phiIdx][cotIdx];
357 }
358
359 return contribution;
360}

◆ getHitsVsClustersTable()

std::vector< std::vector< unsigned short > > getHitsVsClustersTable ( const std::vector< SimpleCluster > & clusters)
protected

Definition at line 318 of file NDFinder.cc.

319{
320 // Creates a (Number Clusters)x(Number Hits) matrix
321 std::vector<unsigned short> hitElem(m_nHits, 0);
322 std::vector<std::vector<unsigned short>> hitsVsClusters(clusters.size(), hitElem);
323 // Fill the matrix with all the hit contributions
324 for (unsigned short clusterIdx = 0; clusterIdx < clusters.size(); ++clusterIdx) {
325 SimpleCluster cluster = clusters[clusterIdx];
326 cell_index peakCell = cluster.getPeakCell();
327 for (unsigned short hitIdx = 0; hitIdx < m_hitIDs.size(); ++hitIdx) {
328 unsigned short contribution = getHitContribution(peakCell, hitIdx);
329 hitsVsClusters[clusterIdx][hitIdx] = contribution;
330 }
331 }
332 return hitsVsClusters;
333}

◆ getMaximumHitInSuperLayer()

int getMaximumHitInSuperLayer ( const std::vector< ContributionInfo > & contributionInfos,
unsigned short superLayer )
protected

Definition at line 382 of file NDFinder.cc.

383{
384 std::vector<std::vector<int>> contributionsInSL;
385 for (const ContributionInfo& contributionInfo : contributionInfos) {
386 if (contributionInfo.superLayer == superLayer) {
387 unsigned short hitIdx = contributionInfo.hitIndex;
388 unsigned short contribution = contributionInfo.contribution;
389 short priorityTime = contributionInfo.priorityTime;
390 contributionsInSL.push_back({hitIdx, contribution, priorityTime});
391 }
392 }
393 if (contributionsInSL.empty()) return -1;
394 // Sort by drift time
395 std::sort(contributionsInSL.begin(), contributionsInSL.end(),
396 [](const std::vector<int>& a, const std::vector<int>& b) { return a[2] < b[2]; });
397 // Find max contribution
398 int maximumHit = contributionsInSL[0][0];
399 int maximumContribution = contributionsInSL[0][1];
400 for (const auto& hit : contributionsInSL) {
401 if (hit[1] > maximumContribution) {
402 maximumHit = hit[0];
403 maximumContribution = hit[1];
404 }
405 }
406 return maximumHit;
407}

◆ getTrackParameterEstimate()

std::array< double, 3 > getTrackParameterEstimate ( const std::array< double, 3 > & centerOfGravity)
protected

Definition at line 465 of file NDFinder.cc.

466{
467 std::array<double, 3> estimatedParameters;
468 for (unsigned short dimension = 0; dimension < 3; ++dimension) {
469 double trackParameter = m_acceptanceRanges[dimension][0] + (centerOfGravity[dimension] + 0.5) * m_binSizes[dimension];
470 estimatedParameters[dimension] = trackParameter;
471 }
472 return transformTrackParameters(estimatedParameters);
473}

◆ getTrackRadius()

static double getTrackRadius ( double transverseMomentum)
inlinestaticprotected

Definition at line 182 of file NDFinder.h.

182{ return transverseMomentum * 1e11 / (3e8 * 1.5); }

◆ init()

void init ( const NDFinderParameters & ndFinderParameters)

Definition at line 27 of file NDFinder.cc.

28{
29 m_ndFinderParams = ndFinderParameters;
30
31 // Initialization of the pointer arrays, fills hit to sector LUT
32 initLookUpArrays();
33 initHitToSectorMap();
34
35 // Load the axial and stereo track to hit relations from file.
36 loadCompressedHitReps(m_ndFinderParams.axialFile, m_compAxialBins, *m_compAxialHitReps);
37 loadCompressedHitReps(m_ndFinderParams.stereoFile, m_compStereoBins, *m_compStereoHitReps);
38
39 // Fills the expanded hit representations (from compressed hits to weights)
40 fillExpandedHitReps(m_compAxialBins, *m_compAxialHitReps, *m_expAxialHitReps);
41 fillExpandedHitReps(m_compStereoBins, *m_compStereoHitReps, *m_expStereoHitReps);
42
43 // Reset the NDFinder data structure to process next event
44 reset();
45
46 // Parameters necessary for the clustering algorithm
47 ClustererParameters clustererParams = {
48 ndFinderParameters.iterations,
49 ndFinderParameters.omegaTrim,
50 ndFinderParameters.phiTrim,
51 m_nOmega,
52 m_nPhi,
53 m_nCot
54 };
55 m_clusterer = Clusterizend(clustererParams);
56}

◆ initHitToSectorMap()

void initHitToSectorMap ( )
protected

Definition at line 91 of file NDFinder.cc.

92{
93 // Number of first priority wires in each super layer (TS per SL)
94 constexpr std::array<unsigned short, 9> nWires = {160, 160, 192, 224, 256, 288, 320, 352, 384};
95 // Number of priority wires (= number of TS) per SL in a single (1/32) phi sector
96 std::vector<unsigned short> wiresPerSector;
97 // Lookup table: Maps the TS id to the SL number
98 std::vector<unsigned short> hitToSuperLayer;
99 // Integrated number of priority wires for each SL
100 std::vector<unsigned short> cumulativeWires = {0};
101 // Integrated number of sector priority wires for each SL (Axial even, Stereo odd)
102 std::vector<unsigned short> cumulativeSectorWires = {0, 0};
103 for (unsigned short superLayer = 0; superLayer < m_nSL; ++superLayer) {
104 wiresPerSector.push_back(nWires[superLayer] / m_phiGeo);
105 for (unsigned short _ = 0; _ < nWires[superLayer]; ++_) {
106 hitToSuperLayer.push_back(superLayer);
107 }
108 cumulativeWires.push_back(cumulativeWires[superLayer] + nWires[superLayer]);
109 cumulativeSectorWires.push_back(cumulativeSectorWires[superLayer] + nWires[superLayer] / m_phiGeo);
110 }
111 for (unsigned short hit = 0; hit < m_nTS; ++hit) {
112 unsigned short superLayer = hitToSuperLayer[hit];
113 bool isAxial = (superLayer % 2 == 0);
114 unsigned short wireIDinSL = hit - cumulativeWires[superLayer];
115 unsigned short wireIDinSector = wireIDinSL % wiresPerSector[superLayer];
116 unsigned short relativeWireIDinSector = cumulativeSectorWires[superLayer] + wireIDinSector;
117 unsigned short relativeSectorIDinSuperLayer = static_cast<unsigned short>(floor(wireIDinSL / wiresPerSector[superLayer]));
118 c2array& hitToSectorIDs = *m_hitToSectorIDs;
119 hitToSectorIDs[hit][0] = static_cast<unsigned short>(isAxial);
120 hitToSectorIDs[hit][1] = relativeWireIDinSector;
121 hitToSectorIDs[hit][2] = relativeSectorIDinSuperLayer;
122 }
123}

◆ initLookUpArrays()

void initLookUpArrays ( )
protected

Definition at line 72 of file NDFinder.cc.

73{
74 // Shapes of the arrays holding the hit patterns
75 const std::array<c2index, 2> shapeHitToSectorIDs = {{m_nTS, m_nPrio}};
76 const std::array<c5index, 5> shapeCompAxialHitReps = {{m_nAxial, m_nPrio, m_nOmega, m_nPhiComp, 1}};
77 const std::array<c5index, 5> shapeCompStereoHitReps = {{m_nStereo, m_nPrio, m_nOmega, m_nPhiComp, m_nCot}};
78 const std::array<c5index, 5> shapeExpAxialHitReps = {{m_nAxial, m_nPrio, m_nOmega, m_nPhi, m_nCot}};
79 const std::array<c5index, 5> shapeExpStereoHitReps = {{m_nStereo, m_nPrio, m_nOmega, m_nPhi, m_nCot}};
80 const std::array<c3index, 3> shapeHough = {{m_nOmega, m_nPhi, m_nCot}};
81
82 m_hitToSectorIDs = new c2array(shapeHitToSectorIDs);
83 m_compAxialHitReps = new c5array(shapeCompAxialHitReps);
84 m_compStereoHitReps = new c5array(shapeCompStereoHitReps);
85 m_expAxialHitReps = new c5array(shapeExpAxialHitReps);
86 m_expStereoHitReps = new c5array(shapeExpStereoHitReps);
87 m_houghSpace = new c3array(shapeHough);
88}

◆ loadCompressedHitReps()

void loadCompressedHitReps ( const std::string & fileName,
const SectorBinning & compBins,
c5array & compHitsToWeights )
protected

Definition at line 126 of file NDFinder.cc.

127{
128 // Array of the entries in trg/cdc/data/ndFinderArray*Comp.txt.gz
129 std::vector<unsigned short> flatArray;
130 std::ifstream arrayFileGZ(fileName, std::ios_base::in | std::ios_base::binary);
131 if (!arrayFileGZ.is_open()) {
132 B2ERROR("Could not open array file: " << fileName);
133 return;
134 }
135 boost::iostreams::filtering_istream arrayStream;
136 arrayStream.push(boost::iostreams::gzip_decompressor());
137 arrayStream.push(arrayFileGZ);
138 unsigned short uline;
139 while (arrayStream >> uline) {
140 flatArray.push_back(uline);
141 }
142 arrayFileGZ.close();
143 unsigned long arrayIndex = 0;
144 for (c5index hitID = 0; hitID < compBins.nHitIDs; ++hitID) {
145 for (c5index priorityWire = 0; priorityWire < compBins.nPriorityWires; ++priorityWire) {
146 for (c5index omegaIdx = 0; omegaIdx < compBins.omega; ++omegaIdx) {
147 for (c5index phiIdx = 0; phiIdx < compBins.phi; ++phiIdx) {
148 for (c5index cotIdx = 0; cotIdx < compBins.cot; ++cotIdx) {
149 compHitsToWeights[hitID][priorityWire][omegaIdx][phiIdx][cotIdx] = flatArray[arrayIndex];
150 ++arrayIndex;
151 }
152 }
153 }
154 }
155 }
156}

◆ processHitForHoughSpace()

void processHitForHoughSpace ( const unsigned short hitIdx)
protected

Definition at line 214 of file NDFinder.cc.

215{
216 const c2array& hitToSectorIDs = *m_hitToSectorIDs;
217 unsigned short orientation = hitToSectorIDs[m_hitIDs[hitIdx]][0];
218 unsigned short relativeWireID = hitToSectorIDs[m_hitIDs[hitIdx]][1];
219 unsigned short relativeSectorID = hitToSectorIDs[m_hitIDs[hitIdx]][2];
220 unsigned short phiSectorStart = relativeSectorID * m_nPhiSector;
221 unsigned short priorityWire = m_priorityWirePos[hitIdx];
222
223 WireInfo wireInfo = {relativeWireID, phiSectorStart, priorityWire};
224 if (orientation == 1) {
225 writeHitToHoughSpace(wireInfo, *m_expAxialHitReps);
226 } else {
227 writeHitToHoughSpace(wireInfo, *m_expStereoHitReps);
228 }
229}

◆ relateHitsToClusters()

std::vector< SimpleCluster > relateHitsToClusters ( std::vector< SimpleCluster > & clusters)
protected

Definition at line 296 of file NDFinder.cc.

297{
298 std::vector<std::vector<unsigned short>> hitsVsClusters = getHitsVsClustersTable(clusters);
299 std::vector<SimpleCluster> goodClusters;
300 if (hitsVsClusters.empty()) return goodClusters;
301
302 for (unsigned short clusterIdx = 0; clusterIdx < hitsVsClusters.size(); ++clusterIdx) {
303 std::vector<ContributionInfo> contributionInfos = extractContributionInfos(hitsVsClusters[clusterIdx]);
304 for (unsigned short superLayer = 0; superLayer < 9; ++superLayer) {
305 int maximumHit = getMaximumHitInSuperLayer(contributionInfos, superLayer);
306 if (maximumHit >= 0) { // there exists a hit
307 clusters[clusterIdx].addHitToCluster(static_cast<unsigned short>(maximumHit));
308 }
309 }
310 if (checkHitSuperLayers(clusters[clusterIdx])) {
311 goodClusters.push_back(clusters[clusterIdx]);
312 }
313 }
314 return goodClusters;
315}

◆ reset()

void reset ( )

Definition at line 185 of file NDFinder.cc.

186{
187 // Clear the vector of the found tracks
188 m_ndFinderTracks.clear();
189
190 // Clear the hit informations
191 m_hitIDs.clear();
192 m_hitSLIDs.clear();
193 m_nHits = 0;
194 m_priorityWirePos.clear();
195 m_priorityWireTime.clear();
196
197 // Create a new Hough space
198 delete m_houghSpace;
199 std::array<c3index, 3> shapeHough = {{m_nOmega, m_nPhi, m_nCot}};
200 m_houghSpace = new c3array(shapeHough);
201}

◆ runTrackFinding()

void runTrackFinding ( )
protected

Definition at line 247 of file NDFinder.cc.

248{
249 c3array& houghSpace = *m_houghSpace;
250 m_clusterer.setNewPlane(houghSpace);
251 std::vector<SimpleCluster> allClusters = m_clusterer.makeClusters();
252 std::vector<SimpleCluster> validClusters = relateHitsToClusters(allClusters);
253
254 for (SimpleCluster& cluster : validClusters) {
255 std::array<double, 3> centerOfGravity = calculateCenterOfGravity(cluster);
256 std::array<double, 3> estimatedParameters = getTrackParameterEstimate(centerOfGravity);
257
258 // Readouts for the 3DFinderInfo class for analysis (Hough space + cluster info)
259 std::vector<ROOT::Math::XYZVector> readoutHoughSpace;
260 std::vector<ROOT::Math::XYZVector> readoutCluster;
261
262 if (m_ndFinderParams.storeAdditionalReadout) {
263 // Readout of the complete Hough space
264 for (c3index omegaIdx = 0; omegaIdx < m_nOmega; ++omegaIdx) {
265 for (c3index phiIdx = 0; phiIdx < m_nPhi; ++phiIdx) {
266 for (c3index cotIdx = 0; cotIdx < m_nCot; ++cotIdx) {
267 unsigned short element = houghSpace[omegaIdx][phiIdx][cotIdx];
268 readoutHoughSpace.push_back(ROOT::Math::XYZVector(element, 0, 0));
269 }
270 }
271 }
272 // Readout of the peak cluster weight
273 unsigned int peakWeight = cluster.getPeakWeight();
274 readoutCluster.push_back(ROOT::Math::XYZVector(peakWeight, 0, 0));
275 // Readout of the number of cluster cells
276 unsigned short nCells = cluster.getCells().size();
277 readoutCluster.push_back(ROOT::Math::XYZVector(nCells, 0, 0));
278 // Readout of the cluster center of gravity
279 readoutCluster.push_back(ROOT::Math::XYZVector(centerOfGravity[0], centerOfGravity[1], centerOfGravity[2]));
280 // Readout of the cluster weights
281 for (const cell_index& cellIdx : cluster.getCells()) {
282 unsigned short element = houghSpace[cellIdx[0]][cellIdx[1]][cellIdx[2]];
283 readoutCluster.push_back(ROOT::Math::XYZVector(element, 0, 0));
284 }
285 // Readout of the cluster cell indices
286 for (const cell_index& cellIdx : cluster.getCells()) {
287 readoutCluster.push_back(ROOT::Math::XYZVector(cellIdx[0], cellIdx[1], cellIdx[2]));
288 }
289 }
290 m_ndFinderTracks.push_back(NDFinderTrack(estimatedParameters,
291 std::move(cluster), std::move(readoutHoughSpace), std::move(readoutCluster)));
292 }
293}

◆ transformTrackParameters()

std::array< double, 3 > transformTrackParameters ( const std::array< double, 3 > & estimatedParameters)
protected

Definition at line 476 of file NDFinder.cc.

477{
478 std::array<double, 3> transformed;
479 // Omega
480 if (estimatedParameters[0] == 0.) {
481 transformed[0] = estimatedParameters[0];
482 } else { // omega = sign(q)/r, r in cm
483 transformed[0] = -1 / getTrackRadius(1. / estimatedParameters[0]);
484 }
485 // Phi
486 if (estimatedParameters[1] > 180) {
487 transformed[1] = (estimatedParameters[1] - 360) * TMath::DegToRad();
488 } else {
489 transformed[1] = (estimatedParameters[1]) * TMath::DegToRad();
490 }
491 // Cot
492 transformed[2] = estimatedParameters[2];
493 return transformed;
494}

◆ writeHitToHoughSpace()

void writeHitToHoughSpace ( const WireInfo & hitInfo,
const c5array & expHitsToWeights )
protected

Definition at line 232 of file NDFinder.cc.

233{
234 c3array& houghSpace = *m_houghSpace;
235 for (unsigned short cotIdx = 0; cotIdx < m_nCot; ++cotIdx) {
236 for (unsigned short omegaIdx = 0; omegaIdx < m_nOmega; ++omegaIdx) {
237 for (unsigned short phiIdx = 0; phiIdx < m_nPhi; ++phiIdx) {
238 unsigned short houghPhiIdx = (phiIdx + wireInfo.phiSectorStart) % m_nPhi;
239 houghSpace[omegaIdx][houghPhiIdx][cotIdx] +=
240 expHitsToWeights[wireInfo.relativeWireID][wireInfo.priorityWire][omegaIdx][phiIdx][cotIdx];
241 }
242 }
243 }
244}

Member Data Documentation

◆ m_acceptanceRanges

std::array<std::array<double, 2>, 3> m_acceptanceRanges = {m_omegaRange, m_phiRange, m_cotRange}
staticconstexprprivate

Definition at line 241 of file NDFinder.h.

241{m_omegaRange, m_phiRange, m_cotRange};

◆ m_binSizeCot

double m_binSizeCot = (m_cotRange[1] - m_cotRange[0]) / m_nCot
staticconstexprprivate

Definition at line 240 of file NDFinder.h.

◆ m_binSizeOmega

double m_binSizeOmega = (m_omegaRange[1] - m_omegaRange[0]) / m_nOmega
staticconstexprprivate

Definition at line 238 of file NDFinder.h.

◆ m_binSizePhi

double m_binSizePhi = (m_phiRange[1] - m_phiRange[0]) / m_nPhiSector
staticconstexprprivate

Definition at line 239 of file NDFinder.h.

◆ m_binSizes

std::array<double, 3> m_binSizes = {m_binSizeOmega, m_binSizePhi, m_binSizeCot}
staticconstexprprivate

Definition at line 242 of file NDFinder.h.

242{m_binSizeOmega, m_binSizePhi, m_binSizeCot};

◆ m_clusterer

Clusterizend m_clusterer
private

Definition at line 201 of file NDFinder.h.

◆ m_compAxialBins

SectorBinning m_compAxialBins = {m_nOmega, m_nPhiComp, 1, m_nAxial, m_nPrio}
staticconstexprprivate

Definition at line 230 of file NDFinder.h.

230{m_nOmega, m_nPhiComp, 1, m_nAxial, m_nPrio}; // 40, 15, 1, 41, 3

◆ m_compAxialHitReps

c5array* m_compAxialHitReps = nullptr
private

Definition at line 264 of file NDFinder.h.

◆ m_compStereoBins

SectorBinning m_compStereoBins = {m_nOmega, m_nPhiComp, m_nCot, m_nStereo, m_nPrio}
staticconstexprprivate

Definition at line 231 of file NDFinder.h.

231{m_nOmega, m_nPhiComp, m_nCot, m_nStereo, m_nPrio}; // 40, 15, 9, 32, 3

◆ m_compStereoHitReps

c5array* m_compStereoHitReps = nullptr
private

Definition at line 265 of file NDFinder.h.

◆ m_cotRange

std::array<double, 2> m_cotRange = {2.3849627654510415, -1.0061730449796316}
staticconstexprprivate

Definition at line 237 of file NDFinder.h.

237{2.3849627654510415, -1.0061730449796316}; // => theta in [22.75, 135.18]

◆ m_expAxialHitReps

c5array* m_expAxialHitReps = nullptr
private

Definition at line 277 of file NDFinder.h.

◆ m_expStereoHitReps

c5array* m_expStereoHitReps = nullptr
private

Definition at line 278 of file NDFinder.h.

◆ m_hitIDs

std::vector<unsigned short> m_hitIDs
private

Definition at line 189 of file NDFinder.h.

◆ m_hitSLIDs

std::vector<unsigned short> m_hitSLIDs
private

Definition at line 191 of file NDFinder.h.

◆ m_hitToSectorIDs

c2array* m_hitToSectorIDs = nullptr
private

Definition at line 252 of file NDFinder.h.

◆ m_houghSpace

c3array* m_houghSpace = nullptr
private

Definition at line 280 of file NDFinder.h.

◆ m_nAxial

unsigned short m_nAxial = 41
staticconstexprprivate

Definition at line 213 of file NDFinder.h.

◆ m_nCot

unsigned short m_nCot = 9
staticconstexprprivate

Definition at line 220 of file NDFinder.h.

◆ m_ndFinderParams

NDFinderParameters m_ndFinderParams
private

Definition at line 199 of file NDFinder.h.

◆ m_ndFinderTracks

std::vector<NDFinderTrack> m_ndFinderTracks
private

Definition at line 187 of file NDFinder.h.

◆ m_nHits

unsigned short m_nHits {0}
private

Definition at line 197 of file NDFinder.h.

197{0};

◆ m_nOmega

unsigned short m_nOmega = 40
staticconstexprprivate

Definition at line 218 of file NDFinder.h.

◆ m_nPhi

unsigned short m_nPhi = 384
staticconstexprprivate

Definition at line 219 of file NDFinder.h.

◆ m_nPhiComp

unsigned short m_nPhiComp = 15
staticconstexprprivate

Definition at line 229 of file NDFinder.h.

◆ m_nPhiSector

unsigned short m_nPhiSector = m_nPhi / m_phiGeo
staticconstexprprivate

Definition at line 226 of file NDFinder.h.

◆ m_nPrio

unsigned short m_nPrio = 3
staticconstexprprivate

Definition at line 215 of file NDFinder.h.

◆ m_nSL

unsigned short m_nSL = 9
staticconstexprprivate

Definition at line 212 of file NDFinder.h.

◆ m_nStereo

unsigned short m_nStereo = 32
staticconstexprprivate

Definition at line 214 of file NDFinder.h.

◆ m_nTS

unsigned short m_nTS = 2336
staticconstexprprivate

Definition at line 211 of file NDFinder.h.

◆ m_omegaRange

std::array<double, 2> m_omegaRange = {-4., 4.}
staticconstexprprivate

Definition at line 234 of file NDFinder.h.

234{-4., 4.}; // 1/4 = 0.25 GeV (minimum transverse momentum)

◆ m_phiGeo

unsigned short m_phiGeo = 32
staticconstexprprivate

Definition at line 223 of file NDFinder.h.

◆ m_phiRange

std::array<double, 2> m_phiRange = {0., 11.25}
staticconstexprprivate

Definition at line 235 of file NDFinder.h.

235{0., 11.25}; // One phi sector (360/32)

◆ m_priorityWirePos

std::vector<unsigned short> m_priorityWirePos
private

Definition at line 193 of file NDFinder.h.

◆ m_priorityWireTime

std::vector<short> m_priorityWireTime
private

Definition at line 195 of file NDFinder.h.


The documentation for this class was generated from the following files: