ATLAS Offline Software
Loading...
Searching...
No Matches
LArRODMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ********************************************************************
6//
7// NAME: LArRODMonAlg.cxx
8// PACKAGE: LArMonitoring
9//
10// ********************************************************************
11
12#include "LArRODMonAlg.h"
13
19
22
24
26#include "GaudiKernel/ConcurrencyFlags.h"
27#include <cmath>
28#include <algorithm>
29#include <format>
30#include <type_traits>
31
32/*---------------------------------------------------------*/
34
35/*---------------------------------------------------------*/
36StatusCode
38 ATH_MSG_VERBOSE( "In LArRODMonAlg::initialize() ");
39
40 ATH_CHECK(detStore()->retrieve(m_LArOnlineIDHelper, "LArOnlineID"));
41
44 ATH_CHECK(m_digitContainerKey.initialize());
45 ATH_CHECK(m_headerContainerKey.initialize());
46
47 ATH_CHECK(m_keyOFC.initialize());
48 ATH_CHECK(m_keyShape.initialize());
49 ATH_CHECK(m_keyHVScaleCorr.initialize());
50 ATH_CHECK(m_keyPedestal.initialize());
51
52 ATH_CHECK(m_adc2mevKey.initialize());
53
54 ATH_CHECK(m_noiseCDOKey.initialize());
55 ATH_CHECK(m_cablingKey.initialize());
56
57 ATH_CHECK(m_bcContKey.initialize());
58 ATH_CHECK(m_bcMask.buildBitMask(m_problemsToMask,msg()));
59
60 ATH_CHECK( m_eventInfoKey.initialize() );
61
62
63 //Check properties ...
64 if (Gaudi::Concurrency::ConcurrencyFlags::numThreads() > 1) { //MT environment
65 if (m_doDspTestDump) {
66 ATH_MSG_ERROR("Property 'DoDspTestDump' must not be true if nThreads>1");
67 return StatusCode::FAILURE;
68 }
69 if (m_doCellsDump) {
70 ATH_MSG_ERROR("Property 'DoCellsDump' must not be true if nThreads>1");
71 return StatusCode::FAILURE;
72 }
73 }
74
75
76 auto pairCmp = [](const std::pair<int,int>& p1, const std::pair<int,int>& p2) {return (p1.first<p2.first);};
77 if (!std::is_sorted(m_E_precision.begin(),m_E_precision.end(),pairCmp)) {
78 ATH_MSG_ERROR("Configuration problem: Energy ranges not in ascending order!");
79 return StatusCode::FAILURE;
80 }
81
82 if (!std::is_sorted(m_T_precision.begin(),m_T_precision.end(),pairCmp)) {
83 ATH_MSG_ERROR("Configuration problem: Time ranges not in ascending order!");
84 return StatusCode::FAILURE;
85 }
86
87 if (!std::is_sorted(m_Q_precision.begin(),m_Q_precision.end(),pairCmp)) {
88 ATH_MSG_ERROR("Configuration problem: Quality ranges not in ascending order!");
89 return StatusCode::FAILURE;
90 }
91
92
93 // Open output files for DspTest
94 if (m_doDspTestDump) {
95 m_fai.open(m_AiFileName,std::ios::trunc);
96 m_fdig.open(m_DigitsFileName,std::ios::trunc);
97 m_fen.open(m_EnergyFileName,std::ios::trunc);
98 }
99
100 // Output file
101 if (m_doCellsDump) {
102 m_fdump.open(m_DumpCellsFileName);
103 m_fdump<<"febid channel CellID slot FT barrel_ec posneg partition E_off E_on T_off T_on Q_off Q_on event "<<std::endl;
104 }
105
106
107 ATH_MSG_DEBUG("Setting an offset time of " << m_timeOffset << " BC, i.e. " << m_timeOffset*m_BC << " ps");
108
110
112}
113
114StatusCode LArRODMonAlg::fillHistograms(const EventContext& ctx) const {
115 ATH_MSG_VERBOSE( "In LArRODMonAlg::fillHistograms()");
116
117 //monitored variables
118 auto weight_e = Monitored::Scalar<float>("weight_e",1.);
119 auto weight_q = Monitored::Scalar<float>("weight_q",1.);
120 auto weight_t = Monitored::Scalar<float>("weight_t",1.);
121 auto numE = Monitored::Scalar<int>("numE",1.);
122 auto numQ = Monitored::Scalar<int>("numQ",1.);
123 auto numT = Monitored::Scalar<int>("numT",1.);
124 auto gain = Monitored::Scalar<int>("gain",-1);
125 auto partition = Monitored::Scalar<int>("partition",-1);
126 auto partitionI = Monitored::Scalar<int>("partitionI",-1);
127 auto lb = Monitored::Scalar<int>("LBN",0);
128 auto sweetc = Monitored::Scalar<float>("Sweetc",1.);
129
131
133 const ILArPedestal* pedestals=*pedestalHdl;
134
135 //retrieve BadChannel info:
137 const LArBadChannelCont* bcCont{*bcContHdl};
138
139 bool isEventFlaggedByLArNoisyROAlg = false; // keep default as false
140 bool isEventFlaggedByLArNoisyROAlgInTimeW = false; // keep deault as false
141
142 if ( thisEventInfo->isEventFlagBitSet(xAOD::EventInfo::LAr,0) ) {
143 isEventFlaggedByLArNoisyROAlg = true;
144 ATH_MSG_DEBUG( "Event flagged as Noisy" );
145 }
146
147 if ( thisEventInfo->isEventFlagBitSet(xAOD::EventInfo::LAr,3) ) {
148 isEventFlaggedByLArNoisyROAlgInTimeW = true;
149 ATH_MSG_DEBUG( " !!! Noisy event found by LArNoisyROAlg in Time window of 500ms!!!" );
150 }
151
152 // Noise bursts cleaning (LArNoisyRO_Std or TimeWindowVeto) added by B.Trocme - 19/7/12
153 if (m_removeNoiseBursts && (isEventFlaggedByLArNoisyROAlg || isEventFlaggedByLArNoisyROAlgInTimeW)) return StatusCode::SUCCESS;
154
155 // Retrieve stream info
156 int nStreams = m_streams.size();
157 // if ((nStreams == 1 && m_streams[0] == "all") || nStreams <= 0) selectstreams = false;
158
159 lb = thisEventInfo->lumiBlock();
160
161 //Fixme: Use LArTrigStreamMatching also here.
162 const int streamsize = nStreams + 1;
163 std::vector<int> hasStream(streamsize,0);
164 // for (int str = 0; str < nStreams + 1; str++) hasStream[str] = 0;
165
166 bool hasstrlist = false;
167 const std::vector< xAOD::EventInfo::StreamTag >& evtStreamTags=thisEventInfo->streamTags();
168 for (const auto& evtStreamTag : evtStreamTags) {
169 std::vector<std::string>::const_iterator evtStreamTagIt=std::find(m_streams.begin(),m_streams.end(),evtStreamTag.name());
170 if (evtStreamTagIt!=m_streams.end()) {
171 const unsigned str=evtStreamTagIt-m_streams.begin();
172 ATH_MSG_VERBOSE( "Keeping Stream Tag: " << evtStreamTag.type() << "_" << evtStreamTag.name());
173 hasStream[str] = 1;
174 hasstrlist = true;
175 }
176 }
177 if (! hasstrlist) hasStream[nStreams] = 1;
178
179
181
183
185
186 std::set<HWIdentifier> ignoreFEBs;
187
190 if (!febCont) {
191 ATH_MSG_WARNING( "No LArFEB container found in TDS" );
192 } else {
193 for (const auto* febH : *febCont) {
194 if (((m_doCheckSum && febH->ChecksumVerification()==false)) ||
195 (m_doRodStatus && febH->RodStatus()!=0))
196 ignoreFEBs.insert(febH->FEBId());
197 }
198 }
199 ATH_MSG_DEBUG("Found " << ignoreFEBs.size() << " FEBs with checksum errors or statatus errors. Will ignore these FEBs.");
200 }
201
202 std::vector<ERRCOUNTER> errcounters(N_PARTITIONS);
203 ERRCOUNTER allEC;
204
205 std::vector<unsigned> errsPerFEB;
206 errsPerFEB.resize(m_LArOnlineIDHelper->febHashMax(),0);
207
208 const bool ignoreFebs=(ignoreFEBs.size()>0);
209 std::set<HWIdentifier>::const_iterator ignoreFebsEnd=ignoreFEBs.end();
210
211 unsigned count_gain[(int)CaloGain::LARNGAIN] = {0};
212
213 //Build an association of channels in the two LArRawChannelContainers.
214 //The LArRawChannelContainers are unordered collections of LArRawChannels.
215 //But we know that they have the same order because they were built from the same source (namely the LArDigits and RawChannels in the Bytestream)
216 //and we know that the LArRawChannels built offline are a subset of the LArRawChannelContainers read from Bytestream.
217 //Therfore we can search much more efficiently
218 LArRawChannelContainer::const_iterator rcDigIt=rawColl_fromDigits->begin();
219 LArRawChannelContainer::const_iterator rcDigIt_e=rawColl_fromDigits->end();
220 LArRawChannelContainer::const_iterator rcBSIt=rawColl_fromBytestream->begin();
221 LArRawChannelContainer::const_iterator rcBSIt_e=rawColl_fromBytestream->end();
222
223 LArDigitContainer::const_iterator digIt=pLArDigitContainer->begin();
224 LArDigitContainer::const_iterator digIt_e=pLArDigitContainer->end();
225
226
227 //Loop over indices in LArRawChannelContainer built offline (the small one)
228 ATH_MSG_DEBUG( "Entering the LArRawChannel loop." );
229
230 for (;rcDigIt!=rcDigIt_e;++rcDigIt) {
231 const HWIdentifier idDig=rcDigIt->hardwareID();
232 const HWIdentifier febId=m_LArOnlineIDHelper->feb_Id(idDig);
233 // Check if this FEB should be ignored
234 if (ignoreFebs) {
235 if (ignoreFEBs.find(febId)!=ignoreFebsEnd) continue;
236 }
237 //Check if this is a bad channel
238 if (m_skipKnownProblematicChannels && m_bcMask.cellShouldBeMasked(bcCont,idDig)) continue;
239
240 const CaloGain::CaloGain gain = rcDigIt->gain();
241 if ((gain >= ERRCOUNTER::N) or (gain < 0)){
242 ATH_MSG_WARNING( std::format("gain {} is out of range for the ERRCOUNTER array size, {}",
243 static_cast<std::underlying_type_t<CaloGain::CaloGain>>(gain), ERRCOUNTER::N));
244 return StatusCode::FAILURE;
245 }
246 //Check pedestal if needed
247 if (m_skipNullPed) {
248 const float ped = pedestals->pedestal(idDig,gain);
249 if(ped <= (1.0+LArElecCalib::ERRORCODE)) continue;
250 }
251
252 //Now look for corresponding channel in the LArRawChannelContainer read from Bytestream (the big one)
253 LArRawChannelContainer::const_iterator currIt=rcBSIt; //Remember current position in container
254 for (;rcBSIt!=rcBSIt_e && rcBSIt->hardwareID() != idDig; ++rcBSIt);
255 if (rcBSIt==rcBSIt_e) {
256 ATH_MSG_WARNING( "LArDigitContainer not in the expected order. Change of LArByteStream format?" );
257 //Wrap-around
258 for (rcBSIt=rawColl_fromBytestream->begin();rcBSIt!=currIt && rcBSIt->hardwareID() != idDig; ++rcBSIt);
259 if (rcBSIt==currIt) {
260 ATH_MSG_ERROR( "Channel " << m_LArOnlineIDHelper->channel_name(idDig) << " not found." );
261 return StatusCode::FAILURE;
262 }
263 }
264
265 //Now look for corresponding channel in the LArDigitContainer read from Bytestream
266 //Should be in almost in sync with the RawChannelContainer we are iterating over,
267 //but contains disconnected channels that are not part of the LArRawChannelContainer
268 LArDigitContainer::const_iterator currDigIt=digIt; //Remember current position in digit-container
269 for (;digIt!=digIt_e && (*digIt)->hardwareID() != idDig; ++digIt);
270 if (digIt==digIt_e) {
271 ATH_MSG_WARNING( "LArRawChannelContainer not in the expected order. Change of LArRawChannelBuilder behavior?" );
272 //Wrap-around
273 for (digIt=pLArDigitContainer->begin();digIt!=currDigIt && (*digIt)->hardwareID() != idDig; ++digIt);
274 if (digIt==currDigIt) {
275 ATH_MSG_ERROR( "Channel " << m_LArOnlineIDHelper->channel_name(idDig) << " not found in LArDigitContainer." );
276 return StatusCode::FAILURE;
277 }
278 }
279 const LArDigit* dig=*digIt;
280 const std::vector<short>& samples=dig->samples();
281 const auto [minSamplesIt, maxSamplesIt] = std::minmax_element(samples.begin(),samples.end());
282 if (m_adc_th<=0 || (*maxSamplesIt-*minSamplesIt)>m_adc_th) {
283 const diff_t compRes=compareChannel(*rcDigIt,*rcBSIt);
284 if (compRes.e_on!=compRes.e_off || compRes.t_on!=compRes.t_off || compRes.q_on!=compRes.q_off) {
286 detailedOutput(compRes,*dig,ctx);
287 ++m_ndump;
288 }
289 if (m_doCellsDump) {
290 dumpCellInfo(idDig,gain,ctx,compRes);
291 }
292 }
293 //Count errors:
294 const PARTITION p=getPartition(idDig);
295 if (compRes.e_on!=compRes.e_off) {
296 ++(errcounters[p].errors_E[gain]);
297 ++(allEC.errors_E[gain]);
298
299 IdentifierHash febHash=m_LArOnlineIDHelper->feb_Hash(febId);
300 ++(errsPerFEB[febHash]);
301 }
302 if (compRes.t_on!=compRes.t_off) {//Time-error
303 ++(errcounters[p].errors_T[gain]);
304 ++(allEC.errors_T[gain]);
305 }
306
307 if (compRes.q_on!=compRes.q_off) {//Quality-error
308 ++(errcounters[p].errors_Q[gain]);
309 ++(allEC.errors_Q[gain]);
310 }
311
312 }
313 else {
314 ATH_MSG_DEBUG( "Samples : "<< *maxSamplesIt << " " << *minSamplesIt );
315 }
316 }//end loop over rawColl_fromDigits
317
318 ATH_MSG_DEBUG( "End of rawChannels loop" );
319
320 for (unsigned i=0;i<m_LArOnlineIDHelper->febHashMax();++i) {
321 const HWIdentifier febid=m_LArOnlineIDHelper->feb_Id(i);
322 const std::string pn=getPartitionName(febid);
323 sweetc = errsPerFEB[i];
324 fill(m_tools[m_histoGroups.at(pn)],sweetc);
325 }
326
327
328 ATH_MSG_VERBOSE( "*Number of errors in Energy Computation : " );
329 ATH_MSG_VERBOSE( "* Low Gain : " << allEC.errors_E[2] << " / " << count_gain[CaloGain::LARLOWGAIN] );
330 ATH_MSG_VERBOSE( "* Medium Gain : " << allEC.errors_E[1] << " / " << count_gain[CaloGain::LARMEDIUMGAIN] );
331 ATH_MSG_VERBOSE( "* High Gain : " << allEC.errors_E[0] << " / " << count_gain[CaloGain::LARHIGHGAIN] );
332 ATH_MSG_VERBOSE( "*Number of errors in Time Computation : " );
333 ATH_MSG_VERBOSE( "* Low Gain : " << allEC.errors_T[2] << " / " << count_gain[CaloGain::LARLOWGAIN] );
334 ATH_MSG_VERBOSE( "* Medium Gain : " << allEC.errors_T[1] << " / " << count_gain[CaloGain::LARMEDIUMGAIN] );
335 ATH_MSG_VERBOSE( "* High Gain : " << allEC.errors_T[0] << " / " << count_gain[CaloGain::LARHIGHGAIN] );
336 ATH_MSG_VERBOSE( "*Number of errors in Quality Computation : " );
337 ATH_MSG_VERBOSE( "* Low Gain : " << allEC.errors_Q[2] << " / " << count_gain[CaloGain::LARLOWGAIN] );
338 ATH_MSG_VERBOSE( "* Medium Gain : " << allEC.errors_Q[1] << " / " << count_gain[CaloGain::LARMEDIUMGAIN] );
339 ATH_MSG_VERBOSE( "* High Gain : " << allEC.errors_Q[0] << " / " << count_gain[CaloGain::LARHIGHGAIN] );
340
341 for (unsigned p=0;p<N_PARTITIONS;++p) {
342 unsigned allErrsPartE=0;
343 unsigned allErrsPartT=0;
344 unsigned allErrsPartQ=0;
345 partition = p;
346 for (unsigned g=0;g<3;++g) {
347 gain = g;
348 weight_e = (float)errcounters[p].errors_E[g];
349 weight_q = (float)errcounters[p].errors_Q[g];
350 weight_t = (float)errcounters[p].errors_T[g];
351 fill(m_MonGroupName, partition, gain, weight_e, weight_q, weight_t);
352
353 allErrsPartE+=errcounters[p].errors_E[g];
354 allErrsPartT+=errcounters[p].errors_T[g];
355 allErrsPartQ+=errcounters[p].errors_Q[g];
356 }
357 partitionI = p;
358 numE = (float)allErrsPartE;
359 numT = (float)allErrsPartT;
360 numQ = (float)allErrsPartQ;
361 fill(m_MonGroupName, lb, partitionI, numE, numT, numQ);
362 }//end loop over partitions
363
364 /*
365 for(int str = 0; str < nStreams + 1; str++) {
366 if (hasStream[str] == 1) {
367
368 m_hEErrors_LB_stream->Fill((float)m_curr_lb,(float)str,(float)allErr_E);
369 m_hTErrors_LB_stream->Fill((float)m_curr_lb,(float)str,(float)allErr_T);
370 m_hQErrors_LB_stream->Fill((float)m_curr_lb,(float)str,(float)allErr_Q);
371 FIXME
372 }
373 }
374 */
375
376 return StatusCode::SUCCESS;
377}
378
379
380
382 const LArRawChannel& rcBS) const {
383 diff_t result;
384 const HWIdentifier chid=rcDig.channelID();
385 const int slot_fD = m_LArOnlineIDHelper->slot(chid);
386 const int feedthrough_fD = m_LArOnlineIDHelper->feedthrough(chid);
387 const float timeOffline = rcDig.time() - m_timeOffset*m_BC;
388
389 const float& en_fB=rcBS.energy();
390 const float& en_fD=rcDig.energy();
391
392 ATH_MSG_VERBOSE(chid.getString()<<" | "<<timeOffline<<" "<<rcBS.time()<<" | "<<en_fB<<" "<<en_fD);
393
394 if (fabs(timeOffline) > m_peakTime_cut*1000.){
395 ATH_MSG_DEBUG( " timeOffline too large " << timeOffline );
396 return result;
397 }
398
399 const std::string & hg=getPartitionName(chid);
400 auto slot = Monitored::Scalar<int>("slot",slot_fD);
401 auto ft = Monitored::Scalar<int>("FT",feedthrough_fD);
402
403 auto pairValueCmp = [](const int& a, const std::pair<int,int>& b){return a<b.first;};
404 //Energy check:
405 //Find expected precision given the cell-energy:
406 auto e_Precision=std::upper_bound(m_E_precision.begin(),m_E_precision.end(),std::abs(en_fB),pairValueCmp);
407 const size_t energyrange=e_Precision-m_E_precision.begin();
408 auto erange = Monitored::Scalar<int>("Erange",energyrange);
409 auto DiffE = Monitored::Scalar<float>("Ediff",en_fD - en_fB);
410 fill(m_MonGroupName,DiffE,erange);
411
412 auto Eon = Monitored::Scalar<float>("Eon",en_fB);
413 auto Eoff = Monitored::Scalar<float>("Eoff",en_fD);
414 fill(m_tools[m_histoGroups.at(hg)],DiffE,erange,Eon,Eoff);
415
416 if (std::abs(en_fD-en_fB) > e_Precision->second) {
417 //Fill results object for error counting, and dumping (if needed)compRes.e_on!=compRes.e_off)
418 result.e_off=en_fD;
419 result.e_on=en_fB;
420 auto weight_e = Monitored::Scalar<float>("weight_e",1.);
421 fill(m_tools[m_histoGroups.at(hg)],slot,ft,weight_e);
422 }
423
424 const float q_fB=rcBS.quality();
425 const float q_fD=rcDig.quality();
426 const float t_fB=rcBS.time();
427
428 if ((rcDig.provenance() & 0x2000) == 0 || q_fD==0 || t_fB==0 || q_fB==0 || timeOffline==0) {
429 // Skip time/Quality comparison if
430 // * provenance bits indicate the LArRawChannel builder didn't calculate these quantities
431 // * the offline time is zero (may happen if the OFC amplitude < 0.1 )
432 // * online value are zero
433 // * offline quality is 0 (avoid div-by-zero later on)
434 ATH_MSG_VERBOSE("Skip time/Quality comparison, not computed either online or offline");
435 return result;
436 }
437
438 auto DiffT = Monitored::Scalar<float>("Tdiff",timeOffline - t_fB);
439 //Find expected precision given the cell-time:
440 auto t_Precision=std::upper_bound(m_T_precision.begin(),m_T_precision.end(),std::abs(t_fB),pairValueCmp);
441
442 auto Ton = Monitored::Scalar<float>("Ton",t_fB);
443 auto Toff = Monitored::Scalar<float>("Toff",timeOffline);
444 fill(m_tools[m_histoGroups.at(hg)],DiffT,Ton,Toff);
445 fill(m_MonGroupName,DiffT);
446 if (fabs(DiffT) > t_Precision->second) {
447 auto weight_t = Monitored::Scalar<float>("weight_t",1.);
448 fill(m_tools[m_histoGroups.at(hg)],slot,ft,weight_t);
449 result.t_on=t_fB;
450 result.t_off=timeOffline;
451 }
452
453
454 //Quality check:
455 float qdiff = 65535.0; // max possible quality
456 if (q_fD > 0.) qdiff = (q_fD - q_fB)/std::sqrt(q_fD);
457
458 //Find expected precision given the cell-quality:
459 auto q_Precision=std::upper_bound(m_Q_precision.begin(),m_Q_precision.end(),std::abs(q_fB),pairValueCmp);
460
461 auto DiffQ = Monitored::Scalar<float>("Qdiff", qdiff);
462 auto Qon = Monitored::Scalar<float>("Qon",q_fB);
463 auto Qoff = Monitored::Scalar<float>("Qoff",q_fD);
464 fill(m_tools[m_histoGroups.at(hg)],DiffQ,Qon,Qoff);
465 fill(m_MonGroupName,DiffQ);
466
467 if (fabs(DiffQ) > q_Precision->second) {
468 auto weight_q = Monitored::Scalar<float>("weight_q",1.);
469 fill(m_tools[m_histoGroups.at(hg)],slot,ft,weight_q);
470 result.q_on=q_fB;
471 result.q_off=q_fD;
472 }
473 return result;
474}
475
477 const LArDigit& dig,
478 const EventContext& ctx) const{
479
480
481 const HWIdentifier chid=dig.channelID();
482 const auto gain=dig.gain();
483
485 const CaloNoise *noisep = *noiseHdl;
486
488 const ILArPedestal* pedestals=*pedestalHdl;
489
491 const ILArOFC* ofcs=*ofcHdl;
492 const ILArOFC::OFCRef_t& OFCa = ofcs->OFC_a(chid,gain);
493 const ILArOFC::OFCRef_t& OFCb = ofcs->OFC_b(chid,gain);
495
496 const ILArShape* shapes=*shapeHdl;
497 const ILArShape::ShapeRef_t& shape = shapes->Shape(chid,gain);
498 const ILArShape::ShapeRef_t& shapeDer = shapes->ShapeDer(chid,gain);
499
501 const ILArHVScaleCorr* hvScaleCorrs=*hvScaleCorrHdl;
502
504 const LArADC2MeV* adc2mev=*adc2MeVHdl;
505 const auto& polynom_adc2mev=adc2mev->ADC2MEV(chid,gain);
506 const float escale = (polynom_adc2mev)[1];
507 float ramp0 = (polynom_adc2mev)[0];
509 const LArOnOffIdMapping* cabling=*cablingHdl;
510
511 const float hvscale = hvScaleCorrs->HVScaleCorr(chid);
512 const int channel=m_LArOnlineIDHelper->channel(chid);
513 const HWIdentifier febid=m_LArOnlineIDHelper->feb_Id(chid);
514 const std::vector<short>& samples=dig.samples();
515 if (gain == 0) ramp0 = 0.; // no ramp intercepts in HG
516 const float ped = pedestals->pedestal(chid,dig.gain());
517
518
519 //Log-file output if requested ...
521 ATH_MSG_WARNING("Channel " << m_LArOnlineIDHelper->channel_name(chid) << ", gain " << gain
522 <<", run " << ctx.eventID().run_number() << ", evt " << ctx.eventID().event_number());
523 if (cmp.e_on!=cmp.e_off) {
524 ATH_MSG_WARNING("DSP Energy Error:");
525 ATH_MSG_WARNING( " Eonl = " << cmp.e_on << " , Eoff = " << cmp.e_off
526 << " , Eoff - Eonl = " << cmp.e_off-cmp.e_on);
527 }
528 else {
529 ATH_MSG_WARNING("Eonl=Eofl="<< cmp.e_on);
530 }
531 if(cmp.t_off!=cmp.t_on ) {
532 ATH_MSG_WARNING( "DSP Time Error:");
533 ATH_MSG_WARNING( " Tonl = " << cmp.t_on << " , Toff = " << cmp.t_off
534 << " , Toff - Tonl = " << cmp.t_off - cmp.t_on);
535 }
536 if (cmp.q_off!=cmp.q_on) {
537 ATH_MSG_WARNING( "DSP Quality Error");
538 ATH_MSG_WARNING( " Qonl = " << cmp.q_on << " , Qoff = " << cmp.q_off
539 << " (Qoff - Qnl)/sqrt(Qoff) = " << (cmp.q_off - cmp.q_on)/std::sqrt(cmp.q_off));
540 }
541 }
542 if (m_ndump<m_max_dump) {
543 std::string output;
544 output="Digits : ";
545 for (const short s : samples) {output+=std::to_string(s)+ " ";}
546 ATH_MSG_INFO(output);
547
548 output="OFCa : ";
549 for (const auto o : OFCa) {output+=std::to_string(o)+" ";}
550 ATH_MSG_INFO(output);
551
552 output="OFCb : ";
553 for (const auto o : OFCb) {output+=std::to_string(o)+" ";}
554 ATH_MSG_INFO(output);
555
556 output="Shape : ";
557 for (const auto s : shape) {output+=std::to_string(s)+" ";}
558 ATH_MSG_INFO(output);
559
560 output="ShapeDer : ";
561 for (const auto s : shapeDer) {output+=std::to_string(s)+" ";}
562 ATH_MSG_INFO( output );
563
564 ATH_MSG_INFO( "Escale: "<<escale<<" intercept: "<<ramp0<<" pedestal: "<<ped<<" gain: "<<dig.gain() );
565 const Identifier cellid=cabling->cnvToIdentifier(chid);
566 const float noise=noisep->getNoise(cellid,gain);
567 ATH_MSG_INFO( "Noise: "<<noise);
568 ATH_MSG_INFO( "HVScaleCorr: "<<hvscale);
569 double emon=0.;
570 const unsigned nOFCSamp=std::min(samples.size(),OFCa.size());
571 for (unsigned k=0; k<nOFCSamp; ++k) emon += (samples.at(k)-ped)*OFCa.at(k);
572 emon *= escale;
573 emon += ramp0;
574 ATH_MSG_INFO( "intercept + Escale*Sum[(sample-ped)*OFCa] "<<emon);
575 }//end log-file dump
576
577 if(m_doCellsDump) {
578 float sumai = 0.;
579 for (const float a : OFCa) {sumai += a;}
580 float pedplusoffset=0;
581 if (escale*sumai != 0) pedplusoffset = ped - ramp0/(escale*sumai);
582 else pedplusoffset = 0;
583 const float inv_Escale = 1. / escale;
584
585 m_fai << channel<<"\t"<< ped<<"\t"<< pedplusoffset<<"\t"
586 << OFCa[0]*escale<<"\t"<< OFCa[1]*escale<<"\t"<< OFCa[2]*escale<<"\t"<< OFCa[3]*escale<<"\t"<< OFCa[4]*escale<<"\t"
587 << OFCb[0]*escale<<"\t"<< OFCb[1]*escale<<"\t"<< OFCb[2]*escale<<"\t"<< OFCb[3]*escale<<"\t"<< OFCb[4]*escale<<"\t"
588 << shape[0]*inv_Escale<<"\t"<< shape[1]*inv_Escale<<"\t"<< shape[2]*inv_Escale<<"\t"<< shape[3]*inv_Escale<<"\t"<< shape[4]*inv_Escale<<"\t"
589 << shapeDer[0]*inv_Escale<<"\t"<< shapeDer[1]*inv_Escale<<"\t"<< shapeDer[2]*inv_Escale<<"\t"<< shape[3]*inv_Escale<<"\t"<< shapeDer[4]*inv_Escale << std::endl;
590
591 // Dumping file with offline energy and online energ
592 m_fen << m_ndump << " " << cmp.e_off << " " << cmp.e_on ;
593 m_fen << " // FEB " << febid.get_identifier32().get_compact() << " ( channel " << channel << " ), event " << ctx.eventID().event_number() << std::endl;
594
595 // Dumping file with digits
596 m_fdig << channel << " ";
597 for (const short d : samples) {
598 m_fdig << d << " ";
599 }
600 m_fdig << " // FEB " << febid.get_identifier32().get_compact() << " ( channel " << channel << " ), event " << ctx.eventID().event_number() << std::endl;
601 } //end if m_doCellsDump
602 return;
603}
604
606 const int gain,
607 const EventContext& ctx,
608 const diff_t & cmp) const {
609
610 // Dumping cell information in a text file so that it can be compared to unhappy channels lists for instance ...
611
612 const int barrel_ec=m_LArOnlineIDHelper->barrel_ec(chid);
613 const int posneg=m_LArOnlineIDHelper->pos_neg(chid);
614 const int slot = m_LArOnlineIDHelper->slot(chid);
615 const int FT = m_LArOnlineIDHelper->feedthrough(chid);
616 const int channel = m_LArOnlineIDHelper->channel(chid);
617 const HWIdentifier febid= m_LArOnlineIDHelper->feb_Id(chid);
618 m_fdump << "0x" << std::hex << std::setw(8)<<febid.get_identifier32().get_compact() << " " << std::dec << std::setw(3) << std::right << channel << " 0x" << std::hex << std::setw(8)<<chid.get_identifier32().get_compact()
619 <<std::dec << std::setw(3) << std::right << slot << std::setw(3) << std::right << FT << std::setw(3) << std::right << barrel_ec << std::setw(3) << std::right<< posneg << std::setw(6) << std::right << getPartitionName(chid)
620 << " " << gain << " " << " " << cmp.e_off << " "<< cmp.e_on << " "<<cmp.t_off << " "<<cmp.t_on <<" "<<cmp.q_off << " "<<cmp.q_on <<ctx.eventID().event_number()<<std::endl;
621 return;
622}
623
625 errors_E.fill(0);
626 errors_T.fill(0);
627 errors_Q.fill(0);
628 return;
629}
630
632 m_fai.close();
633 m_fdig.close();
634 m_fen.close();
635 m_fdump.close();
636 return StatusCode::SUCCESS;
637}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
LArBadXCont< LArBadChannel > LArBadChannelCont
static Double_t a
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.).
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
float getNoise(const IdentifierHash h, const int gain) const
Accessor by IdentifierHash and gain.
Definition CaloNoise.h:35
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
virtual const float & HVScaleCorr(const HWIdentifier &id) const =0
virtual OFCRef_t OFC_b(const HWIdentifier &id, int gain, int tbin=0) const =0
virtual OFCRef_t OFC_a(const HWIdentifier &id, int gain, int tbin=0) const =0
access to OFCs by online ID, gain, and tbin (!=0 for testbeam)
LArVectorProxy OFCRef_t
This class defines the interface for accessing Optimal Filtering coefficients for each channel provid...
Definition ILArOFC.h:26
virtual float pedestal(const HWIdentifier &id, int gain) const =0
LArVectorProxy ShapeRef_t
This class defines the interface for accessing Shape (Nsample variable, Dt = 25 ns fixed) @stereotype...
Definition ILArShape.h:26
virtual ShapeRef_t Shape(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
virtual ShapeRef_t ShapeDer(const HWIdentifier &id, int gain, int tbin=0, int mode=0) const =0
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
std::string getString() const
Provide a string form of the identifier - hexadecimal.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
const LArVectorProxy ADC2MEV(const HWIdentifier &id, int gain) const
Definition LArADC2MeV.h:32
Liquid Argon digit base class.
Definition LArDigit.h:25
CaloGain::CaloGain gain() const
Definition LArDigit.h:72
const std::vector< short > & samples() const
Definition LArDigit.h:78
const HWIdentifier & channelID() const
Definition LArDigit.h:69
Container class for LArFebHeader.
std::array< unsigned, N > errors_E
std::array< unsigned, N > errors_T
static constexpr int N
std::array< unsigned, N > errors_Q
Gaudi::Property< std::vector< std::pair< int, int > > > m_T_precision
Gaudi::Property< std::vector< std::pair< int, int > > > m_E_precision
const char * getPartitionName(const HWIdentifier chid) const
virtual StatusCode initialize() override final
initialize
Gaudi::Property< float > m_timeOffset
Gaudi::Property< bool > m_printEnergyErrors
Gaudi::Property< bool > m_doRodStatus
Gaudi::Property< std::string > m_DigitsFileName
Gaudi::Property< std::string > m_AiFileName
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
SG::ReadCondHandleKey< ILArPedestal > m_keyPedestal
Gaudi::Property< std::vector< std::pair< int, int > > > m_Q_precision
void dumpCellInfo(const HWIdentifier chid, const int gain, const EventContext &ctx, const diff_t &comp) const
Dump a cell's information and calculated energies into a txt file.
Gaudi::Property< bool > m_skipNullPed
const LArOnlineID * m_LArOnlineIDHelper
SG::ReadHandleKey< LArFebHeaderContainer > m_headerContainerKey
Gaudi::Property< std::vector< std::string > > m_streams
SG::ReadCondHandleKey< LArADC2MeV > m_adc2mevKey
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
Gaudi::Property< bool > m_removeNoiseBursts
virtual ~LArRODMonAlg()
Default destructor.
Gaudi::Property< float > m_peakTime_cut
PARTITION getPartition(const HWIdentifier chid) const
Gaudi::Property< bool > m_skipKnownProblematicChannels
SG::ReadCondHandleKey< ILArOFC > m_keyOFC
Gaudi::Property< std::string > m_DumpCellsFileName
SG::ReadDecorHandleKey< xAOD::EventInfo > m_eventInfoKey
Gaudi::Property< std::vector< std::string > > m_problemsToMask
Gaudi::Property< bool > m_doCellsDump
virtual StatusCode finalize() override final
diff_t compareChannel(const LArRawChannel &rcDig, const LArRawChannel &rcBS) const
SG::ReadHandleKey< LArRawChannelContainer > m_channelKey_fromBytestream
SG::ReadCondHandleKey< LArBadChannelCont > m_bcContKey
LArBadChannelMask m_bcMask
Gaudi::Property< std::string > m_EnergyFileName
SG::ReadCondHandleKey< ILArShape > m_keyShape
Gaudi::Property< unsigned > m_max_dump
SG::ReadCondHandleKey< LArOnOffIdMapping > m_cablingKey
const float m_BC
std::atomic< unsigned > m_ndump
Gaudi::Property< bool > m_doCheckSum
Gaudi::Property< bool > m_doDspTestDump
Gaudi::Property< std::string > m_MonGroupName
Gaudi::Property< std::vector< std::string > > m_partitions
Gaudi::Property< short > m_adc_th
std::map< std::string, int > m_histoGroups
SG::ReadHandleKey< LArDigitContainer > m_digitContainerKey
void detailedOutput(const LArRODMonAlg::diff_t &, const LArDigit &dig, const EventContext &ctx) const
SG::ReadHandleKey< LArRawChannelContainer > m_channelKey_fromDigits
SG::ReadCondHandleKey< ILArHVScaleCorr > m_keyHVScaleCorr
Liquid Argon ROD output object base class.
uint16_t provenance() const
int time() const
uint16_t quality() const
HWIdentifier channelID() const
int energy() const
Declare a monitored scalar variable.
@ LAr
The LAr calorimeter.
int lb
Definition globals.cxx:23
@ LARMEDIUMGAIN
Definition CaloGain.h:18
@ LARLOWGAIN
Definition CaloGain.h:18
@ LARNGAIN
Definition CaloGain.h:19
@ LARHIGHGAIN
Definition CaloGain.h:18
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case).
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
void fill(H5::Group &out_file, size_t iterations)