ATLAS Offline Software
Loading...
Searching...
No Matches
LArFEBMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// ********************************************************************
6// NAME: LArFEBMonAlg.cxx
7//
8// AUTHOR: P. Strizenec, based on LArFEBMon tool by B. Trocme
9// ********************************************************************
10
11#include "LArFEBMonAlg.h"
12
15
21
23
24#include <algorithm>
25#include <math.h>
26#include <sys/types.h>
27
28const unsigned sizeNorm=262144;
29
30// ********************************************************************
31LArFEBMonAlg::LArFEBMonAlg( const std::string& name, ISvcLocator* pSvcLocator)
32 : AthMonitorAlgorithm(name, pSvcLocator),
33 m_onlineHelper(nullptr),
34 m_dspThrDone(false),
35 m_maskedDone(false),
37{
38
39}
40
41
42// ********************************************************************
44
45 ATH_MSG_INFO( "Initializing LArFEBMonAlg " );
46
47 StatusCode sc = detStore()->retrieve(m_onlineHelper, "LArOnlineID");
48 if (sc.isFailure()) {
49 ATH_MSG_ERROR( "Could not get LArOnlineID helper !" );
50 return StatusCode::FAILURE;
51 }
52
53 sc=m_BFKey.initialize();
54 if (sc.isFailure()) {
55 ATH_MSG_ERROR( "Could not initialize Missing FEBs key " << m_BFKey.key() );
56 return StatusCode::FAILURE;
57 } else {
58 ATH_MSG_DEBUG( "Missing FEBs key" << m_BFKey.key() << " initialized" );
59 }
60
61 ATH_CHECK( m_hdrContKey.initialize() );
62 ATH_CHECK( m_lArFebErrorSummaryKey.initialize() );
63
64 m_histoGroups.reserve(m_SubDetNames.size());
65 for (unsigned i=0; i<m_SubDetNames.size(); ++i) {
66 std::vector<std::string> part;
67 part.push_back(m_partitions[2*i]);
68 part.push_back(m_partitions[2*i+1]);
70 }
71
74 ATH_CHECK( m_eventInfoDecorKey.initialize() );
75
77}
78
79// ********************************************************************
80StatusCode LArFEBMonAlg::fillHistograms(const EventContext& ctx) const {
81
82 bool eventRejected = false;
83 std::bitset<13> rejectionBits;
84 // for TTree
85 std::vector<int> febInErrorTree(0);
86 std::vector<int> febErrorTypeTree(0);
87
88 // Retrieve event info to get event time,trigger type...
89 // Retrieved at beg of method now to get the LVL1 type
90 // to check consistency with DSP trigger type
92 ATH_CHECK(thisEvent.isValid());
93 unsigned int l1Trig = thisEvent->level1TriggerType();
94 auto l1 = Monitored::Scalar<int>("LVL1Trig",l1Trig);
96
97 auto eventTime = Monitored::Scalar<int>("timestamp",thisEvent->timeStamp());
98 auto eventTime_ns = Monitored::Scalar<int>("time_ns",thisEvent->timeStampNSOffset());
99
100 unsigned lumi_block = thisEvent->lumiBlock();
101 bool lar_inerror = (thisEvent->errorState(xAOD::EventInfo::LAr)==xAOD::EventInfo::Error) ? true : false;
102
103 ATH_MSG_DEBUG( "LArFEBMonAlg Lumi block: "<<lumi_block);
104
107 if (!hdrCont.isValid()) {
108 ATH_MSG_ERROR( "No LArFebHeaderContainer found in TDS" );
109 return StatusCode::FAILURE;
110 }
111
112 if (hdrCont->size()==0) {
113 ATH_MSG_WARNING( "Got empty LArFebHeaderContainer. Do nothing" );
114 return StatusCode::SUCCESS;
115 }
116
117 if (!lArFebErrorSummary.isValid()) {
118 ATH_MSG_ERROR( "No LArFebErrorSummary found in TDS" );
119 return StatusCode::FAILURE;
120 }
121
122 bool trigok=true;
124 const ToolHandle<Trig::TrigDecisionTool> trigTool=getTrigDecisionTool();
125 //const Trig::TrigDecisionTool *trigTool = dynamic_cast<const Trig::TrigDecisionTool * > (&*trigHdl);
126 std::vector<std::string> l1triggers;
127 if(!trigTool.empty()) {
128 const Trig::ChainGroup* allL1 = trigTool->getChainGroup("L1_.*");
129 l1triggers = allL1->getListOfTriggers();
130 ATH_MSG_DEBUG( "lvl1 item names: [" );
131 for (unsigned int i=0;i< l1triggers.size();i++) {
132 ATH_MSG_DEBUG( i << " " << l1triggers.at(i) << " , " );
133 }
134 ATH_MSG_DEBUG( "] " );
135 } else {
136 ATH_MSG_WARNING("TrigDecisionTool is empty");
137 }
138 if (l1triggers.size()>0) {trigok=true;} else {trigok=false;}
139 }
140
141 uint32_t firstEventType = (*hdrCont->begin())->DetEventType();
142
143 { // adding scope for locking
144 std::lock_guard<std::mutex> lock(m_mut);
145 if(!m_maskedDone) { // should be done once at the beginning
147 m_maskedDone=true;
148 }
149 }
150
151 // At 1st event, retrieve DSP thresholds and fill histogram with values for all channels
152 { // adding scope for locking
153 std::lock_guard<std::mutex> lock(m_mut);
154 if (!m_dspThrDone && firstEventType == 4) {
155
156 auto dspADC = Monitored::Scalar<unsigned int>("dspThrADC",-1);
157 auto dspQT = Monitored::Scalar<unsigned int>("dspThrQT",-1);
158 if (!m_run1DSPThresholdsKey.empty()) {
159 ATH_MSG_DEBUG("Loading run1 version of LAr DSP Thresholds");
161 for (HWIdentifier ch : m_onlineHelper->channel_range()) {
162 dspADC=dspThresh->samplesThr(ch);
163 dspQT=dspThresh->tQThr(ch);
164 fill(m_monGroupName, dspADC, dspQT);
165 }//end loop over channels
166 }
167 else if (!m_run2DSPThresholdsKey.empty()) {
168 ATH_MSG_DEBUG("Loading run2 version of LAr DSP Thresholds");
170 LArDSPThresholdsFlat dspThreshFlat(*dspThrshAttr);
171 if (!dspThreshFlat.good()) {
172 ATH_MSG_WARNING( "Failed to initialize LArDSPThresholdFlat from attribute list loaded from " << m_run2DSPThresholdsKey.key()
173 << ". Will not fill histograms." );
174 }//end if not good
175 const IdentifierHash chanMax=m_onlineHelper->channelHashMax();
176 for (unsigned iChan=0;iChan<chanMax;++iChan) {
177 dspADC=dspThreshFlat.samplesThrByHash(iChan);
178 dspQT=dspThreshFlat.tQThrByHash(iChan);
179 fill(m_monGroupName, dspADC, dspQT);
180 }
181 }
182 else
183 ATH_MSG_WARNING( "No LArDSPThresholds key specified. Will not fill these histograms" );
184 m_dspThrDone=true;
185 }//m_dspThrDone
186 } // locking scope
187
188
189 //Adjust event type if we have raw data in the ROD block
190 if (firstEventType == 4 && (*hdrCont->begin())->RodRawDataSize() != 0) firstEventType = 14;
191
192 std::vector<unsigned int> nfeb(m_partitions.size());
193 int firstEventNbSp=-1;
194 unsigned int totNbOfSweet2 = 0;
195 float larEventSize = 0;
196 float larEventSize_part[8] = {0.,0.,0.,0.,0.,0.,0.,0.};
197
198 LArFebHeaderContainer::const_iterator it = hdrCont->begin();
199 LArFebHeaderContainer::const_iterator it_e = hdrCont->end();
200
201 auto l1word = Monitored::Scalar<int>("LVL1TrigAllDSP",0);
202 // Loop on all available FEBHeader to fill basic parameters histogram : event type, event size, nb of sweet cells...
203 auto slmon = Monitored::Scalar<int>("slotnb",-1);
204 auto ftmon = Monitored::Scalar<int>("FTnb",-1);
205 auto sw1 = Monitored::Scalar<int>("weightsweet1",-1);
206 auto sw2 = Monitored::Scalar<int>("weightsweet2",-1);
207 auto slmis = Monitored::Scalar<int>("slotmist",-1);
208 auto ftmis = Monitored::Scalar<int>("FTmist",-1);
209 for ( ; it!=it_e;++it) {
210 HWIdentifier febid=(*it)->FEBId();
211
212 if (febid.get_identifier32().get_compact() >= 0x38000000 && febid.get_identifier32().get_compact() <= 0x3bc60000 && !(febid.get_identifier32().get_compact() & 0xFFF)) {
213 int barrel_ec = m_onlineHelper->barrel_ec(febid);
214 int pos_neg = m_onlineHelper->pos_neg(febid);
215 int ft = m_onlineHelper->feedthrough(febid);
216 int slot = m_onlineHelper->slot(febid);
217 unsigned int partitionNb_dE = returnPartition(barrel_ec,pos_neg,ft,slot);
218 unsigned int subdet = partitionNb_dE / 2;
219
220 if (partitionNb_dE < m_partitions.size()) {
221 nfeb[partitionNb_dE]++ ;
222 }else{
223 ATH_MSG_WARNING("Unknown partition number: "<< partitionNb_dE << " not filling !");
224 continue;
225 }
226 larEventSize += (float) ((*it)->RodRawDataSize() + (*it)->RodResults1Size() + (*it)->RodResults2Size()); // This quantity is now in megabytes
227 if(partitionNb_dE<8) larEventSize_part[partitionNb_dE] += (float) ((*it)->RodRawDataSize() + (*it)->RodResults1Size() + (*it)->RodResults2Size());
228
229 // Eventype = 2 : transparent/raw data - 4 : Physic - 7 : calibration - 10 : pedestal - 14 : raw data + results
230 uint32_t eventType = (*it)->DetEventType();
231 // If physic mode && raw data != 0, we are in rawdata+results
232 if (eventType == 4 && (*it)->RodRawDataSize() != 0) eventType = 14;
233 //if (firstEventType == 999) firstEventType = eventType;
234 if (firstEventNbSp < 0)
235 if ((*it)->NbSamples() != 0)
236 firstEventNbSp=(*it)->NbSamples();
237
238
239 l1word = (*it)->LVL1TigType();
240 fill(m_monGroupName,l1word);
241
242 if (firstEventType == 4) totNbOfSweet2 = totNbOfSweet2+(*it)->NbSweetCells2();
243 // Fill (nb of evnts and sweet cells per FEB) histos
244 slmon = slot;
245 ftmon = ft;
246 sw1 = (*it)->NbSweetCells1();
247 sw2 = (*it)->NbSweetCells2();
248 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitionNb_dE])],slmon,ftmon,sw1,sw2);
249 if ((*it)->LVL1TigType() == 0 || (*it)->LVL1TigType() == 170 || (*it)->LVL1TigType() != l1Trig){
250 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitionNb_dE])],slmis,ftmis);
251 }
252 }//Test on FEBid
253 }//end of loop over FEB headers
254
255 // Loop over all febs to plot the error from statusword
256 // This is mandatory to also monitor the FEBs with missing headers
257
258 bool anyfebIE = false;
259 for (std::vector<HWIdentifier>::const_iterator allFeb = m_onlineHelper->feb_begin();
260 allFeb != m_onlineHelper->feb_end(); ++allFeb) {
261 HWIdentifier febid = HWIdentifier(*allFeb);
262 bool currentFebStatus = false;
263 uint16_t feberrorSummary = lArFebErrorSummary->feb_error(febid);
264
265 if ( feberrorSummary != 0 ){
266 int barrel_ec = m_onlineHelper->barrel_ec(febid);
267 int pos_neg = m_onlineHelper->pos_neg(febid);
268 int ft = m_onlineHelper->feedthrough(febid);
269 int slot = m_onlineHelper->slot(febid);
270 unsigned int partitionNb_dE = returnPartition(barrel_ec,pos_neg,ft,slot);
271
272 if (partitionNb_dE < m_partitions.size()) {
273 // Fill the errors in partition histograms
274 fillErrorsSummary(partitionNb_dE,ft,slot,feberrorSummary,lar_inerror, rejectionBits, currentFebStatus, eventRejected);
275 }else{
276 ATH_MSG_WARNING("Unknown partition number: "<< partitionNb_dE << " not filling !");
277 }
278
279 if (currentFebStatus && febInErrorTree.size()<33){
280 febInErrorTree.push_back(febid.get_identifier32().get_compact());
281 febErrorTypeTree.push_back(rejectionBits.to_ulong());
282 }
283 }
284 if(currentFebStatus) anyfebIE = currentFebStatus;
285 }
286
287 //Fill general data histos
288 auto evttype = Monitored::Scalar<int>("EvtType",firstEventType);
289
290 float nbOfFeb = 0.;
291 for(auto nf: nfeb) nbOfFeb+=nf;// (nfeb[0]+nfeb[1]+nfeb[2]+nfeb[3]+nfeb[4]+nfeb[5]+nfeb[6]+nfeb[7]);
292 if (firstEventType == 2 || firstEventType == 4 || firstEventType == 14) {
293 auto nbsamp = Monitored::Scalar<int>("NbOfSamp",firstEventNbSp);
294 fill(m_monGroupName, nbsamp);
295 }
296
297 bool newHighWaterMarkNFebBlocksTotal = false;
298 if(m_nbOfFebBlocksTotal < nbOfFeb){ // new number of Febs
299 if(m_nbOfFebBlocksTotal >= 0) newHighWaterMarkNFebBlocksTotal = true;
300 m_nbOfFebBlocksTotal = nbOfFeb;
301 }
302 auto nbfeb = Monitored::Scalar<int>("nbFEB",nbOfFeb);
303 fill(m_monGroupName, evttype, nbfeb);
304
305 auto part = Monitored::Scalar<int>("part",-1);
306 auto nbfebpart = Monitored::Scalar<int>("nbFEBpart",-1);
307 for(unsigned i=0; i<m_partitions.size(); ++i) {
308 part=i;
309 unsigned subdet = i / 2;
310 nbfebpart=nfeb[i];
311 fill(m_monGroupName,part,nbfebpart);
312 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[i])],nbfebpart);
313 }
314
315 // If the nb of DSP headers is lower than the maximum, this means that there are some missing FEBs, probably
316 // due to missing ROS fragment
317
318 auto evtrej = Monitored::Scalar<int>("EvtRej",-1);
319 float evt_yield=-1;
320 auto evtyield = Monitored::Scalar<float>("EvtRejYield",-1);
321 auto evtyieldout = Monitored::Scalar<float>("EvtRejYieldOut",-1);
322 if (febInErrorTree.size()>=1 || newHighWaterMarkNFebBlocksTotal || nbOfFeb < m_nbOfFebBlocksTotal ){
323 evtrej=0; evt_yield = 100.;
324 if (febInErrorTree.size()>=4) evtrej=1;
325 if (thisEvent->isEventFlagBitSet(xAOD::EventInfo::LAr,LArEventBitInfo::DATACORRUPTEDVETO)) evtyieldout=0.; // Vetoed
326 else evtyieldout=100.; // not vetoed
327 }
328 if(evtrej > -1) {
329 fill(m_monGroupName,evtrej);
330 evtrej=-1;
331 }
332
333 if (thisEvent->isEventFlagBitSet(xAOD::EventInfo::LAr,LArEventBitInfo::DATACORRUPTED) || thisEvent->isEventFlagBitSet(xAOD::EventInfo::LAr,LArEventBitInfo::DATACORRUPTEDVETO) || nbOfFeb != m_nbOfFebBlocksTotal){ // Event corrupted (>=1/4 FEBs in error)
334 evtrej=2;
335 auto rbits = Monitored::Scalar<unsigned long>("rejBits", rejectionBits.to_ulong());
336 fill(m_monGroupName, rbits, evtrej);
337
338 evt_yield = 100.;
339 if (thisEvent->isEventFlagBitSet(xAOD::EventInfo::LAr,LArEventBitInfo::DATACORRUPTEDVETO)) {
340 evtrej=4;
341 evtyieldout=0.; // Vetoed
342 } else {
343 evtrej=3;
344 evtyieldout=100.; // not vetoed
345 }
346 } else{ // The event is NOT in error. Fill per LB TProfile
347 evtrej=6; evt_yield = 0.; evtyieldout=0.;
348 }
349 evtyield=evt_yield;
350 auto evSize = Monitored::Scalar<float>("LArEvSize",larEventSize/sizeNorm);
351 auto sweet2 = Monitored::Scalar<int>("NbOfSweet2",totNbOfSweet2);
352 auto lb0 = Monitored::Scalar<int>("LB0",lumi_block); //to avoid 'NbOfEventsVSLB' being filled multiple times
353 fill(m_monGroupName,evtrej,evtyieldout,evtyield,evSize, sweet2, lb0);
354 if (thisEvent->isEventFlagBitSet(xAOD::EventInfo::LAr,LArEventBitInfo::NOISEBURSTVETO)) {
355 evtrej=5;
356 fill(m_monGroupName,evtrej);
357 }
358 evtrej=7;
359 fill(m_monGroupName,evtrej);
361 auto lbfake = Monitored::Scalar<int>("LBf",0);
362 fill(m_monGroupName,evtyield,lbfake);
363 }
364
365 if(anyfebIE) {
366 //Fill LArCorrupted tree and >=1FEB in errors
367 auto mon_febInErrorTree = Monitored::Collection("febHwId", febInErrorTree);
368 auto mon_febErrorTypeTree = Monitored::Collection("febErrorType", febErrorTypeTree);
369 auto evtonerej = Monitored::Scalar<int>("EvtOneErrorYield",100);
370 fill(m_monGroupName,mon_febInErrorTree,mon_febErrorTypeTree,eventTime,eventTime_ns,evtonerej);
371 }
372
373 // Now we could fill the event size
374 auto lb = Monitored::Scalar<int>("LB",lumi_block);
375 auto evsize=Monitored::Scalar<float>("LArEvSizePart",-1);
376 if(environment() == Environment_t::online && m_streams.size() > 0) {
377 std::vector<unsigned int> streamsThisEvent=LArMon::trigStreamMatching(m_streams,thisEvent->streamTags());
378 if(streamsThisEvent.size()==1 && streamsThisEvent[0] == m_streams.size()) streamsThisEvent[0]=m_streams.size()-1; // assuming others are last in the list of streams
379
380 auto streambin=Monitored::Scalar<float>("streamBin",-1);
381
382 unsigned ie(0);
383 for(unsigned int str=0; str<streamsThisEvent.size(); ++str) {
384 if(streamsThisEvent[str] > m_streams.size()) break;
385 if(trigok && streamsThisEvent[str] < m_streams.size() && (m_streams[streamsThisEvent[str]].find("CosmicCalo") != std::string::npos)) { // test excluding events
386 if (!getTrigDecisionTool().empty()) {
387 for(ie=0; ie<m_excoscalo.size(); ++ie) {
388 if(getTrigDecisionTool()->isPassed(m_excoscalo[ie])) break;
389 }
390 }
391 if(ie<m_excoscalo.size()) {
392 ATH_MSG_INFO("Skipping "<<m_excoscalo[ie]<<" for CosmicCalo ");
393 continue; // we should skip this trigger
394 }
395 }
396 streambin = streamsThisEvent[str];
397 evsize = larEventSize/262144;
398 fill(m_monGroupName,lb,streambin,evsize);
399
400 for(unsigned i=0; i <m_partitions.size(); ++i){
401 unsigned subdet = i / 2;
402 evsize = larEventSize_part[i]/sizeNorm;
403 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[i])],lb,streambin,evsize);
404 }
405
406 }
407 } else { // we are filling only simple profiles
408 for(unsigned i=0; i<m_partitions.size(); ++i) {
409 unsigned subdet = i / 2;
410 evsize=larEventSize_part[i]/sizeNorm;
411 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[i])],lb,evsize);
412 }
413 }
414
415
416 return StatusCode::SUCCESS;
417}
418
419
420// ********************************************************************
421void LArFEBMonAlg::fillErrorsSummary(unsigned int partitNb_2,int ft,int slot,uint16_t error, bool lar_inerror, std::bitset<13> &rejectionBits, bool &currentFebStatus, bool &eventRejected) const
422{
423
424 if (m_badFebs.count(std::make_pair(slot,ft)) != 0) return;
425
426
427 auto part = Monitored::Scalar<int>("part",partitNb_2);
428 auto ferror = Monitored::Scalar<int>("febError",-1);
429 if ( error & (1<<0) ){
430 unsigned subdet = partitNb_2 / 2;
431 auto sl = Monitored::Scalar<int>("slotPar",slot);
432 auto ftmon = Monitored::Scalar<int>("FTPar",ft);
433 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
434 currentFebStatus = true;
435 rejectionBits.set(0);
436 ferror=1;
437 fill(m_monGroupName, ferror, part);
438 }
439
440 if ( error & (1<<1) ){
441 unsigned subdet = partitNb_2 / 2;
442 auto sl = Monitored::Scalar<int>("slotBcid",slot);
443 auto ftmon = Monitored::Scalar<int>("FTBcid",ft);
444 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
445 currentFebStatus = true;
446 rejectionBits.set(1);
447 ferror=2;
448 fill(m_monGroupName, ferror, part);
449 }
450
451 if ( error & (1<<2) ){
452 unsigned subdet = partitNb_2 / 2;
453 auto sl = Monitored::Scalar<int>("slotRadd",slot);
454 auto ftmon = Monitored::Scalar<int>("FTRadd",ft);
455 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
456 currentFebStatus = true;
457 rejectionBits.set(2);
458 ferror=3;
459 fill(m_monGroupName, ferror, part);
460 }
461
462 if ( error & (1<<3) ){
463 unsigned subdet = partitNb_2 / 2;
464 auto sl = Monitored::Scalar<int>("slotEvtid",slot);
465 auto ftmon = Monitored::Scalar<int>("FTEvtid",ft);
466 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
467 currentFebStatus = true;
468 rejectionBits.set(3);
469 ferror=4;
470 fill(m_monGroupName, ferror, part);
471 }
472
473 if ( error & (1<<4) ){
474 unsigned subdet = partitNb_2 / 2;
475 auto sl = Monitored::Scalar<int>("slotScac",slot);
476 auto ftmon = Monitored::Scalar<int>("FTScac",ft);
477 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
478 currentFebStatus = true;
479 rejectionBits.set(4);
480 ferror=5;
481 fill(m_monGroupName, ferror, part);
482 }
483
484 if ( error & (1<<5) ){
485 unsigned subdet = partitNb_2 / 2;
486 auto sl = Monitored::Scalar<int>("slotscout",slot);
487 auto ftmon = Monitored::Scalar<int>("FTscout",ft);
488 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
489 currentFebStatus = true;
490 rejectionBits.set(5);
491 ferror=6;
492 fill(m_monGroupName, ferror, part);
493 }
494
495 if ( error & (1<<6) ){
496 unsigned subdet = partitNb_2 / 2;
497 auto sl = Monitored::Scalar<int>("slotgain",slot);
498 auto ftmon = Monitored::Scalar<int>("FTgain",ft);
499 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
500 currentFebStatus = true;
501 rejectionBits.set(6);
502 ferror=7;
503 fill(m_monGroupName, ferror, part);
504 }
505
506 if ( error & (1<<7) ){
507 unsigned subdet = partitNb_2 / 2;
508 auto sl = Monitored::Scalar<int>("slottype",slot);
509 auto ftmon = Monitored::Scalar<int>("FTtype",ft);
510 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
511 currentFebStatus = true;
512 rejectionBits.set(7);
513 ferror=8;
514 fill(m_monGroupName, ferror, part);
515 }
516
517 if ( error & (1<<8) ){
518 unsigned subdet = partitNb_2 / 2;
519 auto sl = Monitored::Scalar<int>("slotsmp",slot);
520 auto ftmon = Monitored::Scalar<int>("FTsmp",ft);
521 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
522 currentFebStatus = true;
523 rejectionBits.set(8);
524 ferror=9;
525 fill(m_monGroupName, ferror, part);
526 }
527
528 if ( error & (1<<9) ){
529 unsigned subdet = partitNb_2 / 2;
530 auto sl = Monitored::Scalar<int>("slotzero",slot);
531 auto ftmon = Monitored::Scalar<int>("FTzero",ft);
532 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
533 currentFebStatus = true;
534 rejectionBits.set(9);
535 ferror=10;
536 fill(m_monGroupName, ferror, part);
537 }
538
539
540 if ( error & (1<<11) ){
541 unsigned subdet = partitNb_2 / 2;
542 auto sl = Monitored::Scalar<int>("slotsum",slot);
543 auto ftmon = Monitored::Scalar<int>("FTsum",ft);
544 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
545 currentFebStatus = true;
546 rejectionBits.set(10);
547 ferror=11;
548 fill(m_monGroupName, ferror, part);
549 }
550
551 if ( error & (1<<12) ){
552 // Check whether this error can be ignored. Useful for calibration run of PS or EMB
553 if (!((m_ignoreMissingHeaderEMB && partitNb_2<2 && slot>=2) || (m_ignoreMissingHeaderPS && partitNb_2<2 && slot==1))){
554 unsigned subdet = partitNb_2 / 2;
555 auto sl = Monitored::Scalar<int>("slotmis",slot);
556 auto ftmon = Monitored::Scalar<int>("FTmis",ft);
557 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
558 currentFebStatus = true;
559 rejectionBits.set(11);
560 ferror=12;
561 fill(m_monGroupName, ferror, part);
562 }
563 }
564
565 if ( error & (1<<13) ){
566 unsigned subdet = partitNb_2 / 2;
567 auto sl = Monitored::Scalar<int>("slotgain",slot);
568 auto ftmon = Monitored::Scalar<int>("FTgain",ft);
569 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
570 currentFebStatus = true;
571 rejectionBits.set(12);
572 ferror=13;
573 fill(m_monGroupName, ferror, part);
574 }
575
576
577 unsigned subdet = partitNb_2 / 2;
578 float ferr=0.;
579 if (currentFebStatus){
580 auto sl = Monitored::Scalar<int>("slotabs",slot);
581 auto ftmon = Monitored::Scalar<int>("FTabs",ft);
582 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],sl,ftmon);
583 if (lar_inerror) {// LArinError
584 eventRejected = true;
585 if(environment() == Environment_t::online) ferr=100.;
586 } else {
587 if(environment() == Environment_t::online) ferr=50.;
588 }
589 }
591 auto lbf = Monitored::Scalar<float>("LBf",0.5);
592 auto erry = Monitored::Scalar<float>("erronl",ferr);
593 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitNb_2])],lbf,erry);
594 }
595
596 return;
597}
598
599/*---------------------------------------------------------*/
600void
602
604 const LArBadFebCont* badFebCont=(*badFebHdl);
605 if(!badFebCont) {
606 ATH_MSG_WARNING( "Do not have Misisng FEB container, no plots !!!" );
607 return;
608 }
609 m_badFebs.clear();
610 // Loop over all FEBs
611 for (std::vector<HWIdentifier>::const_iterator allFeb = m_onlineHelper->feb_begin();
612 allFeb != m_onlineHelper->feb_end(); ++allFeb) {
613 HWIdentifier febid = HWIdentifier(*allFeb);
614 const LArBadFeb febStatus = badFebCont->status(febid);
615 unsigned int binContent = 0;
616 if (febStatus.inError() || febStatus.deadReadout() || febStatus.deadAll() || febStatus.deactivatedInOKS()) binContent = 2;
617 if (febStatus.ignoreErrors() > 0) binContent = 1;
618 if (binContent != 0){
619 int barrel_ec = m_onlineHelper->barrel_ec(febid);
620 int pos_neg = m_onlineHelper->pos_neg(febid);
621 int ft = m_onlineHelper->feedthrough(febid);
622 int slot = m_onlineHelper->slot(febid);
623 unsigned int partitionNb_dE = returnPartition(barrel_ec,pos_neg,ft,slot);
624 int subdet = partitionNb_dE / 2;
625
626 m_badFebs[std::make_pair(slot,ft)] = binContent;
627 if (partitionNb_dE < m_partitions.size()) {
628 auto sl = Monitored::Scalar<int>("slotMasked",slot);
629 auto ftmon = Monitored::Scalar<int>("FTMasked",ft);
630 ATH_MSG_INFO("filling for " << partitionNb_dE << " partition, slot: " << slot << "FT: " << ft);
631 fill(m_tools[m_histoGroups.at(subdet).at(m_partitions[partitionNb_dE])],sl,ftmon);
632 }else{
633 ATH_MSG_WARNING("Unknown partition number: "<< partitionNb_dE << " not filling !");
634 }
635 }
636 }
637}
638
639
640/*---------------------------------------------------------*/
641/*
642 DEV this needs to be migrated, but so far we do not have posibility to dynamically create the histograms....
643void
644LArFEBMonAlg::fillFebInError(const summaryPartition& summ,int errorType,int barrel_ec,int pos_neg,std::string summName)
645{
646 ATH_MSG_DEBUG( "In fillFebInError" );
647
648 // TH2I* tempHisto = TH2I_LW::create(*summ.parity);
649
650 std::string hName = "/LAr/FEBMon/perPartition/FebInErrors/" + summName;
651
652 MonGroup generalGroup( this, hName.c_str(), run, ATTRIB_MANAGED);
653
654 // Loop on TH2D to find which FEB is in error
655 // parity is used to extract binning range. Ok as this is uniform along different errors
656 int nbOfFEBErrors = 0;
657
658 for (unsigned int ix=1; ix <= (summ.parity)->GetNbinsX();ix++){
659 for (unsigned int iy=1; iy <= (summ.parity)->GetNbinsY();iy++){
660 // Found a faulty FEB
661 // If more than 15 FEBs in error in a partition, ignore other FEBs (mandatory to avoid
662 // creation of 1500 histos when a run is bad!).
663 double binContent =0;
664 switch (errorType){
665 case 1:
666 binContent = (summ.parity)->GetBinContent(ix,iy);
667 break;
668 case 2:
669 binContent = (summ.BCID_2halves)->GetBinContent(ix,iy);
670 break;
671 case 3:
672 binContent = (summ.RADD_2halves)->GetBinContent(ix,iy);
673 break;
674 case 4:
675 binContent = (summ.EVTID_2halves)->GetBinContent(ix,iy);
676 break;
677 case 5:
678 binContent = (summ.SCACStatus)->GetBinContent(ix,iy);
679 break;
680 case 6:
681 binContent = (summ.scaOutOfRange)->GetBinContent(ix,iy);
682 break;
683 case 7:
684 binContent = (summ.gainMismatch)->GetBinContent(ix,iy);
685 break;
686 case 8:
687 binContent = (summ.typeMismatch)->GetBinContent(ix,iy);
688 break;
689 case 9:
690 binContent = (summ.badNbOfSamp)->GetBinContent(ix,iy);
691 break;
692 case 10:
693 binContent = (summ.zeroSamp)->GetBinContent(ix,iy);
694 break;
695 case 11:
696 binContent = (summ.checkSum)->GetBinContent(ix,iy);
697 break;
698 case 12:
699 binContent = (summ.missingHeader)->GetBinContent(ix,iy);
700 break;
701 case 13:
702 binContent = (summ.badGain)->GetBinContent(ix,iy);
703 break;
704 }
705
706 if (binContent>0 && nbOfFEBErrors < 15){
707 HWIdentifier errorFebId = m_onlineHelper->feb_Id(barrel_ec,pos_neg,iy-1,ix);
708 IdentifierHash hashId = m_onlineHelper->feb_Hash(errorFebId);
709 if (!m_bfebIE[hashId]) {
710 m_febInError[hashId] = TH1F_LW::create((m_strHelper->feb_str(errorFebId)).c_str(),(m_strHelper->feb_str(errorFebId)+"(UNRELIABLE if # of faulty FEBs>15)").c_str(),13,0.5,13.5);
711 // tempHisto->Print();
712 (m_febInError[hashId]->GetXaxis())->SetBinLabel(1,"Parity");
713 (m_febInError[hashId]->GetXaxis())->SetBinLabel(2,"BCID");
714 (m_febInError[hashId]->GetXaxis())->SetBinLabel(3,"Sample Header");
715 (m_febInError[hashId]->GetXaxis())->SetBinLabel(4,"EVTID");
716 (m_febInError[hashId]->GetXaxis())->SetBinLabel(5,"SCAC status");
717 (m_febInError[hashId]->GetXaxis())->SetBinLabel(6,"Sca out of range");
718 (m_febInError[hashId]->GetXaxis())->SetBinLabel(7,"Gain mismatch");
719 (m_febInError[hashId]->GetXaxis())->SetBinLabel(8,"Type mismatch");
720 (m_febInError[hashId]->GetXaxis())->SetBinLabel(9,"# of samples");
721 (m_febInError[hashId]->GetXaxis())->SetBinLabel(10,"Empty data block");
722 (m_febInError[hashId]->GetXaxis())->SetBinLabel(11,"Checksum / block size");
723 (m_febInError[hashId]->GetXaxis())->SetBinLabel(12,"Missing header");
724 (m_febInError[hashId]->GetXaxis())->SetBinLabel(13,"Bad gain");
725 (m_febInError[hashId]->GetYaxis())->SetTitle("Number of errors");
726
727 StatusCode sc = generalGroup.regHist(m_febInError[hashId]);
728 if (sc.isFailure()) ATH_MSG_ERROR( "Failed to register Feb histogram!" );
729 else m_bfebIE[hashId] = true;
730 }
731 m_febInError[hashId]->SetBinContent(errorType,binContent);
732 m_febInError[hashId]->SetEntries(m_eventsCounter);
733 nbOfFEBErrors++;
734 }
735 }
736 }
737
738 fillYieldHistos(summ.LArAllErrors,summ.LArAllErrorsYield);
739
740 return;
741}
742*/
743/*---------------------------------------------------------*/
744unsigned int LArFEBMonAlg::returnPartition(int be,int pn,int ft,int sl) const {
745 // partitionNb_dE = 0 : EMBC / 1 : EMBA / 2 : EMECC / 3 : EMECA / 4 : HECC / 5 : HECA / 6 : FCALC / 7 : FCALA
746 unsigned int part = be*2+pn;
747 if (be == 1){
748 // This is a HEC FEB - Dirty method as IsHECOnlineFEBId is buggy!
749 if ((ft == 3 || ft == 10 || ft == 16 || ft == 22) && (sl > 2)) part = be*2+pn + 2;
750 if (ft == 6) part = be*2 + pn + 4; // This is FCAL FEB
751 }
752 return part;
753}
754
755
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
LArBadXCont< LArBadFeb > LArBadFebCont
A LArRawConditionsContainer holding thresholds used by the DSP.
const unsigned sizeNorm
static Double_t sc
Handle class for reading a decoration on an object.
static const Attributes_t empty
const ServiceHandle< StoreGateSvc > & detStore() const
Environment_t environment() const
Accessor functions for the environment.
virtual StatusCode initialize() override
initialize
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type get_compact() const
Get the compact id.
This is a "hash" representation of an Identifier.
Identifier32 get_identifier32() const
Get the 32-bit version Identifier, will be invalid if >32 bits needed.
unsigned int ignoreErrors() const
Definition LArBadFeb.h:65
bool deadAll() const
FEB is completely missing, e.g. powered off.
Definition LArBadFeb.h:30
bool deactivatedInOKS() const
Deactivated in OKS.
Definition LArBadFeb.h:39
bool inError() const
FEB has readout errors, cannot be used.
Definition LArBadFeb.h:36
bool deadReadout() const
FEB is not sending readout data, but the L1 trigger path is working.
Definition LArBadFeb.h:33
LArBC_t status(const HWIdentifier channel) const
Query the status of a particular channel or FEB This is the main client access method.
float tQThrByHash(const IdentifierHash &h) const
float samplesThrByHash(const IdentifierHash &h) const
Gaudi::Property< std::vector< std::string > > m_partitions
Gaudi::Property< std::string > m_monGroupName
SG::ReadHandleKey< LArFebErrorSummary > m_lArFebErrorSummaryKey
SG::ReadCondHandleKey< LArBadFebCont > m_BFKey
Gaudi::Property< bool > m_ignoreMissingHeaderPS
SG::ReadCondHandleKey< AthenaAttributeList > m_run2DSPThresholdsKey
Gaudi::Property< std::vector< std::string > > m_excoscalo
SG::ReadHandleKey< LArFebHeaderContainer > m_hdrContKey
SG::ReadDecorHandleKey< xAOD::EventInfo > m_eventInfoDecorKey
virtual StatusCode initialize() override final
initialize
Gaudi::Property< bool > m_ignoreMissingHeaderEMB
std::atomic< int > m_nbOfFebBlocksTotal
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
std::vector< std::map< std::string, int > > m_histoGroups
void plotMaskedFEB() const
unsigned int returnPartition(int be, int pn, int ft, int sl) const
Gaudi::Property< std::vector< std::string > > m_streams
void fillErrorsSummary(unsigned int partitNb_2, int ft, int slot, uint16_t error, bool lar_inerror, std::bitset< 13 > &rejectionBits, bool &currentFebStatus, bool &eventRejected) const
LArFEBMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
const LArOnlineID * m_onlineHelper
Gaudi::Property< std::vector< std::string > > m_SubDetNames
SG::ReadCondHandleKey< LArDSPThresholdsComplete > m_run1DSPThresholdsKey
Declare a monitored scalar variable.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::vector< std::string > getListOfTriggers() const
@ LAr
The LAr calorimeter.
@ Error
The sub-detector issued an error.
int lb
Definition globals.cxx:23
std::vector< unsigned > trigStreamMatching(const std::vector< std::string > &streamsFromJobO, const std::vector< xAOD::EventInfo::StreamTag > &streamInEvent)
std::vector< V > buildToolMap(const ToolHandleArray< GenericMonitoringTool > &tools, const std::string &baseName, int nHist)
Builds an array of indices (base case)
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
void fill(H5::Group &out_file, size_t iterations)