122 {
124 LArDigitContainer* digits=nullptr;
125 LArFebHeaderContainer* febHeaders=nullptr;
126
128 SG::WriteHandle<LArRawChannelContainer> rawChannelsHdl(
m_rawChannelKey,ctx);
129 ATH_CHECK(rawChannelsHdl.record(std::make_unique<LArRawChannelContainer>()));
130 rawChannels=rawChannelsHdl.ptr();
131 rawChannels->reserve(182468);
132 }
133
135 SG::WriteHandle<LArDigitContainer> digitsHdl(
m_digitKey,ctx);
136 ATH_CHECK(digitsHdl.record(std::make_unique<LArDigitContainer>()));
137 digits=digitsHdl.ptr();
139 }
140
142 SG::WriteHandle<LArFebHeaderContainer> febHeadersHdl(
m_febHeaderKey,ctx);
143 ATH_CHECK(febHeadersHdl.record(std::make_unique<LArFebHeaderContainer>()));
144 febHeaders=febHeadersHdl.ptr();
146 }
147
148
150 std::map<eformat::SubDetectorGroup, std::vector<const uint32_t*> > rawEventTOC;
151 eformat::helper::build_toc(*fullEvent, rawEventTOC);
152 auto larRobs=rawEventTOC.find(eformat::LAR);
153 if (larRobs==rawEventTOC.end()) {
154 ATH_MSG_DEBUG(
"No LAr data found in this event. Recording empty LArRawChannelContainer");
155 return StatusCode::SUCCESS;
156 }
157
158
159 std::unique_ptr<LArRodBlockStructure> rodBlock;
162
163
164 for (const uint32_t* robPtr : larRobs->second) {
166 ATH_MSG_VERBOSE(
"Decoding ROB fragment 0x" << std::hex << rob.rob_source_id () <<
" with " << std::dec << rob.rod_fragment_size_word() <<
" ROB words");
167
168 if (rob.rod_fragment_size_word() <3) {
170 ATH_MSG_ERROR(
"Encountered corrupt ROD fragment, less than 3 words!");
171 return StatusCode::FAILURE;
172 }else {
173 continue;
174 }
175 } else if(rob.rob_source_id()& 0x1000 ){
176
177 rodBlock=nullptr;
178 continue;
179 } else if(!(rob.rod_source_id()>>12& 0x0F)
180 && !((rob.rod_source_id()>>20) == 4) ){
181
182 ATH_MSG_WARNING(
"Found not LAr fragment " <<
" event: "<<ctx.eventID().event_number());
184 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());
185 continue;
186 }
187
188
189 eformat::helper::Version
ver(rob.rod_version());
190
191 if (rodBlock==
nullptr || rodMinorVersion !=
ver.minor_version() || rodBlockType!=(rob.rod_detev_type()&0xff)) {
192 rodMinorVersion=
ver.minor_version();
193 rodBlockType=rob.rod_detev_type()&0xff;
194 ATH_MSG_VERBOSE(
"Found version " << rodMinorVersion <<
" of Rod Block Type " << rodBlockType);
195 if (rodBlockType==4) {
196 switch(rodMinorVersion) {
197 case 12:
198 rodBlock.reset(
new LArRodBlockPhysicsV6 (this->
msgSvc().
get()));
199 break;
200 case 11:
201 case 10:
202 rodBlock.reset(
new LArRodBlockPhysicsV5 (this->
msgSvc().
get()));
203 break;
204 default:
206 ATH_MSG_ERROR(
"Found unsupported ROD Block version " << rodMinorVersion
207 << " of ROD block type " << rodBlockType << ". ROD Source id: 0x" <<std::hex<<rob.rod_source_id());
208 return StatusCode::FAILURE;
209 }
210 else {
211 ATH_MSG_WARNING(
"Found unsupported ROD Block version " << rodMinorVersion
212 << " of ROD block type " << rodBlockType << ". ROD Source id: 0x" <<std::hex<<rob.rod_source_id());
213 continue;
214 }
215 }
216 }
217 else if (rodBlockType==2) {
218 switch(rodMinorVersion) {
219 case 4:
220 rodBlock.reset(
new LArRodBlockTransparentV0<LArRodBlockHeaderTransparentV0> (this->
msgSvc().
get()));
221 break;
222 case 12:
223 rodBlock.reset(
new LArRodBlockCalibrationV3 (this->
msgSvc().
get()));
224 break;
225 default:
226 ATH_MSG_WARNING(
"Found unsupported ROD Block version " << rodMinorVersion
227 << " of ROD block type " << rodBlockType);
229 }
230 }
231 }
232
233 const uint32_t* pData=rob.rod_data();
234 const uint32_t nData=rob.rod_ndata();
235 if (nData==0) {
237 ATH_MSG_ERROR(
"ROD 0x"<<std::hex<<rob.rod_source_id() << std::dec <<
" reports data block size 0");
238 return StatusCode::FAILURE;
239 }
240 else {
241 ATH_MSG_WARNING(
"ROD 0x"<<std::hex<<rob.rod_source_id() << std::dec <<
" reports data block size 0");
242 continue;
243 }
244 }
245
246 if (!rodBlock || !rodBlock->setFragment(pData,nData)) {
248 ATH_MSG_ERROR(
"Failed to assign fragment pointer to LArRodBlockStructure");
249 return StatusCode::FAILURE;
250 }
251 else {
252 ATH_MSG_WARNING(
"Failed to assign fragment pointer to LArRodBlockStructure");
253 continue;
254 }
255 }
256
258 const uint32_t onsum = rodBlock->onlineCheckSum();
259 const uint32_t offsum = rodBlock->offlineCheckSum();
260 if(onsum!=offsum) {
264 ATH_MSG_ERROR(
"offline checksum = 0x" << MSG::hex << offsum << MSG::dec);
265 return StatusCode::FAILURE;
266 } else {
267 continue;
268 }
269 }
270 }
271
272
273 do {
274 HWIdentifier fId(Identifier32(rodBlock->getFEBID()));
277 ATH_MSG_ERROR(
"Invalid FEB identifer 0x" << std::hex << fId.get_identifier32().get_compact());
278 return StatusCode::FAILURE;
279 } else {
280 ATH_MSG_WARNING(
"Invalid FEB identifer 0x" << std::hex << fId.get_identifier32().get_compact());
281 continue;
282 }
283 }
284
286 const auto ftId=
m_onlineId->feedthrough_Id(fId);
288 ATH_MSG_DEBUG(
"Feedthrough with id " << MSG::hex << ftId << MSG::dec <<
" not in preselection. Ignored.");
289 continue;
290 } else {
291 ATH_MSG_DEBUG(
"Feedthrough with id " << MSG::hex << ftId << MSG::dec <<
" is preselected.");
292 }
293 }
294
295 const int NthisFebChannel=
m_onlineId->channelInSlotMax(fId);
296
297
301 int32_t quality;
303 int fcNb;
304 while (rodBlock->getNextEnergy(fcNb,energy,time,quality,gain)) {
305 if (fcNb>=NthisFebChannel)
306 continue;
307
308 HWIdentifier cId =
m_onlineId->channel_Id(fId,fcNb);
311 if (quality>0) {
313 iquality = (quality & 0xFFFF);
314 }
315 rawChannels->emplace_back(cId, energy, time, iquality, iprovenance, (
CaloGain::CaloGain)gain);
316 }
317 }
318
319
322 int fcNb;
323 std::vector<short> samples;
324 while (rodBlock->getNextRawData(fcNb,samples,gain)) {
325 if (fcNb>=NthisFebChannel)
326 continue;
327 if (samples.size()==0) continue;
328 HWIdentifier cId =
m_onlineId->channel_Id(fId,fcNb);
330 samples.clear();
331 }
332 }
333
334
336 std::unique_ptr<LArFebHeader> larFebHeader(new LArFebHeader(fId));
338 febHeaders->
push_back(std::move(larFebHeader));
339 }
340
341 }while (rodBlock->nextFEB());
342 }
343 return StatusCode::SUCCESS;
344}
#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,...)
#define ATH_MSG_VERBOSE(x,...)
Athena::TPCnvVers::Current Athena::TPCnvVers::Old Athena::TPCnvVers::Old LArRawChannelContainer
OFFLINE_FRAGMENTS_NAMESPACE::FullEventFragment RawEvent
data type for reading raw event
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
value_type emplace_back(value_type pElem)
Add an element to the end of the collection.
value_type push_back(value_type pElem)
Add an element to the end of the collection.
std::set< HWIdentifier > m_vFinalPreselection
BooleanProperty m_failOnCorruption
SG::WriteHandleKey< LArRawChannelContainer > m_rawChannelKey
const LArOnlineID * m_onlineId
ServiceHandle< IROBDataProviderSvc > m_robDataProviderSvc
SG::WriteHandleKey< LArFebHeaderContainer > m_febHeaderKey
BooleanProperty m_verifyChecksum
SG::WriteHandleKey< LArDigitContainer > m_digitKey
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
time(flags, cells_name, *args, **kw)
eformat::ROBFragment< PointerType > ROBFragment