Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:51

0001 // Original Author:  Anne-Marie Magnan
0002 //         Created:  2010/01/11
0003 //
0004 
0005 #include <sstream>
0006 #include <memory>
0007 #include <list>
0008 #include <algorithm>
0009 #include <cassert>
0010 
0011 #include "FWCore/Utilities/interface/EDGetToken.h"
0012 #include "FWCore/Framework/interface/Frameworkfwd.h"
0013 #include "FWCore/Framework/interface/Event.h"
0014 #include "FWCore/Framework/interface/EventSetup.h"
0015 #include "FWCore/Framework/interface/ESWatcher.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "FWCore/Utilities/interface/InputTag.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "FWCore/ServiceRegistry/interface/Service.h"
0020 #include "FWCore/Utilities/interface/Exception.h"
0021 
0022 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0023 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0024 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0025 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
0026 #include "DataFormats/Common/interface/DetSetVector.h"
0027 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
0028 #include "DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h"
0029 
0030 #include "CondFormats/SiStripObjects/interface/SiStripPedestals.h"
0031 #include "CondFormats/DataRecord/interface/SiStripPedestalsRcd.h"
0032 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
0033 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
0034 
0035 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
0036 
0037 // For plotting.
0038 #include "DQMServices/Core/interface/DQMStore.h"
0039 
0040 #include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
0041 #include "DQM/SiStripMonitorHardware/interface/SiStripSpyUtilities.h"
0042 #include "DQM/SiStripMonitorHardware/interface/SPYHistograms.h"
0043 
0044 #include <DQMServices/Core/interface/DQMEDAnalyzer.h>
0045 
0046 //
0047 // Class declaration
0048 //
0049 
0050 class SiStripSpyMonitorModule : public DQMEDAnalyzer {
0051 public:
0052   explicit SiStripSpyMonitorModule(const edm::ParameterSet&);
0053   ~SiStripSpyMonitorModule() override;
0054 
0055 private:
0056   void analyze(const edm::Event&, const edm::EventSetup&) override;
0057   void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0058   void dqmBeginRun(const edm::Run&, const edm::EventSetup&) override;
0059 
0060   //check if contains pedsubtr data = 0
0061   bool hasNegativePedSubtr(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, uint16_t aPair);
0062 
0063   bool identifyTickmarks(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, const uint16_t threshold);
0064 
0065   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator findTwoConsecutive(
0066       const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, const uint16_t threshold, uint16_t& aCounter);
0067 
0068   //tag of spydata collection
0069   edm::InputTag spyScopeRawDigisTag_;
0070   edm::InputTag spyPedSubtrDigisTag_;
0071 
0072   edm::EDGetTokenT<edm::DetSetVector<SiStripRawDigi> > spyScopeRawDigisToken_;
0073   edm::EDGetTokenT<edm::DetSetVector<SiStripRawDigi> > spyPedSubtrDigisToken_;
0074 
0075   //tag of l1A and apveAddress counters
0076   edm::InputTag spyL1Tag_;
0077   edm::InputTag spyTotCountTag_;
0078   edm::InputTag spyAPVeTag_;
0079 
0080   edm::EDGetTokenT<std::vector<uint32_t> > spyL1Token_;
0081   edm::EDGetTokenT<std::vector<uint32_t> > spyTotCountToken_;
0082   edm::EDGetTokenT<std::vector<uint32_t> > spyAPVeToken_;
0083 
0084   uint32_t minDigiRange_;
0085   uint32_t maxDigiRange_;
0086   uint32_t minDigitalLow_;
0087   uint32_t maxDigitalLow_;
0088   uint32_t minDigitalHigh_;
0089   uint32_t maxDigitalHigh_;
0090 
0091   edm::EventNumber_t evt_;
0092 
0093   //folder name for histograms in DQMStore
0094   std::string folderName_;
0095   //book detailed histograms even if they will be empty (for merging)
0096   bool fillAllDetailedHistograms_;
0097   //do histos vs time with time=event number. Default time = orbit number (s)
0098   bool fillWithEvtNum_;
0099   bool fillWithLocalEvtNum_;
0100 
0101   SPYHistograms histManager_;
0102   uint16_t firstHeaderBit_;
0103   uint16_t firstTrailerBit_;
0104 
0105   sistrip::SpyUtilities::FrameQuality frameQuality_;
0106 
0107   std::ofstream outfile_[20];
0108   std::vector<std::string> outfileNames_;
0109   std::map<std::string, unsigned int> outfileMap_;
0110 
0111   bool writeCabling_;
0112 
0113   edm::ESGetToken<TkDetMap, TrackerTopologyRcd> tkDetMapToken_;
0114   edm::ESGetToken<SiStripFedCabling, SiStripFedCablingRcd> fedCablingToken_;
0115   const SiStripFedCabling* fedCabling_;
0116   edm::ESWatcher<SiStripFedCablingRcd> cablingWatcher_;
0117   void updateFedCabling(const SiStripFedCablingRcd& rcd);
0118 };
0119 
0120 using edm::LogError;
0121 using edm::LogInfo;
0122 using edm::LogWarning;
0123 //
0124 // Constructors and destructor
0125 //
0126 
0127 SiStripSpyMonitorModule::SiStripSpyMonitorModule(const edm::ParameterSet& iConfig)
0128     : spyScopeRawDigisTag_(iConfig.getUntrackedParameter<edm::InputTag>(
0129           "SpyScopeRawDigisTag", edm::InputTag("SiStripSpyUnpacker", "ScopeRawDigis"))),
0130       spyPedSubtrDigisTag_(
0131           iConfig.getUntrackedParameter<edm::InputTag>("SpyPedSubtrDigisTag", edm::InputTag("SiStripFEDEmulator", ""))),
0132       spyL1Tag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyL1Tag",
0133                                                              edm::InputTag("SiStripSpyDigiConverter", "L1ACount"))),
0134       spyTotCountTag_(iConfig.getUntrackedParameter<edm::InputTag>(
0135           "SpyTotalEventCountTag", edm::InputTag("SiStripSpyDigiConverter", "TotalEventCount"))),
0136       spyAPVeTag_(iConfig.getUntrackedParameter<edm::InputTag>("SpyAPVeTag",
0137                                                                edm::InputTag("SiStripSpyDigiConverter", "APVAddress"))),
0138       folderName_(iConfig.getUntrackedParameter<std::string>("HistogramFolderName",
0139                                                              "SiStrip/ReadoutView/SpyMonitoringSummary")),
0140       fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms", false)),
0141       fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber", false)),
0142       fillWithLocalEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithLocalEventNumber", false)),
0143       firstHeaderBit_(0),
0144       firstTrailerBit_(0),
0145       outfileNames_(iConfig.getUntrackedParameter<std::vector<std::string> >("OutputErrors")),
0146       writeCabling_(iConfig.getUntrackedParameter<bool>("WriteCabling", false)),
0147       tkDetMapToken_(esConsumes<edm::Transition::BeginRun>()),
0148       fedCablingToken_(esConsumes<>()),
0149       cablingWatcher_(this, &SiStripSpyMonitorModule::updateFedCabling) {
0150   spyScopeRawDigisToken_ = consumes<edm::DetSetVector<SiStripRawDigi> >(spyScopeRawDigisTag_);
0151   spyPedSubtrDigisToken_ = consumes<edm::DetSetVector<SiStripRawDigi> >(spyPedSubtrDigisTag_);
0152 
0153   spyL1Token_ = consumes<std::vector<uint32_t> >(spyL1Tag_);
0154   spyTotCountToken_ = consumes<std::vector<uint32_t> >(spyTotCountTag_);
0155   spyAPVeToken_ = consumes<std::vector<uint32_t> >(spyAPVeTag_);
0156 
0157   evt_ = 0;
0158   std::ostringstream pDebugStream;
0159   histManager_.initialise(iConfig, &pDebugStream);
0160   const unsigned int nFiles = outfileNames_.size();
0161 
0162   for (unsigned int i(0); i < nFiles; i++) {
0163     std::ostringstream lName;
0164     lName << outfileNames_.at(i) << ".out";
0165     if (i < 20)
0166       outfile_[i].open(lName.str().c_str(), std::ios::out);
0167     outfileMap_[outfileNames_.at(i)] = i;
0168   }
0169 
0170   frameQuality_.minDigiRange = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinDigiRange", 100));
0171   frameQuality_.maxDigiRange = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxDigiRange", 1024));
0172   frameQuality_.minZeroLight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinZeroLight", 0));
0173   frameQuality_.maxZeroLight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxZeroLight", 1024));
0174   frameQuality_.minTickHeight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MinTickHeight", 0));
0175   frameQuality_.maxTickHeight = static_cast<uint16_t>(iConfig.getUntrackedParameter<uint32_t>("MaxTickHeight", 1024));
0176 }
0177 
0178 SiStripSpyMonitorModule::~SiStripSpyMonitorModule() {
0179   const unsigned int nFiles = outfileNames_.size();
0180   for (unsigned int i(0); i < nFiles; i++) {
0181     outfile_[i].close();
0182   }
0183 
0184   outfileMap_.clear();
0185   outfileNames_.clear();
0186 }
0187 
0188 void SiStripSpyMonitorModule::updateFedCabling(const SiStripFedCablingRcd& rcd) {
0189   fedCabling_ = &rcd.get(fedCablingToken_);
0190 }
0191 
0192 void SiStripSpyMonitorModule::dqmBeginRun(const edm::Run& r, const edm::EventSetup& c) {
0193   evt_ = 0;
0194   firstHeaderBit_ = 0;
0195   firstTrailerBit_ = 0;
0196 }
0197 
0198 void SiStripSpyMonitorModule::bookHistograms(DQMStore::IBooker& ibooker,
0199                                              const edm::Run& run,
0200                                              const edm::EventSetup& eSetup) {
0201   ibooker.setCurrentFolder(folderName_);
0202 
0203   LogInfo("SiStripSpyMonitorModule") << " Histograms will be written in " << folderName_
0204                                      << ". Current folder is : " << ibooker.pwd() << std::endl;
0205 
0206   const auto tkDetMap = &eSetup.getData(tkDetMapToken_);
0207   //this propagates dqm_ to the histoclass, must be called !
0208   histManager_.bookTopLevelHistograms(ibooker, tkDetMap);
0209 
0210   if (fillAllDetailedHistograms_)
0211     histManager_.bookAllFEDHistograms(ibooker);
0212 
0213   //dummy error object
0214   SPYHistograms::Errors lError = {};
0215   for (uint16_t lFedId = sistrip::FED_ID_MIN; lFedId <= sistrip::FED_ID_MAX; ++lFedId)
0216     histManager_.bookFEDHistograms(ibooker, lFedId, lError, true);
0217 }
0218 
0219 // ------------ method called to for each event  ------------
0220 void SiStripSpyMonitorModule::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0221   //update cabling and pedestals
0222   cablingWatcher_.check(iSetup);
0223   if (evt_ == 0 && writeCabling_) {
0224     std::ofstream lOutCabling;
0225     lOutCabling.open("trackerDetId_FEDIdChNum_list.txt", std::ios::out);
0226     for (uint16_t lFedId = sistrip::FED_ID_MIN; lFedId <= sistrip::FED_ID_MAX; ++lFedId) {   //loop on feds
0227       for (uint16_t lFedChannel = 0; lFedChannel < sistrip::FEDCH_PER_FED; lFedChannel++) {  //loop on channels
0228         const FedChannelConnection& lConnection = fedCabling_->fedConnection(lFedId, lFedChannel);
0229         if (!lConnection.isConnected())
0230           continue;
0231         uint32_t lDetId = lConnection.detId();
0232         lOutCabling << "FED ID = " << lFedId << ", Channel = " << lFedChannel
0233                     << ",fedkey = " << sistrip::FEDCH_PER_FED * lFedId + lFedChannel << ", detId = " << lDetId
0234                     << std::endl;
0235       }
0236     }
0237     lOutCabling.close();
0238   }
0239 
0240   //For spy data
0241   //get map of TotalEventCount and L1ID, indexed by fedId, and APVaddress indexed by fedIndex.
0242   edm::Handle<std::vector<uint32_t> > lSpyL1IDHandle, lSpyTotCountHandle, lSpyAPVeHandle;
0243   try {
0244     iEvent.getByToken(spyL1Token_, lSpyL1IDHandle);
0245     iEvent.getByToken(spyTotCountToken_, lSpyTotCountHandle);
0246     iEvent.getByToken(spyAPVeToken_, lSpyAPVeHandle);
0247   } catch (const cms::Exception& e) {
0248     LogError("SiStripSpyMonitorModule") << e.what();
0249     return;
0250   }
0251   //const std::map<uint32_t,uint32_t> & lSpyMaxCountMap = *lSpyL1IDHandle;
0252   //const std::map<uint32_t,uint32_t> & lSpyMinCountMap = *lSpyTotCountHandle;
0253   const std::vector<uint32_t>& lSpyAPVeVec = *lSpyAPVeHandle;
0254 
0255   //retrieve the scope digis
0256   edm::Handle<edm::DetSetVector<SiStripRawDigi> > digisHandle;
0257   try {
0258     iEvent.getByToken(spyScopeRawDigisToken_, digisHandle);
0259   } catch (const cms::Exception& e) {
0260     LogError("SiStripSpyMonitorModule") << e.what();
0261     return;
0262   }
0263   const edm::DetSetVector<SiStripRawDigi>* lInputDigis = digisHandle.product();
0264 
0265   //retrieve the reordered payload digis
0266   edm::Handle<edm::DetSetVector<SiStripRawDigi> > payloadHandle;
0267   try {
0268     iEvent.getByToken(spyPedSubtrDigisToken_, payloadHandle);
0269   } catch (const cms::Exception& e) {
0270     LogError("SiStripSpyMonitorModule") << e.what();
0271     return;
0272   }
0273   const edm::DetSetVector<SiStripRawDigi>* lPayloadDigis = payloadHandle.product();
0274 
0275   //for first event only
0276   //loop first on channels to calculate majority value of when the first header bit is found.
0277   //output info message to give the value found
0278   //should currently be 6 but may vary in the futur
0279   //then we can check firstTrailerBit is +256+24 after
0280 
0281   if (evt_ == 0) {
0282     sistrip::SpyUtilities::getMajorityHeader(lInputDigis, firstHeaderBit_);
0283     firstTrailerBit_ = firstHeaderBit_ + 24 + sistrip::STRIPS_PER_FEDCH;
0284   }
0285 
0286   //initialise some counters, filled in histos eventually
0287   SPYHistograms::ErrorCounters lCounters;
0288   lCounters.nNoData = 0;
0289   lCounters.nLowRange = 0;
0290   lCounters.nHighRange = 0;
0291   lCounters.nMinZero = 0;
0292   lCounters.nMaxSat = 0;
0293   lCounters.nLowPb = 0;
0294   lCounters.nHighPb = 0;
0295   lCounters.nOOS = 0;
0296   lCounters.nOtherPbs = 0;
0297   lCounters.nAPVError = 0;
0298   lCounters.nAPVAddressError = 0;
0299   lCounters.nNegPeds = 0;
0300 
0301   //fill event number for output text files
0302   const unsigned int nFiles = outfileNames_.size();
0303   for (unsigned int i(0); i < nFiles; i++) {
0304     outfile_[i] << "**** evt " << iEvent.id().event() << " ****" << std::endl;
0305   }
0306 
0307   //loop over all FEDs and channels
0308 
0309   for (uint16_t lFedId = sistrip::FED_ID_MIN; lFedId <= sistrip::FED_ID_MAX; ++lFedId) {  //loop on feds
0310 
0311     SPYHistograms::Errors lFEDErrors;
0312     lFEDErrors.hasNoData = false;
0313     lFEDErrors.hasLowRange = false;
0314     lFEDErrors.hasHighRange = false;
0315     lFEDErrors.hasMinZero = false;
0316     lFEDErrors.hasMaxSat = false;
0317     lFEDErrors.hasLowPb = false;
0318     lFEDErrors.hasHighPb = false;
0319     lFEDErrors.hasOOS = false;
0320     lFEDErrors.hasOtherPbs = false;
0321     lFEDErrors.hasErrorBit0 = false;
0322     lFEDErrors.hasErrorBit1 = false;
0323     lFEDErrors.hasAPVAddressError0 = false;
0324     lFEDErrors.hasAPVAddressError1 = false;
0325     lFEDErrors.hasNegPeds = false;
0326 
0327     uint32_t lAPVAddrRef = lSpyAPVeVec.at(lFedId);
0328 
0329     for (uint16_t lFedChannel = 0; lFedChannel < sistrip::FEDCH_PER_FED; lFedChannel++) {  //loop on channels
0330 
0331       uint32_t lFedIndex = sistrip::FEDCH_PER_FED * lFedId + lFedChannel;
0332 
0333       const FedChannelConnection& lConnection = fedCabling_->fedConnection(lFedId, lFedChannel);
0334 
0335       if (!lConnection.isConnected())
0336         continue;
0337 
0338       uint32_t lDetId = lConnection.detId();
0339       //uint16_t lNPairs = lConnection.nApvPairs();
0340       uint16_t lPair = lConnection.apvPairNumber();
0341 
0342       edm::DetSetVector<SiStripRawDigi>::const_iterator lDigis = lInputDigis->find(lFedIndex);
0343 
0344       //pedsubtr digis
0345       edm::DetSetVector<SiStripRawDigi>::const_iterator lPayload = lPayloadDigis->find(lDetId);
0346 
0347       //no digis found, continue.
0348       if (lDigis == lInputDigis->end()) {
0349         LogDebug("SiStripSpyMonitorModule") << " -- digis not found in ScopeRawDigis map for FEDID " << lFedId
0350                                             << " and FED channel " << lFedChannel << std::endl;
0351         continue;
0352       }
0353 
0354       sistrip::SpyUtilities::Frame lFrame = sistrip::SpyUtilities::extractFrameInfo(*lDigis);
0355 
0356       SPYHistograms::Errors lErrors;
0357       lErrors.hasNoData = false;
0358       lErrors.hasLowRange = false;
0359       lErrors.hasHighRange = false;
0360       lErrors.hasMinZero = false;
0361       lErrors.hasMaxSat = false;
0362       lErrors.hasLowPb = false;
0363       lErrors.hasHighPb = false;
0364       lErrors.hasOOS = false;
0365       lErrors.hasOtherPbs = false;
0366       lErrors.hasErrorBit0 = false;
0367       lErrors.hasErrorBit1 = false;
0368       lErrors.hasAPVAddressError0 = false;
0369       lErrors.hasAPVAddressError1 = false;
0370       lErrors.hasNegPeds = false;
0371 
0372       uint16_t lRange = sistrip::SpyUtilities::range(lFrame);
0373       uint16_t lThreshold = sistrip::SpyUtilities::threshold(lFrame);
0374 
0375       if (lRange == 0) {
0376         lCounters.nNoData++;
0377         lErrors.hasNoData = true;
0378         lFEDErrors.hasNoData = true;
0379         if (outfileMap_.find("NoData") != outfileMap_.end())
0380           outfile_[outfileMap_["NoData"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0381       } else if (lFrame.digitalLow == 0 && lRange > 0) {
0382         lCounters.nMinZero++;
0383         lErrors.hasMinZero = true;
0384         lFEDErrors.hasMinZero = true;
0385         if (outfileMap_.find("MinZero") != outfileMap_.end())
0386           outfile_[outfileMap_["MinZero"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0387       } else if (lFrame.digitalHigh >= 1023) {
0388         lCounters.nMaxSat++;
0389         lErrors.hasMaxSat = true;
0390         lFEDErrors.hasMaxSat = true;
0391         if (outfileMap_.find("MaxSat") != outfileMap_.end())
0392           outfile_[outfileMap_["MaxSat"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0393       } else if (lRange > 0 && lRange < frameQuality_.minDigiRange) {
0394         lCounters.nLowRange++;
0395         lErrors.hasLowRange = true;
0396         lFEDErrors.hasLowRange = true;
0397         if (outfileMap_.find("LowRange") != outfileMap_.end())
0398           outfile_[outfileMap_["LowRange"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0399       } else if (lRange > frameQuality_.maxDigiRange) {
0400         lCounters.nHighRange++;
0401         lErrors.hasHighRange = true;
0402         lFEDErrors.hasHighRange = true;
0403         if (outfileMap_.find("HighRange") != outfileMap_.end())
0404           outfile_[outfileMap_["HighRange"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0405       } else if (lFrame.digitalLow < frameQuality_.minZeroLight || lFrame.digitalLow > frameQuality_.maxZeroLight) {
0406         lCounters.nLowPb++;
0407         lErrors.hasLowPb = true;
0408         lFEDErrors.hasLowPb = true;
0409         if (outfileMap_.find("LowPb") != outfileMap_.end())
0410           outfile_[outfileMap_["LowPb"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0411       } else if (lFrame.digitalHigh < frameQuality_.minTickHeight || lFrame.digitalHigh > frameQuality_.maxTickHeight) {
0412         lCounters.nHighPb++;
0413         lErrors.hasHighPb = true;
0414         lFEDErrors.hasHighPb = true;
0415         if (outfileMap_.find("HighPb") != outfileMap_.end())
0416           outfile_[outfileMap_["HighPb"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0417       } else if (lFrame.firstHeaderBit != firstHeaderBit_ &&                      //header in wrong position
0418                  ((lFrame.firstHeaderBit != sistrip::SPY_SAMPLES_PER_CHANNEL &&   //header and
0419                    lFrame.firstTrailerBit != sistrip::SPY_SAMPLES_PER_CHANNEL &&  //trailer found
0420                    lFrame.firstTrailerBit - lFrame.firstHeaderBit == 280) ||      //+ right distance between them
0421                   (lFrame.firstHeaderBit != sistrip::SPY_SAMPLES_PER_CHANNEL &&   // or header found
0422                    lFrame.firstTrailerBit == sistrip::SPY_SAMPLES_PER_CHANNEL &&  // and trailer not found
0423                    lFrame.firstHeaderBit > 16) ||  // corresponding to back-to-back frame late enough
0424                   (lFrame.firstHeaderBit == sistrip::SPY_SAMPLES_PER_CHANNEL &&  // or header not found
0425                    identifyTickmarks(*lDigis, lThreshold))  // but such that tickmark compatible with OOS frame
0426                   )) {
0427         lCounters.nOOS++;
0428         lErrors.hasOOS = true;
0429         lFEDErrors.hasOOS = true;
0430         if (outfileMap_.find("OOS") != outfileMap_.end())
0431           outfile_[outfileMap_["OOS"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0432       } else if (!(lFrame.firstHeaderBit == firstHeaderBit_ && lFrame.firstTrailerBit == firstTrailerBit_)) {
0433         lCounters.nOtherPbs++;
0434         lErrors.hasOtherPbs = true;
0435         lFEDErrors.hasOtherPbs = true;
0436         if (outfileMap_.find("OtherPbs") != outfileMap_.end())
0437           outfile_[outfileMap_["OtherPbs"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0438       } else if (lFrame.apvErrorBit.first || lFrame.apvErrorBit.second) {
0439         if (lFrame.apvErrorBit.first) {
0440           lCounters.nAPVError++;
0441           lErrors.hasErrorBit0 = true;
0442           lFEDErrors.hasErrorBit0 = true;
0443         }
0444         if (lFrame.apvErrorBit.second) {
0445           lCounters.nAPVError++;
0446           lErrors.hasErrorBit1 = true;
0447           lFEDErrors.hasErrorBit1 = true;
0448         }
0449         if (outfileMap_.find("APVError") != outfileMap_.end()) {
0450           outfile_[outfileMap_["APVError"]] << lFedId << " " << lFedChannel << " " << lDetId;
0451           if (lFrame.apvErrorBit.first)
0452             outfile_[outfileMap_["APVError"]] << " APV0" << std::endl;
0453           if (lFrame.apvErrorBit.second)
0454             outfile_[outfileMap_["APVError"]] << " APV1" << std::endl;
0455         }
0456       } else if (lFrame.apvAddress.first != lAPVAddrRef || lFrame.apvAddress.second != lAPVAddrRef) {
0457         if (lFrame.apvAddress.first != lAPVAddrRef) {
0458           lCounters.nAPVAddressError++;
0459           lErrors.hasAPVAddressError0 = true;
0460           lFEDErrors.hasAPVAddressError0 = true;
0461         }
0462         if (lFrame.apvAddress.second != lAPVAddrRef) {
0463           lCounters.nAPVAddressError++;
0464           lErrors.hasAPVAddressError1 = true;
0465           lFEDErrors.hasAPVAddressError1 = true;
0466         }
0467         if (outfileMap_.find("APVAddressError") != outfileMap_.end()) {
0468           outfile_[outfileMap_["APVAddressError"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0469           if (lFrame.apvAddress.first != lAPVAddrRef)
0470             outfile_[outfileMap_["APVAddressError"]] << " APV0" << std::endl;
0471           if (lFrame.apvAddress.second != lAPVAddrRef)
0472             outfile_[outfileMap_["APVAddressError"]] << " APV1" << std::endl;
0473         }
0474       } else if (lPayload != lPayloadDigis->end() && hasNegativePedSubtr(*lPayload, lPair)) {
0475         lCounters.nNegPeds++;
0476         lErrors.hasNegPeds = true;
0477         lFEDErrors.hasNegPeds = true;
0478         if (outfileMap_.find("NegPeds") != outfileMap_.end())
0479           outfile_[outfileMap_["NegPeds"]] << lFedId << " " << lFedChannel << " " << lDetId << std::endl;
0480       }
0481 
0482       histManager_.fillDetailedHistograms(lErrors, lFrame, lFedId, lFedChannel);
0483 
0484     }  //loop on channels
0485 
0486     histManager_.fillFEDHistograms(lFEDErrors, lFedId);
0487 
0488   }  //loop on feds
0489 
0490   double lTime;
0491   //if (fillWithEvtNum_)
0492   //lTime = iEvent.id().event();
0493   //else if (fillWithLocalEvtNum_) lTime = evt_;
0494   //no orbit number for spy data !!
0495   //else lTime = iEvent.orbitNumber()/11223.;
0496   if (fillWithLocalEvtNum_) {
0497     // casting from unsigned long long to a double here
0498     // doing it explicitely
0499     lTime = static_cast<double>(evt_);
0500   } else {
0501     // casting from unsigned long long to a double here
0502     // doing it explicitely
0503     lTime = static_cast<double>(iEvent.id().event());
0504   }
0505 
0506   histManager_.fillCountersHistograms(lCounters, lTime);
0507 
0508   //used to fill histo vs time with local event number....
0509   evt_++;
0510 
0511 }  //analyze method
0512 
0513 bool SiStripSpyMonitorModule::hasNegativePedSubtr(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0514                                                   uint16_t aPair) {
0515   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.begin();
0516   const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0517 
0518   uint32_t count = 0;
0519   for (; iDigi != endChannelDigis; ++iDigi) {
0520     const uint16_t val = iDigi->adc();
0521     uint16_t lPair = static_cast<uint16_t>(count / sistrip::STRIPS_PER_FEDCH);
0522     if (val == 0 && lPair == aPair)
0523       return true;
0524     count++;
0525   }
0526 
0527   return false;
0528 }
0529 
0530 bool SiStripSpyMonitorModule::identifyTickmarks(const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis,
0531                                                 const uint16_t threshold) {
0532   //start from the end
0533   uint16_t count = sistrip::SPY_SAMPLES_PER_CHANNEL - 3;
0534   uint16_t lastPos = sistrip::SPY_SAMPLES_PER_CHANNEL;
0535   uint16_t nTrailers = 0;
0536   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator iDigi = channelDigis.end();
0537 
0538   for (; count == 0; count--) {
0539     iDigi = findTwoConsecutive(channelDigis, threshold, count);
0540     //if found, in different position = 70 before than previous value, go and look 70 before
0541     if (iDigi != channelDigis.end() && (lastPos == sistrip::SPY_SAMPLES_PER_CHANNEL || count == lastPos + 1 - 70)) {
0542       nTrailers++;
0543       lastPos = count - 1;
0544       count -= 70;
0545     }
0546     //else keep looking
0547     else
0548       count--;
0549   }
0550 
0551   if (nTrailers > 1)
0552     LogDebug("SiStripSpyMonitorModule") << " -- Found " << nTrailers << " trailers every 70 clock cycles for channel "
0553                                         << channelDigis.detId() << ", evt " << evt_ << std::endl;
0554   //if only one found, should be < 280 otherwise header should have been found and this method would not be called
0555   return (nTrailers > 1) || (nTrailers == 1 && lastPos < 280);
0556 }
0557 
0558 edm::DetSetVector<SiStripRawDigi>::detset::const_iterator SiStripSpyMonitorModule::findTwoConsecutive(
0559     const edm::DetSetVector<SiStripRawDigi>::detset& channelDigis, const uint16_t threshold, uint16_t& aCounter) {
0560   const edm::DetSetVector<SiStripRawDigi>::detset::const_iterator endChannelDigis = channelDigis.end();
0561   edm::DetSetVector<SiStripRawDigi>::detset::const_iterator lStart = channelDigis.begin() + aCounter;
0562 
0563   bool foundTrailer = false;
0564   // Loop over digis looking for last two above threshold
0565   uint8_t aboveThreshold = 0;
0566 
0567   for (; lStart != endChannelDigis; ++lStart) {
0568     if (lStart->adc() > threshold) {
0569       aboveThreshold++;
0570     } else {
0571       aboveThreshold = 0;
0572     }
0573     if (aboveThreshold == 2) {
0574       foundTrailer = true;
0575       break;
0576     }
0577     aCounter++;
0578   }  //end of loop over digis
0579 
0580   if (foundTrailer)
0581     return lStart;
0582   else {
0583     aCounter = sistrip::SPY_SAMPLES_PER_CHANNEL;
0584     return endChannelDigis;
0585   }
0586 }
0587 
0588 //
0589 // Define as a plug-in
0590 //
0591 
0592 #include "FWCore/Framework/interface/MakerMacros.h"
0593 DEFINE_FWK_MODULE(SiStripSpyMonitorModule);