5#define DETAIL_DUMP_ON false
6#define ADC_DUMP_ON false
7#define VALIDATE_DUMP_ON false
11#include "eformat/Issue.h"
12#include "eformat/index.h"
14#include "GaudiKernel/MsgStream.h"
41 declareInterface<LArLATOMEDecoder>(
this);
55 return StatusCode::SUCCESS;
62 if(!
re)
return StatusCode::FAILURE;;
67 }
catch (eformat::Issue& ex) {
68 ATH_MSG_WARNING(
"Exception while checking eformat fragment validity: " << ex.what());
73 return StatusCode::FAILURE;
76 std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> > robIndex;
77 eformat::helper::build_toc(*
re, robIndex);
78 for (
const auto& mapit : robIndex)
79 ATH_MSG_DEBUG(
"Rob Index subdetgroup is " << std::hex << mapit.first);
80 std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> >
::const_iterator robIt = robIndex.find(eformat::LAR);
81 if (robIt != robIndex.end()) {
82 const std::vector<const uint32_t*>& robs = robIt->second;
83 for (
const uint32_t* pRob : robs) {
86 uint32_t latomeSourceID = robFrag.rod_source_id();
88 if (!(latomeSourceID & 0x1000)) {
89 ATH_MSG_DEBUG(
" discarding non latome source ID " << std::hex << latomeSourceID);
92 ATH_MSG_DEBUG(
" found latome source ID " << std::hex << latomeSourceID);
94 const std::vector<HWIdentifier> LATOME_Channels =
map->getChFromSource(latomeSourceID);
95 EventProcess ev(
this, 0, 0, 0, 0, accdigits, caccdigits, header_coll);
96 ev.fillCollection(&robFrag, &LATOME_Channels, onoffmap, clmap);
97 }
catch (eformat::Issue& ex) {
98 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
104 header_coll->
clear();
110 return StatusCode::SUCCESS;
119 if (robFrags.size() > 0) {
122 uint32_t latomeSourceID = pRob->rod_source_id();
124 if (!(latomeSourceID & 0x1000)) {
125 ATH_MSG_DEBUG(
" discarding non latome source ID " << std::hex << latomeSourceID);
128 ATH_MSG_DEBUG(
" found latome source ID " << std::hex << latomeSourceID);
130 EventProcess ev(
this, adc_coll, adc_bas_coll, et_coll, et_id_coll, 0, 0, header_coll);
131 const std::vector<HWIdentifier> LATOME_Channels =
map->getChFromSource(latomeSourceID);
132 ev.fillCollection(pRob, &LATOME_Channels,
nullptr,
nullptr);
133 }
catch (eformat::Issue& ex) {
134 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
138 adc_bas_coll->
clear();
144 header_coll->
clear();
149 return StatusCode::SUCCESS;
155 :
AthMessaging(
Gaudi::svcLocator()->service<IMessageSvc>(
"MessageSvc"),
"LArLATOMEDecoder::EventProcess"),
225 return param == value;
230 if (std::byteswap(p[offset]) != 0xc0ffee00 || std::byteswap(p[offset + 1] != 0xaaaaaaaa)) {
231 ATH_MSG_WARNING(
"Problem in trailer at packet " <<
m_iPacket <<
" words " << std::hex << std::byteswap(p[offset]) <<
", " << std::byteswap(p[offset + 1])
241 int monheadererror = 0;
242 int monheadererrorbit = 0;
244 monheadererror |= (1 << monheadererrorbit++);
247 monheadererror |= (1 << monheadererrorbit++);
249 ATH_MSG_DEBUG(
"Mon header L1ID " << l1IDtmp <<
" different from rod header L1ID " <<
m_l1ID);
253 Word monHeaderMarker = std::byteswap(p[2 + offset]);
254 Word monCheckPoint = std::byteswap(p[4 + offset]);
256 monheadererror |= (1 << monheadererrorbit++);
260 monheadererror |= (1 << monheadererrorbit++);
265 monheadererror |= (1 << monheadererrorbit++);
277 monheadererror |= (1 << monheadererrorbit++);
282 monheadererror |= (1 << monheadererrorbit++);
296 monheadererror |= (1 << monheadererrorbit++);
298 monheadererror |= (1 << monheadererrorbit++);
299 monheadererrorbit += 2;
302 monheadererror |= (1 << monheadererrorbit++);
304 monheadererror |= (1 << monheadererrorbit++);
306 monheadererror |= (1 << monheadererrorbit++);
308 monheadererror |= (1 << monheadererrorbit++);
310 monheadererror |= (1 << monheadererrorbit++);
312 monheadererror |= (1 << monheadererrorbit++);
314 monheadererror |= (1 << monheadererrorbit++);
316 monheadererror |= (1 << monheadererrorbit++);
318 monheadererror |= (1 << monheadererrorbit++);
320 monheadererror |= (1 << monheadererrorbit++);
322 monheadererror |= (1 << monheadererrorbit++);
328 if (monheadererror) {
329 ATH_MSG_WARNING(
" consistency error in mon checker at packet " <<
m_iPacket <<
" errorbits " << std::hex << monheadererror << std::dec);
338 if (energy & (1 << 17))
339 return energy - pow(2, 18);
370 if (byteshift == 4) {
377 byte = ((std::byteswap(p[wordshift])) >> (8 * (4 - 1 - byteshift))) & 0xff;
381 unsigned int msb = 0;
382 unsigned int lsb = 0;
387 word = lsb | (msb << 8);
391 unsigned int& at0Data,
unsigned int& at1Data,
unsigned int& saturation,
bool& at0val,
bool& at1val) {
398 bool satByte = nbytesPerChannel % 2;
404 unsigned int satData = 0;
407 unsigned int word1 = 0;
408 unsigned int word2 = 0;
410 if (nbytesPerChannel > 3) {
413 at0Data = word1 & 0x7fff;
414 at0val = word1 & 0x8000;
415 if (nbytesPerChannel > 3) {
416 at1Data = word2 & 0x7fff;
417 at1val = word2 & 0x8000;
429 at0Data = (at0Data << 3) | (satData & 0x7);
430 at1Data = (at1Data << 3) | ((satData & 0x70) >> 4);
431 saturation = ((satData & 0x88) == 0x88);
433 at0Data = (at0Data << 3) | ((satData & 0x70) >> 4);
434 at1Data = (at1Data << 3) | (satData & 0x7);
435 saturation = ((satData & 0x88) == 0x88);
438 at0Data = (at0Data << 3) | (satData & 0x7);
439 saturation = (satData & 0x20);
442 at1Data = (at1Data << 3) | (satData & 0x7);
443 saturation = (satData & 0x20);
451 const unsigned int sourceID = robFrag->rob_source_id();
452 m_l1ID = robFrag->rod_lvl1_id();
454 const uint32_t* p = robFrag->rod_data();
455 const unsigned int n = robFrag->rod_ndata();
464 const uint32_t* rod_status = robFrag->rod_status();
465 const unsigned int rod_nstatus = robFrag->rod_nstatus();
466 if (rod_nstatus != 27) {
467 ATH_MSG_WARNING(
"Inconsistent number of rod header status elements: nstatus= " << rod_nstatus);
470 if (rod_nstatus > 8) {
471 uint32_t status8 = rod_status[8];
485 pat1.
DAC = rod_status[9];
486 pat1.
delay = rod_status[10];
488 for (
unsigned int i = 0; i < 4; ++i)
489 pat1.
patterns[i] = rod_status[i + 11];
491 pat2.
DAC = rod_status[15];
492 pat2.
delay = rod_status[16];
494 for (
unsigned int i = 0; i < 4; ++i)
495 pat2.
patterns[i] = rod_status[i + 17];
497 pat3.
DAC = rod_status[21];
498 pat3.
delay = rod_status[22];
500 for (
unsigned int i = 0; i < 4; ++i)
501 pat3.
patterns[i] = rod_status[i + 23];
512 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
521 <<
" " << sourceID << std::dec);
530 <<
" " << sourceID << std::dec);
539 for (
unsigned int ip = 1; ip <
m_nPackets; ++ip) {
541 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
547 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
554 ATH_MSG_DEBUG(
" end of header check computed offset=" << std::dec << offset <<
" nwords in payload=" << n);
574 std::vector<unsigned int> bc_size;
595 val.latomeChannel = 99999;
692 val.latomeChannel = 99999;
701 for (
short iBC = 0; iBC < nBC; ++iBC) {
705 if (iBC < startBC1 || iBC >= startBC1 + nBC1)
711 unsigned int oldipacket = 0;
712 for (
unsigned int itimeslot = 0; itimeslot < 6; ++itimeslot) {
713 unsigned int l_bcid = (std::byteswap(p[s]))>>16;
722 unsigned int bcid_c = bcid+1;
727 if(bcid_c != l_bcid){
728 ATH_MSG_WARNING(
"ERROR: BCID not increasing properly between samples, sourceId: " <<
m_nthLATOME <<
" L1ID is: " <<
m_l1ID <<
", BCID is from payload: " << l_bcid <<
", expected BCID is: " << bcid_c <<
", LATOME channel is: " << nsc );
735 unsigned int mux = ((std::byteswap(p[s])) >> 8) & 0xff;
742 unsigned int timeslotsize = timeslot_nsc[itimeslot];
743 unsigned int nbytes = timeslotsize * nbytesPerChannel;
744 unsigned int n64word = nbytes / 8;
747 ATH_MSG_DEBUG(
" at BC " << iBC <<
" timeslot " << itimeslot <<
" " << bcid <<
" " << mux <<
" n64word " << n64word <<
" at0 " << (
int)at0 <<
" at1 "
748 << (
int)at1 <<
" l_bcid " << bcid);
750 unsigned int wordshift = s;
751 unsigned int byteshift = 0;
755 for (
unsigned int ichan = 0; ichan < timeslotsize; ++ichan) {
756 unsigned int at0Data = 0, at1Data = 0, satData = 0;
757 bool at0val =
false, at1val =
false;
765 decodeChannel(wordshift, byteshift, p, at0, at1, at0Data, at1Data, satData, at0val, at1val);
766 ATH_MSG_DEBUG(
" wordshift " << wordshift <<
" byteshift " << byteshift <<
" at0data " << at0Data <<
" at1Data " << at1Data <<
" satData " << satData
767 <<
" at0val " << at0val <<
" at1val " << at1val <<
" nsc " << nsc);
770 const HWIdentifier SCID = nsc < (int) LATOME_Channels->size() ? (*LATOME_Channels)[nsc] : hwidEmpty;
771 if (SCID == hwidEmpty) {
774 int RAWValue0 = -999;
776 ATH_MSG_DEBUG(
"at0 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
781 int defaultADCValue = -1;
782 int defaultEValue = -99999;
786 if ((
unsigned)iBC < rawValuesInEvent.adc.size()) {
787 rawValuesInEvent.adc[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
791 if ((
unsigned)iBC < rawValuesInEvent.adc_bas.size()) {
792 rawValuesInEvent.adc_bas[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
796 if ((
unsigned)iBC < rawValuesInEvent.et.size()) {
797 rawValuesInEvent.et[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
798 rawValuesInEvent.saturation[iBC] = satData;
802 if ((
unsigned)iBC < rawValuesInEvent.et_id.size()) {
803 rawValuesInEvent.et_id[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
804 rawValuesInEvent.saturation[iBC] = satData;
814 int RAWValue1 = -999;
816 ATH_MSG_DEBUG(
"at1 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
822 const size_t BCidx = iBC - startBC1;
825 if (BCidx < rawValuesInEvent.adc.size()) {
826 rawValuesInEvent.adc[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
830 if (BCidx < rawValuesInEvent.adc_bas.size()) {
831 rawValuesInEvent.adc_bas[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
835 if (BCidx < rawValuesInEvent.et.size()) {
836 rawValuesInEvent.et[BCidx] = (at1val) ?
signEnergy(RAWValue1) : defaultEValue;
837 rawValuesInEvent.saturation[BCidx] = satData;
841 if (BCidx < rawValuesInEvent.et_id.size()) {
857 ATH_MSG_ERROR(
"inconsistant wordshift in decoding everaged data");
860 unsigned int averageword = std::byteswap(p[wordshift]);
862 unsigned int sumSq = std::byteswap(p[wordshift]);
864 unsigned long long sumsqMSB = averageword >> 28;
865 sumsqMSB = sumsqMSB << 32;
882 ATH_MSG_DEBUG(
"wordshift before: " << wordshift <<
", s: " << s);
883 if ((wordshift - s) % 2)
885 ATH_MSG_DEBUG(
"wordshift after : " << wordshift <<
", s: " << s);
888 <<
"!=" << n64word * 2 <<
" m_ipacket " <<
m_iPacket);
899 if (onoffmap && clmap) {
900 fillCalib(LATOME_Channels, onoffmap, clmap);
911 uint32_t DAC_value=0;
912 uint16_t delay_value=0;
913 uint16_t isPulsed_value=
false;
914 std::unique_ptr<LArCalibParams> calibParams1;
915 std::unique_ptr<LArCalibParams> calibParams2;
923 cabling = {*cablingHdl};
929 calibParams1=std::make_unique<LArCalibParams>();
930 calibParams2=std::make_unique<LArCalibParams>();
932 if (pattype > 0x48) {
933 StatusCode sc1 = calibParams1->initialize();
934 StatusCode sc2 = calibParams2->initialize();
935 if (sc1 != StatusCode::SUCCESS || sc2 != StatusCode::SUCCESS) {
936 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
939 if (pattype == 0x49 || pattype == 0x4a) {
951 StatusCode sc1 = calibParams1->initialize();
952 if (sc1 != StatusCode::SUCCESS) {
953 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
961 unsigned nWarnings = 0;
964 HWIdentifier SCID = ch < (int) LATOME_Channels->size() ? (*LATOME_Channels)[ch] : hwidEmpty;
965 if (SCID == hwidEmpty) {
974 std::vector<uint64_t> sum;
975 std::vector<uint64_t> sum2;
976 unsigned int ntmin = 9999999;
990 sum[is] = round(fsum);
991 sum2[is] = round(fsum2);
994 std::fill(sum.begin(), sum.end(), 0);
995 std::fill(sum2.begin(), sum2.end(), 0);
996 if (++nWarnings < 64) {
1005 if (pattype == 0x49 || pattype == 0x4a) {
1006 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 0) {
1007 calibParams = calibParams1.get();
1009 calibParams = calibParams2.get();
1011 }
else if (pattype == 0x4b || pattype == 0x4c) {
1012 if (
m_decoder->m_onlineId->isHECchannel(SCID)) {
1013 calibParams = calibParams1.get();
1015 calibParams = calibParams2.get();
1018 calibParams = calibParams1.get();
1020 unsigned int eventNb = 0;
1021 unsigned int numCL = 0;
1022 unsigned int numPulsedLeg = 0;
1023 std::vector<Identifier> ccellIds(0);
1024 Identifier myofflineID = cabling->cnvToIdentifier(SCID);
1025 ccellIds =
m_decoder->m_sc2ccMappingTool->superCellToOfflineID(myofflineID);
1028 const std::vector<HWIdentifier>& calibLineLeg = clcabling->
calibSlotLine(cellLegHWID);
1029 numCL += calibLineLeg.size();
1031 if (calibParams->
isPulsed(eventNb, calibLineHWID)) {
1037 isPulsed_value =
true;
1038 if (numPulsedLeg != numCL) {
1041 isPulsed_value =
false;
1043 DAC_value = calibParams->
DAC(eventNb, SCID) * numPulsedLeg;
1046 int ft =
m_decoder->m_onlineId->feedthrough(SCID);
1047 int slot =
m_decoder->m_onlineId->slot(SCID);
1048 int channel =
m_decoder->m_onlineId->channel(SCID);
1049 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 1 && (ft == 3 || ft == 10 || ft == 16 || ft == 22)) {
1052 if (channel >= 16 && channel <= 31) {
1054 DAC_value = DAC_value / 1.2;
1055 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 1/1.2" <<
endmsg;
1056 }
else if (channel >= 32 && channel <= 47) {
1058 DAC_value = DAC_value * 7. / 8.;
1059 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 7./8." <<
endmsg;
1064 delay_value = calibParams->
Delay(eventNb, SCID);
1071 if (nWarnings > 16) {
1072 ATH_MSG_WARNING(
"Found " << nWarnings <<
" supercells with no valid triggers");
1081 const HWIdentifier SCID = ch < (int) LATOME_Channels->size() ? (*LATOME_Channels)[ch] : hwidEmpty;
1082 if (SCID == hwidEmpty) {
1086 if (
m_decoder->m_ignoreBarrelChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 0)
1088 if (
m_decoder->m_ignoreEndcapChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 1)
1091 std::vector<short> adcValues_inChannel_inEvent;
1101 std::vector<unsigned short> bcid_in_event;
1111 std::vector<unsigned short> bcid_in_event;
1124 std::vector<unsigned short> bcid_in_event;
1138 std::vector<unsigned short> bcid_in_event;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
Tool to get LATOME SC and SCID mapping file and fill std::map variable with it.
static const InterfaceID IID_ILArLATOMEDecoder("LArLATOMEDecoder", 1, 0)
Byte stream converter of LATOME.
#define N_LATOME_CHANNELS
Tool to store LATOME mon header and footer data.
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
const ServiceHandle< StoreGateSvc > & detStore() const
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
void clear()
Erase all the elements in the collection.
std::string getString() const
Provide a string form of the identifier - hexadecimal.
Container class for LArAccumulatedCalibDigit.
Data class for calibration ADC samples preprocessed by the DSP.
Container class for LArAccumulatedDigit.
Data class for ADC samples and autocorr preprocessed by the DSP.
const std::vector< HWIdentifier > & calibSlotLine(const HWIdentifier id) const
unsigned Delay(const unsigned event, const HWIdentifier calibLineID) const
bool isPulsed(const unsigned event, const HWIdentifier calibLineID) const
unsigned DAC(const unsigned event, const HWIdentifier calibLineID) const
Container class for LArDigit.
int signEnergy(unsigned int energy)
static const Word m_monTrailerSize
some cached info to ease processing reading from data header
std::vector< LatomeCalibPatterns > m_latomeCalibPatternsInEvent
LArRawSCContainer * m_et_id_coll
void fillRaw(const std::vector< HWIdentifier > *LATOME_Channels)
Pass ADC values from an event.
unsigned int Word
this should be the same as how we get the data, otherwise we will have bugs.
LArLATOMEHeaderContainer * m_header_coll
EventProcess(const LArLATOMEDecoder *decoderInput, LArDigitContainer *adc_coll, LArDigitContainer *adc_bas_coll, LArRawSCContainer *et_coll, LArRawSCContainer *et_id_coll, LArAccumulatedDigitContainer *accdigits, LArAccumulatedCalibDigitContainer *caccdigits, LArLATOMEHeaderContainer *header_coll)
void decodeChannel(unsigned int &wordshift, unsigned int &byteshift, const uint32_t *p, MonDataType at0, MonDataType at1, unsigned int &at0Data, unsigned int &at1Data, unsigned int &satData, bool &at0val, bool &at1val)
void decodeByte(unsigned int &byte, unsigned int wordshift, unsigned int byteshift, const uint32_t *p)
LArAccumulatedDigitContainer * m_accdigits
const LArLATOMEDecoder * m_decoder
unsigned int bytesPerChannel(MonDataType at0, MonDataType at1)
void fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment *pROB, const std::vector< HWIdentifier > *LATOME_Channels, const LArOnOffIdMapping *onoffmap=nullptr, const LArCalibLineMapping *clmap=nullptr)
Execute decoding for an event.
LArDigitContainer * m_adc_bas_coll
LArAccumulatedCalibDigitContainer * m_caccdigits
bool compareOrSet(Word ¶m, Word value, bool compare)
static const Word s_monHeaderMarker
this is fixed and not read from data
std::vector< LatomeRawData > m_rawValuesInEvent
std::vector< LatomeAveragedRawData > m_averagedRawValuesInEvent
unsigned int decodeHeader(const uint32_t *p, unsigned int offset)
static const Word s_monCheckPoint
std::vector< unsigned short > m_BCIDsInEvent
void increaseByteShift(unsigned int &wordshift, unsigned int &byteshift)
LArRawSCContainer * m_et_coll
void decodeWord(unsigned int &word, unsigned int &wordshift, unsigned int &byteshift, const uint32_t *p)
LArDigitContainer * m_adc_coll
void increaseWordShift(unsigned int &wordshift)
void fillCalib(const std::vector< HWIdentifier > *LATOME_Channels, const LArOnOffIdMapping *onoffmap, const LArCalibLineMapping *clmap)
std::vector< Word > m_packetEnd
unsigned int decodeTrailer(const uint32_t *p, unsigned int offset)
std::vector< unsigned int > patterns
static const InterfaceID & interfaceID()
StatusCode convert(const std::vector< const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment * > &robFrags, const LArLATOMEMapping *map, LArDigitContainer *adc_coll, LArDigitContainer *adc_bas_coll, LArRawSCContainer *et_coll, LArRawSCContainer *et_id_coll, LArLATOMEHeaderContainer *header_coll) const
Converter.
LArLATOMEDecoder(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
virtual StatusCode initialize()
Initialize the converter.
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKeySC
const LArOnline_SuperCellID * m_onlineId
static const int s_nBunches
Maximum value of BCID.
ToolHandle< ICaloSuperCellIDTool > m_sc2ccMappingTool
BooleanProperty m_protectSourceId
class to provide SC mapping
HWIdentifier createSignalChannelID(const Identifier &id) const
create a HWIdentifier from an Identifier (not inline)
Container class for LArRawSC.
Liquid Argon SuperCell raw data.
Base class for LArDigits taken by LATOME.
singleton-like access to IMessageSvc via open function and helper
std::vector< std::string > patterns
=============================================================================
eformat::ROBFragment< PointerType > ROBFragment
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
Extra patterns decribing particle interation process.