9 #include "CTPfragment/CTPdataformat.h"
10 #include "CTPfragment/CTPfragment.h"
18 #include "eformat/SourceIdentifier.h"
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) {
126 return StatusCode::SUCCESS;
130 const EventContext& eventContext) {
135 auto addRob = [&](
const eformat::helper::SourceIdentifier& sid,
const size_t ndata,
const uint32_t*
data){
136 vrobf.push_back(newRobFragment(eventContext, sid.code(), ndata,
data,
m_detEvType));
139 auto convertDataToRob = [&](
const eformat::helper::SourceIdentifier& sid,
const auto& dataVec){
140 uint32_t*
data = newRodData(eventContext, dataVec.size());
142 for (
size_t i=0;
i<dataVec.size(); ++
i) {
143 ATH_MSG_VERBOSE(
" 0x" << MSG::hex << std::setw(8) << dataVec.at(
i).roIWord() << MSG::dec);
144 data[
i] = dataVec.at(
i).roIWord();
146 return addRob(sid, dataVec.size(),
data);
151 const eformat::helper::SourceIdentifier ctpSID{eformat::TDAQ_CTP,
m_ctpModuleID};
152 const std::vector<ROIB::CTPRoI>& ctpDataVec = roibResult->cTPResult().roIVec();
156 rob->rod_minor_version(roibResult->cTPResult().header().formatVersion() & 0xffffu);
164 constexpr
size_t word_size = 32;
165 constexpr
size_t words_per_set = 512 / word_size;
166 constexpr
size_t num_words = 3 * words_per_set;
167 uint32_t* l1bits_data = newRodData(eventContext, num_words);
169 for (
const std::bitset<512>& bset : {tbp,
tap, tav}) {
170 const std::string
sbits = bset.to_string();
171 const size_t iword_output_start = words_per_set * iset;
172 for (
size_t iword_in_set = 0; iword_in_set < words_per_set; ++iword_in_set) {
173 const size_t bword_pos = 512 - (iword_in_set+1) * word_size;
174 std::bitset<word_size> bword{
sbits.substr(bword_pos, word_size)};
175 l1bits_data[iword_output_start + iword_in_set] =
static_cast<uint32_t>(bword.to_ulong());
179 rawEvent->lvl1_trigger_info(num_words, l1bits_data);
188 const eformat::helper::SourceIdentifier muctpiSID{eformat::TDAQ_MUON_CTP_INTERFACE,
m_muCTPIModuleID};
189 const std::vector<ROIB::MuCTPIRoI>& muctpiDataVec = roibResult->muCTPIResult().roIVec();
190 convertDataToRob(muctpiSID, muctpiDataVec);
195 const std::vector<ROIB::JetEnergyResult>& jetEnergyResultVec = roibResult->jetEnergyResult();
196 for (
size_t slink=0; slink<jetEnergyResultVec.size(); ++slink) {
197 const eformat::helper::SourceIdentifier jetSID{eformat::TDAQ_CALO_JET_PROC_ROI,
m_jetModuleID.value().at(slink)};
198 convertDataToRob(jetSID, jetEnergyResultVec.at(slink).roIVec());
204 const std::vector<ROIB::EMTauResult>& emTauResultVec = roibResult->eMTauResult();
205 for (
size_t slink=0; slink<emTauResultVec.size(); ++slink) {
206 const eformat::helper::SourceIdentifier emSID{eformat::TDAQ_CALO_CLUSTER_PROC_ROI,
m_emModuleID.value().at(slink)};
207 convertDataToRob(emSID, emTauResultVec.at(slink).roIVec());
213 const std::vector<ROIB::L1TopoResult>& l1TopoResultVec = roibResult->l1TopoResult();
214 for (
size_t slink=0; slink<l1TopoResultVec.size(); ++slink) {
215 eformat::helper::SourceIdentifier topoSID{l1TopoResultVec.at(slink).rdo().getSourceID()};
218 topoSID = eformat::helper::SourceIdentifier(eformat::TDAQ_CALO_TOPO_PROC,
m_l1TopoModuleID.value().at(slink));
219 ATH_MSG_DEBUG(
"Source ID in L1TopoRDO was zero so using Property for slink " << slink <<
": "
222 else if (topoSID.code() == 0) {
223 topoSID = eformat::helper::SourceIdentifier( eformat::TDAQ_CALO_TOPO_PROC, 0 );
224 ATH_MSG_WARNING(
"Source ID in L1TopoRDO was zero, no properties available for slink counter " << slink
225 <<
", so as a fall back, constructed module 0 with source ID "
228 const std::vector<uint32_t>& dataVec = l1TopoResultVec.at(slink).rdo().getDataWords();
229 uint32_t*
data = newRodData(eventContext, dataVec.size());
230 for (
size_t i=0;
i<dataVec.size(); ++
i) {
231 ATH_MSG_VERBOSE(
" " << MSG::hex << std::setw(8) << std::showbase << dataVec.at(
i) << std::noshowbase << MSG::dec);
234 addRob(topoSID, dataVec.size(),
data);
238 return StatusCode::SUCCESS;
242 const EventContext& eventContext)
const {
245 ATH_MSG_ERROR(
"Conversion from BS to xAOD RoI requested but RoI WriteHandleKey is empty");
246 return StatusCode::FAILURE;
251 std::vector< ROIB::JetEnergyResult > jetEnergyResult(2);
252 std::vector< ROIB::EMTauResult > eMTauResult(4);
253 std::vector< ROIB::L1TopoResult > l1TopoResult;
256 bool cTPFound =
false;
257 bool muCTPIFound =
false;
258 bool jetEnergyFound[2] = {
false,
false};
259 bool eMTauFound[4] = {
false,
false,
false,
false};
260 bool l1TopoFound =
false;
265 eformat::helper::SourceIdentifier rodSID(robf.rod_source_id());
266 eformat::SubDetector rodSubdetId = rodSID.subdetector_id();
267 uint16_t rodModuleId = rodSID.module_id();
269 switch (rodSubdetId) {
273 case eformat::TDAQ_CTP: {
280 if (rodModuleId !=
m_ctpModuleID && rodModuleId != 0)
continue;
281 if (rodModuleId == 0 && robf.rod_fragment_size_word() != 46)
continue;
285 ATH_MSG_DEBUG(
" Found CTP ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
290 std::vector<ROIB::CTPRoI>
content = roibContent<ROIB::CTPRoI>(robf);
296 unsigned int ctpVersionNumber = ((
rod[CTPdataformat::Helper::FormatVersionPos] >> CTPdataformat::CTPFormatVersionShift) & CTPdataformat::CTPFormatVersionMask);
306 case eformat::TDAQ_MUON_CTP_INTERFACE: {
314 ATH_MSG_DEBUG(
" Found MuCTPI ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
319 std::vector<ROIB::MuCTPIRoI>
content = roibContent<ROIB::MuCTPIRoI>(robf);
330 case eformat::TDAQ_CALO_JET_PROC_ROI: {
339 jetEnergyFound[
index] =
true;
340 ATH_MSG_DEBUG(
" Found Jet/Energy ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
345 std::vector<ROIB::JetEnergyRoI>
content = roibContent<ROIB::JetEnergyRoI>(robf);
356 case eformat::TDAQ_CALO_CLUSTER_PROC_ROI: {
365 eMTauFound[
index] =
true;
366 ATH_MSG_DEBUG(
" Found EM/Tau ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
371 std::vector<ROIB::EMTauRoI>
content = roibContent<ROIB::EMTauRoI>(robf);
382 case eformat::TDAQ_CALO_TOPO_PROC: {
391 ATH_MSG_DEBUG(
" Found L1Topo ROD with source ID " << MSG::hex << rodSID.code() << MSG::dec);
408 l1TopoResult.emplace_back(std::move(
header), std::move(trailer), std::move(
content));
413 ATH_MSG_DEBUG(
"Skipping ROD with SubDetID " << rodSID.human_detector());
420 ATH_MSG_DEBUG(
"Building RoIBResult with the following inputs:");
421 ATH_MSG_DEBUG(
" CTP - " << (cTPFound ?
"found" :
"not found"));
422 ATH_MSG_DEBUG(
" MUCTPI - " << (muCTPIFound ?
"found" :
"not found"));
423 ATH_MSG_DEBUG(
" Jet/Energy[0/1] - " << (jetEnergyFound[0] ?
"found" :
"not found") <<
"/"
424 << (jetEnergyFound[1] ?
"found" :
"not found"));
425 ATH_MSG_DEBUG(
" EM/Tau[0/1/2/3] - " << (eMTauFound[0] ?
"found" :
"not found") <<
"/"
426 << (eMTauFound[1] ?
"found" :
"not found") <<
"/"
427 << (eMTauFound[2] ?
"found" :
"not found") <<
"/"
428 << (eMTauFound[3] ?
"found" :
"not found"));
429 ATH_MSG_DEBUG(
" L1Topo - " << (l1TopoFound ?
"found" :
"not found"));
434 ATH_CHECK(roibResult.record(std::make_unique<ROIB::RoIBResult>(std::move(muCTPIResult), std::move(cTPResult), std::move(jetEnergyResult), std::move(eMTauResult))));
438 if (l1TopoFound) roibResult->l1TopoResult(std::move(l1TopoResult));
440 return StatusCode::SUCCESS;
446 uint32_t formatVersion = rob.rod_version();
447 uint32_t evtNum = rob.rod_lvl1_id();
448 uint32_t robFragSize = rob.fragment_size_word();
449 uint32_t rodFragSize = rob.rod_fragment_size_word();
451 uint32_t rodId = rob.rod_source_id();
478 uint32_t nstatus = rob.rod_nstatus();
493 ATH_MSG_DEBUG(
"ROB ID 0x" << MSG::hex << robId <<
" ROD ID 0x" << rodId << MSG::dec <<
" ROB fragment size "
494 << robFragSize <<
" ROD fragment size " << rodFragSize);
500 std::vector<uint32_t>
words;
518 ATH_MSG_VERBOSE(
" 0x" << MSG::hex << std::setfill(
'0') << std::setw(8) << word << MSG::dec);
519 content.push_back(RoIType{word});
530 std::vector<uint32_t> vDataWords;
531 vDataWords.reserve(ndata);
533 ATH_MSG_VERBOSE(
" 0x" << MSG::hex << std::setfill(
'0') << std::setw(8) << word << MSG::dec);
534 vDataWords.push_back(word);
536 content.setDataWords(std::move(vDataWords));
537 content.setSourceID(rob.rod_source_id());