REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawFFT.cxx
1 
18 #include "TRestRawFFT.h"
19 
20 #include <TComplex.h>
21 #include <TVirtualFFT.h>
22 
23 using namespace std;
24 
25 ClassImp(TRestRawFFT);
26 
27 TRestRawFFT::TRestRawFFT() {
28  // TRestRawFFT default constructor
29 }
30 
31 TRestRawFFT::~TRestRawFFT() {
32  // TRestRawFFT destructor
33 }
34 
35 void TRestRawFFT::SetNfft(Int_t n) {
36  fNfft = n;
37 
38  fTimeReal.Set(fNfft);
39  fTimeImg.Set(fNfft);
40  fFrequencyReal.Set(fNfft);
41  fFrequencyImg.Set(fNfft);
42 }
43 
44 Double_t TRestRawFFT::GetFrequencyNorm2(Int_t n) {
45  Double_t norm2 = fFrequencyReal.GetArray()[n] * fFrequencyReal.GetArray()[n] +
46  fFrequencyImg.GetArray()[n] * fFrequencyImg.GetArray()[n];
47 
48  return norm2;
49 }
50 
51 void TRestRawFFT::ForwardSignalFFT(TRestRawSignal* sgnl, Int_t fNStart, Int_t fNEnd) {
52  Int_t n = sgnl->GetNumberOfPoints() - fNStart - fNEnd;
53  SetNfft(n);
54 
55  for (int i = fNStart; i < sgnl->GetNumberOfPoints() - fNEnd; i++) {
56  fTimeReal[i - fNStart] = sgnl->GetData(i);
57  fTimeImg[i - fNStart] = 0;
58  }
59 
60  TVirtualFFT* forward = TVirtualFFT::FFT(1, &fNfft, "R2C");
61  forward->SetPointsComplex(fTimeReal.GetArray(), fTimeImg.GetArray());
62  forward->Transform();
63 
64  for (int i = 0; i < fNfft; i++)
65  forward->GetPointComplex(i, fFrequencyReal.GetArray()[i], fFrequencyImg.GetArray()[i]);
66 
67  delete forward;
68 }
69 
70 void TRestRawFFT::BackwardFFT() {
71  TVirtualFFT* backward = TVirtualFFT::FFT(1, &fNfft, "C2R");
72  backward->SetPointsComplex(fFrequencyReal.GetArray(), fFrequencyImg.GetArray());
73  backward->Transform();
74 
75  for (int i = 0; i < fNfft; i++) {
76  backward->GetPointComplex(i, fTimeReal.GetArray()[i], fTimeImg.GetArray()[i]);
77  fTimeReal.GetArray()[i] /= fNfft;
78  fTimeImg.GetArray()[i] /= fNfft;
79  }
80 
81  delete backward;
82 }
83 
84 void TRestRawFFT::ProduceDelta(Int_t t_o, Int_t Nfft) {
85  SetNfft(Nfft);
86 
87  for (int i = 0; i < fNfft; i++) {
88  fTimeReal[i] = 0;
89  fTimeImg[i] = 0;
90 
91  if (i == t_o) fTimeReal[i] = 1;
92  }
93 
94  TVirtualFFT* forward = TVirtualFFT::FFT(1, &fNfft, "R2C");
95  forward->SetPointsComplex(fTimeReal.GetArray(), fTimeImg.GetArray());
96  forward->Transform();
97 
98  for (int i = 0; i < fNfft; i++)
99  forward->GetPointComplex(i, fFrequencyReal.GetArray()[i], fFrequencyImg.GetArray()[i]);
100 
101  delete forward;
102 }
103 
104 void TRestRawFFT::GetSignal(TRestRawSignal* sgnl) {
105  sgnl->Reset();
106  for (int i = 0; i < fNfft; i++) sgnl->AddPoint(fTimeReal.GetArray()[i]);
107 }
108 
109 void TRestRawFFT::MultiplyBy(TRestRawFFT* fftInput, Int_t from, Int_t to) {
110  if (fftInput->GetNfft() != this->GetNfft()) {
111  cout << "Not the same N FFT" << endl;
112  return;
113  }
114 
115  if (to == 0) to = GetNfft() / 2;
116 
117  for (int i = from; i < GetNfft() / 2; i++) {
118  TComplex top(this->GetFrequencyAmplitudeReal(i), this->GetFrequencyAmplitudeImg(i));
119  TComplex bottom(fftInput->GetFrequencyAmplitudeReal(i), fftInput->GetFrequencyAmplitudeImg(i));
120  TComplex product = top * bottom;
121  fFrequencyReal.GetArray()[i] = product.Re();
122  fFrequencyImg.GetArray()[i] = product.Im();
123  fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
124  fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
125  }
126 }
127 
128 void TRestRawFFT::DivideBy(TRestRawFFT* fftInput, Int_t from, Int_t to) {
129  if (fftInput->GetNfft() != this->GetNfft()) {
130  cout << "Not the same N FFT" << endl;
131  return;
132  }
133 
134  if (to == 0) to = GetNfft() / 2;
135 
136  for (int i = from; i < to; i++) {
137  TComplex top(this->GetFrequencyAmplitudeReal(i), this->GetFrequencyAmplitudeImg(i));
138  TComplex bottom(fftInput->GetFrequencyAmplitudeReal(i), fftInput->GetFrequencyAmplitudeImg(i));
139  TComplex cocient = top / bottom;
140  fFrequencyReal.GetArray()[i] = cocient.Re();
141  fFrequencyImg.GetArray()[i] = cocient.Im();
142  fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
143  fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
144  }
145 }
146 
147 void TRestRawFFT::ApplyResponse(TRestRawFFT* fftInput, Int_t cutOff) {
148  if (cutOff <= 0) cout << "TRestRawFFT::ApplyResponse. cutOff <= 0!!!" << endl;
149  DivideBy(fftInput, 0, cutOff);
150 
151  Double_t normCutOff = GetFrequencyNorm2(cutOff - 1);
152  Double_t scaleFactor = normCutOff / GetFrequencyNorm2(cutOff);
153  scaleFactor = TMath::Sqrt(scaleFactor);
154  for (int i = cutOff; i < GetNfft() / 2; i++) {
155  fFrequencyReal.GetArray()[i] *= scaleFactor;
156  fFrequencyImg.GetArray()[i] *= scaleFactor;
157  fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
158  fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
159  }
160 }
161 
162 void TRestRawFFT::KillFrequencies(Int_t cutOff) {
163  for (int i = cutOff; i < GetNfft() / 2; i++) {
164  fFrequencyReal.GetArray()[i] = 0;
165  fFrequencyImg.GetArray()[i] = 0;
166  fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
167  fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
168  }
169 }
170 
171 void TRestRawFFT::ButterWorthFilter(Int_t cutOff, Int_t order) //, Double_t amp, Double_t decay )
172 {
173  double cOffDouble = (double)cutOff;
174  for (int i = 0; i < fNfft / 2; i++) {
175  double iDouble = (double)i;
176  if (i > cutOff) {
177  fFrequencyReal.GetArray()[i] /= sqrt(1 + pow(iDouble / cOffDouble, 2 * order));
178  fFrequencyImg.GetArray()[i] /= sqrt(1 + pow(iDouble / cOffDouble, 2 * order));
179 
180  fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
181  fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
182  }
183  }
184 }
185 
186 void TRestRawFFT::ApplyLowPassFilter(Int_t cutFrequency) {
187  for (int i = 0; i < fNfft; i++) {
188  if (i >= cutFrequency && i < fNfft - cutFrequency) {
189  fFrequencyReal.GetArray()[i] = 0.;
190  fFrequencyImg.GetArray()[i] = 0.;
191  }
192  }
193 }
194 
195 void TRestRawFFT::GaussianSecondOrderResponse(Double_t f1, Double_t f2, Double_t Ao, Double_t sigma) {
196  Double_t a = TMath::Sqrt(Ao);
197  for (int i = 0; i < fNfft / 2; i++) {
198  Double_t w = (double)2. * i / 3;
199 
200  TComplex* cmplx1 = new TComplex((f1 * f2 - w * w), f1 * w);
201 
202  TComplex* cmplx2 = new TComplex(f1, 0);
203 
204  *cmplx2 /= *cmplx1;
205 
206  *cmplx2 *= a * TMath::Exp(-sigma * w * w);
207 
208  fFrequencyReal.GetArray()[i] = cmplx2->Re();
209  fFrequencyImg.GetArray()[i] = cmplx2->Im();
210  }
211 
212  for (int i = fNfft / 2; i < fNfft; i++) {
213  fFrequencyReal.GetArray()[i] = fFrequencyReal.GetArray()[fNfft - i - 1];
214  fFrequencyImg.GetArray()[i] = fFrequencyImg.GetArray()[fNfft - i - 1];
215  }
216 
217  // WriteFrequencyToTextFile( "frequencyResponse" );
218 
219  BackwardFFT();
220 
221  // WriteTimeSignalToTextFile ( "timeSignal" );
222 }
223 
224 void TRestRawFFT::SetSecondOrderAnalyticalResponse(Double_t f1, Double_t f2, Double_t to) {
225  for (int i = 0; i < fNfft / 2; i++) {
226  Double_t w = 2.59 * (double)i;
227 
228  TComplex* cmplx1 = new TComplex(f1 * w, (f1 * f2 - w * w));
229 
230  TComplex* cmplx2 = new TComplex(f1, 0);
231 
232  *cmplx2 /= *cmplx1;
233 
234  TComplex phase(TComplex::Exp(TComplex(0, -w * to)));
235 
236  *cmplx2 *= phase;
237 
238  fFrequencyReal.GetArray()[i] = cmplx2->Re();
239  fFrequencyImg.GetArray()[i] = cmplx2->Im();
240  }
241  for (int i = fNfft / 2; i < fNfft; i++) {
242  fFrequencyReal.GetArray()[i] = fFrequencyReal.GetArray()[fNfft - i - 1];
243  fFrequencyImg.GetArray()[i] = fFrequencyImg.GetArray()[fNfft - i - 1];
244  }
245 
246  WriteFrequencyToTextFile("/home/javier/tmp/frequencyResponse");
247 
248  BackwardFFT();
249 
250  WriteTimeSignalToTextFile("/home/javier/tmp/timeSignal");
251 }
252 
253 void TRestRawFFT::RemoveBaseline() {
254  Double_t real = this->GetFrequencyAmplitudeReal(1);
255  Double_t img = this->GetFrequencyAmplitudeImg(1);
256  Double_t module = sqrt(real * real + img * img);
257  this->SetNode(0, module);
258 }
259 
260 void TRestRawFFT::RenormalizeNode(Int_t n, Double_t factor) {
261  fFrequencyReal.GetArray()[fNfft - n - 1] = fFrequencyReal.GetArray()[n] / factor;
262  fFrequencyImg.GetArray()[fNfft - n - 1] = fFrequencyImg.GetArray()[n] / factor;
263 
264  fFrequencyReal.GetArray()[n] = fFrequencyReal.GetArray()[n] / factor;
265  fFrequencyImg.GetArray()[n] = fFrequencyImg.GetArray()[n] / factor;
266 }
267 
268 void TRestRawFFT::WriteFrequencyToTextFile(TString filename) {
269  FILE* fff = fopen(filename.Data(), "w");
270  for (int i = 0; i < fNfft; i++)
271  fprintf(fff, "%d\t%17.14e\t%17.14e\n", i, fFrequencyReal.GetArray()[i], fFrequencyImg.GetArray()[i]);
272  fclose(fff);
273 }
274 
275 void TRestRawFFT::WriteTimeSignalToTextFile(TString filename) {
276  FILE* fff = fopen(filename.Data(), "w");
277  for (int i = 0; i < fNfft; i++)
278  fprintf(fff, "%d\t%e\t%e\n", i, fTimeReal.GetArray()[i], fTimeImg.GetArray()[i]);
279  fclose(fff);
280 }
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
void Reset()
Initializes the existing signal data and sets it to zero while keeping the array size.
Double_t GetData(Int_t n) const
It returns the data value of point n including baseline correction.
void AddPoint(Short_t)
Adds a new point to the end of the signal data array.
Int_t GetNumberOfPoints() const
Returns the actual number of points, or size of the signal.