CMS 3D CMS Logo

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

Generated on Tue Jun 9 17:33:38 2009 for CMSSW by  doxygen 1.5.4