CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DQM/SiStripCommissioningAnalysis/src/FastFedCablingAlgorithm.cc

Go to the documentation of this file.
00001 #include "DQM/SiStripCommissioningAnalysis/interface/FastFedCablingAlgorithm.h"
00002 #include "CondFormats/SiStripObjects/interface/FastFedCablingAnalysis.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h"
00004 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "TProfile.h"
00007 #include "TH1.h"
00008 #include <iostream>
00009 #include <sstream>
00010 #include <iomanip>
00011 #include <cmath>
00012 
00013 using namespace sistrip;
00014 
00015 // ----------------------------------------------------------------------------
00016 // 
00017 FastFedCablingAlgorithm::FastFedCablingAlgorithm( const edm::ParameterSet & pset, FastFedCablingAnalysis* const anal ) 
00018   : CommissioningAlgorithm(anal),
00019     histo_(0,"")
00020 {;}
00021 
00022 // ----------------------------------------------------------------------------
00023 // 
00024 void FastFedCablingAlgorithm::extract( const std::vector<TH1*>& histos ) { 
00025 
00026   if ( !anal() ) {
00027     edm::LogWarning(mlCommissioning_)
00028       << "[FastFedCablingAlgorithm::" << __func__ << "]"
00029       << " NULL pointer to Analysis object!";
00030     return; 
00031   }
00032   
00033   // Check number of histograms
00034   if ( histos.size() != 1 ) {
00035     anal()->addErrorCode(sistrip::numberOfHistos_);
00036   }
00037   
00038   // Extract FED key from histo title
00039   if ( !histos.empty() ) { anal()->fedKey( extractFedKey( histos.front() ) ); }
00040   
00041   // Extract histograms
00042   std::vector<TH1*>::const_iterator ihis = histos.begin();
00043   for ( ; ihis != histos.end(); ihis++ ) {
00044       
00045     // Check for NULL pointer
00046     if ( !(*ihis) ) { continue; }
00047     
00048     // Check name
00049     SiStripHistoTitle title( (*ihis)->GetName() );
00050     if ( title.runType() != sistrip::FAST_CABLING ) {
00051       anal()->addErrorCode(sistrip::unexpectedTask_);
00052       continue;
00053     }
00054 
00055     // Extract cabling histo
00056     histo_.first = *ihis;
00057     histo_.second = (*ihis)->GetName();
00058     
00059   }
00060   
00061 }
00062 
00063 // -----------------------------------------------------------------------------
00064 // 
00065 void FastFedCablingAlgorithm::analyse() { 
00066 
00067   if ( !anal() ) {
00068     edm::LogWarning(mlCommissioning_)
00069       << "[FastFedCablingAlgorithm::" << __func__ << "]"
00070       << " NULL pointer to base Analysis object!";
00071     return; 
00072   }
00073 
00074   CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() );
00075   FastFedCablingAnalysis* anal = dynamic_cast<FastFedCablingAnalysis*>( tmp );
00076   if ( !anal ) {
00077     edm::LogWarning(mlCommissioning_)
00078       << "[FastFedCablingAlgorithm::" << __func__ << "]"
00079       << " NULL pointer to derived Analysis object!";
00080     return; 
00081   }
00082 
00083   if ( !histo_.first ) {
00084     anal->addErrorCode(sistrip::nullPtr_);
00085     return;
00086   }
00087   
00088   TProfile* histo = dynamic_cast<TProfile*>(histo_.first);
00089   if ( !histo ) {
00090     anal->addErrorCode(sistrip::nullPtr_);
00091     return;
00092   }
00093 
00094   // Initialization
00095   uint16_t zero_entries = 0;
00096   uint16_t nbins = static_cast<uint16_t>( histo->GetNbinsX() );
00097   std::vector<float> contents; 
00098   std::vector<float> errors;
00099   std::vector<float> entries;
00100   contents.reserve( nbins );
00101   errors.reserve( nbins );
00102   entries.reserve( nbins );
00103 
00104   // Copy histo contents to containers and find min/max
00105   anal->max_ = -1.*sistrip::invalid_;
00106   for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) {
00107     contents.push_back( histo->GetBinContent(ibin+1) );
00108     errors.push_back( histo->GetBinError(ibin+1) );
00109     entries.push_back( histo->GetBinEntries(ibin+1) );
00110     if ( entries[ibin] ) { 
00111       if ( contents[ibin] > anal->max_ ) { anal->max_ = contents[ibin]; }
00112       if ( contents[ibin] < anal->min_ ) { anal->min_ = contents[ibin]; }
00113     } else { zero_entries++; }
00114   }
00115   if ( anal->max_ < -1. * sistrip::valid_ ) { anal->max_ = sistrip::invalid_; }
00116   
00117   // Check number of bins
00118   if ( contents.size() != FastFedCablingAnalysis::nBitsForDcuId_ + FastFedCablingAnalysis::nBitsForLldCh_ ) { 
00119     anal->addErrorCode(sistrip::numberOfBins_);
00120     return; 
00121   }
00122   
00123   // Check for bins with zero entries
00124   if ( zero_entries ) { 
00125     anal->addErrorCode(sistrip::noEntries_);
00126     return; 
00127   }
00128 
00129   // Check min and max found
00130   if ( anal->max_ > sistrip::valid_  || 
00131        anal->min_ > sistrip::valid_ ) { 
00132     return; 
00133   }
00134   
00135   // Calculate range and mid-range levels
00136   anal->range_ = anal->max_ - anal->min_;
00137   anal->midRange_ = anal->min_ + anal->range_ / 2.;
00138   
00139   // Check if range is above threshold
00140   if ( anal->range_ < FastFedCablingAnalysis::threshold_ ) {
00141     anal->addErrorCode(sistrip::smallDataRange_);
00142     return; 
00143   }
00144   
00145   // Identify samples to be either "low" or "high"
00146   std::vector<float> high;
00147   std::vector<float> low;
00148   for ( uint16_t ibin = 0; ibin < nbins; ibin++ ) { 
00149     if ( entries[ibin] ) {
00150       if ( contents[ibin] < anal->midRange_ ) { 
00151         low.push_back( contents[ibin] ); 
00152       } else { 
00153         high.push_back( contents[ibin] ); 
00154       }
00155     }
00156   }
00157 
00158   // Find median of high and low levels
00159   sort( high.begin(), high.end() );
00160   sort( low.begin(), low.end() );
00161   if ( !high.empty() ) { anal->highMedian_ = high[ high.size()%2 ? high.size()/2 : high.size()/2 ]; }
00162   if ( !low.empty() ) { anal->lowMedian_ = low[ low.size()%2 ? low.size()/2 : low.size()/2 ]; }
00163 
00164   // Check if light levels above thresholds
00165   //if ( anal->highMedian_ < FastFedCablingAnalysis::dirtyThreshold_ ) { anal->addErrorCode(sistrip::invalidLightLevel_); }
00166   //if ( anal->lowMedian_ < FastFedCablingAnalysis::trimDacThreshold_ ) { anal->addErrorCode(sistrip::invalidTrimDacLevel_); }
00167   
00168   // Find mean and rms in "low" samples
00169   anal->lowMean_ = 0.;
00170   anal->lowRms_ = 0.;
00171   for ( uint16_t ibin = 0; ibin < low.size(); ibin++ ) {
00172     anal->lowMean_ += low[ibin];
00173     anal->lowRms_ += low[ibin] * low[ibin];
00174   }
00175   if ( !low.empty() ) { 
00176     anal->lowMean_ = anal->lowMean_ / low.size();
00177     anal->lowRms_ = anal->lowRms_ / low.size();
00178   } else { 
00179     anal->lowMean_ = 1. * sistrip::invalid_;
00180     anal->lowRms_ = 1. * sistrip::invalid_;
00181   }
00182   if ( anal->lowMean_ < sistrip::valid_ ) { 
00183     anal->lowRms_ = sqrt( fabs(anal->lowRms_-anal->lowMean_*anal->lowMean_) ); 
00184   } else {
00185     anal->lowMean_ = 1. * sistrip::invalid_;
00186     anal->lowRms_ = 1. * sistrip::invalid_;
00187   }
00188 
00189   // Find mean and rms in "high" samples
00190   anal->highMean_ = 0.;
00191   anal->highRms_ = 0.;
00192   for ( uint16_t ibin = 0; ibin < high.size(); ibin++ ) {
00193     anal->highMean_ += high[ibin];
00194     anal->highRms_ += high[ibin] * high[ibin];
00195   }
00196   if ( !high.empty() ) { 
00197     anal->highMean_ = anal->highMean_ / high.size();
00198     anal->highRms_ = anal->highRms_ / high.size();
00199   } else { 
00200     anal->highMean_ = 1. * sistrip::invalid_;
00201     anal->highRms_ = 1. * sistrip::invalid_;
00202   }
00203   if ( anal->highMean_ < sistrip::valid_ ) { 
00204     anal->highRms_ = sqrt( fabs(anal->highRms_- anal->highMean_*anal->highMean_) ); 
00205   } else {
00206     anal->highMean_ = 1. * sistrip::invalid_;
00207     anal->highRms_ = 1. * sistrip::invalid_;
00208   }
00209 
00210   // Check if light levels above thresholds
00211   //if ( anal->highMean_ < FastFedCablingAnalysis::dirtyThreshold_ ) { anal->addErrorCode(sistrip::invalidLightLevel_); }
00212   //if ( anal->lowMean_ < FastFedCablingAnalysis::trimDacThreshold_ ) { anal->addErrorCode(sistrip::invalidTrimDacLevel_); }
00213 
00214   // Recalculate range
00215   if ( anal->highMean_ < 1. * sistrip::valid_ &&
00216        anal->lowMean_  < 1. * sistrip::valid_ ) { 
00217     anal->range_ = anal->highMean_ - anal->lowMean_;
00218     anal->midRange_ = anal->lowMean_ + anal->range_ / 2.;
00219   } else { 
00220     anal->range_ = 1. * sistrip::invalid_;
00221     anal->midRange_ = 1. * sistrip::invalid_;
00222   }
00223   
00224   // Check if updated range is valid and above threshold 
00225   if ( anal->range_ > 1. * sistrip::valid_ ||
00226        anal->range_ < FastFedCablingAnalysis::threshold_ ) {
00227     anal->addErrorCode(sistrip::smallDataRange_);
00228     return; 
00229   }
00230   
00231   // Extract DCU id
00232   anal->dcuHardId_ = 0;
00233   for ( uint16_t ibin = 0; ibin < FastFedCablingAnalysis::nBitsForDcuId_; ibin++ ) {
00234     if ( entries[ibin] ) {
00235       if ( contents[ibin] > anal->midRange_ ) {
00236         anal->dcuHardId_ += 0xFFFFFFFF & (1<<ibin);
00237       }
00238     }
00239   }
00240   if ( !anal->dcuHardId_ ) { anal->dcuHardId_ = sistrip::invalid32_; }
00241 
00242   // Extract DCU id
00243   anal->lldCh_ = 0;
00244   for ( uint16_t ibin = 0; ibin < FastFedCablingAnalysis::nBitsForLldCh_; ibin++ ) {
00245     if ( entries[FastFedCablingAnalysis::nBitsForDcuId_+ibin] ) {
00246       if ( contents[FastFedCablingAnalysis::nBitsForDcuId_+ibin] > anal->midRange_ ) {
00247         anal->lldCh_ += ( 0x3 & (1<<ibin) );
00248       }
00249     }
00250   }
00251   anal->lldCh_++; // starts from 1
00252   if ( !anal->lldCh_ ) { anal->lldCh_ = sistrip::invalid_; }
00253 
00254 }