ATLAS Offline Software
LArCalibValidationAlg.icc
Go to the documentation of this file.
1 //Dear emacs, this is -*-c++-*-
2 /*
3  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
4 */
5 
6 
7 #include "CaloIdentifier/CaloGain.h"
8 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
9 #include "LArIdentifier/LArOnline_SuperCellID.h"
10 
11 template<class CONDITIONSCONTAINER, class REFCONTAINER>
12 LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::LArCalibValidationAlg (const std::string& name, ISvcLocator* pSvcLocator) :
13  AthAlgorithm(name,pSvcLocator),
14  m_myMsgLvl(MSG::ERROR) {
15  declareProperty("ValidationKey",m_validationKey="",
16  "SG key of the LArConditionsContainer to be validated");
17 
18  declareProperty("UseBadChannelInfo",m_useBCInfo=true,
19  "Use bad-channel info to skip validation for some type of bad-channels and for channel-description");
20 
21  declareProperty("CheckCompletness",m_checkCompleteness=true,
22  "Check if all FEBs of each COOL channel are present");
23 
24  declareProperty("MsgLevelForDeviations", m_myMsgLvlProp=MSG::ERROR,
25  "Message Level for reporting deviations");
26 
27  declareProperty("ListOfDevChannels",m_chanFileName="",
28  "File name to store list of deviating channels");
29  declareProperty("ListOfDevFEBs",m_febFileName="",
30  "File name to store list of FEBs with deviating channels");
31 
32  declareProperty("PatchMissingFEBs",m_patchMissingFEBs=false,
33  "Patch missing FEBs using values from reference container.");
34 
35  declareProperty("MaxNumberMessages",m_maxmessages=2000,
36  "Maximum number of messages to be printed");
37 
38  declareProperty("PrintFailedPattern",m_printFailedPattern=true,
39  "Identifiy FEBs and Calib-lines with many deviating channels");
40 
41  declareProperty("DoFebAverages",m_doFebAverages=true,
42  "Compare also FEB averages");
43 
44  declareProperty("UseCorrChannels",m_useCorrChannel=true,
45  "True: Use separate correction COOL channel, False: Correction + data in the same channel");
46 
47 }
48 
49 template<class CONDITIONSCONTAINER,class REFCONTAINER>
50 LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::~LArCalibValidationAlg() {
51 }
52 
53 
54 template<class CONDITIONSCONTAINER,class REFCONTAINER>
55 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::initialize() {
56  m_myMsgLvl=MSG::Level(m_myMsgLvlProp);
57  if (m_patchMissingFEBs || m_patchCBs.size()) m_checkCompleteness=true;
58  ATH_CHECK(m_cablingKey.initialize());
59  ATH_CHECK(m_BCKey.initialize());
60  ATH_CHECK(m_CLKey.initialize());
61  ATH_CHECK(m_referenceKey.initialize());
62  if(m_isSC) {
63  m_gainMap.push_back(std::string("HG"));
64  } else {
65  m_gainMap.push_back(std::string("HG"));
66  m_gainMap.push_back(std::string("MG"));
67  m_gainMap.push_back(std::string("LG"));
68  }
69  return StatusCode::SUCCESS;
70 }
71 
72 template<class CONDITIONSCONTAINER, class REFCONTAINER>
73 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::stop() {
74  ATH_MSG_INFO ( "Entering LArCalibValidationAlg/"<<name() ) ;
75 
76  if(m_isSC) {
77  const LArOnline_SuperCellID *onlHlp=nullptr;
78  ATH_CHECK( detStore()->retrieve(onlHlp, "LArOnline_SuperCellID") );
79  m_onlineHelper = dynamic_cast<const LArOnlineID_Base*>(onlHlp);
80 
81  const CaloCell_SuperCell_ID *cId=nullptr;
82  ATH_CHECK( detStore()->retrieve(cId, "CaloCell_SuperCell_ID") );
83  m_caloId=dynamic_cast<const CaloCell_Base_ID*>(cId);
84  } else {
85  const LArOnlineID *onlHlp=nullptr;
86  ATH_CHECK( detStore()->retrieve(onlHlp, "LArOnlineID") );
87  m_onlineHelper = dynamic_cast<const LArOnlineID_Base*>(onlHlp);
88 
89  const CaloCell_ID *cId=nullptr;
90  ATH_CHECK( detStore()->retrieve(cId, "CaloCell_ID") );
91  m_caloId=dynamic_cast<const CaloCell_Base_ID*>(cId);
92  }
93 
94  /// Get bad-channel tool
95  if (m_useBCInfo) {
96  ATH_CHECK(m_bcMask.buildBitMask(m_problemsToMask,msg()));
97 
98  }
99 
100  const EventContext& ctx = Gaudi::Hive::currentContext();
101 
102  const LArOnOffIdMapping* cabling=nullptr;
103  SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{m_cablingKey, ctx};
104  cabling=*cablingHdl;
105  if(!cabling) {
106  ATH_MSG_ERROR( "Do not have cabling !" );
107  return StatusCode::FAILURE;
108  }
109 
110  SG::ReadCondHandle<LArCalibLineMapping> clHdl{m_CLKey, ctx};
111  const LArCalibLineMapping *clCont {*clHdl};
112  if(!clCont) {
113  ATH_MSG_ERROR( "Do not have calib line mapping !!!" );
114  return StatusCode::FAILURE;
115  }
116 
117  SG::ReadCondHandle<LArBadChannelCont> readHandle{m_BCKey, ctx};
118  const LArBadChannelCont *bcCont {*readHandle};
119  if(!bcCont) {
120  ATH_MSG_ERROR( "Do not have Bad chan container !!!" );
121  return StatusCode::FAILURE;
122  }
123 
124  /// Open files for text output
125  if (m_chanFileName.size()>0) {
126  m_chanFile.open(m_chanFileName.c_str());
127  if (!m_chanFile.is_open())
128  ATH_MSG_ERROR ( "Failed to open output file " << m_chanFileName << ". No output will be written." ) ;
129  }
130 
131  if (m_febFileName.size()>0) {
132  m_febFile.open(m_febFileName.c_str());
133  if (!m_febFile.is_open())
134  ATH_MSG_ERROR ( "Failed to open output file " << m_febFileName << ". No output will be written." ) ;
135  else
136  m_febFile << "barelEC side FT slot gain (coolChannel) : bad/total" <<std::endl;
137  }
138 
139  // For compatibility with existing configurations, look in the detector
140  // store first, then in conditions.
141  m_reference=detStore()->template tryConstRetrieve<REFCONTAINER> (m_referenceKey.key());
142  if (!m_reference) {
143  SG::ReadCondHandle<REFCONTAINER> readHandle{m_referenceKey};
144  m_reference = *readHandle;
145  }
146 
147  /// Retrieve container to be validated
148  if (m_patchMissingFEBs || m_patchCBs.size()) { //want to patch -> non-const container needed
149  ATH_CHECK( detStore()->retrieve(m_nc_validation,m_validationKey) );
150  m_validation=m_nc_validation;
151  }
152  else { //no patching -> need only non-const container
153  m_nc_validation=NULL;
154  ATH_CHECK( detStore()->retrieve(m_validation,m_validationKey) );
155  }
156  if (m_validation==m_reference) //compare pointers
157  ATH_MSG_WARNING ( "The same container is used as reference!" ) ;
158 
159  ATH_CHECK( preLoop() ); // Call preLoop method of derived algorithm
160 
161  /// Reset counters:
162  m_nChecked=0;
163  m_nFailedValidation=0;
164  m_nValidated=0;
165  m_nBad=0;
166  m_nNoReference=0;
167 
168  unsigned maxgain;
169  if(m_isSC) maxgain=CaloGain::LARMEDIUMGAIN; else maxgain=CaloGain::LARNGAIN;
170  m_checkedIds.resize(maxgain); //For the gains
171 
172  for (unsigned igain=CaloGain::LARHIGHGAIN;
173  igain<maxgain ; ++igain ) {
174  CONTIT it=m_validation->begin(igain);
175  CONTIT it_e=m_validation->end(igain);
176  for (;it!=it_e;it++) {
177  const HWIdentifier chid = it.channelId();
178  // ignore empty or disconnected instances
179  if (it->isEmpty() || !cabling->isOnlineConnected(chid)) continue;
180  ++m_nChecked;
181 
182  if (m_useBCInfo) {
183  if (m_bcMask.cellShouldBeMasked(bcCont,chid)) {
184  ATH_MSG_DEBUG ( channelDescription(chid,cabling,bcCont,igain) << " known to be bad by bad-channel tool. Ignore." ) ;
185  ++m_nBad;
186  continue;
187  }
188  }
189  //ATH_MSG_INFO( "Working on " << channelDescription(chid,cabling,bcCont,gain) );
190  const LArCondObj& val=*it;
191  const LArCondObj ref=getRefObj(chid,igain);
192  //Check if we actually got a reference channel.
193  //If not: Consider as an error because we can't validate!
194  if (ref.isEmpty()) {
195  ATH_MSG_ERROR ( "Reference for " << channelDescription(chid,cabling,bcCont,igain) << " is empty!" ) ;
196  //Report als missing reference as 'bad' for feb-summary
197  m_checkedIds[igain].push_back(std::make_pair(chid,false));
198  ++m_nNoReference;
199  continue;
200  }
201  //Call the overloaded validation method for an individual channel
202  const bool isGood=validateChannel(ref,val,chid,igain,cabling,bcCont);
203  m_checkedIds[igain].push_back(std::make_pair(chid,isGood));
204  if (isGood)
205  ++m_nValidated;
206  else {
207  ++m_nFailedValidation;
208  }
209  }//end loop over container
210  ATH_MSG_INFO("checked "<<m_checkedIds[igain].size()<<" channels for gain "<<igain);
211  }//end loop over gain
212 
213  if (m_checkCompleteness) checkCoolChannelCompleteness(cabling, clCont, bcCont);
214 
215  ATH_MSG_INFO("checked completness");
216 
217  //call summary method
218  findFailedPatterns(cabling, clCont, bcCont);
219  StatusCode sc=summary(cabling, bcCont);
220 
221  if (m_febFile.is_open()) m_febFile.close();
222  if (m_chanFile.is_open()) m_chanFile.close();
223 
224  //W.L 27.4.2009: Always return sucess as athena rel >=15.1.0 apparently doesn't like recoverable in finalize
225  sc.ignore();
226  return StatusCode::SUCCESS;
227 }
228 
229 template<class CONDITIONSCONTAINER,class REFCONTAINER>
230 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::preLoop() {
231  return StatusCode::SUCCESS;
232 }
233 
234 
235 template<class CONDITIONSCONTAINER,class REFCONTAINER>
236 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::summary(const LArOnOffIdMapping */*cabling*/, const LArBadChannelCont */*bcCont*/) {
237 
238  ATH_MSG_INFO ( "Checked " << m_nChecked << " channels from container \"" << m_validationKey
239  << "\" against container \"" << m_referenceKey.key() << "\"" ) ;
240 
241  if (m_useBCInfo)
242  ATH_MSG_INFO ( "Number of channels skipped according to masking: " << m_nBad ) ;
243 
244  if (m_nNoReference)
245  ATH_MSG_ERROR ( "No reference found for " << m_nNoReference << " channels" ) ;
246 
247  if (m_nFailedValidation)
248  msg() << m_myMsgLvl << "Found " << m_nFailedValidation << " channels with calibration deviating significantly from reference" << endmsg;
249 
250  if (m_nNoReference==0 && m_nFailedValidation==0)
251  ATH_MSG_INFO ( "All " << m_nValidated << " Channels passed the validation criteria" ) ;
252  else
253  ATH_MSG_INFO ( "Found " << m_nValidated << " Channels that passed the validation criteria" ) ;
254 
255  if (m_nFailedValidation || m_nNoReference)
256  return StatusCode::RECOVERABLE;
257  else
258  return StatusCode::SUCCESS;
259 }
260 
261 
262 template<class CONDITIONSCONTAINER, class REFCONTAINER>
263 void LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::findFailedPatterns(const LArOnOffIdMapping *cabling, const LArCalibLineMapping *clCont, const LArBadChannelCont *bcCont) {
264  unsigned gain=0;
265  std::vector<CHECKEDID_t>::const_iterator it_gain=m_checkedIds.begin();
266  std::vector<CHECKEDID_t>::const_iterator it_gain_e=m_checkedIds.end();
267  for (;it_gain!=it_gain_e;++it_gain,++gain) {//loop over gains
268 
269  //That's the data type to keep track of the number 'good' and 'bad' channels in each FEB
270  //For each FEB (whose id is the key of map) we have a pair of numbers (the pair is the payload of the map)
271  //The first number of the pair counts the good channes in this FEB, the second one counts the bad channels
272  typedef std::map<HWIdentifier,std::pair<unsigned,unsigned> > COUNTING_t;
273  COUNTING_t statiPerFEB;
274  //The same thing for the calibration line...
275  COUNTING_t statiPerCalibLine;
276 
277  CHECKEDID_t::const_iterator it_id=it_gain->begin();
278  CHECKEDID_t::const_iterator it_id_e=it_gain->end();
279  for (;it_id!=it_id_e;++it_id) { //loop over identifiers of suspicious channels
280  const HWIdentifier chid=it_id->first;
281  const bool isGood=it_id->second;
282  //Fill channel status fer FEB
283  const HWIdentifier febId=m_onlineHelper->feb_Id(chid);
284  if (isGood)
285  ++statiPerFEB[febId].first;
286  else
287  ++statiPerFEB[febId].second;
288 
289  //Fill channel status per calibLine
290  const std::vector<HWIdentifier>& calibIdvec=clCont->calibSlotLine(chid);
291  for (const HWIdentifier& hwid : calibIdvec) {
292  if (isGood)
293  ++statiPerCalibLine[hwid].first;
294  else
295  ++statiPerCalibLine[hwid].second;
296  }
297  }//end loop over identifiers of suspicious channels
298  //Check fraction of failed channels per FEBs
299  //Reminder: second.first -> good second.second -> bad
300 
301  COUNTING_t::const_iterator itFEB=statiPerFEB.begin();
302  COUNTING_t::const_iterator itFEB_e=statiPerFEB.end();
303  for (;itFEB!=itFEB_e;++itFEB) {
304  const float badFrac=float(itFEB->second.second)/(itFEB->second.first+itFEB->second.second);
305  febOutput(itFEB->first,gain, itFEB->second.first,itFEB->second.second);
306  if (m_printFailedPattern && badFrac>0.2)
307  msg() << m_myMsgLvl << channelDescription(itFEB->first,cabling,bcCont,gain,true) << " has " << badFrac*100 << "% suspicious channels" << endmsg;
308  }
309 
310 
311  /* Commented out until apparent bug in calib-line mapping EMEC special crate is fixed
312  if (m_printFailedPattern) {
313  //Check fraction of failed channels per calibLine
314  COUNTING_t::const_iterator itCalibLine=statiPerCalibLine.begin();
315  COUNTING_t::const_iterator itCalibLine_e=statiPerCalibLine.end();
316  for (;itCalibLine!=itCalibLine_e;++itCalibLine) {
317  if (itCalibLine->second.second>=itCalibLine->second.first) {//if at least half of the readout channels belonging to a calib-line are suspicious..
318  (*m_log) << m_myMsgLvl << channelDescription(itCalibLine->first,cabling,bcCont,gain) <<": " << itCalibLine->second.second
319  << " channels out of " << itCalibLine->second.first+itCalibLine->second.second << " are suspicious." << endmsg;
320  }
321  }
322  }
323  */
324  }//end loop over gains
325  return;
326 }
327 
328 
329 template<class CONDITIONSCONTAINER, class REFCONTAINER>
330 void LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::febOutput(const HWIdentifier& febid, const unsigned gain, const unsigned nGood, const unsigned nBad){
331  const float frac=float(nBad)/(nGood+nBad);
332 
333  if (m_febFile.is_open() && nBad>0) {
334  m_febFile << m_onlineHelper->barrel_ec(febid) << " "
335  << m_onlineHelper->pos_neg(febid) << " "
336  << m_onlineHelper->feedthrough(febid) << " "
337  << m_onlineHelper->slot(febid) << " ";
338  if (gain==0) m_febFile << "H";
339  else if (gain==1) m_febFile << "M";
340  else if (gain==2) m_febFile << "L";
341  else m_febFile << "?";
342 
343  m_febFile << " (" << m_validation->coolChannel(febid,gain) << ")"
344  << " : " << nBad << "/" << nGood+nBad << " ";
345 
346  for (unsigned i=0;i<unsigned(4*frac);i++)
347  m_febFile << "*";
348 
349  m_febFile << std::endl;
350  }
351  return;
352 }
353 
354 
355 
356 template<class CONDITIONSCONTAINER, class REFCONTAINER>
357 const std::string LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::channelDescription(const HWIdentifier& chid,
358  const LArOnOffIdMapping *cabling,
359  const LArBadChannelCont *bcCont,
360  const unsigned gain,
361  bool isFeb) const {
362  std::ostringstream output;
363 
364  bool isCalib=false;
365  if (!isFeb) isCalib=m_onlineHelper->isCalibration(chid);
366 
367  if (gain<3)
368  // output << "Gain:"<< gain << " ";
369  output << m_gainMap[gain] << " ";
370  if (isFeb)
371  output << "FEB [";
372  else if (isCalib)
373  output << "Calib Line [";
374  else
375  output << "Channel [";
376  //output << " id=0x" << std::hex << chid.get_compact() << std::dec << " ";
377  if (m_onlineHelper->barrel_ec(chid)==0)
378  output << "Bar";
379  else
380  output << "End";
381 
382  // output << ",Side:";
383  if (m_onlineHelper->pos_neg(chid)==0)
384  output << ",C";
385  else
386  output << ",A";
387 
388  output << ",FT:" << m_onlineHelper->feedthrough(chid)
389  << ",Sl:" << m_onlineHelper->slot(chid);
390 
391  if (isFeb)
392  output << ",CC:" << m_validation->coolChannel(chid,gain);
393 
394  if (!isFeb) {
395  output << ",Ch:" << m_onlineHelper->channel(chid);
396  if (!isCalib) {
397  try {
398  //if (cabling->isOnlineConnected(chid)) {
399  if (m_onlineHelper->isFCALchannel(chid))
400  output << ",FCAL";
401  if (m_onlineHelper->isHECchannel(chid))
402  output << ",HEC";
403  if (m_onlineHelper->isEMBchannel(chid))
404  output << ",EMB";
405  if (m_onlineHelper->isEMECchannel(chid))
406  output << ",EMEC";
407  const Identifier id=cabling->cnvToIdentifier(chid);
408  output << ",Samp:" << m_caloId->sampling(id);
409  //Could add Eta, phi....
410  //}//end if is connected
411  //else
412  // output << ",disconnected";
413  }
414  catch (LArID_Exception&) {}
415  }//end if !isCalibration
416  }//end if !isFeb
417  output << "]";
418 
419  if (!isFeb && !isCalib && m_useBCInfo)
420  if (!(bcCont->status(chid).good()))
421  output << " BC [0x" << std::hex << bcCont->status(chid).packedData()<<"]" << std::dec;
422 
423  return output.str();
424 }
425 
426 template<class CONDITIONSCONTAINER, class REFCONTAINER>
427 bool LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::checkCoolChannelCompleteness(const LArOnOffIdMapping *cabling, const LArCalibLineMapping *clCont, const LArBadChannelCont *bcCont) {
428  ATH_MSG_INFO("checkCoolChannelCompleteness starting....");
429  bool retVal=true;
430  bool retVal1=true;
431  FEBANDGAIN_t missing; //Keep track of missing FEBs
432  CBANDCHANANDGAIN_t missingCBs; //Keep track of missing CBs
433  //typedef typename CONDITIONSCONTAINER::MultChanCollection MULTICHANCOLL;
434  typedef typename CONDITIONSCONTAINER::Subset SUBSET;
435  const MULTICHANCOLL* multiChanColl=m_validation; //Cast to base-class
436  typename MULTICHANCOLL::const_iterator it=multiChanColl->begin();
437  typename MULTICHANCOLL::const_iterator it_e=multiChanColl->end();
438  unsigned subsetIndex=0;
439  for (;it!=it_e;++it) {
440  //const SUBSET* subset=*it;
441  typename SUBSET::ConstSubsetIt febIt=(*it)->subsetBegin();
442  typename SUBSET::ConstSubsetIt febIt_e=(*it)->subsetEnd();
443  const unsigned gain=(*it)->gain();
444  for (;febIt!=febIt_e;++febIt) {
445  const HWIdentifier febId(febIt->first);
446  const typename SUBSET::ChannelVector& data=febIt->second;
447  ATH_MSG_DEBUG ( "Subset #" << subsetIndex << " " << channelDescription(febId,cabling, bcCont,gain,true) << " has " << data.size() << " channels" ) ;
448  if (data.size()==0) {
449  if (m_patchMissingFEBs) {
450  ATH_MSG_WARNING ( "Found incomplete COOL channel!"
451  << channelDescription(febId,cabling, bcCont, gain,true) << " missing! Will try to patch..." ) ;
452  missing.push_back(FEBANDGAIN_t::value_type(febId,gain)); //remember missing FEB/gain pair
453  }
454  else {
455  retVal=false;
456  ATH_MSG_ERROR ( "Found incomplete COOL channel! " << channelDescription(febId,cabling, bcCont, gain,true) << " missing!" ) ;
457  }
458  }
459 
460  if(m_patchCBs.size()) { // loop over channels, if connected to asked CBs
461  msg()<<MSG::INFO <<" m_patchCBs.size() "<<m_patchCBs.size()<<" ";
462  for(unsigned i=0; i<m_patchCBs.size();++i) msg()<<MSG::INFO <<m_patchCBs[i]<<" ";
463  msg() << endmsg;
464  int chmax=128;
465  if(m_isSC) chmax=320;
466  for(int ch=0; ch<chmax; ++ch) {
467  const HWIdentifier chanId = m_onlineHelper->channel_Id(febId,ch);
468  if(! chanId.is_valid() ) {
469  //ATH_MSG_INFO("Not valid HWIdentifier for channel "<<ch<<"of FEB "<<febId.get_identifier32().get_compact());
470  ATH_MSG_INFO("Not valid HWIdentifier for channel "<<ch);
471  continue;
472  }
473  if( m_isSC && (! m_onlineHelper->is_slar(chanId)) ) {
474  ATH_MSG_WARNING("Not a SC identifier, skipping ! ");
475  continue;
476  }
477  try { const HWIdentifier chanIdd(chanId.get_identifier32().get_compact());chanIdd.show();}
478  catch (...) {
479  ATH_MSG_WARNING("Something wrong with this id, skipping ! ");
480  continue;
481  }
482  const std::vector<HWIdentifier>& cLids=clCont->calibSlotLine(chanId);
483  msg()<<MSG::DEBUG <<" CL size: "<<cLids.size()<<": ";
484  for(unsigned cl=0; cl<cLids.size(); ++cl) msg()<<MSG::DEBUG <<cLids[cl].get_identifier32().get_compact()<<" ";
485  msg() << endmsg;
486  for(unsigned cl=0; cl<cLids.size(); ++cl) {
487  const HWIdentifier calibModuleID = m_onlineHelper->calib_module_Id(cLids[cl]);
488  if (std::find(m_patchCBs.begin(),m_patchCBs.end(),calibModuleID.get_identifier32().get_compact()) != m_patchCBs.end()) { // we should patch this channel
489  missingCBs.push_back(std::make_pair(std::make_pair(febId,gain), ch));
490  break;
491  }
492  } // over CLs
493  }// over channels
494  retVal1=false;
495  }
496 
497 
498  }//End loop over FEBs in subset
499  ++subsetIndex;
500  }//End loop over subsets in container
501 
502  ATH_MSG_INFO("missing.size(): "<<missing.size()<<" missingCBs.size(): "<<missingCBs.size());
503 
504  if (missing.size())
505  retVal=patchMissingFEBs(missing,cabling,bcCont);
506 
507  if (m_patchMissingFEBs && m_useCorrChannel) {
508  const std::vector<unsigned> completedChans = m_nc_validation->completeCorrectionChannels();
509  if (completedChans.size()>0) {
510  msg() << MSG::INFO << "Artificially inserted correction subsets in COOL channels" ;
511  for(size_t j=0;j<completedChans.size();++j)
512  msg() << MSG::INFO << " " << completedChans[j];
513  msg() << MSG::INFO << endmsg;
514  }
515  }
516  if (retVal)
517  ATH_MSG_INFO ( "All Cool channel completly filled (" << multiChanColl->size() << " subsets)" ) ;
518  else
519  ATH_MSG_ERROR ( "Not all COOL channnels completely filled" ) ;
520 
521  if (missingCBs.size()) retVal1 = patchMissingCalibBoards(missingCBs,cabling,bcCont);
522  if (retVal1)
523  ATH_MSG_INFO ( "All missing CalibBoards completly filled " ) ;
524  else
525  ATH_MSG_ERROR ( "Not all CalibBoards completely filled" ) ;
526 
527  ATH_MSG_INFO("checkCoolChannelCompleteness done....");
528  return retVal && retVal1;
529 }
530 
531 
532 template<class CONDITIONSCONTAINER, class REFCONTAINER>
533 bool LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::patchMissingFEBs(const FEBANDGAIN_t& febAndGain, const LArOnOffIdMapping *cabling, const LArBadChannelCont *bcCont) {
534  unsigned nGood=0;
535  FEBANDGAIN_t::const_iterator missingIt=febAndGain.begin();
536  FEBANDGAIN_t::const_iterator missingIt_e=febAndGain.end();
537  for (;missingIt!=missingIt_e;++missingIt) {
538  const HWIdentifier febId=missingIt->first;
539  const unsigned gain=missingIt->second;
540  const int nChan=m_onlineHelper->channelInSlotMax(febId);
541 
542  //Insert at least one (dummy) value for the missing FEB so it showes up the feb-map.
543  //Creating corrections for inexisting channels causes problems.
544  const HWIdentifier firstChannel=m_onlineHelper->channel_Id(febId,0);
545  const typename CONDITIONSCONTAINER::LArCondObj dummy;
546  m_nc_validation->setPdata(firstChannel,dummy,gain);
547 
548  //Loop over all channels of this FEB and insert corrections for it
549  int nMissing=0;
550  for (int ch=0;ch<nChan;ch++) {
551  const HWIdentifier chid=m_onlineHelper->channel_Id(febId,ch);
552  const LArCondObj obj = getRefObj(chid,gain);
553  if (obj.isEmpty()) { //Can't get reference object
554  if (cabling->isOnlineConnected(chid)) { //Don't care if not connected
555  ATH_MSG_ERROR ( "Channel " << ch << " of missing " << channelDescription(febId,cabling, bcCont, gain,true)
556  << " can't be found in reference container either." ) ;
557  ++nMissing;
558  }//end if isConnected
559  }//end if isEmpty
560  else {
561  StatusCode sc=m_nc_validation->insertCorrection(chid,obj,gain,m_useCorrChannel);
562  if (sc.isFailure()) {
563  ++nMissing;
564  ATH_MSG_ERROR ( "Failed to insert correction for channel " << ch << " of missing " << channelDescription(febId,cabling, bcCont, gain,true) ) ;
565  }
566  else {
567  ATH_MSG_DEBUG ( "Copied channel " << ch << " of missing " << channelDescription(febId,cabling, bcCont,gain,true)
568  << " from reference container" ) ;
569  }
570  ++nGood;
571  }
572  }//end loop over channels of feb
573  if (nMissing==0)
574  ATH_MSG_INFO ( "Sucessfully patched " << channelDescription(febId,cabling,bcCont,gain,true) << " using values from the reference container." ) ;
575  else
576  ATH_MSG_ERROR ( "Failed to patch all channels of FEB" << channelDescription(febId,cabling,bcCont,gain,true) ) ;
577 
578  }//end loop over all pairs of missing febid and gain
579 
580  if (nGood>0)
581  return true;
582  else
583  return false; //Looks like this FEB isn't in the reference container either.
584 }
585 
586 template<class CONDITIONSCONTAINER, class REFCONTAINER>
587 bool LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::patchMissingCalibBoards(const CBANDCHANANDGAIN_t& CBAndGain, const LArOnOffIdMapping *cabling, const LArBadChannelCont *bcCont) {
588  unsigned nGood=0;
589  unsigned nMissing=0;
590  CBANDCHANANDGAIN_t::const_iterator missingIt=CBAndGain.begin();
591  CBANDCHANANDGAIN_t::const_iterator missingIt_e=CBAndGain.end();
592  for (;missingIt!=missingIt_e;++missingIt) {
593  const HWIdentifier febId=(missingIt->first).first;
594  const unsigned gain=(missingIt->first).second;
595  const int chan=missingIt->second;
596 
597  //Insert at least one (dummy) value for the missing channel so it showes up the feb-map.
598  //Creating corrections for inexisting channels causes problems.
599  const HWIdentifier ourChannel=m_onlineHelper->channel_Id(febId,chan);
600  const typename CONDITIONSCONTAINER::LArCondObj dummy;
601  m_nc_validation->setPdata(ourChannel,dummy,gain);
602 
603  const LArCondObj obj = getRefObj(ourChannel,gain);
604  if (obj.isEmpty()) { //Can't get reference object
605  if (cabling->isOnlineConnected(ourChannel)) { //Don't care if not connected
606  ATH_MSG_ERROR ( "Channel " << chan << " of FEB " << channelDescription(febId,cabling,bcCont,gain,true)
607  << " can't be found in reference container either." ) ;
608  ++nMissing;
609  }//end if isConnected
610  }//end if isEmpty
611  else {
612  StatusCode sc=m_nc_validation->insertCorrection(ourChannel,obj,gain,m_useCorrChannel);
613  if (sc.isFailure()) {
614  ++nMissing;
615  ATH_MSG_ERROR ( "Failed to insert correction for channel " << chan << " of FEB " << channelDescription(febId,cabling,bcCont,gain,true) ) ;
616  } else {
617  ATH_MSG_DEBUG ( "Copied channel " << chan << " of FEB " << channelDescription(febId,cabling,bcCont,gain,true)
618  << " from reference container" ) ;
619  ++nGood;
620  }
621  }
622 
623  }//end loop over febid and gain and channels
624 
625  if (nMissing==0)
626  ATH_MSG_INFO ( "Sucessfully patched all " << nGood << " channels by using values from the reference container." ) ;
627  else
628  ATH_MSG_ERROR ( "Failed to patch all asked channels, only " << nGood << " channels patched") ;
629 
630 
631  return nGood>0; //Do we have good patched channels ?
632 }
633