164 ATH_CHECK(jJContainer.record(std::make_unique<xAOD::jFexSRJetRoIContainer>(), std::make_unique<xAOD::jFexSRJetRoIAuxContainer>()));
165 ATH_MSG_DEBUG(
"Recorded jFexSRJetRoIContainer with key " << jJContainer.key());
169 ATH_CHECK(jLJContainer.record(std::make_unique<xAOD::jFexLRJetRoIContainer>(), std::make_unique<xAOD::jFexLRJetRoIAuxContainer>()));
170 ATH_MSG_DEBUG(
"Recorded jFexLRJetRoIContainer with key " << jLJContainer.key());
174 ATH_CHECK(jTauContainer.record(std::make_unique<xAOD::jFexTauRoIContainer>(), std::make_unique<xAOD::jFexTauRoIAuxContainer>()));
175 ATH_MSG_DEBUG(
"Recorded jFexTauRoIContainer with key " << jTauContainer.key());
179 ATH_CHECK(jEMContainer.record(std::make_unique<xAOD::jFexFwdElRoIContainer>(), std::make_unique<xAOD::jFexFwdElRoIAuxContainer>()));
180 ATH_MSG_DEBUG(
"Recorded jFexFwdElRoIContainer with key " << jEMContainer.key());
184 ATH_CHECK(jTEContainer.record(std::make_unique<xAOD::jFexSumETRoIContainer>(), std::make_unique<xAOD::jFexSumETRoIAuxContainer>()));
185 ATH_MSG_DEBUG(
"Recorded jFexSumETRoIContainer with key " << jTEContainer.key());
189 ATH_CHECK(jXEContainer.record(std::make_unique<xAOD::jFexMETRoIContainer>(), std::make_unique<xAOD::jFexMETRoIAuxContainer>()));
190 ATH_MSG_DEBUG(
"Recorded jFexMETRoIContainer with key " << jXEContainer.key());
196 for (
const ROBF* rob : vrobf) {
199 ATH_MSG_DEBUG(
"Starting to decode " << rob->rod_ndata() <<
" ROD words from ROB 0x" << std::hex << rob->rob_source_id() << std::dec);
202 if(rob->rod_ndata() <= 0){
203 std::stringstream sdetail;
204 sdetail <<
"Not enough ROB words to read: "<<rob->rod_ndata() ;
205 std::stringstream slocation;
206 slocation <<
"0x"<< std::hex << rob->rob_source_id();
207 std::stringstream stitle;
208 stitle <<
"Invalid amount of ROB words" ;
209 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
214 const auto dataArray =
std::span{rob->rod_data(), rob->rod_ndata()};
215 std::vector<uint32_t> vec_words(dataArray.begin(),dataArray.end());
217 std::stringstream myPrint;
219 myPrint <<
"jFEX TOB words to decode:"<< std::endl;
221 for (
const uint32_t word : vec_words) {
222 myPrint << aux <<
" raw word ---> 0x"<< std::hex << word << std::dec << std::endl;
228 bool READ_TOBS =
true;
230 unsigned int trailers_pos = rob->rod_ndata() - jBits::ROD_WORDS;
232 if(vec_words.size() < (jBits::ROD_WORDS+jBits::jFEX2ROD_WORDS) || trailers_pos < (jBits::ROD_WORDS+jBits::jFEX2ROD_WORDS) ){
233 std::stringstream sdetail;
234 sdetail <<
"Not enough jFEX TOB words to decode (<4). Number of word to decode: "<<vec_words.size()<<
". Position within the vector: "<<trailers_pos ;
235 std::stringstream slocation;
236 slocation <<
"0x"<< std::hex << rob->rob_source_id();
237 std::stringstream stitle;
238 stitle <<
"Less than 4 trailers" ;
239 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
245 const auto [RODerror] =
RODTrailer ( vec_words.at(rob->rod_ndata()-2), vec_words.at(rob->rod_ndata()-1) );
249 bool corTrailer = ((RODerror >> jBits::ROD_ERROR_CORR_TRAILER ) & jBits::ROD_TRAILER_1b);
250 bool payloadCRC = ((RODerror >> jBits::ROD_ERROR_PAYLOAD_CRC ) & jBits::ROD_TRAILER_1b);
251 bool headerCRC = ((RODerror >> jBits::ROD_ERROR_HEADER_CRC ) & jBits::ROD_TRAILER_1b);
252 bool reserved = ((RODerror >> jBits::ROD_ERROR_RESERVED ) & jBits::ROD_TRAILER_1b);
253 bool lenerror = ((RODerror >> jBits::ROD_ERROR_LENGTH_MISMATCH ) & jBits::ROD_TRAILER_1b);
254 bool headmismatch = ((RODerror >> jBits::ROD_ERROR_HEADER_MISMATCH ) & jBits::ROD_TRAILER_1b);
255 bool processerror = ((RODerror >> jBits::ROD_ERROR_PROC_TIMEOUT ) & jBits::ROD_TRAILER_1b);
257 std::stringstream sdetail;
258 sdetail <<
"ROD Trailer Error bits set - 7-bits error word: 0x"<< std::hex <<RODerror << std::dec<< std::endl;
259 sdetail <<
"Corrective Trailer: "<< corTrailer << std::endl;
260 sdetail <<
"Payload CRC : "<< payloadCRC << std::endl;
261 sdetail <<
"Header CRC : "<< headerCRC << std::endl;
262 sdetail <<
"Reserved (=0) : "<< reserved << std::endl;
263 sdetail <<
"Length Mismatch : "<< lenerror << std::endl;
264 sdetail <<
"Header Mismatch : "<< headmismatch << std::endl;
265 sdetail <<
"Processor timeout : "<< processerror << std::endl;
266 std::stringstream slocation;
267 slocation <<
"ROD Error";
271 std::stringstream stitle;
272 stitle <<
"Corrective Trailer" ;
273 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
274 return StatusCode::FAILURE;
277 std::stringstream stitle;
278 stitle <<
"Payload CRC" ;
279 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
280 return StatusCode::FAILURE;
283 std::stringstream stitle;
284 stitle <<
"Header CRC" ;
285 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
286 return StatusCode::FAILURE;
289 std::stringstream stitle;
290 stitle <<
"Length mismatch" ;
291 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
292 return StatusCode::FAILURE;
295 std::stringstream stitle;
296 stitle <<
"Header mismatch" ;
297 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
298 return StatusCode::FAILURE;
301 std::stringstream stitle;
302 stitle <<
"Processor Timeout" ;
303 printError(slocation.str(),stitle.str(),MSG::ERROR,stitle.str() +
" - "+ sdetail.str());
304 return StatusCode::FAILURE;
307 return StatusCode::FAILURE;
313 const auto [n_xjJ, n_xjLJ, n_xjTau, n_xjEM] =
xTOBCounterTrailer( vec_words.at(trailers_pos-3) );
314 const auto [n_jJ, n_jLJ, n_jTau, n_jEM, n_jTE, n_jXE] =
TOBCounterTrailer ( vec_words.at(trailers_pos-4) );
315 unsigned int n_tobs = n_jJ + n_jLJ + n_jTau + n_jEM + n_jTE + n_jXE;
316 unsigned int n_xtobs = n_xjJ + n_xjLJ + n_xjTau + n_xjEM;
317 unsigned int total_tobs = n_tobs+n_xtobs;
324 unsigned int paddingWord = 0;
326 ATH_MSG_DEBUG(
"Odd number of TOBs + xTOBs:"<< total_tobs<<
", there is a padding word!");
332 bool corTrailer = ((
error >> jBits::ERROR_CORR_TRAILER ) & jBits::ROD_TRAILER_1b);
333 bool safemode = ((
error >> jBits::ERROR_SAFE_MODE ) & jBits::ROD_TRAILER_1b);
334 bool proterror = ((
error >> jBits::ERROR_PROTOCOL_ERROR ) & jBits::ROD_TRAILER_1b);
335 bool lenerror = ((
error >> jBits::ERROR_LENGTH_MISMATCH ) & jBits::ROD_TRAILER_1b);
336 bool headmismatch = ((
error >> jBits::ERROR_HEADER_MISMATCH ) & jBits::ROD_TRAILER_1b);
337 bool processerror = ((
error >> jBits::ERROR_PROC_TIMEOUT ) & jBits::ROD_TRAILER_1b);
339 std::stringstream sdetail;
340 sdetail <<
"jFEX to ROD Trailer Error bits set - 6-bits error word: 0x"<< std::hex <<
error << std::dec<< std::endl;
341 sdetail <<
"Corrective Trailer: "<< corTrailer << std::endl;
342 sdetail <<
"Safe Mode : "<< safemode << std::endl;
343 sdetail <<
"Protocol error : "<< proterror << std::endl;
344 sdetail <<
"Length Mismatch : "<< lenerror << std::endl;
345 sdetail <<
"Header Mismatch : "<< headmismatch << std::endl;
346 sdetail <<
"Processor timeout : "<< processerror << std::endl;
347 std::stringstream slocation;
348 slocation <<
"Error bit set";
351 std::stringstream stitle;
352 stitle <<
"Corrective Trailer" ;
353 printError(slocation.str(),stitle.str(),MSG::ERROR,sdetail.str());
356 return StatusCode::FAILURE;
359 std::stringstream stitle;
360 stitle <<
"Safe Mode" ;
361 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
364 std::stringstream stitle;
365 stitle <<
"Protocol error" ;
366 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
369 std::stringstream stitle;
370 stitle <<
"Length mismatch" ;
374 std::stringstream stitle;
375 stitle <<
"Header mismatch" ;
379 std::stringstream stitle;
380 stitle <<
"Processor Timeout" ;
386 if(
payload != (total_tobs + jBits::TOB_TRAILERS + paddingWord)){
387 std::stringstream sdetail;
388 sdetail <<
"Payload="<<
payload<<
" is different from TOBs+Trailers+padding words="<< total_tobs + jBits::TOB_TRAILERS + paddingWord <<
" in FPGA: "<< fpga <<
" and jFEX: "<< jfex <<
". SKIPPED!" ;
389 std::stringstream slocation;
390 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
391 std::stringstream stitle;
392 stitle <<
"Wrong payload" ;
393 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
396 int neg_positions = trailers_pos - (
payload + jBits::TOB_TRAILERS);
398 if(neg_positions < 0){
399 std::stringstream sdetail;
400 sdetail <<
"jFEX TOB decoder has discarded the whole event. Due to a wrong payload cannot continue decoding" ;
401 std::stringstream slocation;
402 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
403 std::stringstream stitle;
404 stitle <<
"Event discarded" ;
411 trailers_pos -= (
payload+jBits::TOB_TRAILERS);
414 if(trailers_pos == 0) {
421 if(
payload < jBits::TOB_TRAILERS){
422 std::stringstream sdetail;
423 sdetail <<
"Payload: "<<
payload<<
" is lower than the expected size (at least" << jBits::TOB_TRAILERS <<
"trailers)" ;
424 std::stringstream slocation;
425 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
426 std::stringstream stitle;
427 stitle <<
"Event discarded" ;
429 printError(slocation.str(),stitle.str(),MSG::WARNING,sdetail.str());
434 unsigned int tobIndex = trailers_pos - (jBits::jFEX2ROD_WORDS + jBits::TOB_TRAILERS + paddingWord);
436 if(paddingWord == 1){
437 ATH_MSG_DEBUG(
"Padding word: "<< std::hex << vec_words.at(tobIndex) <<std::dec);
444 for(
unsigned int i=tobIndex;
i>tobIndex-n_xjEM;
i--) {
445 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jEM xTOB");
446 jEMContainer->push_back( std::make_unique<xAOD::jFexFwdElRoI>() );
447 jEMContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),0,
m_jEMRes,
eta,
phi);
453 for(
unsigned int i=tobIndex;
i>tobIndex-n_xjTau;
i--) {
454 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jTau xTOB");
455 jTauContainer->push_back( std::make_unique<xAOD::jFexTauRoI>() );
456 jTauContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),0,
m_jTauRes,
eta,
phi);
462 for(
unsigned int i=tobIndex;
i>tobIndex-n_xjLJ;
i--) {
463 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jLJ xTOB");
464 jLJContainer->push_back( std::make_unique<xAOD::jFexLRJetRoI>() );
465 jLJContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),0,
m_jLJRes,
eta,
phi);
471 for(
unsigned int i=tobIndex;
i>tobIndex-n_xjJ;
i--) {
472 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jJ xTOB");
473 jJContainer->push_back( std::make_unique<xAOD::jFexSRJetRoI>() );
474 jJContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),0,
m_jJRes,
eta,
phi);
491 if(fpga == jBits::FPGA_U1 || fpga == jBits::FPGA_U4 ){
492 for(
unsigned int i=tobIndex;
i>tobIndex-n_jXE;
i--) {
493 jXEContainer->push_back( std::make_unique<xAOD::jFexMETRoI>() );
494 jXEContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),
m_jXERes);
502 if(fpga == jBits::FPGA_U1 || fpga == jBits::FPGA_U4 ) {
503 for(
unsigned int i=tobIndex;
i>tobIndex-n_jTE;
i--) {
504 jTEContainer->push_back( std::make_unique<xAOD::jFexSumETRoI>() );
505 jTEContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),
m_jTERes);
512 for(
unsigned int i=tobIndex;
i>tobIndex-n_jEM;
i--) {
513 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jEM TOB");
514 jEMContainer->push_back( std::make_unique<xAOD::jFexFwdElRoI>() );
515 jEMContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),1,
m_jEMRes,
eta,
phi);
521 for(
unsigned int i=tobIndex;
i>tobIndex-n_jTau;
i--) {
522 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jTau TOB");
523 jTauContainer->push_back( std::make_unique<xAOD::jFexTauRoI>() );
524 jTauContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),1,
m_jTauRes,
eta,
phi);
530 for(
unsigned int i=tobIndex;
i>tobIndex-n_jLJ;
i--) {
531 const auto [
eta,
phi ] =
getEtaPhi(jfex, fpga, vec_words.at(
i-1),
"jLJ TOB");
532 jLJContainer->push_back( std::make_unique<xAOD::jFexLRJetRoI>() );
533 jLJContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),1,
m_jLJRes,
eta,
phi);
539 for(
unsigned int i=tobIndex;
i>tobIndex-n_jJ;
i--) {
541 jJContainer->push_back( std::make_unique<xAOD::jFexSRJetRoI>() );
542 jJContainer->back()->initialize(jfex, fpga, vec_words.at(
i-1),1,
m_jJRes,
eta,
phi);
548 trailers_pos -= (
payload + jBits::jFEX2ROD_WORDS);
550 if(trailers_pos != tobIndex){
551 std::stringstream sdetail;
552 sdetail <<
"Something went wrong decoding jFEX BS data. Trailer position: " << trailers_pos <<
" should match the TOB index position:" << tobIndex ;
553 std::stringstream slocation;
554 slocation <<
"jFEX "<< jfex <<
" FPGA "<< fpga <<
" in 0x"<< std::hex << rob->rob_source_id();
555 std::stringstream stitle;
556 stitle <<
"Wrong amount of words" ;
558 printError(slocation.str(),stitle.str(),MSG::ERROR,sdetail.str());
560 return StatusCode::FAILURE;
564 if(trailers_pos == 0){
570 return StatusCode::SUCCESS;