ATLAS Offline Software
LArRawDataReadingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "LArRawDataReadingAlg.h"
11 #include "eformat/Version.h"
12 #include "eformat/index.h"
13 
19 
20 #include "LArFebHeaderReader.h"
22 
23 LArRawDataReadingAlg::LArRawDataReadingAlg(const std::string& name, ISvcLocator* pSvcLocator) :
24  AthReentrantAlgorithm(name, pSvcLocator) {}
25 
29 
32 
35 
37 
38  ATH_CHECK(m_robDataProviderSvc.retrieve());
39  ATH_CHECK(detStore()->retrieve(m_onlineId,"LArOnlineID"));
40  return StatusCode::SUCCESS;
41 }
42 
43 StatusCode LArRawDataReadingAlg::execute(const EventContext& ctx) const {
44  LArRawChannelContainer* rawChannels=nullptr;
45  LArDigitContainer* digits=nullptr;
46  LArFebHeaderContainer* febHeaders=nullptr;
47 
48  if (m_doRawChannels) {
50  ATH_CHECK(rawChannelsHdl.record(std::make_unique<LArRawChannelContainer>()));
51  rawChannels=rawChannelsHdl.ptr();
52  rawChannels->reserve(182468); //Total number of LAr readout channels
53  }
54 
55  if (m_doDigits) {
57  ATH_CHECK(digitsHdl.record(std::make_unique<LArDigitContainer>()));
58  digits=digitsHdl.ptr();
59  digits->reserve(1000); //Approximate number of Digits above threshold
60  }
61 
62  if (m_doFebHeaders) {
64  ATH_CHECK(febHeadersHdl.record(std::make_unique<LArFebHeaderContainer>()));
65  febHeaders=febHeadersHdl.ptr();
66  febHeaders->reserve(1524); //Total number of LAr Front End Boards
67  }
68 
69  //Get full events and filter out LAr ROBs
70  const RawEvent* fullEvent=m_robDataProviderSvc->getEvent(ctx);
71  std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> > rawEventTOC;
72  eformat::helper::build_toc(*fullEvent, rawEventTOC);
73  auto larRobs=rawEventTOC.find(eformat::LAR);
74  if (larRobs==rawEventTOC.end()) {
75  ATH_MSG_DEBUG("No LAr data found in this event. Recording empty LArRawChannelContainer");
76  return StatusCode::SUCCESS;
77  }
78 
79 
80  std::unique_ptr<LArRodBlockStructure> rodBlock;
81  uint16_t rodMinorVersion=0x0;
82  uint32_t rodBlockType=0x0;
83 
84 
85  for (const uint32_t* robPtr : larRobs->second) {
87  ATH_MSG_VERBOSE("Decoding ROB fragment 0x" << std::hex << rob.rob_source_id () << " with " << std::dec << rob.rod_fragment_size_word() << " ROB words");
88 
89  if (rob.rod_fragment_size_word() <3) {
90  if (m_failOnCorruption) {
91  ATH_MSG_ERROR("Encountered corrupt ROD fragment, less than 3 words!");
92  return StatusCode::FAILURE;
93  }else {
94  continue;
95  }
96  } else if(rob.rob_source_id()& 0x1000 ){
97  //ATH_MSG_DEBUG(" skip Latome fragment with source ID "<< std::hex << rob.rob_source_id()
98  rodBlock=nullptr;
99  continue;
100  } else if(!(rob.rod_source_id()>>12& 0x0F) //0xnn0nnn must be
101  && !((rob.rod_source_id()>>20) == 4) ){ //0x4nnnnn must be
102 
103  ATH_MSG_WARNING("Found not LAr fragment " << " event: "<<ctx.eventID().event_number());
105  ATH_MSG_WARNING("Rob source id.: 0x"<< std::hex << rob.rob_source_id () <<std::dec <<" ROD Source id: 0x"<<std::hex<<rob.rod_source_id()<<std::dec<<" Lvl1ID: "<<eventInfo->extendedLevel1ID());
106  continue;
107  }
108 
109 
110  eformat::helper::Version ver(rob.rod_version());
111  //(re-)init rodBlock only once per event or if (very unlikly or even impossible) some FEBs have a differnt firmware
112  if (rodBlock==nullptr || rodMinorVersion !=ver.minor_version() || rodBlockType!=(rob.rod_detev_type()&0xff)) {
113  rodMinorVersion=ver.minor_version();
114  rodBlockType=rob.rod_detev_type()&0xff;
115  ATH_MSG_VERBOSE("Found version " << rodMinorVersion << " of Rod Block Type " << rodBlockType);
116  if (rodBlockType==4) { //Physics mode
117  switch(rodMinorVersion) {
118  case 12: //Physics mode v6 09.03.2011 for LHC
119  rodBlock.reset(new LArRodBlockPhysicsV6);
120  break;
121  case 11: //Physics mode v5 16.06.2008 for LHC
122  case 10: //Physics mode v5 16.06.2008 for LHC
123  rodBlock.reset(new LArRodBlockPhysicsV5);
124  break;
125  default: // Unknown version of rod block type 4 (Physics mode)
126  if (m_failOnCorruption) {
127  ATH_MSG_ERROR("Found unsupported ROD Block version " << rodMinorVersion
128  << " of ROD block type " << rodBlockType << ". ROD Source id: 0x" <<std::hex<<rob.rod_source_id());
129  return StatusCode::FAILURE;
130  }
131  else {
132  ATH_MSG_WARNING("Found unsupported ROD Block version " << rodMinorVersion
133  << " of ROD block type " << rodBlockType << ". ROD Source id: 0x" <<std::hex<<rob.rod_source_id());
134  continue;
135  }
136  }// end switch(rodMinorVersion)
137  }//end rodBlockType==4 (physics mode)
138  else if (rodBlockType==2) { //Transparent mode
139  switch(rodMinorVersion) {
140  case 4:
142  break;
143  case 12:
144  rodBlock.reset(new LArRodBlockCalibrationV3);
145  break;
146  default:
147  ATH_MSG_WARNING("Found unsupported ROD Block version " << rodMinorVersion
148  << " of ROD block type " << rodBlockType);
149  return m_failOnCorruption ? StatusCode::FAILURE : StatusCode::SUCCESS;
150  }
151  }
152  }//End if need to re-init RodBlock
153 
154  const uint32_t* pData=rob.rod_data();
155  const uint32_t nData=rob.rod_ndata();
156  if (nData==0) {
157  if (m_failOnCorruption) {
158  ATH_MSG_ERROR("ROD 0x"<<std::hex<<rob.rod_source_id() << std::dec << " reports data block size 0");
159  return StatusCode::FAILURE;
160  }
161  else {
162  ATH_MSG_WARNING("ROD 0x"<<std::hex<<rob.rod_source_id() << std::dec << " reports data block size 0");
163  continue; //Jump to next ROD
164  }
165  }
166 
167  if (!rodBlock->setFragment(pData,nData)) {
168  ATH_MSG_ERROR("Failed to assign fragment pointer to LArRodBlockStructure");
169  return StatusCode::FAILURE;
170  }
171 
172  if(m_verifyChecksum) {
173  const uint32_t onsum = rodBlock->onlineCheckSum();
174  const uint32_t offsum = rodBlock->offlineCheckSum();
175  if(onsum!=offsum) {
176  if (m_failOnCorruption) {
177  ATH_MSG_ERROR("Checksum error:");
178  ATH_MSG_ERROR("online checksum = 0x" << MSG::hex << onsum);
179  ATH_MSG_ERROR("offline checksum = 0x" << MSG::hex << offsum << MSG::dec);
180  return StatusCode::FAILURE;
181  } else {
182  continue; //Jump to the next ROD-block
183  }
184  }
185  }
186 
187  //Loop over FEBs in ROD:
188  do {
189  HWIdentifier fId(Identifier32(rodBlock->getFEBID()));
190  if (!m_onlineId->isValidId(fId)) {
191  if (m_failOnCorruption){
192  ATH_MSG_ERROR("Invalid FEB identifer 0x" << std::hex << fId.get_identifier32().get_compact());
193  return StatusCode::FAILURE;
194  } else {
195  ATH_MSG_WARNING("Invalid FEB identifer 0x" << std::hex << fId.get_identifier32().get_compact());
196  continue; //Jump to next FEB
197  }
198  }
199  const int NthisFebChannel=m_onlineId->channelInSlotMax(fId);
200 
201  //Decode RawChanels (if requested)
202  if (m_doRawChannels) {
203  int32_t energy;
204  int32_t time;
205  int32_t quality;
206  uint32_t gain;
207  int fcNb;
208  while (rodBlock->getNextEnergy(fcNb,energy,time,quality,gain)) {
209  if (fcNb>=NthisFebChannel)
210  continue;
211 
212  HWIdentifier cId = m_onlineId->channel_Id(fId,fcNb);
213  uint16_t iquality = 0;
214  uint16_t iprovenance = LArProv::DSPCALC; //0x1000
215  if (quality>0) {
216  iprovenance |= LArProv::QTPRESENT; //0x2000
217  iquality = (quality & 0xFFFF);
218  }
219  rawChannels->emplace_back(cId, energy, time, iquality, iprovenance, (CaloGain::CaloGain)gain);
220  }//end getNextEnergyLoop
221  }//end if m_doRawChannels
222 
223  //Decode LArDigits (if requested)
224  if (m_doDigits) {
225  uint32_t gain;
226  int fcNb;
227  std::vector<short> samples;
228  while (rodBlock->getNextRawData(fcNb,samples,gain)) {
229  if (fcNb>=NthisFebChannel)
230  continue;
231  if (samples.size()==0) continue; // Ignore missing cells
232  HWIdentifier cId = m_onlineId->channel_Id(fId,fcNb);
233  digits->emplace_back(new LArDigit(cId, (CaloGain::CaloGain)gain, std::move(samples)));
234  samples.clear();
235  }//end getNextRawData loop
236  }//end if m_doDigits
237 
238  //Decode FebHeaders (if requested)
239  if (m_doFebHeaders) {
240  std::unique_ptr<LArFebHeader> larFebHeader(new LArFebHeader(fId));
241  LArFebHeaderReader::fillFebHeader(larFebHeader.get(),rodBlock.get(),rob);
242  febHeaders->push_back(std::move(larFebHeader));
243  }//end if m_doFebHeaders
244 
245  }while (rodBlock->nextFEB()); //Get NextFeb
246  } //end loop over ROBs
247  return StatusCode::SUCCESS;
248 }
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
Identifier32
Definition: Identifier32.h:25
LArRodBlockPhysicsV5
Definition: LArRodBlockPhysicsV5.h:32
LArFebHeaderReader::fillFebHeader
void fillFebHeader(LArFebHeader *lfh, const LArRodBlockStructure *bl, const ROBFragment &robFrag)
Fill info for one FEB Header.
Definition: LArFebHeaderReader.cxx:10
DataVector::emplace_back
value_type emplace_back(value_type pElem)
Add an element to the end of the collection.
LArRawDataReadingAlg::m_rawChannelKey
SG::WriteHandleKey< LArRawChannelContainer > m_rawChannelKey
Definition: LArRawDataReadingAlg.h:34
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
LArRawDataReadingAlg.h
CaloCondBlobAlgs_fillNoiseFromASCII.gain
gain
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:110
RawEvent
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
Definition: RawEvent.h:37
LArRawDataReadingAlg::m_doFebHeaders
bool m_doFebHeaders
Definition: LArRawDataReadingAlg.h:54
LArRodBlockPhysicsV6
Definition: LArRodBlockPhysicsV6.h:32
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
HWIdentifier
Definition: HWIdentifier.h:13
LArRodBlockStructure::getNextEnergy
virtual int getNextEnergy(int &channelNumber, int32_t &energy, int32_t &time, int32_t &quality, uint32_t &gain)
Definition: LArRodBlockStructure.h:456
LArRawDataReadingAlg::m_febHeaderKey
SG::WriteHandleKey< LArFebHeaderContainer > m_febHeaderKey
Definition: LArRawDataReadingAlg.h:37
LArRodBlockPhysicsV5.h
LArRawDataReadingAlg::m_digitKey
SG::WriteHandleKey< LArDigitContainer > m_digitKey
Definition: LArRawDataReadingAlg.h:36
LArRodBlockStructure::offlineCheckSum
virtual uint32_t offlineCheckSum() const
Definition: LArRodBlockStructure.cxx:163
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
LArRawDataReadingAlg::m_doDigits
bool m_doDigits
Definition: LArRawDataReadingAlg.h:53
Pythia8_A14_NNPDF23LO_Var1Down_Common.ver
ver
Definition: Pythia8_A14_NNPDF23LO_Var1Down_Common.py:26
LArRodBlockPhysicsV6.h
LArRawDataReadingAlg::m_verifyChecksum
BooleanProperty m_verifyChecksum
Definition: LArRawDataReadingAlg.h:45
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
Identifier32::get_compact
value_type get_compact(void) const
Get the compact id.
Definition: Identifier32.h:171
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
LArDigit
Liquid Argon digit base class.
Definition: LArDigit.h:25
eformat::ROBFragment
Definition: L1CaloBsDecoderUtil.h:12
LArOnlineID_Base::channelInSlotMax
int channelInSlotMax(const HWIdentifier Id) const
Return the Maximum channel number of a given feb slot.
Definition: LArOnlineID_Base.cxx:286
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::WriteHandle::ptr
pointer_type ptr()
Dereference the pointer.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
01SubmitToGrid.samples
samples
Definition: 01SubmitToGrid.py:58
LArRawDataReadingAlg::LArRawDataReadingAlg
LArRawDataReadingAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: LArRawDataReadingAlg.cxx:23
LArProv::QTPRESENT
@ QTPRESENT
Definition: LArProvenance.h:33
LArRawDataReadingAlg::m_doRawChannels
bool m_doRawChannels
Definition: LArRawDataReadingAlg.h:52
LArOnlineID_Base::channel_Id
HWIdentifier channel_Id(int barrel_ec, int pos_neg, int feedthrough, int slot, int channel) const
create channel identifier from fields
Definition: LArOnlineID_Base.cxx:1569
xAOD::EventInfo_v1::extendedLevel1ID
uint32_t extendedLevel1ID() const
The extended Level-1 identifier.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
LArRodBlockStructure::getFEBID
uint32_t getFEBID() const
Definition: LArRodBlockStructure.h:297
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
LArFebHeader
Holds information from the FEB Header.
Definition: LArFebHeader.h:21
LArOnlineID_Base::isValidId
bool isValidId(const HWIdentifier id) const
Returns false if the identifier is not a LAr-online id or any of the sub-fields is out of range.
Definition: LArOnlineID_Base.cxx:1333
LArProv::DSPCALC
@ DSPCALC
Definition: LArProvenance.h:32
LArRodBlockCalibrationV3
This class provides decoding/encoding from/to ROD format.
Definition: LArRodBlockCalibrationV3.h:24
LArRodBlockStructure::nextFEB
bool nextFEB()
Definition: LArRodBlockStructure.h:497
LArFebHeaderContainer.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
LArRodBlockTransparentV0.h
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
LArDigitContainer.h
CaloGain::CaloGain
CaloGain
Definition: CaloGain.h:11
LArRawDataReadingAlg::execute
StatusCode execute(const EventContext &ctx) const override
Definition: LArRawDataReadingAlg.cxx:43
LArRawDataReadingAlg::m_eventInfoKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
Definition: LArRawDataReadingAlg.h:39
LArRodBlockStructure.h
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
LArFebHeaderReader.h
CaloSwCorrections.time
def time(flags, cells_name, *args, **kw)
Definition: CaloSwCorrections.py:242
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
LArRodBlockStructure::getNextRawData
virtual int getNextRawData(int &channelNumber, std::vector< short > &samples, uint32_t &gain)
Definition: LArRodBlockStructure.cxx:88
LArRawDataReadingAlg::m_onlineId
const LArOnlineID * m_onlineId
Definition: LArRawDataReadingAlg.h:49
LArRodBlockStructure::setFragment
bool setFragment(const uint32_t *p, uint32_t n)
Definition: LArRodBlockStructure.h:252
LArRawDataReadingAlg::initialize
StatusCode initialize() override
Definition: LArRawDataReadingAlg.cxx:26
LArProvenance.h
LArDigitContainer
Container class for LArDigit.
Definition: LArDigitContainer.h:24
LArRodBlockTransparentV0
Definition: LArRodBlockTransparentV0.h:53
LArFebHeaderContainer
Container class for LArFebHeader.
Definition: LArFebHeaderContainer.h:20
LArRodBlockStructure::onlineCheckSum
virtual uint32_t onlineCheckSum() const
Definition: LArRodBlockStructure.cxx:155
Identifier::get_identifier32
Identifier32 get_identifier32(void) const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
LArRawDataReadingAlg::m_failOnCorruption
BooleanProperty m_failOnCorruption
Definition: LArRawDataReadingAlg.h:46
LArRawDataReadingAlg::m_robDataProviderSvc
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
Definition: LArRawDataReadingAlg.h:42
LAR
@ LAR
Definition: RegSelEnums.h:27
IROBDataProviderSvc.h
LArRawChannelContainer.h
LArOnlineID.h
LArRawChannelContainer
Container for LArRawChannel (IDC using LArRawChannelCollection)
Definition: LArRawChannelContainer.h:26
LArRodBlockCalibrationV3.h