45 ATH_CHECK(mode!=ConversionMode::Undefined);
54 if (msgLvl(MSG::DEBUG)) {
55 std::string_view modeName {(mode==ConversionMode::Encoding) ?
"encoding" :
"decoding"};
56 auto enabledStr = [](
bool v)
constexpr {
return std::string_view(v ?
"enabled" :
"disabled");};
69 std::vector<eformat::helper::SourceIdentifier> configuredROBSIDs;
70 std::ostringstream
str;
75 configuredROBSIDs.emplace_back(eformat::TDAQ_CTP,
m_ctpModuleID);
81 configuredROBSIDs.emplace_back(eformat::TDAQ_MUON_CTP_INTERFACE,
m_muCTPIModuleID);
89 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_JET_PROC_ROI, module_id);
90 str <<
"0x" << std::hex << module_id << std::dec <<
" ";
99 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_CLUSTER_PROC_ROI, module_id);
100 str <<
"0x" << std::hex << module_id << std::dec <<
" ";
109 configuredROBSIDs.emplace_back(eformat::TDAQ_CALO_TOPO_PROC, module_id);
110 str <<
"0x" << std::hex << module_id << std::dec <<
" ";
116 for (
const auto& sid : configuredROBSIDs) {
121 if (
m_doCTP && mode==ConversionMode::Encoding) {
126 return StatusCode::SUCCESS;
131 const EventContext& eventContext) {
136 auto addRob = [&](
const eformat::helper::SourceIdentifier& sid,
const size_t ndata,
const uint32_t*
data){
137 vrobf.push_back(newRobFragment(eventContext, sid.code(), ndata,
data,
m_detEvType));
140 auto convertDataToRob = [&](
const eformat::helper::SourceIdentifier& sid,
const auto& dataVec){
141 uint32_t*
data = newRodData(eventContext, dataVec.size());
143 for (
size_t i=0; i<dataVec.size(); ++i) {
144 ATH_MSG_VERBOSE(
" 0x" << MSG::hex << std::setw(8) << dataVec.at(i).roIWord() << MSG::dec);
145 data[i] = dataVec.at(i).roIWord();
147 return addRob(sid, dataVec.size(),
data);
152 const eformat::helper::SourceIdentifier ctpSID{eformat::TDAQ_CTP,
m_ctpModuleID};
153 const std::vector<ROIB::CTPRoI>& ctpDataVec = roibResult->cTPResult().roIVec();
157 rob->rod_minor_version(roibResult->cTPResult().header().formatVersion() & 0xffffu);
165 constexpr size_t word_size = 32;
166 constexpr size_t words_per_set = 512 / word_size;
167 constexpr size_t num_words = 3 * words_per_set;
168 uint32_t* l1bits_data = newRodData(eventContext, num_words);
170 for (
const std::bitset<512>& bset : {tbp, tap, tav}) {
171 const std::string
sbits = bset.to_string();
172 const size_t iword_output_start = words_per_set * iset;
173 for (
size_t iword_in_set = 0; iword_in_set < words_per_set; ++iword_in_set) {
174 const size_t bword_pos = 512 - (iword_in_set+1) * word_size;
175 std::bitset<word_size> bword{
sbits.substr(bword_pos, word_size)};
176 l1bits_data[iword_output_start + iword_in_set] =
static_cast<uint32_t
>(bword.to_ulong());
180 rawEvent->lvl1_trigger_info(num_words, l1bits_data);
183 const uint32_t triggerType = roibResult->cTPResult().header().triggerType();
184 rawEvent->lvl1_trigger_type(
static_cast<uint8_t
>(triggerType & 0xFF));
189 const eformat::helper::SourceIdentifier muctpiSID{eformat::TDAQ_MUON_CTP_INTERFACE,
m_muCTPIModuleID};
190 const std::vector<ROIB::MuCTPIRoI>& muctpiDataVec = roibResult->muCTPIResult().roIVec();
191 convertDataToRob(muctpiSID, muctpiDataVec);
196 const std::vector<ROIB::JetEnergyResult>& jetEnergyResultVec = roibResult->jetEnergyResult();
197 for (
size_t slink=0; slink<jetEnergyResultVec.size(); ++slink) {
198 const eformat::helper::SourceIdentifier jetSID{eformat::TDAQ_CALO_JET_PROC_ROI,
m_jetModuleID.value().at(slink)};
199 convertDataToRob(jetSID, jetEnergyResultVec.at(slink).roIVec());
205 const std::vector<ROIB::EMTauResult>& emTauResultVec = roibResult->eMTauResult();
206 for (
size_t slink=0; slink<emTauResultVec.size(); ++slink) {
207 const eformat::helper::SourceIdentifier emSID{eformat::TDAQ_CALO_CLUSTER_PROC_ROI,
m_emModuleID.value().at(slink)};
208 convertDataToRob(emSID, emTauResultVec.at(slink).roIVec());
214 const std::vector<ROIB::L1TopoResult>& l1TopoResultVec = roibResult->l1TopoResult();
215 for (
size_t slink=0; slink<l1TopoResultVec.size(); ++slink) {
216 eformat::helper::SourceIdentifier topoSID{l1TopoResultVec.at(slink).rdo().getSourceID()};
219 topoSID = eformat::helper::SourceIdentifier(eformat::TDAQ_CALO_TOPO_PROC,
m_l1TopoModuleID.value().at(slink));
220 ATH_MSG_DEBUG(
"Source ID in L1TopoRDO was zero so using Property for slink " << slink <<
": "
223 else if (topoSID.code() == 0) {
224 topoSID = eformat::helper::SourceIdentifier( eformat::TDAQ_CALO_TOPO_PROC, 0 );
225 ATH_MSG_WARNING(
"Source ID in L1TopoRDO was zero, no properties available for slink counter " << slink
226 <<
", so as a fall back, constructed module 0 with source ID "
229 const std::vector<uint32_t>& dataVec = l1TopoResultVec.at(slink).rdo().getDataWords();
230 uint32_t*
data = newRodData(eventContext, dataVec.size());
231 for (
size_t i=0; i<dataVec.size(); ++i) {
232 ATH_MSG_VERBOSE(
" " << MSG::hex << std::setw(8) << std::showbase << dataVec.at(i) << std::noshowbase << MSG::dec);
233 data[i] = dataVec.at(i);
235 addRob(topoSID, dataVec.size(),
data);
239 return StatusCode::SUCCESS;
243 const EventContext& eventContext)
const {
246 ATH_MSG_ERROR(
"Conversion from BS to xAOD RoI requested but RoI WriteHandleKey is empty");
247 return StatusCode::FAILURE;
252 std::vector< ROIB::JetEnergyResult > jetEnergyResult(2);
253 std::vector< ROIB::EMTauResult > eMTauResult(4);
254 std::vector< ROIB::L1TopoResult > l1TopoResult;
257 bool cTPFound =
false;
258 bool muCTPIFound =
false;
259 bool jetEnergyFound[2] = {
false,
false};
260 bool eMTauFound[4] = {
false,
false,
false,
false};
261 bool l1TopoFound =
false;
266 eformat::helper::SourceIdentifier rodSID(robf.rod_source_id());
267 eformat::SubDetector rodSubdetId = rodSID.subdetector_id();
268 uint16_t rodModuleId = rodSID.module_id();
270 switch (rodSubdetId) {
274 case eformat::TDAQ_CTP: {
281 if (rodModuleId !=
m_ctpModuleID && rodModuleId != 0)
continue;
282 if (rodModuleId == 0 && robf.rod_fragment_size_word() != 46)
continue;
286 ATH_MSG_DEBUG(
" Found CTP ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
297 unsigned int ctpVersionNumber = ((rod[CTPdataformat::Helper::FormatVersionPos] >> CTPdataformat::CTPFormatVersionShift) & CTPdataformat::CTPFormatVersionMask);
300 cTPResult =
ROIB::CTPResult(ctpVersionNumber, std::move(
header), std::move(trailer), std::move(content));
307 case eformat::TDAQ_MUON_CTP_INTERFACE: {
315 ATH_MSG_DEBUG(
" Found MuCTPI ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
331 case eformat::TDAQ_CALO_JET_PROC_ROI: {
340 jetEnergyFound[
index] =
true;
341 ATH_MSG_DEBUG(
" Found Jet/Energy ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
357 case eformat::TDAQ_CALO_CLUSTER_PROC_ROI: {
366 eMTauFound[
index] =
true;
367 ATH_MSG_DEBUG(
" Found EM/Tau ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
383 case eformat::TDAQ_CALO_TOPO_PROC: {
392 ATH_MSG_DEBUG(
" Found L1Topo ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
401 content.setStatusWords({status.status_word, status.status_info});
409 l1TopoResult.emplace_back(std::move(
header), std::move(trailer), std::move(content));
414 ATH_MSG_DEBUG(
"Skipping ROD with SubDetID " << rodSID.human_detector());
421 ATH_MSG_DEBUG(
"Building RoIBResult with the following inputs:");
422 ATH_MSG_DEBUG(
" CTP - " << (cTPFound ?
"found" :
"not found"));
423 ATH_MSG_DEBUG(
" MUCTPI - " << (muCTPIFound ?
"found" :
"not found"));
424 ATH_MSG_DEBUG(
" Jet/Energy[0/1] - " << (jetEnergyFound[0] ?
"found" :
"not found") <<
"/"
425 << (jetEnergyFound[1] ?
"found" :
"not found"));
426 ATH_MSG_DEBUG(
" EM/Tau[0/1/2/3] - " << (eMTauFound[0] ?
"found" :
"not found") <<
"/"
427 << (eMTauFound[1] ?
"found" :
"not found") <<
"/"
428 << (eMTauFound[2] ?
"found" :
"not found") <<
"/"
429 << (eMTauFound[3] ?
"found" :
"not found"));
430 ATH_MSG_DEBUG(
" L1Topo - " << (l1TopoFound ?
"found" :
"not found"));
435 ATH_CHECK(roibResult.record(std::make_unique<ROIB::RoIBResult>(std::move(muCTPIResult), std::move(cTPResult), std::move(jetEnergyResult), std::move(eMTauResult))));
439 if (l1TopoFound) roibResult->l1TopoResult(std::move(l1TopoResult));
441 return StatusCode::SUCCESS;
447 uint32_t formatVersion = rob.rod_version();
448 uint32_t evtNum = rob.rod_lvl1_id();
449 uint32_t robFragSize = rob.fragment_size_word();
450 uint32_t rodFragSize = rob.rod_fragment_size_word();
451 uint32_t robId = rob.source_id();
452 uint32_t rodId = rob.rod_source_id();
463 catch (std::exception
const & ex) {
471 catch (std::exception
const & ex) {
478 rob.rod_status(status);
479 uint32_t nstatus = rob.rod_nstatus();
481 if (msgLvl(MSG::VERBOSE)) {
482 for (uint32_t i=0; i<nstatus; ++i, ++status) {
483 ATH_MSG_VERBOSE(
" Status word: 0x" << MSG::hex << std::setw(8) << std::setfill(
'0') << *status);
486 rob.rod_status(status);
488 if(nstatus > 0) dataStatus.
status_word =
static_cast<uint32_t
>(*status);
491 dataStatus.
status_info =
static_cast<uint32_t
>(*status);
494 ATH_MSG_DEBUG(
"ROB ID 0x" << MSG::hex << robId <<
" ROD ID 0x" << rodId << MSG::dec <<
" ROB fragment size "
495 << robFragSize <<
" ROD fragment size " << rodFragSize);