5#define DETAIL_DUMP_ON false
6#define ADC_DUMP_ON false
7#define VALIDATE_DUMP_ON false
14#include "GaudiKernel/MsgStream.h"
26 declareInterface<LArLATOMEDecoder>(
this);
40 return StatusCode::SUCCESS;
47 if(!
re)
return StatusCode::FAILURE;;
52 }
catch (eformat::Issue& ex) {
53 ATH_MSG_WARNING(
"Exception while checking eformat fragment validity: " << ex.what());
58 return StatusCode::FAILURE;
61 std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> > robIndex;
62 eformat::helper::build_toc(*
re, robIndex);
63 for (
const auto& mapit : robIndex)
64 ATH_MSG_DEBUG(
"Rob Index subdetgroup is " << std::hex << mapit.first);
65 std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> >
::const_iterator robIt = robIndex.find(eformat::LAR);
66 if (robIt != robIndex.end()) {
67 const std::vector<const uint32_t*>& robs = robIt->second;
68 for (
const uint32_t* pRob : robs) {
72 uint32_t latomeSourceID = robFrag.rod_source_id();
73 if (!(latomeSourceID & 0x1000)) {
74 ATH_MSG_DEBUG(
" discarding non latome source ID " << std::hex << latomeSourceID);
77 ATH_MSG_DEBUG(
" found latome source ID " << std::hex << latomeSourceID);
79 EventProcess ev(
this, 0, 0, 0, 0, accdigits, caccdigits, header_coll);
80 ev.fillCollection(&robFrag,
map, onoffmap, clmap);
81 }
catch (eformat::Issue& ex) {
82 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
94 return StatusCode::SUCCESS;
103 if (robFrags.size() > 0) {
107 uint32_t latomeSourceID = pRob->rod_source_id();
108 if (!(latomeSourceID & 0x1000)) {
109 ATH_MSG_DEBUG(
" discarding non latome source ID " << std::hex << latomeSourceID);
112 ATH_MSG_DEBUG(
" found latome source ID " << std::hex << latomeSourceID);
114 EventProcess ev(
this, adc_coll, adc_bas_coll, et_coll, et_id_coll, 0, 0, header_coll);
115 ev.fillCollection(pRob,
map,
nullptr,
nullptr);
116 }
catch (eformat::Issue& ex) {
117 ATH_MSG_WARNING(
" exception thrown by ROBFragment, badly corrupted event. Abort decoding ");
121 adc_bas_coll->
clear();
127 header_coll->
clear();
132 return StatusCode::SUCCESS;
138 :
AthMessaging(
Gaudi::svcLocator()->service<IMessageSvc>(
"MessageSvc"),
"LArLATOMEDecoder::EventProcess"),
207 return param == value;
212 if (bswap_32(p[offset]) != 0xc0ffee00 || bswap_32(p[offset + 1] != 0xaaaaaaaa)) {
213 ATH_MSG_WARNING(
"Problem in trailer at packet " <<
m_iPacket <<
" words " << std::hex << bswap_32(p[offset]) <<
", " << bswap_32(p[offset + 1])
223 int monheadererror = 0;
224 int monheadererrorbit = 0;
226 monheadererror |= (1 << monheadererrorbit++);
229 monheadererror |= (1 << monheadererrorbit++);
231 ATH_MSG_DEBUG(
"Mon header L1ID " << l1IDtmp <<
" different from rod header L1ID " <<
m_l1ID);
235 Word monHeaderMarker = bswap_32(p[2 + offset]);
236 Word monCheckPoint = bswap_32(p[4 + offset]);
238 monheadererror |= (1 << monheadererrorbit++);
242 monheadererror |= (1 << monheadererrorbit++);
247 monheadererror |= (1 << monheadererrorbit++);
259 monheadererror |= (1 << monheadererrorbit++);
264 monheadererror |= (1 << monheadererrorbit++);
277 monheadererror |= (1 << monheadererrorbit++);
279 monheadererror |= (1 << monheadererrorbit++);
280 monheadererrorbit += 2;
283 monheadererror |= (1 << monheadererrorbit++);
285 monheadererror |= (1 << monheadererrorbit++);
287 monheadererror |= (1 << monheadererrorbit++);
289 monheadererror |= (1 << monheadererrorbit++);
291 monheadererror |= (1 << monheadererrorbit++);
293 monheadererror |= (1 << monheadererrorbit++);
295 monheadererror |= (1 << monheadererrorbit++);
297 monheadererror |= (1 << monheadererrorbit++);
299 monheadererror |= (1 << monheadererrorbit++);
301 monheadererror |= (1 << monheadererrorbit++);
303 monheadererror |= (1 << monheadererrorbit++);
309 if (monheadererror) {
310 ATH_MSG_WARNING(
" consistency error in mon checker at packet " <<
m_iPacket <<
" errorbits " << std::hex << monheadererror << std::dec);
319 if (energy & (1 << 17))
320 return energy -
pow(2, 18);
351 if (byteshift == 4) {
358 byte = ((bswap_32(p[wordshift])) >> (8 * (4 - 1 - byteshift))) & 0xff;
362 unsigned int msb = 0;
363 unsigned int lsb = 0;
368 word = lsb | (msb << 8);
372 unsigned int& at0Data,
unsigned int& at1Data,
unsigned int& saturation,
bool& at0val,
bool& at1val) {
379 bool satByte = nbytesPerChannel % 2;
385 unsigned int satData = 0;
388 unsigned int word1 = 0;
389 unsigned int word2 = 0;
391 if (nbytesPerChannel > 3) {
394 at0Data = word1 & 0x7fff;
395 at0val = word1 & 0x8000;
396 if (nbytesPerChannel > 3) {
397 at1Data = word2 & 0x7fff;
398 at1val = word2 & 0x8000;
410 at0Data = (at0Data << 3) | (satData & 0x7);
411 at1Data = (at1Data << 3) | ((satData & 0x70) >> 4);
412 saturation = ((satData & 0x88) == 0x88);
414 at0Data = (at0Data << 3) | ((satData & 0x70) >> 4);
415 at1Data = (at1Data << 3) | (satData & 0x7);
416 saturation = ((satData & 0x88) == 0x88);
419 at0Data = (at0Data << 3) | (satData & 0x7);
420 saturation = (satData & 0x20);
423 at1Data = (at1Data << 3) | (satData & 0x7);
424 saturation = (satData & 0x20);
436 const unsigned int sourceID = robFrag->rob_source_id();
444 m_l1ID = robFrag->rod_lvl1_id();
446 const uint32_t* p = robFrag->rod_data();
447 const unsigned int n = robFrag->rod_ndata();
454 const uint32_t* rod_status = robFrag->rod_status();
455 const unsigned int rod_nstatus = robFrag->rod_nstatus();
456 if (rod_nstatus != 27) {
457 ATH_MSG_WARNING(
"Inconsistent number of rod header status elements: nstatus= " << rod_nstatus);
460 if (rod_nstatus > 8) {
461 uint32_t status8 = rod_status[8];
469 pat1.
DAC = rod_status[9];
470 pat1.
delay = rod_status[10];
472 for (
unsigned int i = 0; i < 4; ++i)
473 pat1.
patterns[i] = rod_status[i + 11];
475 pat2.
DAC = rod_status[15];
476 pat2.
delay = rod_status[16];
478 for (
unsigned int i = 0; i < 4; ++i)
479 pat2.
patterns[i] = rod_status[i + 17];
481 pat3.
DAC = rod_status[21];
482 pat3.
delay = rod_status[22];
484 for (
unsigned int i = 0; i < 4; ++i)
485 pat3.
patterns[i] = rod_status[i + 23];
495 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
504 <<
" " << sourceID << std::dec);
513 <<
" " << sourceID << std::dec);
522 for (
unsigned int ip = 1; ip <
m_nPackets; ++ip) {
524 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
529 ATH_MSG_WARNING(
"Data corruption, offset found at pos 0 (" << offset <<
") is larger than the ROB fragment size (" <<
m_ROBFragSize <<
"). Ignoring data.");
536 ATH_MSG_DEBUG(
" end of header check computed offset=" << std::dec << offset <<
" nwords in payload=" << n);
555 std::vector<unsigned int> bc_size;
576 val.latomeChannel = 99999;
673 val.latomeChannel = 99999;
682 for (
short iBC = 0; iBC < nBC; ++iBC) {
686 if (iBC < startBC1 || iBC >= startBC1 + nBC1)
692 unsigned int oldipacket = 0;
693 for (
unsigned int itimeslot = 0; itimeslot < 6; ++itimeslot) {
694 unsigned int l_bcid = (bswap_32(p[s]))>>16;
703 unsigned int bcid_c = bcid+1;
708 if(bcid_c != l_bcid){
709 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 );
716 unsigned int mux = ((bswap_32(p[s])) >> 8) & 0xff;
723 unsigned int timeslotsize = timeslot_nsc[itimeslot];
724 unsigned int nbytes = timeslotsize * nbytesPerChannel;
725 unsigned int n64word = nbytes / 8;
728 ATH_MSG_DEBUG(
" at BC " << iBC <<
" timeslot " << itimeslot <<
" " << bcid <<
" " << mux <<
" n64word " << n64word <<
" at0 " << (
int)at0 <<
" at1 "
729 << (
int)at1 <<
" l_bcid " << bcid);
731 unsigned int wordshift = s;
732 unsigned int byteshift = 0;
736 for (
unsigned int ichan = 0; ichan < timeslotsize; ++ichan) {
737 unsigned int at0Data = 0, at1Data = 0, satData = 0;
738 bool at0val =
false, at1val =
false;
746 decodeChannel(wordshift, byteshift, p, at0, at1, at0Data, at1Data, satData, at0val, at1val);
747 ATH_MSG_DEBUG(
" wordshift " << wordshift <<
" byteshift " << byteshift <<
" at0data " << at0Data <<
" at1Data " << at1Data <<
" satData " << satData
748 <<
" at0val " << at0val <<
" at1val " << at1val <<
" nsc " << nsc);
752 if (SCID == hwidEmpty) {
755 int RAWValue0 = -999;
757 ATH_MSG_DEBUG(
"at0 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
762 int defaultADCValue = -1;
763 int defaultEValue = -99999;
767 if ((
unsigned)iBC < rawValuesInEvent.adc.size()) {
768 rawValuesInEvent.adc[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
772 if ((
unsigned)iBC < rawValuesInEvent.adc_bas.size()) {
773 rawValuesInEvent.adc_bas[iBC] = (at0val) ? RAWValue0 : defaultADCValue;
777 if ((
unsigned)iBC < rawValuesInEvent.et.size()) {
778 rawValuesInEvent.et[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
779 rawValuesInEvent.saturation[iBC] = satData;
783 if ((
unsigned)iBC < rawValuesInEvent.et_id.size()) {
784 rawValuesInEvent.et_id[iBC] = (at0val) ?
signEnergy(RAWValue0) : defaultEValue;
785 rawValuesInEvent.saturation[iBC] = satData;
795 int RAWValue1 = -999;
797 ATH_MSG_DEBUG(
"at1 bad quality bit for SC:" << nsc <<
" BC " << iBC <<
" latome " << robFrag->rod_source_id());
803 const size_t BCidx = iBC - startBC1;
806 if (BCidx < rawValuesInEvent.adc.size()) {
807 rawValuesInEvent.adc[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
811 if (BCidx < rawValuesInEvent.adc_bas.size()) {
812 rawValuesInEvent.adc_bas[BCidx] = (at1val) ? RAWValue1 : defaultADCValue;
816 if (BCidx < rawValuesInEvent.et.size()) {
817 rawValuesInEvent.et[BCidx] = (at1val) ?
signEnergy(RAWValue1) : defaultEValue;
818 rawValuesInEvent.saturation[BCidx] = satData;
822 if (BCidx < rawValuesInEvent.et_id.size()) {
838 ATH_MSG_ERROR(
"inconsistant wordshift in decoding everaged data");
841 unsigned int averageword = bswap_32(p[wordshift]);
843 unsigned int sumSq = bswap_32(p[wordshift]);
845 unsigned long long sumsqMSB = averageword >> 28;
846 sumsqMSB = sumsqMSB << 32;
863 ATH_MSG_DEBUG(
"wordshift before: " << wordshift <<
", s: " << s);
864 if ((wordshift - s) % 2)
866 ATH_MSG_DEBUG(
"wordshift after : " << wordshift <<
", s: " << s);
869 <<
"!=" << n64word * 2 <<
" m_ipacket " <<
m_iPacket);
880 if (onoffmap && clmap) {
892 uint32_t DAC_value=0;
893 uint16_t delay_value=0;
894 uint16_t isPulsed_value=
false;
895 std::unique_ptr<LArCalibParams> calibParams1;
896 std::unique_ptr<LArCalibParams> calibParams2;
904 cabling = {*cablingHdl};
910 calibParams1=std::make_unique<LArCalibParams>();
911 calibParams2=std::make_unique<LArCalibParams>();
913 if (pattype > 0x48) {
914 StatusCode sc1 = calibParams1->initialize();
915 StatusCode sc2 = calibParams2->initialize();
916 if (sc1 != StatusCode::SUCCESS || sc2 != StatusCode::SUCCESS) {
917 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
920 if (pattype == 0x49 || pattype == 0x4a) {
932 StatusCode sc1 = calibParams1->initialize();
933 if (sc1 != StatusCode::SUCCESS) {
934 ATH_MSG_WARNING(
"could not initialize LArCalibParams, acc calib will not be filled ");
942 unsigned nWarnings = 0;
946 if (SCID == hwidEmpty) {
955 std::vector<uint64_t> sum;
956 std::vector<uint64_t> sum2;
957 unsigned int ntmin = 9999999;
971 sum[is] = round(fsum);
972 sum2[is] = round(fsum2);
975 std::fill(sum.begin(), sum.end(), 0);
976 std::fill(sum2.begin(), sum2.end(), 0);
977 if (++nWarnings < 64) {
978 ATH_MSG_WARNING(
"No valid triggers for supercell " << SCID.getString());
986 if (pattype == 0x49 || pattype == 0x4a) {
987 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 0) {
988 calibParams = calibParams1.get();
990 calibParams = calibParams2.get();
992 }
else if (pattype == 0x4b || pattype == 0x4c) {
993 if (
m_decoder->m_onlineId->isHECchannel(SCID)) {
994 calibParams = calibParams1.get();
996 calibParams = calibParams2.get();
999 calibParams = calibParams1.get();
1001 unsigned int eventNb = 0;
1002 unsigned int numCL = 0;
1003 unsigned int numPulsedLeg = 0;
1004 std::vector<Identifier> ccellIds(0);
1005 Identifier myofflineID = cabling->cnvToIdentifier(SCID);
1006 ccellIds =
m_decoder->m_sc2ccMappingTool->superCellToOfflineID(myofflineID);
1009 const std::vector<HWIdentifier>& calibLineLeg = clcabling->
calibSlotLine(cellLegHWID);
1010 numCL += calibLineLeg.size();
1012 if (calibParams->
isPulsed(eventNb, calibLineHWID)) {
1018 isPulsed_value =
true;
1019 if (numPulsedLeg != numCL) {
1022 isPulsed_value =
false;
1024 DAC_value = calibParams->
DAC(eventNb, SCID) * numPulsedLeg;
1027 int ft =
m_decoder->m_onlineId->feedthrough(SCID);
1028 int slot =
m_decoder->m_onlineId->slot(SCID);
1029 int channel =
m_decoder->m_onlineId->channel(SCID);
1030 if (
m_decoder->m_onlineId->barrel_ec(SCID) == 1 && (ft == 3 || ft == 10 || ft == 16 || ft == 22)) {
1033 if (channel >= 16 && channel <= 31) {
1035 DAC_value = DAC_value / 1.2;
1036 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 1/1.2" <<
endmsg;
1037 }
else if (channel >= 32 && channel <= 47) {
1039 DAC_value = DAC_value * 7. / 8.;
1040 m_decoder->msg(MSG::DEBUG) <<
"Multiplying DAC for channel " << SCID <<
"by 7./8." <<
endmsg;
1045 delay_value = calibParams->
Delay(eventNb, SCID);
1052 if (nWarnings > 16) {
1053 ATH_MSG_WARNING(
"Found " << nWarnings <<
" supercells with no valid triggers");
1063 if (SCID == hwidEmpty) {
1067 if (
m_decoder->m_ignoreBarrelChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 0)
1069 if (
m_decoder->m_ignoreEndcapChannels &&
m_decoder->m_onlineId->barrel_ec(SCID) == 1)
1072 std::vector<short> adcValues_inChannel_inEvent;
1082 std::vector<unsigned short> bcid_in_event;
1092 std::vector<unsigned short> bcid_in_event;
1105 std::vector<unsigned short> bcid_in_event;
1119 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
constexpr int pow(int base, int exp) noexcept
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
Extra patterns decribing particle interation process.