void caffe_cpu_fft<float>(const int howmany, const int n, const float* x, complex<float>* y) { /* FFTW plan handle */ fftwf_plan hplan = 0; const float *in = x; fftwf_complex *out = reinterpret_cast<fftwf_complex *>(y); int Ni[] = {n}; int No[] = {n/2+1}; hplan = fftwf_plan_many_dft_r2c(1, Ni, howmany, const_cast<float *>(in), Ni, 1, n, out, No, 1, n/2+1, FFTW_ESTIMATE); if (0 == hplan) goto failed; fftwf_execute(hplan); fftwf_destroy_plan(hplan); failed: return; }
OptFFT::OptFFT(const size_t maxDataSize) { assert( maxDataSize % OVERLAPSAMPLES == 0 ); // DOUBLE //m_pIn = static_cast<double*>( fftw_malloc(sizeof(double) * FRAMESIZE) ); //m_pOut = static_cast<fftw_complex*>( fftw_malloc(sizeof(fftw_complex) * (FRAMESIZE/2 + 1)) ); //m_p = fftw_plan_dft_r2c_1f(FRAMESIZE, m_pIn, m_pOut, FFTW_ESTIMATE); // FFTW_ESTIMATE or FFTW_MEASURE // FLOAT // m_pIn = static_cast<float*>( fftwf_malloc(sizeof(float) * FRAMESIZE) ); // m_pOut = static_cast<fftwf_complex*>( fftwf_malloc(sizeof(fftwf_complex) * (FRAMESIZE/2 + 1)) ); //// in destroyed when line executed //m_p = fftwf_plan_dft_r2c_1d(FRAMESIZE, m_pIn, m_pOut, FFTW_ESTIMATE); // FFTW_ESTIMATE or FFTW_MEASURE //----------------------------------------------------------------- int numSamplesPerFrame = FRAMESIZE; int numSamplesPerFrameOut = FRAMESIZE/2+1; m_maxFrames = static_cast<int> ( (maxDataSize - FRAMESIZE) / OVERLAPSAMPLES + 1 ); m_pIn = static_cast<float*> ( fftwf_malloc(sizeof(float) * (numSamplesPerFrame * m_maxFrames) ) ); if ( !m_pIn ) { ostringstream oss; oss << "fftwf_malloc failed on m_pIn. Trying to allocate <" << sizeof(float) * (numSamplesPerFrame * m_maxFrames) << "> bytes"; throw std::runtime_error(oss.str()); } m_pOut = static_cast<fftwf_complex*>( fftwf_malloc(sizeof(fftwf_complex) * (numSamplesPerFrameOut* m_maxFrames) ) ); if ( !m_pOut ) { ostringstream oss; oss << "fftwf_malloc failed on m_pOut. Trying to allocate <" << sizeof(fftwf_complex) * (numSamplesPerFrameOut* m_maxFrames) << "> bytes"; throw std::runtime_error(oss.str()); } // in destroyed when line executed m_p = fftwf_plan_many_dft_r2c(1, &numSamplesPerFrame, m_maxFrames, m_pIn, &numSamplesPerFrame, 1, numSamplesPerFrame, m_pOut, &numSamplesPerFrameOut, 1, numSamplesPerFrameOut, FFTW_ESTIMATE | FFTW_DESTROY_INPUT); if ( !m_p ) throw std::runtime_error ("fftwf_plan_many_dft_r2c failed"); double base = exp( log( static_cast<double>(MAXFREQ) / static_cast<double>(MINFREQ) ) / static_cast<double>(Filter::NBANDS) ); m_powTable.resize( Filter::NBANDS+1 ); for ( unsigned int i = 0; i < Filter::NBANDS + 1; ++i ) m_powTable[i] = static_cast<unsigned int>( (pow(base, static_cast<double>(i)) - 1.0) * MINCOEF ); m_pFrames = new float*[m_maxFrames]; if ( !m_pFrames ) { ostringstream oss; oss << "Allocation failed on m_pFrames. Trying to allocate <" << sizeof(float*) * m_maxFrames << "> bytes"; throw std::runtime_error(oss.str()); } for (int i = 0; i < m_maxFrames; ++i) { m_pFrames[i] = new float[Filter::NBANDS]; if ( !m_pFrames[i] ) throw std::runtime_error("Allocation failed on m_pFrames"); } }
int main(int argc, char* argv[]) { bool verb, pow2; char key[7], *mode;; int n1, n2, n1padded, n2padded, num, dim, n[SF_MAX_DIM], npadded[SF_MAX_DIM], ii[SF_MAX_DIM]; int i, j, i1, i2, index, nw, iter, niter, nthr, *pad; float thr, pclip, normp; float *dobs_t, *thresh, *mask; fftwf_complex *mm, *dd, *dobs; fftwf_plan fft1, ifft1, fftrem, ifftrem;/* execute plan for FFT and IFFT */ sf_file in, out, Fmask; /* mask and I/O files*/ sf_init(argc,argv); /* Madagascar initialization */ in=sf_input("in"); /* read the data to be interpolated */ out=sf_output("out"); /* output the reconstructed data */ Fmask=sf_input("mask"); /* read the (n-1)-D mask for n-D data */ if(!sf_getbool("verb",&verb)) verb=false; /* verbosity */ if(!sf_getbool("pow2",&pow2)) pow2=false; /* round up the length of each axis to be power of 2 */ if (!sf_getint("niter",&niter)) niter=100; /* total number of iterations */ if (!sf_getfloat("pclip",&pclip)) pclip=10.; /* starting data clip percentile (default is 10)*/ if ( !(mode=sf_getstring("mode")) ) mode = "exp"; /* thresholding mode: 'hard', 'soft','pthresh','exp'; 'hard', hard thresholding; 'soft', soft thresholding; 'pthresh', generalized quasi-p; 'exp', exponential shrinkage */ if (pclip <=0. || pclip > 100.) sf_error("pclip=%g should be > 0 and <= 100",pclip); if (!sf_getfloat("normp",&normp)) normp=1.; /* quasi-norm: normp<2 */ for (i=0; i < SF_MAX_DIM; i++) {/* dimensions */ snprintf(key,3,"n%d",i+1); if (!sf_getint(key,n+i) && (NULL == in || !sf_histint(in,key,n+i))) break; /*( n# size of #-th axis )*/ sf_putint(out,key,n[i]); } if (0==i) sf_error("Need n1="); dim=i; pad=sf_intalloc (dim); for (i=0; i<dim; i++) pad[i]=0; sf_getints("pad",pad,dim); /* number of zeros to be padded for each axis */ n1=n[0]; n2=sf_leftsize(in,1); for (i=0; i<SF_MAX_DIM; i++) npadded[i]=1; npadded[0]=n1+pad[0]; n1padded=npadded[0]; n2padded=1; for (i=1; i<dim; i++){ npadded[i]=n[i]+pad[i]; if (pow2) {/* zero-padding to be power of 2 */ npadded[i]=nextpower2(n[i]); fprintf(stderr,"n%d=%d n%dpadded=%d\n",i,n[i],i,npadded[i]); } n2padded*=npadded[i]; } nw=npadded[0]/2+1; num=nw*n2padded;/* data: total number of elements in frequency domain */ /* allocate data and mask arrays */ thresh=(float*) malloc(nw*n2padded*sizeof(float)); dobs_t=(float*) fftwf_malloc(n1padded*n2padded*sizeof(float)); /* time domain observation */ dobs=(fftwf_complex*)fftwf_malloc(nw*n2padded*sizeof(fftwf_complex));/* freq-domain observation */ dd=(fftwf_complex*) fftwf_malloc(nw*n2padded*sizeof(fftwf_complex)); mm=(fftwf_complex*) fftwf_malloc(nw*n2padded*sizeof(fftwf_complex)); if (NULL != sf_getstring("mask")){ mask=sf_floatalloc(n2padded); } else sf_error("mask needed!"); /* initialize the input data and mask arrays */ memset(dobs_t,0,n1padded*n2padded*sizeof(float)); memset(mask,0,n2padded*sizeof(float)); for (i=0; i<n1*n2; i+=n1){ sf_line2cart(dim,n,i,ii); j=sf_cart2line(dim,npadded,ii); sf_floatread(&dobs_t[j], n1, in); sf_floatread(&mask[j/n1padded], 1, Fmask); } /* FFT for the 1st dimension and the remaining dimensions */ fft1=fftwf_plan_many_dft_r2c(1, &n1padded, n2padded, dobs_t, &n1padded, 1, n1padded, dobs, &n1padded, 1, nw, FFTW_MEASURE); ifft1=fftwf_plan_many_dft_c2r(1, &n1padded, n2padded, dobs, &n1padded, 1, nw, dobs_t, &n1padded, 1, n1padded, FFTW_MEASURE); fftrem=fftwf_plan_many_dft(dim-1, &npadded[1], nw, dd, &npadded[1], nw, 1, dd, &npadded[1], nw, 1, FFTW_FORWARD, FFTW_MEASURE); ifftrem=fftwf_plan_many_dft(dim-1, &npadded[1], nw, dd, &npadded[1], nw, 1, dd, &npadded[1], nw, 1, FFTW_BACKWARD, FFTW_MEASURE); /* transform the data from time domain to frequency domain: dobs_t-->dobs */ fftwf_execute(fft1); for(i=0; i<num; i++) dobs[i]/=sqrtf(n1padded); memset(mm,0,num*sizeof(fftwf_complex)); /* Iterative Shrinkage-Thresholding (IST) Algorithm: mm^{k+1}=T[mm^k+A^* M^* (dobs-M A mm^k)] (M^*=M; Mdobs=dobs) =T[mm^k+A^*(dobs-M A mm^k)]; (k=0,1,...niter-1) dd^=A mm^; */ for(iter=0; iter<niter; iter++) { /* dd<-- A mm^k */ memcpy(dd, mm, num*sizeof(fftwf_complex)); fftwf_execute(ifftrem); for(i=0; i<num; i++) dd[i]/=sqrtf(n2padded); /* apply mask: dd<--dobs-M A mm^k=dobs-M dd */ for(i2=0; i2<n2padded; i2++) for(i1=0; i1<nw; i1++) { index=i1+nw*i2; dd[index]=dobs[index]-mask[i2]*dd[index]; } /* mm^k += A^*(dobs-M A mm^k); dd=dobs-M A mm^k */ fftwf_execute(fftrem); for(i=0; i<num; i++) mm[i]+=dd[i]/sqrtf(n2padded); /* perform thresholding */ for(i=0; i<num; i++) thresh[i]=cabsf(mm[i]); nthr = 0.5+num*(1.-0.01*pclip); /* round off */ if (nthr < 0) nthr=0; if (nthr >= num) nthr=num-1; thr=sf_quantile(nthr, num, thresh); sf_cpthresh(mm, num, thr, normp, mode); if (verb) sf_warning("iteration %d;",iter+1); } /* frequency--> time domain: dobs-->dobs_t */ memcpy(dd, mm, num*sizeof(fftwf_complex)); fftwf_execute(ifftrem); for(i=0; i<num; i++) dd[i]/=sqrtf(n2padded); memcpy(dobs, dd, num*sizeof(fftwf_complex)); fftwf_execute(ifft1); for(i=0; i<n1padded*n2padded; i++) dobs_t[i]/=sqrtf(n1padded); for (i=0; i<n1*n2; i+=n1){ sf_line2cart(dim,n,i,ii); j=sf_cart2line(dim,npadded,ii); sf_floatwrite(&dobs_t[j],n1,out); } free(thresh); fftwf_free(dobs_t); fftwf_free(dobs); fftwf_free(dd); fftwf_free(mm); exit(0); }
int main(int argc, char** argv){ float tr[6]; const float ZAP=32; const uint64_t TSIZE=18; const uint64_t zapE=64; fftwf_init_threads(); fftwf_plan_with_nthreads(omp_get_max_threads()); logmsg("Open file '%s'",argv[1]); FILE* f = fopen(argv[1],"r"); int hdr_bytes = read_header(f); const uint64_t nskip = hdr_bytes; const uint64_t nchan = nchans; logmsg("Nchan=%"PRIu64", tsamp=%f",nchan,tsamp); mjk_rand_t *random = mjk_rand_init(12345); rewind(f); FILE* of = fopen("clean.fil","w"); uint8_t hdr[nskip]; fread(hdr,1,nskip,f); fwrite(hdr,1,nskip,of); const uint64_t nsamp_per_block=round(pow(2,TSIZE)); logmsg("Tblock = %f",nsamp_per_block*tsamp); mjk_clock_t *t_all = init_clock(); start_clock(t_all); mjk_clock_t *t_read = init_clock(); mjk_clock_t *t_trns= init_clock(); mjk_clock_t *t_rms = init_clock(); mjk_clock_t *t_fft = init_clock(); mjk_clock_t *t_spec = init_clock(); const uint64_t bytes_per_block = nchan*nsamp_per_block; uint8_t *buffer = calloc(bytes_per_block,1); float **data = malloc_2df(nchan,nsamp_per_block); float **clean = malloc_2df(nchan,nsamp_per_block); float *bpass = calloc(nchan,sizeof(float)); float *ch_var=NULL; float *ch_mean=NULL; float *ch_fft_n=NULL; float *ch_fft_p=NULL; logmsg("Planning FFT - this will take a long time the first time it is run!"); start_clock(t_fft); FILE * wisfile; if(wisfile=fopen("wisdom.txt","r")){ fftwf_import_wisdom_from_file(wisfile); fclose(wisfile); } const int fftX=nsamp_per_block; const int fftY=nchan; const int fftXo=nsamp_per_block/2+1; float *X = fftwf_malloc(sizeof(float)*fftX); for (uint64_t i = 0; i < nsamp_per_block ; i++){ X[i]=i; } float *tseries = fftwf_malloc(sizeof(float)*fftX); float complex *fseries = fftwf_malloc(sizeof(float complex)*fftXo); float *pseries = fftwf_malloc(sizeof(float)*fftXo); uint8_t *mask = malloc(sizeof(uint8_t)*fftXo); fftwf_plan fft_1d = fftwf_plan_dft_r2c_1d(fftX,tseries,fseries,FFTW_MEASURE|FFTW_DESTROY_INPUT); complex float * fftd = fftwf_malloc(sizeof(complex float)*(fftXo*fftY)); fftwf_plan fft_plan = fftwf_plan_many_dft_r2c( 1,&fftX,fftY, data[0] ,&fftX,1,fftX, fftd ,&fftXo,1,fftXo, FFTW_MEASURE|FFTW_PRESERVE_INPUT); logmsg("Planning iFFT - this will take a long time the first time it is run!"); fftwf_plan ifft_plan = fftwf_plan_many_dft_c2r( 1,&fftX,fftY, fftd ,&fftXo,1,fftXo, clean[0] ,&fftX,1,fftX, FFTW_MEASURE|FFTW_PRESERVE_INPUT); if(!fft_plan){ logmsg("Error - could not do FFT plan"); exit(2); } wisfile=fopen("wisdom.txt","w"); fftwf_export_wisdom_to_file(wisfile); fclose(wisfile); stop_clock(t_fft); logmsg("T(planFFT)= %.2lfs",read_clock(t_fft)); reset_clock(t_fft); float min_var=1e9; float max_var=0; float min_fft_n=1e9; float max_fft_n=0; float min_fft_p=1e9; float max_fft_p=0; float min_mean=1e9; float max_mean=0; uint64_t nblocks=0; uint64_t totread=0; while(!feof(f)){ nblocks++; ch_var = realloc(ch_var,nchan*nblocks*sizeof(float)); ch_mean = realloc(ch_mean,nchan*nblocks*sizeof(float)); ch_fft_n = realloc(ch_fft_n,nchan*nblocks*sizeof(float)); ch_fft_p = realloc(ch_fft_p,nchan*nblocks*sizeof(float)); start_clock(t_read); uint64_t read = fread(buffer,1,bytes_per_block,f); stop_clock(t_read); if (read!=bytes_per_block){ nblocks--; break; } totread+=read; logmsg("read=%"PRIu64" bytes. T=%fs",read,totread*tsamp/(float)nchan); uint64_t offset = (nblocks-1)*nchan; start_clock(t_trns); // transpose with small blocks in order to increase cache efficiency. #define BLK 8 #pragma omp parallel for schedule(static,2) shared(buffer,data) for (uint64_t j = 0; j < nchan ; j+=BLK){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ for (uint64_t k = 0; k < BLK ; k++){ data[j+k][i] = buffer[i*nchan+j+k]; } } } #pragma omp parallel for shared(data) for (uint64_t j = 0; j < nchan ; j++){ if(j<zapE || (nchan-j) < zapE){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ data[j][i]=ZAP; } } } if(nblocks==1){ #pragma omp parallel for shared(data,bpass) for (uint64_t j = 0; j < nchan ; j++){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ bpass[j]+=data[j][i]; } bpass[j]/=(float)nsamp_per_block; bpass[j]-=ZAP; } } #pragma omp parallel for shared(data,bpass) for (uint64_t j = 0; j < nchan ; j++){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ data[j][i]-=bpass[j]; } } stop_clock(t_trns); start_clock(t_rms); #pragma omp parallel for shared(data,ch_mean,ch_var) for (uint64_t j = 0; j < nchan ; j++){ float mean=0; for (uint64_t i = 0; i < nsamp_per_block ; i++){ mean+=data[j][i]; } mean/=(float)nsamp_per_block; if(mean > ZAP+5 || mean < ZAP-5){ logmsg("ZAP ch=%"PRIu64,j); for (uint64_t i = 0; i < nsamp_per_block ; i++){ data[j][i]=ZAP; } } float ss=0; float x=0; for (uint64_t i = 0; i < nsamp_per_block ; i++){ x = data[j][i]-mean; ss+=x*x; } float var=ss/(float)nsamp_per_block; if (var > 0){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ float v = (data[j][i]-mean)/sqrt(var); if(v > 3 || v < -3){ data[j][i]=mjk_rand_gauss(random)*sqrt(var)+mean; } } } ch_var[offset+j] = var; ch_mean[offset+j] = mean; } stop_clock(t_rms); for (uint64_t i = 0; i < nsamp_per_block ; i++){ tseries[i]=0; } float tmean=0; float tvar=0; float max=0; float min=1e99; //#pragma omp parallel for shared(data,tseries) // NOT THREAD SAFE for (uint64_t j = 0; j < nchan ; j++){ tmean+=ch_mean[offset+j]; tvar+=ch_var[offset+j]; for (uint64_t i = 0; i < nsamp_per_block ; i++){ tseries[i]+=data[j][i]; if(data[j][i]>max)max=data[j][i]; if(data[j][i]<min)min=data[j][i]; } } float ss=0; float mm=0; for (uint64_t i = 0; i < nsamp_per_block ; i++){ float x=tseries[i]-tmean; mm+=tseries[i]; ss+=x*x; } float rvar=ss/(float)nsamp_per_block; logmsg("var=%g tvar=%g",ss/(float)nsamp_per_block,tvar); logmsg("mean=%g tmean=%g",mm/(float)nsamp_per_block,tmean); cpgopen("3/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,fftX,tmean-sqrt(tvar)*30,tmean+sqrt(tvar)*30); cpgbox("ABN",0,0,"ABN",0,0); cpgline(fftX,X,tseries); cpgsci(2); cpgclos(); tr[0] = 0.0 ; tr[1] = 1; tr[2] = 0; tr[3] = 0.5; tr[4] = 0; tr[5] = 1; logmsg("max=%g min=%g",max,min); cpgopen("4/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nsamp_per_block,0,nchan); cpgbox("ABN",0,0,"ABN",0,0); cpggray(*data,nsamp_per_block,nchan,1,nsamp_per_block,1,nchan,tmean/(float)nchan+sqrt(rvar/(float)nchan),tmean/(float)nchan-sqrt(rvar/(float)nchan),tr); cpgclos(); start_clock(t_fft); fftwf_execute(fft_1d); fftwf_execute(fft_plan); stop_clock(t_fft); { float T = sqrt(fftXo*tvar)*12; logmsg("Zap T=%.2e",T); float fx[fftXo]; float fT[fftXo]; #pragma omp parallel for shared(fseries,pseries,mask) for (uint64_t i = 0; i < fftXo ; i++){ mask[i]=1; } #pragma omp parallel for shared(fseries,pseries,mask) for (uint64_t i = 0; i < fftXo ; i++){ pseries[i]=camp(fseries[i]); fx[i]=i; float TT = T; if (i>512)TT=T/2.0; if(i>32){ fT[i]=TT; if (pseries[i] > TT) { mask[i]=0; } } else fT[i]=0; } uint64_t nmask=0; for (uint64_t i = 0; i < fftXo ; i++){ if (mask[i]==0){ nmask++; } } logmsg("masked=%d (%.2f%%)",nmask,100*nmask/(float)fftXo); cpgopen("1/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,fftXo,0,T*10); cpgbox("ABN",0,0,"ABN",0,0); cpgline(fftXo,fx,pseries); cpgsci(2); cpgline(fftXo,fx,fT); cpgclos(); } // exit(1); start_clock(t_spec); //FILE* ff=fopen("plot","w"); #pragma omp parallel for shared(fftd,ch_mean,ch_fft_n,ch_fft_p) for (uint64_t j = 0; j < nchan ; j++){ float var = ch_var[offset+j]; float m=sqrt(var*fftXo/2.0); float T = sqrt(var*fftXo)*3; uint64_t n=0; float p=0; float complex *fftch = fftd + fftXo*j; for(uint64_t i = 1; i < fftXo; i++){ if (camp(fftch[i]) > T) { n++; p+=camp(fftch[i]); } // if(j==512)fprintf(ff,"%f ",camp(fftch[i])); if(mask[i]==0){ fftch[i]=m*(mjk_rand_gauss(random) + I*mjk_rand_gauss(random)); } // if(j==512)fprintf(ff,"%f\n",camp(fftch[i])); } ch_fft_n[offset+j]=n; ch_fft_p[offset+j]=p; } // fclose(ff); logmsg("iFFT"); fftwf_execute(ifft_plan); #pragma omp parallel for schedule(static,2) shared(buffer,clean) for (uint64_t j = 0; j < nchan ; j+=BLK){ for (uint64_t i = 0; i < nsamp_per_block ; i++){ for (uint64_t k = 0; k < BLK ; k++){ clean[j+k][i]/=(float)fftX; buffer[i*nchan+j+k] = round(clean[j+k][i]); } } if(j==512){ cpgopen("2/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,fftX,ch_mean[j]-sqrt(ch_var[j])*10,ch_mean[j]+sqrt(ch_var[j])*10); cpgbox("ABN",0,0,"ABN",0,0); cpgline(fftX,X,data[j]); cpgsci(2); cpgline(fftX,X,clean[j]); cpgclos(); } } fwrite(buffer,1,bytes_per_block,of); for (uint64_t i = 0; i < nsamp_per_block ; i++){ tseries[i]=0; } tmean=0; tvar=0; max=0; min=1e99; //#pragma omp parallel for shared(clean,tseries) // NOT THREAD SAFE for (uint64_t j = 0; j < nchan ; j++){ tmean+=ch_mean[offset+j]; tvar+=ch_var[offset+j]; for (uint64_t i = 0; i < nsamp_per_block ; i++){ tseries[i]+=clean[j][i]; if(clean[j][i]>max)max=clean[j][i]; if(clean[j][i]<min)min=clean[j][i]; } } ss=0; mm=0; for (uint64_t i = 0; i < nsamp_per_block ; i++){ float x=tseries[i]-tmean; mm+=tseries[i]; ss+=x*x; } rvar=ss/(float)nsamp_per_block; logmsg("var=%g tvar=%g",ss/(float)nsamp_per_block,tvar); logmsg("mean=%g tmean=%g",mm/(float)nsamp_per_block,tmean); cpgopen("5/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,fftX,tmean-sqrt(tvar)*30,tmean+sqrt(tvar)*30); cpgbox("ABN",0,0,"ABN",0,0); cpgline(fftX,X,tseries); cpgsci(2); cpgclos(); tr[0] = 0.0 ; tr[1] = 1; tr[2] = 0; tr[3] = 0.5; tr[4] = 0; tr[5] = 1; logmsg("max=%g min=%g",max,min); cpgopen("6/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nsamp_per_block,0,nchan); cpgbox("ABN",0,0,"ABN",0,0); cpggray(*clean,nsamp_per_block,nchan,1,nsamp_per_block,1,nchan,tmean/(float)nchan+sqrt(rvar/(float)nchan),tmean/(float)nchan-sqrt(rvar/(float)nchan),tr); cpgclos(); stop_clock(t_spec); for (uint64_t j = 0; j < nchan ; j++){ float mean=ch_mean[offset+j]; if (mean > max_mean)max_mean=mean; if (mean < min_mean)min_mean=mean; float var=ch_var[offset+j]; if (var > max_var)max_var=var; if (var < min_var)min_var=var; float fft_n=ch_fft_n[offset+j]; if (fft_n > max_fft_n)max_fft_n=fft_n; if (fft_n < min_fft_n)min_fft_n=fft_n; float fft_p=ch_fft_p[offset+j]; if (fft_p > max_fft_p)max_fft_p=fft_p; if (fft_p < min_fft_p)min_fft_p=fft_p; } } stop_clock(t_all); fclose(of); logmsg("T(all) = %.2lfs",read_clock(t_all)); logmsg("T(read) = %.2lfs",read_clock(t_read)); logmsg("T(trans)= %.2lfs",read_clock(t_trns)); logmsg("T(fft) = %.2lfs",read_clock(t_fft)); logmsg("T(fan) = %.2lfs",read_clock(t_spec)); logmsg("T(rms) = %.2lfs",read_clock(t_rms)); logmsg("T(rest) = %.2lfs",read_clock(t_all)-read_clock(t_read)-read_clock(t_trns)-read_clock(t_rms)-read_clock(t_fft)-read_clock(t_spec)); tr[0] = -tsamp*nsamp_per_block*0.5; tr[2] = tsamp*nsamp_per_block; tr[1] = 0; tr[3] = 0.5; tr[5] = 0; tr[4] = 1; cpgopen("1/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_mean,nchan,nblocks,1,nchan,1,nblocks,max_mean,min_mean,tr); cpgclos(); cpgopen("2/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_var,nchan,nblocks,1,nchan,1,nblocks,max_var,min_var,tr); cpgclos(); cpgopen("3/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_fft_n,nchan,nblocks,1,nchan,1,nblocks,max_fft_n,min_fft_n,tr); cpgclos(); cpgopen("4/xs"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_fft_p,nchan,nblocks,1,nchan,1,nblocks,max_fft_p,min_fft_p,tr); cpgclos(); cpgopen("mean.ps/vcps"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_mean,nchan,nblocks,1,nchan,1,nblocks,max_mean,min_mean,tr); cpgclos(); cpgopen("var.ps/vcps"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_var,nchan,nblocks,1,nchan,1,nblocks,max_var,min_var,tr); cpgclos(); cpgopen("fft_n.ps/vcps"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_fft_n,nchan,nblocks,1,nchan,1,nblocks,max_fft_n,min_fft_n,tr); cpgclos(); cpgopen("fft_p.ps/vcps"); cpgsvp(0.1,0.9,0.1,0.9); cpgswin(0,nblocks*tsamp*nsamp_per_block,0,nchan); cpgbox("ABN",600,10,"ABN",100,1); cpggray(ch_fft_p,nchan,nblocks,1,nchan,1,nblocks,max_fft_p,min_fft_p,tr); cpgclos(); fclose(f); free(buffer); free_2df(data); return 0; }
/* Set up fft plans. Need to have npol, nphase, nchan * already filled in struct */ int cyclic_init_ffts(struct cyclic_work *w) { /* Infer lag, harmonic sizes from chan/phase */ w->nlag = w->nchan; // Total number of lags including + and - w->nharm = w->nphase/2 + 1; // Only DC and positive harmonics /* Alloc temp arrays for planning */ PS ps; CS cs; CC cc; PC pc; struct filter_time ft; struct filter_freq ff; struct profile_phase pp; struct profile_harm ph; ps.npol = cs.npol = cc.npol = pc.npol = w->npol; ps.nphase = pc.nphase = w->nphase; ps.nchan = cs.nchan = w->nchan; cs.nharm = cc.nharm = w->nharm; cc.nlag = pc.nlag = w->nlag; cyclic_alloc_ps(&ps); cyclic_alloc_cs(&cs); cyclic_alloc_cc(&cc); cyclic_alloc_pc(&pc); ft.nlag = w->nlag; ff.nchan = w->nchan; pp.nphase = w->nphase; ph.nharm = w->nharm; filter_alloc_time(&ft); filter_alloc_freq(&ff); profile_alloc_phase(&pp); profile_alloc_harm(&ph); /* FFT plans */ int rv=0; /* ps2cs - r2c fft along phase (fastest) axis */ w->ps2cs = fftwf_plan_many_dft_r2c(1, &w->nphase, w->npol*w->nchan, ps.data, NULL, 1, w->nphase, cs.data, NULL, 1, w->nharm, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->ps2cs == NULL) rv++; /* cs2cc - c2c ifft along channel axis */ w->cs2cc = fftwf_plan_many_dft(1, &w->nchan, w->npol*w->nharm, cs.data, NULL, w->nharm*w->npol, 1, cc.data, NULL, w->nharm*w->npol, 1, FFTW_BACKWARD, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->cs2cc == NULL) rv++; /* cc2cs - c2c fft along lag axis */ w->cc2cs = fftwf_plan_many_dft(1, &w->nlag, w->npol*w->nharm, cc.data, NULL, w->nharm*w->npol, 1, cs.data, NULL, w->nharm*w->npol, 1, FFTW_FORWARD, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->cc2cs == NULL) rv++; /* time2freq, freq2time for filters */ w->time2freq = fftwf_plan_dft_1d(w->nlag, ft.data, ff.data, FFTW_FORWARD, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->time2freq == NULL) rv++; w->freq2time = fftwf_plan_dft_1d(w->nchan, ff.data, ft.data, FFTW_BACKWARD, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->freq2time == NULL) rv++; /* phase2harm, harm2phase for profiles */ w->phase2harm = fftwf_plan_dft_r2c_1d(w->nphase, pp.data, ph.data, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->phase2harm == NULL) rv++; w->harm2phase = fftwf_plan_dft_c2r_1d(w->nphase, ph.data, pp.data, FFTW_MEASURE | FFTW_PRESERVE_INPUT); if (w->harm2phase == NULL) rv++; cyclic_free_ps(&ps); cyclic_free_cs(&cs); cyclic_free_cc(&cc); cyclic_free_pc(&pc); filter_free_time(&ft); filter_free_freq(&ff); profile_free_phase(&pp); profile_free_harm(&ph); return(rv); }
int main(int argc,char *argv[]) { //this is C, so I have to declare all sorts of variables in advance //update, I guess it's C++ now so this is a luxury int i; int j; eggname[0]='\0'; //handle the command line options int onindex; if(((onindex=handle_options(argc,argv))==-1)||(argc-onindex<0)) {print_usage(); return -1;}; // char *eggname=argv[onindex]; if(eggname[0]=='\0') { fprintf(stderr,"no input file given, use -i option\n"); return -1; } //open the egg /* struct egg current; mBreakEgg(eggname,¤t); mParseEggHeader(¤t); sampling_rate_mhz=current.data->sample_rate; */ // Monarch *egg=Monarch::OpenForReading(eggname); // Monarch *egg=Monarch::Open(std::string(eggname),ReadMode); const Monarch *egg=Monarch::OpenForReading(std::string(eggname)); egg->ReadHeader(); const MonarchHeader *eggheader=egg->GetHeader(); const MonarchRecord *event; sampling_rate_mhz=eggheader->GetAcquisitionRate(); // printf("record size: %d\n",eggheader->GetRecordSize()); //decide the optimal size for ffts and allocate memory if(eggheader->GetRecordSize()<(unsigned int)fft_size) { // if(current.data->record_size<fft_size) { fprintf(stderr,"fft size larger than record size. make fft size smaller. aborting"); return -1; } //nffts_per_event=current.data->record_size/fft_size; nffts_per_event=eggheader->GetRecordSize()/fft_size; fft_output_size=fft_size/2+1; //fft_input=fftwf_alloc_real(fft_size*nffts_per_event); fft_input=(float*)fftwf_malloc(sizeof(float)*nffts_per_event*fft_size); //fft_output=fftwf_alloc_complex(fft_size*nffts_per_event); fft_output=(fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex)*fft_output_size*nffts_per_event); output_powerspectrum=(double*)malloc(sizeof(double)*fft_output_size); for(i=0;i<fft_output_size;i++) output_powerspectrum[i]=0; //create the fft plan fft_plan=fftwf_plan_many_dft_r2c(1,&fft_size,nffts_per_event,fft_input,NULL,1,fft_size,fft_output,NULL,1,fft_output_size,FFTW_ESTIMATE); //perform ffts //int on_event=0; int nffts_so_far=0; //while((mHatchNextEvent(¤t)!=1)&&(on_event<=max_number_of_events)) { //while((event=egg->GetNextEvent())!=NULL&&(on_event<=max_number_of_events)) { while(egg->ReadRecord()) { if(on_channel==1) event=egg->GetRecordSeparateOne(); else event=egg->GetRecordSeparateTwo(); if(event==NULL) { fprintf(stderr,"ERROR: event was null. aborting\n"); return -1; } //convert data to floats //for(i=0;i<current.data->record_size;i++) for(i=0;i<eggheader->GetRecordSize();i++) //fft_input[i]=(float)(current.data->record[i])-128.0; fft_input[i]=(float)(event->fData[i])-128.0; //perform the ffts fftwf_execute(fft_plan); //pack in to power spectrum int on_pt=0; for(i=0;i<nffts_per_event;i++) for(j=0;j<fft_output_size;j++) { output_powerspectrum[j]+=fft_output[on_pt][0]*fft_output[on_pt][0]+fft_output[on_pt][1]*fft_output[on_pt][1]; on_pt++; } nffts_so_far+=nffts_per_event; } //normalize to power in milliwatts // each sample * 0.5 (volts fullscale)/255 (levels) /(sqrt(fftlength) // power *2 (positive and negative freqs) *1000 mW/W / naverages //1000 (milliwatts/watt) * 0.5 (volts fullscale)/256 (levels) / (sqrt(fft_length)*(number of averages) / 50 ohms double normalization=2.0*(1000.0*0.5*0.5/(256.0*256.0))*(1.0/(((double)fft_size*fft_size)*((double)nffts_so_far)))/50.0; for(i=0;i<fft_output_size;i++) output_powerspectrum[i]*=normalization; //print out result if(format=='j') { //ASCII output, JSON printf("{ \"sampling_rate\": %d , ",sampling_rate_mhz); printf("\"data\": ["); for(i=0;i<fft_output_size;i++) { if(i!=0) printf(","); printf("%g",output_powerspectrum[i]); } printf("] }"); } else if(format=='a') { for(i=0;i<fft_output_size;i++) printf("%g %g\n",sampling_rate_mhz*((double)i)/((double)(2*fft_output_size)),output_powerspectrum[i]); } else { //binary fwrite(output_powerspectrum,sizeof(double),fft_output_size,stdout); } //clean up egg->Close(); fftwf_destroy_plan(fft_plan); fftwf_free(fft_input); fftwf_free(fft_output); free(output_powerspectrum); //mCleanUp(¤t); return 0; }