12 #define SINCOS __sincos 23 return 1. - TMath::Abs(Double_t(2*j -n)/n);
29 return 1. -TMath::Power(Double_t(2*j -n)/n,2);
35 std::vector<double> tVec;
36 std::vector<double> vVec;
38 Int_t numIn=grIn->GetN();
43 for (
int samp=0;samp<numIn;samp++) {
44 grIn->GetPoint(samp,tIn,vIn);
53 std::cout <<
"Insufficent points for interpolation\n";
58 ROOT::Math::Interpolator chanInterp(tVec,vVec,ROOT::Math::Interpolation::kAKIMA);
60 Int_t roughPoints=Int_t((lastTime-startTime)/deltaT);
63 Double_t *newTimes =
new Double_t[roughPoints+100];
64 Double_t *newVolts =
new Double_t[roughPoints+100];
66 for(Double_t time=startTime;time<=lastTime;time+=deltaT) {
67 newTimes[numPoints]=time;
68 newVolts[numPoints]=chanInterp.Eval(time);
75 TGraph *grInt =
new TGraph(numPoints,newTimes,newVolts);
87 Int_t numIn=grIn->GetN();
88 Double_t *tIn=grIn->GetX();
89 Double_t *vIn=grIn->GetY();
90 Double_t oldDt=tIn[1]-tIn[0];
92 return getInterpolatedGraph(grIn,deltaT);
95 Int_t fftLength=(numIn/2)+1;
96 Int_t newFFTLength=(oldDt/deltaT)*fftLength;
98 Int_t numPoints=(newFFTLength-1)*2;
100 Double_t scaleFactor=Double_t(numPoints)/Double_t(numIn);
101 for(
int i=0;i<newFFTLength;i++) {
103 thePaddedFft[i]=theFFt[i];
107 thePaddedFft[i].
re=0;
108 thePaddedFft[i].
im=0;
112 Double_t *newTimes =
new Double_t[numPoints];
113 Double_t *newVolts = doInvFFT(numPoints,thePaddedFft);
114 for(Int_t i=0;i<numPoints;i++) {
115 newTimes[i]=tIn[0]+deltaT*(i-1);
120 TGraph *grInt =
new TGraph(numPoints,newTimes,newVolts);
124 delete [] thePaddedFft;
187 static std::map<int, std::pair<fftw_plan, fftw_plan> > cached_plans;
192 #ifdef FFTTOOLS_THREAD_SAFE 193 #ifdef FFTTOOLS_USE_OMP 194 Sorry, you cannot compile
using both FFTTOOLS_THREAD_SAFE and FFTTOOLS_USE_OMP.
200 #ifdef FFTTOOLS_THREAD_SAFE 201 #define USE_PER_THREAD_MEMORY 204 static TMutex plan_mutex;
205 #define GET_TID() TThread::SelfId() 210 #ifdef FFTTOOLS_USE_OMP 211 #define USE_PER_THREAD_MEMORY 213 #define GET_TID() omp_get_thread_num() 217 #ifdef USE_PER_THREAD_MEMORY 225 #ifdef FFTTOOLS_USE_OMP 226 static std::map<int, std::vector<double *> > cached_xs;
227 static std::map<int, std::vector<fftw_complex *> > cached_Xs;
229 static std::map<int, std::map<long,double *> > cached_xs;
230 static std::map<int, std::map<long,fftw_complex *> > cached_Xs;
234 static std::map<int, double*> cached_xs;
235 static std::map<int, fftw_complex*> cached_Xs;
238 static fftw_plan getPlan(
int len,
bool forward =
true)
245 #ifdef FFTOOLS_THREAD_SAFE 251 std::map<int,std::pair<fftw_plan, fftw_plan> >::iterator it = cached_plans.find(len);
254 bool must_plan = it == cached_plans.end();
255 bool must_allocate = must_plan;
257 #ifdef USE_PER_THREAD_MEMORY 258 unsigned long tid = GET_TID();
260 #ifdef FFTTOOLS_USE_OMP 261 must_allocate = must_allocate || cached_xs[len].size() <= tid || cached_xs[len][tid] == 0 ;
263 must_allocate = must_allocate || cached_xs[len].count(tid) == 0 || cached_xs[len][tid] == 0 ;
269 fftw_complex * mem_X = 0;
273 #ifdef FFTTOOLS_ALLOCATE_CONTIGUOUS 280 void * mem = fftw_malloc(
sizeof(
double) * (len + len % 8) + (1 + len/2) *
sizeof(fftw_complex));
281 mem_x = (
double*) mem;
282 mem_X = (fftw_complex*) (mem_x + len + (len % 8));
286 mem_x= fftw_alloc_real(len);
287 mem_X= fftw_alloc_complex(len/2+1);
290 #ifdef USE_PER_THREAD_MEMORY 293 #ifdef FFTTOOLS_USE_OMP 296 cached_xs[len] = std::vector<double*>(tid+1,0);
297 cached_Xs[len] = std::vector<fftw_complex*>(tid+1,0);
300 if (cached_xs[len].size() <= tid)
302 cached_xs[len].resize(tid+1,0);
303 cached_Xs[len].resize(tid+1,0);
308 cached_xs[len][tid] = mem_x;
309 cached_Xs[len][tid] = mem_X;
313 cached_xs[len] = mem_x;
314 cached_Xs[len] = mem_X;
324 std::pair<fftw_plan,fftw_plan> plans;
325 #ifdef FFTW_USE_PATIENT 326 plans.first = fftw_plan_dft_r2c_1d(len,mem_x, mem_X, FFTW_PATIENT | FFTW_PRESERVE_INPUT);
327 plans.second = fftw_plan_dft_c2r_1d(len,mem_X, mem_x, FFTW_PATIENT);
329 plans.first = fftw_plan_dft_r2c_1d(len,mem_x, mem_X, FFTW_MEASURE | FFTW_PRESERVE_INPUT);
330 plans.second = fftw_plan_dft_c2r_1d(len,mem_X, mem_x, FFTW_MEASURE);
332 cached_plans[len] = plans;
335 #ifdef FFTOOLS_THREAD_SAFE 341 return forward ? (*it).second.first : (*it).second.second;
345 return forward ? cached_plans[len].first : cached_plans[len].second;
355 #ifdef FFTTOOLS_USE_OMP 356 #pragma omp critical (fft_tools) 358 plan = getPlan(length,
true);
361 plan = getPlan(length,
true);
364 fftw_execute_dft_r2c(plan, (
double*) in, (fftw_complex*) out);
375 #ifdef FFTTOOLS_USE_OMP 376 #pragma omp critical (fft_tools) 378 plan = getPlan(length,
false);
381 plan = getPlan(length,
false);
384 fftw_complex new_in[length/2+1]
__attribute__((aligned(32)));
386 #if ( __clang__major__ >3 || (__clang_major__==3 && __clang_minor__ >=6) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) 391 memcpy(new_in, ain, (length/2+1) *
sizeof(
FFTWComplex));
392 fftw_execute_dft_c2r(plan,new_in, out);
394 #if ( __clang__major__ >3 || (__clang_major__==3 && __clang_minor__ >=6) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) 395 double * aout = (
double*) __builtin_assume_aligned(out,32);
397 double * aout = (
double*) out;
401 for (
int i = 0; i < length; i++)
411 #ifdef FFTTOOLS_USE_OMP 412 #pragma omp critical (fft_tools) 414 plan = getPlan(length,
false);
417 plan = getPlan(length,
false);
421 #if ( __clang__major__ >3 || (__clang_major__==3 && __clang_minor__ >=6) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) 422 fftw_execute_dft_c2r(plan, (fftw_complex*) in, out);
424 double * aout = (
double*) __builtin_assume_aligned(out,32);
426 double * aout = (
double*) out;
429 for (
int i = 0; i < length; i++)
439 const int numFreqs= (length/2)+1;
440 #ifdef FFTTOOLS_USE_OMP 442 fftw_complex * mem_X;
444 unsigned long tid = GET_TID();
445 #pragma omp critical (fft_tools) 447 plan = getPlan(length,
true);
448 mem_X = cached_Xs[length][tid];
449 mem_x = cached_xs[length][tid];
452 fftw_plan plan = getPlan(length,
true);
454 #if FFTTOOLS_THREAD_SAFE 455 unsigned long tid = GET_TID();
457 fftw_complex * mem_X = cached_Xs[length][tid];
458 double * mem_x = cached_xs[length][tid];
466 #ifdef USE_PER_THREAD_MEMORY 468 memcpy(mem_x, theInput,
sizeof(
double)*length);
469 fftw_execute_dft_r2c(plan, mem_x, mem_X);
470 memcpy(myOutput, mem_X,
sizeof(fftw_complex)*numFreqs);
472 memcpy(cached_xs[length], theInput,
sizeof(
double)*length);
474 memcpy(myOutput, cached_Xs[length],
sizeof(fftw_complex)*numFreqs);
488 #ifdef FFTTOOLS_USE_OMP 489 fftw_complex * mem_X;
492 unsigned long tid = GET_TID();
493 #pragma omp critical (fft_tools) 495 plan = getPlan(length,
false);
496 mem_X = cached_Xs[length][tid];
497 mem_x = cached_xs[length][tid];
500 fftw_plan plan = getPlan(length,
false);
502 #if FFTTOOLS_THREAD_SAFE 504 unsigned long tid = GET_TID();
505 fftw_complex * mem_X = cached_Xs[length][tid];
506 double *mem_x = cached_xs[length][tid];
512 double *theOutput =
new double [length];
514 #ifdef USE_PER_THREAD_MEMORY 515 memcpy(mem_X, theInput,
sizeof(fftw_complex) * (length/2 + 1));
516 fftw_execute_dft_c2r(plan, mem_X, mem_x);
518 memcpy (cached_Xs[length], theInput,
sizeof(fftw_complex) * (length/2 +1));
520 double * mem_x = cached_xs[length];
524 for(
int i=0; i<length; i++){
529 memcpy(theOutput, mem_x,
sizeof(
double)*length);
540 for(
int i=0;i<numArrays;i++) {
541 theFFTs[i]=doFFT(eachLength,thePtrPtr[i]);
544 int fftLength=(eachLength/2)+1;
548 for(
int i=0;i<fftLength;i++) {
549 double tempAbs0=
getAbs(theFFTs[0][i]);
550 double tempTotAbs=tempAbs0;
551 for(
int arNum=1;arNum<numArrays;arNum++) {
552 tempTotAbs+=
getAbs(theFFTs[arNum][i]);
555 combinedFFT[i].
re=theFFTs[0][i].
re*(tempTotAbs/(tempAbs0*double(numArrays)));
556 combinedFFT[i].
im=theFFTs[0][i].
im*(tempTotAbs/(tempAbs0*double(numArrays)));
559 for(
int i=0;i<numArrays;i++) {
560 delete [] theFFTs[i];
563 double *newValues=doInvFFT(eachLength,combinedFFT);
564 delete [] combinedFFT;
572 double totalWeight=0;
574 for(
int i=0;i<numGraphs;i++) {
575 totalWeight+=theWeights[i];
581 for(
int i=0;i<numGraphs;i++) {
582 double *oldY=grPtr[i]->GetY();
583 int oldLength=grPtr[i]->GetN();
584 theFFTs[i]=doFFT(oldLength,oldY);
587 int fftLength=((grPtr[0]->GetN())/2)+1;
590 for(
int i=0;i<fftLength;i++) {
592 double tempAbs0=
getAbs(theFFTs[0][i]);
593 double tempTotAbs=tempAbs0*theWeights[0];
594 for(
int grNum=1;grNum<numGraphs;grNum++) {
595 tempTotAbs+=
getAbs(theFFTs[grNum][i])*theWeights[grNum];
598 combinedFFT[i].
re=theFFTs[0][i].
re*(tempTotAbs/(tempAbs0*double(totalWeight)));
599 combinedFFT[i].
im=theFFTs[0][i].
im*(tempTotAbs/(tempAbs0*double(totalWeight)));
602 double tempAbs0=
getAbs(theFFTs[0][i]);
603 double tempTotAbs=tempAbs0;
604 for(
int grNum=1;grNum<numGraphs;grNum++) {
605 tempTotAbs+=
getAbs(theFFTs[grNum][i]);
608 combinedFFT[i].
re=theFFTs[0][i].
re*(tempTotAbs/(tempAbs0*double(numGraphs)));
609 combinedFFT[i].
im=theFFTs[0][i].
im*(tempTotAbs/(tempAbs0*double(numGraphs)));
613 for(
int i=0;i<numGraphs;i++) {
614 delete [] theFFTs[i];
618 double *newX=grPtr[0]->GetX();
619 int newLength=grPtr[0]->GetN();
620 double *newY=doInvFFT(newLength,combinedFFT);
621 TGraph *grOut =
new TGraph(newLength,newX,newY);
622 delete [] combinedFFT;
630 int length=gr1->GetN();
631 Double_t *y1=gr1->GetY();
632 int length2=gr2->GetN();
633 if(length2<length) length=length2;
634 Double_t *y2=gr2->GetY();
635 Double_t denom=gr1->GetRMS(2)*gr2->GetRMS(2);
637 Double_t *x1=gr1->GetX();
638 Double_t *x2=gr2->GetX();
640 double deltaT=x1[1]-x1[0];
641 double waveOffset=x1[0]-x2[0];
649 (*zeroOffset)+=Int_t(waveOffset/deltaT);
656 int lastRealSamp=N-1;
660 minDtIndex=TMath::Floor((dtMin-waveOffset)/deltaT)+(N/2);
661 if(minDtIndex<0) minDtIndex=0;
662 maxDtIndex=TMath::Ceil((dtMax-waveOffset)/deltaT)+(N/2);
663 if(maxDtIndex<0) maxDtIndex=0;
670 double *xVals =
new double [N];
671 double *corVals=
new double [N];
672 for(
int i=minDtIndex;i<=maxDtIndex;i++) {
674 int dtIndex=(i-minDtIndex);
677 xVals[dtIndex]=((i-N/2)*deltaT)+waveOffset;
679 if(i>=firstRealSamp && i<=lastRealSamp) {
681 Int_t firstIndex=(i-firstRealSamp);
682 Int_t secondIndex=length-1;
683 if(firstIndex>length-1) {
684 int offset=firstIndex-(length-1);
693 for(;firstIndex>=0 && secondIndex>=0;firstIndex--) {
695 corVals[dtIndex]+=y1[firstIndex]*y2[secondIndex];
699 corVals[dtIndex]/=denom*sqrt(numSamples);
703 TGraph *grCor =
new TGraph((maxDtIndex-minDtIndex)+1,xVals,corVals);
712 int length=gr1->GetN();
713 Double_t *y1=gr1->GetY();
714 int length2=gr2->GetN();
715 Double_t *y2=gr2->GetY();
716 Double_t denom=gr1->GetRMS(2)*gr2->GetRMS(2);
718 int N=int(TMath::Power(2,
int(TMath::Log2(length))+2));
720 N=int(TMath::Power(2,
int(TMath::Log2(length2))+2));
723 int firstRealSamp=1+(N-2*length)/2;
724 int lastRealSamp=firstRealSamp+2*(length-1);
726 Double_t *corVal=grCor->GetY();
730 for(
int i=0;i<N;i++) {
731 if(i>=firstRealSamp && i<=lastRealSamp) {
733 norm1+=(y1[i-firstRealSamp]*y1[i-firstRealSamp]);
734 norm2+=(y2[length-1-(i-firstRealSamp)]*y2[length-1-(i-firstRealSamp)]);
735 int effN=1+(i-firstRealSamp);
736 corVal[i]/=(sqrt(effN)*denom);
739 norm1-=(y1[i-1-(N/2)]*y1[i-1-(N/2)]);
740 norm2-=(y2[length-(i-(N/2))]*y2[length-(i-(N/2))]);
741 int effN=(1+lastRealSamp-i);
742 corVal[i]/=(sqrt(effN)*denom);
756 int length=gr1->GetN();
757 int length2=gr2->GetN();
759 int N=int(TMath::Power(2,
int(TMath::Log2(length))+2));
761 N=int(TMath::Power(2,
int(TMath::Log2(length2))+2));
764 int firstRealSamp=(N-length)/2;
766 double *oldY1 =
new double [N];
767 double *oldY2 =
new double [N];
771 gr1->GetPoint(1,x2,y2);
772 gr1->GetPoint(0,x,y);
776 gr2->GetPoint(0,x2,y2);
777 double waveOffset=firstX-x2;
784 for(
int i=0;i<N;i++) {
786 if(i<firstRealSamp || i>=firstRealSamp+length)
789 gr1->GetPoint(i-firstRealSamp,x,y);
793 if(i<firstRealSamp || i>=firstRealSamp+length2)
796 gr2->GetPoint(i-firstRealSamp,x,y);
806 (*zeroOffset)+=Int_t(waveOffset/deltaT);
809 double *xVals =
new double [N];
810 double *yVals =
new double [N];
812 for(
int i=0;i<N;i++) {
815 xVals[i+(N/2)]=(i*deltaT)+waveOffset;
816 yVals[i+(N/2)]=corVals[i];
820 xVals[i-(N/2)]=((i-N)*deltaT)+waveOffset;
821 yVals[i-(N/2)]=corVals[i];
826 TGraph *grCor =
new TGraph(N,xVals,yVals);
840 TGraph *gr1 = getInterpolatedGraph(grIn1,deltaT);
841 TGraph *gr2 = getInterpolatedGraph(grIn2,deltaT);
854 double *newY1 =
new double [length];
855 double *newY2 =
new double [length];
856 for(
int i=0;i<length;i++) {
857 newY1[i]=(double)oldY1[i];
858 newY2[i]=(double)oldY2[i];
876 int newLength=(length/2)+1;
880 for(
int i=0;i<newLength;i++) {
881 double reFFT1=theFFT1[i].
re;
882 double imFFT1=theFFT1[i].
im;
883 double reFFT2=theFFT2[i].
re;
884 double imFFT2=theFFT2[i].
im;
887 tempStep[i].
re=(reFFT1*reFFT2+imFFT1*imFFT2)/
double(no2/2);
889 tempStep[i].
im=(imFFT1*reFFT2-reFFT1*imFFT2)/
double(no2/2);
892 double *theOutput=doInvFFT(length,tempStep);
903 int tempLength=gr1->GetN();
904 if(firstIndex<0 || lastIndex>tempLength)
return 0;
906 int length=lastIndex-firstIndex;
908 double *y1 = gr1->GetY();
910 double *y2 = gr2->GetY();
921 double *oldY = grWave->GetY();
922 double *oldX = grWave->GetX();
924 int length=grWave->GetN();
926 double *invInvSpectrum = doInvFFT(length,theFFT);
928 TGraph *grInvInv =
new TGraph(length,oldX,invInvSpectrum);
940 int newLength=(length/2)+1;
941 for(
int i=0;i<newLength;i++) {
942 double tempIm=theFFT[i].
im;
943 theFFT[i].
im=theFFT[i].
re;
944 theFFT[i].
re=-1*tempIm;
946 double *hilbert = doInvFFT(length,theFFT);
953 double *oldY = grWave->GetY();
954 double *oldX = grWave->GetX();
955 int length=grWave->GetN();
957 TGraph *grHilbert =
new TGraph(length,oldX,hilbert);
967 double *realY = grWave->GetY();
968 double *x = grWave->GetX();
970 double *hilY=grHilbert->GetY();
971 int length=grWave->GetN();
972 Double_t *envY=
new Double_t[length];
973 for(
int i=0;i<length;i++) {
975 envY[i]=TMath::Sqrt(realY[i]*realY[i] + hilY[i]*hilY[i]);
978 TGraph *grEnvelope =
new TGraph(length,x,envY);
987 Double_t *inY = grWave->GetY();
988 Double_t *inX = grWave->GetX();
989 Int_t length=grWave->GetN();
990 Double_t *smoothY =
new Double_t[length];
991 for(
int i=0;i<length;i++) {
993 if(i<halfWidth || length-i<=halfWidth) {
995 for(
int j=i-halfWidth;j<=i+halfWidth;j++) {
996 if(j>=0 && j<length) {
1002 smoothY[i]/=countVals;
1005 for(
int j=i-halfWidth;j<=i+halfWidth;j++) {
1008 smoothY[i]/=1+2*halfWidth;
1011 TGraph *grSmooth =
new TGraph(length,inX,smoothY);
1018 Double_t *oldY=grWave->GetY();
1019 Double_t *t = grWave->GetX();
1020 Int_t numPoints = grWave->GetN();
1021 Double_t *newY =
new Double_t [numPoints];
1022 for(
int i=0;i<numPoints;i++) {
1025 TGraph *grNew =
new TGraph(numPoints,t,newY);
1033 double *oldY = grWave->GetY();
1034 double *oldX = grWave->GetX();
1035 double deltaT=oldX[1]-oldX[0];
1036 int length=grWave->GetN();
1039 int newLength=(length/2)+1;
1040 double *newY =
new double [newLength];
1041 double *newX =
new double [newLength];
1044 double deltaF=1/(deltaT*length);
1047 for(
int i=0;i<newLength;i++) {
1048 float power=pow(
getAbs(theFFT[i]),2);
1049 if(i>0 && i<newLength-1) power*=2;
1060 TGraph *grPower =
new TGraph(newLength,newX,newY);
1072 double *oldY = grWave->GetY();
1073 double *oldX = grWave->GetX();
1074 double deltaT=oldX[1]-oldX[0];
1075 int length=grWave->GetN();
1078 int newLength=(length/2)+1;
1080 double *newY =
new double [newLength];
1081 double *newX =
new double [newLength];
1084 double deltaF=1/(deltaT*length);
1087 for(
int i=0;i<newLength;i++) {
1088 float power=pow(
getAbs(theFFT[i]),2);
1089 if(i>0 && i<newLength-1) power*=2;
1090 power/=double(length*length);
1098 TGraph *grPower =
new TGraph(newLength,newX,newY);
1108 double *oldY = grWave->GetY();
1109 double *oldX = grWave->GetX();
1110 double deltaT=oldX[1]-oldX[0];
1111 int length=grWave->GetN();
1114 int newLength=(length/2)+1;
1116 double *newY =
new double [newLength];
1117 double *newX =
new double [newLength];
1120 double deltaF=1/(deltaT*length);
1125 for(
int i=0;i<newLength;i++) {
1126 float power=pow(
getAbs(theFFT[i]),2);
1127 if(i>0 && i<newLength-1) power*=2;
1128 power*=deltaT/(length);
1139 TGraph *grPower =
new TGraph(newLength,newX,newY);
1199 double *oldY = grWave->GetY();
1200 double *oldX = grWave->GetX();
1201 double deltaT=oldX[1]-oldX[0];
1202 int length=grWave->GetN();
1205 int newLength=(length/2)+1;
1207 double *newY =
new double [newLength];
1208 double *newX =
new double [newLength];
1211 double deltaF=1/(deltaT*length);
1216 for(
int i=0;i<newLength;i++) {
1217 float power=pow(
getAbs(theFFT[i]),2);
1218 if(i>0 && i<newLength-1) power*=2;
1219 power*=deltaT/(length);
1232 TGraph *grPower =
new TGraph(newLength,newX,newY);
1241 TGraph *FFTtools::makePowerSpectrumMilliVoltsNanoSecondsdB(
const TGraph *grWave)
1243 double *oldY = grWave->GetY();
1244 double *oldX = grWave->GetX();
1245 double deltaT=oldX[1]-oldX[0];
1246 int length=grWave->GetN();
1249 int newLength=(length/2)+1;
1251 double *newY =
new double [newLength];
1252 double *newX =
new double [newLength];
1255 double deltaF=1/(deltaT*length);
1260 for(
int i=0;i<newLength;i++) {
1261 float power=pow(getAbs(theFFT[i]),2);
1262 if(i>0 && i<newLength-1) power*=2;
1263 power*=deltaT/(length);
1269 if (power>0 ) power=10*TMath::Log10(power);
1277 TGraph *grPower =
new TGraph(newLength,newX,newY);
1288 double *oldY = grWave->GetY();
1289 double *oldX = grWave->GetX();
1290 double deltaT=oldX[1]-oldX[0];
1291 int length=grWave->GetN();
1294 int newLength=(length/2)+1;
1296 double *newY =
new double [newLength];
1297 double *newX =
new double [newLength];
1300 double deltaF=1/(deltaT*length);
1305 for(
int i=0;i<newLength;i++) {
1307 double power=pow(
getAbs(theFFT[i]),2);
1308 if(i>0 && i<newLength-1) power*=2;
1309 power*=deltaT/(length);
1315 logpower=10*TMath::Log10(power);
1327 TGraph *grPower =
new TGraph(newLength,newX,newY);
1338 TGraph *grPad=
padWave(grWave,padFactor);
1347 TGraph *grPad=
padWave(grWave,padFactor);
1356 double *oldY = grWave->GetY();
1357 double *oldX = grWave->GetX();
1358 double deltaT=oldX[1]-oldX[0];
1359 int length=grWave->GetN();
1362 int newLength=(length/2)+1;
1363 double *newY =
new double [newLength];
1364 double *newX =
new double [newLength];
1366 double deltaF=1/(deltaT*length);
1370 for(
int i=0;i<newLength;i++) {
1371 float power=pow(
getAbs(theFFT[i]),2);
1372 if(i>0 && i<newLength-1) power*=2;
1379 TGraph *grPower =
new TGraph(newLength,newX,newY);
1389 return sqrt(theNum.
re*theNum.
re+theNum.
im*theNum.
im);
1395 Double_t integral=0;
1396 Double_t freq,power;
1397 if(firstBin<0) firstBin=0;
1398 if(lastBin<0) lastBin=gr->GetN()-1;
1399 for(
int i=firstBin;i<=lastBin;i++) {
1400 gr->GetPoint(i,freq,power);
1408 Double_t integral=0;
1409 Double_t freq,power;
1410 gr->GetPoint(1,freq,power);
1412 gr->GetPoint(0,freq,power);
1414 if(firstBin<0) firstBin=0;
1415 if(lastBin<0) lastBin=gr->GetN()-1;
1416 for(
int i=firstBin;i<=lastBin;i++) {
1417 gr->GetPoint(i,freq,power);
1425 Double_t integral=0;
1426 Double_t time,volts;
1427 if(firstBin<0) firstBin=0;
1428 if(lastBin<0) lastBin=gr->GetN()-1;
1429 for(
int i=firstBin;i<=lastBin;i++) {
1430 gr->GetPoint(i,time,volts);
1431 integral+=volts*volts;
1438 Double_t integral=0;
1439 Double_t this_time=0, next_time=0, this_v=0, next_v=0, dt=0;
1441 if(firstBin<0) firstBin=0;
1442 if(lastBin<0) lastBin = gr->GetN()-1;
1443 for(
int samp=firstBin; samp<lastBin; samp++){
1444 gr->GetPoint(samp, this_time, this_v);
1445 gr->GetPoint(samp+1, next_time, next_v);
1446 dt=next_time-this_time;
1447 integral+=this_v*this_v*dt;
1450 integral+=next_v*next_v*dt;
1459 gr->GetPoint(0,x,y);
1462 for(
int i=1;i<gr->GetN();i++) {
1463 gr->GetPoint(i,x,y);
1476 gr->GetPoint(0,x,y);
1479 for(
int i=1;i<gr->GetN();i++) {
1480 gr->GetPoint(i,x,y);
1492 if(firstBin<0 || lastBin<0 || firstBin>gr->GetN() || lastBin>gr->GetN() ||
1496 gr->GetPoint(firstBin,x,y);
1499 for(
int i=firstBin;i<lastBin;i++) {
1500 gr->GetPoint(i,x,y);
1513 gr->GetPoint(0,x,y);
1516 Int_t numPoints=gr->GetN();
1517 for(
int i=1;i<numPoints;i++) {
1518 gr->GetPoint(i,x,y);
1530 if(firstBin<0 || lastBin<0 || firstBin>gr->GetN() || lastBin>gr->GetN() ||
1534 gr->GetPoint(firstBin,x,y);
1537 for(
int i=firstBin;i<lastBin;i++) {
1538 gr->GetPoint(i,x,y);
1553 gr->GetPoint(0,x,y);
1554 Double_t peakVal=y*y;
1556 Int_t numPoints=gr->GetN();
1557 for(
int i=1;i<numPoints;i++) {
1558 gr->GetPoint(i,x,y);
1572 Int_t numPoints=gr->GetN();
1573 Double_t *y = gr->GetY();
1574 Double_t *ySq =
new Double_t [numPoints];
1575 for(
int i=0;i<numPoints;i++) {
1578 Int_t peakInd=TMath::LocMax(numPoints,ySq);
1580 rms=TMath::RMS(numPoints,ySq);
1589 Int_t numPoints=grRec->GetN();
1590 Double_t *y = grRec->GetY();
1591 Int_t peakInd=TMath::LocMax(numPoints,y);
1593 rms=TMath::RMS(numPoints,y);
1601 Int_t N1=grA->GetN();
1602 Int_t N2=grB->GetN();
1603 if(N1!=N2)
return NULL;
1605 Double_t *newY =
new Double_t [N1];
1606 Double_t *xVals=grA->GetX();
1608 for(
int i=0;i<N1;i++) {
1609 grA->GetPoint(i,x,yA);
1610 grB->GetPoint(i,x,yB);
1613 TGraph *grDiff =
new TGraph(N1,xVals,newY);
1621 Int_t N = grWave->GetN();
1622 Double_t *X=grWave->GetX();
1623 Double_t *
Y=grWave->GetY();
1624 Double_t *newX =
new Double_t[N];
1625 for(
int i=0;i<N;i++)
1626 newX[i]=X[i]+deltaT;
1627 TGraph *grOut =
new TGraph(N,newX,
Y);
1634 Int_t N1=grA->GetN();
1635 Int_t N2=grB->GetN();
1636 if(N1!=N2)
return NULL;
1638 Double_t *newY =
new Double_t [N1];
1639 Double_t *xVals=grA->GetX();
1641 for(
int i=0;i<N1;i++) {
1642 grA->GetPoint(i,x,yA);
1643 grB->GetPoint(i,x,yB);
1646 TGraph *grRat =
new TGraph(N1,xVals,newY);
1654 Int_t N1=grA->GetN();
1655 Int_t N2=grB->GetN();
1663 Double_t *xVals=grA->GetX();
1664 Double_t *xBVals=grB->GetX();
1665 Double_t deltaF=xVals[1]-xVals[0];
1666 Double_t deltaFB=xBVals[1]-xBVals[0];
1668 if(TMath::Abs(deltaFB-deltaF)>1)
return NULL;
1670 Double_t *newY =
new Double_t [newN];
1672 for(
int i=0;i<newN;i++) {
1673 grA->GetPoint(i,x,yA);
1674 grB->GetPoint(i,x,yB);
1677 TGraph *grRat =
new TGraph(newN,xVals,newY);
1684 Int_t N1=grA->GetN();
1685 Int_t N2=grB->GetN();
1693 Double_t *xVals=grA->GetX();
1694 Double_t *xBVals=grB->GetX();
1695 Double_t deltaF=xVals[1]-xVals[0];
1696 Double_t deltaFB=xBVals[1]-xBVals[0];
1700 if(TMath::Abs(deltaFB-deltaF)>1)
return NULL;
1702 Double_t *newY =
new Double_t [newN];
1704 for(
int i=0;i<newN;i++) {
1705 grA->GetPoint(i,x,yA);
1706 grB->GetPoint(i,x,yB);
1707 newY[i]=10*TMath::Log10(yA/yB);
1709 TGraph *grRat =
new TGraph(newN,xVals,newY);
1718 Int_t newN=N/factor;
1719 Double_t *xVals=gr->GetX();
1720 Double_t *yVals=gr->GetY();
1722 Double_t *newX =
new Double_t [newN];
1723 Double_t *newY =
new Double_t [newN];
1727 for(
int i=0;i<N;i++) {
1730 if((i+1)%factor==0) {
1733 newX[(i+1)/factor-1]=sumX/factor;
1734 newY[(i+1)/factor-1]=sumY/factor;
1739 TGraph *grSmooth =
new TGraph(newN,newX,newY);
1746 double *oldY = grWave->GetY();
1747 double *oldX = grWave->GetX();
1748 double deltaT=oldX[1]-oldX[0];
1749 int realLength = grWave->GetN();
1750 int length = grWave->GetN()*padFactor;
1751 double *paddedY =
new double [length];
1752 double *paddedX =
new double [length];
1753 int newStart=(realLength*(padFactor-1))/2;
1754 for(
int i=0;i<length;i++) {
1755 int waveIndex=i-newStart;
1757 paddedX[i]=(waveIndex*deltaT)+oldX[0];
1758 if(waveIndex>=0 && waveIndex<realLength) {
1759 paddedY[i]=oldY[waveIndex];
1762 TGraph *grPadded =
new TGraph(length,paddedX,paddedY);
1770 double *oldY = grWave->GetY();
1771 double *oldX = grWave->GetX();
1772 double deltaT=oldX[1]-oldX[0];
1773 int realLength = grWave->GetN();
1774 if(newLength<realLength) {
1775 std::cerr <<
"Can't pad waveform of length " << realLength
1776 <<
" to " << newLength <<
" you need to crop not pad\n";
1779 int length = newLength;
1780 double *paddedY =
new double [length];
1781 double *paddedX =
new double [length];
1782 int newStart=(newLength-realLength)/2;
1783 for(
int i=0;i<length;i++) {
1784 int waveIndex=i-newStart;
1786 paddedX[i]=(waveIndex*deltaT)+oldX[0];
1787 if(waveIndex>=0 && waveIndex<realLength) {
1788 paddedY[i]=oldY[waveIndex];
1791 TGraph *grPadded =
new TGraph(length,paddedX,paddedY);
1804 Int_t numPoints = gr->GetN();
1805 Double_t *x = gr->GetX();
1806 Double_t *y = gr->GetY();
1807 Double_t *yRec =
new Double_t [numPoints];
1808 for(
int i=0;i<numPoints;i++) {
1809 yRec[i]=sign*TMath::Abs(y[i]);
1811 TGraph *grRec =
new TGraph(numPoints,x,yRec);
1818 Double_t *ySq =
new Double_t [gr->GetN()];
1819 Double_t *xOrig =
new Double_t [gr->GetN()];
1820 Double_t *yEnvelope =
new Double_t[gr->GetN()];
1821 Double_t *xEnvelope =
new Double_t[gr->GetN()];
1826 for(
int i=0;i<gr->GetN();i++) {
1827 gr->GetPoint(i,x,y);
1832 yEnvelope[numPoints]=ySq[0];
1833 xEnvelope[numPoints]=xOrig[0];
1837 else if(i==gr->GetN()-1 && ySq[i]>ySq[i-1]) {
1838 yEnvelope[numPoints]=ySq[i];
1839 xEnvelope[numPoints]=xOrig[i];
1842 else if(ySq[i-1]>ySq[i-2] && ySq[i-1]>ySq[i]) {
1843 yEnvelope[numPoints]=ySq[i-1];
1844 xEnvelope[numPoints]=xOrig[i-1];
1848 TGraph *grEnvelope=
new TGraph(numPoints,xEnvelope,yEnvelope);
1851 delete [] yEnvelope;
1852 delete [] xEnvelope;
1858 TGraph *grPad=
padWave(grWave,padFactor);
1859 Int_t numTot=grPad->GetN();
1860 Double_t *tVals = grPad->GetX();
1861 Double_t *vVals = grPad->GetY();
1862 Int_t m2=numFreqs*2;
1863 Double_t *inTimes =
new Double_t[m2];
1864 Double_t *inVolts =
new Double_t[m2];
1865 Double_t *outFreqs=
new Double_t[m2];
1866 Double_t *outPower=
new Double_t[m2];
1867 Int_t numSegs=(numTot-1)/numFreqs;
1868 Double_t delta= numSegs>1 ? Double_t(numTot-m2)/(numSegs-1.) : 0.;
1870 cerr <<
"Not enough data points for this many frequency bins" << endl;
1874 for(
int i=0;i<m2;i++) {
1878 for(
int k=0;k<numSegs;k++) {
1879 Int_t noff = (Int_t)(k*delta + 0.5);
1880 for(
int i=0;i<m2;i++) {
1881 inTimes[i]=tVals[i+noff];
1884 TGraph grTemp(m2,inTimes,inVolts);
1886 Double_t *tempFreq = grPowTemp->GetX();
1887 Double_t *tempPower = grPowTemp->GetY();
1888 numOut=grPowTemp->GetN();
1889 for(
int i=0;i<numOut;i++) {
1890 outFreqs[i]=tempFreq[i];
1891 outPower[i]+=tempPower[i];
1897 TGraph *grRet =
new TGraph (numOut,outFreqs,outPower);
1907 for(
int samp=1;samp<numPoints;samp++) {
1908 Double_t deltaT=inputX[samp]-inputX[samp-1];
1909 Double_t deltaV=inputY[samp]-inputY[samp-1];
1910 outputX[count]=inputX[samp];
1911 outputY[count]=deltaV/deltaT;
1924 Int_t numPoints=grIn->GetN();
1925 if(numPoints<2)
return NULL;
1926 Double_t *xVals=grIn->GetX();
1927 Double_t *yVals=grIn->GetY();
1928 Double_t *newX =
new Double_t [numPoints];
1929 Double_t *newY =
new Double_t [numPoints];
1931 TGraph *grDeriv =
new TGraph(numPoints-1,newX,newY);
1941 double *oldY = grWave->GetY();
1942 double *oldX = grWave->GetX();
1943 double deltaT=oldX[1]-oldX[0];
1944 int length=grWave->GetN();
1947 int newLength=(length/2)+1;
1950 double deltaF=1/(deltaT*length);
1955 for(
int i=0;i<newLength;i++) {
1957 if(tempF<minFreq || tempF>maxFreq) {
1965 double *filteredVals = doInvFFT(length,theFFT);
1968 TGraph *grFiltered =
new TGraph(length,oldX,filteredVals);
1970 delete [] filteredVals;
1978 double *oldY = grWave->GetY();
1979 double *oldX = grWave->GetX();
1980 double deltaT=oldX[1]-oldX[0];
1981 int length=grWave->GetN();
1984 int newLength=(length/2)+1;
1987 double deltaF=1/(deltaT*length);
1992 for(
int i=0;i<newLength;i++) {
1994 if(tempF>minFreq && tempF<maxFreq) {
2002 double *filteredVals = doInvFFT(length,theFFT);
2005 TGraph *grFiltered =
new TGraph(length,oldX,filteredVals);
2007 delete [] filteredVals;
2014 Int_t numPoints=grWave->GetN();
2015 if(numPoints<1)
return NULL;
2016 Double_t *xVals=grWave->GetX();
2017 Double_t *yVals=grWave->GetY();
2019 Double_t *outX =
new Double_t[numPoints];
2020 Double_t *outY =
new Double_t[numPoints];
2023 for(
int i=0;i<numPoints;i++) {
2024 if(xVals[i]>=minTime && xVals[i]<=maxTime) {
2025 outX[outPoints]=xVals[i];
2026 outY[outPoints]=yVals[i];
2031 TGraph *grCrop =
new TGraph(outPoints,outX,outY);
2041 double *oldY = grWave->GetY();
2042 double *oldX = grWave->GetX();
2043 double deltaT=oldX[1]-oldX[0];
2044 int length=grWave->GetN();
2047 int newLength=(length/2)+1;
2050 double deltaF=1/(deltaT*length);
2055 for(
int i=0;i<newLength;i++) {
2057 for(
int notch=0;notch<numNotches;notch++) {
2058 if(tempF>minFreq[notch] && tempF<maxFreq[notch]) {
2068 double *filteredVals = doInvFFT(length,theFFT);
2071 TGraph *grFiltered =
new TGraph(length,oldX,filteredVals);
2073 delete [] filteredVals;
2096 Int_t nBins = gr->GetN();
2098 Double_t *yVals = gr->GetY();
2103 for(
int i=0;i<nRMS;i++){
2105 meanSq+=yVals[i]*yVals[i];
2107 mean/=
static_cast<double>(nRMS);
2108 meanSq/=
static_cast<double>(nRMS);
2115 for(
int i=0;i<nBins;i++){
2118 if(y<yVals[i-1] && trending==0){
2119 if(TMath::Abs(y-yVals[firstBin]>p2p)){
2120 p2p=TMath::Abs(y-yVals[firstBin]);
2123 else if(y<yVals[i-1] && (trending==1 || trending==2)){
2126 if(TMath::Abs(y-yVals[firstBin]>p2p)){
2127 p2p=TMath::Abs(y-yVals[firstBin]);
2130 else if(y>yVals[i-1] && (trending==0 || trending==2)){
2133 if(TMath::Abs(y-yVals[firstBin]>p2p)){
2134 p2p=TMath::Abs(y-yVals[firstBin]);
2137 else if(y>yVals[i-1] && trending==1){
2138 if(TMath::Abs(y-yVals[firstBin]>p2p)){
2139 p2p=TMath::Abs(y-yVals[firstBin]);
2142 else if(y==yVals[i-1]){
2145 else if(trending==3){
2156 std::cout <<
"trending cock up!" << std::endl;
2157 std::cout <<
"y " << y <<
" yVals[i] " << yVals[i] <<
" yVals[i-1] " << yVals[i-1] << std::endl;
2165 rms=sqrt(meanSq-mean*mean);
2179 Int_t nBins = gr->GetN();
2180 Double_t yMax = -9999;
2183 for(
int i=0;i<nBins;i++){
2184 gr->GetPoint(i,x,y);
2195 Double_t FFTtools::getEnvelopeSNR(
const TGraph *gr){
2199 Double_t snr = getEnvelopeSNR(gr,dummyPeak,dummyRms,dummyTime);
2207 Double_t FFTtools::getEnvelopeSNR(
const TGraph *gr,Double_t &peak,Double_t &rms,Double_t &timeOfPeak)
2212 Int_t nBins = gr->GetN();
2213 Double_t *xVals = gr->GetX();
2214 Double_t *yVals = gr->GetY();
2219 for(
int i=0;i<nRMS;i++){
2221 meanSq+=yVals[i]*yVals[i];
2223 mean/=
static_cast<double>(nRMS);
2224 meanSq/=
static_cast<double>(nRMS);
2231 for(
int i=0;i<nBins;i++){
2233 std::cout <<
"this isn't an envelope!!!" << std::endl;
2246 rms=sqrt(meanSq-mean*mean);
2258 Double_t *freqs=inputMag->GetX();
2259 Double_t *newVmmhz=inputMag->GetY();
2260 Int_t numFreqs=inputMag->GetN();
2261 Double_t *vmhz =
new Double_t [numFreqs];
2262 Int_t numPoints=2*(numFreqs-1);
2264 Double_t df=freqs[1]-freqs[0];
2265 for(
int i=0;i<numFreqs;i++) {
2266 vmhz[i]=newVmmhz[i]/1e6;
2269 freqDom[i].
im=vmhz[i];
2273 Double_t *newT =
new Double_t [numPoints];
2274 Double_t *newV =
new Double_t [numPoints];
2275 Double_t dt=1./(numPoints*df);
2276 for(
int i=0;i<numPoints;i++) {
2278 Int_t tempInd=(numPoints/2)-(i+1);
2280 newT[tempInd]=-i*dt;
2281 newV[tempInd]=tempV[i]*df*numPoints/sqrt(2);
2285 Int_t tempInd=numPoints+(numPoints/2)-(i+1);
2287 newT[tempInd]=(numPoints-i)*dt;
2288 newV[tempInd]=tempV[i]*df*numPoints/sqrt(2);
2295 TGraph *grWave =
new TGraph(numPoints,newT,newV);
2306 return ((y2 - y1)* ((x - x1) / (x2-x1)) + y1);
2311 Int_t numPointsA=grA->GetN();
2312 Int_t numPointsB=grB->GetN();
2314 Double_t *tA=grA->GetX();
2315 Double_t *inA=grA->GetY();
2316 Double_t *inB=grB->GetY();
2319 Double_t deltaT=tA[1]-tA[0];
2322 Int_t numPoints=numPointsA;
2323 if(numPointsB>numPoints) {
2324 numPoints=numPointsB;
2326 Double_t *A=
new Double_t[numPoints];
2327 Double_t *B=
new Double_t[numPoints];
2328 Double_t *T=
new Double_t[numPoints];
2330 for(
int i=0;i<numPoints;i++) {
2331 Int_t indA=(i-(numPoints-numPointsA)/2);
2332 T[i]=t0+indA*deltaT;
2333 if(indA<0 || indA>=numPointsA)
2338 Int_t indB=(i-(numPoints-numPointsB)/2);
2339 if(indB<0 || indB>=numPointsB)
2347 Int_t numFreqs=(numPoints/2)+1;
2352 Double_t deltaF=1./(numPoints*deltaT);
2353 for(
int i=0;i<numFreqs;i++) {
2372 Double_t *AB=doInvFFT(numPoints,fftA);
2373 Double_t *newAB =
new Double_t[numPoints];
2374 for(
int i=0;i<numPoints;i++) {
2376 newAB[i]=AB[(numPoints/2)+i];
2380 newAB[i]=AB[i-(numPoints/2)];
2384 TGraph *grConv =
new TGraph(numPoints,T,newAB);
2401 Int_t numPointsA=grA->GetN();
2402 Int_t numPointsB=grB->GetN();
2403 if(numPointsA!=numPointsB) {
2404 std::cout <<
"gr method " << numPointsA <<
" " << numPointsB <<
"\n";
2412 Double_t *tA=grA->GetX();
2413 Double_t deltaT=tA[1]-tA[0];
2415 Int_t numPoints=numPointsA;
2416 Int_t numFreqs=grA->getNumFreqs();
2421 Double_t deltaF=1./(numPoints*deltaT);
2422 for(
int i=0;i<numFreqs;i++) {
2428 Double_t *AB=doInvFFT(numPoints,fftAB);
2429 Double_t *newAB =
new Double_t[numPoints];
2430 for(
int i=0;i<numPoints;i++) {
2432 newAB[i]=AB[(numPoints/2)+i];
2436 newAB[i]=AB[i-(numPoints/2)];
2449 TGraph **grInt =
new TGraph* [numGraphs];
2450 for(
int i=0;i<numGraphs;i++)
2451 grInt[i]=getInterpolatedGraph(grPtrPtr[i],deltaTInt);
2453 for(
int i=0;i<numGraphs;i++)
2467 if(numGraphs<2)
return NULL;
2470 TGraph *grA = (TGraph*) grPtrPtr[0]->Clone();
2473 Int_t numPoints=grA->GetN();
2474 Double_t *timeVals= grA->GetX();
2475 Double_t *safeTimeVals =
new Double_t[numPoints];
2476 Double_t *sumVolts =
new Double_t [numPoints];
2477 for(
int i=0;i<numPoints;i++)
2478 safeTimeVals[i]=timeVals[i];
2483 for(
int graphNum=1;graphNum<numGraphs;graphNum++) {
2484 TGraph *grB = grPtrPtr[graphNum];
2485 if(grB->GetN()<numPoints)
2486 numPoints=grB->GetN();
2492 Int_t offset=peakBin-(grCorAB->GetN()/2);
2495 Double_t *aVolts = grA->GetY();
2496 Double_t *bVolts = grB->GetY();
2498 for(
int ind=0;ind<numPoints;ind++) {
2500 int bIndex=ind-offset;
2502 if(bIndex>=0 && bIndex<numPoints) {
2503 sumVolts[ind]=(aVolts[aIndex]+bVolts[bIndex]);
2506 sumVolts[ind]=aVolts[aIndex];
2511 TGraph *grComAB =
new TGraph(numPoints,safeTimeVals,sumVolts);
2521 for(
int i=0;i<numPoints;i++) {
2522 sumVolts[i]/=countWaves;
2524 Double_t meanVal=TMath::Mean(numPoints,sumVolts);
2525 for(
int i=0;i<numPoints;i++) {
2526 sumVolts[i]-=meanVal;
2529 TGraph *grRet =
new TGraph(numPoints,safeTimeVals,sumVolts);
2530 delete [] safeTimeVals;
2537 if(numGraphs<2)
return NULL;
2539 TGraph *grA = (TGraph*) grPtrPtr[0]->Clone();
2541 Int_t numPoints=grA->GetN();
2542 Double_t *timeVals= grA->GetX();
2543 Double_t *safeTimeVals =
new Double_t[numPoints];
2544 Double_t *sumVolts =
new Double_t [numPoints];
2545 for(
int i=0;i<numPoints;i++)
2546 safeTimeVals[i]=timeVals[i];
2549 for(
int graphNum=1;graphNum<numGraphs;graphNum++) {
2550 TGraph *grB = grPtrPtr[graphNum];
2551 if(grB->GetN()<numPoints)
2552 numPoints=grB->GetN();
2557 Int_t correlationBin = correlationBinPtr[graphNum-1];
2559 Int_t peakBin =
FFTtools::getPeakBin(grCorAB,correlationBin - binWiggleRoom, correlationBin + binWiggleRoom);
2563 Int_t offset=peakBin-(grCorAB->GetN()/2);
2565 Double_t *aVolts = grA->GetY();
2566 Double_t *bVolts = grB->GetY();
2568 for(
int ind=0;ind<numPoints;ind++) {
2570 int bIndex=ind-offset;
2572 if(bIndex>=0 && bIndex<numPoints) {
2573 sumVolts[ind]=(aVolts[aIndex]+bVolts[bIndex]);
2576 sumVolts[ind]=aVolts[aIndex];
2580 TGraph *grComAB =
new TGraph(numPoints,safeTimeVals,sumVolts);
2588 for(
int i=0;i<numPoints;i++) {
2589 sumVolts[i]/=countWaves;
2591 Double_t meanVal=TMath::Mean(numPoints,sumVolts);
2592 for(
int i=0;i<numPoints;i++) {
2593 sumVolts[i]-=meanVal;
2596 TGraph *grRet =
new TGraph(numPoints,safeTimeVals,sumVolts);
2597 delete [] safeTimeVals;
2617 return sin(TMath::Pi()*x) / (TMath::Pi()* x);
2633 rot+= N*(1+(-rot-1)/N);;
2636 std::rotate(g->GetY(), g->GetY() + rot, g->GetY() + N);
2644 int fftlen = length/2 +1;
2645 if (max_i <= 0 || max_i >= fftlen) max_i = fftlen-1;
2646 if (min_i < 0) min_i = 0;
2650 bool work_given = work;
2662 for(
int i=0;i<fftlen;i++)
2664 double reFFT1=A[i].
re;
2665 double imFFT1=A[i].
im;
2666 double reFFT2=B[i].
re;
2667 double imFFT2=B[i].
im;
2675 weight /= (1 + TMath::Power(
double(min_i)/i,2*order));
2678 if (max_i < fftlen - 1)
2680 weight /=( 1 +TMath::Power(
double(i)/max_i,2*order));
2686 rmsA += weight*(reFFT1 * reFFT1 + imFFT1 * imFFT1) * 2 / (length*length);
2687 rmsB += weight*(reFFT2 * reFFT2 + imFFT2 * imFFT2) * 2 / (length*length);
2689 work[i].
re=weight*(reFFT1*reFFT2+imFFT1*imFFT2)/length;
2690 work[i].
im=weight*(imFFT1*reFFT2-reFFT1*imFFT2)/length;
2695 double norm = (rmsA && rmsB) ? 1./(sqrt(rmsA*rmsB)) : 1;
2696 for (
int i = 0; i< length; i++)
2711 #ifndef FFTTOOLS_COMPAT_MODE 2715 win->apply(g->GetN(), g->GetY());
2724 for (
int i = 0; i < N/2; i++)
2737 int n = realN ? realN : g->GetN();
2738 double x0 = g->GetX()[0];
2739 double x1 = g->GetX()[g->GetN()-1];
2740 return (x1-x0)/(n-0.5);
2747 TF1 f(
"polysub",TString::Format(
"pol%d",order));
2749 for (
int i = 0; i < g->GetN(); i++)
2751 g->GetY()[i]-= f.Eval(g->GetX()[i]);
2761 if (!y) y =
new double[N];
2762 double start_val = edge == ZEROES_OUTSIDE ? 0 : x[0];
2763 double end_val = edge == ZEROES_OUTSIDE ? 0 : x[N-1];
2764 for (
int i = 0; i < N; i++)
2767 for (
int j = delay-M/2; j < delay +(M+1)/2; j++)
2774 else if ( i + j >= N)
2783 y[i] += X * h[delay + M/2+j];
2794 double u = rng ? rng->Uniform(0,1) : gRandom->Uniform(0,1);
2795 return sigma * sqrt(-2*log(u));
2799 template<
typename T>
2800 static void unwrap(
size_t N, T * vals, T period)
2803 for (
size_t i = 1; i < N; i++)
2805 if (vals[i] - vals[i-1] + adjust > period/2)
2809 else if (vals[i] - vals[i-1] + adjust < -period/2)
2819 template <
typename T>
2820 static void wrap(
size_t N, T * vals, T period, T center)
2822 T start = center - period/2;
2823 for (
size_t i = 0; i < N; i++)
2826 vals[i] -= nsub * period;
2831 template <
typename T>
2832 static void wrap(
size_t N, T * vals, T period)
2834 wrap<T>(N,vals,period,period/2);
2841 ::wrap<float>(N, vals, period);
2847 ::unwrap<float>(N, vals, period);
2853 ::wrap<double>(N, vals, period);
2859 ::unwrap<double>(N, vals, period);
2866 ::wrap<float>(N, vals, period, center);
2874 ::wrap<double>(N, vals, period, center);
2883 double t0 = g->GetX()[0];
2884 if (t < t0)
return 0;
2885 double dt = g->GetX()[1] - t0;
2887 int bin_low = int ((t-t0)/dt);
2889 if (bin_low >= g->GetN())
return 0;
2890 if (bin_low == g->GetN()-1)
return g->GetY()[g->GetN()-1];
2892 int bin_high = bin_low + 1;
2893 double frac = (t - (t0 + dt * bin_low)) / dt;
2895 double val_low = g->GetY()[bin_low];
2896 double val_high = g->GetY()[bin_high];
2898 return frac * val_high + (1-frac) * val_low;
2905 int FFTtools::saveWisdom(
const char * file)
2911 FILE* filePtr = fopen(file,
"w");
2914 fftw_export_wisdom_to_file(filePtr);
2919 std::cerr <<
"Warning! " << __PRETTY_FUNCTION__ <<
" could not open " << file <<
" in write mode." 2927 int FFTtools::loadWisdom(
const char * file)
2934 FILE* filePtr = fopen(file,
"r");
2937 fftw_import_wisdom_from_file(filePtr);
2942 std::cerr <<
"Warning! " << __PRETTY_FUNCTION__ <<
" could not open " << file <<
" in read mode." 2956 void FFTtools::stokesParameters(
int N,
const double * __restrict x,
const double * __restrict xh,
2957 const double * __restrict y,
const double * __restrict yh,
2958 double * __restrict I,
double * __restrict Q,
double * __restrict U,
double * __restrict V,
2959 double * __restrict Iins,
double * __restrict Qins,
double * __restrict Uins,
double * __restrict Vins,
2970 for (
int i = 0; i <N; i++)
2972 std::complex<double> X(x[i], xh[i]);
2973 std::complex<double>
Y(y[i], yh[i]);
2975 bool is_max =
false;
2977 if (I || Iins || only_max)
2979 double dI = std::norm(X) + std::norm(
Y);
2982 if (only_max && dI > max_dI)
2988 if (Iins && !only_max) Iins[i] = dI;
2989 if (Iins && is_max) *Iins = dI;
2995 double dQ = std::norm(X) - std::norm(
Y);
2997 if (Qins && !only_max) Qins[i] = dQ;
2998 if (Qins && is_max) *Qins = dQ;
3003 double dU = 2 * ( X * std::conj(
Y)).real();
3005 if (Uins && !only_max) Uins[i] = dU;
3006 if (Uins && is_max) *Uins = dU;
3011 double dV =-2* ( X * std::conj(
Y)).imag();
3013 if (Vins && !only_max) Vins[i] = dV;
3014 if (Vins && is_max) *Vins = dV;
3025 #ifdef ENABLE_VECTORIZE 3026 #include "vectorclass.h" 3027 #include "vectormath_trig.h" 3030 #define VEC_T double 3037 if (nmultiples < 1)
return;
3038 if (nmultiples == 1)
return dftAtFreq(g,f,phase,amp,real,imag);
3040 double w = 2 * TMath::Pi() * f;
3042 const double * t = g->GetX();
3043 const double * y = g->GetX();
3047 double sin_f[N], cos_f[N];
3048 double sin_nf[N], cos_nf[N];
3053 #ifdef ENABLE_VECTORIZE 3058 int leftover = N % VEC_N;
3059 int nit = N / VEC_N + (leftover ? 1 : 0);
3063 for (
int i = 0; i < nit; i++)
3065 if (i < nit -1 || !leftover)
3067 vect.load(t+VEC_N*i);
3068 vecy.load(y+VEC_N*i);
3072 vect.load_partial(leftover, t+VEC_N*i);
3073 vecy.load_partial(leftover, y+VEC_N*i);
3077 VEC ang = vect * vw;
3078 VEC vec_sin, vec_cos;
3079 vec_sin = sincos(&vec_cos, ang);
3083 if ( i < nit -1 || !leftover)
3085 vec_sin.store(sin_f + i * VEC_N);
3086 vec_cos.store(cos_f + i * VEC_N);
3091 vec_sin.store_partial(leftover, sin_f + i * VEC_N);
3092 vec_cos.store_partial(leftover, cos_f + i * VEC_N);
3098 vsin += horizontal_add(vec_sin);
3099 vcos += horizontal_add(vec_cos);
3108 for (
int i = 0; i < N; i++)
3111 SINCOS(w* t[i], &s,&c);
3120 if (phase) phase[0] = atan2(vsin,vcos);
3121 if (amp) amp[0] = sqrt(vsin*vsin + vcos*vcos);
3122 if (real) real[0] = vcos;
3123 if (imag) imag[0] = vsin;
3125 memcpy(sin_nf, sin_f,
sizeof(sin_f));
3126 memcpy(cos_nf, cos_f,
sizeof(cos_f));
3130 for (
int j = 1; j < nmultiples; j++)
3135 #ifdef ENABLE_VECTORIZE 3140 for (
int i = 0; i < nit; i++)
3142 if (i < nit -1 || !leftover)
3144 vect.load(t+VEC_N*i);
3145 vecy.load(y+VEC_N*i);
3146 vsin_f.load(sin_f + VEC_N * i);
3147 vcos_f.load(cos_f + VEC_N * i);
3148 vsin_nf.load(sin_nf + VEC_N * i);
3149 vcos_nf.load(cos_nf + VEC_N * i);
3153 vect.load_partial(leftover, t+VEC_N*i);
3154 vecy.load_partial(leftover, y+VEC_N*i);
3155 vsin_f.load_partial(leftover, sin_f + VEC_N * i);
3156 vcos_f.load_partial(leftover, cos_f + VEC_N * i);
3157 vsin_nf.load_partial(leftover, sin_nf + VEC_N * i);
3158 vcos_nf.load_partial(leftover, cos_nf + VEC_N * i);
3161 VEC vec_sin = vcos_f * vcos_nf - vsin_f * vsin_nf;
3162 VEC vec_cos = vcos_f * vsin_nf + vsin_f * vcos_nf;
3164 if ( i < nit -1 || !leftover)
3166 vec_sin.store(sin_nf + i * VEC_N);
3167 vec_cos.store(cos_nf + i * VEC_N);
3172 vec_sin.store_partial(leftover, sin_nf + i * VEC_N);
3173 vec_cos.store_partial(leftover, cos_nf + i * VEC_N);
3179 vsin += horizontal_add(vec_sin);
3180 vcos += horizontal_add(vec_cos);
3184 for (
int i = 0; i < N; i++)
3186 double tempcos = cos_f[i] * cos_nf[i] - sin_f[i] * sin_nf[i];
3187 double tempsin = cos_f[i] * sin_nf[i] + sin_f[i] *cos_nf[i];
3188 cos_nf[i] = tempcos;
3189 sin_nf[i] = tempsin;
3191 vcos += tempcos * y[i];
3192 vsin += tempsin * y[i];
3196 if (phase) phase[j] = atan2(vsin,vcos);
3197 if (amp) amp[j] = sqrt(vsin*vsin + vcos*vcos);
3198 if (real) real[j] = vcos;
3199 if (imag) imag[j] = vsin;
3206 void FFTtools::dftAtFreq(
const TGraph * g,
double f,
double * phase ,
double * amp,
double * real,
double * imag)
3209 double w = 2 * TMath::Pi() * f;
3213 const double * t = g->GetX();
3214 const double * y = g->GetY();
3217 #ifdef ENABLE_VECTORIZE 3223 int leftover = N % VEC_N;
3224 int nit = N/VEC_N + (leftover ? 1 : 0);
3226 for (
int i = 0; i < nit; i++)
3228 if (i < nit -1 || !leftover)
3230 vect.load(t+VEC_N*i);
3231 vecy.load(y+VEC_N*i);
3235 vect.load_partial(leftover, t+VEC_N*i);
3236 vecy.load_partial(leftover, y+VEC_N*i);
3239 VEC ang = vect * vw;
3240 VEC vec_sin, vec_cos;
3241 vec_sin = sincos(&vec_cos, ang);
3245 vsin += horizontal_add(vec_sin);
3246 vcos += horizontal_add(vec_cos);
3249 for (
int i = 0; i < N; i++)
3252 SINCOS(w*t[i], &s,&c);
3265 *phase=atan2(vsin,vcos);
3268 *amp = sqrt(vsin*vsin + vcos*vcos);
3280 double minval = TMath::Power(10,mindb/20);
3281 double min = log(minval);
3284 double * logmag =
new double[N];
3287 for (
int i = 0; i < N; i++)
3289 logmag[i]= G[i] < minval ? min : log(G[i]);
3294 for (
int i = 0; i < N; i++)
3296 double mag = G[i] < minval ? minval : G[i];
3298 if ( i == 0 || i == N-1)
3306 output[i].
re = mag * cos(phase[i]);
3307 output[i].
im = mag * sin(phase[i]);
3320 FFTWComplex * G = doFFT(gin->GetN(), gin->GetY());
3321 int nfft = gin->GetN()/2+1;
3322 double * mag =
new double[nfft];
3323 for (
int i = 0; i < nfft; i++) mag[i] = G[i].
getAbs();
3325 TGraph * out =
new TGraph(*gin);
3327 str.Form(
"minphase_%s",gin->GetName());
3328 out->SetName(str.Data());
3329 str.Form(
"Minimum Phase %s",gin->GetTitle());
3330 out->SetTitle(str.Data());
3331 double * y = doInvFFT(out->GetN(),
Y);
3332 for (
int i = 0; i < out->GetN(); i++) out->GetY()[i] = y[i];
3344 TGraph * out =
new TGraph(*gin);
3347 str.Form(
"fixeddelay%s",gin->GetName());
3348 out->SetName(str.Data());
3349 str.Form(
"Fixed Delay (%g) %s",delay, gin->GetTitle());
3350 out->SetTitle(str.Data());
3352 double dt = gin->GetX()[1] - gin->GetX()[0];
3353 double dw = TMath::Pi()*2/(gin->GetN() * dt);
3354 FFTWComplex * G = doFFT(gin->GetN(), gin->GetY());
3355 for (
int i = 0; i < gin->GetN()/2; i++)
3357 double mag = G[i].getAbs();
3358 double ph = -delay * i*dw;
3361 double * y = doInvFFT(out->GetN(), G);
3362 for (
int i = 0; i < out->GetN(); i++) out->GetY()[i] = y[i];
3374 double * real =
new double[N];
3375 double * imag =
new double[N];
3377 for (
int i = 0; i < N; i++)
3379 real[i] = signal[i].
re;
3380 imag[i] = signal[i].
im;
3386 for (
int i = 0; i < N; i++)
3388 double diff=hilbert[i]-imag[i];
3397 return sqrt(sum2/N);
3403 const double * __restrict__ x,
3404 const double * __restrict__ y,
3405 double * __restrict__ out)
3407 if (!out) out =
new double[N];
3412 for (
int i = 0; i < N; i++)
3417 while(x[min_i] < x[i] - W)
3419 sumV2 -= y[min_i]*y[min_i];
3424 out[i] = sqrt(2*sumV2/navg);
3431 const double * __restrict__ x,
3432 const double * __restrict__ y,
3433 double * __restrict__ out)
3435 if (!out) out =
new double[N];
3438 memset(out,0, N *
sizeof(
double));
3443 for (
int i = 0; i < N; )
3447 if (! ((i == 0 || fabs(y[i]) > fabs(y[i-1])) && (i == N-1 || fabs(y[i]) > fabs(y[i+i]))) )
3459 while (ii < N && x[ii] < x[i] + min)
3461 if (fabs(y[ii]) > fabs(y[i]))
3474 out[i] = fabs(y[i]);
3477 if (first_out < 0) first_out = i;
3478 if (i > last_out) last_out = i;
3485 for (
int i =0; i < first_out; i++ )
3486 out[i] = out[first_out];
3488 double x0 = x[first_out];
3489 double y0 = out[first_out];
3496 while(!out[++next_out]);
3498 double x1 = x[next_out];
3499 double y1 = out[next_out];
3503 double m = (y1-y0)/(x1-x0);
3504 for ( ; i < next_out; i++)
3506 out[i] = y0 + (x[i] - x0) * m;
3515 for (
int i =last_out+1; i < N; i++ )
3516 out[i] = out[last_out];
struct __attribute__((packed))
Debugging use only TURF scaler data.
double im
The imaginary part.
This is a wrapper class for an RF Signal.
This is a wrapper class for a complex number.
Inelasticity distributions: stores parametrizations and picks inelasticities.