00001 #include "TemplateConvolveAPGenerator.h"
00002
00003 #include "EventNavigator.h"
00004 #include "TAPGeneratorFactory.h"
00005 #include "TemplateConvolver.h"
00006 #include "TPulseIsland.h"
00007 #include "TAnalysedPulse.h"
00008 #include "debug_tools.h"
00009
00010 #include <iostream>
00011 using std::cout;
00012 using std::endl;
00013
00014 TemplateArchive* TemplateConvolveAPGenerator::fTemplateArchive=NULL;
00015
00016 TemplateConvolveAPGenerator::TemplateConvolveAPGenerator(TAPGeneratorOptions* opts):
00017 TVAnalysedPulseGenerator("TemplateConvolve",opts),
00018 fPedestal(EventNavigator::Instance().GetSetupRecord().GetPedestal(GetChannel())),
00019 fTicksPerNs(EventNavigator::Instance().GetSetupRecord().GetTickLength(GetChannel())),
00020
00021 fMuScTimeOffset(0.),
00022 fExpectPileUp(false), fIntegralRatio(NULL)
00023 {
00024
00025 if(!fTemplateArchive){
00026 fTemplateArchive=new TemplateArchive(opts->GetString("template_archive").c_str(),"READ");
00027 }
00028 fTemplate=fTemplateArchive->GetTemplate(GetChannel());
00029 fTemplate->RebinToOriginalSampling();
00030 fTemplate->NormaliseToSumSquares();
00031
00032 int fit_peak= opts->GetInt("n_quad_fit",5);
00033 int left= opts->GetInt("left",20);
00034 int right= opts->GetInt("right",120);
00035 fConvolver=new TemplateConvolver(GetChannel(), fTemplate, fit_peak, left, right);
00036 TH1* tpl=(TH1*)fTemplate->GetHisto()->Clone("Template");
00037 tpl->SetDirectory(gDirectory);
00038 fConvolver->CharacteriseTemplate();
00039
00040
00041 if(opts->GetFlag("use_IR_cut")){
00042 fIntegralRatio=new Algorithm::IntegralRatio(
00043 opts->GetInt("start_integral",10),
00044 opts->GetInt("start_tail",60),
00045 opts->GetInt("stop_integral",0),
00046 EventNavigator::Instance().GetSetupRecord().GetPolarity(GetChannel()));
00047 fIntegralMax=opts->GetDouble("max_integral");
00048 fIntegralMin=opts->GetDouble("min_integral");
00049 fIntegralRatioMax=opts->GetDouble("max_ratio");
00050 fIntegralRatioMin=opts->GetDouble("min_ratio");
00051 }
00052 }
00053
00054 int TemplateConvolveAPGenerator::ProcessPulses(
00055 const PulseIslandList& pulseList,
00056 AnalysedPulseList& analysedList){
00057
00058
00059 double integral, ratio;
00060 TTemplateConvolveAnalysedPulse* tap;
00061 for (PulseIslandList::const_iterator tpi=pulseList.begin();
00062 tpi!=pulseList.end(); tpi++){
00063
00064
00065 if(fIntegralRatio && !PassesIntegralRatio(*tpi, integral,ratio)){
00066 continue;
00067 }
00068 Algorithm::TpiMinusPedestal_iterator waveform((*tpi)->GetSamples().begin(),fPedestal);
00069 Algorithm::TpiMinusPedestal_iterator end((*tpi)->GetSamples().end());
00070
00071
00072 int n_peaks=fConvolver->Convolve(waveform,end );
00073 if(n_peaks<0) {
00074 if(Debug())cout<<"Waveform too small to analyze"<<endl;
00075 continue;
00076 }
00077 n_peaks= fConvolver->FindPeaks(fExpectPileUp , waveform);
00078
00079 const TemplateConvolver::PeaksVector& peaks=fConvolver->GetPeaks();
00080 int count=0;
00081 for(TemplateConvolver::PeaksVector::const_iterator i_tap=peaks.begin();
00082 i_tap!=peaks.end(); ++i_tap){
00083
00084
00085
00086
00087
00088
00089 tap = MakeNewTAP<TTemplateConvolveAnalysedPulse>(tpi-pulseList.begin());
00090 if(fIntegralRatio){
00091 tap->SetIntegral(integral);
00092 tap->SetIntegralRatio(ratio);
00093 }
00094 tap->SetNPeaks(n_peaks);
00095 tap->SetPeakRank(count);
00096 tap->SetEnergyConvolve(fConvolver->GetEnergyConvolution());
00097 tap->SetTimeConvolve(fConvolver->GetTimeConvolution());
00098 tap->SetTimeOffset(i_tap->time);
00099 tap->SetAmplitudeScale(i_tap->amplitude);
00100 tap->SetAmplitude(i_tap->amplitude*fConvolver->GetAmplitudeScale());
00101 tap->SetQuadraticFit(i_tap->quad,i_tap->linear, i_tap->constant);
00102 tap->SetTemplate(fTemplate);
00103 tap->SetPedestal(fPedestal);
00104 double time= CalibrateTime(i_tap->time + fConvolver->GetTimeShift() +0.5, *tpi);
00105 tap->SetTime(time);
00106
00107
00108
00109 analysedList.push_back(tap);
00110
00112
00113
00114
00115 count++;
00116 }
00117 }
00118
00119 return 0;
00120 }
00121
00122 bool TemplateConvolveAPGenerator::PassesIntegralRatio(const TPulseIsland* pulse, double& integral, double& ratio)const{
00123 if(!fIntegralRatio) return true;
00124 try{
00125 fIntegralRatio->SetPedestalToMinimum(pulse);
00126 (*fIntegralRatio)(pulse);
00127 }catch(std::out_of_range& e){
00128 return false;
00129 }
00130 integral=fIntegralRatio->GetTotal();
00131 ratio=fIntegralRatio->GetRatio();
00132 if( fIntegralMax < integral || fIntegralMin > integral
00133 || fIntegralRatioMax < ratio || fIntegralRatioMin > ratio) {
00134 return false;
00135 }
00136 return true;
00137 }
00138
00139 double TemplateConvolveAPGenerator::CalibrateTime(double clockTime, const TPulseIsland* tpi)const{
00140 return (clockTime + (double)tpi->GetTimeStamp()) * fTicksPerNs - fMuScTimeOffset;
00141 }
00142
00143 ALCAP_TAP_GENERATOR(TemplateConvolve, template_archive, n_quad_fit, left, right, use_IR_cut, min_integral, max_integral, min_ratio, max_ratio );