00001 #ifndef RecoLocalCalo_EcalRecAlgos_EcalUncalibRecHitRecAnalFitAlgo_HH
00002 #define RecoLocalCalo_EcalRecAlgos_EcalUncalibRecHitRecAnalFitAlgo_HH
00003
00014 #include "CLHEP/Matrix/Matrix.h"
00015 #include "CLHEP/Matrix/SymMatrix.h"
00016 #include "RecoLocalCalo/EcalRecAlgos/interface/EcalUncalibRecHitRecAbsAlgo.h"
00017 #include <vector>
00018 #include <string>
00019
00020 #include "TROOT.h"
00021 #include "TMinuit.h"
00022 #include "TGraph.h"
00023 #include "TF1.h"
00024
00025 template<class C> class EcalUncalibRecHitRecAnalFitAlgo : public EcalUncalibRecHitRecAbsAlgo<C>
00026 {
00027
00028
00029 private:
00030
00031 double pulseShapeFunction(double* var, double* par) {
00032 double x = var[0];
00033 double ampl = par[0];
00034 double tp = par[1];
00035 double alpha = par[2];
00036 double t0 = par[3];
00037
00038 double f = pow( (x-t0)/tp , alpha ) * exp( -alpha*(x-tp-t0)/tp );
00039 return ampl*f;
00040 };
00041
00042 double pedestalFunction(double* var, double* par) {
00043 double x = var[0];
00044 double ped = par[0];
00045 return ped;
00046 };
00047
00048 public:
00049
00050 virtual ~EcalUncalibRecHitRecAnalFitAlgo<C>() { };
00051
00052
00054 virtual EcalUncalibratedRecHit makeRecHit(const C& dataFrame, const double* pedestals,
00055 const double* gainRatios,
00056 const EcalWeightSet::EcalWeightMatrix** weights,
00057 const EcalWeightSet::EcalChi2WeightMatrix** chi2Matrix)
00058 {
00059 double amplitude_(-1.), pedestal_(-1.), jitter_(-1.), chi2_(-1.);
00060
00061
00062
00063 double frame[C::MAXSAMPLES];
00064
00065 int gainId0 = 1;
00066 int iGainSwitch = 0;
00067 double maxsample(-1);
00068 int imax(-1);
00069 bool isSaturated = 0;
00070 uint32_t flag = 0;
00071 for(int iSample = 0; iSample < C::MAXSAMPLES; iSample++) {
00072 int gainId = dataFrame.sample(iSample).gainId();
00073 if ( dataFrame.isSaturated() != -1 )
00074 {
00075 gainId = 3;
00076 isSaturated = 1;
00077 }
00078
00079 if (gainId != gainId0) iGainSwitch++ ;
00080 if (!iGainSwitch)
00081 frame[iSample] = double(dataFrame.sample(iSample).adc());
00082 else
00083 frame[iSample] = double(((double)(dataFrame.sample(iSample).adc()) - pedestals[gainId-1]) * gainRatios[gainId-1]);
00084
00085 if( frame[iSample]>maxsample ) {
00086 maxsample= frame[iSample];
00087 imax=iSample;
00088 }
00089 }
00090
00091
00092
00093
00094
00095 double xarray[10]={0.,1.,2.,3.,4.,5.,6.,7.,8.,9.};
00096 TGraph graph(10,xarray,frame);
00097
00098
00099 TF1 pulseShape = TF1("pulseShape",
00100 "[0]*pow((x - [3])/[1],[2])*exp(-[2]*(x - [1] - [3])/[1])",
00101 imax-1.,imax+3.);
00102 TF1 pedestal = TF1("pedestal","[0]",0.,2.);
00103
00104
00105
00106 TF1 pluseAndPed = TF1("pulseAndPed","pedestal+pulseShape");
00107
00108
00109
00110 double FIT_A=(double)maxsample;
00111 pulseShape.SetParameter(0,FIT_A);
00112 pulseShape.SetParName(0,"Amplitude");
00113
00114 double FIT_Tp=(double)imax;
00115 pulseShape.SetParameter(1,FIT_Tp);
00116 pulseShape.SetParName(1,"t_{P}");
00117
00118 double FIT_ALFA=1.5;
00119 pulseShape.SetParameter(2,FIT_ALFA);
00120 pulseShape.SetParName(2,"\\alpha");
00121
00122 double FIT_To=3.;
00123 pulseShape.SetParameter(3,FIT_To);
00124 pulseShape.SetParName(3,"t_{0}");
00125
00126
00127 pedestal.SetParameter(0,frame[0]);
00128 pedestal.SetParName(0,"Pedestal");
00129
00130
00131
00132 graph.Fit("pulseShape","QRM");
00133
00134
00135 if ( std::string(gMinuit->fCstatu.Data()) == std::string("CONVERGED ") ) {
00136
00137 double amplitude_value=pulseShape.GetParameter(0);
00138
00139 graph.Fit("pedestal","QRL");
00140
00141 double pedestal_value=pedestal.GetParameter(0);
00142
00143 if (!iGainSwitch)
00144 amplitude_ = amplitude_value - pedestal_value;
00145 else
00146 amplitude_ = amplitude_value;
00147
00148 pedestal_ = pedestal_value;
00149 jitter_ = pulseShape.GetParameter(3);
00150 chi2_ = 1.;
00151 if (isSaturated) flag = EcalUncalibratedRecHit::kSaturated;
00152
00153
00154
00155
00156
00157
00158
00159 }
00160
00161 return EcalUncalibratedRecHit( dataFrame.id(), amplitude_, pedestal_, jitter_ - 6, chi2_, flag);
00162 }
00163 };
00164 #endif