CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DQMOffline/CalibTracker/plugins/SiStripFEDErrorsDQM.cc

Go to the documentation of this file.
00001 #include "SiStripFEDErrorsDQM.h"
00002 
00003 #include "CalibTracker/SiStripCommon/interface/SiStripDetInfoFileReader.h"
00004 
00005 using namespace std;
00006 using namespace edm;
00007 
00008 SiStripFEDErrorsDQM::SiStripFEDErrorsDQM(const edm::ParameterSet& iConfig) :
00009   SiStripBaseServiceFromDQM<SiStripBadStrip>::SiStripBaseServiceFromDQM(iConfig),
00010   iConfig_(iConfig),
00011   fp_(iConfig.getUntrackedParameter<edm::FileInPath>("file",edm::FileInPath("CalibTracker/SiStripCommon/data/SiStripDetInfo.dat"))),
00012   cablingCacheId_(0),
00013   threshold_(iConfig.getUntrackedParameter<double>("Threshold",0)),
00014   debug_(iConfig.getUntrackedParameter<unsigned int>("Debug",0))
00015 {
00016   obj_ = 0;
00017   edm::LogInfo("SiStripFEDErrorsDQM") <<  "[SiStripFEDErrorsDQM::SiStripFEDErrorsDQM()]";
00018 }
00019 
00020 SiStripFEDErrorsDQM::~SiStripFEDErrorsDQM() {
00021   edm::LogInfo("SiStripFEDErrorsDQM") <<  "[SiStripFEDErrorsDQM::~SiStripFEDErrorsDQM]";
00022 }
00023 
00024 // ------------ method called to for each event  ------------
00025 void SiStripFEDErrorsDQM::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00026 {
00027   //update cabling
00028   updateCabling(iSetup);
00029 
00030   if (readBadAPVs())
00031     {
00032       // Save the parameters to the db.
00033       edm::Service<cond::service::PoolDBOutputService> mydbservice;
00034       if( mydbservice.isAvailable() ){
00035         if( mydbservice->isNewTagRequest("SiStripBadStripRcd") ){
00036           mydbservice->createNewIOV<SiStripBadStrip>(obj_, mydbservice->beginOfTime(),mydbservice->endOfTime(),"SiStripBadStripRcd");
00037         } else {
00038           mydbservice->appendSinceTime<SiStripBadStrip>(obj_, mydbservice->currentTime(),"SiStripBadStripRcd");      
00039         }
00040       } else {
00041         edm::LogError("SiStripFEDErrorsDQM")<<"Service is unavailable"<<std::endl;
00042       }
00043     }
00044 
00045 }
00046 
00047 // ------------ method called once each job just before starting event loop  ------------
00048 void 
00049 SiStripFEDErrorsDQM::beginJob()
00050 {
00051 }
00052 
00053 // ------------ method called once each job just after ending the event loop  ------------
00054 void 
00055 SiStripFEDErrorsDQM::endJob() {
00056 }
00057 
00058 void SiStripFEDErrorsDQM::updateCabling(const edm::EventSetup& iSetup)
00059 {
00060   uint32_t currentCacheId = iSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
00061   if (cablingCacheId_ != currentCacheId) {
00062     edm::ESHandle<SiStripFedCabling> cablingHandle;
00063     iSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
00064     cabling_ = cablingHandle.product();
00065     cablingCacheId_ = currentCacheId;
00066   }
00067 }
00068 
00069 bool SiStripFEDErrorsDQM::readBadAPVs(){
00070 
00071   //std::cout << "[SiStripFEDErrorsDQM::readBadAPVs]" << std::endl;
00072 
00073   openRequestedFile();
00074 
00075   //std::cout << "[SiStripFEDErrorsDQM::readBadAPVs]: opened requested file" << std::endl;
00076 
00077   obj_=new SiStripBadStrip();
00078 
00079   SiStripDetInfoFileReader lReader(fp_.fullPath());
00080 
00081   std::ostringstream lPath;
00082   lPath << "Run " << getRunNumber() << "/SiStrip/Run summary/ReadoutView/";
00083 
00084   dqmStore_->setCurrentFolder(lPath.str());
00085   LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Now in " << dqmStore_->pwd() << std::endl;
00086 
00087   std::string lBaseDir = dqmStore_->pwd();
00088 
00089   std::vector<std::pair<std::string,unsigned int> > lFedsFolder;
00090   //for FED errors, use summary folder and fedId=0
00091   //do not put a slash or "goToDir" won't work...
00092   lFedsFolder.push_back(std::pair<std::string,unsigned int>("FedMonitoringSummary",0));
00093 
00094   //for FE/channel/APV errors, they are written in a folder per FED, 
00095   //if there was at least one error.
00096   //So just loop on folders and see which ones exist.
00097   for (unsigned int ifed(FEDNumbering::MINSiStripFEDID); 
00098        ifed<= FEDNumbering::MAXSiStripFEDID;
00099        ifed++){//loop on FEDs
00100 
00101     std::ostringstream lFedDir;
00102     lFedDir << "FrontEndDriver" << ifed;
00103     if (!goToDir(lFedDir.str())) continue;
00104     //if (!dqmStore_->dirExists(lFedDir.str())) continue;
00105     else {
00106       if (debug_) LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] - Errors detected for FED " << ifed << std::endl;
00107       lFedsFolder.push_back(std::pair<std::string,unsigned int>(lFedDir.str(),ifed));
00108     }
00109     dqmStore_->goUp();
00110   }
00111 
00112   unsigned int nAPVsTotal = 0;
00113   //retrieve total number of APVs valid and connected from cabling:
00114   if (!cabling_) {
00115     edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] cabling not filled, return false " << std::endl;
00116     return false;
00117   }
00118   const std::vector<uint16_t>& lFedVec = cabling_->feds();
00119   for (unsigned int iFed(0);iFed<lFedVec.size();iFed++){
00120     if (lFedVec.at(iFed) < sistrip::FED_ID_MIN || lFedVec.at(iFed) > sistrip::FED_ID_MAX) {
00121       edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Invalid fedid : " << lFedVec.at(iFed) << std::endl;
00122       continue;
00123     }
00124     const std::vector<FedChannelConnection>& lConnVec = cabling_->connections(lFedVec.at(iFed));
00125     for (unsigned int iConn(0); iConn<lConnVec.size();iConn++){
00126       const FedChannelConnection & lConnection = lConnVec.at(iConn);
00127       if (!lConnection.isConnected()) continue;
00128       unsigned int lDetid = lConnection.detId();
00129       if (!lDetid || lDetid == sistrip::invalid32_) continue;
00130       //2 APVs per channel....
00131       nAPVsTotal += 2;
00132     }
00133   }
00134 
00135   edm::LogInfo("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Total number of APVs found : " << nAPVsTotal << std::endl;
00136 
00137   unsigned int nAPVsWithErrorTotal = 0;
00138   unsigned int nFolders = 0;
00139   float lNorm = 0;
00140 
00141   
00142   for( std::vector<std::pair<std::string,unsigned int> >::const_iterator iFolder = lFedsFolder.begin(); 
00143        iFolder != lFedsFolder.end(); 
00144        ++iFolder ) {//loop on lFedsFolders
00145     std::string lDirName = lBaseDir + "/" + (*iFolder).first;
00146     unsigned int lFedId = (*iFolder).second;
00147     
00148     if (!goToDir((*iFolder).first)) continue;
00149 
00150     std::vector<MonitorElement *> lMeVec = dqmStore_->getContents(lDirName);
00151     
00152     if (nFolders == 0) {
00153       
00154       for( std::vector<MonitorElement *>::const_iterator iMe = lMeVec.begin(); 
00155            iMe != lMeVec.end(); 
00156            ++iMe ) {//loop on ME found in directory
00157       
00158         std::string lMeName = (*iMe)->getName() ;
00159         if (lMeName.find("nFEDErrors") != lMeName.npos){
00160           lNorm = (*iMe)->getEntries();
00161         }
00162       }
00163       //if norm histo has not been found, no point in continuing....
00164       if (lNorm < 1) {
00165         edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] nFEDErrors not found, norm is " << lNorm << std::endl;
00166         return false;
00167       }
00168     }
00169 
00170     unsigned int nAPVsWithError = 0;
00171         
00172     for( std::vector<MonitorElement *>::const_iterator iMe = lMeVec.begin(); 
00173          iMe != lMeVec.end(); 
00174          ++iMe ) {//loop on ME found in directory
00175       
00176       if ((*iMe)->getEntries() == 0) continue;
00177       std::string lMeName = (*iMe)->getName() ;
00178       
00179       bool lookForErrors = false;
00180       if (nFolders == 0) {
00181         //for the first element of lFedsFolder: this is FED errors
00182         lookForErrors = 
00183           lMeName.find("DataMissing") != lMeName.npos ||
00184           lMeName.find("AnyFEDErrors") != lMeName.npos || 
00185           (lMeName.find("CorruptBuffer") != lMeName.npos && 
00186            lMeName.find("nFED") == lMeName.npos);
00187       }
00188       else {
00189         //for the others, it is channel or FE errors.
00190         lookForErrors = 
00191           lMeName.find("APVAddressError") != lMeName.npos ||
00192           lMeName.find("APVError") != lMeName.npos ||
00193           lMeName.find("BadMajorityAddresses") != lMeName.npos ||
00194           lMeName.find("FEMissing") != lMeName.npos ||
00195           lMeName.find("OOSBits") != lMeName.npos ||
00196           lMeName.find("UnlockedBits") != lMeName.npos;
00197       }
00198 
00199       if (lookForErrors) readHistogram(*iMe,nAPVsWithError,lNorm,lFedId);
00200 
00201     }//loop on ME found in directory
00202 
00203     nAPVsWithErrorTotal += nAPVsWithError;      
00204     ++nFolders;
00205 
00206     dqmStore_->goUp();
00207 
00208   }//loop on lFedsFolders
00209 
00210   edm::LogInfo("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readBadAPVs] Total APVs with error found above threshold = " << nAPVsWithErrorTotal << std::endl;
00211 
00212   dqmStore_->cd();
00213 
00214   addErrors();
00215 
00216   return true;
00217 }//method
00218 
00219 void SiStripFEDErrorsDQM::readHistogram(MonitorElement* aMe,
00220                                         unsigned int & aCounter, 
00221                                         const float aNorm,
00222                                         const unsigned int aFedId)
00223 {
00224   unsigned short lFlag = 0;
00225   std::string lMeName = aMe->getName();
00226   if (lMeName.find("DataMissing") != lMeName.npos) {
00227     lFlag = 0;
00228   }
00229   else if (lMeName.find("AnyFEDErrors") != lMeName.npos) {
00230     lFlag = 1;
00231   }
00232   else if (lMeName.find("CorruptBuffer") != lMeName.npos && 
00233            lMeName.find("nFED") == lMeName.npos) {
00234     lFlag = 2;
00235   }
00236   else if (lMeName.find("FEMissing") != lMeName.npos) {
00237     lFlag = 3;
00238   }
00239   else if (lMeName.find("BadMajorityAddresses") != lMeName.npos) {
00240     lFlag = 4;
00241   }
00242   else if (lMeName.find("UnlockedBits") != lMeName.npos) {
00243     lFlag = 5;
00244   }
00245   else if (lMeName.find("OOSBits") != lMeName.npos) {
00246     lFlag = 6;
00247   }
00248   else if (lMeName.find("APVAddressError") != lMeName.npos) {
00249     lFlag = 7;
00250   }
00251   else if (lMeName.find("APVError") != lMeName.npos) {
00252     lFlag = 8;
00253   }
00254   else {
00255     edm::LogError("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] Shouldn't be here ..." << std::endl;
00256     return;
00257   }
00258 
00259   if (debug_) {
00260     LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] Reading histo : " << lMeName << ", flag = " << lFlag << std::endl;
00261   }
00262 
00263   unsigned int lNBins = aMe->getNbinsX();
00264   int lBinShift = 0;
00265   bool lIsFedHist = false;
00266   bool lIsAPVHist = false;
00267   bool lIsFeHist = false;
00268   bool lIsChHist = false;
00269 
00270   if (lNBins > 200) {
00271     lBinShift = FEDNumbering::MINSiStripFEDID-1;//shift for FED ID from bin number
00272     lIsFedHist = true;
00273   }
00274   else {
00275     lBinShift = -1;//shift for channel/APV/FE id from bin number
00276     if (lNBins > 100) lIsAPVHist = true;
00277     else if (lNBins < 10) lIsFeHist = true;
00278     else lIsChHist = true;
00279   }
00280 
00281   if (debug_) { 
00282     LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] lIsFedHist: " << lIsFedHist << std::endl
00283                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsAPVHist: " << lIsAPVHist << std::endl
00284                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsFeHist : " << lIsFeHist << std::endl
00285                                     << "[SiStripFEDErrorsDQM::readHistogramError] lIsChHist : " << lIsChHist << std::endl;
00286   }
00287 
00288   for (unsigned int ibin(1); ibin<lNBins+1; ibin++){
00289     if (aMe->getBinContent(ibin)>0){
00290       float lStat = aMe->getBinContent(ibin)*1./aNorm;
00291       if (lStat <= threshold_) {
00292         if (debug_) LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::readHistogramError] ---- Below threshold : " << lStat << std::endl;
00293         continue;
00294       }
00295       if (lIsFedHist) {
00296         unsigned int lFedId = ibin+lBinShift;
00297         //loop on all enabled channels of this FED....
00298         for (unsigned int iChId = 0; 
00299              iChId < sistrip::FEDCH_PER_FED; 
00300              iChId++) {//loop on channels
00301           const FedChannelConnection & lConnection = cabling_->connection(lFedId,iChId);
00302           if (!lConnection.isConnected()) continue;
00303           addBadAPV(lConnection,0,lFlag,aCounter);
00304         }
00305       }
00306       else {
00307         if(lIsFeHist) {
00308           unsigned int iFeId = ibin+lBinShift;
00309           //loop on all enabled channels of this FE....
00310           for (unsigned int iFeCh = 0; 
00311              iFeCh < sistrip::FEDCH_PER_FEUNIT; 
00312              iFeCh++) {//loop on channels
00313             unsigned int iChId = sistrip::FEDCH_PER_FEUNIT*iFeId+iFeCh;
00314             const FedChannelConnection & lConnection = cabling_->connection(aFedId,iChId);
00315             if (!lConnection.isConnected()) continue;
00316             addBadAPV(lConnection,0,lFlag,aCounter);
00317           }
00318         }
00319         else {
00320           unsigned int iChId = ibin+lBinShift;
00321           if (lIsAPVHist) {
00322             unsigned int iAPVid = iChId%2+1;
00323             iChId = static_cast<unsigned int>(iChId/2.);
00324             const FedChannelConnection & lConnection = cabling_->connection(aFedId,iChId);
00325             addBadAPV(lConnection,iAPVid,lFlag,aCounter);
00326 
00327           }//ifAPVhists
00328           else {
00329             const FedChannelConnection & lConnection = cabling_->connection(aFedId,iChId);
00330             addBadAPV(lConnection,0,lFlag,aCounter);
00331           }
00332         }//if not FE hist
00333       }//if not FED hist
00334     }//if entries in histo
00335   }//loop on bins
00336 }//method readHistogram
00337 
00338 void SiStripFEDErrorsDQM::addBadAPV(const FedChannelConnection & aConnection,
00339                                     const unsigned short aAPVNumber,
00340                                     const unsigned short aFlag,
00341                                     unsigned int & aCounter)
00342 {
00343   if (!aConnection.isConnected()) {
00344     edm::LogWarning("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadAPV] Warning, incompatible cabling ! Channel is not connected, but entry found in histo ... " << std::endl;
00345     return;
00346   }
00347   unsigned int lDetid = aConnection.detId();
00348   if (!lDetid || lDetid == sistrip::invalid32_) {
00349     edm::LogWarning("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadAPV] Warning, DetId is invalid: " << lDetid << std::endl;
00350     return;
00351   }
00352   //unsigned short nChInModule = aConnection.nApvPairs();
00353   unsigned short lApvNum = 0;
00354   if (aAPVNumber < 2) {
00355     lApvNum = 2*aConnection.apvPairNumber();
00356     addBadStrips(aConnection,lDetid,lApvNum,aFlag,aCounter);
00357   }
00358   if (aAPVNumber == 0 || aAPVNumber == 2) {
00359     lApvNum = 2*aConnection.apvPairNumber()+1;
00360     addBadStrips(aConnection,lDetid,lApvNum,aFlag,aCounter);
00361   }
00362 }
00363 
00364 
00365 void SiStripFEDErrorsDQM::addBadStrips(const FedChannelConnection & aConnection,
00366                                        const unsigned int aDetId,
00367                                        const unsigned short aApvNum,
00368                                        const unsigned short aFlag,
00369                                        unsigned int & aCounter)
00370 {
00371   // std::vector<unsigned int> lStripVector;
00372   unsigned int lBadStripRange;
00373   unsigned short lFirstBadStrip=aApvNum*128;
00374   unsigned short lConsecutiveBadStrips=128;
00375 
00376   lBadStripRange = obj_->encode(lFirstBadStrip,lConsecutiveBadStrips,aFlag);
00377 
00378   LogTrace("SiStripFEDErrorsDQM") << "[SiStripFEDErrorsDQM::addBadStrips] ---- Adding : detid " << aDetId
00379                                   << " (FED " << aConnection.fedId() 
00380                                   << ", Ch " << aConnection.fedCh () << ")"
00381                                   << ", APV " << aApvNum
00382                                   << ", flag " << aFlag
00383                                   << std::endl;
00384 
00385   detIdErrors_[aDetId].push_back(lBadStripRange);
00386 
00387   // lStripVector.push_back(lBadStripRange);
00388   // SiStripBadStrip::Range lRange(lStripVector.begin(),lStripVector.end());
00389   // if ( !obj_->put(aDetId,lRange) ) {
00390   //   edm::LogError("SiStripFEDErrorsDQM")<<"[SiStripFEDErrorsDQM::addBadStrips] detid already exists." << std::endl;
00391   // }
00392   
00393   aCounter++;
00394 }
00395 
00396 void SiStripFEDErrorsDQM::addErrors()
00397 {
00398   for( std::map<uint32_t, std::vector<uint32_t> >::const_iterator it = detIdErrors_.begin(); it != detIdErrors_.end(); ++it )
00399     {
00400 
00401       std::vector<uint32_t> lList = it->second;
00402 
00403       //map of first strip number and flag
00404       //purpose is to encode all existing flags into a unique one...
00405       std::map<unsigned short,unsigned short> lAPVMap;
00406       lAPVMap.clear();
00407 
00408       for (uint32_t iCh(0); iCh<lList.size(); iCh++) {
00409         SiStripBadStrip::data lData = obj_->decode(lList.at(iCh));
00410         unsigned short lFlag = 0;
00411         setFlagBit(lFlag,lData.flag);
00412       
00413         //std::cout << " -- Detid " << it->first << ", strip " << lData.firstStrip << ", flag " << lData.flag << std::endl;
00414 
00415         std::pair<std::map<unsigned short,unsigned short>::iterator,bool> lInsert = lAPVMap.insert(std::pair<unsigned short,unsigned short>(lData.firstStrip,lFlag));
00416         if (!lInsert.second) {
00417           //std::cout << " ---- Adding bit : " << lData.flag << " to " << lInsert.first->second << ": ";
00418           setFlagBit(lInsert.first->second,lData.flag);
00419           //std::cout << lInsert.first->second << std::endl;
00420         }
00421       }
00422 
00423       //encode the new flag
00424       std::vector<unsigned int> lStripVector;
00425       unsigned short lConsecutiveBadStrips=128;
00426 
00427       for (std::map<unsigned short,unsigned short>::iterator lIter = lAPVMap.begin();
00428            lIter != lAPVMap.end(); 
00429            lIter++)
00430         {
00431           lStripVector.push_back(obj_->encode(lIter->first,lConsecutiveBadStrips,lIter->second));
00432         }
00433 
00434       SiStripBadStrip::Range lRange(lStripVector.begin(),lStripVector.end());
00435       if ( !obj_->put(it->first,lRange) ) {
00436         edm::LogError("SiStripFEDErrorsDQM")<<"[SiStripFEDErrorsDQM::addBadStrips] detid already exists." << std::endl;
00437       }
00438     }
00439 }
00440 
00441 void SiStripFEDErrorsDQM::setFlagBit(unsigned short & aFlag, const unsigned short aBit)
00442 {
00443 
00444   aFlag = aFlag | (0x1 << aBit) ;
00445 
00446 
00447 }
00448 
00449 
00450 
00451 
00452 //define this as a plug-in
00453 // DEFINE_FWK_MODULE(SiStripFEDErrorsDQM);
00454 
00455