00001 #include "TemplateConvolver.h"
00002 #include "TTemplate.h"
00003 #include "TDirectory.h"
00004 #include "debug_tools.h"
00005 #include <iostream>
00006 #include <cmath>
00007 #include "InterpolatePulse.h"
00008 #include <TF1.h>
00009 #include "EventNavigator.h"
00010
00011 using namespace Algorithm;
00012
00013 TemplateConvolver::TemplateConvolver(const IDs::channel ch, TTemplate* tpl, int peak_fit_samples, int left, int right):
00014 fChannel(ch), fTemplate(tpl),fQuadFit(peak_fit_samples), fPolarity(EventNavigator::GetSetupRecord().GetPolarity(ch)),
00015 fLeftSafety(left),fRightSafety(right),
00016 fTemplateLength(fTemplate->GetHisto()->GetNbinsX() - fLeftSafety - fRightSafety),
00017 fTemplateTime(fTemplate->GetTime()-fLeftSafety){
00018 if(fTemplateLength <0) return;
00019
00020 TH1_wrapper hist(fTemplate->GetHisto());
00021 fEnergyConvolve=new Convolver<TH1_c_iterator>(hist.begin(fLeftSafety), hist.end(fRightSafety));
00022
00023 const int num_weights=2;
00024 const int weights[num_weights]={-1,1};
00025 fTimeWeights.assign(weights, weights+num_weights);
00026 fTimeConvolve=new Convolver<std::vector<int>::iterator>(fTimeWeights.begin(),fTimeWeights.end());
00027 }
00028
00029 TemplateConvolver::~TemplateConvolver(){
00030 delete fTimeConvolve;
00031 delete fEnergyConvolve;
00032 }
00033
00034 int TemplateConvolver::Convolve(const Algorithm::TpiMinusPedestal_iterator& begin, const Algorithm::TpiMinusPedestal_iterator& end){
00035
00036 if(!ResetVectors(end - begin)){
00037 return -1;
00038 }
00039
00040
00041 fEnergyConvolve->Process(begin,end, fEnergySamples.begin());
00042
00043
00044 fTimeConvolve->Process(fEnergySamples.begin(),fEnergySamples.end(),fTimeSamples.begin());
00045
00046 return 0;
00047 }
00048
00049 bool TemplateConvolver::ResetVectors(int size){
00050
00051 size-=fTemplateLength;
00052 if( size < 1 ) return false;
00053 fEnergySamples.resize(size);
00054 fTimeSamples.resize(size - fTimeWeights.size() );
00055 fPeaks.clear();
00056 return true;
00057 }
00058
00059 int TemplateConvolver::FindPeaks(bool expect_pile_up, const Algorithm::TpiMinusPedestal_iterator& waveform){
00060 if(expect_pile_up) return FindAllPeaks(fEnergySamples, fTimeSamples,&waveform);
00061 return FindBestPeak(fEnergySamples, fTimeSamples,&waveform);
00062 }
00063
00064 int TemplateConvolver::FindAllPeaks(const SamplesVector& energy,
00065 const SamplesVector& time, const Algorithm::TpiMinusPedestal_iterator* pedestal){
00066 double last_sample=time.front();
00067 FoundPeaks tmp=FoundPeaks();
00068 for(SamplesVector::const_iterator i_sample=time.begin()+1; i_sample!=time.end(); ++i_sample){
00069
00070
00071 if( (last_sample * *i_sample)<0 && (*i_sample - last_sample ) <0 ){
00072 int peak=i_sample - time.begin();
00073 if(pedestal) FitPeak(tmp, peak, energy, time,pedestal->GetPedestal());
00074 else FitPeak(tmp, peak, energy, time, 0);
00075 fPeaks.insert(tmp);
00076 }
00077 last_sample = *i_sample;
00078 }
00079
00080 return fPeaks.size();
00081 }
00082
00083 int TemplateConvolver::FindBestPeak(const SamplesVector& energy,
00084 const SamplesVector& time, const Algorithm::TpiMinusPedestal_iterator* pedestal){
00085 double last_sample=time.front();
00086 double best_amp=-1e9;
00087 FoundPeaks tmp=FoundPeaks();
00088 FoundPeaks best=FoundPeaks();
00089 int peak_count=0;
00090 for(SamplesVector::const_iterator i_sample=time.begin()+1; i_sample!=time.end(); ++i_sample){
00091 if( last_sample>0 && *i_sample<0){
00092 int peak=i_sample - time.begin();
00093 if(pedestal) FitPeak(tmp, peak, energy, time,pedestal->GetPedestal());
00094 else FitPeak(tmp, peak, energy, time, 0);
00095 if( (tmp.amplitude > best_amp) ){
00096 best=tmp;
00097 best_amp=tmp.amplitude;
00098 }
00099 ++peak_count;
00100 }
00101 last_sample = *i_sample;
00102 }
00103 fPeaks.insert(best);
00104 return peak_count;
00105 }
00106
00107
00108 void TemplateConvolver::FitPeak(FoundPeaks& output, int index, const SamplesVector& energy, const SamplesVector& time, double pedestal){
00109
00110 int peak=(fQuadFit.GetSize()-1)/2;
00111
00112 if( index > peak) peak=index-peak;
00113
00114 fQuadFit.Fit(energy.begin() + peak, output.quad, output.linear, output.constant);
00115
00116 output.time= index + output.linear/2/output.quad;
00117 output.pedestal=pedestal;
00118 output.amplitude=output.constant - output.linear*output.linear/4/output.quad;
00119 }
00120
00121 void TemplateConvolver::CharacteriseTemplate(){
00122 fPeaks.clear();
00123
00124
00125 TH1_wrapper hist(fTemplate->GetHisto());
00126 fTemplateACF.assign(fTemplate->GetHisto()->GetNbinsX()- fTemplateLength,0);
00127 fTemplateACFDerivative.assign(fTemplateACF.size()- fTimeWeights.size(),0);
00128
00129
00130 fEnergyConvolve->Process(hist.begin(), hist.end(), fTemplateACF.begin());
00131 fTimeConvolve->Process(fTemplateACF.begin(), fTemplateACF.end(), fTemplateACFDerivative.begin());
00132 FindBestPeak(fTemplateACF, fTemplateACFDerivative, NULL);
00133
00134
00135 fTemplateQuad=fPeaks.begin()->quad;
00136 fTemplateLin=fPeaks.begin()->linear;
00137 fTemplateConst=fPeaks.begin()->constant;
00138 fTemplateScale=fTemplate->GetAmplitude();
00139 fTemplateScale/=fPeaks.begin()->constant - fPeaks.begin()->linear*fPeaks.begin()->linear/4/fPeaks.begin()->quad;
00140
00141
00142 fTemplateACFHist=functions::VectorToHist(fTemplateACF,"Template_ACF","Auto-correlation of template");
00143 TF1* fit=new TF1("Fit","[0]*(x-[3])**2+[1]*(x-[3])+[2]", 0 , fTemplateACFHist->GetNbinsX());
00144 fit->SetParameter(0,fTemplateQuad);
00145 fit->SetParameter(1,fTemplateLin);
00146 fit->SetParameter(2,fTemplateConst);
00147 fit->SetParameter(3,fPeaks.begin()->time + fTemplateTime);
00148 fTemplateACFHist->GetListOfFunctions()->Add(fit);
00149 fTemplateACFHist->Clone()->Write();
00150 fTemplateACFDerivativeHist=functions::VectorToHist(fTemplateACFDerivative,"Template_ACF_derivative","Derivative of auto-correlation of template");
00151 fTemplateACFDerivativeHist->Clone()->Write();
00152
00153 fPeaks.clear();
00154
00155 }