00001
00002
00003
00004
00005
00010
00011
00012
00013
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
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
00070 DQMStore* dqm_;
00071 MonitorElement* fedsPresent_;
00072 MonitorElement* fedFatalErrors_;
00073 MonitorElement* fedNonFatalErrors_;
00074
00075
00076 unsigned int updateFrequency_;
00077
00078 std::vector<unsigned int> fedsPresentBinContents_;
00079 std::vector<unsigned int> fedFatalErrorBinContents_;
00080 std::vector<unsigned int> fedNonFatalErrorBinContents_;
00081 unsigned int eventCount_;
00082
00083
00084 bool doPayloadChecks_, checkChannelLengths_, checkPacketCodes_, checkFELengths_, checkChannelStatusBits_;
00085
00086
00087 uint32_t cablingCacheId_;
00088 const SiStripFedCabling* cabling_;
00089 };
00090
00091
00092
00093
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
00131
00132
00133
00134 void
00135 SiStripFEDCheckPlugin::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00136 {
00137
00138 updateCabling(iSetup);
00139
00140
00141 edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
00142 iEvent.getByLabel(rawDataTag_,rawDataCollectionHandle);
00143 const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
00144
00145
00146 const unsigned int siStripFedIdMin = FEDNumbering::getSiStripFEDIds().first;
00147 const unsigned int siStripFedIdMax = FEDNumbering::getSiStripFEDIds().second;
00148
00149
00150 for (unsigned int fedId = siStripFedIdMin; fedId <= siStripFedIdMax; fedId++) {
00151 const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
00152
00153 if (!fedData.size() || !fedData.data()) {
00154 fillPresent(fedId,0);
00155 continue;
00156 }
00157
00158 fillPresent(fedId,1);
00159
00160 if (hasFatalError(fedData,fedId)) {
00161 fillFatalError(fedId,1);
00162 } else {
00163 fillFatalError(fedId,0);
00164
00165 fillNonFatalError(fedId,hasNonFatalError(fedData,fedId) ? 1 : 0);
00166 }
00167 }
00168
00169
00170 doUpdateIfNeeded();
00171 }
00172
00173
00174 void
00175 SiStripFEDCheckPlugin::beginJob(const edm::EventSetup&)
00176 {
00177
00178 const FEDNumbering numbering;
00179 const unsigned int siStripFedIdMin = numbering.getSiStripFEDIds().first;
00180 const unsigned int siStripFedIdMax = numbering.getSiStripFEDIds().second;
00181
00182 dqm_ = &(*edm::Service<DQMStore>());
00183 dqm_->setCurrentFolder(dirName_);
00184
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
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
00215 const sistrip::FEDBufferBase buffer(fedData.data(),fedData.size(),true);
00216
00217 if (!buffer.doDAQHeaderAndTrailerChecks()) fatalError = true;
00218
00219 if (!buffer.checkBufferFormat()) fatalError = true;
00220
00221 if (!buffer.checkCRC()) fatalError = true;
00222
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
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
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
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
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
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
00377
00378
00379 #include "FWCore/Framework/interface/MakerMacros.h"
00380 DEFINE_FWK_MODULE(SiStripFEDCheckPlugin);