18#include "TRestRawFFT.h"
21#include <TVirtualFFT.h>
27TRestRawFFT::TRestRawFFT() {
31TRestRawFFT::~TRestRawFFT() {
35void TRestRawFFT::SetNfft(Int_t n) {
40 fFrequencyReal.Set(fNfft);
41 fFrequencyImg.Set(fNfft);
44Double_t TRestRawFFT::GetFrequencyNorm2(Int_t n) {
45 Double_t norm2 = fFrequencyReal.GetArray()[n] * fFrequencyReal.GetArray()[n] +
46 fFrequencyImg.GetArray()[n] * fFrequencyImg.GetArray()[n];
51void TRestRawFFT::ForwardSignalFFT(
TRestRawSignal* sgnl, Int_t fNStart, Int_t fNEnd) {
56 fTimeReal[i - fNStart] = sgnl->
GetData(i);
57 fTimeImg[i - fNStart] = 0;
60 TVirtualFFT* forward = TVirtualFFT::FFT(1, &fNfft,
"R2C");
61 forward->SetPointsComplex(fTimeReal.GetArray(), fTimeImg.GetArray());
64 for (
int i = 0; i < fNfft; i++)
65 forward->GetPointComplex(i, fFrequencyReal.GetArray()[i], fFrequencyImg.GetArray()[i]);
70void TRestRawFFT::BackwardFFT() {
71 TVirtualFFT* backward = TVirtualFFT::FFT(1, &fNfft,
"C2R");
72 backward->SetPointsComplex(fFrequencyReal.GetArray(), fFrequencyImg.GetArray());
73 backward->Transform();
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;
84void TRestRawFFT::ProduceDelta(Int_t t_o, Int_t Nfft) {
87 for (
int i = 0; i < fNfft; i++) {
91 if (i == t_o) fTimeReal[i] = 1;
94 TVirtualFFT* forward = TVirtualFFT::FFT(1, &fNfft,
"R2C");
95 forward->SetPointsComplex(fTimeReal.GetArray(), fTimeImg.GetArray());
98 for (
int i = 0; i < fNfft; i++)
99 forward->GetPointComplex(i, fFrequencyReal.GetArray()[i], fFrequencyImg.GetArray()[i]);
106 for (
int i = 0; i < fNfft; i++) sgnl->
AddPoint(fTimeReal.GetArray()[i]);
109void TRestRawFFT::MultiplyBy(
TRestRawFFT* fftInput, Int_t from, Int_t to) {
110 if (fftInput->GetNfft() != this->GetNfft()) {
111 cout <<
"Not the same N FFT" << endl;
115 if (to == 0) to = GetNfft() / 2;
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];
128void TRestRawFFT::DivideBy(
TRestRawFFT* fftInput, Int_t from, Int_t to) {
129 if (fftInput->GetNfft() != this->GetNfft()) {
130 cout <<
"Not the same N FFT" << endl;
134 if (to == 0) to = GetNfft() / 2;
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];
147void TRestRawFFT::ApplyResponse(
TRestRawFFT* fftInput, Int_t cutOff) {
148 if (cutOff <= 0) cout <<
"TRestRawFFT::ApplyResponse. cutOff <= 0!!!" << endl;
149 DivideBy(fftInput, 0, cutOff);
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];
162void 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];
171void TRestRawFFT::ButterWorthFilter(Int_t cutOff, Int_t order)
173 double cOffDouble = (double)cutOff;
174 for (
int i = 0; i < fNfft / 2; i++) {
175 double iDouble = (double)i;
177 fFrequencyReal.GetArray()[i] /= sqrt(1 + pow(iDouble / cOffDouble, 2 * order));
178 fFrequencyImg.GetArray()[i] /= sqrt(1 + pow(iDouble / cOffDouble, 2 * order));
180 fFrequencyReal.GetArray()[fNfft - i - 1] = fFrequencyReal.GetArray()[i];
181 fFrequencyImg.GetArray()[fNfft - i - 1] = fFrequencyImg.GetArray()[i];
186void 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.;
195void 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;
200 TComplex* cmplx1 =
new TComplex((f1 * f2 - w * w), f1 * w);
202 TComplex* cmplx2 =
new TComplex(f1, 0);
206 *cmplx2 *= a * TMath::Exp(-sigma * w * w);
208 fFrequencyReal.GetArray()[i] = cmplx2->Re();
209 fFrequencyImg.GetArray()[i] = cmplx2->Im();
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];
224void 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;
228 TComplex* cmplx1 =
new TComplex(f1 * w, (f1 * f2 - w * w));
230 TComplex* cmplx2 =
new TComplex(f1, 0);
234 TComplex phase(TComplex::Exp(TComplex(0, -w * to)));
238 fFrequencyReal.GetArray()[i] = cmplx2->Re();
239 fFrequencyImg.GetArray()[i] = cmplx2->Im();
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];
246 WriteFrequencyToTextFile(
"/home/javier/tmp/frequencyResponse");
250 WriteTimeSignalToTextFile(
"/home/javier/tmp/timeSignal");
253void 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);
260void 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;
264 fFrequencyReal.GetArray()[n] = fFrequencyReal.GetArray()[n] / factor;
265 fFrequencyImg.GetArray()[n] = fFrequencyImg.GetArray()[n] / factor;
268void 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]);
275void 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]);
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.