1 //Dear emacs, this is -*-c++-*-
3 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
7 #include "CaloIdentifier/CaloGain.h"
8 #include "CaloIdentifier/CaloCell_SuperCell_ID.h"
9 #include "LArIdentifier/LArOnline_SuperCellID.h"
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");
18 declareProperty("UseBadChannelInfo",m_useBCInfo=true,
19 "Use bad-channel info to skip validation for some type of bad-channels and for channel-description");
21 declareProperty("CheckCompletness",m_checkCompleteness=true,
22 "Check if all FEBs of each COOL channel are present");
24 declareProperty("MsgLevelForDeviations", m_myMsgLvlProp=MSG::ERROR,
25 "Message Level for reporting deviations");
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");
32 declareProperty("PatchMissingFEBs",m_patchMissingFEBs=false,
33 "Patch missing FEBs using values from reference container.");
35 declareProperty("MaxNumberMessages",m_maxmessages=2000,
36 "Maximum number of messages to be printed");
38 declareProperty("PrintFailedPattern",m_printFailedPattern=true,
39 "Identifiy FEBs and Calib-lines with many deviating channels");
41 declareProperty("DoFebAverages",m_doFebAverages=true,
42 "Compare also FEB averages");
44 declareProperty("UseCorrChannels",m_useCorrChannel=true,
45 "True: Use separate correction COOL channel, False: Correction + data in the same channel");
49 template<class CONDITIONSCONTAINER,class REFCONTAINER>
50 LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::~LArCalibValidationAlg() {
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());
63 m_gainMap.push_back(std::string("HG"));
65 m_gainMap.push_back(std::string("HG"));
66 m_gainMap.push_back(std::string("MG"));
67 m_gainMap.push_back(std::string("LG"));
69 return StatusCode::SUCCESS;
72 template<class CONDITIONSCONTAINER, class REFCONTAINER>
73 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::stop() {
74 ATH_MSG_INFO ( "Entering LArCalibValidationAlg/"<<name() ) ;
77 const LArOnline_SuperCellID *onlHlp=nullptr;
78 ATH_CHECK( detStore()->retrieve(onlHlp, "LArOnline_SuperCellID") );
79 m_onlineHelper = dynamic_cast<const LArOnlineID_Base*>(onlHlp);
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);
85 const LArOnlineID *onlHlp=nullptr;
86 ATH_CHECK( detStore()->retrieve(onlHlp, "LArOnlineID") );
87 m_onlineHelper = dynamic_cast<const LArOnlineID_Base*>(onlHlp);
89 const CaloCell_ID *cId=nullptr;
90 ATH_CHECK( detStore()->retrieve(cId, "CaloCell_ID") );
91 m_caloId=dynamic_cast<const CaloCell_Base_ID*>(cId);
94 /// Get bad-channel tool
96 ATH_CHECK(m_bcMask.buildBitMask(m_problemsToMask,msg()));
100 const EventContext& ctx = Gaudi::Hive::currentContext();
102 const LArOnOffIdMapping* cabling=nullptr;
103 SG::ReadCondHandle<LArOnOffIdMapping> cablingHdl{m_cablingKey, ctx};
106 ATH_MSG_ERROR( "Do not have cabling !" );
107 return StatusCode::FAILURE;
110 SG::ReadCondHandle<LArCalibLineMapping> clHdl{m_CLKey, ctx};
111 const LArCalibLineMapping *clCont {*clHdl};
113 ATH_MSG_ERROR( "Do not have calib line mapping !!!" );
114 return StatusCode::FAILURE;
117 SG::ReadCondHandle<LArBadChannelCont> readHandle{m_BCKey, ctx};
118 const LArBadChannelCont *bcCont {*readHandle};
120 ATH_MSG_ERROR( "Do not have Bad chan container !!!" );
121 return StatusCode::FAILURE;
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." ) ;
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." ) ;
136 m_febFile << "barelEC side FT slot gain (coolChannel) : bad/total" <<std::endl;
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());
143 SG::ReadCondHandle<REFCONTAINER> readHandle{m_referenceKey};
144 m_reference = *readHandle;
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;
152 else { //no patching -> need only non-const container
153 m_nc_validation=NULL;
154 ATH_CHECK( detStore()->retrieve(m_validation,m_validationKey) );
156 if (m_validation==m_reference) //compare pointers
157 ATH_MSG_WARNING ( "The same container is used as reference!" ) ;
159 ATH_CHECK( preLoop() ); // Call preLoop method of derived algorithm
163 m_nFailedValidation=0;
169 if(m_isSC) maxgain=CaloGain::LARMEDIUMGAIN; else maxgain=CaloGain::LARNGAIN;
170 m_checkedIds.resize(maxgain); //For the gains
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;
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." ) ;
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!
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));
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));
207 ++m_nFailedValidation;
209 }//end loop over container
210 ATH_MSG_INFO("checked "<<m_checkedIds[igain].size()<<" channels for gain "<<igain);
211 }//end loop over gain
213 if (m_checkCompleteness) checkCoolChannelCompleteness(cabling, clCont, bcCont);
215 ATH_MSG_INFO("checked completness");
217 //call summary method
218 findFailedPatterns(cabling, clCont, bcCont);
219 StatusCode sc=summary(cabling, bcCont);
221 if (m_febFile.is_open()) m_febFile.close();
222 if (m_chanFile.is_open()) m_chanFile.close();
224 //W.L 27.4.2009: Always return sucess as athena rel >=15.1.0 apparently doesn't like recoverable in finalize
226 return StatusCode::SUCCESS;
229 template<class CONDITIONSCONTAINER,class REFCONTAINER>
230 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::preLoop() {
231 return StatusCode::SUCCESS;
235 template<class CONDITIONSCONTAINER,class REFCONTAINER>
236 StatusCode LArCalibValidationAlg<CONDITIONSCONTAINER,REFCONTAINER>::summary(const LArOnOffIdMapping */*cabling*/, const LArBadChannelCont */*bcCont*/) {
238 ATH_MSG_INFO ( "Checked " << m_nChecked << " channels from container \"" << m_validationKey
239 << "\" against container \"" << m_referenceKey.key() << "\"" ) ;
242 ATH_MSG_INFO ( "Number of channels skipped according to masking: " << m_nBad ) ;
245 ATH_MSG_ERROR ( "No reference found for " << m_nNoReference << " channels" ) ;
247 if (m_nFailedValidation)
248 msg() << m_myMsgLvl << "Found " << m_nFailedValidation << " channels with calibration deviating significantly from reference" << endmsg;
250 if (m_nNoReference==0 && m_nFailedValidation==0)
251 ATH_MSG_INFO ( "All " << m_nValidated << " Channels passed the validation criteria" ) ;
253 ATH_MSG_INFO ( "Found " << m_nValidated << " Channels that passed the validation criteria" ) ;
255 if (m_nFailedValidation || m_nNoReference)
256 return StatusCode::RECOVERABLE;
258 return StatusCode::SUCCESS;
262 template<class CONDITIONSCONTAINER, class REFCONTAINER>
263 void LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::findFailedPatterns(const LArOnOffIdMapping *cabling, const LArCalibLineMapping *clCont, const LArBadChannelCont *bcCont) {
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
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;
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);
285 ++statiPerFEB[febId].first;
287 ++statiPerFEB[febId].second;
289 //Fill channel status per calibLine
290 const std::vector<HWIdentifier>& calibIdvec=clCont->calibSlotLine(chid);
291 for (const HWIdentifier& hwid : calibIdvec) {
293 ++statiPerCalibLine[hwid].first;
295 ++statiPerCalibLine[hwid].second;
297 }//end loop over identifiers of suspicious channels
298 //Check fraction of failed channels per FEBs
299 //Reminder: second.first -> good second.second -> bad
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;
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;
324 }//end loop over gains
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);
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 << "?";
343 m_febFile << " (" << m_validation->coolChannel(febid,gain) << ")"
344 << " : " << nBad << "/" << nGood+nBad << " ";
346 for (unsigned i=0;i<unsigned(4*frac);i++)
349 m_febFile << std::endl;
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,
362 std::ostringstream output;
365 if (!isFeb) isCalib=m_onlineHelper->isCalibration(chid);
368 // output << "Gain:"<< gain << " ";
369 output << m_gainMap[gain] << " ";
373 output << "Calib Line [";
375 output << "Channel [";
376 //output << " id=0x" << std::hex << chid.get_compact() << std::dec << " ";
377 if (m_onlineHelper->barrel_ec(chid)==0)
382 // output << ",Side:";
383 if (m_onlineHelper->pos_neg(chid)==0)
388 output << ",FT:" << m_onlineHelper->feedthrough(chid)
389 << ",Sl:" << m_onlineHelper->slot(chid);
392 output << ",CC:" << m_validation->coolChannel(chid,gain);
395 output << ",Ch:" << m_onlineHelper->channel(chid);
398 //if (cabling->isOnlineConnected(chid)) {
399 if (m_onlineHelper->isFCALchannel(chid))
401 if (m_onlineHelper->isHECchannel(chid))
403 if (m_onlineHelper->isEMBchannel(chid))
405 if (m_onlineHelper->isEMECchannel(chid))
407 const Identifier id=cabling->cnvToIdentifier(chid);
408 output << ",Samp:" << m_caloId->sampling(id);
409 //Could add Eta, phi....
410 //}//end if is connected
412 // output << ",disconnected";
414 catch (LArID_Exception&) {}
415 }//end if !isCalibration
419 if (!isFeb && !isCalib && m_useBCInfo)
420 if (!(bcCont->status(chid).good()))
421 output << " BC [0x" << std::hex << bcCont->status(chid).packedData()<<"]" << std::dec;
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....");
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
456 ATH_MSG_ERROR ( "Found incomplete COOL channel! " << channelDescription(febId,cabling, bcCont, gain,true) << " missing!" ) ;
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]<<" ";
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);
473 if( m_isSC && (! m_onlineHelper->is_slar(chanId)) ) {
474 ATH_MSG_WARNING("Not a SC identifier, skipping ! ");
477 try { const HWIdentifier chanIdd(chanId.get_identifier32().get_compact());chanIdd.show();}
479 ATH_MSG_WARNING("Something wrong with this id, skipping ! ");
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()<<" ";
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));
498 }//End loop over FEBs in subset
500 }//End loop over subsets in container
502 ATH_MSG_INFO("missing.size(): "<<missing.size()<<" missingCBs.size(): "<<missingCBs.size());
505 retVal=patchMissingFEBs(missing,cabling,bcCont);
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;
517 ATH_MSG_INFO ( "All Cool channel completly filled (" << multiChanColl->size() << " subsets)" ) ;
519 ATH_MSG_ERROR ( "Not all COOL channnels completely filled" ) ;
521 if (missingCBs.size()) retVal1 = patchMissingCalibBoards(missingCBs,cabling,bcCont);
523 ATH_MSG_INFO ( "All missing CalibBoards completly filled " ) ;
525 ATH_MSG_ERROR ( "Not all CalibBoards completely filled" ) ;
527 ATH_MSG_INFO("checkCoolChannelCompleteness done....");
528 return retVal && retVal1;
532 template<class CONDITIONSCONTAINER, class REFCONTAINER>
533 bool LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::patchMissingFEBs(const FEBANDGAIN_t& febAndGain, const LArOnOffIdMapping *cabling, const LArBadChannelCont *bcCont) {
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);
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);
548 //Loop over all channels of this FEB and insert corrections for it
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." ) ;
558 }//end if isConnected
561 StatusCode sc=m_nc_validation->insertCorrection(chid,obj,gain,m_useCorrChannel);
562 if (sc.isFailure()) {
564 ATH_MSG_ERROR ( "Failed to insert correction for channel " << ch << " of missing " << channelDescription(febId,cabling, bcCont, gain,true) ) ;
567 ATH_MSG_DEBUG ( "Copied channel " << ch << " of missing " << channelDescription(febId,cabling, bcCont,gain,true)
568 << " from reference container" ) ;
572 }//end loop over channels of feb
574 ATH_MSG_INFO ( "Sucessfully patched " << channelDescription(febId,cabling,bcCont,gain,true) << " using values from the reference container." ) ;
576 ATH_MSG_ERROR ( "Failed to patch all channels of FEB" << channelDescription(febId,cabling,bcCont,gain,true) ) ;
578 }//end loop over all pairs of missing febid and gain
583 return false; //Looks like this FEB isn't in the reference container either.
586 template<class CONDITIONSCONTAINER, class REFCONTAINER>
587 bool LArCalibValidationAlg<CONDITIONSCONTAINER, REFCONTAINER>::patchMissingCalibBoards(const CBANDCHANANDGAIN_t& CBAndGain, const LArOnOffIdMapping *cabling, const LArBadChannelCont *bcCont) {
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;
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);
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." ) ;
609 }//end if isConnected
612 StatusCode sc=m_nc_validation->insertCorrection(ourChannel,obj,gain,m_useCorrChannel);
613 if (sc.isFailure()) {
615 ATH_MSG_ERROR ( "Failed to insert correction for channel " << chan << " of FEB " << channelDescription(febId,cabling,bcCont,gain,true) ) ;
617 ATH_MSG_DEBUG ( "Copied channel " << chan << " of FEB " << channelDescription(febId,cabling,bcCont,gain,true)
618 << " from reference container" ) ;
623 }//end loop over febid and gain and channels
626 ATH_MSG_INFO ( "Sucessfully patched all " << nGood << " channels by using values from the reference container." ) ;
628 ATH_MSG_ERROR ( "Failed to patch all asked channels, only " << nGood << " channels patched") ;
631 return nGood>0; //Do we have good patched channels ?