CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_6/src/DQM/SiStripCommissioningAnalysis/src/PedsFullNoiseAlgorithm.cc

Go to the documentation of this file.
00001 #include "DQM/SiStripCommissioningAnalysis/interface/PedsFullNoiseAlgorithm.h"
00002 #include "CondFormats/SiStripObjects/interface/PedsFullNoiseAnalysis.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 "TH2.h"
00009 #include "TF1.h"
00010 #include <iostream>
00011 #include <iomanip>
00012 #include <cmath>
00013 
00014 using namespace sistrip;
00015 
00016 // ----------------------------------------------------------------------------
00017 // 
00018 PedsFullNoiseAlgorithm::PedsFullNoiseAlgorithm( const edm::ParameterSet & pset, PedsFullNoiseAnalysis* const anal ) 
00019   : CommissioningAlgorithm(anal),
00020     hPeds_(0,""),
00021     hNoise_(0,""),
00022     hNoise1D_(0,""),
00023     deadStripMax_(pset.getParameter<double>("DeadStripMax")),
00024     noisyStripMin_(pset.getParameter<double>("NoisyStripMin")),
00025     noiseDef_(pset.getParameter<std::string>("NoiseDefinition")),
00026     ksProbCut_(pset.getParameter<double>("KsProbCut"))
00027 {
00028   //LogDebug(mlCommissioning_)
00029   //  << "[PedsFullNoiseAlgorithm::" << __func__ << "]"
00030   //  << " Set maximum noise deviation for dead strip determination to: " << deadStripMax_;
00031         // LogDebug(mlCommissioning_)
00032   //  << "[PedsFullNoiseAlgorithm::" << __func__ << "]"
00033   //  << " Set minimal noise deviation for noise strip determination to: " << noisyStripMin_;
00034 }
00035 
00036 // ----------------------------------------------------------------------------
00037 //
00038  
00039 void PedsFullNoiseAlgorithm::extract( const std::vector<TH1*>& histos ) { 
00040 
00041   if ( !anal() ) {
00042     edm::LogWarning(mlCommissioning_)
00043       << "[PedsFullNoiseAlgorithm::" << __func__ << "]"
00044       << " NULL pointer to Analysis object!";
00045     return; 
00046   }
00047 
00048   // Check number of histograms
00049   if ( histos.size() != 3 ) { 
00050     anal()->addErrorCode(sistrip::numberOfHistos_);
00051   }
00052   
00053   // Extract FED key from histo title
00054   if ( !histos.empty() ) { 
00055     anal()->fedKey( extractFedKey( histos.front() ) );
00056   }
00057   
00058   // Extract 1D histograms
00059   std::vector<TH1*>::const_iterator ihis = histos.begin();
00060   for ( ; ihis != histos.end(); ihis++ ) {
00061     
00062     // Check for NULL pointer
00063     if ( !(*ihis) ) { continue; }
00064     
00065 // TO BE UPDATED!!!
00066     // Check run type
00067     SiStripHistoTitle title( (*ihis)->GetName() );
00068 /*    if ( title.runType() != sistrip::PEDS_FULL_NOISE ) {
00069       anal()->addErrorCode(sistrip::unexpectedTask_);
00070       continue;
00071     }
00072 */
00073     // Extract peds histos
00074     if ( title.extraInfo().find(sistrip::extrainfo::roughPedestals_) != std::string::npos ) {
00075       //@@ something here for rough peds?
00076     } else if ( title.extraInfo().find(sistrip::extrainfo::pedestals_) != std::string::npos ) {
00077       hPeds_.first = *ihis;
00078       hPeds_.second = (*ihis)->GetName();
00079     } else if ( title.extraInfo().find(sistrip::extrainfo::commonMode_) != std::string::npos ) {
00080       //@@ something here for CM plots?
00081     } else if ( title.extraInfo().find(sistrip::extrainfo::noiseProfile_) != std::string::npos ) {
00082       //@@ something here for noise profile plot?
00083       hNoise1D_.first = *ihis;
00084       hNoise1D_.second = (*ihis)->GetName();
00085     } else if ( title.extraInfo().find(sistrip::extrainfo::noise2D_) != std::string::npos ) {
00086       hNoise_.first = *ihis;
00087       hNoise_.second = (*ihis)->GetName();
00088     } else { 
00089       anal()->addErrorCode(sistrip::unexpectedExtraInfo_);
00090     }  
00091   }
00092 
00093 }
00094 
00095 // -----------------------------------------------------------------------------
00096 // 
00097 void PedsFullNoiseAlgorithm::analyse() {
00098 
00099   if ( !anal() ) {
00100     edm::LogWarning(mlCommissioning_)
00101       << "[PedsFullNoiseAlgorithm::" << __func__ << "]"
00102       << " NULL pointer to base Analysis object!";
00103     return; 
00104   }
00105 
00106   CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() );
00107   PedsFullNoiseAnalysis* ana = dynamic_cast<PedsFullNoiseAnalysis*>( tmp );
00108   if ( !ana ) {
00109     edm::LogWarning(mlCommissioning_)
00110       << "[PedsFullNoiseAlgorithm::" << __func__ << "]"
00111       << " NULL pointer to derived Analysis object!";
00112     return; 
00113   }
00114 
00115   if ( !hPeds_.first ) {
00116     ana->addErrorCode(sistrip::nullPtr_);
00117     return;
00118   }
00119 
00120   if ( !hNoise_.first ) {
00121     ana->addErrorCode(sistrip::nullPtr_);
00122     return;
00123   }
00124   
00125   TProfile * peds_histo = dynamic_cast<TProfile *>(hPeds_.first);
00126   TH2S * noise_histo            = dynamic_cast<TH2S *>(hNoise_.first);
00127   if ( !peds_histo ) {
00128     ana->addErrorCode(sistrip::nullPtr_);
00129     return;
00130   }
00131 
00132   if ( !noise_histo ) {
00133     ana->addErrorCode(sistrip::nullPtr_);
00134     return;
00135   }
00136 
00137   if ( peds_histo->GetNbinsX() != 256 ) {
00138     ana->addErrorCode(sistrip::numberOfBins_);
00139     return;
00140   }
00141 
00142   if ( noise_histo->GetNbinsY() != 256 ) { // X range is configurable
00143     ana->addErrorCode(sistrip::numberOfBins_);
00144     return;
00145   }
00146   
00147         // Iterate through APVs 
00148         for ( uint16_t iapv = 0; iapv < 2; iapv++ ) {
00149         
00150     // Used to calc mean and rms for peds and noise
00151     float p_sum = 0., p_sum2 = 0., p_max = -1.*sistrip::invalid_, p_min = sistrip::invalid_;
00152     float n_sum = 0., n_sum2 = 0., n_max = -1.*sistrip::invalid_, n_min = sistrip::invalid_;
00153     float r_sum = 0., r_sum2 = 0., r_max = -1.*sistrip::invalid_, r_min = sistrip::invalid_;               
00154     // Iterate through strips of APV
00155     for ( uint16_t istr = 0; istr < 128; istr++ ) {
00156         
00157       ana->ksProb_[iapv].push_back(0);
00158       ana->noiseGaus_[iapv].push_back(0);
00159       ana->noiseBin84_[iapv].push_back(0);
00160       ana->noiseRMS_[iapv].push_back(0);
00161       ana->noiseSignif_[iapv].push_back(0);
00162     
00163       // pedestals and raw noise
00164       if ( peds_histo ) {
00165                 if ( peds_histo->GetBinEntries(iapv*128 + istr + 1) ) {
00166                         ana->peds_[iapv][istr] = peds_histo->GetBinContent(iapv*128 + istr + 1);
00167                         p_sum += ana->peds_[iapv][istr];
00168                         p_sum2 += (ana->peds_[iapv][istr] * ana->peds_[iapv][istr]);
00169                         if ( ana->peds_[iapv][istr] > p_max ) { p_max = ana->peds_[iapv][istr];}
00170                         if ( ana->peds_[iapv][istr] < p_min ) { p_min = ana->peds_[iapv][istr];}
00171                         ana->raw_[iapv][istr] = peds_histo->GetBinError(iapv*128 + istr + 1);
00172                         r_sum += ana->raw_[iapv][istr];
00173                         r_sum2 += (ana->raw_[iapv][istr] * ana->raw_[iapv][istr]);
00174                         if ( ana->raw_[iapv][istr] > r_max ) { r_max = ana->raw_[iapv][istr]; }
00175                         if ( ana->raw_[iapv][istr] < r_min ) { r_min = ana->raw_[iapv][istr]; }
00176                 }
00177       }
00178       // Noise from Full Distribution
00179       if ( noise_histo ) {
00180         // Fit the ADC Distribution from TH2S by projecting it out and fitting.
00181         
00182         TH1S * noisehist = new TH1S("noisehist","",noise_histo->GetNbinsX(),
00183                                                         -noise_histo->GetNbinsX()/2,noise_histo->GetNbinsX()/2);
00184                     
00185         
00186         for(int i=0;i<=noise_histo->GetNbinsX()+1;i++){
00187          noisehist->SetBinContent(i,noise_histo->GetBinContent(i,iapv*128 + istr + 1));
00188         }           
00189         // If the histogram is valid.
00190         if(noisehist->Integral() > 0){
00191                 ana->noiseRMS_[iapv][istr] = noisehist->GetRMS();
00192                 noisehist->Fit("gaus","Q");                       
00193                 ana->noiseGaus_[iapv][istr]     = noisehist->GetFunction("gaus")->GetParameter(2);
00194           
00195           // new Bin84 method
00196                 std::vector<float> integralFrac;
00197                         integralFrac.push_back(1.*noisehist->GetBinContent(0)/noisehist->Integral(0,noisehist->GetNbinsX()));
00198                 // Calculate the integral of distro as a function of bins.
00199                 for(int i = 1; i < noisehist->GetNbinsX();i++){
00200                         integralFrac.push_back(float(noisehist->GetBinContent(i))/
00201                 noisehist->Integral(0,noisehist->GetNbinsX())+integralFrac[i-1]);
00202                         //Take the two bins next to 84% and solve for x in 0.84 = mx+b
00203                         if (integralFrac[i] >= 0.84135 && integralFrac[i-1] < 0.84135) {
00204                         // my quadratic noise calculation
00205                                 double w = noisehist->GetBinWidth(i);
00206                                 double a = noisehist->GetBinContent(i-1);
00207                                 double b = noisehist->GetBinContent(i);
00208                                 double f = w*(0.84135 -integralFrac[i-1])/(integralFrac[i]-integralFrac[i-1]);
00209                                 double x = 0;
00210                                 if (a==b) {
00211                                         x = f;
00212                                 } else {
00213                                         double aa = (b-a)/(2*w);
00214                                         double bb = (b+a)/2;
00215                                         double cc = -b*f;
00216                                         double dd = bb*bb-4*aa*cc; //if (dd<0) dd=0;
00217                                         x = (-bb+sqrt(dd))/(2*aa);
00218                                 }
00219                                 ana->noiseBin84_[iapv][istr] = noisehist->GetBinLowEdge(i) + x;
00220                         }
00221           } 
00222                 // Compare shape of ADC to a histogram made of Gaus Fit for KSProb, Chi2Prob, Etc...
00223                 TH1D * FitHisto = new TH1D("FitHisto","FitHisto",noisehist->GetNbinsX(),
00224                            -noisehist->GetNbinsX()/2,noisehist->GetNbinsX()/2);
00225                 FitHisto->Add(noisehist->GetFunction("gaus"));
00226                 FitHisto->Sumw2();
00227                 noisehist->Sumw2();
00228           
00229                 if(FitHisto->Integral() > 0){
00230                         // This is stored as a float but will be plotted as an int at the summary histos.
00231             // This forces the histo to draw 10000 bins instead of 1.
00232                         ana->ksProb_[iapv][istr] = noisehist->KolmogorovTest(FitHisto)*10000;
00233                 }               
00234                 delete FitHisto;
00235         }
00236         delete noisehist;    
00237       }    
00238       // Assigning the actual noise values used for Upload!!!!!!!!!!!!!!!!!!!!
00239       if (noiseDef_ == "Bin84") {
00240         if (ana->noiseBin84_[iapv][istr] > 0) {
00241           ana->noise_[iapv][istr] = ana->noiseBin84_[iapv][istr];
00242         } else {
00243           ana->noise_[iapv][istr] = ana->noiseRMS_[iapv][istr];
00244         }
00245       } else if (noiseDef_ == "RMS") {
00246         ana->noise_[iapv][istr] = ana->noiseRMS_[iapv][istr];
00247       } else edm::LogWarning(mlCommissioning_)<< "[PedsFullNoiseAlgorithm::"
00248                                 << __func__ << "]"<< " Unknown noise definition!!!";
00249       
00250       // Setting Sum of RMS and RMS^2 for Dead/Noisy Strip calculations
00251       n_sum += ana->noise_[iapv][istr];
00252       n_sum2 += (ana->noise_[iapv][istr] * ana->noise_[iapv][istr]);
00253       if ( ana->noise_[iapv][istr] > n_max ) { n_max = ana->noise_[iapv][istr]; }
00254       if ( ana->noise_[iapv][istr] < n_min ) { n_min = ana->noise_[iapv][istr]; }
00255       
00256     } // strip loop
00257   
00258     // Calc mean and rms for peds
00259     if ( !ana->peds_[iapv].empty() ) { 
00260         p_sum /= static_cast<float>( ana->peds_[iapv].size() );
00261       p_sum2 /= static_cast<float>( ana->peds_[iapv].size() );
00262       ana->pedsMean_[iapv] = p_sum;
00263       ana->pedsSpread_[iapv] = sqrt( fabs(p_sum2 - p_sum*p_sum) );
00264     }
00265   
00266     // Calc mean and rms for noise using noiseRMS.
00267     if ( !ana->noise_[iapv].empty() ) { 
00268         n_sum /= static_cast<float>( ana->noise_[iapv].size() );
00269       n_sum2 /= static_cast<float>( ana->noise_[iapv].size() );
00270       ana->noiseMean_[iapv] = n_sum;
00271       ana->noiseSpread_[iapv] = sqrt( fabs(n_sum2 - n_sum*n_sum) );
00272     }
00273 
00274     // Calc mean and rms for raw noise
00275     if ( !ana->raw_[iapv].empty() ) { 
00276         r_sum /= static_cast<float>( ana->raw_[iapv].size() );
00277       r_sum2 /= static_cast<float>( ana->raw_[iapv].size() );
00278       ana->rawMean_[iapv] = r_sum;
00279       ana->rawSpread_[iapv] = sqrt( fabs(r_sum2 - r_sum*r_sum) );
00280     }
00281       
00282     // Set max and min values for peds, noise and raw noise
00283     if ( p_max > -1.*sistrip::maximum_ ) { ana->pedsMax_[iapv] = p_max; }
00284     if ( p_min < 1.*sistrip::maximum_ )  { ana->pedsMin_[iapv] = p_min; }
00285     if ( n_max > -1.*sistrip::maximum_ ) { ana->noiseMax_[iapv] = n_max; }
00286     if ( n_min < 1.*sistrip::maximum_ )  { ana->noiseMin_[iapv] = n_min; }
00287     if ( r_max > -1.*sistrip::maximum_ ) { ana->rawMax_[iapv] = r_max; }
00288     if ( r_min < 1.*sistrip::maximum_ )  { ana->rawMin_[iapv] = r_min; }
00289   
00290     // Set dead and noisy strips
00291     for ( uint16_t istr = 0; istr < 128; istr++ ) { // strip loop 
00292       // Set the significance of the noise of each strip also compared to apv avg.
00293       ana->noiseSignif_[iapv][istr] = (ana->noise_[iapv][istr]-ana->noiseMean_[iapv])/ana->noiseSpread_[iapv];
00294       if ( ana->noiseMin_[iapv] > sistrip::maximum_ || ana->noiseMax_[iapv] > sistrip::maximum_ ) { 
00295         continue; 
00296       }
00297       // Strip Masking for Dead Strips
00298       if(ana->noiseSignif_[iapv][istr] < -deadStripMax_){
00299         ana->dead_[iapv].push_back(istr);
00300         SiStripFecKey fec_key(ana->fecKey());
00301         LogTrace(mlDqmClient_)<<"DeadSignif "<<ana->noiseSignif_[iapv][istr]
00302         <<" "<<fec_key.fecCrate()
00303         <<" "<<fec_key.fecSlot()
00304         <<" "<<fec_key.fecRing()
00305         <<" "<<fec_key.ccuAddr()
00306         <<" "<<fec_key.ccuChan()
00307         <<" "<<fec_key.lldChan()
00308         <<" "<<iapv*128+istr<<std::endl;
00309       } // Strip Masking for Dead Strips
00310       // Laurent's Method for Flagging bad strips in TIB
00311       else if((ana->noiseMax_[iapv]/ana->noiseMean_[iapv] > 3 || ana->noiseSpread_[iapv] > 3)
00312       && ana->noiseSignif_[iapv][istr] > 1){
00313         ana->noisy_[iapv].push_back(istr);
00314         SiStripFecKey fec_key(ana->fecKey());
00315         LogTrace(mlDqmClient_)<<"NoisyLM "<<ana->noiseMax_[iapv]/ana->noiseMean_[iapv]     
00316         <<" "<<fec_key.fecCrate()
00317         <<" "<<fec_key.fecSlot()
00318         <<" "<<fec_key.fecRing()
00319         <<" "<<fec_key.ccuAddr()
00320         <<" "<<fec_key.ccuChan()
00321         <<" "<<fec_key.lldChan()
00322         <<" "<<iapv*128+istr<<std::endl;
00323       } // if NoisyLM 
00324       //Strip Masking for Non Gassian Strips which are also noisy.
00325       else if(ana->ksProb_[iapv][istr] < ksProbCut_){
00326         ana->noisy_[iapv].push_back(istr);
00327         SiStripFecKey fec_key(ana->fecKey());  
00328         LogTrace(mlDqmClient_)<<"NoisyKS "<<ana->ksProb_[iapv][istr] 
00329         <<" "<<fec_key.fecCrate()
00330         <<" "<<fec_key.fecSlot()
00331         <<" "<<fec_key.fecRing()
00332         <<" "<<fec_key.ccuAddr()
00333         <<" "<<fec_key.ccuChan()
00334         <<" "<<fec_key.lldChan()
00335         <<" "<<iapv*128+istr<<std::endl;
00336       } //Strip Masking for Non Gassian Strips which are also noisy.
00337       else if(ana->noiseSignif_[iapv][istr] > noisyStripMin_){
00338         ana->noisy_[iapv].push_back(istr);
00339         SiStripFecKey fec_key(ana->fecKey());
00340         LogTrace(mlDqmClient_)<<"NoisySignif "<<ana->noiseSignif_[iapv][istr]    
00341         <<" "<<fec_key.fecCrate()
00342         <<" "<<fec_key.fecSlot()
00343         <<" "<<fec_key.fecRing()
00344         <<" "<<fec_key.ccuAddr()
00345         <<" "<<fec_key.ccuChan()
00346         <<" "<<fec_key.lldChan()
00347         <<" "<<iapv*128+istr<<std::endl;
00348       } // if Signif 
00349     }// strip loop to set dead or noisy strips   
00350         } // apv loop
00351   //std::cout << std::endl;
00352 }