Go to the documentation of this file.00001 #include "CalibCalorimetry/EcalPedestalOffsets/interface/TPedValues.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003
00004 #include <math.h>
00005 #include <iostream>
00006 #include <cassert>
00007 #include "TGraphErrors.h"
00008 #include "TAxis.h"
00009 #include "TF1.h"
00010
00011 void reset (double vett[256])
00012 {
00013 for (int i=0 ; i<256; ++i) vett[i] = 0. ;
00014 }
00015
00016
00017 TPedValues::TPedValues (double RMSmax, int bestPedestal) :
00018 m_bestPedestal (bestPedestal) ,
00019 m_RMSmax (RMSmax)
00020 {
00021 LogDebug ("EcalPedOffset") << "entering TPedValues ctor ..." ;
00022 for(int i=0; i<1700;++i)
00023 endcapCrystalNumbers[i] = 0;
00024 }
00025
00026
00027 TPedValues::TPedValues (const TPedValues & orig)
00028 {
00029 LogDebug ("EcalPedOffset") << "entering TPedValues copyctor ..." ;
00030 m_bestPedestal = orig.m_bestPedestal ;
00031 m_RMSmax = orig.m_RMSmax ;
00032
00033 for (int gain = 0 ; gain < 3 ; ++gain)
00034 for (int crystal = 0 ; crystal < 1700 ; ++crystal)
00035 for (int DAC = 0 ; DAC < 256 ; ++DAC)
00036 m_entries[gain][crystal][DAC] = orig.m_entries[gain][crystal][DAC] ;
00037
00038 for(int i=0; i<1700;++i)
00039 endcapCrystalNumbers[i] = orig.endcapCrystalNumbers[i];
00040 }
00041
00042
00043
00044 TPedValues::~TPedValues () {}
00045
00046
00047 void TPedValues::insert (const int gainId,
00048 const int crystal,
00049 const int DAC,
00050 const int pedestal,
00051 const int endcapIndex)
00052 {
00053
00054
00055 if (gainId <= 0 || gainId >= 4)
00056 {
00057 edm::LogWarning ("EcalPedOffset") << "WARNING : TPedValues : gainId " << gainId
00058 << " does not exist, entry skipped" ;
00059 return ;
00060 }
00061
00062
00063 if (crystal <= 0 || crystal > 1700)
00064 {
00065 edm::LogWarning ("EcalPedOffset") << "WARNING : TPedValues : crystal " << crystal
00066 << " does not exist, entry skipped" ;
00067 return ;
00068 }
00069
00070
00071 if (DAC < 0 || DAC >= 256)
00072 {
00073 edm::LogWarning ("EcalPedOffset") << "WARNING : TPedValues : DAC value " << DAC
00074 << " is out range, entry skipped" ;
00075 return ;
00076 }
00077 m_entries[gainId-1][crystal-1][DAC].insert (pedestal) ;
00078 endcapCrystalNumbers[crystal-1] = endcapIndex;
00079 return ;
00080 }
00081
00082
00083 TPedResult TPedValues::terminate (const int & DACstart, const int & DACend) const
00084 {
00085 assert (DACstart >= 0) ;
00086 assert (DACend <= 256) ;
00087
00088
00089 TPedResult bestDAC ;
00091 for (int gainId = 1 ; gainId < 4 ; ++gainId)
00092 {
00094 for (int crystal = 0 ; crystal < 1700 ; ++crystal)
00095 {
00097 double delta = 1000 ;
00098 int dummyBestDAC = -1 ;
00099 bool hasDigis = false;
00101 for (int DAC = DACstart ; DAC < DACend ; ++DAC)
00102 {
00103 double average = m_entries[gainId-1][crystal][DAC].average () ;
00104 if (average == -1) continue ;
00105 hasDigis = true;
00106 if (m_entries[gainId-1][crystal][DAC].RMSSq () > m_RMSmax * m_RMSmax) continue ;
00107 if (fabs (average - m_bestPedestal) < delta && average>1 )
00108 {
00109 delta = fabs (average - m_bestPedestal) ;
00110 dummyBestDAC = DAC ;
00111 }
00112 }
00113
00114 bestDAC.m_DACvalue[gainId-1][crystal] = dummyBestDAC ;
00115
00116 if ((dummyBestDAC == (DACend-1) || dummyBestDAC == -1) && hasDigis)
00117 {
00118 int gainHuman;
00119 if (gainId ==1) gainHuman =12;
00120 else if (gainId ==2) gainHuman =6;
00121 else if (gainId ==3) gainHuman =1;
00122 else gainHuman =-1;
00123 edm::LogError("EcalPedOffset")
00124 << " TPedValues : cannot find best DAC value for channel: "
00125 << endcapCrystalNumbers[crystal]
00126 << " gain: " << gainHuman;
00127 }
00128
00129 }
00130 }
00131 return bestDAC ;
00132 }
00133
00134
00135 int TPedValues::checkEntries (const int & DACstart, const int & DACend) const
00136 {
00137 assert (DACstart >= 0) ;
00138 assert (DACend <= 256) ;
00139 int returnCode = 0 ;
00141 for (int gainId = 1 ; gainId < 4 ; ++gainId)
00142 {
00144 for (int crystal = 0 ; crystal < 1700 ; ++crystal)
00145 {
00147 for (int DAC = DACstart ; DAC < DACend ; ++DAC)
00148 {
00149 double average = m_entries[gainId-1][crystal][DAC].average () ;
00150 if (average == -1)
00151 {
00152 ++returnCode ;
00154
00155
00156
00157
00158
00159
00160
00161
00162 }
00163
00164
00165
00166
00167
00168
00169
00170 }
00171 }
00172 }
00173 return returnCode ;
00174 }
00175
00176
00178 int TPedValues::makePlots (TFile * rootFile, const std::string & dirName,
00179 const double maxSlope, const double minSlope, const double maxChi2OverNDF) const
00180 {
00181 using namespace std;
00182
00183 if (!rootFile->cd (dirName.c_str ()))
00184 {
00185 rootFile->mkdir (dirName.c_str ()) ;
00186 rootFile->cd (dirName.c_str ()) ;
00187 }
00188
00189
00190 for (int xtl=0 ; xtl<1700 ; ++xtl)
00191 {
00192
00193 for (int gain=0 ; gain<3 ; ++gain)
00194 {
00195 vector<double> asseX;
00196 vector<double> sigmaX;
00197 vector<double> asseY;
00198 vector<double> sigmaY;
00199 asseX.reserve(256);
00200 sigmaX.reserve(256);
00201 asseY.reserve(256);
00202 sigmaY.reserve(256);
00203
00204 for (int dac=0 ; dac<256 ; ++dac)
00205 {
00206 double average = m_entries[gain][xtl][dac].average();
00207 if(average > -1)
00208 {
00209 double rms = m_entries[gain][xtl][dac].RMS();
00210 asseX.push_back(dac);
00211 sigmaX.push_back(0);
00212 asseY.push_back(average);
00213 sigmaY.push_back(rms);
00214 }
00215 }
00216 if(asseX.size() > 0)
00217 {
00218 int lastBin = 0;
00219 while(lastBin<(int)asseX.size()-1 && asseY[lastBin+1]>0
00220 && (asseY[lastBin+1]-asseY[lastBin+2])!=0)
00221 lastBin++;
00222
00223 int fitRangeEnd = (int)asseX[lastBin];
00224 int kinkPt = 64;
00225 if(fitRangeEnd < 66)
00226 kinkPt = fitRangeEnd-4;
00227 TGraphErrors graph(asseX.size(),&(*asseX.begin()),&(*asseY.begin()),
00228 &(*sigmaX.begin()),&(*sigmaY.begin()));
00229 char funct[120];
00230 sprintf(funct,"(x<%d)*([0]*x+[1])+(x>=%d)*([2]*x+[3])",kinkPt,kinkPt);
00231 TF1 fitFunction("fitFunction",funct,asseX[0],fitRangeEnd);
00232 fitFunction.SetLineColor(2);
00233
00234 char name[120] ;
00235 int gainHuman;
00236 if (gain ==0) gainHuman =12;
00237 else if (gain ==1) gainHuman =6;
00238 else if (gain ==2) gainHuman =1;
00239 else gainHuman =-1;
00240 sprintf (name,"XTL%04d_GAIN%02d",endcapCrystalNumbers[xtl],gainHuman) ;
00241 graph.GetXaxis()->SetTitle("DAC value");
00242 graph.GetYaxis()->SetTitle("Average pedestal ADC");
00243 graph.Fit("fitFunction","RWQ");
00244 graph.Write (name);
00245
00246 double slope1 = fitFunction.GetParameter(0);
00247 double slope2 = fitFunction.GetParameter(2);
00248
00249 if(fitFunction.GetChisquare()/fitFunction.GetNDF()>maxChi2OverNDF ||
00250 fitFunction.GetChisquare()/fitFunction.GetNDF()<0 ||
00251 slope1>0 || slope2>0 ||
00252 ((slope1<-29 || slope1>-18) && slope1<0) ||
00253 ((slope2<-29 || slope2>-18) && slope2<0))
00254 {
00255 edm::LogError("EcalPedOffset") << "TPedValues : TGraph for channel:" <<
00256 endcapCrystalNumbers[xtl] <<
00257 " gain:" << gainHuman << " is not linear;" << " slope of line1:" <<
00258 fitFunction.GetParameter(0) << " slope of line2:" <<
00259 fitFunction.GetParameter(2) << " reduced chi-squared:" <<
00260 fitFunction.GetChisquare()/fitFunction.GetNDF();
00261 }
00262
00263
00264
00265 if((asseX.back()-asseX.front()+1)!=asseX.size())
00266 edm::LogError("EcalPedOffset") << "TPedValues : Pedestal average not found " <<
00267 "for all DAC values scanned in channel:" << endcapCrystalNumbers[xtl]
00268 << " gain:" << gainHuman;
00269 }
00270 }
00271 }
00272
00273 return 0 ;
00274 }
00275
00276
00277 int TPedValues::getCrystalNumber(int xtal) const
00278 {
00279 return endcapCrystalNumbers[xtal];
00280 }