CMS 3D CMS Logo

SiStripFEDDataCheck.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: DQM/SiStripMonitorHardware
4 // Class: SiStripFEDCheckPlugin
5 //
10 //
11 // Original Author: Nicholas Cripps
12 // Created: 2008/09/16
13 //
14 //
15 #include <memory>
16 
29 
36 
39 
41 
43 
44 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
45 
47 
48 //
49 // Class declaration
50 //
51 
53 public:
55  ~SiStripFEDCheckPlugin() override;
56  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
57 
58 private:
59  void analyze(const edm::Event&, const edm::EventSetup&) override;
60  void dqmEndRun(edm::Run const&, edm::EventSetup const&) override;
61 
62  void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
63 
64  bool hasFatalError(const FEDRawData& fedData, unsigned int fedId) const;
65  bool hasNonFatalError(const FEDRawData& fedData, unsigned int fedId) const;
66  void updateCabling(const SiStripFedCablingRcd& cablingRcd);
67 
68  inline void fillPresent(unsigned int fedId, bool present);
69  inline void fillFatalError(unsigned int fedId, bool fatalError);
70  inline void fillNonFatalError(unsigned int fedId, float nonFatalError);
71 
72  void doUpdateIfNeeded();
73  void updateHistograms();
74 
79 
80  //Histograms
86 
89 
90  //For histogram cache
91  unsigned int
92  updateFrequency_; //Update histograms with cached values every n events. If zero then fill normally every event
93  //cache values
94  std::vector<unsigned int> fedsPresentBinContents_;
95  std::vector<unsigned int> fedFatalErrorBinContents_;
96  std::vector<unsigned int> fedNonFatalErrorBinContents_;
97  unsigned int eventCount_; //incremented by doUpdateIfNeeded()
98 
99  //Fine grained control of tests
101 
102  //Cabling
104 
108 
109  unsigned int siStripFedIdMin_;
110  unsigned int siStripFedIdMax_;
111 
113 };
114 
115 //
116 // Constructors and destructor
117 //
118 
120  : rawDataTag_(iConfig.getParameter<edm::InputTag>("RawDataTag")),
121  dirName_(iConfig.getUntrackedParameter<std::string>("DirName", "SiStrip/FEDIntegrity/")),
122  printDebug_(iConfig.getUntrackedParameter<bool>("PrintDebugMessages", false)),
123  doPLOTfedsPresent_(iConfig.getParameter<bool>("doPLOTfedsPresent")),
124  doPLOTfedFatalErrors_(iConfig.getParameter<bool>("doPLOTfedFatalErrors")),
125  doPLOTfedNonFatalErrors_(iConfig.getParameter<bool>("doPLOTfedNonFatalErrors")),
126  doPLOTnFEDinVsLS_(iConfig.getParameter<bool>("doPLOTnFEDinVsLS")),
127  doPLOTnFEDinWdataVsLS_(iConfig.getParameter<bool>("doPLOTnFEDinWdataVsLS")),
128  fedsPresent_(nullptr),
129  fedFatalErrors_(nullptr),
130  fedNonFatalErrors_(nullptr),
131  nFEDinVsLS_(nullptr),
132  nFEDinWdataVsLS_(nullptr),
133  updateFrequency_(iConfig.getUntrackedParameter<unsigned int>("HistogramUpdateFrequency", 0)),
134  fedsPresentBinContents_(FEDNumbering::MAXSiStripFEDID + 1, 0),
135  fedFatalErrorBinContents_(FEDNumbering::MAXSiStripFEDID + 1, 0),
136  fedNonFatalErrorBinContents_(FEDNumbering::MAXSiStripFEDID + 1, 0),
137  eventCount_(0),
138  doPayloadChecks_(iConfig.getUntrackedParameter<bool>("DoPayloadChecks", true)),
139  checkChannelLengths_(iConfig.getUntrackedParameter<bool>("CheckChannelLengths", true)),
140  checkPacketCodes_(iConfig.getUntrackedParameter<bool>("CheckChannelPacketCodes", true)),
141  checkFELengths_(iConfig.getUntrackedParameter<bool>("CheckFELengths", true)),
142  checkChannelStatusBits_(iConfig.getUntrackedParameter<bool>("CheckChannelStatus", true)),
143  verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
144  fedCablingWatcher_(this, &SiStripFEDCheckPlugin::updateCabling),
145  fedCablingToken_(esConsumes<>()),
146  tTopoToken_(esConsumes<>()) {
147  rawDataToken_ = consumes<FEDRawDataCollection>(rawDataTag_);
149  std::stringstream ss;
150  ss << "Payload checks are disabled but individual payload checks have been enabled. The following payload checks "
151  "will be skipped: ";
153  ss << "Channel length check, ";
154  if (checkPacketCodes_)
155  ss << "Channel packet code check, ";
157  ss << "Cabled channel status bits checks, ";
158  if (checkFELengths_)
159  ss << "FE Unit legnth check";
160  edm::LogWarning("SiStripFEDCheck") << ss.str();
161  }
162 
165 
166  conf_ = iConfig;
167 }
168 
170 
171 //
172 // Member functions
173 //
174 
175 // ------------ method called to for each event ------------
177  const auto tTopo = &iSetup.getData(tTopoToken_);
178  fedCablingWatcher_.check(iSetup);
179 
180  //get raw data
181  edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
182  const bool gotData = iEvent.getByToken(rawDataToken_, rawDataCollectionHandle);
183  if (verbose_)
184  std::cout << "[SiStripFEDCheckPlugin::analyze] gotData ? " << (gotData ? "YES" : "NOPE") << std::endl;
185  if (!gotData) {
186  //module is required to silently do nothing when data is not present
187  return;
188  }
189  const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
190 
191  //FED errors
192  FEDErrors lFedErrors;
193 
194  //loop over siStrip FED IDs
195  size_t nFEDin = 0;
196  size_t nFEDinWdata = 0;
197  for (unsigned int fedId = siStripFedIdMin_; fedId <= siStripFedIdMax_; fedId++) {
198  const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
199 
200  //create an object to fill all errors
201  //third param to false:save time by not initialising anything not used here
202  lFedErrors.initialiseFED(fedId, cabling_, tTopo, false);
203 
204  //check data exists
205  if (!fedData.size() || !fedData.data()) {
206  fillPresent(fedId, false);
207  continue;
208  }
209  if (verbose_)
210  std::cout << "FED " << fedId;
211  if (verbose_)
212  std::cout << " fedData.size(): " << fedData.size();
213  if (verbose_)
214  std::cout << " fedData.data(): " << fedData.data() << std::endl;
215  if (fedData.size())
216  nFEDin++;
217  if (fedData.size() && fedData.data())
218  nFEDinWdata++;
219 
220  //fill buffer present histogram
221  fillPresent(fedId, true);
222 
223  //check for fatal errors
224  //no need for debug output
225  bool hasFatalErrors = false;
226  float rateNonFatal = 0;
227 
228  std::unique_ptr<const sistrip::FEDBuffer> buffer;
229 
230  if (!lFedErrors.fillFatalFEDErrors(fedData, 0)) {
231  hasFatalErrors = true;
232  } else {
233  //need to construct full object to go any further
235  const auto st_buffer = sistrip::preconstructCheckFEDBuffer(fedData, true);
236  if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
237  throw cms::Exception("FEDBuffer") << st_buffer << " (check debug output for more details)";
238  }
239  auto tmp_buffer = std::make_unique<sistrip::FEDBuffer>(fedData, true);
240  tmp_buffer->findChannels();
241  buffer = std::move(tmp_buffer); // const now
242  if (doPayloadChecks_) {
243  bool channelLengthsOK = checkChannelLengths_ ? buffer->checkChannelLengthsMatchBufferLength() : true;
244  bool channelPacketCodesOK = checkPacketCodes_ ? buffer->checkChannelPacketCodes() : true;
245  bool feLengthsOK = checkFELengths_ ? buffer->checkFEUnitLengths() : true;
246  if (!channelLengthsOK || !channelPacketCodesOK || !feLengthsOK) {
247  hasFatalErrors = true;
248  }
249  }
251  rateNonFatal = lFedErrors.fillNonFatalFEDErrors(buffer.get(), cabling_);
252  }
253  }
254 
255  if (hasFatalErrors) {
256  fillFatalError(fedId, true);
257  if (printDebug_) {
258  if (!buffer.get()) {
259  const auto st_buffer = sistrip::preconstructCheckFEDBuffer(fedData, true);
260  if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
261  throw cms::Exception("FEDBuffer") << st_buffer << " (check debug output for more details)";
262  }
263  auto tmp_buffer = std::make_unique<sistrip::FEDBuffer>(fedData, true);
264  tmp_buffer->findChannels();
265  buffer = std::move(tmp_buffer); // const now
266  }
267  edm::LogInfo("SiStripFEDCheck") << "Fatal error with FED ID " << fedId << ". Check summary: " << std::endl
268  << buffer->checkSummary() << std::endl;
269  std::stringstream ss;
270  buffer->dump(ss);
271  edm::LogInfo("SiStripFEDCheck") << ss.str();
272  }
273  } else {
274  fillFatalError(fedId, false);
275  //fill non-fatal errors histogram if there were no fatal errors
276  fillNonFatalError(fedId, rateNonFatal);
277  if (printDebug_ && rateNonFatal > 0) {
278  if (!buffer.get()) {
279  const auto st_buffer = sistrip::preconstructCheckFEDBuffer(fedData, true);
280  if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
281  throw cms::Exception("FEDBuffer") << st_buffer << " (check debug output for more details)";
282  }
283  auto tmp_buffer = std::make_unique<sistrip::FEDBuffer>(fedData, true);
284  tmp_buffer->findChannels();
285  buffer = std::move(tmp_buffer); // const now
286  }
287  edm::LogInfo("SiStripFEDCheck") << "Non-fatal error with FED ID " << fedId << " for " << rateNonFatal
288  << " of the channels. Check summary: " << std::endl
289  << buffer->checkSummary() << std::endl;
290  std::stringstream ss;
291  buffer->dump(ss);
292  edm::LogInfo("SiStripFEDCheck") << ss.str();
293  }
294  }
295  } //loop over FED IDs
296  if (verbose_)
297  std::cout << "nFEDin: " << nFEDin << " nFEDinWdata: " << nFEDinWdata << std::endl;
298  if (doPLOTnFEDinVsLS_)
299  nFEDinVsLS_->Fill(static_cast<double>(iEvent.id().luminosityBlock()), nFEDin);
301  nFEDinWdataVsLS_->Fill(static_cast<double>(iEvent.id().luminosityBlock()), nFEDinWdata);
302 
303  //update histograms if needed
305 }
306 
307 // ------------ method called once each job just before starting event loop ------------
309  const edm::Run& run,
310  const edm::EventSetup& eSetup) {
311  size_t nFED = siStripFedIdMax_ - siStripFedIdMin_ + 1;
312  double xFEDmin = siStripFedIdMin_ - 0.5;
313  double xFEDmax = siStripFedIdMax_ + 0.5;
314 
315  //get DQM store
316  ibooker.setCurrentFolder(dirName_);
317  //book histograms
318  if (doPLOTfedsPresent_) {
319  fedsPresent_ =
320  ibooker.book1D("FEDEntries", "Number of times FED buffer is present in data", nFED, xFEDmin, xFEDmax);
321  fedsPresent_->setAxisTitle("FED-ID", 1);
322  }
323 
324  if (doPLOTfedFatalErrors_) {
325  fedFatalErrors_ = ibooker.book1D("FEDFatal", "Number of fatal errors in FED buffer", nFED, xFEDmin, xFEDmax);
326  fedFatalErrors_->setAxisTitle("FED-ID", 1);
327  }
328 
331  ibooker.book1D("FEDNonFatal", "Number of non fatal errors in FED buffer", nFED, xFEDmin, xFEDmax);
332  fedNonFatalErrors_->setAxisTitle("FED-ID", 1);
333  }
334 
335  int LSBin = conf_.getParameter<int>("LSBin");
336  double LSMin = conf_.getParameter<double>("LSMin");
337  double LSMax = conf_.getParameter<double>("LSMax");
338 
339  if (doPLOTnFEDinVsLS_) {
340  nFEDinVsLS_ =
341  ibooker.bookProfile("nFEDinVsLS", "number of FED in Vs LS", LSBin, LSMin, LSMax, nFED, xFEDmin, xFEDmax);
342  nFEDinVsLS_->setAxisTitle("LS", 1);
343  nFEDinVsLS_->setAxisTitle("FED-ID", 2);
344  }
345 
347  nFEDinWdataVsLS_ = ibooker.bookProfile(
348  "nFEDinWdataVsLS", "number of FED in (with data) Vs LS", LSBin, LSMin, LSMax, nFED, xFEDmin, xFEDmax);
349  nFEDinWdataVsLS_->setAxisTitle("LS", 1);
350  nFEDinWdataVsLS_->setAxisTitle("FED-ID", 2);
351  }
352 }
353 
354 // ------------ method called once each run just after ending the event loop ------------
356 
358  cabling_ = &cablingRcd.get(fedCablingToken_);
359 }
360 
361 void SiStripFEDCheckPlugin::fillPresent(unsigned int fedId, bool present) {
362  if (present) {
363  if (updateFrequency_)
365  else if (doPLOTfedsPresent_)
367  }
368 }
369 
370 void SiStripFEDCheckPlugin::fillFatalError(unsigned int fedId, bool fatalError) {
371  if (updateFrequency_) {
372  if (fatalError)
374  } else {
375  //fedFatalErrors_->Fill( fatalError ? 1 : 0 );
376  if (fatalError)
379  }
380 }
381 
382 void SiStripFEDCheckPlugin::fillNonFatalError(unsigned int fedId, float nonFatalError) {
383  if (updateFrequency_) {
384  if (nonFatalError > 0)
385  fedNonFatalErrorBinContents_[fedId]++; //nonFatalError;
386  } else {
387  if (nonFatalError > 0)
390  }
391 }
392 
394  eventCount_++;
397  }
398 }
399 
401  //if the cache is not being used then do nothing
402  if (!updateFrequency_)
403  return;
404  unsigned int entriesFedsPresent = 0;
405  unsigned int entriesFatalErrors = 0;
406  unsigned int entriesNonFatalErrors = 0;
407  for (unsigned int fedId = siStripFedIdMin_, bin = 1; fedId < siStripFedIdMax_ + 1; fedId++, bin++) {
408  unsigned int fedsPresentBin = fedsPresentBinContents_[fedId];
409  if (doPLOTfedsPresent_)
410  fedsPresent_->getTH1()->SetBinContent(bin, fedsPresentBin);
411  entriesFedsPresent += fedsPresentBin;
412  unsigned int fedFatalErrorsBin = fedFatalErrorBinContents_[fedId];
414  fedFatalErrors_->getTH1()->SetBinContent(bin, fedFatalErrorsBin);
415  entriesFatalErrors += fedFatalErrorsBin;
416  unsigned int fedNonFatalErrorsBin = fedNonFatalErrorBinContents_[fedId];
418  fedNonFatalErrors_->getTH1()->SetBinContent(bin, fedNonFatalErrorsBin);
419  entriesNonFatalErrors += fedNonFatalErrorsBin;
420  }
421  if (doPLOTfedsPresent_)
422  fedsPresent_->getTH1()->SetEntries(entriesFedsPresent);
424  fedFatalErrors_->getTH1()->SetEntries(entriesFatalErrors);
426  fedNonFatalErrors_->getTH1()->SetEntries(entriesNonFatalErrors);
427 }
430 
431  // Directory to book histograms in
432  desc.addUntracked<std::string>("DirName", "SiStrip/FEDIntegrity/");
433  // Raw data collection
434  desc.add<edm::InputTag>("RawDataTag", edm::InputTag("source"));
435  // Number of events to cache info before updating histograms
436  // (set to zero to disable cache)
437  // HistogramUpdateFrequency = cms.untracked.uint32(0),
438  desc.addUntracked<unsigned int>("HistogramUpdateFrequency", 1000);
439  // Print info about errors buffer dumps to LogInfo(SiStripFEDCheck)
440  desc.addUntracked<bool>("PrintDebugMessages", false);
441  desc.add<bool>("doPLOTfedsPresent", true);
442  desc.add<bool>("doPLOTfedFatalErrors", true);
443  desc.add<bool>("doPLOTfedNonFatalErrors", true);
444  desc.add<bool>("doPLOTnFEDinVsLS", false);
445  desc.add<bool>("doPLOTnFEDinWdataVsLS", false);
446  // Write the DQM store to a file (DQMStore.root) at the end of the run
447  desc.addUntracked<bool>("WriteDQMStore", false);
448  // Use to disable all payload (non-fatal) checks
449  desc.addUntracked<bool>("DoPayloadChecks", true);
450  // Use to disable check on channel lengths
451  desc.addUntracked<bool>("CheckChannelLengths", true);
452  // Use to disable check on channel packet codes
453  desc.addUntracked<bool>("CheckChannelPacketCodes", true);
454  // Use to disable check on FE unit lengths in full debug header
455  desc.addUntracked<bool>("CheckFELengths", true);
456  // Use to disable check on channel status bits
457  desc.addUntracked<bool>("CheckChannelStatus", true);
458  desc.add<int>("LSBin", 5000);
459  desc.add<double>("LSMin", 0.5);
460  desc.add<double>("LSMax", 5000.5);
461 
462  descriptions.addDefault(desc);
463 }
464 
465 //
466 // Define as a plug-in
467 //
468 
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
void dqmEndRun(edm::Run const &, edm::EventSetup const &) override
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
MonitorElement * nFEDinWdataVsLS_
example_stream int eventCount_
void fillFatalError(unsigned int fedId, bool fatalError)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tTopoToken_
edm::EDGetTokenT< FEDRawDataCollection > rawDataToken_
const SiStripFedCabling * cabling_
edm::ESGetToken< SiStripFedCabling, SiStripFedCablingRcd > fedCablingToken_
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:45
MonitorElement * fedNonFatalErrors_
void Fill(long long x)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int iEvent
Definition: GenABIO.cc:224
edm::ESWatcher< SiStripFedCablingRcd > fedCablingWatcher_
void addDefault(ParameterSetDescription const &psetDescription)
PRODUCT const & get(ESGetToken< PRODUCT, T > const &iToken) const
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
void updateCabling(const SiStripFedCablingRcd &cablingRcd)
void analyze(const edm::Event &, const edm::EventSetup &) override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool getData(T &iHolder) const
Definition: EventSetup.h:122
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
Log< level::Info, false > LogInfo
std::vector< unsigned int > fedFatalErrorBinContents_
std::vector< unsigned int > fedsPresentBinContents_
Constants and enumerated types for FED/FEC systems.
MonitorElement * nFEDinVsLS_
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
SiStripFEDCheckPlugin(const edm::ParameterSet &)
HLT enums.
bool hasFatalError(const FEDRawData &fedData, unsigned int fedId) const
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:24
MonitorElement * fedFatalErrors_
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
MonitorElement * fedsPresent_
void fillNonFatalError(unsigned int fedId, float nonFatalError)
std::vector< unsigned int > fedNonFatalErrorBinContents_
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
bool hasNonFatalError(const FEDRawData &fedData, unsigned int fedId) const
void fillPresent(unsigned int fedId, bool present)
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)