13 #include "framework/logging/Logger.h"
14 #include "boost/iostreams/filter/gzip.hpp"
15 #include "boost/iostreams/filtering_streambuf.hpp"
16 #include "boost/iostreams/filtering_stream.hpp"
17 #include "trg/cdc/NDFinder.h"
24 bool diagonal,
int minhits,
int minhits_axial,
27 int mincells,
bool verbose,
28 string& axialFile,
string& stereoFile)
30 m_params.minhits = (
long unsigned int) minhits;
31 m_params.minhits_axial = (
long unsigned int) minhits_axial;
32 m_params.thresh = (float) thresh;
33 m_params.minassign = (float) minassign;
34 m_params.mincells = (
long unsigned int) mincells;
35 m_params.axialFile = axialFile;
36 m_params.stereoFile = stereoFile;
37 m_clusterer_params.minweight = (
unsigned short) minweight;
38 m_clusterer_params.minpts = (
unsigned short) minpts;
39 m_clusterer_params.diagonal = diagonal;
44 B2DEBUG(55,
"initialized binnings");
46 initHitModAxSt(*m_parrayHitMod);
47 B2DEBUG(55,
"initialized HitMod, a map of tsid to (orient, relid, letter).");
50 loadArray(m_params.axialFile, m_compaxbins, *m_pcompAxial);
51 B2DEBUG(55,
"loaded zero suppressed axial array ");
52 loadArray(m_params.stereoFile, m_compstbins, *m_pcompStereo);
53 B2DEBUG(55,
"loaded zero suppressed stereo array ");
56 restoreZeros(m_expaxbins, m_compaxbins, *m_parrayAxialExp, *m_pcompAxial);
57 B2DEBUG(55,
"restored expanded axial array (11/32 phi) ");
58 restoreZeros(m_expstbins, m_compstbins, *m_parrayStereoExp, *m_pcompStereo);
59 B2DEBUG(55,
"restored expanded stereo array (11/32 phi) ");
60 squeezeAll(m_axbins, *m_parrayAxial, *m_parrayAxialExp, m_params.parcels, m_params.parcelsExp);
61 B2DEBUG(55,
"squeezed axial array (11/32 phi) --> (7/32 phi): ");
62 squeezeAll(m_stbins, *m_parrayStereo, *m_parrayStereoExp, m_params.parcels, m_params.parcelsExp);
63 B2DEBUG(55,
"squeezed stereo array (11/32 phi) --> (7/32 phi)");
67 m_clusterer.setPlaneShape(m_planeShape);
93 m_nPhiOne = m_nPhiFull / m_params.phigeo;
97 m_nPhiUse = m_params.parcels * m_nPhiOne;
99 m_nPhiExp = m_params.parcelsExp * m_nPhiOne;
101 m_axbins.hitid = m_nAx;
102 m_stbins.hitid = m_nSt;
103 m_axbins.phi = m_nPhiUse;
104 m_stbins.phi = m_nPhiUse;
105 m_compaxbins.hitid = m_nAx;
106 m_compstbins.hitid = m_nSt;
107 m_compaxbins.phi = m_nPhiComp;
108 m_compstbins.phi = m_nPhiComp;
109 m_compaxbins.theta = 1;
110 m_expaxbins.hitid = m_nAx;
111 m_expstbins.hitid = m_nSt;
112 m_expaxbins.phi = m_nPhiExp;
113 m_expstbins.phi = m_nPhiExp;
115 m_fullbins.hitid = m_nTS;
116 m_fullbins.phi = m_nPhiFull;
118 m_pc5shapeax = {{ m_nAx, m_nPrio, m_nOmega, m_nPhiUse, m_nTheta }};
119 m_pc5shapest = {{ m_nSt, m_nPrio, m_nOmega, m_nPhiUse, m_nTheta }};
120 m_pc3shape = {{ m_nOmega, m_nPhiFull, m_nTheta }};
121 m_pc2shapeHitMod = {{ m_nTS, m_nPrio}};
122 m_pc5shapeCompAx = {{ m_nAx, m_nPrio, m_nOmega, m_nPhiComp, 1 }};
123 m_pc5shapeCompSt = {{ m_nSt, m_nPrio, m_nOmega, m_nPhiComp, m_nTheta }};
124 m_pc5shapeExpAx = {{ m_nAx, m_nPrio, m_nOmega, m_nPhiExp, m_nTheta }};
125 m_pc5shapeExpSt = {{ m_nSt, m_nPrio, m_nOmega, m_nPhiExp, m_nTheta }};
127 m_parrayAxial =
new c5array(m_pc5shapeax);
128 m_parrayStereo =
new c5array(m_pc5shapest);
129 m_phoughPlane =
new c3array(m_pc3shape);
130 m_parrayHitMod =
new c2array(m_pc2shapeHitMod);
131 m_pcompAxial =
new c5array(m_pc5shapeCompAx);
132 m_pcompStereo =
new c5array(m_pc5shapeCompSt);
133 m_parrayAxialExp =
new c5array(m_pc5shapeExpAx);
134 m_parrayStereoExp =
new c5array(m_pc5shapeExpSt);
136 m_nWires = {160, 160, 192, 224, 256, 288, 320, 352, 384};
138 m_planeShape = {m_nOmega, m_nPhiFull, m_nTheta};
141 vector<float> omegaRange = { -5., 5.};
142 vector<float> phiRange = {0., 11.25};
143 vector<float> thetaRange = {19., 140.};
144 float ssOmega = (omegaRange[1] - omegaRange[0]) / m_nOmega;
145 float ssPhi = (phiRange[1] - phiRange[0]) / m_nPhiOne;
146 float ssTheta = (thetaRange[1] - thetaRange[0]) / m_nTheta;
147 m_acceptRanges.push_back(omegaRange);
148 m_acceptRanges.push_back(phiRange);
149 m_acceptRanges.push_back(thetaRange);
150 m_slotsizes.push_back(ssOmega);
151 m_slotsizes.push_back(ssPhi);
152 m_slotsizes.push_back(ssTheta);
159 vector<c5elem> flatArray;
160 ifstream arrayFileGZ(filename, ios_base::in | ios_base::binary);
161 boost::iostreams::filtering_istream arrayStream;
162 arrayStream.push(boost::iostreams::gzip_decompressor());
163 arrayStream.push(arrayFileGZ);
165 if (arrayFileGZ.is_open()) {
166 while (arrayStream >> uline) {
167 flatArray.push_back(uline);
171 B2ERROR(
"could not open array file: " << filename);
173 B2DEBUG(55,
"loaded array from file " << filename);
174 unsigned long icount = 0;
175 for (c5index ihit = 0; ihit < bins.hitid; ihit++) {
176 for (c5index iprio = 0; iprio < bins.prio; iprio++) {
177 for (c5index iomega = 0; iomega < bins.omega; iomega++) {
178 for (c5index iphi = 0; iphi < bins.phi; iphi++) {
179 for (c5index itheta = 0; itheta < bins.theta; itheta++) {
180 hitsToTracks[ihit][iprio][iomega][iphi][itheta] = flatArray[icount];
192 unsigned short phigeo = m_params.phigeo;
193 std::vector<int> modSLs;
194 std::vector<int> toslid;
195 std::vector<int> sloffsets = {0};
196 std::vector<int> modoffsetsAxSt = {0, 0};
197 for (
int isl = 0; isl < m_nSL; isl++) {
198 modSLs.push_back(m_nWires[isl] / phigeo);
199 for (
int itsrel = 0; itsrel < m_nWires[isl]; itsrel++) {
200 toslid.push_back(isl);
202 sloffsets.push_back(sloffsets[isl] + m_nWires[isl]);
203 int last = modoffsetsAxSt[isl];
204 modoffsetsAxSt.push_back(last + m_nWires[isl] / phigeo);
206 for (
int its = 0; its < m_nTS; its++) {
207 int sl = toslid[its];
208 bool isAxial = (sl % 2 == 0);
209 int idInSL = its - sloffsets[sl];
210 int modSL = modSLs[sl];
211 int modId = idInSL % modSL;
212 int letter = (int) floor(idInSL / modSL);
213 int relId = (int)(modoffsetsAxSt[sl] + modId);
214 hitMod[its][0] = (int)(isAxial);
215 hitMod[its][1] = relId;
216 hitMod[its][2] = letter;
221 void NDFinder::squeezeOne(c5array& writeArray, c5array& readArray,
int outparcels,
int inparcels, c5index ihit, c5index iprio,
222 c5index itheta,
c5elem nomega)
224 int outnphi = (int)(12 * outparcels);
225 c5index trafstart = (c5index)((inparcels - outparcels) / 2 * 12);
226 c5index trafend = (c5index)(trafstart + outnphi);
227 for (c5index iomega = 0; iomega < nomega; iomega++) {
228 for (c5index iphi = 0; iphi < outnphi; iphi++) {
229 c5index readPhi = trafstart + iphi;
230 writeArray[ihit][iprio][iomega][iphi][itheta] = readArray[ihit][iprio][iomega][readPhi][itheta];
232 for (c5index iphi = 0; iphi < trafstart; iphi++) {
233 c5index writePhi = (c5index)(outnphi - trafstart + iphi);
234 writeArray[ihit][iprio][iomega][writePhi][itheta] += readArray[ihit][iprio][iomega][iphi][itheta];
236 for (c5index iphi = 0; iphi < trafstart; iphi++) {
237 c5index readPhi = trafend + iphi;
238 writeArray[ihit][iprio][iomega][iphi][itheta] += readArray[ihit][iprio][iomega][readPhi][itheta];
246 for (c5index ihit = 0; ihit < writebins.hitid; ihit++) {
247 for (c5index iprio = 0; iprio < writebins.prio; iprio++) {
248 for (c5index itheta = 0; itheta < writebins.theta; itheta++) {
249 squeezeOne(writeArray, readArray, outparcels, inparcels, ihit, iprio, itheta, writebins.omega);
258 B2DEBUG(55,
"restoreZeros: zerobins.theta " << zerobins.theta <<
", combins.theta " << compbins.theta);
259 for (c5index ihit = 0; ihit < compbins.hitid; ihit++) {
260 for (c5index iprio = 0; iprio < compbins.prio; iprio++) {
261 for (c5index iomega = 0; iomega < compbins.omega; iomega++) {
262 for (c5index itheta = 0; itheta < compbins.theta; itheta++) {
263 c5elem phiStart = compArray[ihit][iprio][iomega][0][itheta];
264 c5elem phiWidth = compArray[ihit][iprio][iomega][1][itheta];
265 for (c5index iphi = 0; iphi < phiWidth; iphi++) {
266 c5elem phiCur = phiStart + iphi;
267 expArray[ihit][iprio][iomega][phiCur][itheta] = compArray[ihit][iprio][iomega][iphi + 2][itheta];
268 if (compbins.theta == 1) {
269 for (c5index jtheta = 1; jtheta < zerobins.theta; jtheta++) {
270 expArray[ihit][iprio][iomega][phiCur][jtheta] = compArray[ihit][iprio][iomega][iphi + 2][itheta];
282 ushort minweightShow = 1)
285 ushort phiend = bins.phi;
286 bool started =
false;
287 unsigned long phiSlice = 0;
288 for (c3index iphi = 0; iphi < bins.phi; iphi++) {
289 for (c3index itheta = 0; itheta < bins.theta; itheta++) {
290 for (c3index iomega = 0; iomega < bins.omega; iomega++) {
291 phiSlice += hitsToTracks[iomega][iphi][itheta];
294 if (phiSlice == 0 and not started) {
296 }
else if (phiSlice != 0 and not started) {
298 }
else if (phiSlice != 0 and started) {
300 }
else if (phiSlice == 0 and started) {
306 B2DEBUG(55,
"printArray3D, phistart = " << phistart <<
", phiend = " << phiend);
307 auto d3shp = hitsToTracks.shape();
308 B2DEBUG(55,
"printArray shape: " << d3shp[0] <<
", " << d3shp[1] <<
", " << d3shp[2]);
310 if (phiend == phistart) {
314 for (c3index iomega = 0; iomega < bins.omega; iomega += om_inc) {
315 for (c3index iphi = phistart; iphi < phiend; iphi += phi_inc) {
317 ushort valRed = (ushort)((hitsToTracks[iomega][iphi][itheta]) / divide);
318 if (valRed <= minweightShow)
331 c2array& arrayHitMod = *m_parrayHitMod;
333 c2elem orient = arrayHitMod[m_hitIds[ihit]][0];
334 c2elem hitr = arrayHitMod[m_hitIds[ihit]][1];
335 c2elem letter = arrayHitMod[m_hitIds[ihit]][2];
337 unsigned short prio = m_prioPos[ ihit ];
338 short letterShort = (short) letter;
342 short DstartShort = (letterShort - 3) % m_params.phigeo * m_nPhiOne;
343 if (DstartShort < 0) {DstartShort = m_nPhiFull + DstartShort;}
346 short DstartComp = (letterShort - 5) % m_params.phigeo * m_nPhiOne;
347 if (DstartComp < 0) {DstartComp = m_nPhiFull + DstartComp;}
349 m_vecDstart.push_back(DstartShort);
350 m_hitOrients.push_back(orient);
353 addC3Comp(hitr, prio, *m_pcompAxial, DstartComp, m_compaxbins);
355 addC3Comp(hitr, prio, *m_pcompStereo, DstartComp, m_compstbins);
361 ushort prio,
const c5array& hitsToTracks,
365 c3array& houghPlane = *m_phoughPlane;
366 for (ushort itheta = 0; itheta < m_nTheta; itheta++) {
367 if (bins.theta > 1) {
370 for (ushort iomega = 0; iomega < m_nOmega; iomega++) {
371 ushort startfield = 0;
373 ushort xstart = hitsToTracks[hitr][prio][iomega][startfield][ntheta];
374 ushort xlen = hitsToTracks[hitr][prio][iomega][lenfield][ntheta];
375 for (ushort iphiz = 0; iphiz < xlen; iphiz++) {
376 ushort iphix = iphiz + 2;
377 ushort iphi = iphiz + xstart;
378 ushort iHoughPhi = (iphi + Dstart) % m_nPhiFull;
379 houghPlane[iomega][iHoughPhi][itheta] += hitsToTracks[hitr][prio][iomega][iphix][ntheta];
389 for (
unsigned short ihit = 0; ihit < m_nHits; ihit++) {
393 B2DEBUG(55,
"m_houghPlane, 2");
394 printArray3D(*m_phoughPlane, m_fullbins);
402 unsigned short nClusters = clusters.size();
403 unsigned short default_value = 0;
404 std::vector<unsigned short> hitElem(m_nHits, default_value);
405 std::vector<std::vector<unsigned short>> hitsVsClusters(nClusters, hitElem);
407 for (
unsigned long iclus = 0; iclus < clusters.size(); iclus++) {
409 vector<cell_index> entries = cli.
getEntries();
410 cell_index maxid = getMax(entries);
411 for (
unsigned long ihit = 0; ihit < m_hitIds.size(); ihit++) {
412 ushort contrib = hitContrib(maxid, ihit);
413 hitsVsClusters[iclus][ihit] = contrib;
416 return hitsVsClusters;
419 vector<SimpleCluster>
422 vector<SimpleCluster> useclusters;
423 vector<unsigned long> restHits;
424 if (hitsVsClusters.size() > 0) {
425 for (
unsigned long ihit = 0; ihit < m_hitIds.size(); ihit++) {
426 int cid = hitToCluster(hitsVsClusters, ihit);
428 clusters[cid].add_hit(ihit, hitsVsClusters[cid][ihit], m_hitOrients[ihit]);
430 restHits.push_back(ihit);
435 vector<bool> processed(hitsVsClusters.size(),
false);
436 for (
long unsigned int iround = 0; iround <= (m_params.minhits - 2); iround++) {
438 vector<unsigned long> stillRest;
439 for (
unsigned long irhit = 0; irhit < restHits.size(); irhit++) {
440 unsigned long ihit = restHits[irhit];
441 int cid = hitToCluster(hitsVsClusters, ihit);
443 clusters[cid].add_hit(ihit, hitsVsClusters[cid][ihit], m_hitOrients[ihit]);
445 stillRest.push_back(ihit);
448 restHits = stillRest;
451 for (
long unsigned int iclus = 0; iclus < hitsVsClusters.size(); iclus++) {
452 if (processed[iclus])
456 if (clu.
get_hits().size() >= m_params.minhits && clu.
get_naxial() >= m_params.minhits_axial) {
457 useclusters.push_back(clusters[iclus]);
458 processed[iclus] =
true;
459 msg <<
", add iclu=" << iclus <<
"(nHits=" << clu.
get_hits().size() <<
",round=" << iround <<
")";
460 }
else if (clu.
get_hits().size() < ((m_params.minhits - 2) + iround)) {
461 msg <<
", skip iclu=" << iclus <<
"(nHits=" << clu.
get_hits().size() <<
",round=" << iround <<
")";
462 for (
unsigned long int ihics = 0; ihics < hitsVsClusters[0].size(); ihics++) {
463 hitsVsClusters[iclus][ihics] = 0;
465 processed[iclus] =
true;
466 for (
unsigned short ihirs : clu.
get_hits()) {
467 restHits.push_back(ihirs);
473 B2DEBUG(55,
"iround=" << iround <<
474 ", restHits: " << restHits.size() <<
", useclusters: " <<
475 useclusters.size() <<
", msg=" << msg.str());
485 c3array& houghPlane = *m_phoughPlane;
486 m_clusterer.setNewPlane(houghPlane);
487 std::vector<SimpleCluster> allClusters = m_clusterer.dbscan();
488 std::vector<SimpleCluster> clusters;
490 if (clu.getEntries().size() > m_params.mincells) {
491 clusters.push_back(clu);
495 std::vector<std::vector<unsigned short>> hitsVsClusters = getHitsVsClusters(clusters);
496 vector<SimpleCluster> useclusters = relateHitsToClusters(hitsVsClusters, clusters);
498 for (
unsigned long iclus = 0; iclus < useclusters.size(); iclus++) {
500 vector<cell_index> entries = cli.
getEntries();
501 cell_index maxid = getMax(entries);
502 ushort maxval = houghPlane[maxid[0]][maxid[1]][maxid[2]];
503 float cutoff = m_params.thresh * maxval;
504 vector<cellweight> highWeight = getHighWeight(entries, cutoff);
505 vector<vector<long int>> flatHW;
506 for (
auto cx : highWeight) {
507 flatHW.push_back({cx.index[0], cx.index[1], cx.index[2], (
unsigned short int)cx.weight});
509 vector<double> result = getWeightedMean(highWeight);
510 vector<double> estimate = getBinToVal(result);
511 vector<double> transformed = transform(estimate);
523 return - 1 / cdc_track_radius(1. / estVal);
525 }
else if (idx == 1) {
526 float phiMod = estVal;
530 return phiMod * m_pi_deg;
532 float thetRad = estVal * m_pi_deg;
533 return cos(thetRad) / sin(thetRad);
536 std::vector<double> NDFinder::transform(std::vector<double> estimate)
538 std::vector<double> transformed;
539 for (
int idx = 0; idx < 3; idx++) {
540 transformed.push_back(transformVar(estimate[idx], idx));
548 vector<double> estimate;
549 for (ushort idim = 0; idim < 3; idim++) {
550 double trafd = m_acceptRanges[idim][0] + (thisAv[idim] + 0.5) * m_slotsizes[idim];
551 estimate.push_back(trafd);
565 axomega += elem.index[0] * elem.weight;
566 axphi += elem.index[1] * elem.weight;
567 axtheta += elem.index[2] * elem.weight;
569 weightSum += elem.weight;
571 axomega /= weightSum;
573 axtheta /= weightSum;
574 vector<double> result = {axomega, axphi, axtheta};
581 std::vector<std::vector<ushort>> candWeights;
583 for (
unsigned long iclus = 0; iclus < hitsVsClusters.size(); iclus++) {
584 std::vector<ushort> cwEntry = {(ushort) iclus, hitsVsClusters[iclus][ihit]};
585 candWeights.push_back(cwEntry);
587 if (candWeights.size() == 1) {
588 if (candWeights[0][1] > 0) {
591 }
else if (candWeights.size() > 1) {
593 bool operator()(vector<ushort> i, vector<ushort> j) {
return (i[1] > j[1]);}
595 sort(candWeights.begin(), candWeights.end(), mySortObject);
597 if (candWeights[0][1] > 0) {
598 float crit = fabs((
float)candWeights[0][1] - (
float)candWeights[1][1]) / ((float)candWeights[0][1]);
599 if (crit > m_params.minassign) {
600 cur_clus = candWeights[0][0];
610 ushort cur_weight = 0;
611 cell_index cur_max_index = {0, 0, 0};
612 const c3array& houghPlane = *m_phoughPlane;
614 for (
const cell_index& entry : entries) {
615 if (houghPlane[entry[0]][entry[1]][entry[2]] > cur_weight) {
616 cur_weight = houghPlane[entry[0]][entry[1]][entry[2]];
617 cur_max_index = entry;
620 return cur_max_index;
626 vector<cellweight> cellsAndWeight;
627 const c3array& houghPlane = *m_phoughPlane;
628 for (cell_index& entry : entries) {
629 ushort cellWeight = houghPlane[entry[0]][entry[1]][entry[2]];
630 if (cellWeight > cutoff) {
632 cur_elem.index = entry;
633 cur_elem.weight = cellWeight;
634 cellsAndWeight.push_back(cur_elem);
637 return cellsAndWeight;
644 ushort iHoughPhi = peak[1];
645 short Dstart = m_vecDstart[ihit];
646 ushort iphi = iHoughPhi - Dstart;
647 if (Dstart > iHoughPhi && Dstart > 300) {
648 iphi = m_nPhiFull - Dstart + iHoughPhi;
650 ushort iomega = peak[0];
651 ushort itheta = peak[2];
652 ushort orient = m_hitOrients[ihit];
654 const c2array& arrayHitMod = *m_parrayHitMod;
655 c2elem hitr = arrayHitMod[m_hitIds[ihit]][1];
656 unsigned short prio = m_prioPos[ ihit ];
657 if (Dstart > m_nPhiFull) {
658 B2ERROR(
"phi overflow: iHoughPhi = " << iHoughPhi <<
", Dstart = " << Dstart <<
", iphi=" << iphi);
660 if (iphi < m_nPhiUse) {
662 contrib = (*m_parrayAxial)[hitr][prio][iomega][iphi][itheta];
664 contrib = (*m_parrayStereo)[hitr][prio][iomega][iphi][itheta];
675 B2DEBUG(55,
"clusterer_params minweight=" << cpa.
minweight <<
", minpts=" << cpa.
minpts <<
", diagonal=" << cpa.
diagonal);
676 B2DEBUG(55,
"ndFinderParams minhits=" << m_params.minhits <<
677 ", minhits_axial=" << m_params.minhits_axial <<
", thresh=" << m_params.thresh <<
", minassign=" <<
678 m_params.minassign <<
679 ", mincells=" << m_params.mincells);
Store track parameters of found tracks.
std::vector< cellweight > getHighWeight(std::vector< cell_index > entries, float cutoff)
Candidate cells as seed for the clustering.
std::vector< SimpleCluster > relateHitsToClusters(std::vector< std::vector< unsigned short >> &hitsVsClusters, std::vector< SimpleCluster > &clusters)
Use confusion matrix to related hits to clusters.
void initBins()
Initialize the binnings and reserve the arrays.
void initHitModAxSt(c2array &hitMod)
Initialize hit modulo mappings.
void getCM()
NDFinder internal functions for track finding.
void squeezeAll(ndbinning writebins, c5array &writeArray, c5array &readArray, int outparcels, int inparcels)
Loop over all hits and theta bins and squeeze all 2D (omega,phi) planes.
void loadArray(const std::string &filename, ndbinning bins, c5array &hitsToTracks)
Load an NDFinder array of hit representations in track phase space.
void restoreZeros(ndbinning zerobins, ndbinning compbins, c5array &expArray, const c5array &compArray)
Restore non-zero suppressed hit curves.
ushort hitContrib(cell_index peak, ushort ihit)
Determine weight contribution of a single hit to a single cell.
void squeezeOne(c5array &writeArray, c5array &readArray, int outparcels, int inparcels, c5index ihit, c5index iprio, c5index itheta, c5elem nomega)
Squeeze phi-axis in a 2D (omega,phi) plane.
std::vector< double > getBinToVal(std::vector< double >)
Scale the weighted center to track parameter values.
void addC3Comp(ushort hitr, ushort prio, const c5array &hitsToTracks, short Dstart, ndbinning bins)
In place array addition to houghmap Comp: A = A + B.
void printParams()
Debug: print configured parameters.
void addLookup(unsigned short ihit)
Add a single axial or stereo hit to the houghmap.
int hitToCluster(std::vector< std::vector< unsigned short >> &hitsVsClusters, unsigned short hit)
Determine the best cluster for a single hit, given hitsVsClusters confusion matrix.
void findTracks()
main function for track finding
std::vector< std::vector< unsigned short > > getHitsVsClusters(std::vector< SimpleCluster > &clusters)
Create hits to clusters confusion matrix.
std::vector< double > getWeightedMean(std::vector< cellweight >)
Calculate the weighted center of a cluster.
float transformVar(float estVal, int idx)
Calculate physical units.
void printArray3D(c3array &hitsToTracks, ndbinning bins, ushort, ushort, ushort, ushort)
Debug Tool: Print part of the houghmap.
cell_index getMax(const std::vector< cell_index > &)
Peak cell in cluster.
void init(int minweight, int minpts, bool diagonal, int minhits, int minhits_axial, double thresh, double minassign, int mincells, bool verbose, std::string &axialFile, std::string &stereoFile)
initialization
unsigned long get_naxial()
Get number related axial hits.
std::vector< unsigned short > get_hits()
Get ids of related hits (indices of the TS StoreArray)
std::vector< cell_index > getEntries()
Get member cells in the cluster.
unsigned short c2elem
TS-Id to 1/32 phi-sector mapping is stored in a 2D array.
unsigned short c5elem
Store hit patterns in a 5D array (hitid, prio, omega, phi, theta)
Abstract base class for different kinds of events.
unsigned short minweight
minimum weight for a cluster cell
bool diagonal
Consider diagonal adjacent cells as neighbors.
unsigned short minpts
minimum number of neighbours for a cluster core cell
Default binning in a (7/32) phi-sector.