CMS 3D CMS Logo

SiStripFEDMonitor.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: DQM/SiStripMonitorHardware
4 // Class: SiStripFEDMonitorPlugin
5 //
10 //
11 // Original Author: Nicholas Cripps
12 // Created: 2008/09/16
13 //
14 //Modified : Anne-Marie Magnan
15 // ---- 2009/04/21 : histogram management put in separate class
16 // struct helper to simplify arguments of functions
17 // ---- 2009/04/22 : add TkHistoMap with % of bad channels per module
18 // ---- 2009/04/27 : create FEDErrors class
19 
20 #include <sstream>
21 #include <memory>
22 #include <list>
23 #include <algorithm>
24 #include <cassert>
25 
37 
44 
47 
49 
50 #include "DQM/SiStripMonitorHardware/interface/FEDHistograms.hh"
51 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
52 
54 
56 
57 //
58 // Class declaration
59 //
60 
62 {
63  public:
65  ~SiStripFEDMonitorPlugin() override;
66  private:
67  void analyze(const edm::Event&, const edm::EventSetup&) override;
68  void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
69  const edm::EventSetup& context) override;
70  void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
71  const edm::EventSetup& context) override;
72  void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override;
73 
74  //update the cabling if necessary
75  void updateCabling(const edm::EventSetup& eventSetup);
76 
77  static bool pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
78  const std::pair<unsigned int, unsigned int> & pair2);
79 
80  void getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
81  unsigned int & aMajorityCounter,
82  std::vector<unsigned int> & afedIds);
83 
84  //tag of FEDRawData collection
88 
89  //histogram helper class
90  FEDHistograms fedHists_;
91  //folder name for histograms in DQMStore
94  //book detailed histograms even if they will be empty (for merging)
96  //do histos vs time with time=event number. Default time = orbit number (s)
98  //print debug messages when problems are found: 1=error debug, 2=light debug, 3=full debug
99  unsigned int printDebug_;
100  //FED cabling
101  uint32_t cablingCacheId_;
103 
104  //add parameter to save computing time if TkHistoMap/Median/FeMajCheck are not enabled
108 
109  unsigned int nEvt_;
110 
111  //FED errors
112  //need class member for lumi histograms
113  FEDErrors fedErrors_;
114  unsigned int maxFedBufferSize_;
115 
117 };
118 
119 
120 //
121 // Constructors and destructor
122 //
123 
125  : rawDataTag_(iConfig.getUntrackedParameter<edm::InputTag>("RawDataTag",edm::InputTag("source",""))),
126  topFolderName_(iConfig.getUntrackedParameter<std::string>("TopFolderName","SiStrip")),
127  fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms",false)),
128  fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber",false)),
129  printDebug_(iConfig.getUntrackedParameter<unsigned int>("PrintDebugMessages",1)),
130  cablingCacheId_(0),
132  fullDebugMode_(iConfig.getUntrackedParameter<bool>("FullDebugMode",false))
133 {
134  std::string subFolderName = iConfig.getUntrackedParameter<std::string>("HistogramFolderName","ReadoutView");
135  folderName_ = topFolderName_ + "/" + subFolderName;
136 
137 
138  rawDataToken_ = consumes<FEDRawDataCollection>(rawDataTag_);
139  heToken_ = consumes<EventWithHistory>(edm::InputTag("consecutiveHEs") );
140 
141  //print config to debug log
142  std::ostringstream debugStream;
143  if (printDebug_>1) {
144  debugStream << "[SiStripFEDMonitorPlugin]Configuration for SiStripFEDMonitorPlugin: " << std::endl
145  << "[SiStripFEDMonitorPlugin]\tRawDataTag: " << rawDataTag_ << std::endl
146  << "[SiStripFEDMonitorPlugin]\tHistogramFolderName: " << folderName_ << std::endl
147  << "[SiStripFEDMonitorPlugin]\tFillAllDetailedHistograms? " << (fillAllDetailedHistograms_ ? "yes" : "no") << std::endl
148  << "[SiStripFEDMonitorPlugin]\tFillWithEventNumber?" << (fillWithEvtNum_ ? "yes" : "no") << std::endl
149  << "[SiStripFEDMonitorPlugin]\tPrintDebugMessages? " << (printDebug_ ? "yes" : "no") << std::endl;
150  }
151 
152  //don;t generate debug mesages if debug is disabled
153  std::ostringstream* pDebugStream = (printDebug_>1 ? &debugStream : nullptr);
154 
155  fedHists_.initialise(iConfig,pDebugStream);
156 
157  doTkHistoMap_ = fedHists_.tkHistoMapEnabled();
158 
159  doMedHists_ = fedHists_.cmHistosEnabled();
160 
161  doFEMajorityCheck_ = fedHists_.feMajHistosEnabled();
162 
163  if (printDebug_) {
164  LogTrace("SiStripMonitorHardware") << debugStream.str();
165  }
166 
167  nEvt_ = 0;
168 }
169 
171 {
172 }
173 
174 
175 //
176 // Member functions
177 //
178 
179 // ------------ method called to for each event ------------
180 void
182  const edm::EventSetup& iSetup)
183 {
184  //Retrieve tracker topology from geometry
185  edm::ESHandle<TrackerTopology> tTopoHandle;
186  iSetup.get<TrackerTopologyRcd>().get(tTopoHandle);
187  const TrackerTopology* const tTopo = tTopoHandle.product();
188 
189  //update cabling
190  updateCabling(iSetup);
191 
192  //get raw data
193  edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
194  iEvent.getByToken(rawDataToken_,rawDataCollectionHandle);
195  const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
196 
197  fedErrors_.initialiseEvent();
198 
199  //add the deltaBX value if the product exist
200 
202  iEvent.getByToken(heToken_,he);
203 
204  if(he.isValid() && !he.failedToGet()) {
205  fedErrors_.fillEventProperties(he->deltaBX());
206  }
207 
208  //initialise map of fedId/bad channel number
209  std::map<unsigned int,std::pair<unsigned short,unsigned short> > badChannelFraction;
210 
211  unsigned int lNFEDMonitoring = 0;
212  unsigned int lNFEDUnpacker = 0;
213  unsigned int lNChannelMonitoring = 0;
214  unsigned int lNChannelUnpacker = 0;
215 
216  unsigned int lNTotBadFeds = 0;
217  unsigned int lNTotBadChannels = 0;
218  unsigned int lNTotBadActiveChannels = 0;
219 
220  std::vector<std::vector<std::pair<unsigned int,unsigned int> > > lFeMajFrac;
221  const unsigned int nParts = 4;
222  if (doFEMajorityCheck_){
223  lFeMajFrac.resize(nParts);
224  //max nFE per partition
225  lFeMajFrac[0].reserve(912);
226  lFeMajFrac[1].reserve(1080);
227  lFeMajFrac[2].reserve(768);
228  lFeMajFrac[3].reserve(760);
229  }
230 
231  maxFedBufferSize_ = 0;
232 
233  //loop over siStrip FED IDs
234  for (unsigned int fedId = FEDNumbering::MINSiStripFEDID;
236  fedId++) {//loop over FED IDs
237  unsigned int lNBadChannels_perFEDID = 0;
238  const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
239 
240  //create an object to fill all errors
241  fedErrors_.initialiseFED(fedId,cabling_,tTopo);
242 
243  double aLumiSection = iEvent.orbitNumber()/262144.0;
244 
245  //Do detailed check
246  //first check if data exists
247  bool lDataExist = fedErrors_.checkDataPresent(fedData);
248  if (!lDataExist) {
249  fedHists_.fillFEDHistograms(fedErrors_,0,fullDebugMode_,aLumiSection, lNBadChannels_perFEDID);
250  continue;
251  }
252 
253 
254 
255  //check for problems and fill detailed histograms
256  fedErrors_.fillFEDErrors(fedData,
258  printDebug_,
259  lNChannelMonitoring,
260  lNChannelUnpacker,
261  doMedHists_,
262  fedHists_.cmHistPointer(false),
263  fedHists_.cmHistPointer(true),
265  lFeMajFrac
266  );
267 
268  //check filled in previous method.
269  bool lFailUnpackerFEDcheck = fedErrors_.failUnpackerFEDCheck();
270 
271  fedErrors_.incrementFEDCounters();
272  unsigned int lSize = fedData.size();
273  if (lSize > maxFedBufferSize_){
274  maxFedBufferSize_ = lSize;
275  }
276  //std::cout << " -- " << fedId << " " << lSize << std::endl;
277 
278  //fedHists_.fillFEDHistograms(fedErrors_,lSize,fullDebugMode_);
279 
280  bool lFailMonitoringFEDcheck = fedErrors_.failMonitoringFEDCheck();
281  if (lFailMonitoringFEDcheck) lNTotBadFeds++;
282 
283 
284  //sanity check: if something changed in the unpacking code
285  //but wasn't propagated here
286  //print only the summary, and more info if printDebug>1
287  if (lFailMonitoringFEDcheck != lFailUnpackerFEDcheck) {
288  if (printDebug_>1) {
289  std::ostringstream debugStream;
290  debugStream << " --- WARNING: FED " << fedId << std::endl
291  << " ------ Monitoring FED check " ;
292  if (lFailMonitoringFEDcheck) debugStream << "failed." << std::endl;
293  else debugStream << "passed." << std::endl ;
294  debugStream << " ------ Unpacker FED check " ;
295  if (lFailUnpackerFEDcheck) debugStream << "failed." << std::endl;
296  else debugStream << "passed." << std::endl ;
297  edm::LogError("SiStripMonitorHardware") << debugStream.str();
298  }
299 
300  if (lFailMonitoringFEDcheck) lNFEDMonitoring++;
301  else if (lFailUnpackerFEDcheck) lNFEDUnpacker++;
302  }
303 
304 
305  //Fill TkHistoMap:
306  //add an entry for all channels (good = 0),
307  //so that tkHistoMap knows which channels should be there.
308  if (doTkHistoMap_ && !fedHists_.tkHistoMapPointer()) {
309  edm::LogWarning("SiStripMonitorHardware") << " -- Fedid " << fedId
310  << ", TkHistoMap enabled but pointer is null." << std::endl;
311  }
312 
313  fedErrors_.fillBadChannelList(doTkHistoMap_,
314  fedHists_.tkHistoMapPointer(),
315  fedHists_.getFedvsAPVpointer(),
316  lNTotBadChannels,
317  lNTotBadActiveChannels,
318  lNBadChannels_perFEDID
319  );
320  fedHists_.fillFEDHistograms(fedErrors_,lSize,fullDebugMode_,aLumiSection, lNBadChannels_perFEDID);
321  }//loop over FED IDs
322 
323 
324  if (doFEMajorityCheck_){
325  for (unsigned int iP(0); iP<nParts; ++iP){
326  //std::cout << " -- Partition " << iP << std::endl;
327  //std::cout << " --- Number of elements in vec = " << lFeMajFrac[iP].size() << std::endl;
328  if (lFeMajFrac[iP].empty()) continue;
329  std::sort(lFeMajFrac[iP].begin(),lFeMajFrac[iP].end(),SiStripFEDMonitorPlugin::pairComparison);
330 
331  unsigned int lMajorityCounter = 0;
332  std::vector<unsigned int> lfedIds;
333 
334  getMajority(lFeMajFrac[iP],lMajorityCounter,lfedIds);
335  //std::cout << " -- Found " << lfedIds.size() << " unique elements not matching the majority." << std::endl;
336  fedHists_.fillMajorityHistograms(iP,static_cast<float>(lMajorityCounter)/lFeMajFrac[iP].size(),lfedIds);
337  }
338  }
339 
340  if ((lNTotBadFeds> 0 || lNTotBadChannels>0) && printDebug_>1) {
341  std::ostringstream debugStream;
342  debugStream << "[SiStripFEDMonitorPlugin] --- Total number of bad feds = "
343  << lNTotBadFeds << std::endl
344  << "[SiStripFEDMonitorPlugin] --- Total number of bad channels = "
345  << lNTotBadChannels << std::endl
346  << "[SiStripFEDMonitorPlugin] --- Total number of bad active channels = "
347  << lNTotBadActiveChannels << std::endl;
348  edm::LogInfo("SiStripMonitorHardware") << debugStream.str();
349  }
350 
351  if ((lNFEDMonitoring > 0 || lNFEDUnpacker > 0 || lNChannelMonitoring > 0 || lNChannelUnpacker > 0) && printDebug_) {
352  std::ostringstream debugStream;
353  debugStream
354  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
355  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
356  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at FED level : " << std::endl
357  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNFEDMonitoring << std::endl
358  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNFEDUnpacker << std::endl
359  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
360  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at Channel level : " << std::endl
361  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNChannelMonitoring << std::endl
362  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNChannelUnpacker << std::endl
363  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
364  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl ;
365  edm::LogError("SiStripMonitorHardware") << debugStream.str();
366 
367  }
368 
369  fedErrors_.getFEDErrorsCounters().nTotalBadChannels = lNTotBadChannels;
370  fedErrors_.getFEDErrorsCounters().nTotalBadActiveChannels = lNTotBadActiveChannels;
371 
372  //time in seconds since beginning of the run or event number
373  if (fillWithEvtNum_) {
374  // explicitely casting the event number unsigned long long to double here
375  double eventNumber = static_cast<double>(iEvent.id().event());
376  fedHists_.fillCountersHistograms(
377  fedErrors_.getFEDErrorsCounters(),
378  fedErrors_.getChannelErrorsCounters(),
380  eventNumber);
381  } else {
382  double aTime = iEvent.orbitNumber()/11223.;
383  fedHists_.fillCountersHistograms(
384  fedErrors_.getFEDErrorsCounters(),
385  fedErrors_.getChannelErrorsCounters(),
387  aTime);
388  }
389 
390  nEvt_++;
391 
392 }//analyze method
393 
394 
395 bool SiStripFEDMonitorPlugin::pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
396  const std::pair<unsigned int, unsigned int> & pair2){
397  return (pair1.second < pair2.second) ;
398 }
399 
400 void SiStripFEDMonitorPlugin::getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
401  unsigned int & aMajorityCounter,
402  std::vector<unsigned int> & afedIds) {
403 
404 
405  unsigned int lMajAddress = 0;
406  std::vector<std::pair<unsigned int,unsigned int> >::const_iterator lIter = aFeMajVec.begin();
407  unsigned int lMajAddr = (*lIter).second;
408  unsigned int lCounter = 0;
409 
410  //std::cout << " --- First element: addr = " << lMajAddr << " counter = " << lCounter << std::endl;
411  unsigned int iele=0;
412  //bool foundMaj = false;
413  for ( ; lIter != aFeMajVec.end(); ++lIter,++iele) {
414  //std::cout << " ---- Ele " << iele << " " << (*lIter).first << " " << (*lIter).second << " ref " << lMajAddr << std::endl;
415  if ((*lIter).second == lMajAddr) {
416  ++lCounter;
417  //std::cout << " ----- =ref: Counter = " << lCounter << std::endl;
418  }
419  else {
420  //std::cout << " ----- !=ref: Counter = " << lCounter << " Majority = " << aMajorityCounter << std::endl;
421  if (lCounter > aMajorityCounter) {
422  //std::cout << " ------ >Majority: " << std::endl;
423  aMajorityCounter = lCounter;
424  // AV bug here??
425  lMajAddress = lMajAddr;
426  // lMajAddress = (*lIter).second;
427  //foundMaj=true;
428  }
429  lCounter = 0;
430  lMajAddr = (*lIter).second;
431  --lIter;
432  --iele;
433  }
434  }
435  // AV Bug here? The check has to be done regardless foundMaj == false or true
436  // if (!foundMaj) {
437  if (lCounter > aMajorityCounter) {
438  //std::cout << " ------ >Majority: " << std::endl;
439  aMajorityCounter = lCounter;
440  lMajAddress = lMajAddr;
441  }
442  // }
443  //std::cout << " -- found majority value for " << aMajorityCounter << " elements out of " << aFeMajVec.size() << "." << std::endl;
444  //get list of feds with address different from majority in partition:
445  lIter = aFeMajVec.begin();
446  afedIds.reserve(135);
447  for ( ; lIter != aFeMajVec.end(); ++lIter ) {
448  if((*lIter).second != lMajAddress) {
449  afedIds.push_back((*lIter).first);
450  }
451  else {
452  lIter += aMajorityCounter-1;
453  if(lIter >= aFeMajVec.end()) {
454  std::cout << "Here it is a bug: " << aMajorityCounter << " " << aFeMajVec.size() << " " << lIter - aFeMajVec.end() << std::endl;
455  }
456  }
457  }
458  //std::cout << " -- Found " << lfedIds.size() << " elements not matching the majority." << std::endl;
459  if (!afedIds.empty()) {
460  std::sort(afedIds.begin(),afedIds.end());
461  std::vector<unsigned int>::iterator lIt = std::unique(afedIds.begin(),afedIds.end());
462  afedIds.erase(lIt,afedIds.end());
463  }
464 
465 }
466 
468 {
469  ibooker.setCurrentFolder(folderName_);
470 
471  edm::ESHandle<TkDetMap> tkDetMapHandle;
472  eSetup.get<TrackerTopologyRcd>().get(tkDetMapHandle);
473  const TkDetMap* tkDetMap = tkDetMapHandle.product();
474 
475  fedHists_.bookTopLevelHistograms(ibooker, tkDetMap);
476 
477  if (fillAllDetailedHistograms_) fedHists_.bookAllFEDHistograms(ibooker , fullDebugMode_ );
478 }
479 
480 void
482  const edm::EventSetup& context)
483 {
484 
485  fedErrors_.initialiseLumiBlock();
486 
487 }
488 
489 
490 void
492  const edm::EventSetup& context)
493 {
494  fedHists_.fillLumiHistograms(fedErrors_.getLumiErrors());
495 }
496 
497 
498 
499 
501 {
502  uint32_t currentCacheId = eventSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
503  if (cablingCacheId_ != currentCacheId) {
504  edm::ESHandle<SiStripFedCabling> cablingHandle;
505  eventSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
506  cabling_ = cablingHandle.product();
507  cablingCacheId_ = currentCacheId;
508  }
509 }
510 
511 
512 //
513 // Define as a plug-in
514 //
515 
size
Write out results.
EventNumber_t event() const
Definition: EventID.h:41
T getUntrackedParameter(std::string const &, T const &) const
edm::EDGetTokenT< FEDRawDataCollection > rawDataToken_
void beginLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &context) override
long long deltaBX(const unsigned int ev2, const unsigned int ev1) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
const SiStripFedCabling * cabling_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void analyze(const edm::Event &, const edm::EventSetup &) override
void getMajority(const std::vector< std::pair< unsigned int, unsigned int > > &aFeMajVec, unsigned int &aMajorityCounter, std::vector< unsigned int > &afedIds)
void endLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &context) override
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
int iEvent
Definition: GenABIO.cc:230
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:268
SiStripFEDMonitorPlugin(const edm::ParameterSet &)
def unique(seq, keepstr=True)
Definition: tier0.py:25
#define end
Definition: vmac.h:39
int orbitNumber() const
Definition: EventBase.h:67
bool isValid() const
Definition: HandleBase.h:74
#define LogTrace(id)
bool failedToGet() const
Definition: HandleBase.h:78
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
edm::EventID id() const
Definition: EventBase.h:60
#define begin
Definition: vmac.h:32
HLT enums.
T get() const
Definition: EventSetup.h:62
static bool pairComparison(const std::pair< unsigned int, unsigned int > &pair1, const std::pair< unsigned int, unsigned int > &pair2)
edm::EDGetTokenT< EventWithHistory > heToken_
T const * product() const
Definition: ESHandle.h:86
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
void updateCabling(const edm::EventSetup &eventSetup)
Definition: Run.h:44