150 ATH_CHECK(jJContainer.
record(std::make_unique<xAOD::jFexSRJetRoIContainer>(), std::make_unique<xAOD::jFexSRJetRoIAuxContainer>()));
151 ATH_MSG_DEBUG(
"Recorded jFexSRJetRoIContainer with key " << jJContainer.
key());
155 ATH_CHECK(jLJContainer.
record(std::make_unique<xAOD::jFexLRJetRoIContainer>(), std::make_unique<xAOD::jFexLRJetRoIAuxContainer>()));
156 ATH_MSG_DEBUG(
"Recorded jFexLRJetRoIContainer with key " << jLJContainer.
key());
160 ATH_CHECK(jTauContainer.
record(std::make_unique<xAOD::jFexTauRoIContainer>(), std::make_unique<xAOD::jFexTauRoIAuxContainer>()));
161 ATH_MSG_DEBUG(
"Recorded jFexTauRoIContainer with key " << jTauContainer.
key());
165 ATH_CHECK(jEMContainer.
record(std::make_unique<xAOD::jFexFwdElRoIContainer>(), std::make_unique<xAOD::jFexFwdElRoIAuxContainer>()));
166 ATH_MSG_DEBUG(
"Recorded jFexFwdElRoIContainer with key " << jEMContainer.
key());
170 ATH_CHECK(jTEContainer.
record(std::make_unique<xAOD::jFexSumETRoIContainer>(), std::make_unique<xAOD::jFexSumETRoIAuxContainer>()));
171 ATH_MSG_DEBUG(
"Recorded jFexSumETRoIContainer with key " << jTEContainer.
key());
175 ATH_CHECK(jXEContainer.
record(std::make_unique<xAOD::jFexMETRoIContainer>(), std::make_unique<xAOD::jFexMETRoIAuxContainer>()));
176 ATH_MSG_DEBUG(
"Recorded jFexMETRoIContainer with key " << jXEContainer.
key());
182 for (
const ROBF* rob : vrobf) {
185 ATH_MSG_DEBUG(
"Starting to decode " << rob->rod_ndata() <<
" ROD words from ROB 0x" << std::hex << rob->rob_source_id() << std::dec);
188 if(rob->rod_ndata() <= 0){
189 std::stringstream sdetail;
190 sdetail <<
"Not enough ROB words to read: "<<rob->rod_ndata() ;
191 std::stringstream slocation;
192 slocation <<
"0x"<< std::hex << rob->rob_source_id();
193 std::stringstream stitle;
194 stitle <<
"Invalid amount of ROB words" ;
195 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
200 const auto dataArray = std::span{rob->rod_data(), rob->rod_ndata()};
201 std::vector<uint32_t> vec_words(dataArray.begin(),dataArray.end());
203 std::stringstream myPrint;
205 myPrint <<
"jFEX TOB words to decode:"<< std::endl;
207 for (
const uint32_t word : vec_words) {
208 myPrint << aux <<
" raw word ---> 0x"<< std::hex << word << std::dec << std::endl;
214 bool READ_TOBS =
true;
219 std::stringstream sdetail;
220 sdetail <<
"Not enough jFEX TOB words to decode (<4). Number of word to decode: "<<vec_words.size()<<
". Position within the vector: "<<trailers_pos ;
221 std::stringstream slocation;
222 slocation <<
"0x"<< std::hex << rob->rob_source_id();
223 std::stringstream stitle;
224 stitle <<
"Less than 4 trailers" ;
225 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
231 const auto [RODerror] =
RODTrailer ( vec_words.at(rob->rod_ndata()-2), vec_words.at(rob->rod_ndata()-1) );
243 std::stringstream sdetail;
244 sdetail <<
"ROD Trailer Error bits set - 7-bits error word: 0x"<< std::hex <<RODerror << std::dec<< std::endl;
245 sdetail <<
"Corrective Trailer: "<< corTrailer << std::endl;
246 sdetail <<
"Payload CRC : "<< payloadCRC << std::endl;
247 sdetail <<
"Header CRC : "<< headerCRC << std::endl;
248 sdetail <<
"Reserved (=0) : "<< reserved << std::endl;
249 sdetail <<
"Length Mismatch : "<< lenerror << std::endl;
250 sdetail <<
"Header Mismatch : "<< headmismatch << std::endl;
251 sdetail <<
"Processor timeout : "<< processerror << std::endl;
252 std::stringstream slocation;
253 slocation <<
"ROD Error";
257 std::stringstream stitle;
258 stitle <<
"Corrective Trailer" ;
259 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
260 return StatusCode::FAILURE;
263 std::stringstream stitle;
264 stitle <<
"Payload CRC" ;
265 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
266 return StatusCode::FAILURE;
269 std::stringstream stitle;
270 stitle <<
"Header CRC" ;
271 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
272 return StatusCode::FAILURE;
275 std::stringstream stitle;
276 stitle <<
"Length mismatch" ;
277 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
278 return StatusCode::FAILURE;
281 std::stringstream stitle;
282 stitle <<
"Header mismatch" ;
283 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
284 return StatusCode::FAILURE;
287 std::stringstream stitle;
288 stitle <<
"Processor Timeout" ;
289 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
290 return StatusCode::FAILURE;
293 return StatusCode::FAILURE;
298 const auto [payload, fpga, jfex,
error] =
jFEXtoRODTrailer ( vec_words.at(trailers_pos-2), vec_words.at(trailers_pos-1) );
299 const auto [n_xjJ, n_xjLJ, n_xjTau, n_xjEM] =
xTOBCounterTrailer( vec_words.at(trailers_pos-3) );
300 const auto [n_jJ, n_jLJ, n_jTau, n_jEM, n_jTE, n_jXE] =
TOBCounterTrailer ( vec_words.at(trailers_pos-4) );
301 unsigned int n_tobs = n_jJ + n_jLJ + n_jTau + n_jEM + n_jTE + n_jXE;
302 unsigned int n_xtobs = n_xjJ + n_xjLJ + n_xjTau + n_xjEM;
303 unsigned int total_tobs = n_tobs+n_xtobs;
310 unsigned int paddingWord = 0;
312 ATH_MSG_DEBUG(
"Odd number of TOBs + xTOBs:"<< total_tobs<<
", there is a padding word!");
325 std::stringstream sdetail;
326 sdetail <<
"jFEX to ROD Trailer Error bits set - 6-bits error word: 0x"<< std::hex <<
error << std::dec<< std::endl;
327 sdetail <<
"Corrective Trailer: "<< corTrailer << std::endl;
328 sdetail <<
"Safe Mode : "<< safemode << std::endl;
329 sdetail <<
"Protocol error : "<< proterror << std::endl;
330 sdetail <<
"Length Mismatch : "<< lenerror << std::endl;
331 sdetail <<
"Header Mismatch : "<< headmismatch << std::endl;
332 sdetail <<
"Processor timeout : "<< processerror << std::endl;
333 std::stringstream slocation;
334 slocation <<
"Error bit set";
337 std::stringstream stitle;
338 stitle <<
"Corrective Trailer" ;
339 printError(slocation.str(),stitle.str(),MSG::ERROR,sdetail.str());
342 return StatusCode::FAILURE;
345 std::stringstream stitle;
346 stitle <<
"Safe Mode" ;
347 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
350 std::stringstream stitle;
351 stitle <<
"Protocol error" ;
352 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
355 std::stringstream stitle;
356 stitle <<
"Length mismatch" ;
357 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
360 std::stringstream stitle;
361 stitle <<
"Header mismatch" ;
362 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
365 std::stringstream stitle;
366 stitle <<
"Processor Timeout" ;
367 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
373 std::stringstream sdetail;
374 sdetail <<
"Payload="<< payload<<
" is different from TOBs+Trailers+padding words="<< total_tobs +
jBits::TOB_TRAILERS + paddingWord <<
" in FPGA: "<< fpga <<
" and jFEX: "<< jfex <<
". SKIPPED!" ;
375 std::stringstream slocation;
376 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
377 std::stringstream stitle;
378 stitle <<
"Wrong payload" ;
379 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
384 if(neg_positions < 0){
385 std::stringstream sdetail;
386 sdetail <<
"jFEX TOB decoder has discarded the whole event. Due to a wrong payload cannot continue decoding" ;
387 std::stringstream slocation;
388 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
389 std::stringstream stitle;
390 stitle <<
"Event discarded" ;
392 printError(slocation.str(),stitle.str(),MSG::DEBUG,sdetail.str());
400 if(trailers_pos == 0) {
408 std::stringstream sdetail;
409 sdetail <<
"Payload: "<< payload<<
" is lower than the expected size (at least" <<
jBits::TOB_TRAILERS <<
"trailers)" ;
410 std::stringstream slocation;
411 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
412 std::stringstream stitle;
413 stitle <<
"Event discarded" ;
415 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
422 if(paddingWord == 1){
423 ATH_MSG_DEBUG(
"Padding word: "<< std::hex << vec_words.at(tobIndex) <<std::dec);
430 for(
unsigned int i=tobIndex; i>tobIndex-n_xjEM; i--) {
431 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jEM xTOB");
432 jEMContainer->push_back( std::make_unique<xAOD::jFexFwdElRoI>() );
433 jEMContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),0,
m_jEMRes,
eta,
phi);
439 for(
unsigned int i=tobIndex; i>tobIndex-n_xjTau; i--) {
440 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jTau xTOB");
441 jTauContainer->push_back( std::make_unique<xAOD::jFexTauRoI>() );
442 jTauContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),0,
m_jTauRes,
eta,
phi);
459 for(
unsigned int i=tobIndex; i>tobIndex-n_xjJ; i--) {
460 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jJ xTOB");
461 jJContainer->push_back( std::make_unique<xAOD::jFexSRJetRoI>() );
462 jJContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),0,
m_jJRes,
eta,
phi);
480 for(
unsigned int i=tobIndex; i>tobIndex-n_jXE; i--) {
481 jXEContainer->push_back( std::make_unique<xAOD::jFexMETRoI>() );
482 jXEContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),
m_jXERes);
491 for(
unsigned int i=tobIndex; i>tobIndex-n_jTE; i--) {
492 jTEContainer->push_back( std::make_unique<xAOD::jFexSumETRoI>() );
493 jTEContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),
m_jTERes);
500 for(
unsigned int i=tobIndex; i>tobIndex-n_jEM; i--) {
501 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jEM TOB");
502 jEMContainer->push_back( std::make_unique<xAOD::jFexFwdElRoI>() );
503 jEMContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),1,
m_jEMRes,
eta,
phi);
509 for(
unsigned int i=tobIndex; i>tobIndex-n_jTau; i--) {
510 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jTau TOB");
511 jTauContainer->push_back( std::make_unique<xAOD::jFexTauRoI>() );
512 jTauContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),1,
m_jTauRes,
eta,
phi);
518 for(
unsigned int i=tobIndex; i>tobIndex-n_jLJ; i--) {
519 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jLJ TOB");
520 jLJContainer->push_back( std::make_unique<xAOD::jFexLRJetRoI>() );
521 jLJContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),1,
m_jLJRes,
eta,
phi);
527 for(
unsigned int i=tobIndex; i>tobIndex-n_jJ; i--) {
528 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(i-1),
"jJ TOB");
529 jJContainer->push_back( std::make_unique<xAOD::jFexSRJetRoI>() );
530 jJContainer->back()->initialize(jfex, fpga, vec_words.at(i-1),1,
m_jJRes,
eta,
phi);
538 if(trailers_pos != tobIndex){
539 std::stringstream sdetail;
540 sdetail <<
"Something went wrong decoding jFEX BS data. Trailer position: " << trailers_pos <<
" should match the TOB index position:" << tobIndex ;
541 std::stringstream slocation;
542 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
543 std::stringstream stitle;
544 stitle <<
"Wrong amount of words" ;
546 printError(slocation.str(),stitle.str(),MSG::ERROR,sdetail.str());
548 return StatusCode::FAILURE;
552 if(trailers_pos == 0){
558 return StatusCode::SUCCESS;
795 const EventContext& eventContext) {
798 if (
tc && !
tc->empty()) {
800 bucketContainer<xAOD::jFexSRJetRoI >(l1, blocks);
801 bucketContainer<xAOD::jFexLRJetRoI >(l1, blocks);
802 bucketContainer<xAOD::jFexTauRoI >(l1, blocks);
803 bucketContainer<xAOD::jFexFwdElRoI >(l1, blocks);
804 bucketContainer<xAOD::jFexMETRoI >(l1, blocks);
805 bucketContainer<xAOD::jFexSumETRoI >(l1, blocks);
808 std::vector<uint32_t> words;
809 for (
const auto& [key, blk] : blocks) {
810 const uint32_t jfex = key.first;
811 const uint32_t fpga = key.second;
813 const uint32_t n_jJ = blk.jJ.size();
814 const uint32_t n_jLJ = blk.jLJ.size();
815 const uint32_t n_jTau = blk.jTau.size();
816 const uint32_t n_jEM = blk.jEM.size();
817 const uint32_t n_jTE = blk.jTE.size();
818 const uint32_t n_jXE = blk.jXE.size();
819 const uint32_t n_xjJ = blk.xjJ.size();
820 const uint32_t n_xjLJ = blk.xjLJ.size();
821 const uint32_t n_xjTau = blk.xjTau.size();
822 const uint32_t n_xjEM = blk.xjEM.size();
824 const uint32_t total_tobs = n_jJ + n_jLJ + n_jTau + n_jEM + n_jTE + n_jXE
825 + n_xjJ + n_xjLJ + n_xjTau + n_xjEM;
826 const uint32_t paddingWord = (total_tobs % 2 == 0) ? 0 : 1;
834 for (uint32_t w : blk.jJ) words.push_back(w);
835 for (uint32_t w : blk.jLJ) words.push_back(w);
836 for (uint32_t w : blk.jTau) words.push_back(w);
837 for (uint32_t w : blk.jEM) words.push_back(w);
838 for (uint32_t w : blk.jTE) words.push_back(w);
839 for (uint32_t w : blk.jXE) words.push_back(w);
840 for (uint32_t w : blk.xjJ) words.push_back(w);
841 for (uint32_t w : blk.xjLJ) words.push_back(w);
842 for (uint32_t w : blk.xjTau) words.push_back(w);
843 for (uint32_t w : blk.xjEM) words.push_back(w);
844 if (paddingWord) words.push_back(0);
847 n_jTE > 0, n_jXE > 0));
850 words.push_back(rod[0]);
851 words.push_back(rod[1]);
858 clearCache(eventContext);
859 uint32_t*
data = newRodData(eventContext, words.size());
860 std::copy(words.begin(), words.end(),
data);
863 eformat::helper::SourceIdentifier sid(eformat::TDAQ_CALO_FEAT_EXTRACT_ROI, 0x2000);
864 vrobf.push_back(newRobFragment(eventContext, sid.code(), words.size(),
data, 0));
866 return StatusCode::SUCCESS;