CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/DQM/SiStripMonitorHardware/plugins/SiStripSpyMonitorModule.cc

Go to the documentation of this file.
00001 // Original Author:  Anne-Marie Magnan
00002 //         Created:  2010/01/11
00003 // $Id: SiStripSpyMonitorModule.cc,v 1.4 2010/04/21 10:40:21 amagnan Exp $
00004 //
00005 
00006 #include <sstream>
00007 #include <memory>
00008 #include <list>
00009 #include <algorithm>
00010 #include <cassert>
00011 
00012 #include "FWCore/Framework/interface/Frameworkfwd.h"
00013 #include "FWCore/Framework/interface/EDAnalyzer.h"
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/Framework/interface/EventSetup.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00018 #include "FWCore/Utilities/interface/InputTag.h"
00019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00020 #include "FWCore/ServiceRegistry/interface/Service.h"
00021 #include "FWCore/Utilities/interface/Exception.h"
00022 
00023 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00024 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00025 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00026 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00027 #include "DataFormats/Common/interface/DetSetVector.h"
00028 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
00029 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
00030 
00031 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
00032 #include "CondFormats/DataRecord/interface/SiStripPedestalsRcd.h"
00033 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
00034 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00035 
00036 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
00037 
00038 // For plotting.
00039 #include "DQMServices/Core/interface/DQMStore.h"
00040 #include "DQMServices/Core/interface/MonitorElement.h"
00041 
00042 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
00043 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUtilities.h"
00044 #include "DQM/SiStripMonitorHardware/interface/SPYHistograms.h"
00045 
00046 //
00047 // Class declaration
00048 //
00049 
00050 class SiStripSpyMonitorModule : public edm::EDAnalyzer
00051 {
00052  public:
00053 
00054 
00055   explicit SiStripSpyMonitorModule(const edm::ParameterSet&);
00056   ~SiStripSpyMonitorModule();
00057 
00058  private:
00059 
00060   virtual void beginJob();
00061   virtual void analyze(const edm::Event&, const edm::EventSetup&);
00062   virtual void endJob();
00063 
00064 
00065   //check if contains pedsubtr data = 0
00066   bool hasNegativePedSubtr(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00067                            uint16_t aPair);
00068 
00069   bool identifyTickmarks(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00070                          const uint16_t threshold);
00071 
00072   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator
00073   findTwoConsecutive(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00074                      const uint16_t threshold,
00075                      uint16_t & aCounter);
00076 
00077   //tag of spydata collection
00078   edm::InputTag spyScopeRawDigisTag_;
00079   edm::InputTag spyPedSubtrDigisTag_;
00080 
00081   //tag of l1A and apveAddress counters
00082   edm::InputTag spyL1Tag_;
00083   edm::InputTag spyTotCountTag_;
00084   edm::InputTag spyAPVeTag_;
00085 
00086   uint32_t minDigiRange_;
00087   uint32_t maxDigiRange_;
00088   uint32_t minDigitalLow_;
00089   uint32_t maxDigitalLow_;
00090   uint32_t minDigitalHigh_;
00091   uint32_t maxDigitalHigh_;
00092 
00093   unsigned int evt_;
00094 
00095   DQMStore* dqm_;
00096   //folder name for histograms in DQMStore
00097   std::string folderName_;
00098   //book detailed histograms even if they will be empty (for merging)
00099   bool fillAllDetailedHistograms_;
00100   //do histos vs time with time=event number. Default time = orbit number (s)
00101   bool fillWithEvtNum_;
00102   bool fillWithLocalEvtNum_;
00103   //write the DQMStore to a root file at the end of the job
00104   bool writeDQMStore_;
00105   std::string dqmStoreFileName_;
00106 
00107   SPYHistograms histManager_;  
00108   uint16_t firstHeaderBit_;
00109   uint16_t firstTrailerBit_;
00110 
00111   sistrip::SpyUtilities utility_;
00112   sistrip::SpyUtilities::FrameQuality frameQuality_;
00113 
00114   std::ofstream outfile_[20];  
00115   std::vector<std::string> outfileNames_;  
00116   std::map<std::string,unsigned int> outfileMap_;
00117 
00118   bool writeCabling_;
00119 
00120 };
00121 
00122 
00123 
00124 using edm::LogError;
00125 using edm::LogWarning;
00126 using edm::LogInfo;
00127 //
00128 // Constructors and destructor
00129 //
00130 
00131 SiStripSpyMonitorModule::SiStripSpyMonitorModule(const edm::ParameterSet& iConfig)
00132   : spyScopeRawDigisTag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyScopeRawDigisTag",edm::InputTag("SiStripSpyUnpacker","ScopeRawDigis"))),
00133     spyPedSubtrDigisTag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyPedSubtrDigisTag",edm::InputTag("SiStripFEDEmulator",""))),
00134     spyL1Tag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyL1Tag",edm::InputTag("SiStripSpyDigiConverter","L1ACount"))),
00135     spyTotCountTag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyTotalEventCountTag",edm::InputTag("SiStripSpyDigiConverter","TotalEventCount"))),
00136     spyAPVeTag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyAPVeTag",edm::InputTag("SiStripSpyDigiConverter","APVAddress"))),
00137     dqm_(0),
00138     folderName_(iConfig.getUntrackedParameter<std::string>("HistogramFolderName","SiStrip/ReadoutView/SpyMonitoringSummary")),
00139     fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms",false)),
00140     fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber",false)),
00141     fillWithLocalEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithLocalEventNumber",false)),
00142     writeDQMStore_(iConfig.getUntrackedParameter<bool>("WriteDQMStore",false)),
00143     dqmStoreFileName_(iConfig.getUntrackedParameter<std::string>("DQMStoreFileName","DQMStore.root")),
00144     firstHeaderBit_(0),
00145     firstTrailerBit_(0),
00146     outfileNames_(iConfig.getUntrackedParameter<std::vector<std::string> >("OutputErrors")),
00147     writeCabling_(iConfig.getUntrackedParameter<bool>("WriteCabling",false))
00148 {
00149 
00150   evt_ = 0;
00151   std::ostringstream pDebugStream;
00152   histManager_.initialise(iConfig,&pDebugStream);
00153   const unsigned int nFiles = outfileNames_.size();
00154 
00155   for (unsigned int i(0); i<nFiles; i++){
00156     std::ostringstream lName;
00157     lName << outfileNames_.at(i) <<  ".out";
00158     if (i<20) outfile_[i].open(lName.str().c_str(),std::ios::out);
00159     outfileMap_[outfileNames_.at(i)] = i;
00160   }
00161 
00162   frameQuality_.minDigiRange = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinDigiRange",100));
00163   frameQuality_.maxDigiRange = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxDigiRange",1024));
00164   frameQuality_.minZeroLight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinZeroLight",0));
00165   frameQuality_.maxZeroLight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxZeroLight",1024));
00166   frameQuality_.minTickHeight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinTickHeight",0));
00167   frameQuality_.maxTickHeight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxTickHeight",1024));
00168   
00169 }
00170 
00171 SiStripSpyMonitorModule::~SiStripSpyMonitorModule()
00172 { 
00173   const unsigned int nFiles = outfileNames_.size();
00174   for (unsigned int i(0); i<nFiles; i++){
00175     outfile_[i].close();
00176   }
00177 
00178   outfileMap_.clear();
00179   outfileNames_.clear();
00180 
00181 }
00182 
00183 
00184 // ------------ method called once each job just before starting event loop  ------------
00185 void 
00186 SiStripSpyMonitorModule::beginJob()
00187 {
00188 
00189   //get DQM store
00190   dqm_ = &(*edm::Service<DQMStore>());
00191   dqm_->setCurrentFolder(folderName_);
00192 
00193   LogInfo("SiStripSpyMonitorModule") << " Histograms will be written in " 
00194                                      << folderName_ 
00195                                      << ". Current folder is : " 
00196                                      << dqm_->pwd() 
00197                                      << std::endl;
00198   
00199   //this propagates dqm_ to the histoclass, must be called !
00200   histManager_.bookTopLevelHistograms(dqm_);
00201   
00202   if (fillAllDetailedHistograms_) histManager_.bookAllFEDHistograms();
00203 
00204   evt_ = 0;
00205   firstHeaderBit_ = 0;
00206   firstTrailerBit_ = 0;
00207 }
00208 
00209 
00210 
00211 // ------------ method called to for each event  ------------
00212 void
00213 SiStripSpyMonitorModule::analyze(const edm::Event& iEvent, 
00214                                   const edm::EventSetup& iSetup)
00215 {
00216 
00217   static bool firstEvent = true;
00218   //update cabling and pedestals
00219   const SiStripFedCabling* lCabling = utility_.getCabling( iSetup );
00220   if (firstEvent && writeCabling_){
00221     std::ofstream lOutCabling;
00222     lOutCabling.open("trackerDetId_FEDIdChNum_list.txt",std::ios::out);
00223     for (uint16_t lFedId = sistrip::FED_ID_MIN; lFedId <= sistrip::FED_ID_MAX; ++lFedId) {//loop on feds
00224       for (uint16_t lFedChannel = 0; lFedChannel < sistrip::FEDCH_PER_FED; lFedChannel++){//loop on channels
00225         const FedChannelConnection & lConnection = lCabling->connection(lFedId,lFedChannel);
00226         if (!lConnection.isConnected()) continue;
00227         uint32_t lDetId = lConnection.detId();
00228         lOutCabling << "FED ID = " << lFedId 
00229                     << ", Channel = " << lFedChannel 
00230                     << ",fedkey = " << sistrip::FEDCH_PER_FED*lFedId + lFedChannel
00231                     << ", detId = " << lDetId 
00232                     << std::endl;
00233       }
00234     }
00235     lOutCabling.close();
00236   }
00237 
00238   //For spy data
00239   //get map of TotalEventCount and L1ID, indexed by fedId, and APVaddress indexed by fedIndex.
00240   edm::Handle<std::vector<uint32_t> > lSpyL1IDHandle,lSpyTotCountHandle,lSpyAPVeHandle;
00241   try {
00242     iEvent.getByLabel(spyL1Tag_,lSpyL1IDHandle);
00243     iEvent.getByLabel(spyTotCountTag_,lSpyTotCountHandle);
00244     iEvent.getByLabel(spyAPVeTag_,lSpyAPVeHandle);
00245   }
00246   catch (const cms::Exception& e) {
00247     LogError("SiStripSpyMonitorModule") << e.what() ;
00248     return;
00249   }
00250   //const std::map<uint32_t,uint32_t> & lSpyMaxCountMap = *lSpyL1IDHandle;
00251   //const std::map<uint32_t,uint32_t> & lSpyMinCountMap = *lSpyTotCountHandle;
00252   const std::vector<uint32_t> & lSpyAPVeVec = *lSpyAPVeHandle;
00253 
00254   //retrieve the scope digis
00255   edm::Handle<edm::DetSetVector<SiStripRawDigi> > digisHandle;
00256   try {
00257     iEvent.getByLabel(spyScopeRawDigisTag_, digisHandle);
00258   }
00259   catch (const cms::Exception& e) {
00260     LogError("SiStripSpyMonitorModule") << e.what() ;
00261     return;
00262   }
00263   const edm::DetSetVector<SiStripRawDigi> * lInputDigis = digisHandle.product();
00264 
00265   //retrieve the reordered payload digis
00266   edm::Handle<edm::DetSetVector<SiStripRawDigi> > payloadHandle;
00267   try {
00268     iEvent.getByLabel(spyPedSubtrDigisTag_, payloadHandle);
00269   }
00270   catch (const cms::Exception& e) {
00271     LogError("SiStripSpyMonitorModule") << e.what() ;
00272     return;
00273   }
00274   const edm::DetSetVector<SiStripRawDigi> * lPayloadDigis = payloadHandle.product();
00275 
00276 
00277   //for first event only
00278   //loop first on channels to calculate majority value of when the first header bit is found.
00279   //output info message to give the value found
00280   //should currently be 6 but may vary in the futur
00281   //then we can check firstTrailerBit is +256+24 after
00282 
00283   if (firstEvent){
00284     sistrip::SpyUtilities::getMajorityHeader(lInputDigis,firstHeaderBit_);
00285     firstTrailerBit_ = firstHeaderBit_+24+sistrip::STRIPS_PER_FEDCH;
00286   }
00287 
00288   //initialise some counters, filled in histos eventually
00289   SPYHistograms::ErrorCounters lCounters;
00290   lCounters.nNoData = 0;
00291   lCounters.nLowRange = 0;
00292   lCounters.nHighRange = 0;
00293   lCounters.nMinZero = 0;
00294   lCounters.nMaxSat = 0;
00295   lCounters.nLowPb = 0;
00296   lCounters.nHighPb = 0;
00297   lCounters.nOOS = 0;
00298   lCounters.nOtherPbs = 0;
00299   lCounters.nAPVError = 0;
00300   lCounters.nAPVAddressError = 0;
00301   lCounters.nNegPeds = 0;
00302 
00303 
00304 
00305   //fill event number for output text files
00306   const unsigned int nFiles = outfileNames_.size();
00307   for (unsigned int i(0); i<nFiles; i++){
00308     outfile_[i] << "**** evt "<< iEvent.id().event() << " ****" << std::endl ;
00309   }
00310 
00311 
00312   //loop over all FEDs and channels
00313   
00314   for (uint16_t lFedId = sistrip::FED_ID_MIN; lFedId <= sistrip::FED_ID_MAX; ++lFedId) {//loop on feds
00315 
00316     SPYHistograms::Errors lFEDErrors;
00317     lFEDErrors.hasNoData = false;
00318     lFEDErrors.hasLowRange = false; 
00319     lFEDErrors.hasHighRange = false; 
00320     lFEDErrors.hasMinZero = false;
00321     lFEDErrors.hasMaxSat = false;
00322     lFEDErrors.hasLowPb = false;
00323     lFEDErrors.hasHighPb = false;
00324     lFEDErrors.hasOOS = false;
00325     lFEDErrors.hasOtherPbs = false;
00326     lFEDErrors.hasErrorBit0 = false;
00327     lFEDErrors.hasErrorBit1 = false;
00328     lFEDErrors.hasAPVAddressError0 = false;
00329     lFEDErrors.hasAPVAddressError1 = false;
00330     lFEDErrors.hasNegPeds = false;
00331  
00332     uint32_t lAPVAddrRef = lSpyAPVeVec.at(lFedId);
00333 
00334     for (uint16_t lFedChannel = 0; lFedChannel < sistrip::FEDCH_PER_FED; lFedChannel++){//loop on channels
00335       
00336       uint32_t lFedIndex = sistrip::FEDCH_PER_FED*lFedId + lFedChannel;
00337       
00338       const FedChannelConnection & lConnection = lCabling->connection(lFedId,lFedChannel);
00339 
00340       if (!lConnection.isConnected()) continue;
00341 
00342       uint32_t lDetId = lConnection.detId();
00343       //uint16_t lNPairs = lConnection.nApvPairs();
00344       uint16_t lPair = lConnection.apvPairNumber();
00345 
00346       edm::DetSetVector<SiStripRawDigi>::const_iterator lDigis = lInputDigis->find(lFedIndex);
00347 
00348       //pedsubtr digis
00349       edm::DetSetVector<SiStripRawDigi>::const_iterator lPayload = lPayloadDigis->find(lDetId);
00350        
00351       //no digis found, continue.
00352       if (lDigis == lInputDigis->end()) {
00353         LogDebug("SiStripSpyMonitorModule") << " -- digis not found in ScopeRawDigis map for FEDID " 
00354                                                   << lFedId << " and FED channel " << lFedChannel << std::endl;
00355         continue;
00356       }
00357 
00358       sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*lDigis);
00359       
00360       SPYHistograms::Errors lErrors;
00361       lErrors.hasNoData = false;
00362       lErrors.hasLowRange = false; 
00363       lErrors.hasHighRange = false; 
00364       lErrors.hasMinZero = false;
00365       lErrors.hasMaxSat = false;
00366       lErrors.hasLowPb = false;
00367       lErrors.hasHighPb = false;
00368       lErrors.hasOOS = false;
00369       lErrors.hasOtherPbs = false;
00370       lErrors.hasErrorBit0 = false;
00371       lErrors.hasErrorBit1 = false;
00372       lErrors.hasAPVAddressError0 = false;
00373       lErrors.hasAPVAddressError1 = false;
00374       lErrors.hasNegPeds = false;
00375       
00376       uint16_t lRange = sistrip::SpyUtilities::range(lFrame);
00377       uint16_t lThreshold = sistrip::SpyUtilities::threshold(lFrame);
00378 
00379       if (lRange == 0) {
00380         lCounters.nNoData++;
00381         lErrors.hasNoData = true;
00382         lFEDErrors.hasNoData = true;
00383         if (outfileMap_.find("NoData") != outfileMap_.end()) outfile_[outfileMap_["NoData"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00384       }
00385       else if (lFrame.digitalLow == 0 && lRange > 0) {
00386         lCounters.nMinZero++;
00387         lErrors.hasMinZero = true;
00388         lFEDErrors.hasMinZero = true;
00389         if (outfileMap_.find("MinZero") != outfileMap_.end()) outfile_[outfileMap_["MinZero"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00390       }
00391       else if (lFrame.digitalHigh >= 1023){
00392         lCounters.nMaxSat++;
00393         lErrors.hasMaxSat = true;
00394         lFEDErrors.hasMaxSat = true;
00395         if (outfileMap_.find("MaxSat") != outfileMap_.end()) outfile_[outfileMap_["MaxSat"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00396       }
00397       else if (lRange > 0 && lRange < frameQuality_.minDigiRange) {
00398         lCounters.nLowRange++;
00399         lErrors.hasLowRange = true;
00400         lFEDErrors.hasLowRange = true;
00401         if (outfileMap_.find("LowRange") != outfileMap_.end()) outfile_[outfileMap_["LowRange"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00402       }
00403       else if (lRange > frameQuality_.maxDigiRange) {
00404         lCounters.nHighRange++;
00405         lErrors.hasHighRange = true;
00406         lFEDErrors.hasHighRange = true;
00407         if (outfileMap_.find("HighRange") != outfileMap_.end()) outfile_[outfileMap_["HighRange"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00408       }
00409       else if (lFrame.digitalLow < frameQuality_.minZeroLight || lFrame.digitalLow > frameQuality_.maxZeroLight) {
00410         lCounters.nLowPb++;
00411         lErrors.hasLowPb = true;
00412         lFEDErrors.hasLowPb = true;
00413         if (outfileMap_.find("LowPb") != outfileMap_.end()) outfile_[outfileMap_["LowPb"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00414       }
00415       else if (lFrame.digitalHigh < frameQuality_.minTickHeight || lFrame.digitalHigh > frameQuality_.maxTickHeight){
00416         lCounters.nHighPb++;
00417         lErrors.hasHighPb = true;
00418         lFEDErrors.hasHighPb = true;
00419         if (outfileMap_.find("HighPb") != outfileMap_.end()) outfile_[outfileMap_["HighPb"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00420       }
00421       else if ( lFrame.firstHeaderBit != firstHeaderBit_ && //header in wrong position
00422                 ( (lFrame.firstHeaderBit != sistrip::SPY_SAMPLES_PER_CHANNEL && //header and 
00423                    lFrame.firstTrailerBit != sistrip::SPY_SAMPLES_PER_CHANNEL && //trailer found
00424                    lFrame.firstTrailerBit-lFrame.firstHeaderBit == 280) ||      //+ right distance between them
00425                   (lFrame.firstHeaderBit != sistrip::SPY_SAMPLES_PER_CHANNEL && // or header found
00426                    lFrame.firstTrailerBit == sistrip::SPY_SAMPLES_PER_CHANNEL && // and trailer not found
00427                    lFrame.firstHeaderBit > 16 ) || // corresponding to back-to-back frame late enough
00428                   (lFrame.firstHeaderBit == sistrip::SPY_SAMPLES_PER_CHANNEL && // or header not found
00429                    identifyTickmarks(*lDigis,lThreshold) ) // but such that tickmark compatible with OOS frame
00430                   )
00431                 ){
00432         lCounters.nOOS++;
00433         lErrors.hasOOS = true;
00434         lFEDErrors.hasOOS = true;
00435         if (outfileMap_.find("OOS") != outfileMap_.end()) outfile_[outfileMap_["OOS"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00436       }
00437       else if ( !(lFrame.firstHeaderBit == firstHeaderBit_ && lFrame.firstTrailerBit == firstTrailerBit_) ){
00438         lCounters.nOtherPbs++;
00439         lErrors.hasOtherPbs = true;
00440         lFEDErrors.hasOtherPbs = true;
00441         if (outfileMap_.find("OtherPbs") != outfileMap_.end()) outfile_[outfileMap_["OtherPbs"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00442       }
00443       else if (lFrame.apvErrorBit.first || lFrame.apvErrorBit.second) {
00444         if (lFrame.apvErrorBit.first) {
00445           lCounters.nAPVError++;
00446           lErrors.hasErrorBit0 = true;
00447           lFEDErrors.hasErrorBit0 = true;
00448         }
00449         if (lFrame.apvErrorBit.second) {
00450           lCounters.nAPVError++;
00451           lErrors.hasErrorBit1 = true;
00452           lFEDErrors.hasErrorBit1 = true;
00453         }
00454         if (outfileMap_.find("APVError") != outfileMap_.end()) {
00455           outfile_[outfileMap_["APVError"]]  << lFedId << " " << lFedChannel << " " << lDetId ;
00456           if (lFrame.apvErrorBit.first) outfile_[outfileMap_["APVError"]] << " APV0" << std::endl;
00457           if (lFrame.apvErrorBit.second) outfile_[outfileMap_["APVError"]] << " APV1" << std::endl;
00458         }
00459       }
00460       else if ( lFrame.apvAddress.first != lAPVAddrRef || 
00461                 lFrame.apvAddress.second != lAPVAddrRef ) {
00462         if (lFrame.apvAddress.first != lAPVAddrRef){
00463           lCounters.nAPVAddressError++;
00464           lErrors.hasAPVAddressError0 = true;
00465           lFEDErrors.hasAPVAddressError0 = true;
00466         }
00467         if (lFrame.apvAddress.second != lAPVAddrRef){
00468           lCounters.nAPVAddressError++;
00469           lErrors.hasAPVAddressError1 = true;
00470           lFEDErrors.hasAPVAddressError1 = true;
00471         }
00472         if (outfileMap_.find("APVAddressError") != outfileMap_.end()){
00473           outfile_[outfileMap_["APVAddressError"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00474           if (lFrame.apvAddress.first != lAPVAddrRef) outfile_[outfileMap_["APVAddressError"]]  << " APV0" << std::endl;
00475           if (lFrame.apvAddress.second != lAPVAddrRef) outfile_[outfileMap_["APVAddressError"]]  << " APV1" << std::endl;
00476         }
00477       }
00478       else if (lPayload != lPayloadDigis->end() && hasNegativePedSubtr(*lPayload,lPair)){
00479         lCounters.nNegPeds++;
00480         lErrors.hasNegPeds = true;
00481         lFEDErrors.hasNegPeds = true;
00482         if (outfileMap_.find("NegPeds") != outfileMap_.end()) outfile_[outfileMap_["NegPeds"]]  << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
00483       }
00484 
00485       histManager_.fillDetailedHistograms(lErrors,lFrame,lFedId,lFedChannel);
00486 
00487     }//loop on channels
00488 
00489 
00490     histManager_.fillFEDHistograms(lFEDErrors,lFedId);
00491 
00492   }//loop on feds
00493 
00494   double lTime;
00495   //if (fillWithEvtNum_) 
00496   //lTime = iEvent.id().event();
00497   //else if (fillWithLocalEvtNum_) lTime = evt_;
00498   //no orbit number for spy data !!
00499   //else lTime = iEvent.orbitNumber()/11223.;
00500   lTime = iEvent.id().event();
00501   if (fillWithLocalEvtNum_) lTime = evt_;
00502   
00503   histManager_.fillCountersHistograms(lCounters,lTime);
00504  
00505 
00506   //used to fill histo vs time with local event number....
00507   evt_++;
00508   firstEvent = false;
00509 
00510 }//analyze method
00511 
00512 
00513 
00514 // ------------ method called once each job just after ending the event loop  ------------
00515 void 
00516 SiStripSpyMonitorModule::endJob()
00517 {
00518 
00519   LogInfo("SiStripSpyMonitorModule") << "WriteDQMStore ? " << writeDQMStore_ 
00520                                      << " file name = " << dqmStoreFileName_
00521                                      << std::endl;
00522   if (writeDQMStore_) dqm_->save(dqmStoreFileName_);
00523 
00524   const unsigned int nFiles = outfileNames_.size();
00525   for (unsigned int i(0); i<nFiles; i++){
00526     outfile_[i].close();
00527   }
00528 
00529   outfileMap_.clear();
00530   outfileNames_.clear();
00531 
00532 }
00533 
00534 
00535 
00536 bool SiStripSpyMonitorModule::hasNegativePedSubtr(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00537                                                   uint16_t aPair)
00538 {
00539   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
00540   const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00541 
00542   uint32_t count = 0;
00543   for (; iDigi != endChannelDigis; ++iDigi) {
00544     const uint16_t val = iDigi->adc();
00545     uint16_t lPair = static_cast<uint16_t>(count/sistrip::STRIPS_PER_FEDCH);
00546     if (val == 0 && lPair == aPair) return true;
00547     count++;
00548   }
00549 
00550   return false;
00551 
00552 }
00553 
00554 bool SiStripSpyMonitorModule::identifyTickmarks(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00555                                                       const uint16_t threshold) 
00556 {
00557 
00558   //start from the end
00559   uint16_t count = sistrip::SPY_SAMPLES_PER_CHANNEL-3;
00560   uint16_t lastPos = sistrip::SPY_SAMPLES_PER_CHANNEL;
00561   uint16_t nTrailers = 0;
00562   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.end();
00563 
00564   for ( ; count == 0; count--){
00565     iDigi = findTwoConsecutive(channelDigis,threshold,count);
00566     //if found, in different position = 70 before than previous value, go and look 70 before
00567     if (iDigi != channelDigis.end() && 
00568         (lastPos == sistrip::SPY_SAMPLES_PER_CHANNEL || count == lastPos+1-70)) {
00569       nTrailers++;
00570       lastPos = count-1;
00571       count -= 70;
00572     }
00573     //else keep looking
00574     else count--;
00575   }
00576 
00577   if (nTrailers > 1) LogDebug("SiStripSpyMonitorModule") << " -- Found "
00578                                                          << nTrailers << " trailers every 70 clock cycles for channel " 
00579                                                          << channelDigis.detId() 
00580                                                          << ", evt " << evt_
00581                                                          << std::endl;
00582   //if only one found, should be < 280 otherwise header should have been found and this method would not be called
00583   return (nTrailers > 1) || (nTrailers == 1 && lastPos < 280);
00584 
00585 }
00586 
00587 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator
00588 SiStripSpyMonitorModule::findTwoConsecutive(const edm::DetSetVector<SiStripRawDigi>::detset & channelDigis,
00589                                                   const uint16_t threshold,
00590                                                   uint16_t & aCounter)
00591 {
00592   const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
00593   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator lStart = channelDigis.begin()+aCounter;
00594 
00595   bool foundTrailer = false;
00596   // Loop over digis looking for last two above threshold
00597   uint8_t aboveThreshold = 0;
00598 
00599   for (; lStart != endChannelDigis; ++lStart) {
00600     if ( lStart->adc() > threshold) {
00601       aboveThreshold++;
00602     }
00603     else {
00604       aboveThreshold = 0;
00605     }
00606     if (aboveThreshold == 2) {foundTrailer = true; break; }
00607     aCounter++;
00608   }//end of loop over digis
00609   
00610   if (foundTrailer) return lStart;
00611   else {
00612     aCounter = sistrip::SPY_SAMPLES_PER_CHANNEL;
00613     return endChannelDigis;
00614   }
00615 }
00616 
00617 //
00618 // Define as a plug-in
00619 //
00620 
00621 #include "FWCore/Framework/interface/MakerMacros.h"
00622 DEFINE_FWK_MODULE(SiStripSpyMonitorModule);
00623