ATLAS Offline Software
FPGADataFormatTool.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 
6 #include "FPGADataFormatTool.h"
8 
10  ATH_MSG_INFO("Initializing IEFTrackingFPGADataFormatTool tool");
11 
12  ATH_CHECK(detStore()->retrieve(m_PIX_mgr, "ITkPixel"));
13  ATH_CHECK(detStore()->retrieve(m_pixelId, "PixelID"));
14  ATH_CHECK(detStore()->retrieve(m_SCT_mgr, "ITkStrip"));
15  ATH_CHECK(detStore()->retrieve(m_sctId, "SCT_ID"));
16 
17  return StatusCode::SUCCESS;
18 }
19 
21  const PixelRDO_Container &pixelRDO,
22  std::vector<uint64_t> &encodedData,
23  const EventContext &ctx) const {
24 
25  // Fill the event header
26  ATH_CHECK(fillHeader(encodedData));
27 
28  // Convert the strip RDO
29  ATH_CHECK(convertPixelRDO(pixelRDO, encodedData, ctx));
30 
31  // Fill the event footer
32  ATH_CHECK(fillFooter(encodedData));
33 
34 
35  return StatusCode::SUCCESS;
36 }
37 
39  const SCT_RDO_Container &stripRDO,
40  std::vector<uint64_t> &encodedData,
41  const EventContext &ctx) const {
42 
43  // Fill the event header
44  ATH_CHECK(fillHeader(encodedData));
45 
46  // Convert the strip RDO
47  ATH_CHECK(convertStripRDO(stripRDO, encodedData, ctx));
48 
49  // Fill the event footer
50  ATH_CHECK(fillFooter(encodedData));
51 
52  return StatusCode::SUCCESS;
53 }
54 
55 
56 
58  const PixelRDO_Container &pixelRDO,
59  std::vector<uint64_t> &encodedData,
60  const EventContext &/*ctx*/
61  ) const {
62 
63  int pixelCounter = 0;
64  bool filledHeader = false;
65  for (const InDetRawDataCollection<PixelRDORawData>* pixel_rdoCollection : pixelRDO)
66  {
67  if (pixel_rdoCollection == nullptr) { continue; }
68 
69  // loop on all RDOs
70  for (const PixelRDORawData* pixelRawData : *pixel_rdoCollection)
71  {
72  Identifier rdoId = pixelRawData->identify();
73  // get the det element from the det element collection
74  const InDetDD::SiDetectorElement* sielement = m_PIX_mgr->getDetectorElement(rdoId);
75 
76  // Fill the module header
77  if(!filledHeader)
78  {
79  ATH_CHECK(fillModuleHeader(sielement, encodedData));
80  filledHeader = true;
81  }
82 
83  // Get the pixel word
85  (pixelRawData == pixel_rdoCollection->back()), // last
86  m_pixelId->eta_index(rdoId), // ROW
87  m_pixelId->phi_index(rdoId), // COL
88  pixelRawData->getToT(), // TOT
89  pixelRawData->getLVL1A(), // Lvl!
90  pixelCounter, // id
91  0 // Spare
92  );
93  pixelCounter++;
94 
95  // Push the word into the vector
96  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_PIXEL_EF_RDO(pixelWord));
97 
98  } // end for each RDO in the collection
99 
100  // reset the header
101  filledHeader = false;
102 
103  } // for each pixel RDO collection
104 
105  return StatusCode::SUCCESS;
106 }
107 
108 
110  const SCT_RDO_Container &stripRDO,
111  std::vector<uint64_t> &encodedData,
112  const EventContext &/*ctx*/
113  ) const {
114 
115  constexpr int MaxChannelinStripRow = 128;
116  int stripNumber = 0;
117 
118  bool filledHeader = false;
119 
120  for (const InDetRawDataCollection<SCT_RDORawData>* SCT_Collection : stripRDO) {
121  if (SCT_Collection == nullptr) { continue; }
122 
123  std::map<int, bool> firedStrips;
124  // Preprocess the SCT collection hits to get information for encoding strip in ITK format
125  // All strips fired read into a map to an overview of full module that should be used to encode
126  // the data into the ITk formatl
127  for (const SCT_RDORawData* sctRawData : *SCT_Collection)
128  {
129  const Identifier rdoId = sctRawData->identify();
130  const int baseLineStrip{m_sctId->strip(rdoId)};
131 
132  for(int i = 0; i < sctRawData->getGroupSize(); i++) {
133  firedStrips[baseLineStrip+ i] = true;
134  }
135  }
136 
137  // Loop over the fired hits and encode them in the ITk strips hit map
138  // It find unique hits in the list that can be encoded and don't overlap
139  std::map<int, int> stripEncodingForITK;
140  for(auto& [stripID, fired]: firedStrips)
141  {
142  // Don't use the strip that has been set false.
143  // This will be the case where neighbouring strip will "used up in the cluster"
144  // And then we don't want to re use them
145  if(!fired) continue;
146 
147  // Check the next 3 hits if they are there and have a hit in them
148  std::bitset<3> hitMap;
149 
150  // Get the current chip id of the strip
151  int currChipID = stripID / MaxChannelinStripRow;
152  // Compute the maximum stripID this chip can have
153  int maxStripIDForCurrChip = (currChipID + 1) * MaxChannelinStripRow;
154 
155  for(int i = 0; i < 3; i++)
156  {
157  // We don't want to "cluster" strips that are outside the range of this chip
158  if((stripID + 1 + i) >= maxStripIDForCurrChip) continue;
159 
160  if(firedStrips.find(stripID + 1 + i) != firedStrips.end())
161  {
162  if(firedStrips.at(stripID + 1 + i))
163  {
164  hitMap[2 - i] = 1;
165  firedStrips[stripID + 1 + i] = false;
166  }
167  else
168  {
169  hitMap[2 - i] = 0;
170  }
171  }
172  }
173  // Encode the hit map into a int
174  stripEncodingForITK[stripID] = (int)(hitMap.to_ulong());
175  }
176 
177  // count number of strip we need to encode for figuring if we are at the last strip
178  int stripToEncode = 0;
179  int stripAlreadyEncoded = 0;
180  for(const auto& [stripID, fired]: firedStrips)
181  {
182  if(fired) stripToEncode += 1;
183  }
184 
185  // Actual creation of the FPGAHit objects
186  for (const SCT_RDORawData* sctRawData : *SCT_Collection)
187  {
188  const Identifier rdoId = sctRawData->identify();
189  // get the det element from the det element collection
190  const InDetDD::SiDetectorElement* sielement = m_SCT_mgr->getDetectorElement(rdoId);
191 
192  // If the strip has been identified by the previous for loop as a valid hit that can be encoded into ITk Strip format
193  int stripID = m_sctId->strip(rdoId);
194  if(stripEncodingForITK.find(stripID) != stripEncodingForITK.end())
195  {
196  // Fill the module header
197  if(!filledHeader)
198  {
199  if(!fillModuleHeader(sielement, encodedData)) return StatusCode::FAILURE;
200  filledHeader = true;
201  }
202 
203  // Each ITK ABC chip reads 128 channels in one row, so we just need to divide the current strip with 128 to get the chip index
204  // for the Strip ID, it is the remainder left after dividing by 128
205  int chipID = stripID / MaxChannelinStripRow;
206  int ITkStripID = stripID % MaxChannelinStripRow;
207 
208  // for each ABC chip readout, each reads 256 channels actually. 0-127 corresponds to lower row and then 128-255 corresponds to the
209  // upper. This can be simulated in the code by using the eta module index. Even index are not offest, while odd index, the
210  // strip id is offest by 128
211  // One point to not is that for barrel, the eta module index start at 1, and not zero. Hence a shift of 1 is needed
212  int offset = m_sctId->eta_module(rdoId) % 2;
213  if(m_sctId->barrel_ec(rdoId) == 0) offset = (std::abs(m_sctId->eta_module(rdoId)) - 1) % 2;
214 
215  ITkStripID += offset * MaxChannelinStripRow;
216 
217  stripAlreadyEncoded++;
219  (stripAlreadyEncoded == stripToEncode), //last
220  chipID, //chip ID
221  ITkStripID, //strip ID
222  stripEncodingForITK.at(stripID), // cluster map
223  stripNumber, // id
224  0 // spare
225  );
226  stripNumber++;
227  // Push the word into the vector
228  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_STRIP_EF_RDO(stripWord));
229  }
230 
231  } // end for each RDO in the strip collection
232 
233  // reset the header
234  filledHeader = false;
235 
236  } // end for each strip RDO collection
237  // dump all RDO's and SDO's for a given event, for debugging purposes
238 
239  return StatusCode::SUCCESS;
240 }
241 
242 
243 // Helper function for common header and Footer info
244 StatusCode FPGADataFormatTool::fillHeader(std::vector<uint64_t> &encodedData) const
245 {
246  // Fill the event header
248  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_HDR_w1(header_w1));
249 
250  // Fill the event header
251  auto header_w2 = FPGADataFormatUtilites::fill_EVT_HDR_w2 (242000, 0);
252  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_HDR_w2(header_w2));
253 
254  // Fill the event header
255  auto header_w3 = FPGADataFormatUtilites::fill_EVT_HDR_w3 (0, 0);
256  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_HDR_w3(header_w3));
257 
258  return StatusCode::SUCCESS;
259 }
260 
261 StatusCode FPGADataFormatTool::fillFooter(std::vector<uint64_t> &encodedData) const
262 {
263  // Fill the event header
265  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_FTR_w1(footer_w1));
266 
267  // Fill the event header
268  auto footer_w2 = FPGADataFormatUtilites::fill_EVT_FTR_w2 (0);
269  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_FTR_w2(footer_w2));
270 
271  // Fill the event header
272  auto footer_w3 = FPGADataFormatUtilites::fill_EVT_FTR_w3 (encodedData.size(), 44939973);
273  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_EVT_FTR_w3(footer_w3));
274 
275  return StatusCode::SUCCESS;
276 }
277 
278 StatusCode FPGADataFormatTool::fillModuleHeader(const InDetDD::SiDetectorElement* sielement, std::vector<uint64_t> &encodedData) const
279 {
281  encodedData.push_back(FPGADataFormatUtilites::get_dataformat_M_HDR_w3(mod_w1));
282 
283  return StatusCode::SUCCESS;
284 }
FPGADataFormatUtilites::fill_EVT_FTR_w2
EVT_FTR_w2 fill_EVT_FTR_w2(const uint64_t error_flags)
Definition: FPGADataFormatUtilities.h:182
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
FPGADataFormatTool::fillFooter
StatusCode fillFooter(std::vector< uint64_t > &encodedData) const
Definition: FPGADataFormatTool.cxx:261
PixelID::phi_index
int phi_index(const Identifier &id) const
Definition: PixelID.h:658
FPGADataFormatTool::fillHeader
StatusCode fillHeader(std::vector< uint64_t > &encodedData) const
Definition: FPGADataFormatTool.cxx:244
InDetDD::SiDetectorManager::getDetectorElement
virtual SiDetectorElement * getDetectorElement(const Identifier &id) const =0
access to individual elements using Identifier or IdentiferHash
FPGADataFormatTool::convertPixelRDO
StatusCode convertPixelRDO(const PixelRDO_Container &pixelRDO, std::vector< uint64_t > &encodedData, const EventContext &ctx) const
Definition: FPGADataFormatTool.cxx:57
FPGADataFormatUtilites::EVT_HDR_FLAG
const int EVT_HDR_FLAG
Definition: FPGADataFormatUtilities.h:16
FPGADataFormatUtilites::get_dataformat_EVT_FTR_w3
uint64_t get_dataformat_EVT_FTR_w3(const EVT_FTR_w3 in)
Definition: FPGADataFormatUtilities.h:167
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
FPGADataFormatTool::initialize
virtual StatusCode initialize() override
Definition: FPGADataFormatTool.cxx:9
Identifier::get_identifier32
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
SCT_RDORawData
Definition: SCT_RDORawData.h:24
SCT_ID::barrel_ec
int barrel_ec(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: SCT_ID.h:728
FPGADataFormatTool::m_PIX_mgr
const InDetDD::SiDetectorManager * m_PIX_mgr
Definition: FPGADataFormatTool.h:47
FPGADataFormatUtilites::fill_EVT_HDR_w2
EVT_HDR_w2 fill_EVT_HDR_w2(const uint64_t &runnumber, const uint64_t &time)
Definition: FPGADataFormatUtilities.h:98
InDetRawDataContainer
Definition: InDetRawDataContainer.h:27
FPGADataFormatUtilites::get_dataformat_EVT_HDR_w1
uint64_t get_dataformat_EVT_HDR_w1(const EVT_HDR_w1 &in)
Definition: FPGADataFormatUtilities.h:66
FPGADataFormatUtilites::get_dataformat_STRIP_EF_RDO
uint64_t get_dataformat_STRIP_EF_RDO(const STRIP_EF_RDO in)
Definition: FPGADataFormatUtilities.h:316
Identifier32::get_compact
value_type get_compact() const
Get the compact id.
Definition: Identifier32.h:44
FPGADataFormatUtilites::fill_EVT_HDR_w1
EVT_HDR_w1 fill_EVT_HDR_w1(const uint64_t &flag, const uint64_t &l0id, const uint64_t &bcid, const uint64_t &spare)
Definition: FPGADataFormatUtilities.h:89
FPGADataFormatUtilites::fill_M_HDR_w3
M_HDR_w3 fill_M_HDR_w3(const uint64_t flag, const uint64_t modid, const uint64_t spare)
Definition: FPGADataFormatUtilities.h:224
FPGADataFormatUtilites::fill_PIXEL_EF_RDO
PIXEL_EF_RDO fill_PIXEL_EF_RDO(const uint64_t last, const uint64_t row, const uint64_t col, const uint64_t tot, const uint64_t lvl1, const uint64_t id, const uint64_t spare)
Definition: FPGADataFormatUtilities.h:295
FPGADataFormatTool::convertStripRDO
StatusCode convertStripRDO(const SCT_RDO_Container &stripRDO, std::vector< uint64_t > &encodedData, const EventContext &ctx) const
Definition: FPGADataFormatTool.cxx:109
FPGADataFormatUtilites::fill_EVT_FTR_w1
EVT_FTR_w1 fill_EVT_FTR_w1(const uint64_t flag, const uint64_t spare, const uint64_t hdr_crc)
Definition: FPGADataFormatUtilities.h:174
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
FPGADataFormatUtilites::get_dataformat_M_HDR_w3
uint64_t get_dataformat_M_HDR_w3(const M_HDR_w3 in)
Definition: FPGADataFormatUtilities.h:216
InDetRawDataCollection
Definition: InDetRawDataCollection.h:31
FPGADataFormatTool::fillModuleHeader
StatusCode fillModuleHeader(const InDetDD::SiDetectorElement *sielement, std::vector< uint64_t > &encodedData) const
Definition: FPGADataFormatTool.cxx:278
PixelID::eta_index
int eta_index(const Identifier &id) const
Definition: PixelID.h:664
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FPGADataFormatUtilities.h
FPGADataFormatUtilites::fill_EVT_FTR_w3
EVT_FTR_w3 fill_EVT_FTR_w3(const uint64_t word_count, const uint64_t crc)
Definition: FPGADataFormatUtilities.h:188
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
FPGADataFormatUtilites::fill_STRIP_EF_RDO
STRIP_EF_RDO fill_STRIP_EF_RDO(const uint64_t last, const uint64_t chipid, const uint64_t strip_num, const uint64_t cluster_map, const uint64_t id, const uint64_t spare)
Definition: FPGADataFormatUtilities.h:327
FPGADataFormatTool::m_pixelId
const PixelID * m_pixelId
Definition: FPGADataFormatTool.h:44
FPGADataFormatUtilites::get_dataformat_EVT_HDR_w2
uint64_t get_dataformat_EVT_HDR_w2(const EVT_HDR_w2 &in)
Definition: FPGADataFormatUtilities.h:75
FPGADataFormatUtilites::get_dataformat_PIXEL_EF_RDO
uint64_t get_dataformat_PIXEL_EF_RDO(const PIXEL_EF_RDO in)
Definition: FPGADataFormatUtilities.h:283
FPGADataFormatTool::convertStripHitsToFPGADataFormat
virtual StatusCode convertStripHitsToFPGADataFormat(const SCT_RDO_Container &stripRDO, std::vector< uint64_t > &encodedData, const EventContext &ctx) const override
Covert the Strip RDOs to the test vector format as requited by FPGA EF tracking alogrithms.
Definition: FPGADataFormatTool.cxx:38
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
FPGADataFormatTool::m_sctId
const SCT_ID * m_sctId
Definition: FPGADataFormatTool.h:45
FPGADataFormatUtilites::get_dataformat_EVT_FTR_w2
uint64_t get_dataformat_EVT_FTR_w2(const EVT_FTR_w2 in)
Definition: FPGADataFormatUtilities.h:161
FPGADataFormatTool.h
SCT_ID::strip
int strip(const Identifier &id) const
Definition: SCT_ID.h:764
FPGADataFormatUtilites::get_dataformat_EVT_HDR_w3
uint64_t get_dataformat_EVT_HDR_w3(const EVT_HDR_w3 &in)
Definition: FPGADataFormatUtilities.h:82
SCT_ID::eta_module
int eta_module(const Identifier &id) const
Definition: SCT_ID.h:746
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
PixelRDORawData
Definition: PixelRDORawData.h:23
FPGADataFormatUtilites::M_HDR_FLAG
const int M_HDR_FLAG
Definition: FPGADataFormatUtilities.h:197
FPGADataFormatTool::m_SCT_mgr
const InDetDD::SiDetectorManager * m_SCT_mgr
Definition: FPGADataFormatTool.h:48
FPGADataFormatUtilites::EVT_FTR_FLAG
const int EVT_FTR_FLAG
Definition: FPGADataFormatUtilities.h:114
FPGADataFormatTool::convertPixelHitsToFPGADataFormat
virtual StatusCode convertPixelHitsToFPGADataFormat(const PixelRDO_Container &pixelRDO, std::vector< uint64_t > &encodedData, const EventContext &ctx) const override
Covert the Pixel RDOs to the test vector format as requited by FPGA EF tracking alogrithms.
Definition: FPGADataFormatTool.cxx:20
FPGADataFormatUtilites::get_dataformat_EVT_FTR_w1
uint64_t get_dataformat_EVT_FTR_w1(const EVT_FTR_w1 in)
Definition: FPGADataFormatUtilities.h:153
FPGADataFormatUtilites::fill_EVT_HDR_w3
EVT_HDR_w3 fill_EVT_HDR_w3(const uint64_t &status, const uint64_t &crc)
Definition: FPGADataFormatUtilities.h:105
InDetDD::SolidStateDetectorElementBase::identify
virtual Identifier identify() const override final
identifier of this detector element (inline)
Identifier
Definition: IdentifierFieldParser.cxx:14