/*--------------------------------------------------------------------------*/ long _fftwfI (char *wisdom_file) /* import */ { FILE *fp; int stat; fp = fopen(wisdom_file, "r"); if((fp = fopen(wisdom_file, "r"))==NULL) { printf("Error reading wisdom file\"%s\"\n",wisdom_file); fflush(stdout); exit(0); } stat = fftwf_import_wisdom_from_file(fp); fclose(fp); return stat; }
void read_wisdom(void) { FILE *wisdomfile; static char wisdomfilenm[120]; /* First try to import the system wisdom if available */ fftwf_import_system_wisdom(); sprintf(wisdomfilenm, "%s/lib/fftw_wisdom.txt", getenv("PRESTO")); wisdomfile = fopen(wisdomfilenm, "r"); if (wisdomfile == NULL) { printf("Warning: Couldn't open '%s'\n" " You should run 'makewisdom'. See $PRESTO/INSTALL.\n", wisdomfilenm); } else { if (!fftwf_import_wisdom_from_file(wisdomfile)) printf("Warning: '%s' is not up-to-date.\n" " You should run 'makewisdom'. See $PRESTO/INSTALL.\n", wisdomfilenm); fclose(wisdomfile); } }
int main() { if (FILE* wisdomfile = fopen("wisdom.wis","r")) { fftwf_import_wisdom_from_file(wisdomfile); fclose(wisdomfile); } const int N[] = {32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072}; const int sizeN = 13; int cfft[sizeN]; int nfft[sizeN]; double t; double tavg; double tfprev; double tbprev; for (int l = 0; l < sizeN; l++) { cfft[l] = N[l]+1; nfft[l] = N[l]*2; } FILE *fp = fopen("fftw.csv","w"); for (int l = 0; l < sizeN; l++) { printf("\n\nTiming N = %u, cfft = %u\n",N[l],cfft[l]); float *a = new float[nfft[l]]; fftwf_complex *b = (fftwf_complex*)fftwf_malloc(cfft[l]*sizeof(fftwf_complex)); fftwf_plan fwd; fftwf_plan bck; int trial; float temp; fprintf(fp,"%u, ",N[l]); //ESTIMATE --------------- --------------- temp = (float)get_time(); for (int i = 0; i < nfft[i]; i++) a[i] = temp; float* bptr = (float*)b; for (int i = 0; i < 2*cfft[i]; i++) bptr[i] = temp; printf("ESTIMATE: \n"); fwd = fftwf_plan_dft_r2c_1d(nfft[l],a,b,FFTW_ESTIMATE); bck = fftwf_plan_dft_c2r_1d(nfft[l],b,a,FFTW_ESTIMATE); t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(fwd); t += get_time(); } tavg = t/trial; printf("FWD trials: %u, total time: %5g, avg time: %5g\n",trial,t,tavg); fprintf(fp,"%g, ",tavg); tfprev = tavg; t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(bck); t += get_time(); } tavg = t/trial; printf("BCK trials: %u, total time: %5g, avg time: %5g\n",trial,t,tavg); fprintf(fp,"%g, ",tavg); tbprev = tavg; fftwf_destroy_plan(fwd); fftwf_destroy_plan(bck); //MEASURE --------------- --------------- temp = (float)get_time(); for (int i = 0; i < nfft[i]; i++) a[i] = temp; bptr = (float*)b; for (int i = 0; i < 2*cfft[i]; i++) bptr[i] = temp; printf("MEASURE: \n"); fwd = fftwf_plan_dft_r2c_1d(nfft[l],a,b,FFTW_MEASURE); bck = fftwf_plan_dft_c2r_1d(nfft[l],b,a,FFTW_MEASURE); t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(fwd); t += get_time(); } tavg = t/trial; printf("FWD trials: %u, total time: %5g, avg time: %5g (%5g,%5g)\n",trial,t,tavg,100*tavg/tfprev,100*tfprev/tavg); fprintf(fp,"%g, ",tavg); tfprev = tavg; t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(bck); t += get_time(); } tavg = t/trial; printf("BCK trials: %u, total time: %5g, avg time: %5g (%5g,%5g)\n",trial,t,tavg,100*tavg/tbprev,100*tbprev/tavg); fprintf(fp,"%g, ",tavg); tbprev = tavg; fftwf_destroy_plan(fwd); fftwf_destroy_plan(bck); //PATIENT --------------- --------------- temp = (float)get_time(); for (int i = 0; i < nfft[i]; i++) a[i] = temp; bptr = (float*)b; for (int i = 0; i < 2*cfft[i]; i++) bptr[i] = temp; printf("PATIENT: \n"); fwd = fftwf_plan_dft_r2c_1d(nfft[l],a,b,FFTW_PATIENT); bck = fftwf_plan_dft_c2r_1d(nfft[l],b,a,FFTW_PATIENT); t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(fwd); t += get_time(); } tavg = t/trial; printf("FWD trials: %u, total time: %5g, avg time: %5g (%5g,%5g)\n",trial,t,tavg,100*tavg/tfprev,100*tfprev/tavg); fprintf(fp,"%g, ",tavg); t = 0; for (trial = 0; trial < MAX_TRIALS; trial++) { if (t > MAX_TIME) break; t -= get_time(); fftwf_execute(bck); t += get_time(); } tavg = t/trial; printf("BCK trials: %u, total time: %5g, avg time: %5g (%5g,%5g)\n",trial,t,tavg,100*tavg/tbprev,100*tbprev/tavg); fprintf(fp,"%g\n",tavg); fftwf_destroy_plan(fwd); fftwf_destroy_plan(bck); delete[] a; fftwf_free(b); } if (FILE* wisdomfile = fopen("wisdom.wis","w")) { fftwf_export_wisdom_to_file(wisdomfile); fclose(wisdomfile); } fclose(fp); return 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; }
int main(int argc, char *argv[]) { int opt=0, verb=0; int max_harm = 64, max_lag=0; int isub = 1; while ((opt=getopt(argc,argv,"hvI:H:L:"))!=-1) { switch (opt) { case 'v': verb++; break; case 'I': isub = atoi(optarg); break; case 'H': max_harm = atoi(optarg); break; case 'L': max_lag = atoi(optarg); break; case 'h': usage(); exit(0); break; } } if (optind==argc) { usage(); exit(1); } int i, rv; /* Open file */ fitsfile *f; int status; fits_open_file(&f, argv[optind], READONLY, &status); fits_error_check_fatal(); /* Get basic dims */ struct cyclic_work w; cyclic_load_params(f, &w, &status); fits_error_check_fatal(); if (verb) { printf("Read nphase=%d npol=%d nchan=%d\n", w.nphase, w.npol, w.nchan); fflush(stdout); } int orig_npol = w.npol; w.npol = 1; /* Init FFTs */ fftwf_init_threads(); fftwf_plan_with_nthreads(4); if (verb) { printf("Planning FFTs\n"); fflush(stdout); } #define WF "/home/pdemores/share/cyclic_wisdom.dat" FILE *wf = fopen(WF,"r"); if (wf!=NULL) { fftwf_import_wisdom_from_file(wf); fclose(wf); } rv = cyclic_init_ffts(&w); if (rv) { fprintf(stderr, "Error planning ffts (rv=%d)\n", rv); exit(1); } wf = fopen(WF,"w"); if (wf!=NULL) { fftwf_export_wisdom_to_file(wf); fclose(wf); } /* Alloc some stuff */ struct periodic_spectrum raw; struct cyclic_spectrum cs, model_cs; struct filter_time ht; struct filter_freq hf; struct profile_phase pp; struct profile_harm ph; raw.nphase = pp.nphase = w.nphase; raw.nchan = cs.nchan = hf.nchan = w.nchan; cs.nharm = ph.nharm = w.nharm; ht.nlag = w.nlag; raw.npol = orig_npol; cs.npol = 1; model_cs.nchan = cs.nchan; model_cs.nharm = cs.nharm; model_cs.npol = cs.npol; cyclic_alloc_ps(&raw); cyclic_alloc_cs(&cs); cyclic_alloc_cs(&model_cs); filter_alloc_time(&ht); filter_alloc_freq(&hf); profile_alloc_phase(&pp); profile_alloc_harm(&ph); #if 0 // XXX not implemented yet /* Check bounds */ if (max_harm > w.nharm) { max_harm = w.nharm; } if (max_lag > w.nlag/2) { max_lag = w.nlag/2; } if (verb) { printf("Using max of %d harmonics and %d lags\n", max_harm, max_lag); } #endif /* Load data */ cyclic_load_ps(f, &raw, isub, &status); fits_error_check_fatal(); /* Add polns w/o calibration */ cyclic_pscrunch_ps(&raw, 1.0, 1.0); /* Initialize H, profile guesses */ cyclic_fscrunch_ps(&pp, &raw); profile_phase2harm(&pp, &ph, &w); ht.data[0] = 1.0; for (i=1; i<ht.nlag; i++) { ht.data[i] = 0.0; } filter_profile_norm(&ht, &ph, w.nharm); profile_harm2phase(&ph, &pp, &w); /* convert input data to cyclic spectrum */ cyclic_ps2cs(&raw, &cs, &w); /* could output initial profile */ /* Fill in data struct for nlopt */ struct cyclic_data cdata; cdata.cs = &cs; cdata.s0 = &ph; cdata.ht = &ht; cdata.model_cs = &model_cs; cdata.w = &w; /* Set up minimizer */ const int dim = 2*(w.nharm-1) + 2*w.nlag; /* number of free params */ printf("number of fit params = %d\n", dim); nlopt_opt op; op = nlopt_create(NLOPT_LN_COBYLA, dim); nlopt_set_min_objective(op, cyclic_ms_difference_nlopt, &cdata); nlopt_set_xtol_rel(op, 1e-4); /* Set up initial params */ double *x = (double *)malloc(sizeof(double) * dim); double *xtmp = x; for (i=1; i<ph.nharm; i++) { xtmp[0] = creal(ph.data[i]); xtmp[1] = cimag(ph.data[i]); xtmp += 2; } for (i=0; i<ht.nlag; i++) { xtmp[0] = creal(ht.data[i]); xtmp[1] = cimag(ht.data[i]); xtmp += 2; } /* Run optimization */ double min; if (nlopt_optimize(op, x, &min)) { fprintf(stderr, "nlopt_optimize failed\n"); exit(1); } /* TODO: some kind of output */ /* All done :) */ nlopt_destroy(op); exit(0); }
int main(int argc, char *argv[]) { int opt=0, verb=0; int max_harm = 64, max_lag=0; int causal_filter = 0; while ((opt=getopt(argc,argv,"hvH:L:C"))!=-1) { switch (opt) { case 'v': verb++; break; case 'H': max_harm = atoi(optarg); break; case 'L': max_lag = atoi(optarg); break; case 'C': causal_filter = 1; break; case 'h': usage(); exit(0); break; } } if (optind==argc) { usage(); exit(1); } int i, rv; /* Open file */ fitsfile *f; int status; fits_open_file(&f, argv[optind], READONLY, &status); fits_error_check_fatal(); /* Get basic dims */ struct cyclic_work w; cyclic_load_params(f, &w, &status); fits_error_check_fatal(); if (verb) { printf("Read nphase=%d npol=%d nchan=%d\n", w.nphase, w.npol, w.nchan); fflush(stdout); } int orig_npol = w.npol; w.npol = 1; /* Init FFTs */ fftwf_init_threads(); fftwf_plan_with_nthreads(4); if (verb) { printf("Planning FFTs\n"); fflush(stdout); } #define WF "/home/pdemores/share/cyclic_wisdom.dat" FILE *wf = fopen(WF,"r"); if (wf!=NULL) { fftwf_import_wisdom_from_file(wf); fclose(wf); } rv = cyclic_init_ffts(&w); if (rv) { fprintf(stderr, "Error planning ffts (rv=%d)\n", rv); exit(1); } wf = fopen(WF,"w"); if (wf!=NULL) { fftwf_export_wisdom_to_file(wf); fclose(wf); } /* Alloc some stuff */ struct periodic_spectrum raw; struct cyclic_spectrum cs, cs_neg; struct filter_time ht, ht_new; struct filter_freq hf, hf_new; struct filter_freq *hf_shift_pos, *hf_shift_neg; hf_shift_pos = (struct filter_freq *)malloc( sizeof(struct filter_freq)*w.nharm); hf_shift_neg = (struct filter_freq *)malloc( sizeof(struct filter_freq)*w.nharm); struct profile_phase pp, pp_new; struct profile_harm ph, ph_new; raw.nphase = pp.nphase = pp_new.nphase = w.nphase; raw.nchan = cs.nchan = hf.nchan = hf_new.nchan = w.nchan; cs.nharm = ph.nharm = ph_new.nharm = w.nharm; ht.nlag = ht_new.nlag = w.nlag; for (i=0; i<w.nharm; i++) { hf_shift_pos[i].nchan = w.nchan; } for (i=0; i<w.nharm; i++) { hf_shift_neg[i].nchan = w.nchan; } raw.npol = orig_npol; cs.npol = 1; cs_neg.nchan = cs.nchan; cs_neg.nharm = cs.nharm; cs_neg.npol = cs.npol; cyclic_alloc_ps(&raw); cyclic_alloc_cs(&cs); cyclic_alloc_cs(&cs_neg); filter_alloc_time(&ht); filter_alloc_time(&ht_new); filter_alloc_freq(&hf); filter_alloc_freq(&hf_new); for (i=0; i<w.nharm; i++) { filter_alloc_freq(&hf_shift_pos[i]); filter_alloc_freq(&hf_shift_neg[i]); } profile_alloc_phase(&pp); profile_alloc_phase(&pp_new); profile_alloc_harm(&ph); profile_alloc_harm(&ph_new); /* Check bounds */ if (max_harm > w.nharm) { max_harm = w.nharm; } if (max_lag > w.nlag/2) { max_lag = w.nlag/2; } if (verb) { printf("Using max of %d harmonics and %d lags\n", max_harm, max_lag); } /* Run procedure on subint 0 */ int isub = 1; /* Load data */ cyclic_load_ps(f, &raw, isub, &status); fits_error_check_fatal(); /* Add polns w/o calibration */ cyclic_pscrunch_ps(&raw, 1.0, 1.0); /* Initialize H, profile guesses */ cyclic_fscrunch_ps(&pp, &raw); profile_phase2harm(&pp, &ph, &w); ht.data[0] = 1.0; for (i=1; i<ht.nlag; i++) { ht.data[i] = 0.0; } filter_profile_norm(&ht, &ph, max_harm); profile_harm2phase(&ph, &pp, &w); /* convert to CS, produce shifted version */ cyclic_ps2cs(&raw, &cs, &w); cyclic_ps2cs(&raw, &cs_neg, &w); cyclic_shift_cs(&cs, +1, &w); cyclic_shift_cs(&cs_neg, -1, &w); /* TODO output initial profile */ /* Remove old files */ #define FILT "filters.dat" #define TFILT "tfilters.dat" #define PROF "profs.dat" #define FPROF "fprofs.dat" unlink(FILT); unlink(TFILT); unlink(PROF); unlink(FPROF); FILE *it = fopen("iter.dat", "w"); /* iterate */ int nit=0; double mse=0.0, last_mse=0.0; signal(SIGINT, cc); do { if (verb) { printf("iter %d\n", nit); fflush(stdout); } /* Make freq domain filter */ filter_time2freq(&ht, &hf, &w); write_filter(TFILT, &ht); write_filter_freq(FILT, &hf); /* Make shifted filter array */ filter_shift(hf_shift_pos, &ht, w.nharm, raw.ref_freq/(raw.bw*1e6), &w); filter_shift(hf_shift_neg, &ht, w.nharm, -1.0*raw.ref_freq/(raw.bw*1e6), &w); mse = cyclic_mse(&cs, &cs_neg, &ph, hf_shift_pos, hf_shift_neg, max_harm); /* Update filter, prof */ cyclic_update_filter(&hf_new, &cs, &cs_neg, &ph, hf_shift_pos, hf_shift_neg, max_harm); cyclic_update_profile(&ph_new, &cs, &cs_neg, hf_shift_pos, hf_shift_neg); /* Back to time domain filter */ filter_freq2time(&hf_new, &ht_new, &w); /* Fix filter normalization */ for (i=0; i<ht_new.nlag; i++) ht_new.data[i] /= (float)ht_new.nlag; /* Zero out negative lags */ if (causal_filter) { for (i=ht_new.nlag/2; i<ht_new.nlag; i++) ht_new.data[i] = 0.0; } /* Zero out large lags */ if (max_lag>0) { for (i=max_lag; i<ht_new.nlag-max_lag; i++) ht_new.data[i] = 0.0; } /* Kill nyquist point?? */ ht_new.data[ht_new.nlag/2] = 0.0; /* Normalize prof and filter */ filter_profile_norm(&ht_new, &ph_new, max_harm); /* TODO some kind of convergence test */ double prof_diff = profile_ms_difference(&ph, &ph_new, max_harm); double filt_diff = filter_ms_difference(&ht, &ht_new); /* TODO zero out high harmonics ?? */ /* Step halfway to new versions, except first time */ if (nit==0) { for (i=0; i<w.nharm; i++) ph.data[i] = ph_new.data[i]; for (i=0; i<w.nlag; i++) ht.data[i] = ht_new.data[i]; } else { //double fac = (mse<last_mse) ? 1.0 : 0.5*sqrt(mse/last_mse); double fac=0.25; for (i=0; i<w.nharm; i++) ph.data[i] = (1.0-fac)*ph.data[i] + fac*ph_new.data[i]; for (i=0; i<w.nlag; i++) ht.data[i] = (1.0-fac)*ht.data[i] + fac*ht_new.data[i]; } /* Back to phase domain profile */ ph.data[0] = 0.0; profile_harm2phase(&ph, &pp_new, &w); /* Write out current profiles */ write_profile(PROF, &pp_new); write_fprofile(FPROF, &ph); /* Print convergence params */ if (verb) { fprintf(it,"%.3e %.3e %.8e %.8e\n", prof_diff, filt_diff, mse, mse - last_mse); } last_mse = mse; /* Update iter count */ nit++; } while (run); fclose(it); exit(0); }