LArFFT.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file LArFFT.h
3 ///
4 /// Utility FFT functions
5 ///
6 /// \author Brian Page
7 ////////////////////////////////////////////////////////////////////////
8 #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 
24 ///General LArSoft Utilities
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; ///< object to do FFT
87  TFFTComplexReal *fInverseFFT; ///< object to do Inverse FF
88 
89  void InitializeFFT();
90  void resetSizePerRun(art::Run const&);
91 
92  }; // class LArFFT
93 
94 } //namespace util
95 
96 // "Forward" Fourier Transform
97 //--------------------------------------------------------
98 template <class T> inline void util::LArFFT::DoFFT(std::vector<T> & input,
99  std::vector<TComplex> & output)
100 {
101  double real = 0.; //real value holder
102  double imaginary = 0.; //imaginary value hold
103 
104  // set the points
105  for(size_t p = 0; p < input.size(); ++p)
106  fFFT->SetPoint(p, input[p]);
107 
108  fFFT->Transform();
109 
110  for(int i = 0; i < fFreqSize; ++i){
111  fFFT->GetPointComplex(i, real, imaginary);
112  output[i]=TComplex(real, imaginary);
113  }
114 
115  return;
116 }
117 
118 //Inverse Fourier Transform
119 //-------------------------------------------------
120 template <class T> inline void util::LArFFT::DoInvFFT(std::vector<TComplex> & input,
121  std::vector<T> & output)
122 {
123  for(int i = 0; i < fFreqSize; ++i)
124  fInverseFFT->SetPointComplex(i, input[i]);
125 
126  fInverseFFT->Transform();
127  double factor = 1.0/(double) fSize;
128 
129  for(int i = 0; i < fSize; ++i)
130  output[i] = factor*fInverseFFT->GetPointReal(i,false);
131 
132  return;
133 }
134 
135 //Deconvolution scheme taking all time-domain
136 //information
137 //--------------------------------------------------
138 template <class T> inline void util::LArFFT::Deconvolute(std::vector<T> & input,
139  std::vector<T> & respFunction)
140 {
141  DoFFT(respFunction, fKern);
142  DoFFT(input, fCompTemp);
143 
144  for(int i = 0; i < fFreqSize; i++)
145  fCompTemp[i]/=fKern[i];
146 
147  DoInvFFT(fCompTemp, input);
148 
149  return;
150 }
151 
152 //Deconvolution scheme using an already transformed
153 //response function
154 //saves cpu time if same response function is used
155 //for many consecutive transforms
156 //--------------------------------------------------
157 template <class T> inline void util::LArFFT::Deconvolute(std::vector<T> & input,
158  std::vector<TComplex> & kern)
159 {
160  DoFFT(input, fCompTemp);
161 
162  for(int i = 0; i < fFreqSize; i++)
163  fCompTemp[i]/=kern[i];
164 
165  DoInvFFT(fCompTemp, input);
166 
167  return;
168 }
169 
170 //Convolution scheme taking all time-domain
171 //information
172 //--------------------------------------------------
173 template <class T> inline void util::LArFFT::Convolute(std::vector<T> & shape1,
174  std::vector<T> & shape2)
175 {
176  DoFFT(shape1, fKern);
177  DoFFT(shape2, fCompTemp);
178 
179  for(int i = 0; i < fFreqSize; i++)
180  fCompTemp[i]*=fKern[i];
181 
182  DoInvFFT(fCompTemp, shape1);
183 
184  return;
185 }
186 
187 //Convolution scheme using an already transformed
188 //response function
189 //saves cpu time if same response function is used
190 //for many consecutive transforms
191 //--------------------------------------------------
192 template <class T> inline void util::LArFFT::Convolute(std::vector<T> & input,
193  std::vector<TComplex> & kern)
194 {
195  DoFFT(input, fCompTemp);
196 
197  for(int i = 0; i < fFreqSize; i++)
198  fCompTemp[i]*=kern[i];
199 
200  DoInvFFT(fCompTemp, input);
201 
202  return;
203 }
204 
205 //Correlation taking all time domain data
206 //--------------------------------------------------
207 template <class T> inline void util::LArFFT::Correlate(std::vector<T> & shape1,
208  std::vector<T> & shape2)
209 {
210  DoFFT(shape1, fKern);
211  DoFFT(shape2, fCompTemp);
212 
213  for(int i = 0; i < fFreqSize; i++)
214  fCompTemp[i]*=TComplex::Conjugate(fKern[i]);
215 
216  DoInvFFT(fCompTemp, shape1);
217 
218  return;
219 }
220 
221 //Convolution scheme using an already transformed
222 //response function
223 //saves cpu time if same response function is used
224 //for many consecutive transforms
225 //--------------------------------------------------
226 template <class T> inline void util::LArFFT::Correlate(std::vector<T> & input,
227  std::vector<TComplex> & kern)
228 {
229  DoFFT(input, fCompTemp);
230 
231  for(int i = 0; i < fFreqSize; i++)
232  fCompTemp[i]*=TComplex::Conjugate(kern[i]);
233 
234  DoInvFFT(fCompTemp, input);
235 
236  return;
237 }
238 
239 //Scheme for adding two signals which have an arbitrary
240 //relative translation. Shape1 is translated over shape2
241 //and is replaced with the sum, or the translated result
242 //if add = false
243 //--------------------------------------------------
244 template <class T> inline void util::LArFFT::AlignedSum(std::vector<T> & shape1,
245  std::vector<T> & shape2,
246  bool add)
247 {
248  double shift = PeakCorrelation(shape1,shape2);
249 
250  ShiftData(shape1,shift);
251 
252  if(add)for(int i = 0; i < fSize; i++) shape1[i]+=shape2[i];
253 
254  return;
255 }
256 
257 //Shifts real vectors using above function
258 //--------------------------------------------------
259 template <class T> inline void util::LArFFT::ShiftData(std::vector<T> & input,
260  double shift)
261 {
262  DoFFT(input,fCompTemp);
263  ShiftData(fCompTemp,shift);
264  DoInvFFT(fCompTemp,input);
265 
266  return;
267 }
268 
269 //Returns the length of the translation at which the correlation
270 //of 2 signals is maximal.
271 //--------------------------------------------------
272 template <class T> inline T util::LArFFT::PeakCorrelation(std::vector<T> & shape1,
273  std::vector<T> & shape2)
274 {
275  fConvHist->Reset("ICE");
276  std::vector<T> holder = shape1;
277  Correlate(holder,shape2);
278 
279  int maxT = max_element(holder.begin(), holder.end())-holder.begin();
280  float startT = maxT-fFitBins/2;
281  int offset = 0;
282 
283  for(int i = 0; i < fFitBins; i++) {
284  if(startT+i < 0) offset=fSize;
285  else if(startT+i > fSize) offset=-fSize;
286  else offset = 0;
287  fConvHist->Fill(i,holder[i+startT+offset]);
288  }
289 
290  fPeakFit->SetParameters(fConvHist->GetMaximum(),fFitBins/2,fFitBins/2);
291  fConvHist->Fit(fPeakFit,"QWNR","",0,fFitBins);
292  return fPeakFit->GetParameter(1)+startT;
293 }
294 
296 #endif // LARFFT_H
Namespace for general, non-LArSoft-specific utilities.
void resetSizePerRun(art::Run const &)
void ShiftData(std::vector< TComplex > &input, double shift)
std::string string
Definition: nybbler.cc:12
int fSize
Definition: LArFFT.h:77
Coord add(Coord c1, Coord c2)
Definition: restypedef.cpp:23
std::vector< TComplex > fKern
Definition: LArFFT.h:84
void DoFFT(std::vector< T > &input, std::vector< TComplex > &output)
Definition: LArFFT.h:98
int FFTFitBins() const
Definition: LArFFT.h:71
T PeakCorrelation(std::vector< T > &shape1, std::vector< T > &shape2)
Definition: LArFFT.h:272
Definition: Run.h:17
void DoInvFFT(std::vector< TComplex > &input, std::vector< T > &output)
Definition: LArFFT.h:120
TFFTRealComplex * fFFT
object to do FFT
Definition: LArFFT.h:86
int FFTSize() const
Definition: LArFFT.h:69
static int input(void)
Definition: code.cpp:15695
#define DECLARE_ART_SERVICE(svc, scope)
void Correlate(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:207
p
Definition: test.py:223
LArFFT(fhicl::ParameterSet const &pset, art::ActivityRegistry &reg)
void Convolute(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:173
void Deconvolute(std::vector< T > &input, std::vector< T > &respFunc)
Definition: LArFFT.h:138
void AlignedSum(std::vector< T > &input, std::vector< T > &output, bool add=true)
Definition: LArFFT.h:244
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