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.3 2013/01/03 18:59:36 wmtan 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 
45 
48 
50 
51 #include "DQM/SiStripMonitorHardware/interface/FEDHistograms.hh"
52 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
53 
55 
56 
57 //
58 // Class declaration
59 //
60 
62 {
63  public:
66  private:
67  virtual void beginJob();
68  virtual void analyze(const edm::Event&, const edm::EventSetup&);
69  virtual void endJob();
70  virtual void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
71  const edm::EventSetup& context);
72  virtual void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg,
73  const edm::EventSetup& context);
74 
75  //update the cabling if necessary
76  void updateCabling(const edm::EventSetup& eventSetup);
77 
78  static bool pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
79  const std::pair<unsigned int, unsigned int> & pair2);
80 
81  void getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
82  unsigned int & aMajorityCounter,
83  std::vector<unsigned int> & afedIds);
84 
85  //tag of FEDRawData collection
87  //histogram helper class
88  FEDHistograms fedHists_;
89  //folder name for histograms in DQMStore
91  //book detailed histograms even if they will be empty (for merging)
93  //do histos vs time with time=event number. Default time = orbit number (s)
95  //print debug messages when problems are found: 1=error debug, 2=light debug, 3=full debug
96  unsigned int printDebug_;
97  //bool printDebug_;
98  //write the DQMStore to a root file at the end of the job
101  //the DQMStore
103  //FED cabling
104  uint32_t cablingCacheId_;
106 
107  //add parameter to save computing time if TkHistoMap/Median/FeMajCheck are not enabled
111 
112  unsigned int nEvt_;
113 
114  //FED errors
115  //need class member for lumi histograms
116  FEDErrors fedErrors_;
117  unsigned int maxFedBufferSize_;
118 };
119 
120 
121 //
122 // Constructors and destructor
123 //
124 
126  : rawDataTag_(iConfig.getUntrackedParameter<edm::InputTag>("RawDataTag",edm::InputTag("source",""))),
127  folderName_(iConfig.getUntrackedParameter<std::string>("HistogramFolderName","SiStrip/ReadoutView/FedSummary")),
128  fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms",false)),
129  fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber",false)),
130  printDebug_(iConfig.getUntrackedParameter<unsigned int>("PrintDebugMessages",1)),
131  //printDebug_(iConfig.getUntrackedParameter<bool>("PrintDebugMessages",false)),
132  writeDQMStore_(iConfig.getUntrackedParameter<bool>("WriteDQMStore",false)),
133  dqmStoreFileName_(iConfig.getUntrackedParameter<std::string>("DQMStoreFileName","DQMStore.root")),
134  dqm_(0),
135  cablingCacheId_(0),
136  maxFedBufferSize_(0)
137 {
138  //print config to debug log
139  std::ostringstream debugStream;
140  if (printDebug_>1) {
141  debugStream << "[SiStripFEDMonitorPlugin]Configuration for SiStripFEDMonitorPlugin: " << std::endl
142  << "[SiStripFEDMonitorPlugin]\tRawDataTag: " << rawDataTag_ << std::endl
143  << "[SiStripFEDMonitorPlugin]\tHistogramFolderName: " << folderName_ << std::endl
144  << "[SiStripFEDMonitorPlugin]\tFillAllDetailedHistograms? " << (fillAllDetailedHistograms_ ? "yes" : "no") << std::endl
145  << "[SiStripFEDMonitorPlugin]\tFillWithEventNumber?" << (fillWithEvtNum_ ? "yes" : "no") << std::endl
146  << "[SiStripFEDMonitorPlugin]\tPrintDebugMessages? " << (printDebug_ ? "yes" : "no") << std::endl
147  << "[SiStripFEDMonitorPlugin]\tWriteDQMStore? " << (writeDQMStore_ ? "yes" : "no") << std::endl;
148  if (writeDQMStore_) debugStream << "[SiStripFEDMonitorPlugin]\tDQMStoreFileName: " << dqmStoreFileName_ << std::endl;
149  }
150 
151  //don;t generate debug mesages if debug is disabled
152  std::ostringstream* pDebugStream = (printDebug_>1 ? &debugStream : NULL);
153 
154  fedHists_.initialise(iConfig,pDebugStream);
155 
156  doTkHistoMap_ = fedHists_.tkHistoMapEnabled();
157 
158  doMedHists_ = fedHists_.cmHistosEnabled();
159 
160  doFEMajorityCheck_ = fedHists_.feMajHistosEnabled();
161 
162  if (printDebug_) {
163  LogTrace("SiStripMonitorHardware") << debugStream.str();
164 
165  //debugStream.str("");
166 
167  //debugStream << " -- Quelle est la difference entre un canard ? " << std::endl
168  // << " -- Reponse: c'est qu'il a les deux pattes de la meme longueur, surtout la gauche." << std::endl;
169 
170  //edm::LogError("SiStripMonitorHardware") << debugStream.str();
171  }
172 
173  nEvt_ = 0;
174 
175 }
176 
178 {
179 }
180 
181 
182 //
183 // Member functions
184 //
185 
186 // ------------ method called to for each event ------------
187 void
189  const edm::EventSetup& iSetup)
190 {
191  //Retrieve tracker topology from geometry
192  edm::ESHandle<TrackerTopology> tTopoHandle;
193  iSetup.get<IdealGeometryRecord>().get(tTopoHandle);
194  const TrackerTopology* const tTopo = tTopoHandle.product();
195 
196  //update cabling
197  updateCabling(iSetup);
198 
199  //get raw data
200  edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
201  iEvent.getByLabel(rawDataTag_,rawDataCollectionHandle);
202  const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
203 
204  fedErrors_.initialiseEvent();
205 
206  //add the deltaBX value if the product exist
207 
209  iEvent.getByLabel("consecutiveHEs",he);
210 
211  if(he.isValid() && !he.failedToGet()) {
212  fedErrors_.fillEventProperties(he->deltaBX());
213  }
214 
215  //initialise map of fedId/bad channel number
216  std::map<unsigned int,std::pair<unsigned short,unsigned short> > badChannelFraction;
217 
218  unsigned int lNFEDMonitoring = 0;
219  unsigned int lNFEDUnpacker = 0;
220  unsigned int lNChannelMonitoring = 0;
221  unsigned int lNChannelUnpacker = 0;
222 
223  unsigned int lNTotBadFeds = 0;
224  unsigned int lNTotBadChannels = 0;
225  unsigned int lNTotBadActiveChannels = 0;
226 
227  std::vector<std::vector<std::pair<unsigned int,unsigned int> > > lFeMajFrac;
228  const unsigned int nParts = 4;
229  if (doFEMajorityCheck_){
230  lFeMajFrac.resize(nParts);
231  //max nFE per partition
232  lFeMajFrac[0].reserve(912);
233  lFeMajFrac[1].reserve(1080);
234  lFeMajFrac[2].reserve(768);
235  lFeMajFrac[3].reserve(760);
236  }
237 
238  maxFedBufferSize_ = 0;
239 
240  //loop over siStrip FED IDs
241  for (unsigned int fedId = FEDNumbering::MINSiStripFEDID;
243  fedId++) {//loop over FED IDs
244  const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
245 
246  //create an object to fill all errors
247  fedErrors_.initialiseFED(fedId,cabling_,tTopo);
248  bool lFullDebug = false;
249 
250  //Do detailed check
251  //first check if data exists
252  bool lDataExist = fedErrors_.checkDataPresent(fedData);
253  if (!lDataExist) {
254  fedHists_.fillFEDHistograms(fedErrors_,0,lFullDebug);
255  continue;
256  }
257 
258 
259 
260  //check for problems and fill detailed histograms
261  fedErrors_.fillFEDErrors(fedData,
262  lFullDebug,
263  printDebug_,
264  lNChannelMonitoring,
265  lNChannelUnpacker,
266  doMedHists_,
267  fedHists_.cmHistPointer(false),
268  fedHists_.cmHistPointer(true),
270  lFeMajFrac
271  );
272 
273  //check filled in previous method.
274  bool lFailUnpackerFEDcheck = fedErrors_.failUnpackerFEDCheck();
275 
276  fedErrors_.incrementFEDCounters();
277  unsigned int lSize = fedData.size();
278  if (lSize > maxFedBufferSize_){
279  maxFedBufferSize_ = lSize;
280  }
281  //std::cout << " -- " << fedId << " " << lSize << std::endl;
282 
283  fedHists_.fillFEDHistograms(fedErrors_,lSize,lFullDebug);
284 
285  bool lFailMonitoringFEDcheck = fedErrors_.failMonitoringFEDCheck();
286  if (lFailMonitoringFEDcheck) lNTotBadFeds++;
287 
288 
289  //sanity check: if something changed in the unpacking code
290  //but wasn't propagated here
291  //print only the summary, and more info if printDebug>1
292  if (lFailMonitoringFEDcheck != lFailUnpackerFEDcheck) {
293  if (printDebug_>1) {
294  std::ostringstream debugStream;
295  debugStream << " --- WARNING: FED " << fedId << std::endl
296  << " ------ Monitoring FED check " ;
297  if (lFailMonitoringFEDcheck) debugStream << "failed." << std::endl;
298  else debugStream << "passed." << std::endl ;
299  debugStream << " ------ Unpacker FED check " ;
300  if (lFailUnpackerFEDcheck) debugStream << "failed." << std::endl;
301  else debugStream << "passed." << std::endl ;
302  edm::LogError("SiStripMonitorHardware") << debugStream.str();
303  }
304 
305  if (lFailMonitoringFEDcheck) lNFEDMonitoring++;
306  else if (lFailUnpackerFEDcheck) lNFEDUnpacker++;
307  }
308 
309 
310  //Fill TkHistoMap:
311  //add an entry for all channels (good = 0),
312  //so that tkHistoMap knows which channels should be there.
313  if (doTkHistoMap_ && !fedHists_.tkHistoMapPointer()) {
314  edm::LogWarning("SiStripMonitorHardware") << " -- Fedid " << fedId
315  << ", TkHistoMap enabled but pointer is null." << std::endl;
316  }
317 
318  fedErrors_.fillBadChannelList(doTkHistoMap_,
319  fedHists_.tkHistoMapPointer(),
320  fedHists_.getFedvsAPVpointer(),
321  lNTotBadChannels,
322  lNTotBadActiveChannels);
323  }//loop over FED IDs
324 
325 
326  if (doFEMajorityCheck_){
327  for (unsigned int iP(0); iP<nParts; ++iP){
328  //std::cout << " -- Partition " << iP << std::endl;
329  //std::cout << " --- Number of elements in vec = " << lFeMajFrac[iP].size() << std::endl;
330  if (lFeMajFrac[iP].size()==0) continue;
331  std::sort(lFeMajFrac[iP].begin(),lFeMajFrac[iP].end(),SiStripFEDMonitorPlugin::pairComparison);
332 
333  unsigned int lMajorityCounter = 0;
334  std::vector<unsigned int> lfedIds;
335 
336  getMajority(lFeMajFrac[iP],lMajorityCounter,lfedIds);
337  //std::cout << " -- Found " << lfedIds.size() << " unique elements not matching the majority." << std::endl;
338  fedHists_.fillMajorityHistograms(iP,static_cast<float>(lMajorityCounter)/lFeMajFrac[iP].size(),lfedIds);
339  }
340  }
341 
342  if ((lNTotBadFeds> 0 || lNTotBadChannels>0) && printDebug_>1) {
343  std::ostringstream debugStream;
344  debugStream << "[SiStripFEDMonitorPlugin] --- Total number of bad feds = "
345  << lNTotBadFeds << std::endl
346  << "[SiStripFEDMonitorPlugin] --- Total number of bad channels = "
347  << lNTotBadChannels << std::endl
348  << "[SiStripFEDMonitorPlugin] --- Total number of bad active channels = "
349  << lNTotBadActiveChannels << std::endl;
350  edm::LogInfo("SiStripMonitorHardware") << debugStream.str();
351  }
352 
353  if ((lNFEDMonitoring > 0 || lNFEDUnpacker > 0 || lNChannelMonitoring > 0 || lNChannelUnpacker > 0) && printDebug_) {
354  std::ostringstream debugStream;
355  debugStream
356  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
357  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
358  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at FED level : " << std::endl
359  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNFEDMonitoring << std::endl
360  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNFEDUnpacker << std::endl
361  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
362  << "[SiStripFEDMonitorPlugin]-- Summary of differences between unpacker and monitoring at Channel level : " << std::endl
363  << "[SiStripFEDMonitorPlugin] ---- Number of times monitoring fails but not unpacking = " << lNChannelMonitoring << std::endl
364  << "[SiStripFEDMonitorPlugin] ---- Number of times unpacking fails but not monitoring = " << lNChannelUnpacker << std::endl
365  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl
366  << "[SiStripFEDMonitorPlugin]-------------------------------------------------------------------------" << std::endl ;
367  edm::LogError("SiStripMonitorHardware") << debugStream.str();
368 
369  }
370 
371  FEDErrors::getFEDErrorsCounters().nTotalBadChannels = lNTotBadChannels;
372  FEDErrors::getFEDErrorsCounters().nTotalBadActiveChannels = lNTotBadActiveChannels;
373 
374  //fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(), nEvt_);
375  //time in seconds since beginning of the run or event number
376  if (fillWithEvtNum_) fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(),FEDErrors::getChannelErrorsCounters(),maxFedBufferSize_,iEvent.id().event());
377  else fedHists_.fillCountersHistograms(FEDErrors::getFEDErrorsCounters(),FEDErrors::getChannelErrorsCounters(),maxFedBufferSize_,iEvent.orbitNumber()/11223.);
378 
379  nEvt_++;
380 
381 }//analyze method
382 
383 
384 bool SiStripFEDMonitorPlugin::pairComparison(const std::pair<unsigned int, unsigned int> & pair1,
385  const std::pair<unsigned int, unsigned int> & pair2){
386  return (pair1.second < pair2.second) ;
387 }
388 
389 void SiStripFEDMonitorPlugin::getMajority(const std::vector<std::pair<unsigned int,unsigned int> > & aFeMajVec,
390  unsigned int & aMajorityCounter,
391  std::vector<unsigned int> & afedIds) {
392 
393 
394  unsigned int lMajAddress = 0;
395  std::vector<std::pair<unsigned int,unsigned int> >::const_iterator lIter = aFeMajVec.begin();
396  unsigned int lMajAddr = (*lIter).second;
397  unsigned int lCounter = 0;
398 
399  //std::cout << " --- First element: addr = " << lMajAddr << " counter = " << lCounter << std::endl;
400  unsigned int iele=0;
401  //bool foundMaj = false;
402  for ( ; lIter != aFeMajVec.end(); ++lIter,++iele) {
403  //std::cout << " ---- Ele " << iele << " " << (*lIter).first << " " << (*lIter).second << " ref " << lMajAddr << std::endl;
404  if ((*lIter).second == lMajAddr) {
405  ++lCounter;
406  //std::cout << " ----- =ref: Counter = " << lCounter << std::endl;
407  }
408  else {
409  //std::cout << " ----- !=ref: Counter = " << lCounter << " Majority = " << aMajorityCounter << std::endl;
410  if (lCounter > aMajorityCounter) {
411  //std::cout << " ------ >Majority: " << std::endl;
412  aMajorityCounter = lCounter;
413  // AV bug here??
414  lMajAddress = lMajAddr;
415  // lMajAddress = (*lIter).second;
416  //foundMaj=true;
417  }
418  lCounter = 0;
419  lMajAddr = (*lIter).second;
420  --lIter;
421  --iele;
422  }
423  }
424  // AV Bug here? The check has to be done regardless foundMaj == false or true
425  // if (!foundMaj) {
426  if (lCounter > aMajorityCounter) {
427  //std::cout << " ------ >Majority: " << std::endl;
428  aMajorityCounter = lCounter;
429  lMajAddress = lMajAddr;
430  }
431  // }
432  //std::cout << " -- found majority value for " << aMajorityCounter << " elements out of " << aFeMajVec.size() << "." << std::endl;
433  //get list of feds with address different from majority in partition:
434  lIter = aFeMajVec.begin();
435  afedIds.reserve(135);
436  for ( ; lIter != aFeMajVec.end(); ++lIter ) {
437  if((*lIter).second != lMajAddress) {
438  afedIds.push_back((*lIter).first);
439  }
440  else {
441  lIter += aMajorityCounter-1;
442  if(lIter >= aFeMajVec.end()) {
443  std::cout << "Here it is a bug: " << aMajorityCounter << " " << aFeMajVec.size() << " " << lIter - aFeMajVec.end() << std::endl;
444  }
445  }
446  }
447  //std::cout << " -- Found " << lfedIds.size() << " elements not matching the majority." << std::endl;
448  if (afedIds.size()>0) {
449  std::sort(afedIds.begin(),afedIds.end());
450  std::vector<unsigned int>::iterator lIt = std::unique(afedIds.begin(),afedIds.end());
451  afedIds.erase(lIt,afedIds.end());
452  }
453 
454 }
455 
456 // ------------ method called once each job just before starting event loop ------------
457 void
459 {
460  //get DQM store
463 
464  //this propagates dqm_ to the histoclass, must be called !
465  fedHists_.bookTopLevelHistograms(dqm_);
466 
467  if (fillAllDetailedHistograms_) fedHists_.bookAllFEDHistograms();
468 
469  nEvt_ = 0;
470 
471  //const unsigned int siStripFedIdMin = FEDNumbering::MINSiStripFEDID;
472  //const unsigned int siStripFedIdMax = FEDNumbering::MAXSiStripFEDID;
473 
474  //mark all channels as inactive until they have been 'locked' at least once
475  // activeChannels_.resize(siStripFedIdMax+1);
476  // for (unsigned int fedId = siStripFedIdMin;
477  // fedId <= siStripFedIdMax;
478  // fedId++) {
479  // activeChannels_[fedId].resize(sistrip::FEDCH_PER_FED,false);
480  // }
481 
482 
483 
484 
485 }
486 
487 // ------------ method called once each job just after ending the event loop ------------
488 void
490 {
492 }
493 
494 
495 
496 void
498  const edm::EventSetup& context)
499 {
500 
501  fedErrors_.initialiseLumiBlock();
502 
503 }
504 
505 
506 void
508  const edm::EventSetup& context)
509 {
510  fedHists_.fillLumiHistograms(fedErrors_.getLumiErrors());
511 }
512 
513 
514 
515 
517 {
518  uint32_t currentCacheId = eventSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
519  if (cablingCacheId_ != currentCacheId) {
520  edm::ESHandle<SiStripFedCabling> cablingHandle;
521  eventSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
522  cabling_ = cablingHandle.product();
523  cablingCacheId_ = currentCacheId;
524  }
525 }
526 
527 
528 //
529 // Define as a plug-in
530 //
531 
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:2118
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:361
#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:434
void updateCabling(const edm::EventSetup &eventSetup)