ATLAS Offline Software
Loading...
Searching...
No Matches
gFexByteStreamTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5//***************************************************************************
6// gFexByteStreamTool - description
7// -------------------
8// begin : 20 07 2022
9// email : cecilia.tosciri@cern.ch
10// ***************************************************************************/
11
12#include "gFexByteStreamTool.h"
14#include "eformat/SourceIdentifier.h"
15#include "eformat/Status.h"
16
17#include <span>
18
21
22namespace gPos = LVL1::gFEXPos;
23
25 const std::string& name,
26 const IInterface* parent)
27 : base_class(type, name, parent) {}
28
30 // Conversion mode for gRho TOBs
31 ATH_MSG_DEBUG(" ROB IDs: " << MSG::hex << m_robIds.value() << MSG::dec);
32
33 ConversionMode gRhomode = getConversionMode(m_gFexRhoReadKey, m_gFexRhoWriteKey, msg());
34 ATH_CHECK(gRhomode!=ConversionMode::Undefined);
35 ATH_CHECK(m_gFexRhoWriteKey.initialize(gRhomode==ConversionMode::Decoding));
36 ATH_CHECK(m_gFexRhoReadKey.initialize(gRhomode==ConversionMode::Encoding));
37 ATH_MSG_DEBUG((gRhomode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gRho ");
38
39 // Conversion mode for gSJ TOBs
40 ConversionMode gSJmode = getConversionMode(m_gFexBlockReadKey, m_gFexBlockWriteKey, msg());
41 ATH_CHECK(gSJmode!=ConversionMode::Undefined);
42 ATH_CHECK(m_gFexBlockWriteKey.initialize(gSJmode==ConversionMode::Decoding));
43 ATH_CHECK(m_gFexBlockReadKey.initialize(gSJmode==ConversionMode::Encoding));
44 ATH_MSG_DEBUG((gSJmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gSJ ");
45
46 // Conversion mode for gLJ TOBs
47 ConversionMode gLJmode = getConversionMode(m_gFexJetReadKey, m_gFexJetWriteKey, msg());
48 ATH_CHECK(gLJmode!=ConversionMode::Undefined);
49 ATH_CHECK(m_gFexJetWriteKey.initialize(gLJmode==ConversionMode::Decoding));
50 ATH_CHECK(m_gFexJetReadKey.initialize(gLJmode==ConversionMode::Encoding));
51 ATH_MSG_DEBUG((gLJmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gLJ ");
52
53 // Conversion mode for gScalarEJwoj TOBs
54 ConversionMode gScalarEJwojmode = getConversionMode(m_gScalarEJwojReadKey, m_gScalarEJwojWriteKey, msg());
55 ATH_CHECK(gScalarEJwojmode!=ConversionMode::Undefined);
56 ATH_CHECK(m_gScalarEJwojWriteKey.initialize(gScalarEJwojmode==ConversionMode::Decoding));
57 ATH_CHECK(m_gScalarEJwojReadKey.initialize(gScalarEJwojmode==ConversionMode::Encoding));
58 ATH_MSG_DEBUG((gScalarEJwojmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gScalarEJwoj ");
59
60 // Conversion mode for gEspresso TOBs
61 ConversionMode gEspressomode = getConversionMode(m_gEspressoReadKey, m_gEspressoWriteKey, msg());
62 ATH_CHECK(gEspressomode!=ConversionMode::Undefined);
63 ATH_CHECK(m_gEspressoWriteKey.initialize(gEspressomode==ConversionMode::Decoding));
64 ATH_CHECK(m_gEspressoReadKey.initialize(gEspressomode==ConversionMode::Encoding));
65 ATH_MSG_DEBUG((gEspressomode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gEspresso ");
66
67 // Conversion mode for gMETComponentsJwoj TOBs
68 ConversionMode gMETComponentsJwojmode = getConversionMode(m_gMETComponentsJwojReadKey, m_gMETComponentsJwojWriteKey, msg());
69 ATH_CHECK(gMETComponentsJwojmode!=ConversionMode::Undefined);
70 ATH_CHECK(m_gMETComponentsJwojWriteKey.initialize(gMETComponentsJwojmode==ConversionMode::Decoding));
71 ATH_CHECK(m_gMETComponentsJwojReadKey.initialize(gMETComponentsJwojmode==ConversionMode::Encoding));
72 ATH_MSG_DEBUG((gMETComponentsJwojmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gMETComponentsJwoj ");
73
74 // Conversion mode for gMHTComponentsJwoj TOBs
75 ConversionMode gMHTComponentsJwojmode = getConversionMode(m_gMHTComponentsJwojReadKey, m_gMHTComponentsJwojWriteKey, msg());
76 ATH_CHECK(gMHTComponentsJwojmode!=ConversionMode::Undefined);
77 ATH_CHECK(m_gMHTComponentsJwojWriteKey.initialize(gMHTComponentsJwojmode==ConversionMode::Decoding));
78 ATH_CHECK(m_gMHTComponentsJwojReadKey.initialize(gMHTComponentsJwojmode==ConversionMode::Encoding));
79 ATH_MSG_DEBUG((gMHTComponentsJwojmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gMHTComponentsJwoj ");
80
81 // Conversion mode for gMSTComponentsJwoj TOBs
82 ConversionMode gMSTComponentsJwojmode = getConversionMode(m_gMSTComponentsJwojReadKey, m_gMSTComponentsJwojWriteKey, msg());
83 ATH_CHECK(gMSTComponentsJwojmode!=ConversionMode::Undefined);
84 ATH_CHECK(m_gMSTComponentsJwojWriteKey.initialize(gMSTComponentsJwojmode==ConversionMode::Decoding));
85 ATH_CHECK(m_gMSTComponentsJwojReadKey.initialize(gMSTComponentsJwojmode==ConversionMode::Encoding));
86 ATH_MSG_DEBUG((gMSTComponentsJwojmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gMSTComponentsJwoj ");
87
88 // Conversion mode for gMETComponentsNoiseCut TOBs
89 ConversionMode gMETComponentsNoiseCutmode = getConversionMode(m_gMETComponentsNoiseCutReadKey, m_gMETComponentsNoiseCutWriteKey, msg());
90 ATH_CHECK(gMETComponentsNoiseCutmode!=ConversionMode::Undefined);
91 ATH_CHECK(m_gMETComponentsNoiseCutWriteKey.initialize(gMETComponentsNoiseCutmode==ConversionMode::Decoding));
92 ATH_CHECK(m_gMETComponentsNoiseCutReadKey.initialize(gMETComponentsNoiseCutmode==ConversionMode::Encoding));
93 ATH_MSG_DEBUG((gMETComponentsNoiseCutmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gMETComponentsNoiseCut ");
94
95 // Conversion mode for gMETRms TOBs
96 ConversionMode gMETComponentsRmsmode = getConversionMode(m_gMETComponentsRmsReadKey, m_gMETComponentsRmsWriteKey, msg());
97 ATH_CHECK(gMETComponentsRmsmode!=ConversionMode::Undefined);
98 ATH_CHECK(m_gMETComponentsRmsWriteKey.initialize(gMETComponentsRmsmode==ConversionMode::Decoding));
99 ATH_CHECK(m_gMETComponentsRmsReadKey.initialize(gMETComponentsRmsmode==ConversionMode::Encoding));
100 ATH_MSG_DEBUG((gMETComponentsRmsmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gMETComponentsRms ");
101
102 // Conversion mode for gScalarENoiseCut TOBs
103 ConversionMode gScalarENoiseCutmode = getConversionMode(m_gScalarENoiseCutReadKey, m_gScalarENoiseCutWriteKey, msg());
104 ATH_CHECK(gScalarENoiseCutmode!=ConversionMode::Undefined);
105 ATH_CHECK(m_gScalarENoiseCutWriteKey.initialize(gScalarENoiseCutmode==ConversionMode::Decoding));
106 ATH_CHECK(m_gScalarENoiseCutReadKey.initialize(gScalarENoiseCutmode==ConversionMode::Encoding));
107 ATH_MSG_DEBUG((gScalarENoiseCutmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gScalarENoiseCut ");
108
109 // Conversion mode for gScalarERms TOBs
110 ConversionMode gScalarERmsmode = getConversionMode(m_gScalarERmsReadKey, m_gScalarERmsWriteKey, msg());
111 ATH_CHECK(gScalarERmsmode!=ConversionMode::Undefined);
112 ATH_CHECK(m_gScalarERmsWriteKey.initialize(gScalarERmsmode==ConversionMode::Decoding));
113 ATH_CHECK(m_gScalarERmsReadKey.initialize(gScalarERmsmode==ConversionMode::Encoding));
114 ATH_MSG_DEBUG((gScalarERmsmode==ConversionMode::Encoding ? "Encoding" : "Decoding") << " gScalarERms ");
115
116 //checking all Conversion modes.. avoid misconfigurations
117 const std::array<ConversionMode,2> modes{gSJmode,gLJmode};
118 if (std::any_of(modes.begin(),modes.end(),[&gRhomode](ConversionMode m) { return m!=gRhomode; } )) {
119 ATH_MSG_ERROR("Inconsistent conversion modes");
120 return StatusCode::FAILURE;
121 }
122
123 ATH_CHECK(m_l1MenuKey.initialize());
124
125 if (!m_monTool.empty()) {
126 ATH_CHECK(m_monTool.retrieve());
127 ATH_MSG_INFO("Logging errors to " << m_monTool.name() << " monitoring tool");
128 m_UseMonitoring = true;
129 }
130
131
132 return StatusCode::SUCCESS;
133}
134
136 // Retrieve the L1 menu configuration
138 ATH_CHECK(l1Menu.isValid());
139
140 try {
141 const auto & l1Menu_gJ = l1Menu->thrExtraInfo().gJ();
142 const auto & l1Menu_gLJ = l1Menu->thrExtraInfo().gLJ();
143 const auto & l1Menu_gXE = l1Menu->thrExtraInfo().gXE();
144 const auto & l1Menu_gTE = l1Menu->thrExtraInfo().gTE();
145
146 ATH_CHECK(l1Menu_gJ.isValid());
147 ATH_CHECK(l1Menu_gLJ.isValid());
148 ATH_CHECK(l1Menu_gXE.isValid());
149 ATH_CHECK(l1Menu_gTE.isValid());
150
151 m_gJ_scale = l1Menu_gJ.resolutionMeV();
152 m_gLJ_scale = l1Menu_gLJ.resolutionMeV();
153 m_gXE_scale = l1Menu_gXE.resolutionMeV();
154 m_gTE_scale = l1Menu_gTE.resolutionMeV();
155 } catch (const std::exception& e) {
156 ATH_MSG_ERROR("Exception reading L1Menu: " << e.what());
157 return StatusCode::FAILURE;
158 }
159
160 return StatusCode::SUCCESS;
161
162}
163
164// BS->xAOD conversion
165StatusCode gFexByteStreamTool::convertFromBS(const std::vector<const ROBF*>& vrobf, const EventContext& ctx) const {
166
167 //WriteHandle for gFEX EDMs
168
169 //---Rho Container
171 ATH_CHECK(gRhoContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
172 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gRhoContainer.key());
173
174 //---Small Jets Container
176 ATH_CHECK(gSJContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
177 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gSJContainer.key());
178
179 //---Large Jets Container
181 ATH_CHECK(gLJContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
182 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gLJContainer.key());
183
184 //---Scalar MET and SumET JwoJ Container
186 ATH_CHECK(gScalarEJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
187 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarEJwojContainer.key());
188
189 //---gEspresso Container
191 ATH_CHECK(gEspressoContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
192 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gEspressoContainer.key());
193
194 //---MET Components JwoJ Container
196 ATH_CHECK(gMETComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
197 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsJwojContainer.key());
198
199 //---MHT Components JwoJ Container
201 ATH_CHECK(gMHTComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
202 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMHTComponentsJwojContainer.key());
203
204 //---MST Components JwoJ Container
206 ATH_CHECK(gMSTComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
207 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMSTComponentsJwojContainer.key());
208
209 //---MET Components NoiseCut Container
211 ATH_CHECK(gMETComponentsNoiseCutContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
212 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsNoiseCutContainer.key());
213
214 //---MET Components Rms Container
216 ATH_CHECK(gMETComponentsRmsContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
217 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsRmsContainer.key());
218
219 //---Scalar MET and SumET NoiseCut Container
221 ATH_CHECK(gScalarENoiseCutContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
222 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarENoiseCutContainer.key());
223
224 //---Scalar MET and SumET Rms Container
226 ATH_CHECK(gScalarERmsContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
227 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarERmsContainer.key());
228
229
230 // Iterate over ROBFragments to decode
231 for (const ROBF* rob : vrobf) {
232 // Iterate over ROD words and decode
233
234
235 ATH_MSG_DEBUG("Starting to decode " << rob->rod_ndata() << " ROD words from ROB 0x" << std::hex << rob->rob_source_id());
236
237 //There is no data to decode.. not even the ROD trailers
238 if(rob->rod_ndata() <= 0){
239 continue;
240 }
241
242 const auto dataArray = std::span{rob->rod_data(), rob->rod_ndata()};
243
244
245 // Starting to loop over the gFEX words
246
247 unsigned int n_words = rob->rod_ndata();
248
249 //saving Jet TOBs into the EDM container
250 for(unsigned int iWord=0; iWord<n_words; iWord++) {
251 ATH_MSG_DEBUG("Raw word 0x" << std::hex << dataArray[iWord] << " " << std::bitset<32> (dataArray[iWord]));
252 }
253
254 // Vectors to temporarily store global tob before their are summed together
255 int global_counter = 0;
256 std::vector<uint32_t> JWOJ_MHT(3, 0);
257 std::vector<uint32_t> JWOJ_MST(3, 0);
258 std::vector<uint32_t> JWOJ_MET(3, 0);
259 std::vector<uint32_t> JWOJ_SCALAR(3, 0);
260 std::vector<uint32_t> GESPRESSO(3, 0);
261 std::vector<uint32_t> NC_MET(3, 0);
262 std::vector<uint32_t> NC_SCALAR(3, 0);
263 std::vector<uint32_t> RMS_MET(3, 0);
264 std::vector<uint32_t> RMS_SCALAR(3, 0);
265
266 size_t index = 0;
267 while ( index < n_words ) {
268 const uint32_t headerWord = dataArray[index];//Identify the header words. The first is a header word.
269 const uint32_t blockType = (headerWord >> gPos::BLOCK_TYPE_BIT) & gPos::BLOCK_TYPE_MASK;
270 const uint32_t headerSize = (headerWord >> gPos::HEADER_SIZE_BIT) & gPos::HEADER_SIZE_MASK;
271 const uint32_t errorFlags = (headerWord >> gPos::ERROR_FLAG_BIT) & gPos::ERROR_FLAG_MASK;
272 const uint32_t dataSize = headerWord & gPos::DATA_SIZE_MASK;
273
274 ATH_MSG_DEBUG( "index "<< index );
275 ATH_MSG_DEBUG( "word "<< std::bitset<32> (dataArray[index]) );
276 ATH_MSG_DEBUG( "headerWord "<< std::bitset<32> (headerWord) );
277 ATH_MSG_DEBUG( "blockType "<< std::bitset<4> (blockType) );
278 ATH_MSG_DEBUG( "headerSize "<< std::bitset<2> (headerSize) );
279 ATH_MSG_DEBUG( "errorFlags "<< std::bitset<1> (errorFlags) );
280 ATH_MSG_DEBUG( "dataSize "<< std::bitset<12> (dataSize) );
281
282 const uint32_t blockSize = headerSize + dataSize;
283 if ( (index + blockSize) > n_words ) {
284
285 std::stringstream sdetail;
286 sdetail << "Remaining block size " << (n_words - index) << " is too small for subblock of type " << blockType << " with headerSize " << headerSize << " and dataSize " << dataSize ;
287 std::stringstream slocation;
288 slocation << "0x"<< std::hex << rob->rob_source_id() << std::dec << " type:"<<blockType;
289 std::stringstream stitle;
290 stitle << "Small subblock size " ;
291 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
292
293 }
294
295 index += headerSize;
296
297 const uint32_t numSlices = dataSize / gPos::WORDS_PER_SLICE;
298 ATH_MSG_DEBUG( "numSlices " << numSlices );
299
300 if ( numSlices * gPos::WORDS_PER_SLICE != dataSize ) {
301
302 std::stringstream sdetail;
303 sdetail << "L1CaloBsDecoderRun3::decodeGfexTobs: subblock type " << blockType << " with dataSize " << dataSize << " is not a multiple of " << gPos::WORDS_PER_SLICE << " words" ;
304 std::stringstream slocation;
305 slocation << "0x"<< std::hex << rob->rob_source_id()<< std::dec << " type:"<<blockType;
306 std::stringstream stitle;
307 stitle << "Wrong dataSize" ;
308 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
309
310 //skip decode of this fragment
311 index+=dataSize;
312 continue;
313
314 }
315
316 // The subblock type is 0xA,B,C for jet TOBs from FPGA A,B,C
317 // and 0x1,2,3 for global (MET) TOBs.
318 bool isMet = (blockType >= 0x1 && blockType <= 0x3);
319 bool isJet = (blockType >= 0xA && blockType <= 0xC);
320
321
322 for (uint32_t sliceNumber = 0; sliceNumber < numSlices; sliceNumber++) {
323 if (sliceNumber == 0){
324 if ( !isJet && !isMet ) {
325
326 std::stringstream sdetail;
327 sdetail << "gFexByteStreamTool::decodeGfexTobSlice: Invalid block type " << blockType ;
328 std::stringstream slocation;
329 slocation << "0x"<< std::hex << rob->rob_source_id();
330 std::stringstream stitle;
331 stitle << "Invalid block type" ;
332 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
333
334 }
335
336 for(unsigned int iWord=0; iWord<gPos::WORDS_PER_SLICE; iWord++) {
337
338 if (isJet) {
339 //Skipping the unused words
340 if (std::find(gPos::JET_UNUSED_POSITION.begin(),gPos::JET_UNUSED_POSITION.end(),iWord)!=gPos::JET_UNUSED_POSITION.end()){
341 continue;
342 }
343 //Skipping the trailer words
344 if (std::find(gPos::TRAILER_POSITION.begin(),gPos::TRAILER_POSITION.end(),iWord)!=gPos::TRAILER_POSITION.end()){
345 continue;
346 }
347 //Saving gRho TOBs into the EDM container
348 if (iWord == gPos::GRHO_POSITION){
349 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
350 gRhoContainer->push_back(std::move(myEDM));
351 gRhoContainer->back()->initialize(dataArray[index+iWord], m_gJ_scale);
352 }
353 //Saving gBlock TOBs into the EDM container
354 if (std::find(gPos::GBLOCK_POSITION.begin(),gPos::GBLOCK_POSITION.end(),iWord)!=gPos::GBLOCK_POSITION.end()){
355 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
356 gSJContainer->push_back(std::move(myEDM));
357 gSJContainer->back()->initialize(dataArray[index+iWord], m_gJ_scale);
358 }
359 //Saving gJet TOBs into the EDM container
360 if (std::find(gPos::GJET_POSITION.begin(),gPos::GJET_POSITION.end(),iWord)!=gPos::GJET_POSITION.end()){
361 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
362 gLJContainer->push_back(std::move(myEDM));
363 gLJContainer->back()->initialize(dataArray[index+iWord], m_gLJ_scale);
364 }
365
366 }
367
368 if (isMet){
369 //Skipping the unused words
371 continue;
372 }
373 //Skipping the trailer words
374 if (std::find(gPos::TRAILER_POSITION.begin(),gPos::TRAILER_POSITION.end(),iWord)!=gPos::TRAILER_POSITION.end()){
375 continue;
376 }
377 //Saving jwoj MHT TOBs into the EDM container
378 if (iWord == gPos::JWOJ_MHT_POSITION){
379 global_counter ++;
380 if (blockType == 0x1) {JWOJ_MHT[0] = dataArray[index+iWord];}
381 if (blockType == 0x2) {JWOJ_MHT[1] = dataArray[index+iWord];}
382 if (blockType == 0x3) {JWOJ_MHT[2] = dataArray[index+iWord];}
383 }
384 //Saving jwoj MST TOBs into the EDM container
385 if (iWord == gPos::JWOJ_MST_POSITION){
386 if (blockType == 0x1) {JWOJ_MST[0] = dataArray[index+iWord];}
387 if (blockType == 0x2) {JWOJ_MST[1] = dataArray[index+iWord];}
388 if (blockType == 0x3) {JWOJ_MST[2] = dataArray[index+iWord];}
389 }
390 //Saving jwoj MET TOBs into the EDM container
391 if (iWord == gPos::JWOJ_MET_POSITION){
392 if (blockType == 0x1) {JWOJ_MET[0] = dataArray[index+iWord];}
393 if (blockType == 0x2) {JWOJ_MET[1] = dataArray[index+iWord];}
394 if (blockType == 0x3) {JWOJ_MET[2] = dataArray[index+iWord];}
395 }
396 //Saving jwoj Scalar TOBs into the EDM container
397 if (iWord == gPos::JWOJ_SCALAR_POSITION){
398 if (blockType == 0x1) {JWOJ_SCALAR[0] = dataArray[index+iWord];}
399 if (blockType == 0x2) {JWOJ_SCALAR[1] = dataArray[index+iWord];}
400 if (blockType == 0x3) {JWOJ_SCALAR[2] = dataArray[index+iWord];}
401 }
402 //Saving gEspresso TOBs into the EDM container
403 if (iWord == gPos::GESPRESSO_POSITION){
404 if (blockType == 0x1) {GESPRESSO[0] = dataArray[index+iWord];}
405 if (blockType == 0x2) {GESPRESSO[1] = dataArray[index+iWord];}
406 if (blockType == 0x3) {GESPRESSO[2] = dataArray[index+iWord];}
407 }
408 //Saving Noise Cut MET TOBs into the EDM container
409 if (iWord == gPos::NC_MET_POSITION){
410 if (blockType == 0x1) {NC_MET[0] = dataArray[index+iWord];}
411 if (blockType == 0x2) {NC_MET[1] = dataArray[index+iWord];}
412 if (blockType == 0x3) {NC_MET[2] = dataArray[index+iWord];}
413 }
414 //Saving Noise Cut Scalar TOBs into the EDM container
415 if (iWord == gPos::NC_SCALAR_POSITION){
416 if (blockType == 0x1) {NC_SCALAR[0] = dataArray[index+iWord];}
417 if (blockType == 0x2) {NC_SCALAR[1] = dataArray[index+iWord];}
418 if (blockType == 0x3) {NC_SCALAR[2] = dataArray[index+iWord];}
419 }
420 //Saving Rho+RMS MET TOBs into the EDM container
421 if (iWord == gPos::RMS_MET_POSITION){
422 if (blockType == 0x1) {RMS_MET[0] = dataArray[index+iWord];}
423 if (blockType == 0x2) {RMS_MET[1] = dataArray[index+iWord];}
424 if (blockType == 0x3) {RMS_MET[2] = dataArray[index+iWord];}
425 }
426 //Saving Rho+RMS Scalar TOBs into the EDM container
427 if (iWord == gPos::RMS_SCALAR_POSITION){
428 if (blockType == 0x1) {RMS_SCALAR[0] = dataArray[index+iWord];}
429 if (blockType == 0x2) {RMS_SCALAR[1] = dataArray[index+iWord];}
430 if (blockType == 0x3) {RMS_SCALAR[2] = dataArray[index+iWord];}
431 }
432
433 }
434
435 }
436
437 }
439 }
440
441 ATH_MSG_DEBUG("global_counter is " << global_counter);
442 if (global_counter == 3) {
443
444 fillGlobal(JWOJ_MHT, 3, gMHTComponentsJwojContainer);
445 fillGlobal(JWOJ_MST, 4, gMSTComponentsJwojContainer);
446 int16_t scalar = fillGlobal(JWOJ_MET, 2, gMETComponentsJwojContainer);
447 fillGlobal(JWOJ_SCALAR, 1, gScalarEJwojContainer, scalar);
448
449 fillGlobal(GESPRESSO, 1, gEspressoContainer, 0);
450
451 scalar = fillGlobal(NC_MET, 2, gMETComponentsNoiseCutContainer);
452 fillGlobal(NC_SCALAR, 1, gScalarENoiseCutContainer, scalar);
453
454 scalar = fillGlobal(RMS_MET, 2, gMETComponentsRmsContainer);
455 fillGlobal(RMS_SCALAR, 1, gScalarERmsContainer, scalar);
456
457 global_counter = 0;
458 }
459
460 }
461 }
462 return StatusCode::SUCCESS;
463}
464
465// For MHT, MST, and MET, it sums the x and y components across FPGAs, and also returnes
466// the sum in quadrature (which is actually only used for MET, and discared for MHT and MST)
467// This function also accepts "scalar" as optional variable, which is used to fill the X
468// component of the SCALAR tob.
469int16_t gFexByteStreamTool::fillGlobal(const std::vector<uint32_t> &tob, const int type,
471 int16_t scalar/* = -1*/) const {
472
473 ATH_MSG_DEBUG("fillGlobal with type " << type);
474
475 // 32 bit integers to avoid interim overflows when summing 16b (signed)
476 // quantities from each pFPGA. Proper clamping and bit masking follows afterwards
477 int32_t sum_x = 0;
478 int32_t sum_y = 0;
479
480 // Extract the x and y components and sum them for the three FPGAs
481 for (size_t fpga = 0; fpga < 3; fpga++) {
482 int16_t x = tob[fpga] >> gPos::GLOBAL_X_BIT & gPos::GLOBAL_X_MASK;
483 int16_t y = tob[fpga] >> gPos::GLOBAL_Y_BIT & gPos::GLOBAL_Y_MASK;
484 if (x & 0x00080000) { x = 0xFFFF0000 | x; }
485 if (y & 0x00080000) { y = 0xFFFF0000 | y; }
486 sum_x += x;
487 if (container.key() == "L1_gScalarEJwoj" && y < 0) y = 0;
488 sum_y += y;
489 }
490
491 // Special case for gEspresso: in the readout the gEspresso quantity is stored in x. We need to move it to y to armonize this with the other scalar quantities
492 // This is true for the readout only. On the realtime path gEspresso is sent to Topo on y (see https://docs.google.com/spreadsheets/d/15YVVtGofhXMtV7jXRFzWO0FVUtUAjS-X-aQjh3FKE_w/edit?gid=1546010783#gid=1546010783).
493 if (container.key() == "L1_gEspresso" ) {
494 sum_y = sum_x;
495 }
496
497 if (type == 1) {//we are considering the scalar case (sum_x = MET and sum_y = SumEt)
498 ATH_MSG_DEBUG(" scalar tob, saving " << scalar << " in X component");
499 sum_x = scalar; //Total MET
500 if( sum_y > 0x000FFF) sum_y = 0x000FFF; //Overflow control for SumEt
501 if( sum_y < 0) sum_y = 0;
502
503 } else {
504 if (sum_x < -0x000800) sum_x = -0x000800; //-2048
505 if (sum_x > 0x0007FF) sum_x = 0x0007FF; //2047
506
507 if (sum_y < -0x000800) sum_y = -0x000800; //-2048
508 if (sum_y > 0x0007FF) sum_y = 0x0007FF; //2047
509 }
510
511 ATH_MSG_DEBUG(" fillGlobal type " << type << std::dec << " sum_x " << sum_x << " sum_y " << sum_y);
512
513 uint32_t METword = 0;
514
515 METword = (sum_y & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
516 METword = METword | (sum_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
517 if (sum_y != 0) METword = METword | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
518 if (sum_x != 0) METword = METword | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
519 METword = METword | (type & 0x0000001F) << 26;//TOB ID (5 bits starting at 26)
520
521 // Save to the EDM
522 std::unique_ptr<xAOD::gFexGlobalRoI> myEDM (new xAOD::gFexGlobalRoI());
523 container->push_back(std::move(myEDM));
524 container->back()->setWord(METword);
525 container->back()->setQuantityOne(sum_x);
526 container->back()->setQuantityTwo(sum_y);
527 container->back()->setScaleOne(m_gXE_scale);
528 container->back()->setScaleTwo(m_gTE_scale);
529 container->back()->setStatusOne(1);
530 container->back()->setStatusTwo(1);
531 container->back()->setSaturated(0);
532 container->back()->setGlobalType(type);
533
534
535 int MET2 = sum_x * sum_x + sum_y * sum_y;
536 int16_t MET = std::sqrt(MET2);
537 if (MET > 0x000FFF) MET = 0x000FFF;
538
539 return MET;
540
541}
542
543
545StatusCode gFexByteStreamTool::convertToBS(std::vector<WROBF*>& /*vrobf*/, const EventContext& /*eventContext*/) {
546
547 return StatusCode::SUCCESS;
548
549}
550
551
552void gFexByteStreamTool::printError(const std::string& location, const std::string& title, MSG::Level type, const std::string& detail) const{
553
554 if(m_UseMonitoring){
556 Monitored::Scalar("gfexDecoderErrorLocation",location.empty() ? std::string("UNKNOWN") : location),
557 Monitored::Scalar("gfexDecoderErrorTitle" ,title.empty() ? std::string("UNKNOWN") : title)
558 );
559 }
560 else {
561 msg() << type << detail << endmsg;
562 }
563}
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment ROBF
void printError()
#define y
#define x
Group of local monitoring quantities and retain correlation when filling histograms
Declare a monitored scalar variable.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsRmsWriteKey
virtual StatusCode start() override
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsNoiseCutWriteKey
SG::ReadHandleKey< xAOD::gFexJetRoIContainer > m_gFexRhoReadKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gMHTComponentsJwojReadKey
virtual StatusCode initialize() override
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarEJwojReadKey
virtual StatusCode convertFromBS(const std::vector< const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment * > &vrobf, const EventContext &eventContext) const override
BS->xAOD conversion.
gFexByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
SG::ReadHandleKey< TrigConf::L1Menu > m_l1MenuKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsJwojReadKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsNoiseCutReadKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMSTComponentsJwojWriteKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarERmsReadKey
ToolHandle< GenericMonitoringTool > m_monTool
void printError(const std::string &location, const std::string &title, MSG::Level type, const std::string &detail) const
SG::ReadHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetReadKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMHTComponentsJwojWriteKey
int16_t fillGlobal(const std::vector< uint32_t > &tob, const int type, SG::WriteHandle< xAOD::gFexGlobalRoIContainer > &container, int16_t scalar=-1) const
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarENoiseCutWriteKey
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const EventContext &eventContext) override
xAOD->BS conversion
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gEspressoReadKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsJwojWriteKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsRmsReadKey
SG::ReadHandleKey< xAOD::gFexJetRoIContainer > m_gFexBlockReadKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarEJwojWriteKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gMSTComponentsJwojReadKey
Gaudi::Property< std::vector< uint32_t > > m_robIds
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gEspressoWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetWriteKey
SG::ReadHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarENoiseCutReadKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexBlockWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarERmsWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexRhoWriteKey
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment WROBF
constexpr unsigned int WORDS_PER_SLICE
Definition gFexPos.h:22
constexpr std::array< unsigned int, 4 > GBLOCK_POSITION
Definition gFexPos.h:31
constexpr unsigned int GLOBAL_Y_MASK
Definition gFexPos.h:48
constexpr unsigned int BLOCK_TYPE_BIT
Definition gFexPos.h:14
constexpr std::array< unsigned int, 2 > GJET_POSITION
Definition gFexPos.h:32
constexpr unsigned int DATA_SIZE_MASK
Definition gFexPos.h:20
constexpr unsigned int JWOJ_MHT_POSITION
Definition gFexPos.h:35
constexpr unsigned int GESPRESSO_POSITION
Definition gFexPos.h:39
constexpr unsigned int RMS_MET_POSITION
Definition gFexPos.h:44
constexpr unsigned int NC_SCALAR_POSITION
Definition gFexPos.h:42
constexpr unsigned int GLOBAL_X_MASK
Definition gFexPos.h:47
constexpr std::array< unsigned int, 4 > GLOBAL_UNUSED_POSITION
Definition gFexPos.h:29
constexpr unsigned int BLOCK_TYPE_MASK
Definition gFexPos.h:15
constexpr unsigned int ERROR_FLAG_BIT
Definition gFexPos.h:18
constexpr std::array< unsigned int, 2 > TRAILER_POSITION
Definition gFexPos.h:27
constexpr unsigned int GLOBAL_Y_BIT
Definition gFexPos.h:50
constexpr unsigned int HEADER_SIZE_MASK
Definition gFexPos.h:17
constexpr unsigned int NC_MET_POSITION
Definition gFexPos.h:41
constexpr unsigned int HEADER_SIZE_BIT
Definition gFexPos.h:16
constexpr unsigned int ERROR_FLAG_MASK
Definition gFexPos.h:19
constexpr std::array< unsigned int, 5 > JET_UNUSED_POSITION
Definition gFexPos.h:28
constexpr unsigned int GRHO_POSITION
Definition gFexPos.h:33
constexpr unsigned int JWOJ_SCALAR_POSITION
Definition gFexPos.h:38
constexpr unsigned int JWOJ_MST_POSITION
Definition gFexPos.h:36
constexpr unsigned int RMS_SCALAR_POSITION
Definition gFexPos.h:45
constexpr unsigned int JWOJ_MET_POSITION
Definition gFexPos.h:37
constexpr unsigned int GLOBAL_X_BIT
Definition gFexPos.h:49
Definition MET.py:1
eformat::write::ROBFragment ROBFragment
Definition RawEvent.h:33
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27
Definition index.py:1
gFexJetRoI_v1 gFexJetRoI
Define the latest version of the gFexJetRoI class.
Definition gFexJetRoI.h:16
gFexGlobalRoI_v1 gFexGlobalRoI
Define the latest version of the eFexEMRoI class.
MsgStream & msg
Definition testRead.cxx:32