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
00064 if ( histos.size() != 32 && histos.size() !=2 ) {
00065 cal_->addErrorCode(sistrip::numberOfHistos_);
00066 }
00067
00068
00069 if ( !histos.empty() ) { cal_->fedKey( extractFedKey( histos.front() ) ); }
00070
00071
00072 std::vector<TH1*>::const_iterator ihis = histos.begin();
00073 unsigned int cnt = 0;
00074 for ( ; ihis != histos.end(); ihis++,cnt++ ) {
00075
00076
00077 if ( !(*ihis) ) { continue; }
00078
00079
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
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
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
00165 correctDistribution(histo_[i].first);
00166
00167
00168 cal_->amplitude_[apv][strip] = histo_[i].first->GetMaximum();
00169
00170
00171 cal_->riseTime_[apv][strip] = maximum(histo_[i].first) - turnOn(histo_[i].first);
00172
00173
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
00182 TF1* fit = fitPulse(histo_[i].first);
00183
00184
00185 cal_->timeConstant_[apv][strip] = fit->GetParameter(3);
00186
00187
00188 cal_->smearing_[apv][strip] = fit->GetParameter(4);
00189
00190
00191 cal_->chi2_[apv][strip] = fit->GetChisquare();
00192
00193
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
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
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
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
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
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
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
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