7#include "GaudiKernel/TypeNameString.h"
8#include "GaudiKernel/MsgStream.h"
9#include "GaudiKernel/Bootstrap.h"
10#include "GaudiKernel/ISvcLocator.h"
11#include "GaudiKernel/IToolSvc.h"
37 (
"LArRodDecoder", 1, 0);
45 declareInterface< LArRodDecoder >(
this );
77 m_StatusNMask = !m_StatusMask;
79 StatusCode
sc = detStore()->retrieve(m_onlineHelper,
"LArOnlineID");
87 std::vector<std::string>::const_iterator it = m_LArCellCorrNames.begin();
88 std::vector<std::string>::const_iterator it_end = m_LArCellCorrNames.end();
89 for(; it!=it_end;++it)
93 Gaudi::Utils::TypeNameString li(*it);
94 if((toolSvc()->retrieveTool(li.type(), li.name(), tool)).isFailure() )
97 return StatusCode::FAILURE;
104 return StatusCode::FAILURE;
106 m_LArCellCorrTools.push_back(corr);
110 if (m_vBEPreselection.size() && m_vPosNegPreselection.size() && m_vFTPreselection.size()) {
112 for (
const unsigned BE : m_vBEPreselection) {
113 for (
const unsigned PN : m_vPosNegPreselection) {
114 for (
const unsigned FT : m_vFTPreselection) {
115 HWIdentifier finalFTId=m_onlineHelper->feedthrough_Id(BE,PN,FT);
117 ATH_MSG_INFO(
"Adding feedthrough Barrel/Endcap=" << BE <<
" pos/neg=" << PN <<
" FT=" << FT
118 <<
" (0x" << std::hex << finalFTId32 << std::dec <<
")");
119 m_vFinalPreselection.push_back(finalFTId32);
123 std::sort(m_vFinalPreselection.begin(),m_vFinalPreselection.end());
126 if (m_vBEPreselection.size() || m_vPosNegPreselection.size() || m_vFTPreselection.size()) {
127 ATH_MSG_ERROR(
"Feedthrough preselection: jobOption inconsistency! ");
128 ATH_MSG_ERROR(
"Need to set all three jobOptions BEPreselection PNPreselecton and FTPreselection");
129 return StatusCode::FAILURE;
145 std::vector<short> samples;
147 if (!BlStruct)
return;
153 ATH_MSG_WARNING(
"Invalid FEB identifer 0x" << std::hex << fId32 << std::dec <<
". Skipping");
170 ATH_MSG_DEBUG(
"No Raw Data for this FEB - NULL event for FEBID 0x"<< std::hex << BlStruct->
getFEBID() << std::dec);
178 for(; it_feb!=it_feb_end;++it_feb)
186 ATH_MSG_WARNING(
"RodStatus&0x" << std::hex <<
m_StatusNMask <<
" indicates corrupt data for FEB "<< std::hex << fId32 << std::dec <<
". Ignored.");
197 ATH_MSG_WARNING(
" offline checksum = " << MSG::hex << offsum << MSG::dec);
203 const unsigned int ftId=
m_onlineHelper->feedthrough_Id(fId).get_identifier32().get_compact();
205 ATH_MSG_DEBUG(
"Feedthrough with id 0x" << MSG::hex << ftId << MSG::dec <<
" not in preselection. Ignored.");
212 if (fcNb>=NthisFebChannel)
214 if (samples.size()==0)
continue;
217 dg =
new LArDigit(cId, calogain, std::move(samples));
238 if (!BlStruct)
return;
244 ATH_MSG_WARNING(
"Invalid FEB identifer " << std::hex << fId32 << std::dec <<
". Skipping");
259 ATH_MSG_DEBUG(
"No Physics Data for this FEB - NULL event for FEBID 0x" << std::hex << BlStruct->
getFEBID() << std::dec);
267 for(; it_feb!=it_feb_end;++it_feb)
275 ATH_MSG_WARNING(
"RodStatus&0x" << std::hex <<
m_StatusNMask <<
" indicates corrupt data for FEB "<< std::hex << fId32 << std::dec <<
". Ignored.");
293 int ftId=
m_onlineHelper->feedthrough_Id(fId).get_identifier32().get_compact();
295 ATH_MSG_DEBUG(
"Feedthrough with id " << std::hex << ftId << std::dec <<
" not in preselection. Ignored.");
300 while (BlStruct->
getNextEnergy(fcNb,energy,time,quality,gain)) {
301 if (fcNb>=NthisFebChannel)
304 uint16_t iquality = 0;
305 uint16_t iprovenance = 0x1000;
307 iprovenance |= 0x2000;
308 iquality = (quality & 0xFFFF);
311 coll.push_back(chan);
332 std::vector<short> samples;
334 ATH_MSG_VERBOSE(
"FillCollection for LArCalibDigitContainer is called.");
336 if (!BlStruct)
return;
344 ATH_MSG_DEBUG(
"No Raw Data for this FEB - NULL event for FEBID " << std::hex << BlStruct->
getFEBID());
351 ATH_MSG_DEBUG(
"Bad FebID=0x"<< std::hex << BlStruct->
getFEBID() <<
" found for this FEB, skipping it!");
358 for(; it_feb!=it_feb_end;++it_feb)
366 msg(MSG::WARNING) <<
"RodStatus&0x" << std::hex <<
m_StatusNMask <<
" indicates corrupt data for FEB "<< std::hex << fId32 << std::dec <<
". Ignored." <<
endmsg;
375 msg(MSG::WARNING) <<
"Checksum error:" <<
endmsg;
376 msg(MSG::WARNING) <<
" online checksum = " << MSG::hex << onsum <<
endmsg;
377 msg(MSG::WARNING) <<
" offline checksum = " << MSG::hex << offsum <<
endmsg;
393 unsigned int ftId=
m_onlineHelper->feedthrough_Id(fId).get_identifier32().get_compact();
395 ATH_MSG_DEBUG(
"Feedthrough with id 0x" << std::hex << ftId << std::dec <<
" not in preselection. Ignored.");
401 {
if (fcNb>=NthisFebChannel)
403 if (samples.size()==0)
continue;
416 ATH_MSG_VERBOSE(
"Not LArCalibDigit data block found. Building it using DB values");
419 StatusCode
sc=
detStore()->retrieve(calibParams);
421 {
msg(MSG::ERROR) <<
"Cannot load LArCalibParams from DetStore!" <<
endmsg;
426 if (!evt.isValid()) {
430 const unsigned eventNb=evt->eventNumber();
431 const std::vector<HWIdentifier>* calibChannelIDs;
436 ATH_MSG_DEBUG(
"No Raw Data for this FEB - NULL event for FEBID 0x" << std::hex << BlStruct->
getFEBID() << std::dec);
443 ATH_MSG_DEBUG(
"Bad FebID=0x" << std::hex << BlStruct->
getFEBID() <<
" found for this FEB, skipping it!" << std::dec);
463 while ( (!onOffIdMapping.
isOnlineConnected(cId) || calibChannelIDs->size()==0) && fcNb<128);
465 if ( calibChannelIDs->size()==0 ) {
466 msg(MSG::ERROR) <<
"Cannot get calibration Channel ID for FEB " << std::hex << fId32 << std::dec <<
endmsg;
473 std::vector<HWIdentifier>::const_iterator csl_it=calibChannelIDs->begin();
475 dac=calibParams->
DAC(eventNb,*csl_it);
484 if (fcNb>=NthisFebChannel)
continue;
485 if (samples.size()==0)
continue;
490 if (calibChannelIDs->size()!=0) {
491 csl_it=calibChannelIDs->begin();
492 ispulsed=calibParams->
isPulsed(eventNb,*csl_it);
516 uint32_t gain, ntrigger;
517 int dac,
delay, NStep=-1, StepIndex=-1;
519 uint16_t ispulsed_int;
521 uint32_t FirstGoodFEB=1;
523 std::vector< uint64_t > samplesSum;
524 std::vector< uint64_t > samples2Sum;
527 if (!BlStruct)
return;
544 ATH_MSG_DEBUG(
"Bad FebID=0x" << std::hex << BlStruct->
getFEBID() <<
" found for this FEB, skipping it!" << std::dec);
551 for(; it_feb!=it_feb_end;++it_feb)
559 ATH_MSG_WARNING(
"RodStatus&0x" << std::hex <<
m_StatusNMask <<
" indicates corrupt data for FEB "<< std::hex << fId32 << std::dec <<
". Ignored.");
586 unsigned int ftId=
m_onlineHelper->feedthrough_Id(fId).get_identifier32().get_compact();
588 ATH_MSG_DEBUG(
"Feedthrough with id " << std::hex << ftId << std::dec <<
" not in preselection. Ignored.");
598 if (fcNb>=NthisFebChannel)
continue;
599 if (samplesSum.size()==0)
continue;
609 const std::vector<HWIdentifier>& calibChannelIDs = calibLineMapping.
calibSlotLine(cId);
610 if (calibChannelIDs.size()==0) {
616 for(std::vector<HWIdentifier>::const_iterator csl_it=calibChannelIDs.begin(); csl_it!=calibChannelIDs.end();++csl_it){
619 ispulsed_int=( ispulsed_int | ((uint16_t)ispulsed<<bitShift) );
624 (uint16_t)ispulsed_int, NStep, StepIndex);
637 uint32_t gain, ntrigger;
639 std::vector<uint64_t> sampleSum;
640 std::vector< uint64_t > sampleSquare;
643 if (!BlStruct)
return;
655 ATH_MSG_DEBUG(
"Bad FebID=0x" << std::hex << BlStruct->
getFEBID() <<
" found for this FEB, skipping it!" << std::dec);
662 for(; it_feb!=it_feb_end;++it_feb)
670 ATH_MSG_WARNING(
"RodStatus&0x" << std::hex <<
m_StatusNMask <<
" indicates corrupt data for FEB "<< std::hex << fId32 << std::dec <<
". Ignored.");
697 unsigned int ftId=
m_onlineHelper->feedthrough_Id(fId).get_identifier32().get_compact();
699 ATH_MSG_DEBUG(
"Feedthrough with id " << std::hex << ftId << std::dec <<
" not in preselection. Ignored.");
706 if (fcNb>=NthisFebChannel)
continue;
707 if (sampleSquare.size()==0)
continue;
724 if (!BlStruct)
return;
732 ATH_MSG_WARNING(
"Invalid FEB identifer " << std:: hex << FEBID32 << std::dec <<
". Skipping");
748 const unsigned int ftId=
m_onlineHelper->feedthrough_Id(FEBID).get_identifier32().get_compact();
750 ATH_MSG_DEBUG(
"Feedthrough with id 0x" << std::hex << ftId << std::dec <<
" not in preselection. Ignored.");
761 larFebHeader->
SetSourceId(robFrag.rod_source_id());
763 larFebHeader->
SetELVL1Id(robFrag.rod_lvl1_id());
764 larFebHeader->
SetBCId(robFrag.rod_bc_id());
770 const uint32_t status= BlStruct->
getStatus();
784 larFebHeader->
SetFebBCId(robFrag.rod_bc_id());
786 const uint16_t evtid = BlStruct->
getCtrl1(0) & 0x1f;
787 const uint16_t bcid = BlStruct->
getCtrl2(0) & 0x1fff;
791 for(
int iadc=0;iadc<16;iadc++) {
796 for(
unsigned int i = 0; i<nsample; i++ ) {
810 const unsigned MAXMINOR = 12;
811 const unsigned MAXTYPE = 10;
813 if (rodMinorVersion > MAXMINOR || robBlockType > MAXTYPE) {
815 <<
" / " << rodMinorVersion);
818 std::vector<std::unique_ptr<LArRodBlockStructure> >& blstructs =
820 unsigned int index = robBlockType * (MAXMINOR+1) + rodMinorVersion;
821 if (blstructs.empty()) {
822 blstructs.resize ((MAXMINOR+1)*(MAXTYPE+1));
824 if (!blstructs[
index]) {
827 if (!blstructs[
index]) {
829 <<
" / " << rodMinorVersion);
834 ATH_MSG_DEBUG(
"Found version " << rodMinorVersion <<
" of Rod block type " << robBlockType);
837 return blstructs[
index].get();
846 ATH_MSG_DEBUG(
"Prepare LArRodBlockStructure. Got a fragement of size " << n);
850 eformat::helper::Version ver(robFrag.rod_version());
851 const uint16_t rodMinorVersion=ver.minor_version();
852 const uint32_t rodBlockType=robFrag.rod_detev_type()&0xff;
859 constexpr int maxMess = 100;
860 static std::atomic<int> nMess = 1;
861 int thismess = nMess++;
862 if (thismess <= maxMess) {
863 ATH_MSG_ERROR(
"Could not set fragment (wrong number of samples in data ?) - container will not be filled");
864 if (thismess == maxMess)
873 BlStruct->
setGain(RequestedGain);
882std::unique_ptr<LArRodBlockStructure>
884 unsigned int rodMinorVersion)
const
886 switch (rodBlockType) {
889 switch (rodMinorVersion) {
895 return std::make_unique<LArRodBlockTransparentV0<LArRodBlockHeaderTransparentV0> >(this->msgSvc().get());
897 return std::make_unique<LArRodBlockCalibrationV1>(this->msgSvc().
get());
905 return std::make_unique<LArRodBlockCalibrationV3>(this->msgSvc().
get());
913 return std::make_unique<LArRodBlockTransparentV0<LArRodBlockHeaderTransparentV0> >(this->msgSvc().get());
917 switch (rodMinorVersion) {
919 return std::make_unique<LArRodBlockPhysicsV0>(this->msgSvc().
get());
921 return std::make_unique<LArRodBlockPhysicsV1>(this->msgSvc().
get());
929 return std::make_unique<LArRodBlockPhysicsV2>(this->msgSvc().
get());
931 return std::make_unique<LArRodBlockPhysicsV4>(this->msgSvc().
get());
935 auto bl = std::make_unique<LArRodBlockPhysicsV5>(this->msgSvc().
get());
943 auto bl = std::make_unique<LArRodBlockPhysicsV6>(this->msgSvc().
get());
957 return std::make_unique<LArRodBlockPhysicsV3>(this->msgSvc().
get());
961 switch (rodMinorVersion) {
963 return std::make_unique<LArRodBlockPhysicsV0>(this->msgSvc().
get());
966 return std::make_unique<LArRodBlockPhysicsV2>(this->msgSvc().
get());
974 switch (rodMinorVersion) {
976 return std::make_unique<LArRodBlockCalibrationV0<LArRodBlockHeaderCalibrationV0> >(this->msgSvc().get());
981 return std::make_unique<LArRodBlockCalibrationV1>(this->msgSvc().
get());
983 return std::make_unique<LArRodBlockCalibrationV2>(this->msgSvc().
get());
991 return std::make_unique<LArRodBlockCalibrationV3>(this->msgSvc().
get());
1000 return std::make_unique<LArRodBlockAccumulatedV3>(this->msgSvc().
get());
1006 return std::unique_ptr<LArRodBlockStructure>();
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double delay(std::size_t d)
StatusCode LArRodDecoder::initialize ATLAS_NOT_THREAD_SAFE()
Install fatal handler with default options.
static const InterfaceID IID_ILArRodDecoder("LArRodDecoder", 1, 0)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
value_type get_compact() const
Get the compact id.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
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.
Container class for LArCalibDigit.
void setDelayScale(const double scale)
set delay scale
Base class for LArDigits taken during calibration runs.
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.
Liquid Argon digit base class.
bool isOnlineConnected(const HWIdentifier &sid) const
Test whether a HWIdentifier is connected of not (inline) .
Container for LArRawChannel (IDC using LArRawChannelCollection).
Liquid Argon ROD output object base class.
virtual uint16_t getCtrl1(uint32_t adc) const
bool setFragment(const uint32_t *p, uint32_t n)
virtual uint32_t hasPhysicsBlock() const
virtual uint16_t getNStep() const
virtual uint32_t hasCalibBlock() const
virtual uint16_t getDelay() const
virtual uint16_t getCtrl3(uint32_t adc) const
virtual uint16_t getResults1Size() const
virtual bool getPulsed(unsigned channelNumber) const
virtual uint16_t getDAC() const
virtual int getNextEnergy(int &channelNumber, int32_t &energy, int32_t &time, int32_t &quality, uint32_t &gain)
virtual uint16_t getRawDataSize() const
virtual uint32_t hasAccumBlock() const
virtual int getNextAccumulatedCalibDigit(int &channelNumber, std::vector< uint64_t > &SamplesSum, std::vector< uint64_t > &Samples2Sum, uint32_t &nStepTriggers, uint32_t &gain)
virtual uint32_t hasRawDataBlock() const
virtual bool canSetCalibration()
virtual uint32_t getDspCodeVersion() const
virtual uint16_t getCtrl2(uint32_t adc) const
virtual uint32_t getRadd(uint32_t adc, uint32_t sample) const
uint32_t getFEBID() const
virtual uint16_t getStepIndex() const
virtual uint16_t getNTrigger() const
virtual int setGain(const int GainValue)
virtual uint32_t offlineCheckSum() const
void setFirstSample(const int rearrangeFirstSample)
virtual uint16_t getNbSweetCells2() const
virtual uint32_t getNumberOfSamples() const
virtual uint32_t hasControlWords() const
virtual int getNextRawData(int &channelNumber, std::vector< short > &samples, uint32_t &gain)
virtual uint32_t getStatus() const
virtual uint16_t getResults2Size() const
virtual uint16_t getNbSweetCells1() const
virtual int32_t getDspEventCounter() const
virtual uint32_t onlineCheckSum() const
virtual int getNextAccumulatedDigit(int &channelNumber, std::vector< uint64_t > &SamplesSum, std::vector< uint64_t > &corr2Sum, uint32_t &gain)
std::vector< unsigned int > m_vFinalPreselection
virtual ~LArRodDecoder()
Destructor.
std::vector< std::string > m_LArCellCorrNames
LArRodBlockStructure * prepareBlockStructure1(const uint16_t rodMinorVersion, const uint32_t robBlockType) const
std::vector< int > m_vFTPreselection
const LArOnlineID * m_onlineHelper
std::vector< unsigned int > m_IgnoreCheckFEBs
std::unique_ptr< LArRodBlockStructure > makeBlockStructure(unsigned int rodBlockType, unsigned int rodMinorVersion) const
SG::ReadHandleKey< xAOD::EventInfo > m_evt
static const InterfaceID & interfaceID()
float m_LArCellEthreshold
unsigned short m_requiredPhysicsNSamples
std::vector< int > m_vBEPreselection
void fillCollection(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &robFrag, const uint32_t *p, uint32_t n, LArRawChannelContainer &coll, const CaloGain::CaloGain gain) const
LArRodBlockStructure * prepareBlockStructure(const OFFLINE_FRAGMENTS_NAMESPACE::ROBFragment &robFrag, const uint32_t *p, uint32_t n, const CaloGain::CaloGain RequestedGain) const
std::vector< int > m_vPosNegPreselection
LArRodDecoder(const std::string &type, const std::string &name, const IInterface *parent)
Constructor Standard AlgTool constructor.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
eformat::ROBFragment< PointerType > ROBFragment
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.