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());
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());
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;
162 const uint32_t ndata = rob->rod_ndata();
170 std::vector<int> bcidOffsetsWrtROB;
175 ATH_MSG_ERROR(
"Empty ROD data in MUCTPI ROB 0x" << std::hex << sid.code() << std::dec);
177 return StatusCode::FAILURE;
179 ATH_MSG_DEBUG(
"Starting to decode " << ndata <<
" ROD words");
183 std::vector<std::pair<size_t,size_t>> roiSlices;
184 std::vector<std::pair<size_t,size_t>> topoSlices;
189 ATH_MSG_DEBUG(
"MUCTPI raw word " << iWord <<
": 0x" << std::hex << word << std::dec);
191 ++wordTypeCounts[
static_cast<size_t>(wordType)];
197 <<
", NTOB=" <<
header.tobCount <<
", NCAND=" <<
header.candCount);
199 roiSlices.emplace_back(0,0);
201 topoSlices.emplace_back(0,0);
203 bcidOffsetsWrtROB.push_back(bcidDiff(
header.bcid, rob->rod_bc_id()));
213 if (roiSlices.empty()) {
214 ATH_MSG_ERROR(
"Unexpected data format - found candidate word before any timeslice header");
216 return StatusCode::FAILURE;
219 std::pair<size_t,size_t>&
slice = roiSlices.back();
227 if (topoSlices.empty()) {
228 ATH_MSG_ERROR(
"Unexpected data format - found Topo TOB word before any timeslice header");
229 return StatusCode::FAILURE;
232 std::pair<size_t,size_t>&
slice = topoSlices.back();
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) {
244 ATH_MSG_DEBUG(
"Error bit " << bit <<
": " << LVL1::MuCTPIBits::DataStatusWordErrors.at(bit));
252 ATH_MSG_ERROR(
"The MUCTPI word 0x" << std::hex << word << std::dec <<
" does not match any known word type");
254 return StatusCode::FAILURE;
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;
277 const size_t outputOffset = nOutputSlices/2 - nSlices/2;
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;
295 const size_t topoOutputOffset = nTopoOutputSlices/2 - nTopoSlices/2;
301 auto topoHandleIt = topoHandles.begin();
302 for (
auto& roiHandle : roiHandles) {
303 auto& topoHandle = *topoHandleIt;
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");
314 ATH_MSG_DEBUG(
"Decoded " << monNumRoIs <<
" RoIs into the " << roiHandle.key() <<
" container");
320 return StatusCode::SUCCESS;
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());
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;
348 const uint32_t ndata = rob->rod_ndata();
356 std::vector<int> bcidOffsetsWrtROB;
361 ATH_MSG_ERROR(
"Empty ROD data in MUCTPI ROB 0x" << std::hex << sid.code() << std::dec);
362 return StatusCode::FAILURE;
364 ATH_MSG_DEBUG(
"Starting to decode " << ndata <<
" ROD words");
368 std::vector<std::pair<size_t,size_t>> roiSlices;
369 std::vector<std::pair<size_t,size_t>> topoSlices;
374 ATH_MSG_DEBUG(
"MUCTPI raw word " << iWord <<
": 0x" << std::hex << word << std::dec);
376 ++wordTypeCounts[
static_cast<size_t>(wordType)];
382 <<
", NTOB=" <<
header.tobCount <<
", NCAND=" <<
header.candCount);
384 roiSlices.emplace_back(0,0);
386 topoSlices.emplace_back(0,0);
388 bcidOffsetsWrtROB.push_back(bcidDiff(
header.bcid, rob->rod_bc_id()));
398 if (roiSlices.empty()) {
399 ATH_MSG_ERROR(
"Unexpected data format - found candidate word before any timeslice header");
400 return StatusCode::FAILURE;
403 std::pair<size_t,size_t>&
slice = roiSlices.back();
411 if (topoSlices.empty()) {
412 ATH_MSG_ERROR(
"Unexpected data format - found Topo TOB word before any timeslice header");
413 return StatusCode::FAILURE;
416 std::pair<size_t,size_t>&
slice = topoSlices.back();
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) {
428 ATH_MSG_DEBUG(
"Error bit " << bit <<
": " << LVL1::MuCTPIBits::DataStatusWordErrors.at(bit));
435 ATH_MSG_ERROR(
"The MUCTPI word 0x" << std::hex << word << std::dec <<
" does not match any known word type");
436 return StatusCode::FAILURE;
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;
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;
472 const size_t topoOutputOffset = nTopoOutputSlices/2 - nTopoSlices/2;
476 return StatusCode::SUCCESS;