CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_9_patch3/src/DQM/SiStripCommissioningAnalysis/src/CalibrationAlgorithm.cc

Go to the documentation of this file.
00001 #include "DQM/SiStripCommissioningAnalysis/interface/CalibrationAlgorithm.h"
00002 #include "CondFormats/SiStripObjects/interface/CalibrationAnalysis.h"
00003 #include "DataFormats/SiStripCommon/interface/SiStripHistoTitle.h"
00004 #include "DataFormats/SiStripCommon/interface/SiStripEnumsAndStrings.h"
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006 #include "DQM/SiStripCommissioningAnalysis/interface/SiStripPulseShape.h"
00007 #include "TProfile.h"
00008 #include "TF1.h"
00009 #include "TH1.h"
00010 #include "TVirtualFitter.h"
00011 #include <iostream>
00012 #include <sstream>
00013 #include <iomanip>
00014 #include <cmath>
00015 
00016 using namespace sistrip;
00017 
00018 // ----------------------------------------------------------------------------
00019 // 
00020 CalibrationAlgorithm::CalibrationAlgorithm( const edm::ParameterSet & pset, CalibrationAnalysis* const anal ) 
00021   : CommissioningAlgorithm(anal),
00022     deconv_fitter_(0),
00023     peak_fitter_(0),
00024     cal_(0)
00025 {
00026   deconv_fitter_ = new TF1("deconv_fitter",fdeconv_convoluted,-50,50,5);
00027   deconv_fitter_->FixParameter(0,0);
00028   deconv_fitter_->SetParLimits(1,-100,0);
00029   deconv_fitter_->SetParLimits(2,0,200);
00030   deconv_fitter_->SetParLimits(3,5,100);
00031   deconv_fitter_->FixParameter(3,50);
00032   deconv_fitter_->SetParLimits(4,0,50);
00033   deconv_fitter_->SetParameters(0.,-10,0.96,50,20);
00034   peak_fitter_ = new TF1("peak_fitter",fpeak_convoluted,-50,50,5);
00035   peak_fitter_->FixParameter(0,0);
00036   peak_fitter_->SetParLimits(1,-100,0);
00037   peak_fitter_->SetParLimits(2,0,400);
00038   peak_fitter_->SetParLimits(3,5,100);
00039   peak_fitter_->FixParameter(3,50);
00040   peak_fitter_->SetParLimits(4,0,50);
00041   peak_fitter_->SetParameters(0.,-10,0.96,50,20);
00042 }
00043 
00044 // ----------------------------------------------------------------------------
00045 // 
00046 void CalibrationAlgorithm::extract( const std::vector<TH1*>& histos) {
00047   if ( !anal() ) {
00048     edm::LogWarning(mlCommissioning_)
00049       << "[CalibrationAlgorithm::" << __func__ << "]"
00050       << " NULL pointer to base Analysis object!";
00051     return; 
00052   }
00053 
00054   CommissioningAnalysis* tmp = const_cast<CommissioningAnalysis*>( anal() );
00055   cal_ = dynamic_cast<CalibrationAnalysis*>( tmp );
00056   if ( !cal_ ) {
00057     edm::LogWarning(mlCommissioning_)
00058       << "[CalibrationAlgorithm::" << __func__ << "]"
00059       << " NULL pointer to derived Analysis object!";
00060     return; 
00061   }
00062 
00063   // Check number of histograms
00064   if ( histos.size() != 32 && histos.size() !=2 ) {
00065     cal_->addErrorCode(sistrip::numberOfHistos_);
00066   }
00067   
00068   // Extract FED key from histo title
00069   if ( !histos.empty() ) { cal_->fedKey( extractFedKey( histos.front() ) ); }
00070   
00071   // Extract histograms
00072   std::vector<TH1*>::const_iterator ihis = histos.begin();
00073   unsigned int cnt = 0;
00074   for ( ; ihis != histos.end(); ihis++,cnt++ ) {
00075     
00076     // Check for NULL pointer
00077     if ( !(*ihis) ) { continue; }
00078     
00079     // Check name
00080     SiStripHistoTitle title( (*ihis)->GetName() );
00081     if ( title.runType() != sistrip::CALIBRATION && 
00082          title.runType() != sistrip::CALIBRATION_DECO &&
00083          title.runType() != sistrip::CALIBRATION_SCAN && 
00084          title.runType() != sistrip::CALIBRATION_SCAN_DECO ) {
00085       cal_->addErrorCode(sistrip::unexpectedTask_);
00086       continue;
00087     }
00088     
00089     cal_->isScan_ = ( title.runType() == sistrip::CALIBRATION_SCAN || 
00090                       title.runType() == sistrip::CALIBRATION_SCAN_DECO ); 
00091     
00092     // Extract calibration histo
00093     histo_[cnt].first = *ihis;
00094     histo_[cnt].second = (*ihis)->GetTitle();
00095   }
00096   
00097 }
00098 
00099 // ----------------------------------------------------------------------------
00100 // 
00101 void CalibrationAlgorithm::analyse() { 
00102 
00103   if ( !cal_ ) {
00104     edm::LogWarning(mlCommissioning_)
00105       << "[CalibrationAlgorithm::" << __func__ << "]"
00106       << " NULL pointer to derived Analysis object!";
00107     return; 
00108   }
00109 
00110   float Amean[2]   = {0.,0.};
00111   float Amin[2]    = {2000.,2000.};
00112   float Amax[2]    = {0.,0.};
00113   float Aspread[2] = {0.,0.};
00114   float Tmean[2]   = {0.,0.};
00115   float Tmin[2]    = {2000.,2000.};
00116   float Tmax[2]    = {0.,0.};
00117   float Tspread[2] = {0.,0.};
00118   float Rmean[2]   = {0.,0.};
00119   float Rmin[2]    = {2000.,2000.};
00120   float Rmax[2]    = {0.,0.};
00121   float Rspread[2] = {0.,0.};
00122   float Cmean[2]   = {0.,0.};
00123   float Cmin[2]    = {2000.,2000.};
00124   float Cmax[2]    = {0.,0.};
00125   float Cspread[2] = {0.,0.};
00126   float Smean[2]   = {0.,0.};
00127   float Smin[2]    = {2000.,2000.};
00128   float Smax[2]    = {0.,0.};
00129   float Sspread[2] = {0.,0.};
00130   float Kmean[2]   = {0.,0.};
00131   float Kmin[2]    = {2000000.,2000000.};
00132   float Kmax[2]    = {0.,0.};
00133   float Kspread[2] = {0.,0.};
00134  
00135   unsigned int upperLimit = cal_->isScan_ ? 2 : 32;
00136   float nStrips = cal_->isScan_ ? 1. : 16.;
00137   for(unsigned int i=0;i<upperLimit;++i) {
00138     if ( !histo_[i].first ) {
00139       edm::LogWarning(mlCommissioning_) 
00140         << " NULL pointer to histogram " << i << "!";
00141       return;
00142     }
00143      
00144     // determine which APV and strip is being looked at.
00145     std::string title = histo_[i].first->GetName();
00146     int apv = 0;
00147     int strip = 0;
00148     if(title.find("STRIP")!=std::string::npos && title.find("Apv")!=std::string::npos) {
00149       strip = atoi(title.c_str()+title.find("STRIP")+6);
00150       apv = (atoi(title.c_str()+title.find("Apv")+3))%2;
00151     } else {
00152       strip = (atoi(title.c_str()+title.find_last_of("_")+1))%16;
00153       apv = (atoi(title.c_str()+title.find_last_of("_")+1))/16;
00154       if(title.find("Apv")!=std::string::npos) {
00155         apv = (atoi(title.c_str()+title.find("Apv")+3))%2;
00156         strip = strip*8 + cal_->calchan_;
00157       } else {
00158         edm::LogWarning(mlCommissioning_) 
00159           << " Malformed histogram title! Strip/APV not retreived: " 
00160           << title;
00161       }
00162     }
00163     
00164     // rescale the plot
00165     correctDistribution(histo_[i].first);
00166     
00167     // amplitude
00168     cal_->amplitude_[apv][strip] = histo_[i].first->GetMaximum();
00169     
00170     // rise time
00171     cal_->riseTime_[apv][strip] = maximum(histo_[i].first) - turnOn(histo_[i].first);
00172     
00173     // tail 125 ns after the maximum
00174     int lastBin = histo_[i].first->FindBin(histo_[i].first->GetBinCenter(histo_[i].first->GetMaximumBin())+125);
00175     if(lastBin>histo_[i].first->GetNbinsX()-4) lastBin = histo_[i].first->GetNbinsX()-4;
00176      if(histo_[i].first->GetMaximum()!=0)
00177        cal_->tail_[apv][strip] = 100*histo_[i].first->GetBinContent(lastBin)/histo_[i].first->GetMaximum();
00178      else
00179        cal_->tail_[apv][strip] = 100;
00180   
00181     // perform the fit for the next quantities
00182     TF1* fit = fitPulse(histo_[i].first);
00183     
00184     // time constant
00185     cal_->timeConstant_[apv][strip] = fit->GetParameter(3);
00186   
00187     // smearing
00188     cal_->smearing_[apv][strip] = fit->GetParameter(4);
00189   
00190     // chi2
00191     cal_->chi2_[apv][strip] = fit->GetChisquare();
00192     
00193     //compute mean, max, min, spread
00194     Amean[apv] += cal_->amplitude_[apv][strip]/nStrips;
00195     Amin[apv] = Amin[apv]<cal_->amplitude_[apv][strip] ? Amin[apv] : cal_->amplitude_[apv][strip];
00196     Amax[apv] = Amax[apv]>cal_->amplitude_[apv][strip] ? Amax[apv] : cal_->amplitude_[apv][strip];
00197     Aspread[apv] += cal_->amplitude_[apv][strip]*cal_->amplitude_[apv][strip]/nStrips;
00198     Tmean[apv] += cal_->tail_[apv][strip]/nStrips;
00199     Tmin[apv] = Tmin[apv]<cal_->tail_[apv][strip] ? Tmin[apv] : cal_->tail_[apv][strip];
00200     Tmax[apv] = Tmax[apv]>cal_->tail_[apv][strip] ? Tmax[apv] : cal_->tail_[apv][strip];
00201     Tspread[apv] += cal_->tail_[apv][strip]*cal_->tail_[apv][strip]/nStrips;
00202     Rmean[apv] += cal_->riseTime_[apv][strip]/nStrips;
00203     Rmin[apv] = Rmin[apv]<cal_->riseTime_[apv][strip] ? Rmin[apv] : cal_->riseTime_[apv][strip];
00204     Rmax[apv] = Rmax[apv]>cal_->riseTime_[apv][strip] ? Rmax[apv] : cal_->riseTime_[apv][strip];
00205     Rspread[apv] += cal_->riseTime_[apv][strip]*cal_->riseTime_[apv][strip]/nStrips;
00206     Cmean[apv] += cal_->timeConstant_[apv][strip]/nStrips;
00207     Cmin[apv] = Cmin[apv]<cal_->timeConstant_[apv][strip] ? Cmin[apv] : cal_->timeConstant_[apv][strip];
00208     Cmax[apv] = Cmax[apv]>cal_->timeConstant_[apv][strip] ? Cmax[apv] : cal_->timeConstant_[apv][strip];
00209     Cspread[apv] += cal_->timeConstant_[apv][strip]*cal_->timeConstant_[apv][strip]/nStrips;
00210     Smean[apv] += cal_->smearing_[apv][strip]/nStrips;
00211     Smin[apv] = Smin[apv]<cal_->smearing_[apv][strip] ? Smin[apv] : cal_->smearing_[apv][strip];
00212     Smax[apv] = Smax[apv]>cal_->smearing_[apv][strip] ? Smax[apv] : cal_->smearing_[apv][strip];
00213     Sspread[apv] += cal_->smearing_[apv][strip]*cal_->smearing_[apv][strip]/nStrips;
00214     Kmean[apv] += cal_->chi2_[apv][strip]/nStrips;
00215     Kmin[apv] = Kmin[apv]<cal_->chi2_[apv][strip] ? Kmin[apv] : cal_->chi2_[apv][strip];
00216     Kmax[apv] = Kmax[apv]>cal_->chi2_[apv][strip] ? Kmax[apv] : cal_->chi2_[apv][strip];
00217     Kspread[apv] += cal_->chi2_[apv][strip]*cal_->chi2_[apv][strip]/nStrips;
00218   }
00219                                 
00220   // fill the mean, max, min, spread, ... histograms.
00221   for(int i=0;i<2;++i) {
00222     cal_->mean_amplitude_[i] = Amean[i];
00223     cal_->mean_tail_[i] = Tmean[i];
00224     cal_->mean_riseTime_[i] = Rmean[i];
00225     cal_->mean_timeConstant_[i] = Cmean[i];
00226     cal_->mean_smearing_[i] = Smean[i];
00227     cal_->mean_chi2_[i] = Kmean[i];
00228     cal_->min_amplitude_[i] = Amin[i];
00229     cal_->min_tail_[i] = Tmin[i];
00230     cal_->min_riseTime_[i] = Rmin[i];
00231     cal_->min_timeConstant_[i] = Cmin[i];
00232     cal_->min_smearing_[i] = Smin[i];
00233     cal_->min_chi2_[i] = Kmin[i];
00234     cal_->max_amplitude_[i] = Amax[i];
00235     cal_->max_tail_[i] = Tmax[i];
00236     cal_->max_riseTime_[i] = Rmax[i];
00237     cal_->max_timeConstant_[i] = Cmax[i];
00238     cal_->max_smearing_[i] = Smax[i];
00239     cal_->max_chi2_[i] = Kmax[i];
00240     cal_->spread_amplitude_[i] = sqrt(fabs(Aspread[i]-Amean[i]*Amean[i]));
00241     cal_->spread_tail_[i] = sqrt(fabs(Tspread[i]-Tmean[i]*Tmean[i]));
00242     cal_->spread_riseTime_[i] = sqrt(fabs(Rspread[i]-Rmean[i]*Rmean[i]));
00243     cal_->spread_timeConstant_[i] = sqrt(fabs(Cspread[i]-Cmean[i]*Cmean[i]));
00244     cal_->spread_smearing_[i] = sqrt(fabs(Sspread[i]-Smean[i]*Smean[i]));
00245     cal_->spread_chi2_[i] = sqrt(fabs(Kspread[i]-Kmean[i]*Kmean[i]));
00246   }
00247 }
00248 
00249 // ----------------------------------------------------------------------------
00250 //
00251 void CalibrationAlgorithm::correctDistribution( TH1* histo ) const
00252 {
00253   // return the curve
00254   histo->Scale(-1);
00255   if ( cal_ ) { if( cal_->isScan_ ) histo->Scale(1/16.); }
00256 }
00257 
00258 // ----------------------------------------------------------------------------
00259 //
00260 TF1* CalibrationAlgorithm::fitPulse( TH1* histo, 
00261                                      float rangeLow, 
00262                                      float rangeHigh ) 
00263 {
00264   if(!cal_) return 0;
00265   if(!histo) return 0;
00266   float noise = 4.;
00267   float N = round(histo->GetMaximum()/125.);
00268   float error = sqrt(2*N)*noise;
00269   //float error = sqrt(2)*noise*N; // ?????????
00270   for(int i=1;i<=histo->GetNbinsX();++i) {
00271     histo->SetBinError(i,error);
00272   }
00273   if (cal_->deconv_) {
00274     if(rangeLow>rangeHigh)
00275       histo->Fit(deconv_fitter_,"Q");
00276     else 
00277       histo->Fit(deconv_fitter_,"0Q","",rangeLow,rangeHigh);
00278     return deconv_fitter_; 
00279   } else {
00280     if(rangeLow>rangeHigh)
00281       histo->Fit(peak_fitter_,"Q");
00282     else 
00283       histo->Fit(peak_fitter_,"0Q","",rangeLow,rangeHigh);
00284     return peak_fitter_; 
00285   } 
00286 }
00287 
00288 // ----------------------------------------------------------------------------
00289 //
00290 float CalibrationAlgorithm::maximum( TH1* h ) {
00291     int bin = h->GetMaximumBin();
00292     // fit around the maximum with the detector response and take the max from the fit
00293     TF1* fit = fitPulse(h,h->GetBinCenter(bin)-25,h->GetBinCenter(bin)+25);
00294     return fit->GetMaximumX();
00295 }
00296 
00297 // ----------------------------------------------------------------------------
00298 //
00299 float CalibrationAlgorithm::turnOn( TH1* h ) {
00300     // localize the rising edge
00301     int bin=1;
00302     float amplitude = h->GetMaximum();
00303     for(; bin<= h->GetNbinsX() && h->GetBinContent(bin)<0.4*amplitude; ++bin) {}
00304     float end = h->GetBinLowEdge(bin);
00305     // fit the rising edge with a sigmoid
00306     TF1* sigmoid = new TF1("sigmoid","[0]/(1+exp(-[1]*(x-[2])))+[3]",0,end);
00307     sigmoid->SetParLimits(0,amplitude/10.,amplitude);
00308     sigmoid->SetParLimits(1,0.05,0.5);
00309     sigmoid->SetParLimits(2,end-10,end+10);
00310     sigmoid->SetParLimits(3,-amplitude/10.,amplitude/10.);
00311     sigmoid->SetParameters(amplitude/2.,0.1,end,0.);
00312     h->Fit(sigmoid,"0QR");
00313     // return the point where the fit = 3% signal.
00314     float time = 0.;
00315     float base = sigmoid->GetMinimum(0,end);
00316     for(;time<end && (sigmoid->Eval(time)-base)<0.03*(amplitude-base);time += 0.1) {}
00317     delete sigmoid;
00318     return time-0.05;
00319 }
00320