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