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"
17
18#include <span>
19
22
23namespace gPos = LVL1::gFEXPos;
24
25namespace {
26 // std::less<> (transparent comparator) enables heterogeneous lookup, so the
27 // encoder can pass string_view / string literals to find() without
28 // constructing a temporary std::string at every call site.
29 template<typename ContT>
30 using NamedContainerMap = std::map<std::string, const ContT*, std::less<>>;
31
32 // Index every container of type ContT inside the TrigComposite by its link name,
33 // so the encoder can look up gRho / gBlock / gJet (all gFexJetRoIContainer) and
34 // the 10 Global containers (all gFexGlobalRoIContainer) by their L1_* SG name.
35 template<typename ContT>
36 NamedContainerMap<ContT> indexByName(const xAOD::TrigComposite& l1) {
37 NamedContainerMap<ContT> out;
38 for (const std::string& name : l1.getObjectNames<ContT>()) {
39 auto link = l1.objectLink<ContT>(name);
40 if (!link.isValid()) continue;
41 if (const ContT* c = link.getStorableObjectPointer()) out[name] = c;
42 }
43 return out;
44 }
45
46 // Return the i-th entry's word() from a named container, or 0 if missing/out-of-range.
47 template<typename ContT>
48 uint32_t wordAtOrZero(const NamedContainerMap<ContT>& m,
49 std::string_view name, size_t idx) {
50 auto it = m.find(name);
51 if (it == m.end() || !it->second || idx >= it->second->size()) return 0u;
52 return it->second->at(idx)->word();
53 }
54
55 // Convenience for Global containers, which carry a single TOB per slice.
56 template<typename ContT>
57 uint32_t firstWord(const NamedContainerMap<ContT>& m, std::string_view name) {
58 return wordAtOrZero(m, name, 0);
59 }
60
61 // Repack gFexGlobalRoI::word() (decoder's METword: sum_y in bits 0-11,
62 // sum_x in bits 12-23, status/type in bits 24-30) into the per-FPGA TOB
63 // layout the decoder's fillGlobal() expects on re-read (Y in bits 0-15,
64 // X in bits 16-31). The whole value goes on FPGA-A; FPGA-B/C stay 0 so
65 // the decoder's per-FPGA sum reproduces sum_x / sum_y.
66 //
67 // `signed12bit` controls sign extension of the 12-bit fields:
68 // true for vector-component containers (METx/y, MHTx/y, MSTx/y) where
69 // the value is signed in [-2048, 2047]
70 // false for scalar-energy containers (SCALAR EJwoJ, Espresso, Ristretto,
71 // NoiseCut/Rms Scalar) where the decoder stores an unsigned value
72 // in [0, 4095]; sign-extending here would flip values >= 2048 to
73 // negative and the SCALAR decoder branch then force-zeroes them.
74 uint32_t globalRoIWordToPerFpgaTob(uint32_t metWord, bool signed12bit) {
75 int16_t y = static_cast<int16_t>(metWord & 0xFFF);
76 if (signed12bit && (y & 0x800)) y |= 0xF000; // sign-extend 12→16
77 int16_t x = static_cast<int16_t>((metWord >> 12) & 0xFFF);
78 if (signed12bit && (x & 0x800)) x |= 0xF000;
79 return (static_cast<uint32_t>(static_cast<uint16_t>(x)) << 16)
80 | static_cast<uint32_t>(static_cast<uint16_t>(y));
81 }
82}
83
85 const std::string& name,
86 const IInterface* parent)
87 : base_class(type, name, parent) {}
88
90
91 ATH_MSG_DEBUG(" ROB IDs: " << MSG::hex << m_robIds.value() << MSG::dec);
92
93 // Decoder write keys (BS->xAOD); each one is initialised only if configured.
94 // xAOD->BS mode now consumes RoIs from the TrigCompositeContainer passed to
95 // convertToBS(), so no ReadHandleKey/ConversionMode bookkeeping is needed.
109
110 // Initialize multi-slice write handle keys (only if configured with non-empty key)
124
125 // Initialize slice number decoration keys for out-of-time containers.
126 // Multi-slice mode is activated based on m_gFexJetSliceWriteKey being non-empty,
127 // so all decoration keys are initialized based on that same condition.
128 // When multi-slice mode is enabled, all OOT container keys must be configured together.
142
143 ATH_CHECK(m_l1MenuKey.initialize());
144
145 if (!m_monTool.empty()) {
146 ATH_CHECK(m_monTool.retrieve());
147 ATH_MSG_INFO("Logging errors to " << m_monTool.name() << " monitoring tool");
148 m_UseMonitoring = true;
149 }
150
151
152 return StatusCode::SUCCESS;
153}
154
156 // Retrieve the L1 menu configuration
158 ATH_CHECK(l1Menu.isValid());
159
160 try {
161 const auto & l1Menu_gJ = l1Menu->thrExtraInfo().gJ();
162 const auto & l1Menu_gLJ = l1Menu->thrExtraInfo().gLJ();
163 const auto & l1Menu_gXE = l1Menu->thrExtraInfo().gXE();
164 const auto & l1Menu_gTE = l1Menu->thrExtraInfo().gTE();
165
166 ATH_CHECK(l1Menu_gJ.isValid());
167 ATH_CHECK(l1Menu_gLJ.isValid());
168 ATH_CHECK(l1Menu_gXE.isValid());
169 ATH_CHECK(l1Menu_gTE.isValid());
170
171 m_gJ_scale = l1Menu_gJ.resolutionMeV();
172 m_gLJ_scale = l1Menu_gLJ.resolutionMeV();
173 m_gXE_scale = l1Menu_gXE.resolutionMeV();
174 m_gTE_scale = l1Menu_gTE.resolutionMeV();
175 } catch (const std::exception& e) {
176 ATH_MSG_ERROR("Exception reading L1Menu: " << e.what());
177 return StatusCode::FAILURE;
178 }
179
180 return StatusCode::SUCCESS;
181
182}
183
184// BS->xAOD conversion
185StatusCode gFexByteStreamTool::convertFromBS(const std::vector<const ROBF*>& vrobf, const EventContext& ctx) const {
186
187 //WriteHandle for gFEX EDMs
188
189 // Check if standard L1A containers should be decoded (TOBs=True mode)
190 // or are disabled (TOBs=False mode, standard containers come from HLT result)
191 const bool decodeStdTOBs = !m_gFexRhoWriteKey.key().empty();
192
193 //---Standard L1A TOB containers (only created and recorded when decodeStdTOBs is true)
198 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsJwojContainer;
199 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMHTComponentsJwojContainer;
200 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMSTComponentsJwojContainer;
201 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsNoiseCutContainer;
202 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsRmsContainer;
203 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gScalarENoiseCutContainer;
205
206 if (decodeStdTOBs) {
218
219 ATH_CHECK(gRhoContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
220 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gRhoContainer.key());
221 ATH_CHECK(gSJContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
222 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gSJContainer.key());
223 ATH_CHECK(gLJContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
224 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer with key " << gLJContainer.key());
225 ATH_CHECK(gScalarEJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
226 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarEJwojContainer.key());
227 ATH_CHECK(gMETComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
228 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsJwojContainer.key());
229 ATH_CHECK(gMHTComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
230 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMHTComponentsJwojContainer.key());
231 ATH_CHECK(gMSTComponentsJwojContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
232 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMSTComponentsJwojContainer.key());
233 ATH_CHECK(gMETComponentsNoiseCutContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
234 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsNoiseCutContainer.key());
235 ATH_CHECK(gMETComponentsRmsContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
236 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gMETComponentsRmsContainer.key());
237 ATH_CHECK(gScalarENoiseCutContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
238 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarENoiseCutContainer.key());
239 ATH_CHECK(gScalarERmsContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
240 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gScalarERmsContainer.key());
241 }
242
243 //---gEspresso Container (always decoded - not in HLT result)
245 ATH_CHECK(gEspressoContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
246 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gEspressoContainer.key());
247
248 //---gRistretto Container (always decoded - not in HLT result)
250 ATH_CHECK(gRistrettoContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
251 ATH_MSG_DEBUG("Recorded gFexJetGlobalContainer with key " << gRistrettoContainer.key());
252
253 // Determine if multi-slice mode is enabled (slice 0 = L1A, slices 1,2 = out-of-time)
254 const bool multiSlice = !m_gFexJetSliceWriteKey.empty();
255
256 // Create out-of-time containers for jet TOBs if multi-slice enabled
260 // Create out-of-time containers for global TOBs if multi-slice enabled
261 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gScalarEJwojSliceContainer;
262 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsJwojSliceContainer;
263 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMHTComponentsJwojSliceContainer;
264 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMSTComponentsJwojSliceContainer;
265 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gEspressoSliceContainer;
266 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gRistrettoSliceContainer;
267 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsNoiseCutSliceContainer;
268 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gScalarENoiseCutSliceContainer;
269 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gMETComponentsRmsSliceContainer;
270 SG::WriteHandle<xAOD::gFexGlobalRoIContainer> gScalarERmsSliceContainer;
271
272 if (multiSlice) {
274 ATH_CHECK(gRhoSliceContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
275 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer (out-of-time) with key " << gRhoSliceContainer.key());
276
278 ATH_CHECK(gSJSliceContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
279 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer (out-of-time) with key " << gSJSliceContainer.key());
280
282 ATH_CHECK(gLJSliceContainer.record(std::make_unique<xAOD::gFexJetRoIContainer>(), std::make_unique<xAOD::gFexJetRoIAuxContainer>()));
283 ATH_MSG_DEBUG("Recorded gFexJetRoIContainer (out-of-time) with key " << gLJSliceContainer.key());
284
286 ATH_CHECK(gScalarEJwojSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
287 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gScalarEJwojSliceContainer.key());
288
290 ATH_CHECK(gMETComponentsJwojSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
291 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gMETComponentsJwojSliceContainer.key());
292
294 ATH_CHECK(gMHTComponentsJwojSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
295 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gMHTComponentsJwojSliceContainer.key());
296
298 ATH_CHECK(gMSTComponentsJwojSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
299 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gMSTComponentsJwojSliceContainer.key());
300
302 ATH_CHECK(gEspressoSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
303 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gEspressoSliceContainer.key());
304
306 ATH_CHECK(gRistrettoSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
307 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gRistrettoSliceContainer.key());
308
310 ATH_CHECK(gMETComponentsNoiseCutSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
311 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gMETComponentsNoiseCutSliceContainer.key());
312
314 ATH_CHECK(gScalarENoiseCutSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
315 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gScalarENoiseCutSliceContainer.key());
316
318 ATH_CHECK(gMETComponentsRmsSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
319 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gMETComponentsRmsSliceContainer.key());
320
322 ATH_CHECK(gScalarERmsSliceContainer.record(std::make_unique<xAOD::gFexGlobalRoIContainer>(), std::make_unique<xAOD::gFexGlobalRoIAuxContainer>()));
323 ATH_MSG_DEBUG("Recorded gFexGlobalRoIContainer (out-of-time) with key " << gScalarERmsSliceContainer.key());
324 }
325
326
327 // Iterate over ROBFragments to decode
328 for (const ROBF* rob : vrobf) {
329 // Iterate over ROD words and decode
330
331
332 ATH_MSG_DEBUG("Starting to decode " << rob->rod_ndata() << " ROD words from ROB 0x" << std::hex << rob->rob_source_id());
333
334 //There is no data to decode.. not even the ROD trailers
335 if(rob->rod_ndata() <= 0){
336 continue;
337 }
338
339 const auto dataArray = std::span{rob->rod_data(), rob->rod_ndata()};
340
341
342 // Starting to loop over the gFEX words
343
344 unsigned int n_words = rob->rod_ndata();
345 // The 2-word ROD trailer at the end of rod_data is not part of the
346 // subblock stream; skip it so the parse loop below doesn't read 0/0
347 // as a subblock header and spin forever.
348 constexpr unsigned int ROD_TRAILER_WORDS = 2;
349 if (n_words >= ROD_TRAILER_WORDS) n_words -= ROD_TRAILER_WORDS;
350
351 //saving Jet TOBs into the EDM container
352 for(unsigned int iWord=0; iWord<n_words; iWord++) {
353 ATH_MSG_DEBUG("Raw word 0x" << std::hex << dataArray[iWord] << " " << std::bitset<32> (dataArray[iWord]));
354 }
355
356 // Vectors to temporarily store global tob before they are summed together
357 // For multi-slice support, we use vectors of arrays: [sliceNumber][fpga]
358 // Vectors are dynamically resized based on the actual number of slices in the data
359 // Inner arrays are fixed size 3 (one element per FPGA)
360 std::vector<int> global_counter;
361 std::vector<std::array<uint32_t, 3>> JWOJ_MHT;
362 std::vector<std::array<uint32_t, 3>> JWOJ_MST;
363 std::vector<std::array<uint32_t, 3>> JWOJ_MET;
364 std::vector<std::array<uint32_t, 3>> JWOJ_SCALAR;
365 std::vector<std::array<uint32_t, 3>> GESPRESSO;
366 std::vector<std::array<uint32_t, 3>> GRISTRETTO;
367 std::vector<std::array<uint32_t, 3>> NC_MET;
368 std::vector<std::array<uint32_t, 3>> NC_SCALAR;
369 std::vector<std::array<uint32_t, 3>> RMS_MET;
370 std::vector<std::array<uint32_t, 3>> RMS_SCALAR;
371 // Track slice numbers for global TOBs (to be assigned when fillGlobal is called)
372 std::vector<uint32_t> globalSliceNumbers;
373
374 // Helper lambda to ensure vectors are large enough for a given slice
375 auto ensureSliceCapacity = [&](size_t sliceNum) {
376 if (sliceNum >= global_counter.size()) {
377 size_t newSize = sliceNum + 1;
378 global_counter.resize(newSize, 0);
379 JWOJ_MHT.resize(newSize, {0, 0, 0});
380 JWOJ_MST.resize(newSize, {0, 0, 0});
381 JWOJ_MET.resize(newSize, {0, 0, 0});
382 JWOJ_SCALAR.resize(newSize, {0, 0, 0});
383 GESPRESSO.resize(newSize, {0, 0, 0});
384 GRISTRETTO.resize(newSize, {0, 0, 0});
385 NC_MET.resize(newSize, {0, 0, 0});
386 NC_SCALAR.resize(newSize, {0, 0, 0});
387 RMS_MET.resize(newSize, {0, 0, 0});
388 RMS_SCALAR.resize(newSize, {0, 0, 0});
389 }
390 };
391
392 size_t index = 0;
393 while ( index < n_words ) {
394 const uint32_t headerWord = dataArray[index];//Identify the header words. The first is a header word.
395 const uint32_t blockType = (headerWord >> gPos::BLOCK_TYPE_BIT) & gPos::BLOCK_TYPE_MASK;
396 const uint32_t headerSize = (headerWord >> gPos::HEADER_SIZE_BIT) & gPos::HEADER_SIZE_MASK;
397 const uint32_t errorFlags = (headerWord >> gPos::ERROR_FLAG_BIT) & gPos::ERROR_FLAG_MASK;
398 const uint32_t dataSize = headerWord & gPos::DATA_SIZE_MASK;
399
400 ATH_MSG_DEBUG( "index "<< index );
401 ATH_MSG_DEBUG( "word "<< std::bitset<32> (dataArray[index]) );
402 ATH_MSG_DEBUG( "headerWord "<< std::bitset<32> (headerWord) );
403 ATH_MSG_DEBUG( "blockType "<< std::bitset<4> (blockType) );
404 ATH_MSG_DEBUG( "headerSize "<< std::bitset<2> (headerSize) );
405 ATH_MSG_DEBUG( "errorFlags "<< std::bitset<1> (errorFlags) );
406 ATH_MSG_DEBUG( "dataSize "<< std::bitset<12> (dataSize) );
407
408 const uint32_t blockSize = headerSize + dataSize;
409 if ( (index + blockSize) > n_words ) {
410
411 std::stringstream sdetail;
412 sdetail << "Remaining block size " << (n_words - index) << " is too small for subblock of type " << blockType << " with headerSize " << headerSize << " and dataSize " << dataSize ;
413 std::stringstream slocation;
414 slocation << "0x"<< std::hex << rob->rob_source_id() << std::dec << " type:"<<blockType;
415 std::stringstream stitle;
416 stitle << "Small subblock size " ;
417 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
418
419 }
420
421 index += headerSize;
422
423 const uint32_t numSlices = dataSize / gPos::WORDS_PER_SLICE;
424 ATH_MSG_DEBUG( "numSlices " << numSlices );
425
426 if ( numSlices * gPos::WORDS_PER_SLICE != dataSize ) {
427
428 std::stringstream sdetail;
429 sdetail << "L1CaloBsDecoderRun3::decodeGfexTobs: subblock type " << blockType << " with dataSize " << dataSize << " is not a multiple of " << gPos::WORDS_PER_SLICE << " words" ;
430 std::stringstream slocation;
431 slocation << "0x"<< std::hex << rob->rob_source_id()<< std::dec << " type:"<<blockType;
432 std::stringstream stitle;
433 stitle << "Wrong dataSize" ;
434 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
435
436 //skip decode of this fragment
437 index+=dataSize;
438 continue;
439
440 }
441
442 // The subblock type is 0xA,B,C for jet TOBs from FPGA A,B,C
443 // and 0x1,2,3 for global (MET) TOBs.
444 bool isMet = (blockType >= 0x1 && blockType <= 0x3);
445 bool isJet = (blockType >= 0xA && blockType <= 0xC);
446
447 for (uint32_t sliceNumber = 0; sliceNumber < numSlices; sliceNumber++) {
448
449 // Skip out-of-time slices (slice != 0) if multi-slice mode is disabled
450 if (sliceNumber != 0 && !multiSlice) {
452 continue;
453 }
454
455 if ( !isJet && !isMet ) {
456 std::stringstream sdetail;
457 sdetail << "gFexByteStreamTool::decodeGfexTobSlice: Invalid block type " << blockType ;
458 std::stringstream slocation;
459 slocation << "0x"<< std::hex << rob->rob_source_id();
460 std::stringstream stitle;
461 stitle << "Invalid block type" ;
462 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
463 }
464
465 // Select target containers based on slice (slice 0 = L1A -> main containers, others -> out-of-time containers)
466 auto& targetRhoContainer = (sliceNumber == 0) ? gRhoContainer : gRhoSliceContainer;
467 auto& targetSJContainer = (sliceNumber == 0) ? gSJContainer : gSJSliceContainer;
468 auto& targetLJContainer = (sliceNumber == 0) ? gLJContainer : gLJSliceContainer;
469
470 for(unsigned int iWord=0; iWord<gPos::WORDS_PER_SLICE; iWord++) {
471
472 // Skip jet TOB fill at slice 0 when standard containers are disabled
473 if (isJet && (sliceNumber != 0 || decodeStdTOBs)) {
474 //Skipping the unused words
475 if (std::find(gPos::JET_UNUSED_POSITION.begin(),gPos::JET_UNUSED_POSITION.end(),iWord)!=gPos::JET_UNUSED_POSITION.end()){
476 continue;
477 }
478 //Skipping the trailer words
479 if (std::find(gPos::TRAILER_POSITION.begin(),gPos::TRAILER_POSITION.end(),iWord)!=gPos::TRAILER_POSITION.end()){
480 continue;
481 }
482 // Decorator for slice number - only needed for out-of-time containers
483 // (L1A containers by definition only contain slice 0)
484 static const SG::AuxElement::Decorator<uint32_t> sliceNumberDec("sliceNumber");
485
486 //Saving gRho TOBs into the EDM container
487 if (iWord == gPos::GRHO_POSITION){
488 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
489 targetRhoContainer->push_back(std::move(myEDM));
490 targetRhoContainer->back()->initialize(dataArray[index+iWord], m_gJ_scale);
491 if (sliceNumber != 0) sliceNumberDec(*targetRhoContainer->back()) = sliceNumber;
492 }
493 //Saving gBlock TOBs into the EDM container
494 if (std::find(gPos::GBLOCK_POSITION.begin(),gPos::GBLOCK_POSITION.end(),iWord)!=gPos::GBLOCK_POSITION.end()){
495 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
496 targetSJContainer->push_back(std::move(myEDM));
497 targetSJContainer->back()->initialize(dataArray[index+iWord], m_gJ_scale);
498 if (sliceNumber != 0) sliceNumberDec(*targetSJContainer->back()) = sliceNumber;
499 }
500 //Saving gJet TOBs into the EDM container
501 if (std::find(gPos::GJET_POSITION.begin(),gPos::GJET_POSITION.end(),iWord)!=gPos::GJET_POSITION.end()){
502 std::unique_ptr<xAOD::gFexJetRoI> myEDM (new xAOD::gFexJetRoI());
503 targetLJContainer->push_back(std::move(myEDM));
504 targetLJContainer->back()->initialize(dataArray[index+iWord], m_gLJ_scale);
505 if (sliceNumber != 0) sliceNumberDec(*targetLJContainer->back()) = sliceNumber;
506 }
507
508 }
509
510 // Global TOBs - decode for all slices, store per-slice data
511 // They require data from all 3 FPGAs to be combined later
512 if (isMet){
513 // Ensure we have storage for this slice
514 ensureSliceCapacity(sliceNumber);
515
516 //Skipping the unused words
518 continue;
519 }
520 //Skipping the trailer words
521 if (std::find(gPos::TRAILER_POSITION.begin(),gPos::TRAILER_POSITION.end(),iWord)!=gPos::TRAILER_POSITION.end()){
522 continue;
523 }
524 //Saving jwoj MHT TOBs into the EDM container
525 if (iWord == gPos::JWOJ_MHT_POSITION){
526 global_counter[sliceNumber]++;
527 if (blockType == 0x1) {JWOJ_MHT[sliceNumber][0] = dataArray[index+iWord];}
528 if (blockType == 0x2) {JWOJ_MHT[sliceNumber][1] = dataArray[index+iWord];}
529 if (blockType == 0x3) {JWOJ_MHT[sliceNumber][2] = dataArray[index+iWord];}
530 }
531 //Saving jwoj MST TOBs into the EDM container
532 if (iWord == gPos::JWOJ_MST_POSITION){
533 if (blockType == 0x1) {JWOJ_MST[sliceNumber][0] = dataArray[index+iWord];}
534 if (blockType == 0x2) {JWOJ_MST[sliceNumber][1] = dataArray[index+iWord];}
535 if (blockType == 0x3) {JWOJ_MST[sliceNumber][2] = dataArray[index+iWord];}
536 }
537 //Saving jwoj MET TOBs into the EDM container
538 if (iWord == gPos::JWOJ_MET_POSITION){
539 if (blockType == 0x1) {JWOJ_MET[sliceNumber][0] = dataArray[index+iWord];}
540 if (blockType == 0x2) {JWOJ_MET[sliceNumber][1] = dataArray[index+iWord];}
541 if (blockType == 0x3) {JWOJ_MET[sliceNumber][2] = dataArray[index+iWord];}
542 }
543 //Saving jwoj Scalar TOBs into the EDM container
544 if (iWord == gPos::JWOJ_SCALAR_POSITION){
545 if (blockType == 0x1) {JWOJ_SCALAR[sliceNumber][0] = dataArray[index+iWord];}
546 if (blockType == 0x2) {JWOJ_SCALAR[sliceNumber][1] = dataArray[index+iWord];}
547 if (blockType == 0x3) {JWOJ_SCALAR[sliceNumber][2] = dataArray[index+iWord];}
548 }
549 //Saving gEspresso TOBs into the EDM container
550 if (iWord == gPos::GESPRESSO_POSITION){
551 if (blockType == 0x1) {GESPRESSO[sliceNumber][0] = dataArray[index+iWord];}
552 if (blockType == 0x2) {GESPRESSO[sliceNumber][1] = dataArray[index+iWord];}
553 if (blockType == 0x3) {GESPRESSO[sliceNumber][2] = dataArray[index+iWord];}
554 }
555 //Saving gRistretto TOBs into the EDM container
556 if (iWord == gPos::GRISTRETTO_POSITION){
557 if (blockType == 0x1) {GRISTRETTO[sliceNumber][0] = dataArray[index+iWord];}
558 if (blockType == 0x2) {GRISTRETTO[sliceNumber][1] = dataArray[index+iWord];}
559 if (blockType == 0x3) {GRISTRETTO[sliceNumber][2] = dataArray[index+iWord];}
560 }
561 //Saving Noise Cut MET TOBs into the EDM container
562 if (iWord == gPos::NC_MET_POSITION){
563 if (blockType == 0x1) {NC_MET[sliceNumber][0] = dataArray[index+iWord];}
564 if (blockType == 0x2) {NC_MET[sliceNumber][1] = dataArray[index+iWord];}
565 if (blockType == 0x3) {NC_MET[sliceNumber][2] = dataArray[index+iWord];}
566 }
567 //Saving Noise Cut Scalar TOBs into the EDM container
568 if (iWord == gPos::NC_SCALAR_POSITION){
569 if (blockType == 0x1) {NC_SCALAR[sliceNumber][0] = dataArray[index+iWord];}
570 if (blockType == 0x2) {NC_SCALAR[sliceNumber][1] = dataArray[index+iWord];}
571 if (blockType == 0x3) {NC_SCALAR[sliceNumber][2] = dataArray[index+iWord];}
572 }
573 //Saving Rho+RMS MET TOBs into the EDM container
574 if (iWord == gPos::RMS_MET_POSITION){
575 if (blockType == 0x1) {RMS_MET[sliceNumber][0] = dataArray[index+iWord];}
576 if (blockType == 0x2) {RMS_MET[sliceNumber][1] = dataArray[index+iWord];}
577 if (blockType == 0x3) {RMS_MET[sliceNumber][2] = dataArray[index+iWord];}
578 }
579 //Saving Rho+RMS Scalar TOBs into the EDM container
580 if (iWord == gPos::RMS_SCALAR_POSITION){
581 if (blockType == 0x1) {RMS_SCALAR[sliceNumber][0] = dataArray[index+iWord];}
582 if (blockType == 0x2) {RMS_SCALAR[sliceNumber][1] = dataArray[index+iWord];}
583 if (blockType == 0x3) {RMS_SCALAR[sliceNumber][2] = dataArray[index+iWord];}
584 }
585
586 }
587
588 }
589
591 }
592
593 // Fill global TOBs for each slice that has complete data from all 3 FPGAs
594 for (size_t slice = 0; slice < global_counter.size(); slice++) {
595 ATH_MSG_DEBUG("global_counter[" << slice << "] is " << global_counter[slice]);
596 if (global_counter[slice] == 3) {
597 // Skip out-of-time slices if multi-slice mode is disabled
598 if (slice != 0 && !multiSlice) {
599 global_counter[slice] = 0;
600 continue;
601 }
602
603 // Select target containers based on slice (slice 0 = L1A, others = out-of-time)
604 if (slice == 0 && !decodeStdTOBs) {
605 // Only fill gEspresso and gRistretto when standard TOBs are disabled
606 fillGlobal(GESPRESSO[slice], 1, gEspressoContainer, slice, 0);
607 fillGlobal(GRISTRETTO[slice], 1, gRistrettoContainer, slice, 0);
608 } else {
609 auto& targetMHTContainer = (slice == 0) ? gMHTComponentsJwojContainer : gMHTComponentsJwojSliceContainer;
610 auto& targetMSTContainer = (slice == 0) ? gMSTComponentsJwojContainer : gMSTComponentsJwojSliceContainer;
611 auto& targetMETContainer = (slice == 0) ? gMETComponentsJwojContainer : gMETComponentsJwojSliceContainer;
612 auto& targetScalarContainer = (slice == 0) ? gScalarEJwojContainer : gScalarEJwojSliceContainer;
613 auto& targetEspressoContainer = (slice == 0) ? gEspressoContainer : gEspressoSliceContainer;
614 auto& targetRistrettoContainer = (slice == 0) ? gRistrettoContainer : gRistrettoSliceContainer;
615 auto& targetNCMETContainer = (slice == 0) ? gMETComponentsNoiseCutContainer : gMETComponentsNoiseCutSliceContainer;
616 auto& targetNCScalarContainer = (slice == 0) ? gScalarENoiseCutContainer : gScalarENoiseCutSliceContainer;
617 auto& targetRMSMETContainer = (slice == 0) ? gMETComponentsRmsContainer : gMETComponentsRmsSliceContainer;
618 auto& targetRMSScalarContainer = (slice == 0) ? gScalarERmsContainer : gScalarERmsSliceContainer;
619
620 fillGlobal(JWOJ_MHT[slice], 3, targetMHTContainer, slice);
621 fillGlobal(JWOJ_MST[slice], 4, targetMSTContainer, slice);
622 int16_t scalar = fillGlobal(JWOJ_MET[slice], 2, targetMETContainer, slice);
623 fillGlobal(JWOJ_SCALAR[slice], 1, targetScalarContainer, slice, scalar);
624
625 fillGlobal(GESPRESSO[slice], 1, targetEspressoContainer, slice, 0);
626
627 fillGlobal(GRISTRETTO[slice], 1, targetRistrettoContainer, slice, 0);
628
629 scalar = fillGlobal(NC_MET[slice], 2, targetNCMETContainer, slice);
630 fillGlobal(NC_SCALAR[slice], 1, targetNCScalarContainer, slice, scalar);
631
632 scalar = fillGlobal(RMS_MET[slice], 2, targetRMSMETContainer, slice);
633 fillGlobal(RMS_SCALAR[slice], 1, targetRMSScalarContainer, slice, scalar);
634 } // end else (standard TOBs enabled or out-of-time slice)
635
636 global_counter[slice] = 0;
637 }
638 }
639
640 }
641 }
642 return StatusCode::SUCCESS;
643}
644
645// For MHT, MST, and MET, it sums the x and y components across FPGAs, and also returnes
646// the sum in quadrature (which is actually only used for MET, and discared for MHT and MST)
647// This function also accepts "scalar" as optional variable, which is used to fill the X
648// component of the SCALAR tob.
649int16_t gFexByteStreamTool::fillGlobal(const std::array<uint32_t, 3> &tob, const int type,
651 uint32_t sliceNumber, int16_t scalar/* = -1*/) const {
652
653 ATH_MSG_DEBUG("fillGlobal with type " << type << " slice " << sliceNumber);
654
655 // 32 bit integers to avoid interim overflows when summing 16b (signed)
656 // quantities from each pFPGA. Proper clamping and bit masking follows afterwards
657 int32_t sum_x = 0;
658 int32_t sum_y = 0;
659
660 // Extract the x and y components and sum them for the three FPGAs
661 for (size_t fpga = 0; fpga < 3; fpga++) {
662 int16_t x = tob[fpga] >> gPos::GLOBAL_X_BIT & gPos::GLOBAL_X_MASK;
663 int16_t y = tob[fpga] >> gPos::GLOBAL_Y_BIT & gPos::GLOBAL_Y_MASK;
664 if (x & 0x00080000) { x = 0xFFFF0000 | x; }
665 if (y & 0x00080000) { y = 0xFFFF0000 | y; }
666 sum_x += x;
667 if (container.key() == "L1_gScalarEJwoj" && y < 0) y = 0;
668 sum_y += y;
669 }
670
671 // Special case for gEspresso/gRistretto: in the readout these quantities are stored in x. We need to move them to y to armonize this with the other scalar quantities
672 // 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).
673 if (container.key() == "L1_gEspresso" || container.key() == "L1_gRistretto" ) {
674 sum_y = sum_x;
675 }
676
677 if (type == 1) {//we are considering the scalar case (sum_x = MET and sum_y = SumEt)
678 ATH_MSG_DEBUG(" scalar tob, saving " << scalar << " in X component");
679 sum_x = scalar; //Total MET
680 if( sum_y > 0x000FFF) sum_y = 0x000FFF; //Overflow control for SumEt
681 if( sum_y < 0) sum_y = 0;
682
683 } else {
684 if (sum_x < -0x000800) sum_x = -0x000800; //-2048
685 if (sum_x > 0x0007FF) sum_x = 0x0007FF; //2047
686
687 if (sum_y < -0x000800) sum_y = -0x000800; //-2048
688 if (sum_y > 0x0007FF) sum_y = 0x0007FF; //2047
689 }
690
691 ATH_MSG_DEBUG(" fillGlobal type " << type << std::dec << " sum_x " << sum_x << " sum_y " << sum_y);
692
693 uint32_t METword = 0;
694
695 METword = (sum_y & 0x00000FFF) << 0; //set the Quantity2 to the corresponding slot (LSB)
696 METword = METword | (sum_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
697 if (sum_y != 0) METword = METword | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
698 if (sum_x != 0) METword = METword | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
699 METword = METword | (type & 0x0000001F) << 26;//TOB ID (5 bits starting at 26)
700
701 // Save to the EDM
702 std::unique_ptr<xAOD::gFexGlobalRoI> myEDM (new xAOD::gFexGlobalRoI());
703 container->push_back(std::move(myEDM));
704 container->back()->setWord(METword);
705 container->back()->setQuantityOne(sum_x);
706 container->back()->setQuantityTwo(sum_y);
707 container->back()->setScaleOne(m_gXE_scale);
708 container->back()->setScaleTwo(m_gTE_scale);
709 container->back()->setStatusOne(1);
710 container->back()->setStatusTwo(1);
711 container->back()->setSaturated(0);
712 container->back()->setGlobalType(type);
713
714 // Add slice number decoration only for out-of-time TOBs
715 // (L1A containers by definition only contain slice 0)
716 if (sliceNumber != 0) {
717 static const SG::AuxElement::Decorator<uint32_t> sliceNumberDec("sliceNumber");
718 sliceNumberDec(*container->back()) = sliceNumber;
719 }
720
721 int MET2 = sum_x * sum_x + sum_y * sum_y;
722 int16_t MET = std::sqrt(MET2);
723 if (MET > 0x000FFF) MET = 0x000FFF;
724
725 return MET;
726
727}
728
729
731uint32_t gFexByteStreamTool::buildBlockHeader(uint32_t blockType, uint32_t numSlices) const {
732 constexpr uint32_t headerSize = 1;
733 constexpr uint32_t errorFlag = 0;
734 const uint32_t dataSize = numSlices * gPos::WORDS_PER_SLICE;
735 return ((blockType & gPos::BLOCK_TYPE_MASK ) << gPos::BLOCK_TYPE_BIT )
737 | ((errorFlag & gPos::ERROR_FLAG_MASK ) << gPos::ERROR_FLAG_BIT )
738 | ( dataSize & gPos::DATA_SIZE_MASK );
739}
740
742StatusCode gFexByteStreamTool::convertToBS(std::vector<WROBF*>& vrobf,
744 const EventContext& eventContext) {
745
746 NamedContainerMap<xAOD::gFexJetRoIContainer> jetMap;
747 NamedContainerMap<xAOD::gFexGlobalRoIContainer> globalMap;
748 if (tc && !tc->empty()) {
749 const xAOD::TrigComposite& l1 = *tc->at(0);
750 jetMap = indexByName<xAOD::gFexJetRoIContainer >(l1);
751 globalMap = indexByName<xAOD::gFexGlobalRoIContainer>(l1);
752 }
753
754 constexpr uint32_t numSlices = 1; // slice 0 = L1A; out-of-time slices not emitted in v1
755 std::vector<uint32_t> words;
756 words.reserve(6 * (1 + numSlices * gPos::WORDS_PER_SLICE) + 2);
757
758 // Shared across both subblock loops; reset to 0 at the start of each iteration.
759 std::array<uint32_t, gPos::WORDS_PER_SLICE> slice{};
760
761 // ---- Jet subblocks: blockType 0xA / 0xB / 0xC for FPGA A / B / C ----
762 // The xAOD gBlock / gJet / gRho containers concatenate all three FPGAs' TOBs;
763 // we slice them back deterministically (TOBs 0..3 -> FPGA-A pos 1,2,8,9, etc.)
764 // so a decode -> encode -> decode cycle reproduces the original xAOD content.
765 constexpr std::array<uint32_t, 3> jetBlockTypes = {0xA, 0xB, 0xC};
766 for (uint32_t fpga = 0; fpga < 3; ++fpga) {
767 slice.fill(0);
768 words.push_back(buildBlockHeader(jetBlockTypes[fpga], numSlices));
769 for (size_t s = 0; s < gPos::GBLOCK_POSITION.size(); ++s) {
770 slice[gPos::GBLOCK_POSITION[s]] =
771 wordAtOrZero(jetMap, "L1_gFexSRJetRoI",
772 fpga * gPos::GBLOCK_POSITION.size() + s);
773 }
774 for (size_t s = 0; s < gPos::GJET_POSITION.size(); ++s) {
775 slice[gPos::GJET_POSITION[s]] =
776 wordAtOrZero(jetMap, "L1_gFexLRJetRoI",
777 fpga * gPos::GJET_POSITION.size() + s);
778 }
779 slice[gPos::GRHO_POSITION] = wordAtOrZero(jetMap, "L1_gFexRhoRoI", fpga);
780 // Trailer (pos 6, 13) and unused (pos 0, 4, 5, 11, 12) stay 0: the
781 // decoder skips both groups, so any value would be discarded anyway.
782 for (uint32_t w : slice) words.push_back(w);
783 }
784
785 // ---- Global subblocks: blockType 0x1 / 0x2 / 0x3 for FPGA A / B / C ----
786 // Each xAOD Global RoI carries the sum across the three FPGAs in its word();
787 // we place that sum in the FPGA-A slot and leave FPGA-B/C zero so the decoder's
788 // sum across blockType 0x1 + 0x2 + 0x3 reproduces the xAOD value exactly.
789 constexpr std::array<uint32_t, 3> globalBlockTypes = {0x1, 0x2, 0x3};
790 for (uint32_t fpga = 0; fpga < 3; ++fpga) {
791 slice.fill(0);
792 words.push_back(buildBlockHeader(globalBlockTypes[fpga], numSlices));
793 if (fpga == 0) {
794 // Vector components (signed 12-bit, can be negative)
795 slice[gPos::JWOJ_MHT_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gMHTComponentsJwoj"), /*signed12bit=*/true);
796 slice[gPos::JWOJ_MST_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gMSTComponentsJwoj"), /*signed12bit=*/true);
797 slice[gPos::JWOJ_MET_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gMETComponentsJwoj"), /*signed12bit=*/true);
798 slice[gPos::NC_MET_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gMETComponentsNoiseCut"), /*signed12bit=*/true);
799 slice[gPos::RMS_MET_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gMETComponentsRms"), /*signed12bit=*/true);
800 // Scalar energies (unsigned 12-bit, decoder clamps to [0, 0xFFF])
801 slice[gPos::JWOJ_SCALAR_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gScalarEJwoj"), /*signed12bit=*/false);
802 slice[gPos::GRISTRETTO_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gRistretto"), /*signed12bit=*/false);
803 slice[gPos::GESPRESSO_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gEspresso"), /*signed12bit=*/false);
804 slice[gPos::NC_SCALAR_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gScalarENoiseCut"), /*signed12bit=*/false);
805 slice[gPos::RMS_SCALAR_POSITION] = globalRoIWordToPerFpgaTob(firstWord(globalMap, "L1_gScalarERms"), /*signed12bit=*/false);
806 }
807 for (uint32_t w : slice) words.push_back(w);
808 }
809
810 ATH_MSG_DEBUG("gFex encoder: jetContainers=" << jetMap.size()
811 << " globalContainers=" << globalMap.size()
812 << " words=" << words.size());
813
814 // ROD trailer (decoder only reads the 7-bit error flag in word1 -- write 0/0)
815 words.push_back(0);
816 words.push_back(0);
817
818 clearCache(eventContext);
819 uint32_t* data = newRodData(eventContext, words.size());
820 std::copy(words.begin(), words.end(), data);
821
822 // gFex packs all 6 subblocks (3 Jet + 3 Global) into a single ROB.
823 eformat::helper::SourceIdentifier sid(eformat::TDAQ_CALO_FEAT_EXTRACT_ROI, 0x3000);
824 vrobf.push_back(newRobFragment(eventContext, sid.code(), words.size(), data, 0));
825
826 return StatusCode::SUCCESS;
827}
828
829
830void gFexByteStreamTool::printError(const std::string& location, const std::string& title, MSG::Level type, const std::string& detail) const{
831
832 if(m_UseMonitoring){
834 Monitored::Scalar("gfexDecoderErrorLocation",location.empty() ? std::string("UNKNOWN") : location),
835 Monitored::Scalar("gfexDecoderErrorTitle" ,title.empty() ? std::string("UNKNOWN") : title)
836 );
837 }
838 else {
839 msg() << type << detail << endmsg;
840 }
841}
#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()
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t tc
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment WROBF
Handle class for adding a decoration to an object.
size_t size() const
Number of registered mappings.
#define y
#define x
static const Attributes_t empty
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::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gRistrettoSliceWriteKey
virtual StatusCode convertToBS(std::vector< OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment * > &vrobf, const xAOD::TrigCompositeContainer *tc, const EventContext &eventContext) override
xAOD->BS conversion
virtual StatusCode initialize() override
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarENoiseCutSliceWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarERmsSliceWriteKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gMSTComponentsJwojOOTDecorKey
uint32_t buildBlockHeader(uint32_t blockType, uint32_t numSlices) const
xAOD->BS conversion
virtual StatusCode convertFromBS(const std::vector< const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment * > &vrobf, const EventContext &eventContext) const override
BS->xAOD conversion.
SG::WriteDecorHandleKey< xAOD::gFexJetRoIContainer > m_gFexRhoOOTDecorKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexRhoSliceWriteKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gRistrettoOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gEspressoSliceWriteKey
gFexByteStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
SG::ReadHandleKey< TrigConf::L1Menu > m_l1MenuKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMSTComponentsJwojSliceWriteKey
SG::WriteDecorHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMSTComponentsJwojWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarEJwojSliceWriteKey
ToolHandle< GenericMonitoringTool > m_monTool
void printError(const std::string &location, const std::string &title, MSG::Level type, const std::string &detail) const
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gRistrettoWriteKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarENoiseCutOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMHTComponentsJwojWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMHTComponentsJwojSliceWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsNoiseCutSliceWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarENoiseCutWriteKey
int16_t fillGlobal(const std::array< uint32_t, 3 > &tob, const int type, SG::WriteHandle< xAOD::gFexGlobalRoIContainer > &container, uint32_t sliceNumber, int16_t scalar=-1) const
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gMHTComponentsJwojOOTDecorKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarERmsOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsJwojWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarEJwojWriteKey
SG::WriteDecorHandleKey< xAOD::gFexJetRoIContainer > m_gFexBlockOOTDecorKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsRmsOOTDecorKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gEspressoOOTDecorKey
Gaudi::Property< std::vector< uint32_t > > m_robIds
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarEJwojOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gEspressoWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexBlockWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gScalarERmsWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexRhoWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetSliceWriteKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsJwojSliceWriteKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsNoiseCutOOTDecorKey
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsRmsSliceWriteKey
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexBlockSliceWriteKey
SG::WriteDecorHandleKey< xAOD::gFexGlobalRoIContainer > m_gMETComponentsJwojOOTDecorKey
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:50
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:41
constexpr unsigned int RMS_MET_POSITION
Definition gFexPos.h:46
constexpr unsigned int NC_SCALAR_POSITION
Definition gFexPos.h:44
constexpr unsigned int GLOBAL_X_MASK
Definition gFexPos.h:49
constexpr std::array< unsigned int, 2 > 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:52
constexpr unsigned int HEADER_SIZE_MASK
Definition gFexPos.h:17
constexpr unsigned int NC_MET_POSITION
Definition gFexPos.h:43
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 GRISTRETTO_POSITION
Definition gFexPos.h:40
constexpr unsigned int JWOJ_MST_POSITION
Definition gFexPos.h:36
constexpr unsigned int RMS_SCALAR_POSITION
Definition gFexPos.h:47
constexpr unsigned int JWOJ_MET_POSITION
Definition gFexPos.h:37
constexpr unsigned int GLOBAL_X_BIT
Definition gFexPos.h:51
Definition MET.py:1
eformat::write::ROBFragment ROBFragment
Definition RawEvent.h:33
eformat::ROBFragment< PointerType > ROBFragment
Definition RawEvent.h:27
pointer & link(pointer p) const
Return a reference to the link for an element.
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77
Definition index.py:1
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
gFexJetRoI_v1 gFexJetRoI
Define the latest version of the gFexJetRoI class.
Definition gFexJetRoI.h:16
TrigComposite_v1 TrigComposite
Declare the latest version of the class.
gFexGlobalRoI_v1 gFexGlobalRoI
Define the latest version of the eFexEMRoI class.
setScaleOne setStatusOne setSaturated int16_t
setWord1 uint16_t
setEventNumber uint32_t
MsgStream & msg
Definition testRead.cxx:32