ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ITkPixEncoder.cxx
Go to the documentation of this file.
1 /*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*EXTERNAL CODE PORTED FROM YARR MINIMALLY ADAPTED FOR ATHENA*/
6 
7 /*
8 * Author: Ondra Kovanda, ondrej.kovanda at cern.ch
9 * Date: 03/2024
10 * Description: ITkPix* encoding base class
11 */
12 
13 #include "ITkPixEncoder.h"
14 #include "ITkPixQCoreEncodingLUT.h"
15 #include <bitset>
16 
17 //Constructor sets up the geometry for all future loops
18 
19 ITkPixEncoder::ITkPixEncoder(const unsigned nCol, const unsigned nRow, const unsigned nColInCCol,
20  const unsigned nRowInQRow, const unsigned nEventsPerStream, const bool plainHitMap,
21  const bool dropToT): m_nCol(nCol/nColInCCol), m_nRow(nRow/nRowInQRow),
22  m_nColInCCol(nColInCCol), m_nRowInQRow(nRowInQRow), m_nEventsPerStream(nEventsPerStream),
23  m_plainHitMap(plainHitMap), m_dropToT(dropToT){
24  //nop
25 }
26 
28 
29  //only called from mutex-protected function
30 
31  //This adds 'length' lowest bits to the current block. If the current
32  //block gets filled, push it to the output and start a new block with
33  //the rest of the bits that didn't make it. Need to keep track of the
34  //remaining space in the current word. Also, we only have 63 bits for
35  //the added data, as the first bit is EoS.
36  //Case 1: there's enough space for the entire information to be added
37  if (length <= (63 - m_currBit)){
38 
39  //The position at which the new bits should be inserted into the block
40  //is (length of the block - 1) - (currently last bit) - (length)
41  //We need to keep the first bit for EoS, hence the -1
42  m_currBlock |= (value << (63 - m_currBit - length));
43  m_currBit += length;
44  return;
45  }
46 
47  //Case 2: there's not enough space, so we put what we can, push the block
48  //to the output, and the rest to a new block
49  else {
50 
51  //How much space do we have?
52  uint8_t remainingBits = 63 - m_currBit;
53 
54  //Add that many bits
55  m_currBlock |= ((value >> (length - remainingBits)));
56 
57  //Push the current block to the output and reset it and the current
58  //bit counter. The block needs to be split in 32-bit halves before the output
59  pushWords32();
60 
61  //What are we left with?
62  uint8_t leftoverBits = length - remainingBits;
63 
64  //Now we can add the remainder
65  //Make sure that the remainder we're adding is really only the bits we've not yet
66  //added, otherwise there can be a rogue "1" in the EoS bit, which was already added
67  //in the previous block
68  addBits64((value & (0xFFFFFFFFFFFFFFFF >> (64 - leftoverBits))), leftoverBits);
69 
70  }
71 }
72 
74  //whenever the current block is ready for output,
75  //split it into two 32-bit words and push them to
76  //the output container. Reset the current bloc/bit
77 
78  //only called from mutex-protected function
79 
80  uint32_t word1 = m_currBlock >> 32;
81  uint32_t word2 = m_currBlock & 0xFFFFFFFF;
82  m_words.push_back(word1);
83  m_words.push_back(word2);
84  m_currBlock = 0x0ULL;
85  m_currBit = 0;
86 }
87 
88 void ITkPixEncoder::encodeQCore(const unsigned nCCol, const unsigned nQRow) const {
89 
90  //only called from mutex-protected function
91 
92  //produce hit map and ToTs
93  //First, get the top-left pixel in the QCore
94  unsigned col = nCCol * m_nColInCCol;
95  unsigned row = nQRow * m_nRowInQRow;
96 
97  //now loop, store ToTs, and build index of the
98  //compressed hit map in the LUT
99  uint16_t lutIndex = 0x0000;
100  std::vector<uint16_t> tots;
101  tots.reserve(16);
102  int pix = 0;
103  for (unsigned pixRow = row; pixRow < row + m_nRowInQRow; pixRow++){
104  for (unsigned pixCol = col; pixCol < col + m_nColInCCol; pixCol++){
105  if (m_hitMap(pixCol, pixRow)){
106  lutIndex |= 0x1 << pix;
107  tots.push_back(m_hitMap(pixCol, pixRow) - 1);
108  }
109  pix++;
110  }
111  }
112 
113  //now add the binary-tree encoded & compressed map
114  //from the LUT to the stream. If, instead, the plain
115  //hit map is requested, add the index (which is the
116  //plain hit map in fact)
118 
119  //if dropToT is requested, we can return here
120  if (m_dropToT) return;
121 
122  //and add the four-bit ToT information for each hit
123  for (auto& tot : tots){
124  addBits64(tot, 4);
125  }
126 }
127 
128 bool ITkPixEncoder::hitInQCore(const unsigned CCol, const unsigned QRow) const {
129  //Was there a hit in this QCore?
130 
131  unsigned col = CCol * m_nColInCCol;
132  unsigned row = QRow * m_nRowInQRow;
133 
134  for (unsigned pixRow = row; pixRow < row + m_nRowInQRow; pixRow++){
135  for (unsigned pixCol = col; pixCol < col + m_nColInCCol; pixCol++){
136  if (m_hitMap(pixCol, pixRow)) return true;
137  }
138  }
139 
140  return false;
141 }
142 
144 
145  //only called from mutex-protected function
146 
147  //Fill in a helper map of hit QCores and a vector of last qrow in each ccol
148  m_hitQCores = std::vector<std::vector<bool>>(m_nCCol, std::vector<bool>(m_nQRow, false));
149  m_lastQRow = std::vector<unsigned> (m_nCCol, 0);
150 
151  for (unsigned CCol = 0; CCol < m_nCCol; CCol++){
152  for (unsigned QRow = 0; QRow < m_nQRow; QRow++){
153  //if there's a hit in the qcore, flag the helper map
154  m_hitQCores[CCol][QRow] = hitInQCore(CCol, QRow);
155 
156  //and keep track of the last qrow in each CCol, so that we can
157  //easily set the isLast bit. Numbering starts at 1, in order to
158  //keep the m_lastQRow[CCol] == 0 case denoting "no hit" in the CCol
159  //to save some looping/ifs later on
160  if (m_hitQCores[CCol][QRow]) m_lastQRow[CCol] = QRow + 1;
161  }
162  }
163 
164 }
165 
167 
168  //only called from mutex-protected function
169 
170  //This produces the bits for one event.
171  //First, scan the map and produce helpers
172  scanHitMap();
173 
174  for (unsigned CCol = 0; CCol < m_nCCol; CCol++){
175  //if there are no hits in this CCol, continue
176  if (m_lastQRow[CCol] == 0) continue;
177  //add the 6-bit (CCol + 1) address
178  addBits64(CCol + 1, 6);
179 
180  int previousQRow = -666;
181  for (unsigned QRow = 0; QRow < m_nQRow; QRow++){
182  //if there's no hit in this row, continue
183  if (!m_hitQCores[CCol][QRow]) continue;
184 
185  //add the isLast bit
186  QRow + 1 == m_lastQRow[CCol] ? addBits64(0x1, 1) : addBits64(0x0, 1);
187 
188  //add the isNeighbor bit. If false, add the QRow address as well.
189  if (QRow == (uint)previousQRow + 1){
190  addBits64(0x1, 1);
191  }
192  else {
193  addBits64(0x0, 1);
194  addBits64(QRow, 8);
195  };
196 
197  //add the map and ToT
198  encodeQCore(CCol, QRow);
199 
200  //update the previous QRow
201  previousQRow = QRow;
202  }
203  }
204 }
205 
206 void ITkPixEncoder::streamTag(const uint8_t nStream) const {
207 
208  //only called from mutex-protected function
209 
210  //this adds the 8-bit 'global' stream tag
211  addBits64(nStream, 8);
212 }
213 
214 void ITkPixEncoder::intTag(const uint16_t nEvt) const {
215 
216  //only called from mutex-protected function
217 
218  //this adds 11 bits of interal tagging between events.
219  //does the tag always need to start with 111?
220  uint16_t tag = nEvt | (0b111 << 8);
221  addBits64(tag, 11);
222 }
223 
224 void ITkPixEncoder::clear() const {
225  std::lock_guard<std::mutex> lock(m_mutex);
226  m_words.clear();
227 }
ITkPixEncoding::ITkPixV2QCoreEncodingLUT_Length
constexpr std::array< uint32_t, LookUpTableSize > ITkPixV2QCoreEncodingLUT_Length
Definition: ITkPixQCoreEncodingLUT.h:116
query_example.row
row
Definition: query_example.py:24
ITkPixEncoder.h
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
xAOD::word1
word1
Definition: eFexEMRoI_v1.cxx:87
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
ITkPixEncoder::intTag
void intTag(const uint16_t nEvt) const
Definition: ITkPixEncoder.cxx:214
ITkPixEncoder::hitInQCore
bool hitInQCore(const unsigned CCol, const unsigned QRow) const
Definition: ITkPixEncoder.cxx:128
athena.value
value
Definition: athena.py:124
ITkPixEncoder::clear
void clear() const
Definition: ITkPixEncoder.cxx:224
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
ITkPixEncoder::m_dropToT
bool m_dropToT
Definition: ITkPixEncoder.h:75
ITkPixEncoder::m_nRowInQRow
unsigned m_nRowInQRow
Definition: ITkPixEncoder.h:60
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
ITkPixEncoder::m_nColInCCol
unsigned m_nColInCCol
Definition: ITkPixEncoder.h:60
ITkPixEncoder::pushWords32
void pushWords32() const
Definition: ITkPixEncoder.cxx:73
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ITkPixEncoder::m_plainHitMap
bool m_plainHitMap
Definition: ITkPixEncoder.h:75
ITkPixEncoder::encodeEvent
void encodeEvent() const
Definition: ITkPixEncoder.cxx:166
ITkPixEncoder::ITkPixEncoder
ITkPixEncoder(const unsigned nCol=400, const unsigned nRow=384, const unsigned nColInCCol=8, const unsigned nRowInQRow=2, const unsigned nEventsPerStream=16, const bool plainHitMap=false, const bool dropToT=false)
Definition: ITkPixEncoder.cxx:19
ITkPixQCoreEncodingLUT.h
ITkPixEncoder::m_nCCol
unsigned m_nCCol
Definition: ITkPixEncoder.h:60
ITkPixEncoder::m_mutex
std::mutex m_mutex
Definition: ITkPixEncoder.h:80
query_example.col
col
Definition: query_example.py:7
ITkPixEncoder::encodeQCore
void encodeQCore(const unsigned nCCol, const unsigned nQRow) const
Definition: ITkPixEncoder.cxx:88
ITkPixEncoder::addBits64
void addBits64(const uint64_t value, const uint8_t length) const
Definition: ITkPixEncoder.cxx:27
ITkPixEncoder::streamTag
void streamTag(const uint8_t nStream) const
Definition: ITkPixEncoder.cxx:206
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
ITkPixEncoder::m_nQRow
unsigned m_nQRow
Definition: ITkPixEncoder.h:60
pix
Definition: PixelMapping.cxx:16
ITkPixEncoder::scanHitMap
void scanHitMap() const
Definition: ITkPixEncoder.cxx:143
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
ITkPixEncoding::ITkPixV2QCoreEncodingLUT_Tree
constexpr std::array< uint32_t, LookUpTableSize > ITkPixV2QCoreEncodingLUT_Tree
Definition: ITkPixQCoreEncodingLUT.h:115