9 #include <trg/cdc/modules/houghETF/CDCTriggerHoughETFModule.h>
11 #include <framework/logging/Logger.h>
15 #include <root/TMatrix.h>
23 #define CDC_SUPER_LAYERS 9
24 #define CDC_ETF_SECTOR 64
31 CDCTriggerHoughETFModule::countSL(
bool* layer)
33 if (m_requireSL0 && !layer[0])
return 0;
34 unsigned short lcnt = 0;
35 for (
int i = 0; i < CDC_SUPER_LAYERS; ++i) {
36 if (layer[i] ==
true) ++lcnt;
42 CDCTriggerHoughETFModule::shortTrack(
bool* layer)
44 unsigned short lcnt = 0;
47 for (
int i = 0; i < CDC_SUPER_LAYERS; i += 2) {
48 if (layer[i] ==
true) ++lcnt;
51 return (lcnt >= m_minHitsShort);
64 CDCTriggerHoughETFModule::fastInterceptFinder(
cdcMap& hits,
65 double x1_s,
double x2_s,
66 double y1_s,
double y2_s,
68 unsigned ix_s,
unsigned iy_s)
71 for (
unsigned i = 0; i < iterations; ++i) indent +=
" ";
72 B2DEBUG(150, indent <<
"intercept finder iteration " << iterations
73 <<
" x1 " << x1_s * 180 / M_PI <<
" x2 " << x2_s * 180 / M_PI
74 <<
" y1 " << y1_s <<
" y2 " << y2_s
75 <<
" ix " << ix_s <<
" iy " << iy_s);
84 vector<unsigned> idx_list;
87 double x1_d, x2_d, y1_d, y2_d;
92 unitx = ((x2_s - x1_s) / 2.0);
93 unity = ((y2_s - y1_s) / 2.0);
96 for (i = 0; i < 2 ; ++i) {
98 for (j = 0; j < 2; ++j) {
99 x1_d = x1_s + i * unitx;
100 x2_d = x1_s + (i + 1) * unitx;
101 y1_d = y1_s + j * unity;
102 y2_d = y1_s + (j + 1) * unity;
108 if (x2_d <= -M_PI || x1_d >= M_PI || y2_d <= -maxR + shiftR || y1_d >= maxR + shiftR) {
109 B2DEBUG(150, indent <<
"skip Hough cell outside of plane limits");
115 if (iterations != maxIterations && unitx > M_PI / 2.) {
116 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
121 bool layerHit[CDC_SUPER_LAYERS] = {
false};
122 for (
auto it = hits.begin(); it != hits.end(); ++it) {
129 y1 = m * sin(x1_d - 1e-10) - a * cos(x1_d - 1e-10);
130 y2 = m * sin(x2_d + 1e-10) - a * cos(x2_d + 1e-10);
132 if (iterations == maxIterations && y1 > y2)
continue;
133 if (!((y1 > y2_d && y2 > y2_d) || (y1 < y1_d && y2 < y1_d))) {
134 if (iterations == maxIterations) {
135 idx_list.push_back(iHit);
137 layerHit[iSL] =
true;
140 unsigned short nSL = countSL(layerHit);
141 B2DEBUG(150, indent <<
"i " << i <<
" j " << j
142 <<
" layerHit " <<
int(layerHit[0]) <<
int(layerHit[2])
143 <<
int(layerHit[4]) <<
int(layerHit[6]) <<
int(layerHit[8])
145 if (nSL >= m_minHits || shortTrack(layerHit)) {
146 if (iterations != maxIterations) {
147 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
149 TVector2 v1(x1_d, y1_d);
150 TVector2 v2(x2_d, y2_d);
152 nSL, houghCand.size()));
153 if (m_storePlane > 0) {
154 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
157 }
else if (m_storePlane > 1) {
160 for (
unsigned min = m_minHits - 1; min > 0; --min) {
162 if (iterations != maxIterations) {
163 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
165 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
181 CDCTriggerHoughETFModule::connectedRegions()
183 vector<vector<CDCTriggerHoughCand>> regions;
184 vector<CDCTriggerHoughCand> cpyCand = houghCand;
187 B2DEBUG(50,
"houghCand number " << cpyCand.size());
188 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
190 B2DEBUG(100, houghCand[icand].
getID()
191 <<
" nSL " << houghCand[icand].getSLcount()
192 <<
" x1 " << coord.first.X() <<
" x2 " << coord.second.X()
193 <<
" y1 " << coord.first.Y() <<
" y2 " << coord.second.Y());
197 while (cpyCand.size() > 0) {
198 B2DEBUG(100,
"make new region");
199 vector<CDCTriggerHoughCand> region;
200 vector<CDCTriggerHoughCand> rejected;
202 cpyCand.erase(cpyCand.begin());
203 region.push_back(start);
204 addNeighbors(start, cpyCand, region, rejected, start.getSLcount());
205 regions.push_back(region);
206 for (
auto cand = cpyCand.begin(); cand != cpyCand.end();) {
207 if (inList(*cand, region) || inList(*cand, rejected))
215 for (
unsigned ir = 0; ir < regions.size(); ++ir) {
216 B2DEBUG(50,
"region " << ir <<
" (" << regions[ir].size() <<
" cells).");
218 if (regions[ir].size() < m_minCells) {
219 B2DEBUG(50,
"Skipping region with " << regions[ir].size() <<
" cells.");
222 double xfirst = regions[ir][0].getCoord().first.X();
226 vector<unsigned> mergedList;
227 int xmin = m_nCellsPhi;
229 int ymin = m_nCellsR;
231 vector<TVector2> cellIds = {};
232 for (
unsigned ir2 = 0; ir2 < regions[ir].size(); ++ir2) {
234 B2DEBUG(100,
" " << regions[ir][ir2].
getID()
235 <<
" nSL " << regions[ir][ir2].getSLcount()
236 <<
" x1 " << hc.first.X() <<
" x2 " << hc.second.X()
237 <<
" y1 " << hc.first.Y() <<
" y2 " << hc.second.Y());
238 int ix = floor((hc.first.X() + M_PI) / 2. / M_PI * m_nCellsPhi + 0.5);
239 int iy = floor((hc.first.Y() + maxR - shiftR) / 2. / maxR * m_nCellsR + 0.5);
240 x += (hc.first.X() + hc.second.X());
241 if (xfirst - hc.first.X() > M_PI) {
244 }
else if (hc.first.X() - xfirst > M_PI) {
248 y += (hc.first.Y() + hc.second.Y());
250 vector<unsigned> idList = regions[ir][ir2].getIdList();
251 mergeIdList(mergedList, mergedList, idList);
252 xmin = min(xmin, ix);
253 xmax = max(xmax, ix);
254 ymin = min(ymin, iy);
255 ymax = max(ymax, iy);
256 cellIds.push_back(TVector2(ix, iy));
264 B2DEBUG(50,
"x " << x <<
" y " << y);
267 vector<unsigned> selectedList = {};
268 vector<unsigned> unselectedList = {};
269 selectHits(mergedList, selectedList, unselectedList);
273 m_tracks.appendNew(x, 2. * y, 0.);
275 for (
unsigned i = 0; i < selectedList.size(); ++i) {
276 unsigned its = selectedList[i];
277 if (m_storeTracks) track->addRelationTo(m_segmentHits[its]);
280 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
281 unsigned its = unselectedList[i];
282 if (m_storeTracks) track->addRelationTo(m_segmentHits[its], -1.);
286 m_clusters.appendNew(xmin, xmax, ymin, ymax, cellIds);
287 if (m_storeTracks) track->addRelationTo(cluster);
293 const vector<CDCTriggerHoughCand>& candidates,
294 vector<CDCTriggerHoughCand>& merged,
295 vector<CDCTriggerHoughCand>& rejected,
296 unsigned short nSLmax)
const
298 for (
unsigned icand = 0; icand < candidates.size(); ++icand) {
299 B2DEBUG(120,
"compare center " << center.
getID()
300 <<
" to " << candidates[icand].getID());
301 if (inList(candidates[icand], merged) || inList(candidates[icand], rejected)) {
302 B2DEBUG(120,
" " << candidates[icand].
getID() <<
" already in list");
305 bool reject = inList(center, rejected);
306 if (connected(center, candidates[icand])) {
307 if (m_onlyLocalMax && candidates[icand].getSLcount() < nSLmax) {
308 B2DEBUG(100,
" lower than highest SLcount, rejected");
309 rejected.push_back(candidates[icand]);
310 }
else if (m_onlyLocalMax && !reject && candidates[icand].getSLcount() > nSLmax) {
311 B2DEBUG(100,
" new highest SLcount, clearing list");
312 nSLmax = candidates[icand].getSLcount();
313 for (
unsigned imerged = 0; imerged < merged.size(); ++imerged) {
314 rejected.push_back(merged[imerged]);
317 merged.push_back(candidates[icand]);
318 }
else if (m_onlyLocalMax && candidates[icand].getSLcount() > center.
getSLcount()) {
319 B2DEBUG(100,
" connected to rejected cell, skip");
321 }
else if (m_onlyLocalMax && reject) {
322 B2DEBUG(100,
" connected to rejected cell, rejected");
323 rejected.push_back(candidates[icand]);
325 B2DEBUG(100,
" connected");
326 merged.push_back(candidates[icand]);
328 vector<CDCTriggerHoughCand> cpyCand = candidates;
329 cpyCand.erase(cpyCand.begin() + icand);
330 addNeighbors(candidates[icand], cpyCand, merged, rejected, nSLmax);
337 const vector<CDCTriggerHoughCand>& list)
const
339 for (
unsigned i = 0; i < list.size(); ++i) {
340 if (a == list[i])
return true;
349 double ax1 = a.getCoord().first.X();
350 double ax2 = a.getCoord().second.X();
351 double ay1 = a.getCoord().first.Y();
352 double ay2 = a.getCoord().second.Y();
353 double bx1 = b.getCoord().first.X();
354 double bx2 = b.getCoord().second.X();
355 double by1 = b.getCoord().first.Y();
356 double by2 = b.getCoord().second.Y();
358 bool direct = ((ax2 == bx1 && ay1 == by1) ||
359 (ax1 == bx2 && ay1 == by1) ||
360 (ax1 == bx1 && ay2 == by1) ||
361 (ax1 == bx1 && ay1 == by2) ||
362 (ax1 + 2. * M_PI == bx2 && ay1 == by1) ||
363 (ax2 == bx1 + 2. * M_PI && ay1 == by1));
365 bool diagRise = ((ax2 == bx1 && ay2 == by1) ||
366 (ax1 == bx2 && ay1 == by2) ||
367 (ax1 + 2. * M_PI == bx2 && ay1 == by2) ||
368 (ax2 == bx1 + 2. * M_PI && ay2 == by1));
369 bool diagFall = ((ax1 == bx2 && ay2 == by1) ||
370 (ax2 == bx1 && ay1 == by2) ||
371 (ax2 == bx1 + 2. * M_PI && ay1 == by2) ||
372 (ax1 + 2. * M_PI == bx2 && ay2 == by1));
373 if (m_connect == 4)
return direct;
374 else if (m_connect == 6)
return (direct || diagRise);
375 else if (m_connect == 8)
return (direct || diagRise || diagFall);
376 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
377 return (direct || diagRise);
384 CDCTriggerHoughETFModule::mergeIdList(std::vector<unsigned>& merged,
385 std::vector<unsigned>& a,
386 std::vector<unsigned>& b)
390 for (
auto it = a.begin(); it != a.end(); ++it) {
392 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
399 merged.push_back(*it);
403 for (
auto it = b.begin(); it != b.end(); ++it) {
405 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
412 merged.push_back(*it);
418 CDCTriggerHoughETFModule::findAllCrossingHits(std::vector<unsigned>& list,
419 double x1,
double x2,
420 double y1,
double y2,
423 double m, a, y1_h, y2_h;
424 for (
int iHit = 0; iHit < m_segmentHits.getEntries(); iHit++) {
425 unsigned short iSL = m_segmentHits[iHit]->getISuperLayer();
426 if (iSL % 2)
continue;
428 if (m_suppressClone && inputMap.find(iHit) == inputMap.end())
continue;
430 vector<double> phi = {0, 0, 0};
431 phi[0] = m_segmentHits[iHit]->getSegmentID() - TSoffset[iSL];
432 phi[1] = phi[0] + 0.5;
433 phi[2] = phi[0] - 0.5;
434 vector<double> r = {radius[iSL][0], radius[iSL][1], radius[iSL][1]};
435 for (
unsigned i = 0; i < 3; ++i) {
436 phi[i] *= 2. * M_PI / (TSoffset[iSL + 1] - TSoffset[iSL]);
437 m = cos(phi[i]) / r[i];
438 a = sin(phi[i]) / r[i];
440 y1_h = m * sin(x1 - 1e-10) - a * cos(x1 - 1e-10);
441 y2_h = m * sin(x2 + 1e-10) - a * cos(x2 + 1e-10);
443 if (y1_h > y2_h)
continue;
444 if (!((y1_h > y2 && y2_h > y2) || (y1_h < y1 && y2_h < y1))) {
445 list.push_back(iHit);
456 CDCTriggerHoughETFModule::selectHits(std::vector<unsigned>& list,
457 std::vector<unsigned>& selected,
458 std::vector<unsigned>& unselected)
460 std::vector<int> bestPerSL(5, -1);
461 for (
unsigned i = 0; i < list.size(); ++i) {
462 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
463 bool firstPriority = (m_segmentHits[list[i]]->getPriorityPosition() == 3);
464 if (bestPerSL[iax] < 0) {
467 unsigned itsBest = list[bestPerSL[iax]];
468 bool firstBest = (m_segmentHits[itsBest]->getPriorityPosition() == 3);
471 if ((firstPriority && !firstBest) ||
472 (firstPriority == firstBest &&
473 m_segmentHits[list[i]]->getSegmentID() > m_segmentHits[itsBest]->getSegmentID())) {
479 for (
unsigned i = 0; i < list.size(); ++i) {
480 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
481 if (
int(i) == bestPerSL[iax]) selected.push_back(list[i]);
482 else unselected.push_back(list[i]);
490 CDCTriggerHoughETFModule::patternClustering(
const cdcMap& inputMap)
492 bool foundTrack =
false;
493 std::vector<CDCTriggerSegmentHit*> associatedTSHits;
496 TMatrix plane2(m_nCellsPhi / 2, m_nCellsR / 2);
497 TMatrix planeIcand(m_nCellsPhi, m_nCellsR);
498 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
499 double x = (houghCand[icand].getCoord().first.X() +
500 houghCand[icand].getCoord().second.X()) / 2.;
501 unsigned ix = floor((x + M_PI) / 2. / M_PI * m_nCellsPhi);
502 double y = (houghCand[icand].getCoord().first.Y() +
503 houghCand[icand].getCoord().second.Y()) / 2.;
504 unsigned iy = floor((y + maxR - shiftR) / 2. / maxR * m_nCellsR);
505 plane2[ix / 2][iy / 2] += 1 << ((ix % 2) + 2 * (iy % 2));
506 planeIcand[ix][iy] = icand;
507 B2DEBUG(100,
"candidate " << icand <<
" at ix " << ix <<
" iy " << iy);
510 unsigned nX = m_nCellsPhi / 2;
511 unsigned nY = m_nCellsR / 2;
512 unsigned rX = m_clusterSizeX;
513 unsigned rY = m_clusterSizeY;
514 for (
unsigned ix = 0; ix < nX; ++ix) {
515 for (
unsigned iy = 0; iy < nY; ++iy) {
516 if (!plane2[ix][iy])
continue;
518 unsigned ileft = (ix - 1 + nX) % nX;
519 B2DEBUG(100,
"ix " << ix <<
" iy " << iy);
520 if (connectedLR(plane2[ileft][iy], plane2[ix][iy]) ||
521 (iy > 0 && connectedUD(plane2[ix][iy - 1], plane2[ix][iy])) ||
522 (iy > 0 && connectedDiag(plane2[ileft][iy - 1], plane2[ix][iy]))) {
523 B2DEBUG(100,
"skip connected square");
527 vector<unsigned> pattern(rX * rY, 0);
528 pattern[0] = plane2[ix][iy];
529 vector<TVector2> cellIds = {TVector2(2 * ix, 2 * iy)};
530 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
531 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
532 if (iy + iy2 >= nY)
continue;
533 unsigned ip = ix2 + rX * iy2;
534 unsigned iright = (ix + ix2 + nX) % nX;
535 ileft = (iright - 1 + nX) % nX;
536 B2DEBUG(100,
"ix2 " << ix2 <<
" ileft " << ileft <<
" iright " << iright);
539 connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2])) ||
542 connectedUD(plane2[iright][iy + iy2 - 1], plane2[iright][iy + iy2])) ||
543 (ix2 > 0 && iy2 > 0 &&
544 pattern[ip - rX - 1] &&
545 connectedDiag(plane2[ileft][iy + iy2 - 1], plane2[iright][iy + iy2]))) {
546 pattern[ip] = plane2[iright][iy + iy2];
547 B2DEBUG(100,
"connect cell " << iright <<
" " << iy + iy2);
548 cellIds.push_back(TVector2(2 * (ix + ix2), 2 * (iy + iy2)));
552 B2DEBUG(100,
"cluster starting at " << ix <<
" " << iy);
554 bool overflowRight =
false;
555 bool overflowTop =
false;
556 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
557 unsigned ip = rX - 1 + rX * iy2;
558 if (!pattern[ip])
continue;
559 unsigned iright = (ix + rX + nX) % nX;
560 ileft = (iright - 1 + nX) % nX;
561 if (connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2]) ||
562 ((iy + iy2 + 1 < nY) &&
563 connectedDiag(plane2[ileft][iy + iy2], plane2[iright][iy + iy2 + 1]))) {
564 setReturnValue(
false);
565 overflowRight =
true;
569 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
570 unsigned ip = ix2 + rX * (rY - 1);
571 if (!pattern[ip])
continue;
572 unsigned iright = (ix + ix2 + 1 + nX) % nX;
573 ileft = (iright - 1 + nX) % nX;
574 if (connectedUD(plane2[ileft][iy + rY - 1], plane2[ileft][iy + rY]) ||
575 connectedDiag(plane2[ileft][iy + rY - 1], plane2[iright][iy + rY])) {
576 setReturnValue(
false);
581 if (overflowRight && !overflowTop) {
582 B2DEBUG(100,
"cluster extends right of " << rX <<
" x " << rY <<
" area");
583 }
else if (overflowTop && !overflowRight) {
584 B2DEBUG(100,
"cluster extends above " << rX <<
" x " << rY <<
" area");
585 }
else if (overflowRight && overflowTop) {
586 B2DEBUG(100,
"cluster extends right and above " << rX <<
" x " << rY <<
" area");
589 unsigned topRight2 = topRightSquare(pattern);
590 unsigned topRight = topRightCorner(pattern[topRight2]);
591 unsigned bottomLeft = bottomLeftCorner(pattern[0]);
592 B2DEBUG(100,
"topRight2 " << topRight2 <<
" topRight " << topRight <<
" bottomLeft " << bottomLeft);
594 unsigned ixTR = 2 * (topRight2 % m_clusterSizeX) + (topRight % 2);
595 unsigned ixBL = bottomLeft % 2;
596 unsigned iyTR = 2 * (topRight2 / m_clusterSizeX) + (topRight / 2);
597 unsigned iyBL = bottomLeft / 2;
598 B2DEBUG(100,
"ixTR " << ixTR <<
" ixBL " << ixBL <<
" iyTR " << iyTR <<
" iyBL " << iyBL);
600 if (m_minCells > 1 && ixTR == ixBL && iyTR == iyBL) {
601 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 if (m_useHighPassTimingList) {
644 for (
unsigned i = 0; i < selectedList.size(); ++i)
645 associatedTSHits.push_back(m_segmentHits[selectedList[i]]);
646 associatedTSHitsList.push_back(associatedTSHits);
648 for (
unsigned i = 0; i < idList.size(); ++i)
649 associatedTSHits.push_back(m_segmentHits[idList[i]]);
650 associatedTSHitsList.push_back(associatedTSHits);
656 m_tracks.appendNew(x, 2. * y, 0.);
657 if (m_useHighPassTimingList) {
659 for (
unsigned i = 0; i < selectedList.size(); ++i) {
660 unsigned its = selectedList[i];
661 track->addRelationTo(m_segmentHits[its]);
664 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
665 unsigned its = unselectedList[i];
666 track->addRelationTo(m_segmentHits[its], -1.);
669 for (
unsigned i = 0; i < idList.size(); ++i) {
670 unsigned its = idList[i];
671 track->addRelationTo(m_segmentHits[its], -1.);
676 m_clusters.appendNew(2 * ix, 2 * (ix + m_clusterSizeX) - 1,
677 2 * iy, 2 * (iy + m_clusterSizeY) - 1,
679 track->addRelationTo(cluster);
690 CDCTriggerHoughETFModule::connectedLR(
unsigned patternL,
unsigned patternR)
695 bool connectDirect = (((patternL >> 3) & 1) && ((patternR >> 2) & 1)) ||
696 (((patternL >> 1) & 1) && ((patternR >> 0) & 1));
700 bool connectRise = ((patternL >> 1) & 1) && ((patternR >> 2) & 1);
704 bool connectFall = ((patternL >> 3) & 1) && ((patternR >> 0) & 1);
706 if (m_connect == 4)
return connectDirect;
707 else if (m_connect == 6)
return (connectDirect || connectRise);
708 else if (m_connect == 8)
return (connectDirect || connectRise || connectFall);
709 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
710 return (connectDirect || connectRise);
714 CDCTriggerHoughETFModule::connectedUD(
unsigned patternD,
unsigned patternU)
722 bool connectDirect = (((patternU >> 0) & 1) && ((patternD >> 2) & 1)) ||
723 (((patternU >> 1) & 1) && ((patternD >> 3) & 1));
730 bool connectRise = ((patternU >> 1) & 1) && ((patternD >> 2) & 1);
737 bool connectFall = ((patternU >> 0) & 1) && ((patternD >> 3) & 1);
739 if (m_connect == 4)
return connectDirect;
740 else if (m_connect == 6)
return (connectDirect || connectRise);
741 else if (m_connect == 8)
return (connectDirect || connectRise || connectFall);
742 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
743 return (connectDirect || connectRise);
747 CDCTriggerHoughETFModule::connectedDiag(
unsigned patternLD,
unsigned patternRU)
749 if (m_connect == 4)
return false;
756 return (((patternRU >> 0) & 1) && ((patternLD >> 3) & 1));
760 CDCTriggerHoughETFModule::topRightSquare(vector<unsigned>& pattern)
763 for (
unsigned index = pattern.size() - 1; index > 0; --index) {
764 if (!pattern[index])
continue;
766 unsigned ix = index % m_clusterSizeX;
767 unsigned iy = index / m_clusterSizeX;
768 if (ix < m_clusterSizeX - 1 && iy > 0) {
770 for (
unsigned index2 = index - 1; index2 > 0; --index2) {
771 if (!pattern[index2])
continue;
772 unsigned ix2 = index2 % m_clusterSizeX;
773 unsigned iy2 = index2 / m_clusterSizeX;
774 if (iy2 < iy && ix2 > ix) {
780 setReturnValue(
false);
781 B2DEBUG(100,
"topRightSquare not unique");
790 CDCTriggerHoughETFModule::topRightCorner(
unsigned pattern)
795 if ((pattern >> 3) & 1)
return 3;
796 if ((pattern >> 1) & 1) {
797 if ((pattern >> 2) & 1) {
798 setReturnValue(
false);
799 B2DEBUG(100,
"topRightCorner not unique");
803 if ((pattern >> 2) & 1)
return 2;
808 CDCTriggerHoughETFModule::bottomLeftCorner(
unsigned pattern)
813 if (pattern & 1)
return 0;
814 if ((pattern >> 2) & 1) {
815 if ((pattern >> 1) & 1) {
816 setReturnValue(
false);
817 B2DEBUG(100,
"bottomLeftCorner not unique");
821 if ((pattern >> 1) & 1)
return 1;
825 CDCTriggerHoughETFModule::highPassTimingList()
827 std::vector<int> ftlists;
829 for (
long unsigned int iTrack = 0; iTrack < associatedTSHitsList.size(); iTrack++) {
830 for (
long unsigned int iHit = 0; iHit < associatedTSHitsList[iTrack].size(); iHit++) {
831 short ft = (!m_usePriorityTiming) ? associatedTSHitsList[iTrack][iHit]->fastestTime()
832 : associatedTSHitsList[iTrack][iHit]->priorityTime();
833 ftlists.push_back(ft * 2);
840 CDCTriggerHoughETFModule::getSector(
int id,
int sl)
842 unsigned int localid =
id - TSoffset[sl];
843 unsigned int base = NTS[sl] / NSEC[sl];
844 return localid / base + NSecOffset[sl];
848 CDCTriggerHoughETFModule::sectorTimingList()
850 std::vector<int> ftlists;
851 std::array<std::vector<std::pair<int, int>>, CDC_ETF_SECTOR> arr_sector;
854 for (
long unsigned int iTrack = 0; iTrack < associatedTSHitsList.size(); iTrack++) {
855 for (
long unsigned int iHit = 0; iHit < associatedTSHitsList[iTrack].size(); iHit++) {
856 int sl = associatedTSHitsList[iTrack][iHit]->getISuperLayer();
857 int id = associatedTSHitsList[iTrack][iHit]->getSegmentID();
858 int pp = associatedTSHitsList[iTrack][iHit]->getPriorityPosition();
859 int ft = associatedTSHitsList[iTrack][iHit]->fastestTime() * 2;
861 arr_sector [getSector(
id, sl)].push_back(make_pair(ft, pp));
866 for (
int sec = 0; sec < CDC_ETF_SECTOR; sec++) {
867 if (!arr_sector[sec].size())
continue;
870 for (
auto& ift : arr_sector[sec]) {
871 if ((minft > ift.first) && (pp <= ift.second)) {
876 ftlists.push_back(minft);
883 CDCTriggerHoughETFModule::calcEventTiming()
885 std::vector<int> ftlists;
886 if (m_useHighPassTimingList) {
887 ftlists = highPassTimingList();
889 ftlists = sectorTimingList();
892 if (m_t0CalcMethod == 0) {
893 std::sort(ftlists.begin(), ftlists.end());
894 return ftlists[m_arrivalOrder];
895 }
else if (m_t0CalcMethod == 1) {
896 return median(ftlists);
898 return medianInTimeWindow(ftlists);
903 CDCTriggerHoughETFModule::median(std::vector<int> v)
907 copy(v.begin(), v.end(), back_inserter(_v));
908 std::sort(_v.begin(), _v.end());
910 return _v[(size - 1) / 2];
912 return (_v[(size / 2) - 1] + _v[size / 2]) / 2;
917 CDCTriggerHoughETFModule::medianInTimeWindow(std::vector<int> v)
920 int tbegin = med - abs(m_timeWindowBegin);
921 int tend = med + abs(m_timeWindowEnd);
923 std::vector<int> _inWindow;
925 for (
auto& t : v)
if (t > tbegin && t < tend) _inWindow.push_back(t);
927 if (_inWindow.size()) {
928 return median(_inWindow);
unsigned getID() const
Get candidate number.
unsigned short getSLcount() const
Get super layer count.
Cluster created by the Hough finder of the CDC trigger.
Track created by the CDC trigger.
int getID(const std::vector< double > &breaks, double t)
get id of the time point t
std::map< int, cdcPair > cdcMap
Map of <counter, cdcPair>, for hits with indices.
std::pair< unsigned short, TVector2 > cdcPair
Pair of <iSuperLayer, (x, y)>, for hits in conformal space.
std::pair< TVector2, TVector2 > coord2dPair
Hough Tuples.
Abstract base class for different kinds of events.