5#define DETAIL_DUMP_ON false
6#define ADC_DUMP_ON false
7#define VALIDATE_DUMP_ON false
12#include "eformat/Issue.h"
13#include "eformat/index.h"
15#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) {
87 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 EventProcess ev(
this, 0, 0, 0, 0, accdigits, caccdigits, header_coll);
95 ev.fillCollection(&robFrag,
map, onoffmap, clmap);
96 }
catch (eformat::Issue& ex) {
97 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
103 header_coll->
clear();
109 return StatusCode::SUCCESS;
118 if (robFrags.size() > 0) {
122 uint32_t latomeSourceID = pRob->rod_source_id();
123 if (!(latomeSourceID & 0x1000)) {
124 ATH_MSG_DEBUG(
" discarding non latome source ID " << std::hex << latomeSourceID);
127 ATH_MSG_DEBUG(
" found latome source ID " << std::hex << latomeSourceID);
129 EventProcess ev(
this, adc_coll, adc_bas_coll, et_coll, et_id_coll, 0, 0, header_coll);
130 ev.fillCollection(pRob,
map,
nullptr,
nullptr);
131 }
catch (eformat::Issue& ex) {
132 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
136 adc_bas_coll->
clear();
142 header_coll->
clear();
147 return StatusCode::SUCCESS;
153 :
AthMessaging(
Gaudi::svcLocator()->service<IMessageSvc>(
"MessageSvc"),
"LArLATOMEDecoder::EventProcess"),
223 return param == value;
228 if (bswap_32(p[offset]) != 0xc0ffee00 || bswap_32(p[offset + 1] != 0xaaaaaaaa)) {
229 ATH_MSG_WARNING(
"Problem in trailer at packet " <<
m_iPacket <<
" words " << std::hex << bswap_32(p[offset]) <<
", " << bswap_32(p[offset + 1])
239 int monheadererror = 0;
240 int monheadererrorbit = 0;
242 monheadererror |= (1 << monheadererrorbit++);
245 monheadererror |= (1 << monheadererrorbit++);
247 ATH_MSG_DEBUG(
"Mon header L1ID " << l1IDtmp <<
" different from rod header L1ID " <<
m_l1ID);
251 Word monHeaderMarker = bswap_32(p[2 + offset]);
252 Word monCheckPoint = bswap_32(p[4 + offset]);
254 monheadererror |= (1 << monheadererrorbit++);
258 monheadererror |= (1 << monheadererrorbit++);
263 monheadererror |= (1 << monheadererrorbit++);
275 monheadererror |= (1 << monheadererrorbit++);
280 monheadererror |= (1 << monheadererrorbit++);
294 monheadererror |= (1 << monheadererrorbit++);
296 monheadererror |= (1 << monheadererrorbit++);
297 monheadererrorbit += 2;
300 monheadererror |= (1 << monheadererrorbit++);
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++);
326 if (monheadererror) {
327 ATH_MSG_WARNING(
" consistency error in mon checker at packet " <<
m_iPacket <<
" errorbits " << std::hex << monheadererror << std::dec);
336 if (energy & (1 << 17))
337 return energy - pow(2, 18);
368 if (byteshift == 4) {
375 byte = ((bswap_32(p[wordshift])) >> (8 * (4 - 1 - byteshift))) & 0xff;
379 unsigned int msb = 0;
380 unsigned int lsb = 0;
385 word = lsb | (msb << 8);
389 unsigned int& at0Data,
unsigned int& at1Data,
unsigned int& saturation,
bool& at0val,
bool& at1val) {
396 bool satByte = nbytesPerChannel % 2;
402 unsigned int satData = 0;
405 unsigned int word1 = 0;
406 unsigned int word2 = 0;
408 if (nbytesPerChannel > 3) {
411 at0Data = word1 & 0x7fff;
412 at0val = word1 & 0x8000;
413 if (nbytesPerChannel > 3) {
414 at1Data = word2 & 0x7fff;
415 at1val = word2 & 0x8000;
427 at0Data = (at0Data << 3) | (satData & 0x7);
428 at1Data = (at1Data << 3) | ((satData & 0x70) >> 4);
429 saturation = ((satData & 0x88) == 0x88);
431 at0Data = (at0Data << 3) | ((satData & 0x70) >> 4);
432 at1Data = (at1Data << 3) | (satData & 0x7);
433 saturation = ((satData & 0x88) == 0x88);
436 at0Data = (at0Data << 3) | (satData & 0x7);
437 saturation = (satData & 0x20);
440 at1Data = (at1Data << 3) | (satData & 0x7);
441 saturation = (satData & 0x20);
449 const unsigned int sourceID = robFrag->rob_source_id();
450 m_l1ID = robFrag->rod_lvl1_id();
452 const uint32_t* p = robFrag->rod_data();
453 const unsigned int n = robFrag->rod_ndata();
462 const uint32_t* rod_status = robFrag->rod_status();
463 const unsigned int rod_nstatus = robFrag->rod_nstatus();
464 if (rod_nstatus != 27) {
465 ATH_MSG_WARNING(
"Inconsistent number of rod header status elements: nstatus= " << rod_nstatus);
468 if (rod_nstatus > 8) {
469 uint32_t status8 = rod_status[8];
483 pat1.
DAC = rod_status[9];
484 pat1.
delay = rod_status[10];
486 for (
unsigned int i = 0; i < 4; ++i)
487 pat1.
patterns[i] = rod_status[i + 11];
489 pat2.
DAC = rod_status[15];
490 pat2.
delay = rod_status[16];
492 for (
unsigned int i = 0; i < 4; ++i)
493 pat2.
patterns[i] = rod_status[i + 17];
495 pat3.
DAC = rod_status[21];
496 pat3.
delay = rod_status[22];
498 for (
unsigned int i = 0; i < 4; ++i)
499 pat3.
patterns[i] = rod_status[i + 23];
510 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
519 <<
" " << sourceID << std::dec);
528 <<
" " << sourceID << std::dec);
537 for (
unsigned int ip = 1; ip <
m_nPackets; ++ip) {
539 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
545 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
552 ATH_MSG_DEBUG(
" end of header check computed offset=" << std::dec << offset <<
" nwords in payload=" << n);
572 std::vector<unsigned int> bc_size;
593 val.latomeChannel = 99999;
690 val.latomeChannel = 99999;
699 for (
short iBC = 0; iBC < nBC; ++iBC) {
703 if (iBC < startBC1 || iBC >= startBC1 + nBC1)
709 unsigned int oldipacket = 0;
710 for (
unsigned int itimeslot = 0; itimeslot < 6; ++itimeslot) {
711 unsigned int l_bcid = (bswap_32(p[s]))>>16;
720 unsigned int bcid_c = bcid+1;
725 if(bcid_c != l_bcid){
726 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 );
733 unsigned int mux = ((bswap_32(p[s])) >> 8) & 0xff;
740 unsigned int timeslotsize = timeslot_nsc[itimeslot];
741 unsigned int nbytes = timeslotsize * nbytesPerChannel;
742 unsigned int n64word = nbytes / 8;
745 ATH_MSG_DEBUG(
" at BC " << iBC <<
" timeslot " << itimeslot <<
" " << bcid <<
" " << mux <<
" n64word " << n64word <<
" at0 " << (
int)at0 <<
" at1 "
746 << (
int)at1 <<
" l_bcid " << bcid);
748 unsigned int wordshift = s;
749 unsigned int byteshift = 0;
753 for (
unsigned int ichan = 0; ichan < timeslotsize; ++ichan) {
754 unsigned int at0Data = 0, at1Data = 0, satData = 0;
755 bool at0val =
false, at1val =
false;
763 decodeChannel(wordshift, byteshift, p, at0, at1, at0Data, at1Data, satData, at0val, at1val);
764 ATH_MSG_DEBUG(
" wordshift " << wordshift <<
" byteshift " << byteshift <<
" at0data " << at0Data <<
" at1Data " << at1Data <<
" satData " << satData
765 <<
" at0val " << at0val <<
" at1val " << at1val <<
" nsc " << nsc);
769 if (SCID == hwidEmpty) {
772 int RAWValue0 = -999;
774 ATH_MSG_DEBUG(
"at0 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
779 int defaultADCValue = -1;
780 int defaultEValue = -99999;
784 if ((
unsigned)iBC < rawValuesInEvent.adc.size()) {
785 rawValuesInEvent.adc[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
789 if ((
unsigned)iBC < rawValuesInEvent.adc_bas.size()) {
790 rawValuesInEvent.adc_bas[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
794 if ((
unsigned)iBC < rawValuesInEvent.et.size()) {
795 rawValuesInEvent.et[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
796 rawValuesInEvent.saturation[iBC] = satData;
800 if ((
unsigned)iBC < rawValuesInEvent.et_id.size()) {
801 rawValuesInEvent.et_id[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
802 rawValuesInEvent.saturation[iBC] = satData;
812 int RAWValue1 = -999;
814 ATH_MSG_DEBUG(
"at1 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
820 const size_t BCidx = iBC - startBC1;
823 if (BCidx < rawValuesInEvent.adc.size()) {
824 rawValuesInEvent.adc[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
828 if (BCidx < rawValuesInEvent.adc_bas.size()) {
829 rawValuesInEvent.adc_bas[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
833 if (BCidx < rawValuesInEvent.et.size()) {
834 rawValuesInEvent.et[BCidx] = (at1val) ?
signEnergy(RAWValue1) : defaultEValue;
835 rawValuesInEvent.saturation[BCidx] = satData;
839 if (BCidx < rawValuesInEvent.et_id.size()) {
855 ATH_MSG_ERROR(
"inconsistant wordshift in decoding everaged data");
858 unsigned int averageword = bswap_32(p[wordshift]);
860 unsigned int sumSq = bswap_32(p[wordshift]);
862 unsigned long long sumsqMSB = averageword >> 28;
863 sumsqMSB = sumsqMSB << 32;
880 ATH_MSG_DEBUG(
"wordshift before: " << wordshift <<
", s: " << s);
881 if ((wordshift - s) % 2)
883 ATH_MSG_DEBUG(
"wordshift after : " << wordshift <<
", s: " << s);
886 <<
"!=" << n64word * 2 <<
" m_ipacket " <<
m_iPacket);
897 if (onoffmap && clmap) {
909 uint32_t DAC_value=0;
910 uint16_t delay_value=0;
911 uint16_t isPulsed_value=
false;
912 std::unique_ptr<LArCalibParams> calibParams1;
913 std::unique_ptr<LArCalibParams> calibParams2;
921 cabling = {*cablingHdl};
927 calibParams1=std::make_unique<LArCalibParams>();
928 calibParams2=std::make_unique<LArCalibParams>();
930 if (pattype > 0x48) {
931 StatusCode sc1 = calibParams1->initialize();
932 StatusCode sc2 = calibParams2->initialize();
933 if (sc1 != StatusCode::SUCCESS || sc2 != StatusCode::SUCCESS) {
934 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
937 if (pattype == 0x49 || pattype == 0x4a) {
949 StatusCode sc1 = calibParams1->initialize();
950 if (sc1 != StatusCode::SUCCESS) {
951 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
959 unsigned nWarnings = 0;
963 if (SCID == hwidEmpty) {
972 std::vector<uint64_t> sum;
973 std::vector<uint64_t> sum2;
974 unsigned int ntmin = 9999999;
988 sum[is] = round(fsum);
989 sum2[is] = round(fsum2);
992 std::fill(sum.begin(), sum.end(), 0);
993 std::fill(sum2.begin(), sum2.end(), 0);
994 if (++nWarnings < 64) {
995 ATH_MSG_WARNING(
"No valid triggers for supercell " << SCID.getString());
1003 if (pattype == 0x49 || pattype == 0x4a) {
1004 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 0) {
1005 calibParams = calibParams1.get();
1007 calibParams = calibParams2.get();
1009 }
else if (pattype == 0x4b || pattype == 0x4c) {
1010 if (
m_decoder->m_onlineId->isHECchannel(SCID)) {
1011 calibParams = calibParams1.get();
1013 calibParams = calibParams2.get();
1016 calibParams = calibParams1.get();
1018 unsigned int eventNb = 0;
1019 unsigned int numCL = 0;
1020 unsigned int numPulsedLeg = 0;
1021 std::vector<Identifier> ccellIds(0);
1022 Identifier myofflineID = cabling->cnvToIdentifier(SCID);
1023 ccellIds =
m_decoder->m_sc2ccMappingTool->superCellToOfflineID(myofflineID);
1026 const std::vector<HWIdentifier>& calibLineLeg = clcabling->
calibSlotLine(cellLegHWID);
1027 numCL += calibLineLeg.size();
1029 if (calibParams->
isPulsed(eventNb, calibLineHWID)) {
1035 isPulsed_value =
true;
1036 if (numPulsedLeg != numCL) {
1039 isPulsed_value =
false;
1041 DAC_value = calibParams->
DAC(eventNb, SCID) * numPulsedLeg;
1044 int ft =
m_decoder->m_onlineId->feedthrough(SCID);
1045 int slot =
m_decoder->m_onlineId->slot(SCID);
1046 int channel =
m_decoder->m_onlineId->channel(SCID);
1047 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 1 && (ft == 3 || ft == 10 || ft == 16 || ft == 22)) {
1050 if (channel >= 16 && channel <= 31) {
1052 DAC_value = DAC_value / 1.2;
1053 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 1/1.2" <<
endmsg;
1054 }
else if (channel >= 32 && channel <= 47) {
1056 DAC_value = DAC_value * 7. / 8.;
1057 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 7./8." <<
endmsg;
1062 delay_value = calibParams->
Delay(eventNb, SCID);
1069 if (nWarnings > 16) {
1070 ATH_MSG_WARNING(
"Found " << nWarnings <<
" supercells with no valid triggers");
1080 if (SCID == hwidEmpty) {
1084 if (
m_decoder->m_ignoreBarrelChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 0)
1086 if (
m_decoder->m_ignoreEndcapChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 1)
1089 std::vector<short> adcValues_inChannel_inEvent;
1099 std::vector<unsigned short> bcid_in_event;
1109 std::vector<unsigned short> bcid_in_event;
1122 std::vector<unsigned short> bcid_in_event;
1136 std::vector<unsigned short> bcid_in_event;
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#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
C++23-compatible byteswap()
const ServiceHandle< StoreGateSvc > & detStore() const
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
void clear()
Erase all the elements in the collection.
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
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)
void fillCalib(const LArLATOMEMapping *map, const LArOnOffIdMapping *onoffmap, const LArCalibLineMapping *clmap)
LArAccumulatedDigitContainer * m_accdigits
const LArLATOMEDecoder * m_decoder
unsigned int bytesPerChannel(MonDataType at0, MonDataType at1)
LArDigitContainer * m_adc_bas_coll
LArAccumulatedCalibDigitContainer * m_caccdigits
bool compareOrSet(Word ¶m, Word value, bool compare)
void fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment *pROB, const LArLATOMEMapping *map, const LArOnOffIdMapping *onoffmap=nullptr, const LArCalibLineMapping *clmap=nullptr)
Execute decoding for an event.
void fillRaw(const LArLATOMEMapping *map)
Pass ADC values from an event.
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)
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.