5#ifndef MUONBYTESTREAM_RPCROD_DECODER_H
6#define MUONBYTESTREAM_RPCROD_DECODER_H
12#include "GaudiKernel/GaudiException.h"
13#include "GaudiKernel/ServiceHandle.h"
14#include "GaudiKernel/ToolHandle.h"
27#include "eformat/Issue.h"
28#include "eformat/SourceIdentifier.h"
39 if (printMessage && log.level() <= MSG::WARNING) {
40 log << MSG::WARNING <<
"Unexpected end of RPC data: " << message <<
endmsg;
55 virtual StatusCode
finalize()
override;
61 const bool& decodeSL)
const override;
73 BS data,
const uint32_t data_size,
RpcPad& v,
const uint16_t& subDetector,
81 BS data,
const uint32_t data_size,
RpcPad& v,
const uint32_t& sourceId,
85 BS data,
const uint32_t data_size, std::map<Identifier, RpcPad*>& vmap,
89 inline std::vector<uint16_t>
get16bits(
BS data,
const int size,
const int nHeader,
const int nFooter)
const;
101 Gaudi::Property<int>
m_nobxs {
this,
"NOBXS", 8,
"Number of bunch crossings in readout"};
122 StatusCode
sc = StatusCode::SUCCESS;
127 for (
int i = ini; i < end; i++) {
128 decoded = ((*pdata)[i] & 0xf000) >> 12;
131 if (decoded == 0x9) {
138 sc = StatusCode::FAILURE;
144 else if (decoded == 0xe) {
150 sc = StatusCode::FAILURE;
155 else if (decoded == 0x5) {
161 sc = StatusCode::FAILURE;
167 else if (decoded == 0x6) {
170 }
else if (previous == 8) {
175 sc = StatusCode::FAILURE;
181 else if (decoded == 0xc) {
187 sc = StatusCode::FAILURE;
193 else if (decoded == 0x8) {
199 sc = StatusCode::FAILURE;
205 else if (decoded == 0x4) {
206 if (previous == -1 || previous == 6) {
208 if (matrix.checkCRC8((
ubit16)(*pdata)[i])) {
211 sc = StatusCode::RECOVERABLE;
216 sc = StatusCode::FAILURE;
222 else if (decoded == 0xa) {
228 sc = StatusCode::FAILURE;
234 else if (decoded == 0x7) {
240 sc = StatusCode::FAILURE;
246 else if (decoded == 0xd) {
252 sc = StatusCode::FAILURE;
258 else if (decoded == 0xf) {
259 if (previous == 9 || previous == -1) {
264 sc = StatusCode::FAILURE;
269 else if (decoded == 0xb) {
270 if (previous == 10) {
277 sc = StatusCode::FAILURE;
284 sc = StatusCode::FAILURE;
293 log << MSG::INFO <<
" ============ FINAL RPC DATA FORMAT STAT. =========== " <<
endmsg;
295 log << MSG::INFO <<
" RX Header Errors............." << tmp <<
endmsg;
308 log << MSG::INFO <<
" ==================================================== " <<
endmsg;
313 const std::vector<IdentifierHash>& collections,
317 }
catch (eformat::Issue& ex) {
319 return StatusCode::FAILURE;
322 if (RPC_SECTORLOGIC ==
nullptr) {
ATH_MSG_DEBUG(
"RPC_SECTORLOGIC is null, so we will skip decoding the sector logic information"); }
326 robFrag.rod_data(
data);
329 uint32_t version = robFrag.rod_version();
330 uint32_t sourceId = robFrag.source_id();
331 uint32_t rod_sourceId = robFrag.rod_source_id();
332 uint16_t subDetector = (sourceId & 0xff0000) >> 16;
334 ATH_MSG_VERBOSE(
"ROD version: " << MSG::hex << version << MSG::dec <<
" ROB source ID: " << MSG::hex << sourceId << MSG::dec
335 <<
" ROD source ID: " << MSG::hex << rod_sourceId << MSG::dec <<
" Subdetector: " << MSG::hex
336 << subDetector << MSG::dec);
339 bool isSimulated = (
data[0] == 0xee1234ee) ?
true :
false;
342 if (((version & 0x03000000) == 0x03000000) && (
data[2] != 0x00) && ((
data[0] & 0xffff0000) == 0)) {
345 }
else if (version == 0x2400000 || isSimulated) {
348 }
else if (((version & 0x03000000) == 0x03000000) &&
349 ((
data[0] & 0xffff0000) != 0))
365 std::map<Identifier, RpcPad*> mapOfCollections;
375 if (alreadyPresent) {
376 ATH_MSG_DEBUG(
"RPC RDO collection already exist with collection hash = " <<
static_cast<unsigned int>(it)
377 <<
" converting is skipped!");
379 ATH_MSG_DEBUG(
"Created new Pad Collection Hash ID = " <<
static_cast<unsigned int>(it));
383 mapOfCollections[coll->
identify()] = coll;
388 if (mapOfCollections.empty()) {
389 ATH_MSG_VERBOSE(
"mapOfCollections is empty; fillCollectionsFromRob_v302 will not be called");
390 cnv_sc = StatusCode::SUCCESS;
396 if (cnv_sc != StatusCode::SUCCESS) {
397 if (cnv_sc == StatusCode::RECOVERABLE) {
405 for (
const std::map<Identifier, RpcPad*>::value_type& it : mapOfCollections) {
410 if (
lock.alreadyPresent()) {
411 ATH_MSG_DEBUG(
"RpcPad collection with hash " << (
int)(it.second)->identifyHash()
412 <<
" was already decoded in a parallel view");
415 StatusCode status_lock =
lock.addOrDelete(std::unique_ptr<RpcPad>(it.second));
417 if (status_lock != StatusCode::SUCCESS) {
418 ATH_MSG_ERROR(
"Failed to add RPC PAD collection to container with hash " << (
int)(it.second)->identifyHash());
420 ATH_MSG_DEBUG(
"Adding RpcPad collection with hash " << (
int)(it.second)->identifyHash()
421 <<
" to the RpcPad Container | size = " << (it.second)->size());
433 if (
lock.alreadyPresent()) {
434 ATH_MSG_DEBUG(
"RPC RDO collection already exist with collection hash = " <<
static_cast<unsigned int>(it)
435 <<
" converting is skipped!");
437 ATH_MSG_VERBOSE(
" Created new Pad Collection Hash ID = " <<
static_cast<unsigned int>(it));
445 case 1: cnv_sc =
fillCollection_v300(ctx,
data, robFrag.rod_ndata(), *coll, subDetector, RPC_SECTORLOGIC);
break;
450 if (cnv_sc.isFailure()) {
ATH_MSG_VERBOSE(
"Error into the RPC fillCollections decoding"); }
454 StatusCode status_lock =
lock.addOrDelete(std::unique_ptr<RpcPad>(coll));
457 if (status_lock != StatusCode::SUCCESS) {
458 ATH_MSG_ERROR(
"Failed to add RPC PAD collection to container");
461 ATH_MSG_DEBUG(
"Adding RpcPad collection with hash " << (
int)(it)
462 <<
" to the RpcPad Container | size = " << coll->
size());
475 bool skipSectorLogicDecoding = (sectorLogicContainer ==
nullptr);
476 if (skipSectorLogicDecoding)
ATH_MSG_DEBUG(
"Skip SectorLogic decoding, so SLROC.decodeFragment is not being processed");
488 const int size = p.size();
496 if (
size > 0 && msgLvl(MSG::VERBOSE)) {
497 msg(MSG::VERBOSE) <<
"The size of this ROD-read is " <<
size <<
endmsg;
499 char decoded_char[1000];
500 for (
int i = 0; i <
size; i++) {
501 decoded = (p[i] & 0xf000) >> 12;
502 if (decoded < 0x4) sprintf(decoded_char,
"Hit data");
503 if (decoded == 0x4) sprintf(decoded_char,
"CM Footer");
504 if (decoded == 0x5) sprintf(decoded_char,
"PAD Header");
505 if (decoded == 0x6) sprintf(decoded_char,
"PAD/SL Subheader");
506 if (decoded == 0x7) sprintf(decoded_char,
"PAD Footer");
507 if (decoded == 0x8) sprintf(decoded_char,
"CM Subheader");
508 if (decoded == 0x9) sprintf(decoded_char,
"RX Header");
509 if (decoded == 0xa) sprintf(decoded_char,
"PAD Prefooter");
510 if (decoded == 0xb) sprintf(decoded_char,
"RX Footer");
511 if (decoded == 0xc) sprintf(decoded_char,
"CM Header");
512 if (decoded == 0xd) sprintf(decoded_char,
"SL Header");
513 if (decoded == 0xe) sprintf(decoded_char,
"RX Subheader");
514 if (decoded == 0xf) sprintf(decoded_char,
"SL Footer");
516 msg(MSG::VERBOSE) <<
"word " << i <<
" = " << MSG::hex << p[i] << MSG::dec <<
" " << MSG::hex << decoded << MSG::dec <<
" "
517 << decoded_char <<
endmsg;
523 return StatusCode::FAILURE;
526 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"The source ID is: " << MSG::hex << sourceId <<
endmsg;
528 uint16_t sectorForCabling = 0;
532 uint16_t SLindex = 0;
539 bool foundPad =
false;
541 if (msgLvl(MSG::VERBOSE))
542 msg(MSG::VERBOSE) <<
"The offline ID request for conversion is "
545 bool isSLHeader =
false;
546 bool isSLSubHeader =
false;
547 bool isSLFooter =
false;
548 bool isSLFragment =
false;
549 bool isRXHeader =
false;
550 bool isRXFooter =
false;
551 bool isPADFragment =
false;
552 bool isPadHeader =
false;
553 bool isPadSubHeader =
false;
554 bool isPadPreFooter =
false;
555 bool isPadFooter =
false;
567 unsigned short int PadID = 99;
568 uint16_t slfel1id = 0;
571 uint16_t slstatus = 0;
573 unsigned int SLBodyWords = 0;
574 unsigned int SL_data_sise = 500;
575 unsigned short int SLBuff[500];
579 uint16_t subDetectorID = (sourceId & 0xff0000) >> 16;
581 uint16_t side = (subDetectorID == eformat::MUON_RPC_BARREL_A_SIDE) ? 1 : 0;
583 if (msgLvl(MSG::VERBOSE)) {
584 msg(MSG::VERBOSE) <<
"subDetectorID = 0x" << MSG::hex << subDetectorID << MSG::dec <<
endmsg;
586 msg(MSG::VERBOSE) <<
"rodID = 0x" << MSG::hex << rodId << MSG::dec <<
endmsg;
587 msg(MSG::VERBOSE) <<
"The side is " << side <<
endmsg;
592 for (uint16_t i = 0; i <
size; ++i) {
598 isPadSubHeader =
false;
599 isPadPreFooter =
false;
602 isSLSubHeader =
false;
604 uint32_t currentWord = p[i];
608 if (!skipSectorLogicDecoding) { SLROS.
decodeFragment(currentWord, recField); }
612 isSLFragment =
false;
613 isPADFragment =
false;
615 isPadSubHeader =
true;
620 isSLFragment =
false;
622 isPadPreFooter =
true;
628 isPADFragment =
false;
631 isSLFragment =
false;
633 isSLSubHeader =
true;
637 if (skipSectorLogicDecoding) {
639 isSLSubHeader =
false;
640 isSLFragment =
false;
647 if (msgLvl(MSG::VERBOSE)) {
648 char decoded_char[256];
650 sprintf(decoded_char,
" RX Header");
651 }
else if (isRXFooter) {
652 sprintf(decoded_char,
" RX Footer");
653 }
else if (isSLHeader) {
654 sprintf(decoded_char,
" SL Header");
655 }
else if (isSLSubHeader) {
656 sprintf(decoded_char,
" SL SubHeader");
657 }
else if (isSLFooter) {
658 sprintf(decoded_char,
" SL Footer");
659 }
else if (isPadHeader) {
660 sprintf(decoded_char,
" Pad Header");
661 }
else if (isPadSubHeader) {
662 sprintf(decoded_char,
" Pad SubHeader");
663 }
else if (isPadPreFooter) {
664 sprintf(decoded_char,
" Pad PreFooter");
665 }
else if (isPadFooter) {
666 sprintf(decoded_char,
" Pad Footer");
667 }
else if (isSLFragment) {
668 sprintf(decoded_char,
" SL Fragment");
669 }
else if (isPADFragment) {
670 sprintf(decoded_char,
" Pad Fragment");
672 sprintf(decoded_char,
" Undecoded");
675 msg(MSG::VERBOSE) << i <<
" -->current data word is " << MSG::hex << currentWord << MSG::dec << decoded_char <<
endmsg;
678 if (msgLvl(MSG::VERBOSE)) {
679 msg(MSG::VERBOSE) <<
" this is a RX Header " <<
endmsg;
680 msg(MSG::VERBOSE) <<
" Sector ID=" << RXROS.
RXid() <<
endmsg;
688 uint16_t rxid = RXROS.
RXid();
689 sectorForCabling = 2 * rodId + rxid;
690 sector = side * 32 + sectorForCabling;
706 }
else if (isRXFooter) {
708 }
else if (isSLHeader || isSLFragment || isSLSubHeader || isSLFooter) {
714 slfel1id = SLROS.
fel1id();
717 ATH_MSG_VERBOSE(
" SL Header: slfel1id " << slfel1id <<
" slid: " << slid);
718 }
else if (isSLSubHeader) {
725 else if (isSLFooter) {
726 if (SLindex > 1) {
ATH_MSG_VERBOSE(
"More than 2 SL fragments in sector " << sector); }
728 if (msgLvl(MSG::VERBOSE)) {
729 msg(MSG::VERBOSE) <<
" Number of data words in SectorLogicReadOut= " << SLBodyWords <<
endmsg;
730 msg(MSG::VERBOSE) <<
" TEST SL: " << foundSL <<
endmsg;
733 for (
unsigned short j = 0; j < SLBodyWords; j++) {
734 msg(MSG::VERBOSE) <<
" SL data word " << j <<
" : " << MSG::hex << SLBuff[j] << MSG::dec <<
endmsg;
743 if (sectorLogicContainer && !sectorLogicContainer->
findSector(sector, side)) {
744 slstatus = SLROS.
status();
748 bool inputHeaderFound =
false;
749 bool outputHeaderFound =
false;
750 ATH_MSG_VERBOSE(
"New RpcSectorLogic: sector=" << sector <<
" fel1id=" << slfel1id <<
" BCID=" << slbcid);
752 uint16_t rowinBcid = 999;
753 uint16_t slPadId = 999;
767 uint16_t triggerBcid;
772 inputHeaderFound =
true;
774 if (!inputHeaderFound) {
785 new RpcSLTriggerHit(rowinBcid, slPadId, ptid, roi, outerPlane, overlapPhi, overlapEta, triggerBcid);
788 ATH_MSG_VERBOSE(
"New input RpcSLTriggerHit: ptid, roi= " << ptid <<
" " << roi);
792 outputHeaderFound =
true;
794 if (!outputHeaderFound) {
796 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"ERROR: outputSLHeader missing !!" <<
endmsg;
802 for (
int icand = 0; icand < SLROS.
nTriggerCand(); ++icand) {
808 overlapEta, triggerBcid);
812 ATH_MSG_VERBOSE(
"New output RpcSLTriggerHit: ptid, roi= " << ptid <<
" " << roi);
821 if (sectorLogicContainer) sectorLogicContainer->
push_back(sl);
823 if (sectorLogicContainer && !sectorLogicContainer->
setSector(sector, side)) {
824 ATH_MSG_VERBOSE(
"Sector " << sector <<
" decoded more than once in SL");
829 if (SLBodyWords >= SL_data_sise) {
831 return StatusCode::FAILURE;
833 SLBuff[SLBodyWords] = currentWord;
837 }
else if (isPadHeader || isPADFragment) {
843 if (recField ==
'H') {
844 PadID = PDROS.
padid();
857 side = (sector < 32) ? 0 : 1;
858 uint16_t sectorLogic = sector - side * 32;
861 if (!rpcCabling->
giveOfflineId(side, sectorLogic, PadID, padOfflineId)) {
862 if (msgLvl(MSG::VERBOSE))
863 msg(MSG::VERBOSE) <<
"Cannot retrieve the OfflineID for the PAD n. " << PadID <<
" at side " << side
864 <<
" and sector " << sectorLogic <<
endmsg;
866 if (msgLvl(MSG::VERBOSE))
867 msg(MSG::VERBOSE) <<
"ID " <<
m_idHelperSvc->rpcIdHelper().show_to_string(padOfflineId)
868 <<
" associated to PAD n. " << PadID <<
" at side " << side <<
" and sector " << sectorLogic
873 if (thisPadOfflineId == padOfflineId) {
874 if (msgLvl(MSG::VERBOSE))
875 msg(MSG::VERBOSE) <<
" match found with ID " <<
m_idHelperSvc->rpcIdHelper().show_to_string(thisPadOfflineId)
876 <<
" requested for the conversion; return this collection" <<
endmsg;
880 v.setOnlineId(PadID);
884 v.setLvl1Id(PDROS.
l1id());
887 if (msgLvl(MSG::VERBOSE))
888 msg(MSG::VERBOSE) <<
" match NOT found with ID "
889 <<
m_idHelperSvc->rpcIdHelper().show_to_string(thisPadOfflineId)
890 <<
" requested for the conversion" <<
endmsg;
895 if (recField ==
'S') {
897 v.setBcId(PDROS.
bcid());
898 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found the subheader, setting bcid to: " << PDROS.
bcid() <<
endmsg;
902 if (recField ==
'P') {
903 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found the prefooter" <<
endmsg;
905 v.setStatus(PDROS.
status());
907 if (currentWord & 0x0fff) {
908 if (msgLvl(MSG::VERBOSE))
909 msg(MSG::VERBOSE) <<
"Pad Busy status not zero ! value: " << MSG::hex << (currentWord & 0x0fff) << MSG::dec
914 if (recField ==
'F') {
915 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
" Pad Footer " <<
endmsg;
917 if (msgLvl(MSG::VERBOSE) && PDROS.
errorCode() != 0) {
918 msg(MSG::VERBOSE) <<
"Pad Error flag not zero ! value: " << MSG::hex << PDROS.
errorCode() << MSG::dec <<
endmsg;
926 if (!(PadID > 3 && sector % 2 > 0)) {
return StatusCode::SUCCESS; }
930 isPadFooter ? isPADFragment = false : isPADFragment =
true;
932 if (msgLvl(MSG::VERBOSE)) {
933 msg(MSG::VERBOSE) <<
" current word " << MSG::hex << currentWord << MSG::dec <<
endmsg;
935 msg(MSG::VERBOSE) <<
" ==isPADFragment= " << isPADFragment <<
endmsg;
936 msg(MSG::VERBOSE) <<
" calling pushword: " << MSG::hex << currentWord << MSG::dec <<
endmsg;
951 matrixROS = matrix->getHeader();
952 uint16_t cmaId = matrixROS.
cmid();
953 uint16_t fel1id = matrixROS.
fel1id();
955 matrixROS = matrix->getSubHeader();
956 uint16_t febcid = matrixROS.
febcid();
958 if (msgLvl(MSG::VERBOSE))
959 msg(MSG::VERBOSE) <<
"Creating a new CM, cmaId=" << cmaId <<
" fel1id=" << fel1id <<
" febcid=" << febcid
965 matrixROS = matrix->getFooter();
971 for (
int i = 0; i < matrix->numberOfBodyWords(); ++i) {
972 matrixROS = matrix->getCMAHit(i);
974 uint16_t bcid = matrixROS.
bcid();
975 uint16_t time = matrixROS.
time();
976 uint16_t ijk = matrixROS.
ijk();
981 uint16_t channel = matrixROS.
channel();
985 <<
" ijk=" << ijk <<
" channel=" << channel);
989 }
else if (ijk == 7) {
990 uint16_t overlap = matrixROS.
overlap();
995 <<
" ijk=" << ijk <<
" overlap=" << overlap
1003 v.push_back(coinMatrix);
1014 return StatusCode::SUCCESS;
1022 bool skipSectorLogicDecoding = (sectorLogicContainer ==
nullptr);
1023 if (skipSectorLogicDecoding)
ATH_MSG_DEBUG(
"Skip SectorLogic decoding, so SLROC.decodeFragment is not being processed");
1026 if (msgLvl(MSG::VERBOSE)) {
1027 msg(MSG::VERBOSE) <<
"**********Decoder dumping the words******** " <<
endmsg;
1028 if (data_size > 0) {
1029 msg(MSG::VERBOSE) <<
"The size of this ROD-read is " << data_size <<
endmsg;
1030 for (
unsigned int i = 0; i < data_size; i++)
1031 msg(MSG::VERBOSE) <<
"word " << i <<
" = " << MSG::hex <<
data[i] << MSG::dec <<
endmsg;
1036 uint16_t side = (subDetector == eformat::MUON_RPC_BARREL_A_SIDE) ? 1 : 0;
1039 uint16_t sector = 0;
1042 uint16_t SLindex = 0;
1049 bool foundPad =
false;
1051 bool isSLHeader =
false;
1052 bool isSLFooter =
false;
1053 bool isSLFragment =
false;
1054 bool isRXHeader =
false;
1055 bool isRXFooter =
false;
1056 bool isPADFragment =
false;
1057 bool isPadHeader =
false;
1058 bool isPadSubHeader =
false;
1059 bool isPadPreFooter =
false;
1060 bool isPadFooter =
false;
1071 unsigned short int PadID = 99;
1072 unsigned int SLBodyWords = 0;
1073 unsigned int SL_data_size = 500;
1074 unsigned short int SLBuff[500];
1076 std::unique_ptr<RpcSectorLogic> sl{};
1078 for (uint16_t i = 0; i < data_size; ++i) {
1083 isPadHeader =
false;
1084 isPadSubHeader =
false;
1085 isPadPreFooter =
false;
1086 isPadFooter =
false;
1089 uint32_t currentWord =
data[i];
1092 ATH_MSG_VERBOSE(
" -->current data word is " << std::hex << currentWord << std::dec);
1099 if (RXROS.
isHeader() && !isSLFragment)
1101 else if (RXROS.
isFooter() && !isSLFragment)
1103 else if (PDROS.
isHeader() && !isSLFragment)
1106 isPadSubHeader =
true;
1108 isPadPreFooter =
true;
1109 else if (PDROS.
isFooter() && !isSLFragment)
1117 if (skipSectorLogicDecoding) {
1119 isSLFragment =
false;
1124 if (msgLvl(MSG::VERBOSE)) {
1125 msg(MSG::VERBOSE) <<
" RX Header: " << isRXHeader <<
" RX Footer: " << isRXFooter <<
endmsg;
1126 msg(MSG::VERBOSE) <<
" Pad Header: " << isPadHeader <<
" Pad SubHeader: " << isPadSubHeader
1127 <<
" Pad PreFooter: " << isPadPreFooter <<
" Pad Footer: " << isPadFooter <<
endmsg;
1128 msg(MSG::VERBOSE) <<
" isPADFragment: " << isPADFragment <<
endmsg;
1129 msg(MSG::VERBOSE) <<
" SL Header: " << isSLHeader <<
" SL Footer: " << isSLFooter <<
endmsg;
1130 msg(MSG::VERBOSE) <<
" isSLFragment: " << isSLFragment <<
endmsg;
1136 if (msgLvl(MSG::VERBOSE)) {
1137 msg(MSG::VERBOSE) <<
" this is a RX Header " <<
endmsg;
1138 msg(MSG::VERBOSE) <<
" Sector ID=" << RXROS.
RXid() <<
endmsg;
1152 if (sectorLogicContainer && !sectorLogicContainer->
findSector(sector, 0)) {
1154 sl = std::make_unique<RpcSectorLogic>(sector, 0, 0, errorCode);
1156 }
else if (sectorLogicContainer) {
1159 if ((*itSL)->sectorId() == sector) {
1166 }
else if (isRXFooter) {
1168 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
" this is a RX Footer " <<
endmsg;
1170 }
else if (isSLHeader || isSLFragment) {
1171 isSLFooter ? isSLFragment = false : isSLFragment =
true;
1179 if (msgLvl(MSG::VERBOSE)) {
1186 if (isSLHeader) SLBodyWords = 0;
1189 else if (isSLFooter) {
1191 if (SLindex > 1) {
msg(MSG::ERROR) <<
"More than 2 SL fragments in sector " << sector <<
endmsg; }
1195 msg(MSG::VERBOSE) <<
" Number of data words in SectorLogicReadOut= " << SLBodyWords <<
endmsg;
1196 msg(MSG::VERBOSE) <<
" TEST SL: " << foundSL <<
endmsg;
1201 for (
unsigned short j = 0; j < SLBodyWords; j++) {
1202 msg(MSG::VERBOSE) <<
" SL data word " << j <<
" : " << std::hex << SLBuff[j] << MSG::dec <<
endmsg;
1210 if (sectorLogicContainer && !sectorLogicContainer->
findSector(sector, SLindex)) {
1213 uint16_t nSLlink = 2;
1214 uint16_t nSLgate = 7;
1217 for (
int igate = 0; igate < nSLgate; ++igate) {
1218 for (
int ilink = 0; ilink < nSLlink; ++ilink) {
1219 uint16_t ptid = sectorLogic->
ptid(ilink, igate);
1222 uint16_t cmadd = sectorLogic->
cmadd(ilink, igate);
1224 uint16_t bcid = igate;
1225 uint16_t tower = ilink + 2 * SLindex;
1227 uint16_t opl = sectorLogic->
opl(ilink, igate);
1228 uint16_t ovphi = sectorLogic->
ovphi(ilink, igate);
1229 uint16_t oveta = sectorLogic->
oveta(ilink, igate);
1231 uint16_t triggerBcid = sectorLogic->
bcid(ilink, igate);
1235 sl->push_back(slHit);
1244 if (SLindex == 0) { sl->addTriggerRate(sectorLogic->
padTriggerRate(1)); }
1249 for (
int icount = 0; icount < nSLcount; ++icount) {
1251 sl->addCounter(counter);
1257 if (SLindex == 0 && sectorLogicContainer) { sectorLogicContainer->
push_back(std::move(sl)); }
1264 if (SLBodyWords >= SL_data_size) {
1265 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Sector Logic payload corrupted" <<
endmsg;
1266 return StatusCode::FAILURE;
1268 SLBuff[SLBodyWords] = currentWord;
1272 }
else if (isPadHeader || isPADFragment) {
1275 msg(MSG::VERBOSE) <<
" Pad Header or Pad Fragment " <<
endmsg;
1280 if (recField ==
'H') {
1281 PadID = PDROS.
padid();
1283 uint16_t status = 0;
1285 side = (sector < 32) ? 0 : 1;
1286 uint16_t sectorLogic = sector - side * 32;
1288 msg(MSG::VERBOSE) <<
" Pad Identifier= " << PadID <<
" Status: " << status <<
endmsg;
1295 if (!rpcCabling->
giveOfflineId(side, sectorLogic, PadID, padOfflineId)) {
1296 if (msgLvl(MSG::VERBOSE))
1297 msg(MSG::VERBOSE) <<
"Cannot retrieve the OfflineID for the PAD n. " << PadID <<
" at side " << side
1298 <<
" and sector " << sectorLogic <<
endmsg;
1299 }
else if (msgLvl(MSG::VERBOSE))
1300 msg(MSG::VERBOSE) <<
"ID " <<
m_idHelperSvc->rpcIdHelper().show_to_string(padOfflineId) <<
" associated to PAD n. "
1301 << PadID <<
" at side " << side <<
" and sector " << sectorLogic <<
endmsg;
1304 if (thisPadOfflineId == padOfflineId) {
1305 if (msgLvl(MSG::VERBOSE))
1306 msg(MSG::VERBOSE) <<
" match found with ID " <<
m_idHelperSvc->rpcIdHelper().show_to_string(thisPadOfflineId)
1307 <<
" requested for the conversion; return this collection" <<
endmsg;
1311 msg(MSG::VERBOSE) <<
"Found the pad to convert !" <<
endmsg;
1313 v.setOnlineId(PadID);
1314 v.setStatus(status);
1315 v.setSector(sector);
1318 v.setLvl1Id(PDROS.
l1id());
1321 if (msgLvl(MSG::VERBOSE))
1322 msg(MSG::VERBOSE) <<
" match NOT found with ID "
1323 <<
m_idHelperSvc->rpcIdHelper().show_to_string(thisPadOfflineId)
1324 <<
" requested for the conversion" <<
endmsg;
1329 if (recField ==
'S') {
1331 v.setBcId(PDROS.
bcid());
1333 msg(MSG::VERBOSE) <<
"Found the subheader, setting bcid to: " << PDROS.
bcid() <<
endmsg;
1338 if (recField ==
'F') {
1340 msg(MSG::VERBOSE) <<
" Pad Footer " <<
endmsg;
1345 return StatusCode::SUCCESS;
1349 isPadFooter ? isPADFragment = false : isPADFragment =
true;
1352 msg(MSG::VERBOSE) <<
" current word " << std::hex << currentWord << MSG::dec <<
endmsg;
1354 msg(MSG::VERBOSE) <<
" ==isPADFragment= " << isPADFragment <<
endmsg;
1355 msg(MSG::VERBOSE) <<
" calling pushword: " << std::hex << currentWord << MSG::dec <<
endmsg;
1371 matrixROS = matrix->getHeader();
1372 uint16_t cmaId = matrixROS.
cmid();
1373 uint16_t fel1id = matrixROS.
fel1id();
1375 matrixROS = matrix->getSubHeader();
1376 uint16_t febcid = matrixROS.
febcid();
1379 msg(MSG::VERBOSE) <<
"Creating a new CM, cmaId=" << cmaId <<
" fel1id=" << fel1id <<
" febcid=" << febcid <<
endmsg;
1388 for (
int i = 0; i < matrix->numberOfBodyWords(); ++i) {
1389 matrixROS = matrix->getCMAHit(i);
1391 uint16_t bcid = matrixROS.
bcid();
1392 uint16_t time = matrixROS.
time();
1393 uint16_t ijk = matrixROS.
ijk();
1398 uint16_t channel = matrixROS.
channel();
1401 msg(MSG::VERBOSE) <<
"Adding a fired channel, bcid=" << bcid <<
" time="
1402 <<
" ijk=" << ijk <<
" channel=" << channel <<
endmsg;
1406 }
else if (ijk == 7) {
1407 uint16_t overlap = matrixROS.
overlap();
1411 msg(MSG::VERBOSE) <<
"Adding a fired channel, bcid=" << bcid <<
" time="
1412 <<
" ijk=" << ijk <<
" overlap=" << overlap <<
" threshold=" <<
threshold <<
endmsg;
1419 v.push_back(coinMatrix);
1429 return StatusCode::SUCCESS;
1436 const int rodHeader = 8;
1437 const int rodFooter = 3;
1438 bool printMessage =
true;
1452 if (msgLvl(MSG::VERBOSE))
1453 msg(MSG::VERBOSE) <<
"The offline ID request for conversion is "
1458 std::vector<uint16_t> v16 =
get16bits(
data, data_size, rodHeader, rodFooter);
1460 int word16Count = 0;
1461 int size16 = v16.size();
1463 assert(size16 > 0 && size16 == (
int)(2 * (data_size - rodHeader - rodFooter)));
1480 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"subDetectorID = 0x" << MSG::hex << subDetectorID << MSG::dec <<
endmsg;
1482 uint16_t side = (subDetectorID == eformat::MUON_RPC_BARREL_A_SIDE) ? 0 : 1;
1485 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"rodID = 0x" << MSG::hex << rodId << MSG::dec <<
endmsg;
1487 assert(rodId <= 15);
1490 char rxHeader =
'U';
1491 if (!
ensure_more_data(word16Count, size16,
msg(), printMessage,
"start of data"))
return StatusCode::FAILURE;
1492 uint16_t receiverHeaderFragment = v16[word16Count];
1494 if (rxHeader ==
'H') {
1496 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a receiver header " <<
endmsg;
1497 }
else if (msgLvl(MSG::VERBOSE))
1498 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a receiver header "
1500 <<
" Fragment ID is " << MSG::hex << rxHeader << MSG::dec <<
endmsg;
1502 while (rxHeader ==
'H' && word16Count < size16) {
1503 if (msgLvl(MSG::VERBOSE))
1504 msg(MSG::VERBOSE) <<
"The receiver header word is " << MSG::hex << receiverHeaderFragment << MSG::dec <<
endmsg;
1505 uint16_t slogic = 2 * rodId + rxReadout.
RXid();
1506 uint16_t sectorID = side * 32 + slogic;
1507 assert(slogic <= 31);
1508 char padHeader =
'U';
1509 uint16_t padHeaderFragment = v16[word16Count];
1511 if (padHeader ==
'H') {
1513 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a pad header " <<
endmsg;
1514 }
else if (msgLvl(MSG::VERBOSE))
1515 msg(MSG::VERBOSE) <<
"Rpc_ROD_Decoder::ERROR : Expecting a pad header "
1516 <<
" Fragment ID is " << padHeader <<
endmsg;
1518 while (padHeader ==
'H') {
1519 uint16_t padId = padReadout.
padid();
1521 uint16_t status = 0;
1527 if (!rpcCabling->
giveOfflineId(side, slogic, padId, padOfflineId)) {
1528 if (msgLvl(MSG::VERBOSE))
1529 msg(MSG::VERBOSE) <<
"Cannot retrieve the OfflineID for the PAD n. " << padId <<
" at side " << side
1530 <<
" and sector " << slogic <<
endmsg;
1531 }
else if (msgLvl(MSG::VERBOSE))
1532 msg(MSG::VERBOSE) <<
"ID " <<
m_idHelperSvc->rpcIdHelper().show_to_string(padOfflineId) <<
" associated to PAD n. "
1533 << padId <<
" at side " << side <<
" and sector " << slogic <<
endmsg;
1540 if (thisPadOfflineId == padOfflineId) {
1541 if (msgLvl(MSG::VERBOSE))
1542 msg(MSG::VERBOSE) <<
"Found the collection to return "
1544 v.setOnlineId(padId);
1545 v.setStatus(status);
1546 v.setSector(sectorID);
1548 if (msgLvl(MSG::VERBOSE))
1549 msg(MSG::VERBOSE) <<
m_idHelperSvc->rpcIdHelper().show_to_string(thisPadOfflineId)
1552 char cmaHeader =
'U';
1554 uint16_t cmaHeaderFragment = v16[word16Count];
1556 if (cmaHeader ==
'H') {
1558 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a cma header" <<
endmsg;
1559 }
else if (msgLvl(MSG::VERBOSE))
1560 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a cma header"
1561 <<
" Fragment ID is " << cmaHeader <<
endmsg;
1563 while (cmaHeader ==
'H') {
1564 uint16_t cmaId = matrixReadout.
cmid();
1565 uint16_t fel1id = matrixReadout.
fel1id();
1566 char cmaSubHeader =
'U';
1567 uint16_t febcid =
static_cast<uint16_t
>(-1);
1569 uint16_t cmaSubHeaderFragment = v16[word16Count];
1570 matrixReadout.
decodeFragment(cmaSubHeaderFragment, cmaSubHeader);
1571 if (cmaSubHeader ==
'S') {
1572 febcid = matrixReadout.
febcid();
1574 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a cma sub-header" <<
endmsg;
1575 }
else if (msgLvl(MSG::VERBOSE))
1576 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a cma sub-header"
1577 <<
" Fragment ID is " << cmaSubHeader <<
endmsg;
1582 uint16_t cmaBodyFragment = v16[word16Count];
1584 if (cmaBody ==
'B') {
1586 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a cma body " << MSG::hex << cmaBodyFragment <<
endmsg;
1587 }
else if (msgLvl(MSG::VERBOSE))
1588 msg(MSG::VERBOSE) <<
"Expecting cma body"
1589 <<
" Fragment ID is " << cmaBody <<
endmsg;
1590 while (cmaBody ==
'B') {
1591 uint16_t bcid = matrixReadout.
bcid();
1592 uint16_t time = matrixReadout.
time();
1593 uint16_t ijk = matrixReadout.
ijk();
1597 uint16_t channel = matrixReadout.
channel();
1600 }
else if (ijk == 7) {
1602 uint16_t overlap = matrixReadout.
overlap();
1606 if (msgLvl(MSG::VERBOSE))
1607 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Wrong ijk value " << ijk <<
"in cma body " <<
endmsg;
1614 cmaBodyFragment = v16[word16Count];
1616 if (cmaBody ==
'B') {
1618 if (msgLvl(MSG::VERBOSE))
1619 msg(MSG::VERBOSE) <<
"Found a cma body"
1620 <<
" " << MSG::hex << cmaBodyFragment << MSG::dec <<
endmsg;
1622 ATH_MSG_VERBOSE(
" No more body fragment found " << cmaBody <<
" " << MSG::hex << cmaBodyFragment << MSG::dec);
1623 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"End of a cma body" <<
endmsg;
1625 char cmaFooter =
'U';
1631 uint16_t cmaFooterFragment = v16[word16Count];
1633 if (cmaFooter ==
'F') {
1634 uint16_t crc = matrixReadout.
crc();
1638 ATH_MSG_ERROR(
"Trying to call null coinMatrix - this should never happen!");
1640 if (msgLvl(MSG::VERBOSE))
1641 msg(MSG::VERBOSE) <<
"Found a cma Footer " << MSG::hex << cmaFooterFragment << MSG::dec <<
endmsg;
1643 if (msgLvl(MSG::VERBOSE))
1644 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a cma Footer"
1645 <<
" Fragment ID is " << cmaFooter <<
" " << MSG::hex << cmaFooterFragment << MSG::dec
1649 if (thisPadOfflineId == padOfflineId)
1650 v.push_back(coinMatrix);
1655 cmaHeaderFragment = v16[word16Count];
1657 if (cmaHeader ==
'H') {
1659 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a cma header" <<
endmsg;
1660 }
else if (msgLvl(MSG::VERBOSE))
1661 msg(MSG::VERBOSE) <<
"End of all CMAs" <<
endmsg;
1663 char padFooter =
'U';
1664 uint16_t errorCode =
static_cast<uint16_t
>(-1);
1666 uint16_t padFooterFragment = v16[word16Count];
1668 if (padFooter ==
'F') {
1671 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a pad footer " <<
endmsg;
1672 if (thisPadOfflineId == padOfflineId) {
1673 v.setErrorCode(errorCode);
1675 return StatusCode::FAILURE;
1677 }
else if (msgLvl(MSG::VERBOSE))
1678 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a pad footer "
1679 <<
" Fragment ID is " << padFooter <<
" " << MSG::hex << padFooterFragment << MSG::dec <<
endmsg;
1681 padHeaderFragment = v16[word16Count];
1683 if (padHeader ==
'H') {
1685 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a pad header " <<
endmsg;
1686 }
else if (msgLvl(MSG::VERBOSE))
1687 msg(MSG::VERBOSE) <<
"End of all pads " <<
endmsg;
1690 char rxFooter =
'U';
1692 uint16_t receiverFooterFragment = v16[word16Count];
1694 if (rxFooter ==
'F') {
1696 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a receiver footer " <<
endmsg;
1697 }
else if (msgLvl(MSG::VERBOSE))
1698 msg(MSG::VERBOSE) <<
"RpcROD_Decoder::ERROR : Expecting a receiver footer "
1699 <<
" Fragment ID is " << rxFooter <<
" " << MSG::hex << receiverFooterFragment << MSG::dec <<
endmsg;
1701 if (word16Count < size16) {
1702 receiverHeaderFragment = v16[word16Count];
1704 if (rxHeader ==
'H') {
1706 if (msgLvl(MSG::VERBOSE))
msg(MSG::VERBOSE) <<
"Found a receiver header " <<
endmsg;
1707 }
else if (msgLvl(MSG::VERBOSE))
1708 msg(MSG::VERBOSE) <<
"End of all receivers " <<
endmsg;
1715 return StatusCode::FAILURE;
1719 uint32_t mask = 0x0000FFFF;
1720 uint32_t pos[2] = {16, 0};
1722 std::vector<uint16_t> result;
1724 for (
int i = nHeader; i < (
size - nFooter); i++) {
1725 for (uint32_t j = 0; j < 2; j++) {
1726 uint32_t vshift = v32[i] >> pos[j];
1727 uint16_t fragment = (uint16_t)(vshift & mask);
1728 result.push_back(fragment);
1735 uint32_t mask = 0x0000FFFF;
1736 uint32_t pos[2] = {0, 16};
1738 std::vector<uint16_t> result;
1740 for (
int i = nHeader; i < (
size - nFooter); i++) {
1741 for (uint32_t j = 0; j < 2; j++) {
1742 uint32_t vshift = v32[i] >> pos[j];
1743 uint16_t fragment = (uint16_t)(vshift & mask);
1744 result.push_back(fragment);
#define ATH_MSG_VERBOSE(x)
char data[hepevt_bytes_allocation_ATLAS]
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Current RpcCoinMatrix
Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Current Athena::TPCnvVers::Current Athena::TPCnvVers::Current RpcPad
unsigned short int ubit16
size_t size() const
Number of registered mappings.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
IDC_WriteHandle getWriteHandle(IdentifierHash hash)
virtual bool tryAddFromCache(IdentifierHash hashId) override final
Looks in the cache to see if item already exists if not it returns false, If it does exist it incorpo...
This is a "hash" representation of an Identifier.
ubit16 decodeFragment(ubit16 inputWord, char &field)
StatusCode fillCollectionsFromRob_v302(const EventContext &ctx, BS data, const uint32_t data_size, std::map< Identifier, RpcPad * > &vmap, const uint32_t &sourceId, RpcSectorLogicContainer *, const bool &decodeSL) const
SG::ReadCondHandleKey< RpcCablingCondData > m_rpcReadKey
virtual StatusCode initialize() override
bool isSector13Data() const
std::vector< uint16_t > get16bits(BS data, const int size, const int nHeader, const int nFooter) const
IntegerProperty m_specialROBNumber
Gaudi::Property< int > m_nobxs
virtual ~RpcROD_Decoder()=default
StatusCode fillCollections(const EventContext &ctx, const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &robFrag, RpcPadContainer &rdoIdc, const std::vector< IdentifierHash > &collections, RpcSectorLogicContainer *, const bool &decodeSL) const override
RpcROD_Decoder(const std::string &type, const std::string &name, const IInterface *p)
OFFLINE_FRAGMENTS_NAMESPACE::PointerType BS
std::vector< uint16_t > get16bits_v301(BS data, const int size, const int nHeader, const int nFooter) const
StatusCode fillCollection_v302new(const EventContext &ctx, BS data, const uint32_t data_size, RpcPad &v, const uint32_t &sourceId, RpcSectorLogicContainer *, const bool &) const
StatusCode fillCollection_v240(const EventContext &ctx, BS data, const uint32_t data_size, RpcPad &v) const
fill RpcPads from a block of integers Decode collection for old data format 2.4.0
BooleanProperty m_sector13Data
IntegerProperty m_maxprinterror
virtual StatusCode finalize() override
std::atomic_int m_RPCcheckfail[13]
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
StatusCode fillCollection_v300(const EventContext &ctx, BS data, const uint32_t data_size, RpcPad &v, const uint16_t &subDetector, RpcSectorLogicContainer *) const
fill RpcPads from a block of integers New version for data format 3.0 (ATLAS cosmics)
StatusCode checkdataformat(std::vector< uint16_t > *, int, int) const
StatusCode fillCollection_v302(const EventContext &ctx, BS data, const uint32_t data_size, RpcPad &v, const uint32_t &sourceId, RpcSectorLogicContainer *) const
fill RpcPads from a block of integers New version for data format 3.1 (ATLAS cosmics - NEW RPC READOU...
int specialROBNumber() const
void printcheckformat() const
ubit16 decodeFragment(ubit16 inputWord, char &field)
MatrixReadOut * CMFragment()
SectorLogicReadOut * SLFragment()
int pushWord(const ubit16 inword, uint NOBXS)
ubit16 getSourceIDSubdetectorID()
ubit16 getSourceIDRODID()
void decodeSourceID(RODword sourceID)
int pushWord(const ubit16 inword, uint NOBXS)
MatrixReadOut * CMFragment()
SectorLogicRXReadOut * SLFragment()
ubit16 decodeFragment(ubit16 inputWord, char &field)
bool giveOfflineId(const unsigned short int side, const unsigned short int sector, const unsigned short int padId, Identifier &id) const
Identifier identifier(int i) const
Use IdentifiableContainer with RpcPad.
Identifier identify() const
void setIsInput(bool isInput)
bool setSector(uint16_t sectorId, const uint16_t side=0)
Flag the sector as already decoded.
bool findSector(const uint16_t sectorId, const uint16_t side=0) const
Check if the sector has already been decoded.
void setHasMoreThan2TriggerCand(const bool a)
ubit16 outputOverlap(int nCand) const
ubit16 decodeFragment(ubit16 inputWord, char &field)
ubit16 outputTriggerBcid(int) const
ubit16 outputThreshold(int nCand) const
ubit16 inputTriggerBcid() const
ubit16 outputRowinBcid() const
ubit16 nTriggerCand() const
ubit16 hasMoreThan2TriggerCand() const
ubit16 outputRoi(int nCand) const
ubit16 inputPadId() const
ubit16 inputOverlapPhi() const
ubit16 inputOverlapEta() const
ubit16 inputThreshold() const
ubit16 inputRowinBcid() const
ubit16 inputOuterPlane() const
uint16_t numberOfInputWords()
uint16_t readSLHitCurrent()
ubit16 decodeFragment(ubit16 inputWord, char &field)
ubit16 ptid(ubit16 indexLink, ubit16 indexGate)
ubit16 oveta(ubit16 indexLink, ubit16 indexGate)
ubit16 opl(ubit16 indexLink, ubit16 indexGate)
ubit16 ovphi(ubit16 indexLink, ubit16 indexGate)
ubit16 numberOfCounterWords()
float padTriggerRate(ubit16 padAddress)
ubit16 cmadd(ubit16 indexLink, ubit16 indexGate)
ubit16 bcid(ubit16 indexLink, ubit16 indexGate)
ubit16 readSLCounterCurrent()
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
bool ensure_more_data(int index, int size, MsgStream &log, bool &printMessage, const std::string &message)
const DataType * PointerType
eformat::ROBFragment< PointerType > ROBFragment