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;