CMS 3D CMS Logo

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