LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LArFFT.h
Go to the documentation of this file.
1 #ifndef LARFFT_H
9 #define LARFFT_H
10 
11 #include "TComplex.h"
12 #include "TFFTRealComplex.h"
13 #include "TFFTComplexReal.h"
14 #include "TF1.h"
15 #include "TH1D.h"
16 #include <vector>
17 #include <string>
18 
19 #include "fhiclcpp/ParameterSet.h"
23 
25 namespace util{
26  class LArFFT {
27  public:
29  ~LArFFT();
30 
31 
32  template <class T> void DoFFT(std::vector<T> & input,
33  std::vector<TComplex> & output);
34 
35  template <class T> void DoInvFFT(std::vector<TComplex> & input,
36  std::vector<T> & output);
37 
38  template <class T> void Deconvolute(std::vector<T> & input,
39  std::vector<T> & respFunc);
40 
41  template <class T> void Deconvolute(std::vector<T> & input,
42  std::vector<TComplex> & kern);
43 
44  template <class T> void Convolute(std::vector<T> & input,
45  std::vector<T> & respFunc);
46 
47  template <class T> void Convolute(std::vector<T> & input,
48  std::vector<TComplex> & kern);
49 
50  template <class T> void Correlate(std::vector<T> & input,
51  std::vector<T> & respFunc);
52 
53  template <class T> void Correlate(std::vector<T> & input,
54  std::vector<TComplex> & kern);
55 
56  template <class T> void AlignedSum(std::vector<T> & input,
57  std::vector<T> &output,
58  bool add = true);
59 
60  void ShiftData(std::vector<TComplex> & input,
61  double shift);
62 
63  template <class T> void ShiftData(std::vector<T> & input,
64  double shift);
65 
66  template <class T> T PeakCorrelation(std::vector<T> &shape1,
67  std::vector<T> &shape2);
68 
69  int FFTSize() const { return fSize; }
70  std::string FFTOptions() const { return fOption; }
71  int FFTFitBins() const { return fFitBins; }
72 
73  void ReinitializeFFT(int, std::string, int);
74 
75  private:
76 
77  int fSize; //size of transform
78  int fFreqSize; //size of frequency space
79  std::string fOption; //FFTW setting
80  int fFitBins; //Bins used for peak fit
81  TF1 *fPeakFit; //Gaussian peak function
82  TH1D *fConvHist; //Fit data histogram
83  std::vector<TComplex> fCompTemp; //temporary complex data
84  std::vector<TComplex> fKern; //transformed response function
85 
86  TFFTRealComplex *fFFT;
87  TFFTComplexReal *fInverseFFT;
88 
89  void InitializeFFT();
90 
91  }; // class LArFFT
92 
93 } //namespace util
94 
95 // "Forward" Fourier Transform
96 //--------------------------------------------------------
97 template <class T> inline void util::LArFFT::DoFFT(std::vector<T> & input,
98  std::vector<TComplex> & output)
99 {
100  double real = 0.; //real value holder
101  double imaginary = 0.; //imaginary value hold
102 
103  // set the points
104  for(size_t p = 0; p < input.size(); ++p)
105  fFFT->SetPoint(p, input[p]);
106 
107  fFFT->Transform();
108 
109  for(int i = 0; i < fFreqSize; ++i){
110  fFFT->GetPointComplex(i, real, imaginary);
111  output[i]=TComplex(real, imaginary);
112  }
113 
114  return;
115 }
116 
117 //Inverse Fourier Transform
118 //-------------------------------------------------
119 template <class T> inline void util::LArFFT::DoInvFFT(std::vector<TComplex> & input,
120  std::vector<T> & output)
121 {
122  for(int i = 0; i < fFreqSize; ++i)
123  fInverseFFT->SetPointComplex(i, input[i]);
124 
125  fInverseFFT->Transform();
126  double factor = 1.0/(double) fSize;
127 
128  for(int i = 0; i < fSize; ++i)
129  output[i] = factor*fInverseFFT->GetPointReal(i,false);
130 
131  return;
132 }
133 
134 //Deconvolution scheme taking all time-domain
135 //information
136 //--------------------------------------------------
137 template <class T> inline void util::LArFFT::Deconvolute(std::vector<T> & input,
138  std::vector<T> & respFunction)
139 {
140  DoFFT(respFunction, fKern);
141  DoFFT(input, fCompTemp);
142 
143  for(int i = 0; i < fFreqSize; i++)
144  fCompTemp[i]/=fKern[i];
145 
146  DoInvFFT(fCompTemp, input);
147 
148  return;
149 }
150 
151 //Deconvolution scheme using an already transformed
152 //response function
153 //saves cpu time if same response function is used
154 //for many consecutive transforms
155 //--------------------------------------------------
156 template <class T> inline void util::LArFFT::Deconvolute(std::vector<T> & input,
157  std::vector<TComplex> & kern)
158 {
159  DoFFT(input, fCompTemp);
160 
161  for(int i = 0; i < fFreqSize; i++)
162  fCompTemp[i]/=kern[i];
163 
164  DoInvFFT(fCompTemp, input);
165 
166  return;
167 }
168 
169 //Convolution scheme taking all time-domain
170 //information
171 //--------------------------------------------------
172 template <class T> inline void util::LArFFT::Convolute(std::vector<T> & shape1,
173  std::vector<T> & shape2)
174 {
175  DoFFT(shape1, fKern);
176  DoFFT(shape2, fCompTemp);
177 
178  for(int i = 0; i < fFreqSize; i++)
179  fCompTemp[i]*=fKern[i];
180 
181  DoInvFFT(fCompTemp, shape1);
182 
183  return;
184 }
185 
186 //Convolution scheme using an already transformed
187 //response function
188 //saves cpu time if same response function is used
189 //for many consecutive transforms
190 //--------------------------------------------------
191 template <class T> inline void util::LArFFT::Convolute(std::vector<T> & input,
192  std::vector<TComplex> & kern)
193 {
194  DoFFT(input, fCompTemp);
195 
196  for(int i = 0; i < fFreqSize; i++)
197  fCompTemp[i]*=kern[i];
198 
199  DoInvFFT(fCompTemp, input);
200 
201  return;
202 }
203 
204 //Correlation taking all time domain data
205 //--------------------------------------------------
206 template <class T> inline void util::LArFFT::Correlate(std::vector<T> & shape1,
207  std::vector<T> & shape2)
208 {
209  DoFFT(shape1, fKern);
210  DoFFT(shape2, fCompTemp);
211 
212  for(int i = 0; i < fFreqSize; i++)
213  fCompTemp[i]*=TComplex::Conjugate(fKern[i]);
214 
215  DoInvFFT(fCompTemp, shape1);
216 
217  return;
218 }
219 
220 //Convolution scheme using an already transformed
221 //response function
222 //saves cpu time if same response function is used
223 //for many consecutive transforms
224 //--------------------------------------------------
225 template <class T> inline void util::LArFFT::Correlate(std::vector<T> & input,
226  std::vector<TComplex> & kern)
227 {
228  DoFFT(input, fCompTemp);
229 
230  for(int i = 0; i < fFreqSize; i++)
231  fCompTemp[i]*=TComplex::Conjugate(kern[i]);
232 
233  DoInvFFT(fCompTemp, input);
234 
235  return;
236 }
237 
238 //Scheme for adding two signals which have an arbitrary
239 //relative translation. Shape1 is translated over shape2
240 //and is replaced with the sum, or the translated result
241 //if add = false
242 //--------------------------------------------------
243 template <class T> inline void util::LArFFT::AlignedSum(std::vector<T> & shape1,
244  std::vector<T> & shape2,
245  bool add)
246 {
247  double shift = PeakCorrelation(shape1,shape2);
248 
249  ShiftData(shape1,shift);
250 
251  if(add)for(int i = 0; i < fSize; i++) shape1[i]+=shape2[i];
252 
253  return;
254 }
255 
256 //Shifts real vectors using above function
257 //--------------------------------------------------
258 template <class T> inline void util::LArFFT::ShiftData(std::vector<T> & input,
259  double shift)
260 {
261  DoFFT(input,fCompTemp);
262  ShiftData(fCompTemp,shift);
263  DoInvFFT(fCompTemp,input);
264 
265  return;
266 }
267 
268 //Returns the length of the translation at which the correlation
269 //of 2 signals is maximal.
270 //--------------------------------------------------
271 template <class T> inline T util::LArFFT::PeakCorrelation(std::vector<T> & shape1,
272  std::vector<T> & shape2)
273 {
274  fConvHist->Reset("ICE");
275  std::vector<T> holder = shape1;
276  Correlate(holder,shape2);
277 
278  int maxT = max_element(holder.begin(), holder.end())-holder.begin();
279  float startT = maxT-fFitBins/2;
280  int offset = 0;
281 
282  for(int i = 0; i < fFitBins; i++) {
283  if(startT+i < 0) offset=fSize;
284  else if(startT+i > fSize) offset=-fSize;
285  else offset = 0;
286  fConvHist->Fill(i,holder[i+startT+offset]);
287  }
288 
289  fPeakFit->SetParameters(fConvHist->GetMaximum(),fFitBins/2,fFitBins/2);
290  fConvHist->Fit(fPeakFit,"QWNR","",0,fFitBins);
291  return fPeakFit->GetParameter(1)+startT;
292 }
293 
295 #endif // LARFFT_H
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
void ShiftData(std::vector< TComplex > &input, double shift)
int fSize
Definition: LArFFT.h:77
std::vector< TComplex > fKern
Definition: LArFFT.h:84
#define DECLARE_ART_SERVICE(svc, scope)
Definition: ServiceMacros.h:91
void DoFFT(std::vector< T > &input, std::vector< TComplex > &output)
Definition: LArFFT.h:97
int FFTFitBins() const
Definition: LArFFT.h:71
T PeakCorrelation(std::vector< T > &shape1, std::vector< T > &shape2)
Definition: LArFFT.h:271
void DoInvFFT(std::vector< TComplex > &input, std::vector< T > &output)
Definition: LArFFT.h:119
TFFTRealComplex * fFFT
object to do FFT
Definition: LArFFT.h:86
int FFTSize() const
Definition: LArFFT.h:69
void Correlate(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:206
LArFFT(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
void Convolute(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:172
void Deconvolute(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:137
void AlignedSum(std::vector< T > &input, std::vector< T > &output, bool add=true)
Definition: LArFFT.h:243
TF1 * fPeakFit
Definition: LArFFT.h:81
std::vector< TComplex > fCompTemp
Definition: LArFFT.h:83
std::string FFTOptions() const
Definition: LArFFT.h:70
std::string fOption
Definition: LArFFT.h:79
TFFTComplexReal * fInverseFFT
object to do Inverse FF
Definition: LArFFT.h:87
TH1D * fConvHist
Definition: LArFFT.h:82
int fFitBins
Definition: LArFFT.h:80
void InitializeFFT()
void ReinitializeFFT(int, std::string, int)
int fFreqSize
Definition: LArFFT.h:78