CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DQM/SiStripMonitorHardware/src/SiStripCMMonitor.cc

Go to the documentation of this file.
00001 
00002 // -*- C++ -*-
00003 //
00004 // Package:    DQM/SiStripMonitorHardware
00005 // Class:      SiStripCMMonitorPlugin
00006 // 
00011 //
00012 //         Created:  2009/07/22
00013 // $Id: SiStripCMMonitor.cc,v 1.3 2013/01/03 18:59:36 wmtan Exp $
00014 //
00015 
00016 #include <sstream>
00017 #include <memory>
00018 #include <list>
00019 #include <algorithm>
00020 #include <cassert>
00021 
00022 #include "FWCore/Framework/interface/Frameworkfwd.h"
00023 #include "FWCore/Framework/interface/EDAnalyzer.h"
00024 #include "FWCore/Framework/interface/Event.h"
00025 #include "FWCore/Framework/interface/EventSetup.h"
00026 #include "FWCore/Framework/interface/ESHandle.h"
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include "FWCore/Utilities/interface/InputTag.h"
00029 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00030 #include "FWCore/ServiceRegistry/interface/Service.h"
00031 #include "FWCore/Utilities/interface/Exception.h"
00032 
00033 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00034 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00035 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00036 #include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
00037 #include "DataFormats/DetId/interface/DetId.h"
00038 
00039 #include "CondFormats/DataRecord/interface/SiStripFedCablingRcd.h"
00040 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00041 
00042 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBuffer.h"
00043 
00044 #include "DQMServices/Core/interface/DQMStore.h"
00045 #include "DQMServices/Core/interface/MonitorElement.h"
00046 
00047 #include "DQM/SiStripMonitorHardware/interface/FEDHistograms.hh"
00048 #include "DQM/SiStripMonitorHardware/interface/FEDErrors.hh"
00049 
00050 #include "DataFormats/Common/interface/DetSetVector.h"
00051 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
00052 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00053 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00054 
00055 #include "DQM/SiStripMonitorHardware/interface/CMHistograms.hh"
00056 
00057 //
00058 // Class declaration
00059 //
00060 
00061 class SiStripCMMonitorPlugin : public edm::EDAnalyzer
00062 {
00063  public:
00064 
00065   explicit SiStripCMMonitorPlugin(const edm::ParameterSet&);
00066   ~SiStripCMMonitorPlugin();
00067  private:
00068 
00069   struct Statistics {
00070     double Mean;
00071     double Rms;
00072     double Counter;
00073   };
00074 
00075   virtual void beginJob();
00076   virtual void analyze(const edm::Event&, const edm::EventSetup&);
00077   virtual void endJob();
00078 
00079   //update the cabling if necessary
00080   void updateCabling(const edm::EventSetup& eventSetup);
00081 
00082 
00083   void fillMaps(uint32_t aDetId, unsigned short aChInModule, std::pair<uint16_t,uint16_t> aMedians);
00084 
00085   //tag of FEDRawData collection
00086   edm::InputTag rawDataTag_;
00087   //folder name for histograms in DQMStore
00088   std::string folderName_;
00089   //vector of fedIDs which will have detailed histograms made
00090   std::vector<unsigned int> fedIdVec_;
00091   //book detailed histograms even if they will be empty (for merging)
00092   bool fillAllDetailedHistograms_;
00093   //do histos vs time with time=event number. Default time = orbit number (s)
00094   bool fillWithEvtNum_;
00095   bool fillWithLocalEvtNum_;
00096   //print debug messages when problems are found: 1=error debug, 2=light debug, 3=full debug
00097   unsigned int printDebug_;
00098   //write the DQMStore to a root file at the end of the job
00099   bool writeDQMStore_;
00100   std::string dqmStoreFileName_;
00101   //the DQMStore
00102   DQMStore* dqm_;
00103   //FED cabling
00104   uint32_t cablingCacheId_;
00105   const SiStripFedCabling* cabling_;
00106 
00107   //add parameter to save computing time if TkHistoMap are not filled
00108   bool doTkHistoMap_;
00109 
00110   CMHistograms cmHists_;
00111 
00112   std::map<unsigned int,Statistics> CommonModes_;
00113   std::map<unsigned int,Statistics> CommonModesAPV0minusAPV1_;
00114 
00115   std::pair<uint16_t,uint16_t> prevMedians_[FEDNumbering::MAXSiStripFEDID+1][sistrip::FEDCH_PER_FED];
00116 
00117   unsigned int evt_;
00118 
00119 };
00120 
00121 
00122 //
00123 // Constructors and destructor
00124 //
00125 
00126 SiStripCMMonitorPlugin::SiStripCMMonitorPlugin(const edm::ParameterSet& iConfig)
00127   : rawDataTag_(iConfig.getUntrackedParameter<edm::InputTag>("RawDataTag",edm::InputTag("source",""))),
00128     folderName_(iConfig.getUntrackedParameter<std::string>("HistogramFolderName","SiStrip/ReadoutView/CMMonitoring")),
00129     fedIdVec_(iConfig.getUntrackedParameter<std::vector<unsigned int> >("FedIdVec")),
00130     fillAllDetailedHistograms_(iConfig.getUntrackedParameter<bool>("FillAllDetailedHistograms",false)),
00131     fillWithEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithEventNumber",false)),
00132     fillWithLocalEvtNum_(iConfig.getUntrackedParameter<bool>("FillWithLocalEventNumber",false)),
00133     printDebug_(iConfig.getUntrackedParameter<unsigned int>("PrintDebugMessages",1)),
00134     writeDQMStore_(iConfig.getUntrackedParameter<bool>("WriteDQMStore",false)),
00135     dqmStoreFileName_(iConfig.getUntrackedParameter<std::string>("DQMStoreFileName","DQMStore.root")),
00136     dqm_(0),
00137     cablingCacheId_(0)
00138     
00139 {
00140   //print config to debug log
00141   std::ostringstream debugStream;
00142   if (printDebug_>1) {
00143     debugStream << "[SiStripCMMonitorPlugin]Configuration for SiStripCMMonitorPlugin: " << std::endl
00144                 << "[SiStripCMMonitorPlugin]\tRawDataTag: " << rawDataTag_ << std::endl
00145                 << "[SiStripCMMonitorPlugin]\tHistogramFolderName: " << folderName_ << std::endl
00146                 << "[SiStripCMMonitorPlugin]\tFillAllDetailedHistograms? " << (fillAllDetailedHistograms_ ? "yes" : "no") << std::endl
00147                 << "[SiStripCMMonitorPlugin]\tFillWithEventNumber?" << (fillWithEvtNum_ ? "yes" : "no") << std::endl
00148                 << "[SiStripCMMonitorPlugin]\tPrintDebugMessages? " << (printDebug_ ? "yes" : "no") << std::endl
00149                 << "[SiStripCMMonitorPlugin]\tWriteDQMStore? " << (writeDQMStore_ ? "yes" : "no") << std::endl;
00150     if (writeDQMStore_) debugStream << "[SiStripCMMonitorPlugin]\tDQMStoreFileName: " << dqmStoreFileName_ << std::endl;
00151   }
00152     
00153  std::ostringstream* pDebugStream = (printDebug_>1 ? &debugStream : NULL);
00154 
00155  cmHists_.initialise(iConfig,pDebugStream);
00156 
00157  doTkHistoMap_ = cmHists_.tkHistoMapEnabled();
00158 
00159  CommonModes_.clear();
00160  CommonModesAPV0minusAPV1_.clear();
00161 
00162  for (unsigned int fedId(FEDNumbering::MINSiStripFEDID); fedId <= FEDNumbering::MAXSiStripFEDID; fedId++){
00163    for (unsigned int iCh(0); iCh<sistrip::FEDCH_PER_FED; iCh++){
00164      prevMedians_[fedId][iCh] = std::pair<uint16_t,uint16_t>(0,0);
00165    }
00166  }
00167 
00168 
00169  if (printDebug_) {
00170    LogTrace("SiStripMonitorHardware") << debugStream.str();
00171  }
00172 
00173  evt_ = 0;
00174 
00175 }
00176 
00177 SiStripCMMonitorPlugin::~SiStripCMMonitorPlugin()
00178 {
00179 }
00180 
00181 
00182 //
00183 // Member functions
00184 //
00185 
00186 // ------------ method called to for each event  ------------
00187 void
00188 SiStripCMMonitorPlugin::analyze(const edm::Event& iEvent, 
00189                                  const edm::EventSetup& iSetup)
00190 {
00191   //Retrieve tracker topology from geometry
00192   edm::ESHandle<TrackerTopology> tTopoHandle;
00193   iSetup.get<IdealGeometryRecord>().get(tTopoHandle);
00194   const TrackerTopology* const tTopo = tTopoHandle.product();
00195 
00196   //static bool firstEvent = true;
00197   //static bool isBeingFilled = false;
00198   //update cabling
00199   updateCabling(iSetup);
00200   
00201   //get raw data
00202   edm::Handle<FEDRawDataCollection> rawDataCollectionHandle;
00203   iEvent.getByLabel(rawDataTag_,rawDataCollectionHandle);
00204   const FEDRawDataCollection& rawDataCollection = *rawDataCollectionHandle;
00205   
00206   //FED errors
00207   FEDErrors lFedErrors;
00208 
00209   //loop over siStrip FED IDs
00210   for (unsigned int fedId = FEDNumbering::MINSiStripFEDID; 
00211        fedId <= FEDNumbering::MAXSiStripFEDID; 
00212        fedId++) {//loop over FED IDs
00213     const FEDRawData& fedData = rawDataCollection.FEDData(fedId);
00214 
00215     //create an object to fill all errors
00216     lFedErrors.initialiseFED(fedId,cabling_,tTopo);
00217 
00218     //Do detailed check
00219     //first check if data exists
00220     bool lDataExist = lFedErrors.checkDataPresent(fedData);
00221     if (!lDataExist) {
00222       continue;
00223     }
00224 
00225     std::auto_ptr<const sistrip::FEDBuffer> buffer;
00226 
00227     if (!lFedErrors.fillFatalFEDErrors(fedData,0)) {
00228       continue;
00229     }
00230     else {
00231       //need to construct full object to go any further
00232       buffer.reset(new sistrip::FEDBuffer(fedData.data(),fedData.size(),true));
00233       bool channelLengthsOK = buffer->checkChannelLengthsMatchBufferLength();
00234       bool channelPacketCodesOK = buffer->checkChannelPacketCodes();
00235       bool feLengthsOK = buffer->checkFEUnitLengths();
00236       if ( !channelLengthsOK ||
00237            !channelPacketCodesOK ||
00238            !feLengthsOK ) {
00239         continue;
00240       }
00241     }
00242 
00243     std::ostringstream infoStream;
00244 
00245     
00246     if (printDebug_ > 1) {
00247       infoStream << " --- Processing FED #" << fedId << std::endl;
00248     }
00249 
00250 
00251     std::vector<CMHistograms::CMvalues> values;
00252 
00253     for (unsigned int iCh = 0; 
00254          iCh < sistrip::FEDCH_PER_FED; 
00255          iCh++) {//loop on channels
00256 
00257       const FedChannelConnection & lConnection = cabling_->connection(fedId,iCh);
00258       bool connected = lConnection.isConnected();
00259 
00260       //std::cout << "FedID " << fedId << ", ch " << iCh << ", nAPVPairs " << lConnection.nApvPairs() << " apvPairNumber " << lConnection.apvPairNumber() << std::endl;
00261 
00262       if (!connected) {
00263         continue;
00264       }
00265 
00266       uint32_t lDetId = lConnection.detId();
00267       unsigned short nChInModule = lConnection.nApvPairs();
00268 
00269       if (!lDetId || lDetId == sistrip::invalid32_) continue;
00270 
00271       bool lFailUnpackerChannelCheck = !buffer->channelGood(iCh) && connected;
00272 
00273       if (lFailUnpackerChannelCheck) {
00274         continue;
00275       }
00276       
00277 
00278       //short lAPVPair = lConnection.apvPairNumber();
00279       //short lSubDet = DetId(lDetId).subdetId();
00280 
00281 //       if (firstEvent){
00282 //      infoStream << "Subdet " << lSubDet << ", " ;
00283 //      if (lSubDet == 3) {
00284 //        
00285 //        infoStream << "TIB layer " << tTopo->tibLayer(lDetId)  << ", fedID " << fedId << ", channel " << iCh << std::endl;
00286 //      }
00287 //      else if (lSubDet == 4) {
00288 //        
00289 //        infoStream << "TID side " << tTopo->tibSide(lDetId)  << " wheel " << tTopo->tibWheel(lDetId) << ", ring " << tTopo->tibRing(lDetId) << ", fedID " << fedId << ", channel " << iCh << std::endl;
00290 //      }
00291 //      else if (lSubDet == 5) {
00292 //        
00293 //        infoStream << "TOB side " << tTopo->tibRod(lDetId)[0]  << " layer " << tTopo->tibLayer(lDetId) << ", rod " << tTopo->tibRodNumber(lDetId) << ", fedID " << fedId << ", channel " << iCh << std::endl;
00294 //      }
00295 //      else if (lSubDet == 6) {
00296 //        
00297 //        infoStream << "TEC side " << tTopo->tibSide(lDetId)  << " wheel " << tTopo->tibWheel(lDetId) << ", petal " << tTopo->tibPetalNumber(lDetId) << ", ring " << tTopo->tibRing(lDetId) << ", fedID " << fedId << ", channel " << iCh << std::endl;
00298 //      }
00299 //      isBeingFilled=true;
00300 //       }
00301 
00302       std::ostringstream lMode;
00303       lMode << buffer->readoutMode();
00304       if (printDebug_ > 1) {
00305         static bool lFirst = true;
00306         if (lFirst) {
00307           std::cout << "Readout mode: " << lMode.str() << std::endl;
00308           lFirst = false;
00309         }
00310 
00311       }
00312 
00313       const sistrip::FEDChannel & lChannel = buffer->channel(iCh);
00314       std::pair<uint16_t,uint16_t> medians = std::pair<uint16_t,uint16_t>(0,0);
00315 
00316       if (lMode.str().find("Zero suppressed") != lMode.str().npos && lMode.str().find("lite") == lMode.str().npos) medians = std::pair<uint16_t,uint16_t>(lChannel.cmMedian(0),lChannel.cmMedian(1));
00317       
00318       CMHistograms::CMvalues lVal;
00319       lVal.ChannelID = iCh;
00320       lVal.Medians = std::pair<uint16_t,uint16_t>(medians.first,medians.second);
00321       lVal.PreviousMedians = prevMedians_[fedId][iCh];
00322 
00323 //       if (medians.second-medians.first > 26){
00324 //      std::ostringstream info;
00325 //      if (medians.second-medians.first > 44) info << " --- Second bump: event " << iEvent.id().event() << ", FED/Channel " << fedId << "/" << iCh << ", delta=" << medians.second-medians.first << std::endl;
00326 //      else info << " --- First bump: event " << iEvent.id().event() << ", FED/Channel " << fedId << "/" << iCh << ", delta=" << medians.second-medians.first << std::endl;
00327 //      edm::LogVerbatim("SiStripMonitorHardware") << info.str();
00328 //       }
00329 
00330       if (printDebug_ > 1) {
00331         if (lChannel.length() > 7) {
00332           infoStream << "Medians for channel #" << iCh << " (length " << lChannel.length() << "): " << medians.first << ", " << medians.second << std::endl;
00333         }
00334       }
00335 
00336       values.push_back(lVal);
00337 
00338       //if (iEvent.id().event() > 1000)
00339       fillMaps(lDetId,nChInModule,medians);
00340 
00341       prevMedians_[fedId][iCh] = std::pair<uint16_t,uint16_t>(medians.first,medians.second);
00342       
00343     }//loop on channels
00344     
00345     float lTime = 0;
00346     if (fillWithEvtNum_) lTime = iEvent.id().event();
00347     else if (fillWithLocalEvtNum_) lTime = evt_;//iEvent.id().event();
00348     else lTime = iEvent.orbitNumber()/11223.;
00349 
00350     cmHists_.fillHistograms(values,lTime,fedId);
00351 
00352     //if (printDebug_ > 0 && isBeingFilled && firstEvent) edm::LogVerbatim("SiStripMonitorHardware") << infoStream.str();
00353  
00354 
00355 
00356   }//loop on FEDs
00357 
00358 
00359   //if (isBeingFilled) 
00360   //firstEvent = false;
00361 
00362   evt_++;
00363 
00364 }//analyze method
00365 
00366 // ------------ method called once each job just before starting event loop  ------------
00367 void 
00368 SiStripCMMonitorPlugin::beginJob()
00369 {
00370   //get DQM store
00371   dqm_ = &(*edm::Service<DQMStore>());
00372   dqm_->setCurrentFolder(folderName_);
00373 
00374   cmHists_.bookTopLevelHistograms(dqm_);
00375 
00376   if (fillAllDetailedHistograms_) cmHists_.bookAllFEDHistograms();
00377 
00378 }
00379 
00380 // ------------ method called once each job just after ending the event loop  ------------
00381 void 
00382 SiStripCMMonitorPlugin::endJob()
00383 {
00384 
00385   if (doTkHistoMap_) {//if TkHistoMap is enabled
00386     std::map<unsigned int,Statistics>::iterator fracIter;
00387 
00388     //int ele = 0;
00389     //int nBadChannels = 0;
00390     for (fracIter = CommonModes_.begin(); fracIter!=CommonModes_.end(); fracIter++){
00391       uint32_t detid = fracIter->first;
00392       //if ((fracIter->second).second != 0) {
00393       //std::cout << "------ ele #" << ele << ", Frac for detid #" << detid << " = " <<(fracIter->second).second << "/" << (fracIter->second).first << std::endl;
00394       //nBadChannels++;
00395       //}
00396       float mean = 0;
00397       float rms = 0;
00398       Statistics lStat = fracIter->second;
00399       if (lStat.Counter > 0) mean = lStat.Mean/lStat.Counter;
00400       if (lStat.Counter > 1) rms = sqrt(lStat.Rms/(lStat.Counter-1)-(mean*mean));
00401       cmHists_.fillTkHistoMap(cmHists_.tkHistoMapPointer(0),detid,mean);
00402       cmHists_.fillTkHistoMap(cmHists_.tkHistoMapPointer(1),detid,rms);
00403 
00404       if (printDebug_ > 1) {
00405         std::ostringstream message;
00406         message << "TkHistoMap CM: Detid " << detid << ", mean = " <<  mean << ", rms = " << rms << ", counter = " << lStat.Counter << std::endl;
00407         edm::LogVerbatim("SiStripMonitorHardware") << message.str();
00408       }
00409 
00410       //ele++;
00411     }
00412 
00413     for (fracIter = CommonModesAPV0minusAPV1_.begin(); fracIter!=CommonModesAPV0minusAPV1_.end(); fracIter++){
00414       uint32_t detid = fracIter->first;
00415       //if ((fracIter->second).second != 0) {
00416       //std::cout << "------ ele #" << ele << ", Frac for detid #" << detid << " = " <<(fracIter->second).second << "/" << (fracIter->second).first << std::endl;
00417       //nBadChannels++;
00418       //}
00419       float mean = 0;
00420       float rms = 0;
00421       Statistics lStat = fracIter->second;
00422       if (lStat.Counter > 0) mean = lStat.Mean/lStat.Counter;
00423       if (lStat.Counter > 1) rms = sqrt(lStat.Rms/(lStat.Counter-1)-(mean*mean));
00424       cmHists_.fillTkHistoMap(cmHists_.tkHistoMapPointer(2),detid,mean);
00425       cmHists_.fillTkHistoMap(cmHists_.tkHistoMapPointer(3),detid,rms);
00426 
00427       if (printDebug_ > 1) {
00428         std::ostringstream message;
00429         message << "TkHistoMap APV0minusAPV1: Detid " << detid << ", mean = " <<  mean << ", rms = " << rms << ", counter = " << lStat.Counter << std::endl;
00430         edm::LogVerbatim("SiStripMonitorHardware") << message.str();
00431       }
00432 
00433       //ele++;
00434     }
00435 
00436   }//if TkHistoMap is enabled
00437 
00438   if (writeDQMStore_) dqm_->save(dqmStoreFileName_);
00439 }
00440 
00441 void SiStripCMMonitorPlugin::updateCabling(const edm::EventSetup& eventSetup)
00442 {
00443   uint32_t currentCacheId = eventSetup.get<SiStripFedCablingRcd>().cacheIdentifier();
00444   if (cablingCacheId_ != currentCacheId) {
00445     edm::ESHandle<SiStripFedCabling> cablingHandle;
00446     eventSetup.get<SiStripFedCablingRcd>().get(cablingHandle);
00447     cabling_ = cablingHandle.product();
00448     cablingCacheId_ = currentCacheId;
00449   }
00450 }
00451 
00452 
00453 void SiStripCMMonitorPlugin::fillMaps(uint32_t aDetId, unsigned short aChInModule, std::pair<uint16_t,uint16_t> aMedians)
00454 {
00455 
00456   if (doTkHistoMap_){//if TkHistMap is enabled
00457     std::pair<std::map<unsigned int,Statistics>::iterator,bool> alreadyThere[2];
00458 
00459     Statistics lStat;
00460     lStat.Mean = (aMedians.first+aMedians.second)*1./(2*aChInModule);
00461     lStat.Rms = (aMedians.first+aMedians.second)*(aMedians.first+aMedians.second)*1./(4*aChInModule);
00462     lStat.Counter = 1./aChInModule;
00463 
00464     alreadyThere[0] = CommonModes_.insert(std::pair<unsigned int,Statistics>(aDetId,lStat));
00465     if (!alreadyThere[0].second) {
00466       ((alreadyThere[0].first)->second).Mean += (aMedians.first+aMedians.second)*1./(2*aChInModule);
00467       ((alreadyThere[0].first)->second).Rms += (aMedians.first+aMedians.second)*(aMedians.first+aMedians.second)*1./(4*aChInModule);
00468       ((alreadyThere[0].first)->second).Counter += 1./aChInModule;
00469     }
00470 
00471     lStat.Mean = (aMedians.first-aMedians.second)*1./aChInModule;
00472     lStat.Rms = (aMedians.first-aMedians.second)*(aMedians.first-aMedians.second)*1./aChInModule;
00473     lStat.Counter = 1./aChInModule;
00474 
00475     alreadyThere[1] = CommonModesAPV0minusAPV1_.insert(std::pair<unsigned int,Statistics>(aDetId,lStat));
00476     if (!alreadyThere[1].second) {
00477       ((alreadyThere[1].first)->second).Mean += (aMedians.first-aMedians.second)*1./aChInModule;
00478       ((alreadyThere[1].first)->second).Rms += (aMedians.first-aMedians.second)*(aMedians.first-aMedians.second)*1./aChInModule;
00479       ((alreadyThere[1].first)->second).Counter += 1./aChInModule;
00480     }
00481 
00482   }
00483 
00484 }
00485 
00486 
00487 //
00488 // Define as a plug-in
00489 //
00490 
00491 #include "FWCore/Framework/interface/MakerMacros.h"
00492 DEFINE_FWK_MODULE(SiStripCMMonitorPlugin);