00001 #ifndef TEMPLATE_FITTING_CONVOLVER_H
00002 #define TEMPLATE_FITTING_CONVOLVER_H
00003
00004 #include "debug_tools.h"
00005 #include <TH1.h>
00006 #include <iostream>
00007 #include <utility>
00008
00009 namespace Algorithm{
00010 class TH1_c_iterator;
00011 class TH1_wrapper;
00012 template < typename WeightIterator>
00013 class Convolver;
00014 template < typename InputIterator>
00015 class Pedestal_iterator;
00016 typedef Pedestal_iterator<std::vector<int>::const_iterator> TpiMinusPedestal_iterator;
00017 }
00018
00019 class Algorithm::TH1_c_iterator:public std::iterator<std::random_access_iterator_tag, double>{
00020 public:
00021 TH1_c_iterator():fHist(NULL),fCurrentBin(0),fScale(1.){}
00022 TH1_c_iterator(const TH1* hist, int init=1,double scale=1.):fHist(hist),fCurrentBin(init),fScale(scale){}
00023 TH1_c_iterator(const TH1_c_iterator& rhs):fHist(rhs.fHist),fCurrentBin(rhs.fCurrentBin),fScale(rhs.fScale){}
00024 TH1_c_iterator operator++(){
00025 ++fCurrentBin;
00026 return *this;
00027 }
00028 TH1_c_iterator operator++(int){
00029 TH1_c_iterator tmp(*this);
00030 ++fCurrentBin;
00031 return tmp;
00032 }
00033 TH1_c_iterator operator--(){
00034 --fCurrentBin;
00035 return *this;
00036 }
00037 TH1_c_iterator operator--(int){
00038 TH1_c_iterator tmp(*this);
00039 --fCurrentBin;
00040 return tmp;
00041 }
00042 double operator*()const{
00043 if(fHist ) return fHist->GetBinContent(fCurrentBin)*fScale;
00044 return 0;
00045 }
00046 TH1_c_iterator operator+=(int n){
00047 fCurrentBin+=n;
00048 return *this;
00049 }
00050
00051 TH1_c_iterator operator+(int n)const{
00052 TH1_c_iterator tmp(*this);
00053 tmp.fCurrentBin+=n;
00054 return tmp;
00055 }
00056 TH1_c_iterator operator-(int n)const{
00057 TH1_c_iterator tmp(*this);
00058 tmp.fCurrentBin-=n;
00059 return tmp;
00060 }
00061 bool operator!=(const TH1_c_iterator& rhs)const{
00062 return fCurrentBin!=rhs.fCurrentBin || fHist!=rhs.fHist ;
00063 }
00064 bool operator==(const TH1_c_iterator& rhs)const{
00065 return fCurrentBin==rhs.fCurrentBin && fHist==rhs.fHist;
00066 }
00067 int operator-(const TH1_c_iterator& rhs)const{
00068 return fCurrentBin-rhs.fCurrentBin;
00069 }
00070
00071 private:
00072 const TH1* fHist;
00073 int fCurrentBin;
00074 double fScale;
00075 };
00076
00077 struct Algorithm::TH1_wrapper{
00078 TH1_wrapper(const TH1* hist, double scale=1.): fHisto(hist), fScale(scale){};
00079 TH1_c_iterator begin(int skip=0)const{return TH1_c_iterator(fHisto,1+skip,fScale);}
00080 TH1_c_iterator end(int skip=0)const{return TH1_c_iterator(fHisto,fHisto->GetNbinsX()-skip,fScale);}
00081
00082 private:
00083 const TH1* fHisto;
00084 double fScale;
00085 };
00086
00087 template <typename InputIterator >
00088 struct Algorithm::Pedestal_iterator:public InputIterator{
00089 typedef std::pair<TH1_c_iterator, TH1_c_iterator> HistIter;
00090 typedef std::vector<HistIter> HistList;
00091 Pedestal_iterator(const InputIterator& it, double ped):InputIterator(it),fPedestal(ped){}
00092 Pedestal_iterator(const InputIterator& it):InputIterator(it),fPedestal(0){}
00093 double operator*()const{
00094 return InputIterator::operator*() - GetPedestal();
00095 }
00096 double GetPedestal()const{
00097 double val=fPedestal;
00098
00099
00100
00101 return val;
00102 }
00103 void operator++(){
00104 InputIterator::operator++();
00105 for(HistList::iterator i_hist=fHistograms.begin(); i_hist!=fHistograms.end(); ){
00106 ++(i_hist->first);
00107 if( i_hist->first == i_hist->second ){
00108 fHistograms.erase(i_hist);
00109 continue;
00110 }
00111 ++i_hist;
00112 }
00113 }
00114 void AddHistogram(TH1* hist,double scale, int shift){
00115 TH1_wrapper wrap(hist, scale);
00116 fHistograms.push_back(std::make_pair(wrap.begin(shift), wrap.end()));
00117 }
00118
00119 private:
00120 double fPedestal;
00121 HistList fHistograms;
00122 };
00123
00124 template < typename WeightIterator>
00125 class Algorithm::Convolver{
00126 public:
00127 Convolver( WeightIterator begin, WeightIterator end):fNWeights(end-begin),fBegin(begin), fEnd(end){
00128 }
00129
00130 template <typename InputIterator >
00131 double operator()(const InputIterator& start){
00132 double ret_val=0;
00133 InputIterator i_in=start;
00134 for(WeightIterator i_weight=fBegin; i_weight!=fEnd; ++i_weight){
00135 ret_val+=(*i_weight)*(*i_in);
00136 ++i_in;
00137 }
00138 return ret_val;
00139 }
00140
00141 template <typename InputIterator, typename OutputIterator >
00142 OutputIterator Process(const InputIterator& start, const InputIterator& stop, OutputIterator result){
00143 InputIterator end=stop-fNWeights;
00144 for(InputIterator i_in=start;i_in!=end;++i_in){
00145 *(result)=operator()(i_in);
00146 ++result;
00147 }
00148 return result;
00149 }
00150 int GetNWeights()const {return fNWeights;}
00151
00152 private:
00153 int fNWeights;
00154 WeightIterator fBegin;
00155 WeightIterator fEnd;
00156 };
00157
00158 #endif// TEMPLATE_FITTING_CONVOLVER_H