CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DQM/SiStripMonitorHardware/plugins/SiStripFEDDataCheck.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    DQM/SiStripMonitorHardware
00004 // Class:      SiStripFEDCheckPlugin
00005 // 
00010 //
00011 // Original Author:  Nicholas Cripps
00012 //         Created:  2008/09/16
00013 // $Id: SiStripFEDDataCheck.cc,v 1.18 2010/09/30 15:37:19 amagnan Exp $
00014 //
00015 //
00016 #include <memory>
00017 
00018 #include "FWCore/Framework/interface/Frameworkfwd.h"
00019 #include "FWCore/Framework/interface/EDAnalyzer.h"
00020 #include "FWCore/Framework/interface/Event.h"
00021 #include "FWCore/Framework/interface/EventSetup.h"
00022 #include "FWCore/Framework/interface/ESHandle.h"
00023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00024 #include "FWCore/Utilities/interface/InputTag.h"
00025 #include "FWCore/Utilities/interface/Exception.h"
00026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00027 #include "FWCore/ServiceRegistry/interface/Service.h"
00028 
00029 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00030 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00031 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00032 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
00033 
00034 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
00035 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00036 
00037 #include "DQMServices/Core/interface/DQMStore.h"
00038 #include "DQMServices/Core/interface/MonitorElement.h"
00039 
00040 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
00041 
00042 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
00043 
00044 //
00045 // Class declaration
00046 //
00047 
00048 class SiStripFEDCheckPlugin : public edm::EDAnalyzer
00049 {
00050  public:
00051   explicit SiStripFEDCheckPlugin(const edm::ParameterSet&);
00052   ~SiStripFEDCheckPlugin();
00053  private:
00054   virtual void beginJob();
00055   virtual void analyze(const edm::Event&, const edm::EventSetup&);
00056   virtual void endJob();
00057   virtual void endRun();
00058 
00059   bool hasFatalError(const FEDRawData& fedData, unsigned int fedId) const;
00060   bool hasNonFatalError(const FEDRawData& fedData, unsigned int fedId) const;
00061   void updateCabling(const edm::EventSetup& eventSetup);
00062   
00063   inline void fillPresent(unsigned int fedId, bool present);
00064   inline void fillFatalError(unsigned int fedId, bool fatalError);
00065   inline void fillNonFatalError(unsigned int fedId, float nonFatalError);
00066   
00067   void doUpdateIfNeeded();
00068   void updateHistograms();
00069   
00070   
00071   edm::InputTag rawDataTag_;
00072   std::string dirName_;
00073   bool printDebug_;
00074   bool writeDQMStore_;
00075   
00076   //Histograms
00077   DQMStore* dqm_;
00078   MonitorElement* fedsPresent_;
00079   MonitorElement* fedFatalErrors_;
00080   MonitorElement* fedNonFatalErrors_;
00081   
00082   //For histogram cache
00083   unsigned int updateFrequency_;//Update histograms with cached values every n events. If zero then fill normally every event
00084   //cache values
00085   std::vector<unsigned int> fedsPresentBinContents_;
00086   std::vector<unsigned int> fedFatalErrorBinContents_;
00087   std::vector<unsigned int> fedNonFatalErrorBinContents_;
00088   unsigned int eventCount_;//incremented by doUpdateIfNeeded()
00089   
00090   //Fine grained control of tests
00091   bool doPayloadChecks_, checkChannelLengths_, checkPacketCodes_, checkFELengths_, checkChannelStatusBits_;
00092   
00093   //Cabling
00094   uint32_t cablingCacheId_;
00095   const SiStripFedCabling* cabling_;
00096 };
00097 
00098 
00099 //
00100 // Constructors and destructor
00101 //
00102 
00103 SiStripFEDCheckPlugin::SiStripFEDCheckPlugin(const edm::ParameterSet& iConfig)
00104   : rawDataTag_(iConfig.getParameter<edm::InputTag>("RawDataTag")),
00105     dirName_(iConfig.getUntrackedParameter<std::string>("DirName","SiStrip/FEDIntegrity/")),
00106     printDebug_(iConfig.getUntrackedParameter<bool>("PrintDebugMessages",false)),
00107     writeDQMStore_(iConfig.getUntrackedParameter<bool>("WriteDQMStore",false)),
00108     updateFrequency_(iConfig.getUntrackedParameter<unsigned int>("HistogramUpdateFrequency",0)),
00109     fedsPresentBinContents_(FEDNumbering::MAXSiStripFEDID+1,0),
00110     fedFatalErrorBinContents_(FEDNumbering::MAXSiStripFEDID+1,0),
00111     fedNonFatalErrorBinContents_(FEDNumbering::MAXSiStripFEDID+1,0),
00112     eventCount_(0),
00113     doPayloadChecks_(iConfig.getUntrackedParameter<bool>("DoPayloadChecks",true)),
00114     checkChannelLengths_(iConfig.getUntrackedParameter<bool>("CheckChannelLengths",true)),
00115     checkPacketCodes_(iConfig.getUntrackedParameter<bool>("CheckChannelPacketCodes",true)),
00116     checkFELengths_(iConfig.getUntrackedParameter<bool>("CheckFELengths",true)),
00117     checkChannelStatusBits_(iConfig.getUntrackedParameter<bool>("CheckChannelStatus",true)),
00118     cablingCacheId_(0)
00119 {
00120   if (printDebug_ && !doPayloadChecks_ && (checkChannelLengths_ || checkPacketCodes_ || checkFELengths_)) {
00121     std::stringstream ss;
00122     ss << "Payload checks are disabled but individual payload checks have been enabled. The following payload checks will be skipped: ";
00123     if (checkChannelLengths_) ss << "Channel length check, ";
00124     if (checkPacketCodes_) ss << "Channel packet code check, ";
00125     if (checkChannelStatusBits_) ss << "Cabled channel status bits checks, ";
00126     if (checkFELengths_) ss << "FE Unit legnth check";
00127     edm::LogWarning("SiStripFEDCheck") << ss.str();
00128   }
00129 }
00130 
00131 SiStripFEDCheckPlugin::~SiStripFEDCheckPlugin()
00132 {
00133 }
00134 
00135 
00136 //
00137 // Member functions
00138 //
00139 
00140 // ------------ method called to for each event  ------------
00141 void
00142 SiStripFEDCheckPlugin::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00143 {
00144   //update cabling
00145   updateCabling(iSetup);
00146   
00147   //get raw data
00148   edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
00149   const bool gotData = iEvent.getByLabel(rawDataTag_,rawDataCollectionHandle);
00150   if (!gotData) {
00151     //module is required to silently do nothing when data is not present
00152     return;
00153   }
00154   const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
00155   
00156   //get FED IDs
00157   const unsigned int siStripFedIdMin = FEDNumbering::MINSiStripFEDID;
00158   const unsigned int siStripFedIdMax = FEDNumbering::MAXSiStripFEDID;
00159   
00160   //FED errors
00161   FEDErrors lFedErrors;
00162 
00163   //loop over siStrip FED IDs
00164   for (unsigned int fedId = siStripFedIdMin; fedId <= siStripFedIdMax; fedId++) {
00165     const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
00166 
00167     //create an object to fill all errors
00168     //third param to false:save time by not initialising anything not used here
00169     lFedErrors.initialiseFED(fedId,cabling_,false);
00170 
00171 
00172     //check data exists
00173     if (!fedData.size() || !fedData.data()) {
00174       fillPresent(fedId,0);
00175       continue;
00176     }
00177     //fill buffer present histogram
00178     fillPresent(fedId,1);
00179 
00180     //check for fatal errors
00181     //no need for debug output
00182     bool hasFatalErrors = false;
00183     float rateNonFatal = 0;
00184 
00185     std::auto_ptr<const sistrip::FEDBuffer> buffer;
00186 
00187     if (!lFedErrors.fillFatalFEDErrors(fedData,0)) {
00188       hasFatalErrors = true;
00189     }
00190     else {
00191       //need to construct full object to go any further
00192       if (doPayloadChecks_ || checkChannelStatusBits_) {
00193         
00194         buffer.reset(new sistrip::FEDBuffer(fedData.data(),fedData.size(),true));
00195         if (doPayloadChecks_) {
00196 
00197           bool channelLengthsOK = checkChannelLengths_ ? buffer->checkChannelLengthsMatchBufferLength() : true;
00198           bool channelPacketCodesOK = checkPacketCodes_ ? buffer->checkChannelPacketCodes() : true;
00199           bool feLengthsOK = checkFELengths_ ? buffer->checkFEUnitLengths() : true;
00200           if ( !channelLengthsOK ||
00201                !channelPacketCodesOK ||
00202                !feLengthsOK ) {
00203             hasFatalErrors = true;
00204           }
00205         }
00206         if (checkChannelStatusBits_) rateNonFatal = lFedErrors.fillNonFatalFEDErrors(buffer.get(),cabling_);
00207       }
00208     }
00209 
00210     if (hasFatalErrors) {
00211       fillFatalError(fedId,1);
00212       if (printDebug_) {
00213         if (!buffer.get()) buffer.reset(new sistrip::FEDBuffer(fedData.data(),fedData.size(),true));
00214         edm::LogInfo("SiStripFEDCheck") << "Fatal error with FED ID " << fedId << ". Check summary: " 
00215                                         << std::endl << buffer->checkSummary() << std::endl;
00216         std::stringstream ss;
00217         buffer->dump(ss);
00218         edm::LogInfo("SiStripFEDCheck") << ss.str();
00219       }
00220     }
00221     else {
00222       fillFatalError(fedId,0);
00223       //fill non-fatal errors histogram if there were no fatal errors
00224       fillNonFatalError(fedId,rateNonFatal);
00225       if (printDebug_ && rateNonFatal > 0) {
00226         if (!buffer.get()) buffer.reset(new sistrip::FEDBuffer(fedData.data(),fedData.size(),true));
00227         edm::LogInfo("SiStripFEDCheck") << "Non-fatal error with FED ID " << fedId 
00228                                         << " for " << rateNonFatal << " of the channels. Check summary: " 
00229                                         << std::endl << buffer->checkSummary() << std::endl;
00230         std::stringstream ss;
00231         buffer->dump(ss);
00232         edm::LogInfo("SiStripFEDCheck") << ss.str();
00233       }
00234 
00235     }
00236   }//loop over FED IDs
00237   
00238   //update histograms if needed
00239   doUpdateIfNeeded();
00240 }
00241 
00242 // ------------ method called once each job just before starting event loop  ------------
00243 void 
00244 SiStripFEDCheckPlugin::beginJob()
00245 {
00246   //get FED IDs
00247   const unsigned int siStripFedIdMin = FEDNumbering::MINSiStripFEDID;
00248   const unsigned int siStripFedIdMax = FEDNumbering::MAXSiStripFEDID;
00249   //get DQM store
00250   dqm_ = &(*edm::Service<DQMStore>());
00251   dqm_->setCurrentFolder(dirName_);
00252   //book histograms
00253   fedsPresent_ = dqm_->book1D("FEDEntries",
00254                               "Number of times FED buffer is present in data",
00255                               siStripFedIdMax-siStripFedIdMin+1,
00256                               siStripFedIdMin-0.5,siStripFedIdMax+0.5);
00257   fedsPresent_->setAxisTitle("FED-ID",1);
00258   fedFatalErrors_ = dqm_->book1D("FEDFatal",
00259                               "Number of fatal errors in FED buffer",
00260                               siStripFedIdMax-siStripFedIdMin+1,
00261                               siStripFedIdMin-0.5,siStripFedIdMax+0.5);
00262   fedFatalErrors_->setAxisTitle("FED-ID",1);
00263   fedNonFatalErrors_ = dqm_->book1D("FEDNonFatal",
00264                               "Number of non fatal errors in FED buffer",
00265                               siStripFedIdMax-siStripFedIdMin+1,
00266                               siStripFedIdMin-0.5,siStripFedIdMax+0.5);
00267   fedNonFatalErrors_->setAxisTitle("FED-ID",1);
00268 }
00269 
00270 // ------------ method called once each run just after ending the event loop  ------------
00271 void 
00272 SiStripFEDCheckPlugin::endRun()
00273 {
00274   updateHistograms();
00275 }
00276 
00277 // ------------ method called once each job just after ending the event loop  ------------
00278 void 
00279 SiStripFEDCheckPlugin::endJob()
00280 {
00281   if (writeDQMStore_) dqm_->save("DQMStore.root");
00282 }
00283 
00284 
00285 void SiStripFEDCheckPlugin::updateCabling(const edm::EventSetup& eventSetup)
00286 {
00287   uint32_t currentCacheId = eventSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
00288   if (cablingCacheId_ != currentCacheId) {
00289     edm::ESHandle<SiStripFedCabling> cablingHandle;
00290     eventSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
00291     cabling_ = cablingHandle.product();
00292     cablingCacheId_ = currentCacheId;
00293   }
00294 }
00295 
00296 void SiStripFEDCheckPlugin::fillPresent(unsigned int fedId, bool present)
00297 {
00298   if (present) {
00299     if (updateFrequency_) fedsPresentBinContents_[fedId]++;
00300     else fedsPresent_->Fill(fedId);
00301   }
00302 }
00303 
00304 void SiStripFEDCheckPlugin::fillFatalError(unsigned int fedId, bool fatalError)
00305 {
00306   if (updateFrequency_) {
00307     if (fatalError) fedFatalErrorBinContents_[fedId]++;
00308   } else {
00309     //fedFatalErrors_->Fill( fatalError ? 1 : 0 );
00310     if (fatalError) fedFatalErrors_->Fill(fedId);
00311   }
00312 }
00313 
00314 void SiStripFEDCheckPlugin::fillNonFatalError(unsigned int fedId, float nonFatalError)
00315 {
00316   if (updateFrequency_) {
00317     if (nonFatalError>0) fedNonFatalErrorBinContents_[fedId]++;//nonFatalError;
00318   } else {
00319     if (nonFatalError>0) fedNonFatalErrors_->Fill(fedId);
00320   }
00321 }
00322 
00323 void SiStripFEDCheckPlugin::doUpdateIfNeeded()
00324 {
00325   eventCount_++;
00326   if (updateFrequency_ && (eventCount_%updateFrequency_ == 0)) {
00327     updateHistograms();
00328   }
00329 }
00330 
00331 void SiStripFEDCheckPlugin::updateHistograms()
00332 {
00333   //if the cache is not being used then do nothing
00334   if (!updateFrequency_) return;
00335   const unsigned int siStripFedIdMin = FEDNumbering::MINSiStripFEDID;
00336   const unsigned int siStripFedIdMax = FEDNumbering::MAXSiStripFEDID;
00337   unsigned int entriesFedsPresent = 0;
00338   unsigned int entriesFatalErrors = 0;
00339   unsigned int entriesNonFatalErrors = 0;
00340   for (unsigned int fedId = siStripFedIdMin, bin = 1; fedId < siStripFedIdMax+1; fedId++, bin++) {
00341     unsigned int fedsPresentBin = fedsPresentBinContents_[fedId];
00342     fedsPresent_->getTH1()->SetBinContent(bin,fedsPresentBin);
00343     entriesFedsPresent += fedsPresentBin;
00344     unsigned int fedFatalErrorsBin = fedFatalErrorBinContents_[fedId];
00345     fedFatalErrors_->getTH1()->SetBinContent(bin,fedFatalErrorsBin);
00346     entriesFatalErrors += fedFatalErrorsBin;
00347     unsigned int fedNonFatalErrorsBin = fedNonFatalErrorBinContents_[fedId];
00348     fedNonFatalErrors_->getTH1()->SetBinContent(bin,fedNonFatalErrorsBin);
00349     entriesNonFatalErrors += fedNonFatalErrorsBin;
00350   }
00351   fedsPresent_->getTH1()->SetEntries(entriesFedsPresent);
00352   fedFatalErrors_->getTH1()->SetEntries(entriesFatalErrors);
00353   fedNonFatalErrors_->getTH1()->SetEntries(entriesNonFatalErrors);
00354 }
00355 
00356 //
00357 // Define as a plug-in
00358 //
00359 
00360 #include "FWCore/Framework/interface/MakerMacros.h"
00361 DEFINE_FWK_MODULE(SiStripFEDCheckPlugin);