41 const uint32_t clsTopoKey = packKey(spanRow, spanCol,
bitmask);
44 auto it = mTopologyCache.find(clsTopoKey);
45 if (it != mTopologyCache.end()) {
46 topology = it->second.mTopology;
47 it->second.mFrequency++;
53 topology = mTopologyCache[clsTopoKey].mTopology;
54 LOG(
debug) <<
"Classified new topology: " <<
static_cast<int>(topology);
70 LOG(
debug) <<
"Classifying topology for bitmask: " << std::bitset<16>(
bitmask) <<
", minRow: "
71 <<
static_cast<int>(minRow) <<
", spanRow: " <<
static_cast<int>(spanRow)
72 <<
", minCol: " <<
static_cast<int>(minCol) <<
", spanCol: " <<
static_cast<int>(spanCol);
80 float xCOG{0.f}, zCOG{0.f}, mXMean{0.f}, mZMean{0.f}, mXSigma2{0.f}, mZSigma2{0.f};
83 const int maxRow = minRow + spanRow - 1;
84 const int maxCol = minCol + spanCol - 1;
86 const auto hasDigit = [
bitmask, minRow, minCol, spanCol](
int row,
int col) ->
bool {
87 const int bitIndex = (
row - minRow) * spanCol + (
col - minCol);
88 return (
bitmask & (1U << bitIndex)) != 0;
92 if (spanRow == 1 && spanCol == 1) {
94 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
99 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
104 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
110 for (
int r = minRow;
r <= maxRow; ++
r) {
111 for (
int c = minCol;
c <= maxCol; ++
c) {
112 if (hasDigit(
r,
c)) {
119 if (firedDigits == spanRow * spanCol && spanRow == spanCol) {
121 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
124 if (firedDigits == spanRow * spanCol && spanRow != spanCol) {
126 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
131 const bool hasBottomLeft = hasDigit(minRow, minCol);
132 const bool hasBottomRight = hasDigit(minRow, maxCol);
133 const bool hasTopLeft = hasDigit(maxRow, minCol);
134 const bool hasTopRight = hasDigit(maxRow, maxCol);
137 if (spanRow == spanCol) {
140 const int nCorners = hasTopLeft + hasTopRight + hasBottomLeft + hasBottomRight;
142 const int missing = !hasTopLeft ? 0 : !hasTopRight ? 1
160 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
164 if ((firedDigits == spanRow && hasTopLeft && hasBottomRight && !hasTopRight && !hasBottomLeft) ||
165 (firedDigits == spanRow && hasTopRight && hasBottomLeft && !hasTopLeft && !hasBottomRight)) {
167 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
173 if (spanRow == 3 && spanCol == 2) {
174 const bool hasMiddleMin = hasDigit(minRow, minCol + 1);
175 const bool hasMiddleMax = hasDigit(minRow, maxCol + 1);
177 if (hasMiddleMin && hasMiddleMax) {
178 if (!hasTopLeft && !hasBottomRight && hasTopRight && hasBottomLeft) {
180 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
184 if (hasTopLeft && hasBottomRight && !hasTopRight && !hasBottomLeft) {
186 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
193 if (spanRow == 2 && spanCol == 3) {
194 const bool hasMiddleLeft = hasDigit(minRow + 1, minCol);
195 const bool hasMiddleRight = hasDigit(maxRow + 1, minCol);
197 if (hasMiddleLeft && hasMiddleRight) {
198 if (!hasTopLeft && !hasBottomRight && hasTopRight && hasBottomLeft) {
200 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
204 if (hasTopLeft && hasBottomRight && !hasTopRight && !hasBottomLeft) {
206 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
214 mTopologyCache[packKey(spanRow, spanCol,
bitmask)] = newTopo;
226 const int nBits = std::min(
static_cast<int>(spanRow * spanCol), 16);
228 for (
int iBit = 0; iBit < nBits; ++iBit) {
231 int iRow = iBit / spanCol;
232 int iCol = iBit % spanCol;
234 xOffsetCOG += minRow + iRow;
235 zOffsetCOG += minCol + iCol;
240 topoInfo.
mOffsetXToCOG =
static_cast<int>((
static_cast<float>(xOffsetCOG) / firedPixels) -
static_cast<float>(minRow));
241 topoInfo.
mOffsetZToCOG =
static_cast<int>((
static_cast<float>(zOffsetCOG) / firedPixels) -
static_cast<float>(minCol));
245 topoInfo.
mXMean = -(
static_cast<float>(xOffsetCOG) / firedPixels - minRow) * chipSpecs.PitchRow;
246 topoInfo.
mZMean = (
static_cast<float>(zOffsetCOG) / firedPixels - minCol) * chipSpecs.PitchCol;
247 topoInfo.
mXSigma2 = chipSpecs.PitchRow * chipSpecs.PitchRow / 12. / topoInfo.
mSizeX;
248 topoInfo.
mZSigma2 = chipSpecs.PitchCol * chipSpecs.PitchCol / 12. / topoInfo.
mSizeZ;
250 LOG(
debug) <<
"Computed topology features";
254 LOG(
debug) <<
"Fired Pixels: " << firedPixels;