9 #include <trg/cdc/modules/houghtracking/CDCTrigger2DFinderModule.h>
11 #include <framework/logging/Logger.h>
15 #include <root/TMatrix.h>
18 #define CDC_SUPER_LAYERS 9
24 CDCTrigger2DFinderModule::countSL(
bool* layer)
26 if (m_requireSL0 && !layer[0])
return 0;
27 unsigned short lcnt = 0;
28 for (
int i = 0; i < CDC_SUPER_LAYERS; ++i) {
29 if (layer[i] ==
true) ++lcnt;
35 CDCTrigger2DFinderModule::shortTrack(
bool* layer)
37 unsigned short lcnt = 0;
40 for (
int i = 0; i < CDC_SUPER_LAYERS; i += 2) {
41 if (layer[i] ==
true) ++lcnt;
44 return (lcnt >= m_minHitsShort);
57 CDCTrigger2DFinderModule::fastInterceptFinder(
cdcMap& hits,
58 double x1_s,
double x2_s,
59 double y1_s,
double y2_s,
61 unsigned ix_s,
unsigned iy_s)
64 for (
unsigned i = 0; i < iterations; ++i) indent +=
" ";
65 B2DEBUG(150, indent <<
"intercept finder iteration " << iterations
66 <<
" x1 " << x1_s * 180 / M_PI <<
" x2 " << x2_s * 180 / M_PI
67 <<
" y1 " << y1_s <<
" y2 " << y2_s
68 <<
" ix " << ix_s <<
" iy " << iy_s);
77 vector<unsigned> idx_list;
80 double x1_d, x2_d, y1_d, y2_d;
85 unitx = ((x2_s - x1_s) / 2.0);
86 unity = ((y2_s - y1_s) / 2.0);
89 for (i = 0; i < 2 ; ++i) {
91 for (j = 0; j < 2; ++j) {
92 x1_d = x1_s + i * unitx;
93 x2_d = x1_s + (i + 1) * unitx;
94 y1_d = y1_s + j * unity;
95 y2_d = y1_s + (j + 1) * unity;
101 if (x2_d <= -M_PI || x1_d >= M_PI || y2_d <= -maxR + shiftR || y1_d >= maxR + shiftR) {
102 B2DEBUG(150, indent <<
"skip Hough cell outside of plane limits");
108 if (iterations != maxIterations && unitx > M_PI / 2.) {
109 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
114 bool layerHit[CDC_SUPER_LAYERS] = {
false};
115 for (
auto it = hits.begin(); it != hits.end(); ++it) {
122 y1 = m * sin(x1_d - 1e-10) - a * cos(x1_d - 1e-10);
123 y2 = m * sin(x2_d + 1e-10) - a * cos(x2_d + 1e-10);
125 if (iterations == maxIterations && y1 > y2)
continue;
126 if (!((y1 > y2_d && y2 > y2_d) || (y1 < y1_d && y2 < y1_d))) {
127 if (iterations == maxIterations) {
128 idx_list.push_back(iHit);
130 layerHit[iSL] =
true;
133 unsigned short nSL = countSL(layerHit);
134 B2DEBUG(150, indent <<
"i " << i <<
" j " << j
135 <<
" layerHit " <<
int(layerHit[0]) <<
int(layerHit[2])
136 <<
int(layerHit[4]) <<
int(layerHit[6]) <<
int(layerHit[8])
138 if (nSL >= m_minHits || shortTrack(layerHit)) {
139 if (iterations != maxIterations) {
140 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
142 TVector2 v1(x1_d, y1_d);
143 TVector2 v2(x2_d, y2_d);
145 nSL, houghCand.size()));
146 if (m_storePlane > 0) {
147 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
150 }
else if (m_storePlane > 1) {
153 for (
unsigned min = m_minHits - 1; min > 0; --min) {
155 if (iterations != maxIterations) {
156 fastInterceptFinder(hits, x1_d, x2_d, y1_d, y2_d, iterations + 1, ix, iy);
158 (*m_houghPlane)[ix - (nCells - m_nCellsPhi) / 2][iy - (nCells - m_nCellsR) / 2] = nSL;
174 CDCTrigger2DFinderModule::connectedRegions()
176 vector<vector<CDCTriggerHoughCand>> regions;
177 vector<CDCTriggerHoughCand> cpyCand = houghCand;
180 B2DEBUG(50,
"houghCand number " << cpyCand.size());
181 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
183 B2DEBUG(100, houghCand[icand].
getID()
184 <<
" nSL " << houghCand[icand].getSLcount()
185 <<
" x1 " << coord.first.X() <<
" x2 " << coord.second.X()
186 <<
" y1 " << coord.first.Y() <<
" y2 " << coord.second.Y());
190 while (cpyCand.size() > 0) {
191 B2DEBUG(100,
"make new region");
192 vector<CDCTriggerHoughCand> region;
193 vector<CDCTriggerHoughCand> rejected;
195 cpyCand.erase(cpyCand.begin());
196 region.push_back(start);
197 addNeighbors(start, cpyCand, region, rejected, start.getSLcount());
198 regions.push_back(region);
199 for (
auto cand = cpyCand.begin(); cand != cpyCand.end();) {
200 if (inList(*cand, region) || inList(*cand, rejected))
208 for (
unsigned ir = 0; ir < regions.size(); ++ir) {
209 B2DEBUG(50,
"region " << ir <<
" (" << regions[ir].size() <<
" cells).");
211 if (regions[ir].size() < m_minCells) {
212 B2DEBUG(50,
"Skipping region with " << regions[ir].size() <<
" cells.");
215 double xfirst = regions[ir][0].getCoord().first.X();
219 vector<unsigned> mergedList;
220 int xmin = m_nCellsPhi;
222 int ymin = m_nCellsR;
224 vector<TVector2> cellIds = {};
225 for (
unsigned ir2 = 0; ir2 < regions[ir].size(); ++ir2) {
227 B2DEBUG(100,
" " << regions[ir][ir2].
getID()
228 <<
" nSL " << regions[ir][ir2].getSLcount()
229 <<
" x1 " << hc.first.X() <<
" x2 " << hc.second.X()
230 <<
" y1 " << hc.first.Y() <<
" y2 " << hc.second.Y());
231 int ix = floor((hc.first.X() + M_PI) / 2. / M_PI * m_nCellsPhi + 0.5);
232 int iy = floor((hc.first.Y() + maxR - shiftR) / 2. / maxR * m_nCellsR + 0.5);
233 x += (hc.first.X() + hc.second.X());
234 if (xfirst - hc.first.X() > M_PI) {
237 }
else if (hc.first.X() - xfirst > M_PI) {
241 y += (hc.first.Y() + hc.second.Y());
243 vector<unsigned> idList = regions[ir][ir2].getIdList();
244 mergeIdList(mergedList, mergedList, idList);
245 xmin = min(xmin, ix);
246 xmax = max(xmax, ix);
247 ymin = min(ymin, iy);
248 ymax = max(ymax, iy);
249 cellIds.push_back(TVector2(ix, iy));
257 B2DEBUG(50,
"x " << x <<
" y " << y);
260 vector<unsigned> selectedList = {};
261 vector<unsigned> unselectedList = {};
262 selectHits(mergedList, selectedList, unselectedList);
266 m_tracks.appendNew(x, 2. * y, 0.);
268 for (
unsigned i = 0; i < selectedList.size(); ++i) {
269 unsigned its = selectedList[i];
270 track->addRelationTo(m_segmentHits[its]);
273 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
274 unsigned its = unselectedList[i];
275 track->addRelationTo(m_segmentHits[its], -1.);
279 m_clusters.appendNew(xmin, xmax, ymin, ymax, cellIds);
280 track->addRelationTo(cluster);
286 const vector<CDCTriggerHoughCand>& candidates,
287 vector<CDCTriggerHoughCand>& merged,
288 vector<CDCTriggerHoughCand>& rejected,
289 unsigned short nSLmax)
const
291 for (
unsigned icand = 0; icand < candidates.size(); ++icand) {
292 B2DEBUG(120,
"compare center " << center.
getID()
293 <<
" to " << candidates[icand].getID());
294 if (inList(candidates[icand], merged) || inList(candidates[icand], rejected)) {
295 B2DEBUG(120,
" " << candidates[icand].
getID() <<
" already in list");
298 bool reject = inList(center, rejected);
299 if (connected(center, candidates[icand])) {
300 if (m_onlyLocalMax && candidates[icand].getSLcount() < nSLmax) {
301 B2DEBUG(100,
" lower than highest SLcount, rejected");
302 rejected.push_back(candidates[icand]);
303 }
else if (m_onlyLocalMax && !reject && candidates[icand].getSLcount() > nSLmax) {
304 B2DEBUG(100,
" new highest SLcount, clearing list");
305 nSLmax = candidates[icand].getSLcount();
306 for (
unsigned imerged = 0; imerged < merged.size(); ++imerged) {
307 rejected.push_back(merged[imerged]);
310 merged.push_back(candidates[icand]);
311 }
else if (m_onlyLocalMax && candidates[icand].getSLcount() > center.
getSLcount()) {
312 B2DEBUG(100,
" connected to rejected cell, skip");
314 }
else if (m_onlyLocalMax && reject) {
315 B2DEBUG(100,
" connected to rejected cell, rejected");
316 rejected.push_back(candidates[icand]);
318 B2DEBUG(100,
" connected");
319 merged.push_back(candidates[icand]);
321 vector<CDCTriggerHoughCand> cpyCand = candidates;
322 cpyCand.erase(cpyCand.begin() + icand);
323 addNeighbors(candidates[icand], cpyCand, merged, rejected, nSLmax);
330 const vector<CDCTriggerHoughCand>& list)
const
332 for (
unsigned i = 0; i < list.size(); ++i) {
333 if (a == list[i])
return true;
342 double ax1 = a.getCoord().first.X();
343 double ax2 = a.getCoord().second.X();
344 double ay1 = a.getCoord().first.Y();
345 double ay2 = a.getCoord().second.Y();
346 double bx1 = b.getCoord().first.X();
347 double bx2 = b.getCoord().second.X();
348 double by1 = b.getCoord().first.Y();
349 double by2 = b.getCoord().second.Y();
351 bool direct = ((ax2 == bx1 && ay1 == by1) ||
352 (ax1 == bx2 && ay1 == by1) ||
353 (ax1 == bx1 && ay2 == by1) ||
354 (ax1 == bx1 && ay1 == by2) ||
355 (ax1 + 2. * M_PI == bx2 && ay1 == by1) ||
356 (ax2 == bx1 + 2. * M_PI && ay1 == by1));
358 bool diagRise = ((ax2 == bx1 && ay2 == by1) ||
359 (ax1 == bx2 && ay1 == by2) ||
360 (ax1 + 2. * M_PI == bx2 && ay1 == by2) ||
361 (ax2 == bx1 + 2. * M_PI && ay2 == by1));
362 bool diagFall = ((ax1 == bx2 && ay2 == by1) ||
363 (ax2 == bx1 && ay1 == by2) ||
364 (ax2 == bx1 + 2. * M_PI && ay1 == by2) ||
365 (ax1 + 2. * M_PI == bx2 && ay2 == by1));
366 if (m_connect == 4)
return direct;
367 else if (m_connect == 6)
return (direct || diagRise);
368 else if (m_connect == 8)
return (direct || diagRise || diagFall);
369 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
370 return (direct || diagRise);
377 CDCTrigger2DFinderModule::mergeIdList(std::vector<unsigned>& merged,
378 std::vector<unsigned>& a,
379 std::vector<unsigned>& b)
383 for (
auto it = a.begin(); it != a.end(); ++it) {
385 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
392 merged.push_back(*it);
396 for (
auto it = b.begin(); it != b.end(); ++it) {
398 for (
auto it_in = merged.begin(); it_in != merged.end(); ++it_in) {
405 merged.push_back(*it);
411 CDCTrigger2DFinderModule::findAllCrossingHits(std::vector<unsigned>& list,
412 double x1,
double x2,
413 double y1,
double y2,
416 double m, a, y1_h, y2_h;
417 for (
int iHit = 0; iHit < m_segmentHits.getEntries(); iHit++) {
418 unsigned short iSL = m_segmentHits[iHit]->getISuperLayer();
419 if (iSL % 2)
continue;
421 if (m_suppressClone && inputMap.find(iHit) == inputMap.end())
continue;
423 vector<double> phi = {0, 0, 0};
424 phi[0] = m_segmentHits[iHit]->getSegmentID() - TSoffset[iSL];
425 phi[1] = phi[0] + 0.5;
426 phi[2] = phi[0] - 0.5;
427 vector<double> r = {radius[iSL][0], radius[iSL][1], radius[iSL][1]};
428 for (
unsigned i = 0; i < 3; ++i) {
429 phi[i] *= 2. * M_PI / (TSoffset[iSL + 1] - TSoffset[iSL]);
430 m = cos(phi[i]) / r[i];
431 a = sin(phi[i]) / r[i];
433 y1_h = m * sin(x1 - 1e-10) - a * cos(x1 - 1e-10);
434 y2_h = m * sin(x2 + 1e-10) - a * cos(x2 + 1e-10);
436 if (y1_h > y2_h)
continue;
437 if (!((y1_h > y2 && y2_h > y2) || (y1_h < y1 && y2_h < y1))) {
438 list.push_back(iHit);
449 CDCTrigger2DFinderModule::selectHits(std::vector<unsigned>& list,
450 std::vector<unsigned>& selected,
451 std::vector<unsigned>& unselected)
453 std::vector<int> bestPerSL(5, -1);
454 for (
unsigned i = 0; i < list.size(); ++i) {
455 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
456 bool firstPriority = (m_segmentHits[list[i]]->getPriorityPosition() == 3);
457 if (bestPerSL[iax] < 0) {
460 unsigned itsBest = list[bestPerSL[iax]];
461 bool firstBest = (m_segmentHits[itsBest]->getPriorityPosition() == 3);
464 if ((firstPriority && !firstBest) ||
465 (firstPriority == firstBest &&
466 m_segmentHits[list[i]]->getSegmentID() > m_segmentHits[itsBest]->getSegmentID())) {
472 for (
unsigned i = 0; i < list.size(); ++i) {
473 unsigned iax = m_segmentHits[list[i]]->getISuperLayer() / 2;
474 if (
int(i) == bestPerSL[iax]) selected.push_back(list[i]);
475 else unselected.push_back(list[i]);
483 CDCTrigger2DFinderModule::patternClustering(
const cdcMap& inputMap)
486 TMatrix plane2(m_nCellsPhi / 2, m_nCellsR / 2);
487 TMatrix planeIcand(m_nCellsPhi, m_nCellsR);
488 for (
unsigned icand = 0; icand < houghCand.size(); ++icand) {
489 double x = (houghCand[icand].getCoord().first.X() +
490 houghCand[icand].getCoord().second.X()) / 2.;
491 unsigned ix = floor((x + M_PI) / 2. / M_PI * m_nCellsPhi);
492 double y = (houghCand[icand].getCoord().first.Y() +
493 houghCand[icand].getCoord().second.Y()) / 2.;
494 unsigned iy = floor((y + maxR - shiftR) / 2. / maxR * m_nCellsR);
495 plane2[ix / 2][iy / 2] += 1 << ((ix % 2) + 2 * (iy % 2));
496 planeIcand[ix][iy] = icand;
497 B2DEBUG(100,
"candidate " << icand <<
" at ix " << ix <<
" iy " << iy);
500 unsigned nX = m_nCellsPhi / 2;
501 unsigned nY = m_nCellsR / 2;
502 unsigned rX = m_clusterSizeX;
503 unsigned rY = m_clusterSizeY;
504 for (
unsigned ix = 0; ix < nX; ++ix) {
505 for (
unsigned iy = 0; iy < nY; ++iy) {
506 if (!plane2[ix][iy])
continue;
508 unsigned ileft = (ix - 1 + nX) % nX;
509 B2DEBUG(100,
"ix " << ix <<
" iy " << iy);
510 if (connectedLR(plane2[ileft][iy], plane2[ix][iy]) ||
511 (iy > 0 && connectedUD(plane2[ix][iy - 1], plane2[ix][iy])) ||
512 (iy > 0 && connectedDiag(plane2[ileft][iy - 1], plane2[ix][iy]))) {
513 B2DEBUG(100,
"skip connected square");
517 vector<unsigned> pattern(rX * rY, 0);
518 pattern[0] = plane2[ix][iy];
519 vector<TVector2> cellIds = {TVector2(2 * ix, 2 * iy)};
520 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
521 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
522 if (iy + iy2 >= nY)
continue;
523 unsigned ip = ix2 + rX * iy2;
524 unsigned iright = (ix + ix2 + nX) % nX;
525 ileft = (iright - 1 + nX) % nX;
526 B2DEBUG(100,
"ix2 " << ix2 <<
" ileft " << ileft <<
" iright " << iright);
529 connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2])) ||
532 connectedUD(plane2[iright][iy + iy2 - 1], plane2[iright][iy + iy2])) ||
533 (ix2 > 0 && iy2 > 0 &&
534 pattern[ip - rX - 1] &&
535 connectedDiag(plane2[ileft][iy + iy2 - 1], plane2[iright][iy + iy2]))) {
536 pattern[ip] = plane2[iright][iy + iy2];
537 B2DEBUG(100,
"connect cell " << iright <<
" " << iy + iy2);
538 cellIds.push_back(TVector2(2 * (ix + ix2), 2 * (iy + iy2)));
542 B2DEBUG(100,
"cluster starting at " << ix <<
" " << iy);
544 bool overflowRight =
false;
545 bool overflowTop =
false;
546 for (
unsigned iy2 = 0; iy2 < rY; ++iy2) {
547 unsigned ip = rX - 1 + rX * iy2;
548 if (!pattern[ip])
continue;
549 unsigned iright = (ix + rX + nX) % nX;
550 ileft = (iright - 1 + nX) % nX;
551 if (connectedLR(plane2[ileft][iy + iy2], plane2[iright][iy + iy2]) ||
552 ((iy + iy2 + 1 < nY) &&
553 connectedDiag(plane2[ileft][iy + iy2], plane2[iright][iy + iy2 + 1]))) {
554 setReturnValue(
false);
555 overflowRight =
true;
559 for (
unsigned ix2 = 0; ix2 < rX; ++ix2) {
560 unsigned ip = ix2 + rX * (rY - 1);
561 if (!pattern[ip])
continue;
562 unsigned iright = (ix + ix2 + 1 + nX) % nX;
563 ileft = (iright - 1 + nX) % nX;
564 if (connectedUD(plane2[ileft][iy + rY - 1], plane2[ileft][iy + rY]) ||
565 connectedDiag(plane2[ileft][iy + rY - 1], plane2[iright][iy + rY])) {
566 setReturnValue(
false);
571 if (overflowRight && !overflowTop) {
572 B2DEBUG(100,
"cluster extends right of " << rX <<
" x " << rY <<
" area");
573 }
else if (overflowTop && !overflowRight) {
574 B2DEBUG(100,
"cluster extends above " << rX <<
" x " << rY <<
" area");
575 }
else if (overflowRight && overflowTop) {
576 B2DEBUG(100,
"cluster extends right and above " << rX <<
" x " << rY <<
" area");
579 unsigned topRight2 = topRightSquare(pattern);
580 unsigned topRight = topRightCorner(pattern[topRight2]);
581 unsigned bottomLeft = bottomLeftCorner(pattern[0]);
582 B2DEBUG(100,
"topRight2 " << topRight2 <<
" topRight " << topRight <<
" bottomLeft " << bottomLeft);
584 unsigned ixTR = 2 * (topRight2 % m_clusterSizeX) + (topRight % 2);
585 unsigned ixBL = bottomLeft % 2;
586 unsigned iyTR = 2 * (topRight2 / m_clusterSizeX) + (topRight / 2);
587 unsigned iyBL = bottomLeft / 2;
588 B2DEBUG(100,
"ixTR " << ixTR <<
" ixBL " << ixBL <<
" iyTR " << iyTR <<
" iyBL " << iyBL);
590 if (m_minCells > 1 && ixTR == ixBL && iyTR == iyBL) {
591 B2DEBUG(100,
"skipping cluster of size 1");
594 float centerX = 2 * ix + (ixTR + ixBL) / 2.;
595 if (centerX >= m_nCellsPhi) centerX -= m_nCellsPhi;
596 float centerY = 2 * iy + (iyTR + iyBL) / 2.;
597 B2DEBUG(100,
"center at cell (" << centerX <<
", " << centerY <<
")");
599 double x = -M_PI + (centerX + 0.5) * 2. * M_PI / m_nCellsPhi;
600 double y = -maxR + shiftR + (centerY + 0.5) * 2. * maxR / m_nCellsR;
601 B2DEBUG(100,
"center coordinates (" << x <<
", " << y <<
")");
603 vector <unsigned> idList = {};
604 if (m_hitRelationsFromCorners) {
605 unsigned icandTR = planeIcand[(ixTR + 2 * ix) % m_nCellsPhi][iyTR + 2 * iy];
606 unsigned icandBL = planeIcand[ixBL + 2 * ix][iyBL + 2 * iy];
607 vector<unsigned> candIdListTR = houghCand[icandTR].getIdList();
608 vector<unsigned> candIdListBL = houghCand[icandBL].getIdList();
609 mergeIdList(idList, candIdListTR, candIdListBL);
610 B2DEBUG(100,
"merge id lists from candidates " << icandTR <<
" and " << icandBL);
612 double dx = M_PI / m_nCellsPhi;
613 double dy = maxR / m_nCellsR;
614 double x1 = (round(centerX) == centerX) ? x - dx : x - 2 * dx;
615 double x2 = (round(centerX) == centerX) ? x + dx : x + 2 * dx;
616 double y1 = (round(centerY) == centerY) ? y - dy : y - 2 * dy;
617 double y2 = (round(centerY) == centerY) ? y + dy : y + 2 * dy;
618 findAllCrossingHits(idList, x1, x2, y1, y2, inputMap);
620 if (idList.size() == 0) {
621 setReturnValue(
false);
622 B2DEBUG(100,
"id list empty");
626 vector<unsigned> selectedList = {};
627 vector<unsigned> unselectedList = {};
628 selectHits(idList, selectedList, unselectedList);
632 m_tracks.appendNew(x, 2. * y, 0.);
634 for (
unsigned i = 0; i < selectedList.size(); ++i) {
635 unsigned its = selectedList[i];
636 track->addRelationTo(m_segmentHits[its]);
639 for (
unsigned i = 0; i < unselectedList.size(); ++i) {
640 unsigned its = unselectedList[i];
641 track->addRelationTo(m_segmentHits[its], -1.);
645 m_clusters.appendNew(2 * ix, 2 * (ix + m_clusterSizeX) - 1,
646 2 * iy, 2 * (iy + m_clusterSizeY) - 1,
648 track->addRelationTo(cluster);
657 CDCTrigger2DFinderModule::connectedLR(
unsigned patternL,
unsigned patternR)
662 bool connectDirect = (((patternL >> 3) & 1) && ((patternR >> 2) & 1)) ||
663 (((patternL >> 1) & 1) && ((patternR >> 0) & 1));
667 bool connectRise = ((patternL >> 1) & 1) && ((patternR >> 2) & 1);
671 bool connectFall = ((patternL >> 3) & 1) && ((patternR >> 0) & 1);
673 if (m_connect == 4)
return connectDirect;
674 else if (m_connect == 6)
return (connectDirect || connectRise);
675 else if (m_connect == 8)
return (connectDirect || connectRise || connectFall);
676 else B2WARNING(
"Unknown option for connect " << m_connect <<
", using default.");
677 return (connectDirect || connectRise);
681 CDCTrigger2DFinderModule::connectedUD(
unsigned patternD,
unsigned patternU)
689 bool connectDirect = (((patternU >> 0) & 1) && ((patternD >> 2) & 1)) ||
690 (((patternU >> 1) & 1) && ((patternD >> 3) & 1));
697 bool connectRise = ((patternU >> 1) & 1) && ((patternD >> 2) & 1);
704 bool connectFall = ((patternU >> 0) & 1) && ((patternD >> 3) & 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 CDCTrigger2DFinderModule::connectedDiag(
unsigned patternLD,
unsigned patternRU)
716 if (m_connect == 4)
return false;
723 return (((patternRU >> 0) & 1) && ((patternLD >> 3) & 1));
727 CDCTrigger2DFinderModule::topRightSquare(vector<unsigned>& pattern)
730 for (
unsigned index = pattern.size() - 1; index > 0; --index) {
731 if (!pattern[index])
continue;
733 unsigned ix = index % m_clusterSizeX;
734 unsigned iy = index / m_clusterSizeX;
735 if (ix < m_clusterSizeX - 1 && iy > 0) {
737 for (
unsigned index2 = index - 1; index2 > 0; --index2) {
738 if (!pattern[index2])
continue;
739 unsigned ix2 = index2 % m_clusterSizeX;
740 unsigned iy2 = index2 / m_clusterSizeX;
741 if (iy2 < iy && ix2 > ix) {
747 setReturnValue(
false);
748 B2DEBUG(100,
"topRightSquare not unique");
757 CDCTrigger2DFinderModule::topRightCorner(
unsigned pattern)
762 if ((pattern >> 3) & 1)
return 3;
763 if ((pattern >> 1) & 1) {
764 if ((pattern >> 2) & 1) {
765 setReturnValue(
false);
766 B2DEBUG(100,
"topRightCorner not unique");
770 if ((pattern >> 2) & 1)
return 2;
775 CDCTrigger2DFinderModule::bottomLeftCorner(
unsigned pattern)
780 if (pattern & 1)
return 0;
781 if ((pattern >> 2) & 1) {
782 if ((pattern >> 1) & 1) {
783 setReturnValue(
false);
784 B2DEBUG(100,
"bottomLeftCorner not unique");
788 if ((pattern >> 1) & 1)
return 1;
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.