10 #include <trg/cdc/modules/houghETF/CDCTriggerHoughETFModule.h>
12 #include <framework/logging/Logger.h>
16 #include <root/TMatrix.h>
21 #define CDC_SUPER_LAYERS 9
28 CDCTriggerHoughETFModule::countSL(
bool* layer)
30 if (m_requireSL0 && !layer[0])
return 0;
31 unsigned short lcnt = 0;
32 for (
int i = 0; i < CDC_SUPER_LAYERS; ++i) {
33 if (layer[i] ==
true) ++lcnt;
39 CDCTriggerHoughETFModule::shortTrack(
bool* layer)
41 unsigned short lcnt = 0;
44 for (
int i = 0; i < CDC_SUPER_LAYERS; i += 2) {
45 if (layer[i] ==
true) ++lcnt;
48 return (lcnt >= m_minHitsShort);
61 CDCTriggerHoughETFModule::fastInterceptFinder(
cdcMap& hits,
62 double x1_s,
double x2_s,
63 double y1_s,
double y2_s,
65 unsigned ix_s,
unsigned iy_s)
68 for (
unsigned i = 0; i < iterations; ++i) indent +=
" ";
69 B2DEBUG(150, indent <<
"intercept finder iteration " << iterations
70 <<
" x1 " << x1_s * 180 / M_PI <<
" x2 " << x2_s * 180 / M_PI
71 <<
" y1 " << y1_s <<
" y2 " << y2_s
72 <<
" ix " << ix_s <<
" iy " << iy_s);
81 vector<unsigned> idx_list;
84 double x1_d, x2_d, y1_d, y2_d;
89 unitx = ((x2_s - x1_s) / 2.0);
90 unity = ((y2_s - y1_s) / 2.0);
93 for (i = 0; i < 2 ; ++i) {
95 for (j = 0; j < 2; ++j) {
96 x1_d = x1_s + i * unitx;
97 x2_d = x1_s + (i + 1) * unitx;
98 y1_d = y1_s + j * unity;
99 y2_d = y1_s + (j + 1) * unity;
105 if (x2_d <= -M_PI || x1_d >= M_PI || y2_d <= -maxR + shiftR || y1_d >= maxR + shiftR) {
106 B2DEBUG(150, indent <<
"skip Hough cell outside of plane limits");
112 if (iterations != maxIterations && unitx > M_PI / 2.) {
113 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
118 bool layerHit[CDC_SUPER_LAYERS] = {
false};
119 for (
auto it = hits.begin(); it != hits.end(); ++it) {
126 y1 = m * sin(x1_d - 1e-10) - a * cos(x1_d - 1e-10);
127 y2 = m * sin(x2_d + 1e-10) - a * cos(x2_d + 1e-10);
129 if (iterations == maxIterations && y1 > y2)
continue;
130 if (!((y1 > y2_d && y2 > y2_d) || (y1 < y1_d && y2 < y1_d))) {
131 if (iterations == maxIterations) {
132 idx_list.push_back(iHit);
134 layerHit[iSL] =
true;
137 unsigned short nSL = countSL(layerHit);
138 B2DEBUG(150, indent <<
"i " << i <<
" j " << j
139 <<
" layerHit " <<
int(layerHit[0]) <<
int(layerHit[2])
140 <<
int(layerHit[4]) <<
int(layerHit[6]) <<
int(layerHit[8])
142 if (nSL >= m_minHits || shortTrack(layerHit)) {
143 if (iterations != maxIterations) {
144 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
146 TVector2 v1(x1_d, y1_d);
147 TVector2 v2(x2_d, y2_d);
149 nSL, houghCand.size()));
150 if (m_storePlane > 0) {
151 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
154 }
else if (m_storePlane > 1) {
157 for (
unsigned min = m_minHits - 1; min > 0; --min) {
159 if (iterations != maxIterations) {
160 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
162 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
178 CDCTriggerHoughETFModule::connectedRegions()
180 vector<vector<CDCTriggerHoughCand>> regions;
181 vector<CDCTriggerHoughCand> cpyCand = houghCand;
184 B2DEBUG(50,
"houghCand number " << cpyCand.size());
185 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
187 B2DEBUG(100, houghCand[icand].
getID()
188 <<
" nSL " << houghCand[icand].getSLcount()
189 <<
" x1 " << coord.first.X() <<
" x2 " << coord.second.X()
190 <<
" y1 " << coord.first.Y() <<
" y2 " << coord.second.Y());
194 while (cpyCand.size() > 0) {
195 B2DEBUG(100,
"make new region");
196 vector<CDCTriggerHoughCand> region;
197 vector<CDCTriggerHoughCand> rejected;
199 cpyCand.erase(cpyCand.begin());
200 region.push_back(start);
201 addNeighbors(start, cpyCand, region, rejected, start.getSLcount());
202 regions.push_back(region);
203 for (
auto cand = cpyCand.begin(); cand != cpyCand.end();) {
204 if (inList(*cand, region) || inList(*cand, rejected))
212 for (
unsigned ir = 0; ir < regions.size(); ++ir) {
213 B2DEBUG(50,
"region " << ir <<
" (" << regions[ir].size() <<
" cells).");
215 if (regions[ir].size() < m_minCells) {
216 B2DEBUG(50,
"Skipping region with " << regions[ir].size() <<
" cells.");
219 double xfirst = regions[ir][0].getCoord().first.X();
223 vector<unsigned> mergedList;
224 int xmin = m_nCellsPhi;
226 int ymin = m_nCellsR;
228 vector<TVector2> cellIds = {};
229 for (
unsigned ir2 = 0; ir2 < regions[ir].size(); ++ir2) {
231 B2DEBUG(100,
" " << regions[ir][ir2].
getID()
232 <<
" nSL " << regions[ir][ir2].getSLcount()
233 <<
" x1 " << hc.first.X() <<
" x2 " << hc.second.X()
234 <<
" y1 " << hc.first.Y() <<
" y2 " << hc.second.Y());
235 int ix = floor((hc.first.X() + M_PI) / 2. / M_PI * m_nCellsPhi + 0.5);
236 int iy = floor((hc.first.Y() + maxR - shiftR) / 2. / maxR * m_nCellsR + 0.5);
237 x += (hc.first.X() + hc.second.X());
238 if (xfirst - hc.first.X() > M_PI) {
241 }
else if (hc.first.X() - xfirst > M_PI) {
245 y += (hc.first.Y() + hc.second.Y());
247 vector<unsigned> idList = regions[ir][ir2].getIdList();
248 mergeIdList(mergedList, mergedList, idList);
249 xmin = min(xmin, ix);
250 xmax = max(xmax, ix);
251 ymin = min(ymin, iy);
252 ymax = max(ymax, iy);
253 cellIds.push_back(TVector2(ix, iy));
261 B2DEBUG(50,
"x " << x <<
" y " << y);
264 vector<unsigned> selectedList = {};
265 vector<unsigned> unselectedList = {};
266 selectHits(mergedList, selectedList, unselectedList);
270 m_tracks.appendNew(x, 2. * y, 0.);
272 for (
unsigned i = 0; i < selectedList.size(); ++i) {
273 unsigned its = selectedList[i];
274 if (m_storeTracks) track->addRelationTo(m_segmentHits[its]);
277 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
278 unsigned its = unselectedList[i];
279 if (m_storeTracks) track->addRelationTo(m_segmentHits[its], -1.);
283 m_clusters.appendNew(xmin, xmax, ymin, ymax, cellIds);
284 if (m_storeTracks) track->addRelationTo(cluster);
290 const vector<CDCTriggerHoughCand>& candidates,
291 vector<CDCTriggerHoughCand>& merged,
292 vector<CDCTriggerHoughCand>& rejected,
293 unsigned short nSLmax)
const
295 for (
unsigned icand = 0; icand < candidates.size(); ++icand) {
296 B2DEBUG(120,
"compare center " << center.
getID()
297 <<
" to " << candidates[icand].getID());
298 if (inList(candidates[icand], merged) || inList(candidates[icand], rejected)) {
299 B2DEBUG(120,
" " << candidates[icand].
getID() <<
" already in list");
302 bool reject = inList(center, rejected);
303 if (connected(center, candidates[icand])) {
304 if (m_onlyLocalMax && candidates[icand].getSLcount() < nSLmax) {
305 B2DEBUG(100,
" lower than highest SLcount, rejected");
306 rejected.push_back(candidates[icand]);
307 }
else if (m_onlyLocalMax && !reject && candidates[icand].getSLcount() > nSLmax) {
308 B2DEBUG(100,
" new highest SLcount, clearing list");
309 nSLmax = candidates[icand].getSLcount();
310 for (
unsigned imerged = 0; imerged < merged.size(); ++imerged) {
311 rejected.push_back(merged[imerged]);
314 merged.push_back(candidates[icand]);
315 }
else if (m_onlyLocalMax && candidates[icand].getSLcount() > center.
getSLcount()) {
316 B2DEBUG(100,
" connected to rejected cell, skip");
318 }
else if (m_onlyLocalMax && reject) {
319 B2DEBUG(100,
" connected to rejected cell, rejected");
320 rejected.push_back(candidates[icand]);
322 B2DEBUG(100,
" connected");
323 merged.push_back(candidates[icand]);
325 vector<CDCTriggerHoughCand> cpyCand = candidates;
326 cpyCand.erase(cpyCand.begin() + icand);
327 addNeighbors(candidates[icand], cpyCand, merged, rejected, nSLmax);
334 const vector<CDCTriggerHoughCand>& list)
const
336 for (
unsigned i = 0; i < list.size(); ++i) {
337 if (a == list[i])
return true;
346 double ax1 = a.getCoord().first.X();
347 double ax2 = a.getCoord().second.X();
348 double ay1 = a.getCoord().first.Y();
349 double ay2 = a.getCoord().second.Y();
350 double bx1 = b.getCoord().first.X();
351 double bx2 = b.getCoord().second.X();
352 double by1 = b.getCoord().first.Y();
353 double by2 = b.getCoord().second.Y();
355 bool direct = ((ax2 == bx1 && ay1 == by1) ||
356 (ax1 == bx2 && ay1 == by1) ||
357 (ax1 == bx1 && ay2 == by1) ||
358 (ax1 == bx1 && ay1 == by2) ||
359 (ax1 + 2. * M_PI == bx2 && ay1 == by1) ||
360 (ax2 == bx1 + 2. * M_PI && ay1 == by1));
362 bool diagRise = ((ax2 == bx1 && ay2 == by1) ||
363 (ax1 == bx2 && ay1 == by2) ||
364 (ax1 + 2. * M_PI == bx2 && ay1 == by2) ||
365 (ax2 == bx1 + 2. * M_PI && ay2 == by1));
366 bool diagFall = ((ax1 == bx2 && ay2 == by1) ||
367 (ax2 == bx1 && ay1 == by2) ||
368 (ax2 == bx1 + 2. * M_PI && ay1 == by2) ||
369 (ax1 + 2. * M_PI == bx2 && ay2 == by1));
370 if (m_connect == 4)
return direct;
371 else if (m_connect == 6)
return (direct || diagRise);
372 else if (m_connect == 8)
return (direct || diagRise || diagFall);
373 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
374 return (direct || diagRise);
381 CDCTriggerHoughETFModule::mergeIdList(std::vector<unsigned>& merged,
382 std::vector<unsigned>& a,
383 std::vector<unsigned>& b)
387 for (
auto it = a.begin(); it != a.end(); ++it) {
389 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
396 merged.push_back(*it);
400 for (
auto it = b.begin(); it != b.end(); ++it) {
402 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
409 merged.push_back(*it);
415 CDCTriggerHoughETFModule::findAllCrossingHits(std::vector<unsigned>& list,
416 double x1,
double x2,
417 double y1,
double y2,
420 double m, a, y1_h, y2_h;
421 for (
int iHit = 0; iHit < m_segmentHits.getEntries(); iHit++) {
422 unsigned short iSL = m_segmentHits[iHit]->getISuperLayer();
423 if (iSL % 2)
continue;
425 if (m_suppressClone && inputMap.find(iHit) == inputMap.end())
continue;
427 vector<double> phi = {0, 0, 0};
428 phi[0] = m_segmentHits[iHit]->getSegmentID() - TSoffset[iSL];
429 phi[1] = phi[0] + 0.5;
430 phi[2] = phi[0] - 0.5;
431 vector<double> r = {radius[iSL][0], radius[iSL][1], radius[iSL][1]};
432 for (
unsigned i = 0; i < 3; ++i) {
433 phi[i] *= 2. * M_PI / (TSoffset[iSL + 1] - TSoffset[iSL]);
434 m = cos(phi[i]) / r[i];
435 a = sin(phi[i]) / r[i];
437 y1_h = m * sin(x1 - 1e-10) - a * cos(x1 - 1e-10);
438 y2_h = m * sin(x2 + 1e-10) - a * cos(x2 + 1e-10);
440 if (y1_h > y2_h)
continue;
441 if (!((y1_h > y2 && y2_h > y2) || (y1_h < y1 && y2_h < y1))) {
442 list.push_back(iHit);
453 CDCTriggerHoughETFModule::selectHits(std::vector<unsigned>& list,
454 std::vector<unsigned>& selected,
455 std::vector<unsigned>& unselected)
457 std::vector<int> bestPerSL(5, -1);
459 for (
unsigned i = 0; i < list.size(); ++i) {
460 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
461 bool firstPriority = (m_segmentHits[list[i]]->getPriorityPosition() == 3);
462 if (bestPerSL[iax] < 0) {
465 unsigned itsBest = list[bestPerSL[iax]];
466 bool firstBest = (m_segmentHits[itsBest]->getPriorityPosition() == 3);
469 if ((firstPriority && !firstBest) ||
470 (firstPriority == firstBest &&
471 m_segmentHits[list[i]]->getSegmentID() > m_segmentHits[itsBest]->getSegmentID())) {
477 for (
unsigned i = 0; i < list.size(); ++i) {
478 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
479 if (
int(i) == bestPerSL[iax]) selected.push_back(list[i]);
480 else unselected.push_back(list[i]);
488 CDCTriggerHoughETFModule::patternClustering(
const cdcMap& inputMap)
490 bool foundTrack =
false;
491 std::vector<CDCTriggerSegmentHit*> associatedTSHits;
494 TMatrix plane2(m_nCellsPhi / 2, m_nCellsR / 2);
495 TMatrix planeIcand(m_nCellsPhi, m_nCellsR);
496 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
497 double x = (houghCand[icand].getCoord().first.X() +
498 houghCand[icand].getCoord().second.X()) / 2.;
499 unsigned ix = floor((x + M_PI) / 2. / M_PI * m_nCellsPhi);
500 double y = (houghCand[icand].getCoord().first.Y() +
501 houghCand[icand].getCoord().second.Y()) / 2.;
502 unsigned iy = floor((y + maxR - shiftR) / 2. / maxR * m_nCellsR);
503 plane2[ix / 2][iy / 2] += 1 << ((ix % 2) + 2 * (iy % 2));
504 planeIcand[ix][iy] = icand;
505 B2DEBUG(100,
"candidate " << icand <<
" at ix " << ix <<
" iy " << iy);
508 unsigned nX = m_nCellsPhi / 2;
509 unsigned nY = m_nCellsR / 2;
510 unsigned rX = m_clusterSizeX;
511 unsigned rY = m_clusterSizeY;
512 for (
unsigned ix = 0; ix < nX; ++ix) {
513 for (
unsigned iy = 0; iy < nY; ++iy) {
514 if (!plane2[ix][iy])
continue;
516 unsigned ileft = (ix - 1 + nX) % nX;
517 B2DEBUG(100,
"ix " << ix <<
" iy " << iy);
518 if (connectedLR(plane2[ileft][iy], plane2[ix][iy]) ||
519 (iy > 0 && connectedUD(plane2[ix][iy - 1], plane2[ix][iy])) ||
520 (iy > 0 && connectedDiag(plane2[ileft][iy - 1], plane2[ix][iy]))) {
521 B2DEBUG(100,
"skip connected square");
525 vector<unsigned> pattern(rX * rY, 0);
526 pattern[0] = plane2[ix][iy];
527 vector<TVector2> cellIds = {TVector2(2 * ix, 2 * iy)};
528 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
529 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
530 if (iy + iy2 >= nY)
continue;
531 unsigned ip = ix2 + rX * iy2;
532 unsigned iright = (ix + ix2 + nX) % nX;
533 ileft = (iright - 1 + nX) % nX;
534 B2DEBUG(100,
"ix2 " << ix2 <<
" ileft " << ileft <<
" iright " << iright);
537 connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2])) ||
540 connectedUD(plane2[iright][iy + iy2 - 1], plane2[iright][iy + iy2])) ||
541 (ix2 > 0 && iy2 > 0 &&
542 pattern[ip - rX - 1] &&
543 connectedDiag(plane2[ileft][iy + iy2 - 1], plane2[iright][iy + iy2]))) {
544 pattern[ip] = plane2[iright][iy + iy2];
545 B2DEBUG(100,
"connect cell " << iright <<
" " << iy + iy2);
546 cellIds.push_back(TVector2(2 * (ix + ix2), 2 * (iy + iy2)));
550 B2DEBUG(100,
"cluster starting at " << ix <<
" " << iy);
552 bool overflowRight =
false;
553 bool overflowTop =
false;
554 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
555 unsigned ip = rX - 1 + rX * iy2;
556 if (!pattern[ip])
continue;
557 unsigned iright = (ix + rX + nX) % nX;
558 ileft = (iright - 1 + nX) % nX;
559 if (connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2]) ||
560 ((iy + iy2 + 1 < nY) &&
561 connectedDiag(plane2[ileft][iy + iy2], plane2[iright][iy + iy2 + 1]))) {
562 setReturnValue(
false);
563 overflowRight =
true;
567 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
568 unsigned ip = ix2 + rX * (rY - 1);
569 if (!pattern[ip])
continue;
570 unsigned iright = (ix + ix2 + 1 + nX) % nX;
571 ileft = (iright - 1 + nX) % nX;
572 if (connectedUD(plane2[ileft][iy + rY - 1], plane2[ileft][iy + rY]) ||
573 connectedDiag(plane2[ileft][iy + rY - 1], plane2[iright][iy + rY])) {
574 setReturnValue(
false);
579 if (overflowRight && !overflowTop) {
580 B2DEBUG(100,
"cluster extends right of " << rX <<
" x " << rY <<
" area");
581 }
else if (overflowTop && !overflowRight) {
582 B2DEBUG(100,
"cluster extends above " << rX <<
" x " << rY <<
" area");
583 }
else if (overflowRight && overflowTop) {
584 B2DEBUG(100,
"cluster extends right and above " << rX <<
" x " << rY <<
" area");
587 unsigned topRight2 = topRightSquare(pattern);
588 unsigned topRight = topRightCorner(pattern[topRight2]);
589 unsigned bottomLeft = bottomLeftCorner(pattern[0]);
590 B2DEBUG(100,
"topRight2 " << topRight2 <<
" topRight " << topRight <<
" bottomLeft " << bottomLeft);
592 unsigned ixTR = 2 * (topRight2 % m_clusterSizeX) + (topRight % 2);
593 unsigned ixBL = bottomLeft % 2;
594 unsigned iyTR = 2 * (topRight2 / m_clusterSizeX) + (topRight / 2);
595 unsigned iyBL = bottomLeft / 2;
596 B2DEBUG(100,
"ixTR " << ixTR <<
" ixBL " << ixBL <<
" iyTR " << iyTR <<
" iyBL " << iyBL);
598 if (m_minCells > 1 && ixTR == ixBL && iyTR == iyBL) {
599 B2DEBUG(100,
"skipping cluster of size 1");
604 float centerX = 2 * ix + (ixTR + ixBL) / 2.;
605 if (centerX >= m_nCellsPhi) centerX -= m_nCellsPhi;
606 float centerY = 2 * iy + (iyTR + iyBL) / 2.;
607 B2DEBUG(100,
"center at cell (" << centerX <<
", " << centerY <<
")");
609 double x = -M_PI + (centerX + 0.5) * 2. * M_PI / m_nCellsPhi;
610 double y = -maxR + shiftR + (centerY + 0.5) * 2. * maxR / m_nCellsR;
611 B2DEBUG(100,
"center coordinates (" << x <<
", " << y <<
")");
613 vector <unsigned> idList = {};
614 if (m_hitRelationsFromCorners) {
615 unsigned icandTR = planeIcand[(ixTR + 2 * ix) % m_nCellsPhi][iyTR + 2 * iy];
616 unsigned icandBL = planeIcand[ixBL + 2 * ix][iyBL + 2 * iy];
617 vector<unsigned> candIdListTR = houghCand[icandTR].getIdList();
618 vector<unsigned> candIdListBL = houghCand[icandBL].getIdList();
619 mergeIdList(idList, candIdListTR, candIdListBL);
620 B2DEBUG(100,
"merge id lists from candidates " << icandTR <<
" and " << icandBL);
622 double dx = M_PI / m_nCellsPhi;
623 double dy = maxR / m_nCellsR;
624 double x1 = (round(centerX) == centerX) ? x - dx : x - 2 * dx;
625 double x2 = (round(centerX) == centerX) ? x + dx : x + 2 * dx;
626 double y1 = (round(centerY) == centerY) ? y - dy : y - 2 * dy;
627 double y2 = (round(centerY) == centerY) ? y + dy : y + 2 * dy;
628 findAllCrossingHits(idList, x1, x2, y1, y2, inputMap);
630 if (idList.size() == 0) {
631 setReturnValue(
false);
632 B2DEBUG(100,
"id list empty");
638 vector<unsigned> selectedList = {};
639 vector<unsigned> unselectedList = {};
640 selectHits(idList, selectedList, unselectedList);
642 associatedTSHits.clear();
643 for (
unsigned i = 0; i < selectedList.size(); ++i)
644 associatedTSHits.push_back(m_segmentHits[selectedList[i]]);
645 associatedTSHitsList.push_back(associatedTSHits);
650 m_tracks.appendNew(x, 2. * y, 0.);
652 for (
unsigned i = 0; i < selectedList.size(); ++i) {
653 unsigned its = selectedList[i];
654 track->addRelationTo(m_segmentHits[its]);
657 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
658 unsigned its = unselectedList[i];
659 track->addRelationTo(m_segmentHits[its], -1.);
663 m_clusters.appendNew(2 * ix, 2 * (ix + m_clusterSizeX) - 1,
664 2 * iy, 2 * (iy + m_clusterSizeY) - 1,
666 track->addRelationTo(cluster);
677 CDCTriggerHoughETFModule::connectedLR(
unsigned patternL,
unsigned patternR)
682 bool connectDirect = (((patternL >> 3) & 1) && ((patternR >> 2) & 1)) ||
683 (((patternL >> 1) & 1) && ((patternR >> 0) & 1));
687 bool connectRise = ((patternL >> 1) & 1) && ((patternR >> 2) & 1);
691 bool connectFall = ((patternL >> 3) & 1) && ((patternR >> 0) & 1);
693 if (m_connect == 4)
return connectDirect;
694 else if (m_connect == 6)
return (connectDirect || connectRise);
695 else if (m_connect == 8)
return (connectDirect || connectRise || connectFall);
696 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
697 return (connectDirect || connectRise);
701 CDCTriggerHoughETFModule::connectedUD(
unsigned patternD,
unsigned patternU)
709 bool connectDirect = (((patternU >> 0) & 1) && ((patternD >> 2) & 1)) ||
710 (((patternU >> 1) & 1) && ((patternD >> 3) & 1));
717 bool connectRise = ((patternU >> 1) & 1) && ((patternD >> 2) & 1);
724 bool connectFall = ((patternU >> 0) & 1) && ((patternD >> 3) & 1);
726 if (m_connect == 4)
return connectDirect;
727 else if (m_connect == 6)
return (connectDirect || connectRise);
728 else if (m_connect == 8)
return (connectDirect || connectRise || connectFall);
729 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
730 return (connectDirect || connectRise);
734 CDCTriggerHoughETFModule::connectedDiag(
unsigned patternLD,
unsigned patternRU)
736 if (m_connect == 4)
return false;
743 return (((patternRU >> 0) & 1) && ((patternLD >> 3) & 1));
747 CDCTriggerHoughETFModule::topRightSquare(vector<unsigned>& pattern)
750 for (
unsigned index = pattern.size() - 1; index > 0; --index) {
751 if (!pattern[index])
continue;
753 unsigned ix = index % m_clusterSizeX;
754 unsigned iy = index / m_clusterSizeX;
755 if (ix < m_clusterSizeX - 1 && iy > 0) {
757 for (
unsigned index2 = index - 1; index2 > 0; --index2) {
758 if (!pattern[index2])
continue;
759 unsigned ix2 = index2 % m_clusterSizeX;
760 unsigned iy2 = index2 / m_clusterSizeX;
761 if (iy2 < iy && ix2 > ix) {
767 setReturnValue(
false);
768 B2DEBUG(100,
"topRightSquare not unique");
777 CDCTriggerHoughETFModule::topRightCorner(
unsigned pattern)
782 if ((pattern >> 3) & 1)
return 3;
783 if ((pattern >> 1) & 1) {
784 if ((pattern >> 2) & 1) {
785 setReturnValue(
false);
786 B2DEBUG(100,
"topRightCorner not unique");
790 if ((pattern >> 2) & 1)
return 2;
795 CDCTriggerHoughETFModule::bottomLeftCorner(
unsigned pattern)
800 if (pattern & 1)
return 0;
801 if ((pattern >> 2) & 1) {
802 if ((pattern >> 1) & 1) {
803 setReturnValue(
false);
804 B2DEBUG(100,
"bottomLeftCorner not unique");
808 if ((pattern >> 1) & 1)
return 1;
813 CDCTriggerHoughETFModule::calcEventTiming()
815 std::vector<int> ftlists;
816 for (
long unsigned int iTrack = 0; iTrack < associatedTSHitsList.size(); iTrack++) {
817 for (
long unsigned int iHit = 0; iHit < associatedTSHitsList[iTrack].size(); iHit++) {
818 short fts = (!m_usePriorityTiming) ? associatedTSHitsList[iTrack][iHit]->fastestTime()
819 : associatedTSHitsList[iTrack][iHit]->priorityTime();
820 ftlists.push_back(fts);
823 if (m_t0CalcMethod == 0) {
824 std::sort(ftlists.begin(), ftlists.end());
825 return ftlists[m_arrivalOrder];
826 }
else if (m_t0CalcMethod == 1) {
827 return median(ftlists);
829 return medianInTimeWindow(ftlists);
834 CDCTriggerHoughETFModule::median(std::vector<int> v)
838 copy(v.begin(), v.end(), back_inserter(_v));
839 std::sort(_v.begin(), _v.end());
841 return _v[(size - 1) / 2];
843 return (_v[(size / 2) - 1] + _v[size / 2]) / 2;
848 CDCTriggerHoughETFModule::medianInTimeWindow(std::vector<int> v)
851 int tstart = med - m_timeWindowStart;
852 int tend = med - m_timeWindowEnd;
854 std::vector<int> _inWindow;
856 for (
auto& t : v)
if (t > tstart && t <= tend) _inWindow.push_back(t);
857 if (_inWindow.size() == 0) {
860 return median(_inWindow);