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