128 {
129
131
132 std::vector<SG::WriteHandle<xAOD::MuonRoIContainer>> roiHandles =
m_roiWriteKeys.makeHandles(eventContext);
133 for (auto& roiHandle : roiHandles) {
134 ATH_CHECK(roiHandle.record(std::make_unique<xAOD::MuonRoIContainer>(),
135 std::make_unique<xAOD::MuonRoIAuxContainer>()));
136 ATH_MSG_DEBUG(
"Recorded MuonRoIContainer with key " << roiHandle.key());
137 }
138
139
140 std::vector<SG::WriteHandle<xAOD::MuonRoIContainer>> topoHandles;
143 for (auto& topoHandle : topoHandles) {
144 ATH_CHECK(topoHandle.record(std::make_unique<xAOD::MuonRoIContainer>(),
145 std::make_unique<xAOD::MuonRoIAuxContainer>()));
146 ATH_MSG_DEBUG(
"Recorded MuCTPIL1Topo with key " << topoHandle.key());
147 }
148 }
149
150
151 const eformat::helper::SourceIdentifier sid(
m_robIds.value().at(0));
152 auto it = std::find_if(vrobf.begin(), vrobf.end(), [&sid](
const ROBF* rob){return rob->rob_source_id() == sid.code();});
153 if (it == vrobf.end()) {
154 ATH_MSG_DEBUG(
"No MUCTPI ROB fragment with ID 0x" << std::hex << sid.code() << std::dec
155 << " was found, MuonRoIContainer will be empty");
156 return StatusCode::SUCCESS;
157 }
158
159
162 const uint32_t ndata = rob->rod_ndata();
164
165
166 Monitored::Scalar<uint32_t> monNumWords{"NumWordsInROD", ndata};
170 std::vector<int> bcidOffsetsWrtROB;
172
173
174 if (ndata==0) {
175 ATH_MSG_ERROR(
"Empty ROD data in MUCTPI ROB 0x" << std::hex << sid.code() << std::dec);
176 Monitored::Group(
m_monTool, monNumWords);
177 return StatusCode::FAILURE;
178 }
179 ATH_MSG_DEBUG(
"Starting to decode " << ndata <<
" ROD words");
180
181
182
183 std::vector<std::pair<size_t,size_t>> roiSlices;
184 std::vector<std::pair<size_t,size_t>> topoSlices;
185
186
187 size_t iWord{0};
188 for (
const uint32_t word : std::span{
data, ndata}) {
189 ATH_MSG_DEBUG(
"MUCTPI raw word " << iWord <<
": 0x" << std::hex << word << std::dec);
191 ++wordTypeCounts[static_cast<size_t>(wordType)];
192
193 switch (wordType) {
197 <<
", NTOB=" <<
header.tobCount <<
", NCAND=" <<
header.candCount);
198
199 roiSlices.emplace_back(0,0);
200
201 topoSlices.emplace_back(0,0);
202
203 bcidOffsetsWrtROB.push_back(bcidDiff(
header.bcid, rob->rod_bc_id()));
204 break;
205 }
209 break;
210 }
213 if (roiSlices.empty()) {
214 ATH_MSG_ERROR(
"Unexpected data format - found candidate word before any timeslice header");
215 Monitored::Group(
m_monTool, monNumWords, monWordType, monWordTypeCount, monBCIDOffsetsWrtROB);
216 return StatusCode::FAILURE;
217 }
218
219 std::pair<size_t,size_t>&
slice = roiSlices.back();
222 break;
223 }
227 if (topoSlices.empty()) {
228 ATH_MSG_ERROR(
"Unexpected data format - found Topo TOB word before any timeslice header");
229 return StatusCode::FAILURE;
230 }
231
232 std::pair<size_t,size_t>&
slice = topoSlices.back();
235 break;
236 }
240
241 if (!errorBits.empty()) {
242 ATH_MSG_DEBUG(
"MUCTPI ROD data flagged with errors. The data status word is 0x" << std::hex << word << std::dec);
243 for (size_t bit : errorBits) {
245 }
247 Monitored::Group(
m_monTool, monErrorBits);
248 }
249 break;
250 }
251 default: {
252 ATH_MSG_ERROR(
"The MUCTPI word 0x" << std::hex << word << std::dec <<
" does not match any known word type");
253 Monitored::Group(
m_monTool, monNumWords, monWordType, monWordTypeCount, monBCIDOffsetsWrtROB);
254 return StatusCode::FAILURE;
255 }
256 }
257 ++iWord;
258 }
259
260
261 Monitored::Group(
m_monTool, monNumWords, monWordType, monWordTypeCount, monBCIDOffsetsWrtROB);
262
263
264 const size_t nSlices{roiSlices.size()};
266 if (nSlices > nOutputSlices) {
268 return StatusCode::FAILURE;
269 } else if (nSlices != static_cast<size_t>(rob->rod_detev_type())) {
270 ATH_MSG_ERROR(
"Found " << nSlices <<
" time slices, but Detector Event Type word indicates there should be "
271 << rob->rod_detev_type());
272 return StatusCode::FAILURE;
273 } else if (nSlices!=1 && nSlices!=3 && nSlices!=5) {
274 ATH_MSG_ERROR(
"Expected 1, 3 or 5 time slices but found " << nSlices);
275 return StatusCode::FAILURE;
276 }
277 const size_t outputOffset = nOutputSlices/2 - nSlices/2;
279
280
282 const size_t nTopoSlices{topoSlices.size()};
284 if (nTopoSlices > nTopoOutputSlices) {
286 return StatusCode::FAILURE;
287 } else if (nTopoSlices != static_cast<size_t>(rob->rod_detev_type())) {
288 ATH_MSG_ERROR(
"Found " << nTopoSlices <<
" time slices, but Detector Event Type word indicates there should be "
289 << rob->rod_detev_type());
290 return StatusCode::FAILURE;
291 } else if (nTopoSlices!=1 && nTopoSlices!=3 && nTopoSlices!=5) {
292 ATH_MSG_ERROR(
"Expected 1, 3 or 5 time slices but found " << nTopoSlices);
293 return StatusCode::FAILURE;
294 }
295 const size_t topoOutputOffset = nTopoOutputSlices/2 - nTopoSlices/2;
297 }
298
299
301 auto topoHandleIt = topoHandles.begin();
302 for (auto& roiHandle : roiHandles) {
303 auto& topoHandle = *topoHandleIt;
304 Monitored::Scalar<short> monBCOffset{"BCOffset", bcOffset};
305 Monitored::Scalar<size_t> monNumRoIs{"NumOutputRoIs", roiHandle->size()};
307 Monitored::Scalar<size_t> monNumTopo{"NumOutputTopoTOBs", topoHandle->size()};
308 Monitored::Scalar<int> monNumDiff{"NumOutputDiffRoITopo", static_cast<int>(monNumRoIs)-static_cast<int>(monNumTopo)};
309 ATH_MSG_DEBUG(
"Decoded " << monNumRoIs <<
" RoIs into the " << roiHandle.key() <<
" container "
310 "and " << monNumTopo << " Topo TOBs into the " << topoHandle.key() << " container");
311 Monitored::Group(
m_monTool, monBCOffset, monNumRoIs, monNumTopo, monNumDiff);
312 ++topoHandleIt;
313 } else {
314 ATH_MSG_DEBUG(
"Decoded " << monNumRoIs <<
" RoIs into the " << roiHandle.key() <<
" container");
315 Monitored::Group(
m_monTool, monBCOffset, monNumRoIs);
316 }
317 ++bcOffset;
318 }
319
320 return StatusCode::SUCCESS;
321 }
322
323 else{
324
325
326 std::vector<SG::WriteHandle<xAOD::MuonRoIContainer>> topoHandles;
329 for (auto& topoHandle : topoHandles) {
330 ATH_CHECK(topoHandle.record(std::make_unique<xAOD::MuonRoIContainer>(),
331 std::make_unique<xAOD::MuonRoIAuxContainer>()));
332 ATH_MSG_DEBUG(
"Recorded MuCTPIL1Topo with key " << topoHandle.key());
333 }
334 }
335
336
337 const eformat::helper::SourceIdentifier sid(
m_robIds.value().at(0));
338 auto it = std::find_if(vrobf.begin(), vrobf.end(), [&sid](
const ROBF* rob){return rob->rob_source_id() == sid.code();});
339 if (it == vrobf.end()) {
340 ATH_MSG_DEBUG(
"No MUCTPI ROB fragment with ID 0x" << std::hex << sid.code() << std::dec
341 << " was found, MuonRoIContainer will be empty");
342 return StatusCode::SUCCESS;
343 }
344
345
348 const uint32_t ndata = rob->rod_ndata();
350
351
352 Monitored::Scalar<uint32_t> monNumWords{"NumWordsInROD", ndata};
356 std::vector<int> bcidOffsetsWrtROB;
358
359
360 if (ndata==0) {
361 ATH_MSG_ERROR(
"Empty ROD data in MUCTPI ROB 0x" << std::hex << sid.code() << std::dec);
362 return StatusCode::FAILURE;
363 }
364 ATH_MSG_DEBUG(
"Starting to decode " << ndata <<
" ROD words");
365
366
367
368 std::vector<std::pair<size_t,size_t>> roiSlices;
369 std::vector<std::pair<size_t,size_t>> topoSlices;
370
371
372 size_t iWord{0};
374 ATH_MSG_DEBUG(
"MUCTPI raw word " << iWord <<
": 0x" << std::hex << word << std::dec);
376 ++wordTypeCounts[static_cast<size_t>(wordType)];
377
378 switch (wordType) {
382 <<
", NTOB=" <<
header.tobCount <<
", NCAND=" <<
header.candCount);
383
384 roiSlices.emplace_back(0,0);
385
386 topoSlices.emplace_back(0,0);
387
388 bcidOffsetsWrtROB.push_back(bcidDiff(
header.bcid, rob->rod_bc_id()));
389 break;
390 }
394 break;
395 }
398 if (roiSlices.empty()) {
399 ATH_MSG_ERROR(
"Unexpected data format - found candidate word before any timeslice header");
400 return StatusCode::FAILURE;
401 }
402
403 std::pair<size_t,size_t>&
slice = roiSlices.back();
406 break;
407 }
411 if (topoSlices.empty()) {
412 ATH_MSG_ERROR(
"Unexpected data format - found Topo TOB word before any timeslice header");
413 return StatusCode::FAILURE;
414 }
415
416 std::pair<size_t,size_t>&
slice = topoSlices.back();
419 break;
420 }
424
425 if (!errorBits.empty()) {
426 ATH_MSG_DEBUG(
"MUCTPI ROD data flagged with errors. The data status word is 0x" << std::hex << word << std::dec);
427 for (size_t bit : errorBits) {
429 }
431 }
432 break;
433 }
434 default: {
435 ATH_MSG_ERROR(
"The MUCTPI word 0x" << std::hex << word << std::dec <<
" does not match any known word type");
436 return StatusCode::FAILURE;
437 }
438 }
439 ++iWord;
440 }
441
442
443 const size_t nSlices{roiSlices.size()};
445 if (nSlices > nOutputSlices) {
447 return StatusCode::FAILURE;
448 } else if (nSlices != static_cast<size_t>(rob->rod_detev_type())) {
449 ATH_MSG_ERROR(
"Found " << nSlices <<
" time slices, but Detector Event Type word indicates there should be "
450 << rob->rod_detev_type());
451 return StatusCode::FAILURE;
452 } else if (nSlices!=1 && nSlices!=3 && nSlices!=5) {
453 ATH_MSG_ERROR(
"Expected 1, 3 or 5 time slices but found " << nSlices);
454 return StatusCode::FAILURE;
455 }
456
457
459 const size_t nTopoSlices{topoSlices.size()};
461 if (nTopoSlices > nTopoOutputSlices) {
463 return StatusCode::FAILURE;
464 } else if (nTopoSlices != static_cast<size_t>(rob->rod_detev_type())) {
465 ATH_MSG_ERROR(
"Found " << nTopoSlices <<
" time slices, but Detector Event Type word indicates there should be "
466 << rob->rod_detev_type());
467 return StatusCode::FAILURE;
468 } else if (nTopoSlices!=1 && nTopoSlices!=3 && nTopoSlices!=5) {
469 ATH_MSG_ERROR(
"Expected 1, 3 or 5 time slices but found " << nTopoSlices);
470 return StatusCode::FAILURE;
471 }
472 const size_t topoOutputOffset = nTopoOutputSlices/2 - nTopoSlices/2;
474 }
475
476 return StatusCode::SUCCESS;
477 }
478
479}
#define ATH_CHECK
Evaluate an expression and check for errors.
OFFLINE_FRAGMENTS_NAMESPACE_WRITE::ROBFragment ROBF
char data[hepevt_bytes_allocation_ATLAS]
span(T *ptr, std::size_t sz) -> span< T >
A couple needed deduction guides.
constexpr uint32_t multiplicityWordNumber(uint32_t word)
Decode the index of the multitpicity word, which is 1, 2, or 3.
static constexpr std::array< std::string_view, 16 > DataStatusWordErrors
constexpr auto timesliceHeader(uint32_t word)
Decode timeslice word.
constexpr WordType getWordType(uint32_t word)
Determine the type of a MUCTPI ROD word.
std::vector< size_t > getDataStatusWordErrors(uint32_t word)
Decode the data status word (returns a vector of bit indices for the errors set - empty if no errors)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.