CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // $Id: SiStripFEDMonitor.cc,v 1.44 2012/06/27 16:33:59 threus Exp $
14 //
15 //Modified : Anne-Marie Magnan
16 // ---- 2009/04/21 : histogram management put in separate class
17 // struct helper to simplify arguments of functions
18 // ---- 2009/04/22 : add TkHistoMap with % of bad channels per module
19 // ---- 2009/04/27 : create FEDErrors class
20 
21 #include <sstream>
22 #include <memory>
23 #include <list>
24 #include <algorithm>
25 #include <cassert>
26 
38 
43 
46 
48 
49 #include "DQM/SiStripMonitorHardware/interface/FEDHistograms.hh"
50 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
51 
53 
54 
55 //
56 // Class declaration
57 //
58 
60 {
61  public:
64  private:
65  virtual void beginJob();
66  virtual void analyze(const edm::Event&, const edm::EventSetup&);
67  virtual void endJob();
68  virtual void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
69  const edm::EventSetup& context);
70  virtual void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
71  const edm::EventSetup& context);
72 
73  //update the cabling if necessary
74  void updateCabling(const edm::EventSetup& eventSetup);
75 
76  static bool pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
77  const std::pair<unsigned int, unsigned int> & pair2);
78 
79  void getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
80  unsigned int & aMajorityCounter,
81  std::vector<unsigned int> & afedIds);
82 
83  //tag of FEDRawData collection
85  //histogram helper class
86  FEDHistograms fedHists_;
87  //folder name for histograms in DQMStore
88  std::string folderName_;
89  //book detailed histograms even if they will be empty (for merging)
91  //do histos vs time with time=event number. Default time = orbit number (s)
93  //print debug messages when problems are found: 1=error debug, 2=light debug, 3=full debug
94  unsigned int printDebug_;
95  //bool printDebug_;
96  //write the DQMStore to a root file at the end of the job
98  std::string dqmStoreFileName_;
99  //the DQMStore
101  //FED cabling
102  uint32_t cablingCacheId_;
104 
105  //add parameter to save computing time if TkHistoMap/Median/FeMajCheck are not enabled
109 
110  unsigned int nEvt_;
111 
112  //FED errors
113  //need class member for lumi histograms
114  FEDErrors fedErrors_;
115  unsigned int maxFedBufferSize_;
116 };
117 
118 
119 //
120 // Constructors and destructor
121 //
122 
124  : rawDataTag_(iConfig.getUntrackedParameter<edm::InputTag>("RawDataTag",edm::InputTag("source",""))),
125  folderName_(iConfig.getUntrackedParameter<std::string>("HistogramFolderName","SiStrip/ReadoutView/FedSummary")),
126  fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms",false)),
127  fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber",false)),
128  printDebug_(iConfig.getUntrackedParameter<unsigned int>("PrintDebugMessages",1)),
129  //printDebug_(iConfig.getUntrackedParameter<bool>("PrintDebugMessages",false)),
130  writeDQMStore_(iConfig.getUntrackedParameter<bool>("WriteDQMStore",false)),
131  dqmStoreFileName_(iConfig.getUntrackedParameter<std::string>("DQMStoreFileName","DQMStore.root")),
132  dqm_(0),
133  cablingCacheId_(0),
134  maxFedBufferSize_(0)
135 {
136  //print config to debug log
137  std::ostringstream debugStream;
138  if (printDebug_>1) {
139  debugStream << "[SiStripFEDMonitorPlugin]Configuration for SiStripFEDMonitorPlugin: " << std::endl
140  << "[SiStripFEDMonitorPlugin]\tRawDataTag: " << rawDataTag_ << std::endl
141  << "[SiStripFEDMonitorPlugin]\tHistogramFolderName: " << folderName_ << std::endl
142  << "[SiStripFEDMonitorPlugin]\tFillAllDetailedHistograms? " << (fillAllDetailedHistograms_ ? "yes" : "no") << std::endl
143  << "[SiStripFEDMonitorPlugin]\tFillWithEventNumber?" << (fillWithEvtNum_ ? "yes" : "no") << std::endl
144  << "[SiStripFEDMonitorPlugin]\tPrintDebugMessages? " << (printDebug_ ? "yes" : "no") << std::endl
145  << "[SiStripFEDMonitorPlugin]\tWriteDQMStore? " << (writeDQMStore_ ? "yes" : "no") << std::endl;
146  if (writeDQMStore_) debugStream << "[SiStripFEDMonitorPlugin]\tDQMStoreFileName: " << dqmStoreFileName_ << std::endl;
147  }
148 
149  //don;t generate debug mesages if debug is disabled
150  std::ostringstream* pDebugStream = (printDebug_>1 ? &debugStream : NULL);
151 
152  fedHists_.initialise(iConfig,pDebugStream);
153 
154  doTkHistoMap_ = fedHists_.tkHistoMapEnabled();
155 
156  doMedHists_ = fedHists_.cmHistosEnabled();
157 
158  doFEMajorityCheck_ = fedHists_.feMajHistosEnabled();
159 
160  if (printDebug_) {
161  LogTrace("SiStripMonitorHardware") << debugStream.str();
162 
163  //debugStream.str("");
164 
165  //debugStream << " -- Quelle est la difference entre un canard ? " << std::endl
166  // << " -- Reponse: c'est qu'il a les deux pattes de la meme longueur, surtout la gauche." << std::endl;
167 
168  //edm::LogError("SiStripMonitorHardware") << debugStream.str();
169  }
170 
171  nEvt_ = 0;
172 
173 }
174 
176 {
177 }
178 
179 
180 //
181 // Member functions
182 //
183 
184 // ------------ method called to for each event ------------
185 void
187  const edm::EventSetup& iSetup)
188 {
189  //update cabling
190  updateCabling(iSetup);
191 
192  //get raw data
193  edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
194  iEvent.getByLabel(rawDataTag_,rawDataCollectionHandle);
195  const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
196 
197  fedErrors_.initialiseEvent();
198 
199  //add the deltaBX value if the product exist
200 
202  iEvent.getByLabel("consecutiveHEs",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  const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
238 
239  //create an object to fill all errors
240  fedErrors_.initialiseFED(fedId,cabling_);
241  bool lFullDebug = false;
242 
243  //Do detailed check
244  //first check if data exists
245  bool lDataExist = fedErrors_.checkDataPresent(fedData);
246  if (!lDataExist) {
247  fedHists_.fillFEDHistograms(fedErrors_,0,lFullDebug);
248  continue;
249  }
250 
251 
252 
253  //check for problems and fill detailed histograms
254  fedErrors_.fillFEDErrors(fedData,
255  lFullDebug,
256  printDebug_,
257  lNChannelMonitoring,
258  lNChannelUnpacker,
259  doMedHists_,
260  fedHists_.cmHistPointer(false),
261  fedHists_.cmHistPointer(true),
263  lFeMajFrac
264  );
265 
266  //check filled in previous method.
267  bool lFailUnpackerFEDcheck = fedErrors_.failUnpackerFEDCheck();
268 
269  fedErrors_.incrementFEDCounters();
270  unsigned int lSize = fedData.size();
271  if (lSize > maxFedBufferSize_){
272  maxFedBufferSize_ = lSize;
273  }
274  //std::cout << " -- " << fedId << " " << lSize << std::endl;
275 
276  fedHists_.fillFEDHistograms(fedErrors_,lSize,lFullDebug);
277 
278  bool lFailMonitoringFEDcheck = fedErrors_.failMonitoringFEDCheck();
279  if (lFailMonitoringFEDcheck) lNTotBadFeds++;
280 
281 
282  //sanity check: if something changed in the unpacking code
283  //but wasn't propagated here
284  //print only the summary, and more info if printDebug>1
285  if (lFailMonitoringFEDcheck != lFailUnpackerFEDcheck) {
286  if (printDebug_>1) {
287  std::ostringstream debugStream;
288  debugStream << " --- WARNING: FED " << fedId << std::endl
289  << " ------ Monitoring FED check " ;
290  if (lFailMonitoringFEDcheck) debugStream << "failed." << std::endl;
291  else debugStream << "passed." << std::endl ;
292  debugStream << " ------ Unpacker FED check " ;
293  if (lFailUnpackerFEDcheck) debugStream << "failed." << std::endl;
294  else debugStream << "passed." << std::endl ;
295  edm::LogError("SiStripMonitorHardware") << debugStream.str();
296  }
297 
298  if (lFailMonitoringFEDcheck) lNFEDMonitoring++;
299  else if (lFailUnpackerFEDcheck) lNFEDUnpacker++;
300  }
301 
302 
303  //Fill TkHistoMap:
304  //add an entry for all channels (good = 0),
305  //so that tkHistoMap knows which channels should be there.
306  if (doTkHistoMap_ && !fedHists_.tkHistoMapPointer()) {
307  edm::LogWarning("SiStripMonitorHardware") << " -- Fedid " << fedId
308  << ", TkHistoMap enabled but pointer is null." << std::endl;
309  }
310 
311  fedErrors_.fillBadChannelList(doTkHistoMap_,
312  fedHists_.tkHistoMapPointer(),
313  fedHists_.getFedvsAPVpointer(),
314  lNTotBadChannels,
315  lNTotBadActiveChannels);
316  }//loop over FED IDs
317 
318 
319  if (doFEMajorityCheck_){
320  for (unsigned int iP(0); iP<nParts; ++iP){
321  //std::cout << " -- Partition " << iP << std::endl;
322  //std::cout << " --- Number of elements in vec = " << lFeMajFrac[iP].size() << std::endl;
323  if (lFeMajFrac[iP].size()==0) continue;
324  std::sort(lFeMajFrac[iP].begin(),lFeMajFrac[iP].end(),SiStripFEDMonitorPlugin::pairComparison);
325 
326  unsigned int lMajorityCounter = 0;
327  std::vector<unsigned int> lfedIds;
328 
329  getMajority(lFeMajFrac[iP],lMajorityCounter,lfedIds);
330  //std::cout << " -- Found " << lfedIds.size() << " unique elements not matching the majority." << std::endl;
331  fedHists_.fillMajorityHistograms(iP,static_cast<float>(lMajorityCounter)/lFeMajFrac[iP].size(),lfedIds);
332  }
333  }
334 
335  if ((lNTotBadFeds> 0 || lNTotBadChannels>0) && printDebug_>1) {
336  std::ostringstream debugStream;
337  debugStream << "[SiStripFEDMonitorPlugin] --- Total number of bad feds = "
338  << lNTotBadFeds << std::endl
339  << "[SiStripFEDMonitorPlugin] --- Total number of bad channels = "
340  << lNTotBadChannels << std::endl
341  << "[SiStripFEDMonitorPlugin] --- Total number of bad active channels = "
342  << lNTotBadActiveChannels << std::endl;
343  edm::LogInfo("SiStripMonitorHardware") << debugStream.str();
344  }
345 
346  if ((lNFEDMonitoring > 0 || lNFEDUnpacker > 0 || lNChannelMonitoring > 0 || lNChannelUnpacker > 0) && printDebug_) {
347  std::ostringstream debugStream;
348  debugStream
349  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
350  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
351  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at FED level : " << std::endl
352  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNFEDMonitoring << std::endl
353  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNFEDUnpacker << std::endl
354  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
355  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at Channel level : " << std::endl
356  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNChannelMonitoring << std::endl
357  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNChannelUnpacker << std::endl
358  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
359  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl ;
360  edm::LogError("SiStripMonitorHardware") << debugStream.str();
361 
362  }
363 
364  FEDErrors::getFEDErrorsCounters().nTotalBadChannels = lNTotBadChannels;
365  FEDErrors::getFEDErrorsCounters().nTotalBadActiveChannels = lNTotBadActiveChannels;
366 
367  //fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(), nEvt_);
368  //time in seconds since beginning of the run or event number
369  if (fillWithEvtNum_) fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(),FEDErrors::getChannelErrorsCounters(),maxFedBufferSize_,iEvent.id().event());
370  else fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(),FEDErrors::getChannelErrorsCounters(),maxFedBufferSize_,iEvent.orbitNumber()/11223.);
371 
372  nEvt_++;
373 
374 }//analyze method
375 
376 
377 bool SiStripFEDMonitorPlugin::pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
378  const std::pair<unsigned int, unsigned int> & pair2){
379  return (pair1.second < pair2.second) ;
380 }
381 
382 void SiStripFEDMonitorPlugin::getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
383  unsigned int & aMajorityCounter,
384  std::vector<unsigned int> & afedIds) {
385 
386 
387  unsigned int lMajAddress = 0;
388  std::vector<std::pair<unsigned int,unsigned int> >::const_iterator lIter = aFeMajVec.begin();
389  unsigned int lMajAddr = (*lIter).second;
390  unsigned int lCounter = 0;
391 
392  //std::cout << " --- First element: addr = " << lMajAddr << " counter = " << lCounter << std::endl;
393  unsigned int iele=0;
394  //bool foundMaj = false;
395  for ( ; lIter != aFeMajVec.end(); ++lIter,++iele) {
396  //std::cout << " ---- Ele " << iele << " " << (*lIter).first << " " << (*lIter).second << " ref " << lMajAddr << std::endl;
397  if ((*lIter).second == lMajAddr) {
398  ++lCounter;
399  //std::cout << " ----- =ref: Counter = " << lCounter << std::endl;
400  }
401  else {
402  //std::cout << " ----- !=ref: Counter = " << lCounter << " Majority = " << aMajorityCounter << std::endl;
403  if (lCounter > aMajorityCounter) {
404  //std::cout << " ------ >Majority: " << std::endl;
405  aMajorityCounter = lCounter;
406  // AV bug here??
407  lMajAddress = lMajAddr;
408  // lMajAddress = (*lIter).second;
409  //foundMaj=true;
410  }
411  lCounter = 0;
412  lMajAddr = (*lIter).second;
413  --lIter;
414  --iele;
415  }
416  }
417  // AV Bug here? The check has to be done regardless foundMaj == false or true
418  // if (!foundMaj) {
419  if (lCounter > aMajorityCounter) {
420  //std::cout << " ------ >Majority: " << std::endl;
421  aMajorityCounter = lCounter;
422  lMajAddress = lMajAddr;
423  }
424  // }
425  //std::cout << " -- found majority value for " << aMajorityCounter << " elements out of " << aFeMajVec.size() << "." << std::endl;
426  //get list of feds with address different from majority in partition:
427  lIter = aFeMajVec.begin();
428  afedIds.reserve(135);
429  for ( ; lIter != aFeMajVec.end(); ++lIter ) {
430  if((*lIter).second != lMajAddress) {
431  afedIds.push_back((*lIter).first);
432  }
433  else {
434  lIter += aMajorityCounter-1;
435  if(lIter >= aFeMajVec.end()) {
436  std::cout << "Here it is a bug: " << aMajorityCounter << " " << aFeMajVec.size() << " " << lIter - aFeMajVec.end() << std::endl;
437  }
438  }
439  }
440  //std::cout << " -- Found " << lfedIds.size() << " elements not matching the majority." << std::endl;
441  if (afedIds.size()>0) {
442  std::sort(afedIds.begin(),afedIds.end());
443  std::vector<unsigned int>::iterator lIt = std::unique(afedIds.begin(),afedIds.end());
444  afedIds.erase(lIt,afedIds.end());
445  }
446 
447 }
448 
449 // ------------ method called once each job just before starting event loop ------------
450 void
452 {
453  //get DQM store
456 
457  //this propagates dqm_ to the histoclass, must be called !
458  fedHists_.bookTopLevelHistograms(dqm_);
459 
460  if (fillAllDetailedHistograms_) fedHists_.bookAllFEDHistograms();
461 
462  nEvt_ = 0;
463 
464  //const unsigned int siStripFedIdMin = FEDNumbering::MINSiStripFEDID;
465  //const unsigned int siStripFedIdMax = FEDNumbering::MAXSiStripFEDID;
466 
467  //mark all channels as inactive until they have been 'locked' at least once
468  // activeChannels_.resize(siStripFedIdMax+1);
469  // for (unsigned int fedId = siStripFedIdMin;
470  // fedId <= siStripFedIdMax;
471  // fedId++) {
472  // activeChannels_[fedId].resize(sistrip::FEDCH_PER_FED,false);
473  // }
474 
475 
476 
477 
478 }
479 
480 // ------------ method called once each job just after ending the event loop ------------
481 void
483 {
485 }
486 
487 
488 
489 void
491  const edm::EventSetup& context)
492 {
493 
494  fedErrors_.initialiseLumiBlock();
495 
496 }
497 
498 
499 void
501  const edm::EventSetup& context)
502 {
503  fedHists_.fillLumiHistograms(fedErrors_.getLumiErrors());
504 }
505 
506 
507 
508 
510 {
511  uint32_t currentCacheId = eventSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
512  if (cablingCacheId_ != currentCacheId) {
513  edm::ESHandle<SiStripFedCabling> cablingHandle;
514  eventSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
515  cabling_ = cablingHandle.product();
516  cablingCacheId_ = currentCacheId;
517  }
518 }
519 
520 
521 //
522 // Define as a plug-in
523 //
524 
EventNumber_t event() const
Definition: EventID.h:44
const SiStripFedCabling * cabling_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void save(const std::string &filename, const std::string &path="", const std::string &pattern="", const std::string &rewrite="", SaveReferenceTag ref=SaveWithReference, int minStatus=dqm::qstatus::STATUS_OK, const std::string &fileupdate="RECREATE")
Definition: DQMStore.cc:2113
void getMajority(const std::vector< std::pair< unsigned int, unsigned int > > &aFeMajVec, unsigned int &aMajorityCounter, std::vector< unsigned int > &afedIds)
#define NULL
Definition: scimark2.h:8
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:49
virtual void analyze(const edm::Event &, const edm::EventSetup &)
int iEvent
Definition: GenABIO.cc:243
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
SiStripFEDMonitorPlugin(const edm::ParameterSet &)
#define end
Definition: vmac.h:38
int orbitNumber() const
Definition: EventBase.h:63
bool isValid() const
Definition: HandleBase.h:76
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
#define LogTrace(id)
virtual void endLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &context)
bool failedToGet() const
Definition: HandleBase.h:80
const T & get() const
Definition: EventSetup.h:55
virtual void beginLuminosityBlock(const edm::LuminosityBlock &lumiSeg, const edm::EventSetup &context)
T const * product() const
Definition: ESHandle.h:62
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
edm::EventID id() const
Definition: EventBase.h:56
#define begin
Definition: vmac.h:31
static bool pairComparison(const std::pair< unsigned int, unsigned int > &pair1, const std::pair< unsigned int, unsigned int > &pair2)
tuple cout
Definition: gather_cfg.py:121
tuple size
Write out results.
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:429
void updateCabling(const edm::EventSetup &eventSetup)