static fftpart *get_fftpart(int rlo, int numr) { int ii, jj, index; float powargr, powargi, tmppwr, chunk[LOCALCHUNK]; fftpart *fp; if (rlo + numr > Nfft) { return NULL; } else { fp = (fftpart *) malloc(sizeof(fftpart)); fp->rlo = rlo; fp->numamps = numr; #ifdef USEMMAP fp->amps = (fcomplex *) mmap(0, sizeof(fcomplex) * numr, PROT_READ, MAP_SHARED, mmap_file, 0); #else fp->amps = read_fcomplex_file(fftfile, rlo, numr); #endif if (rlo == 0) r0 = fp->amps[0].r; fp->rawpowers = gen_fvect(fp->numamps); fp->medians = gen_fvect(fp->numamps / LOCALCHUNK); fp->normvals = gen_fvect(fp->numamps / LOCALCHUNK); fp->maxrawpow = 0.0; for (ii = 0; ii < fp->numamps / LOCALCHUNK; ii++) { index = ii * LOCALCHUNK; for (jj = 0; jj < LOCALCHUNK; jj++, index++) { tmppwr = POWER(fp->amps[index].r, fp->amps[index].i); if (tmppwr > fp->maxrawpow) if (rlo || (rlo == 0 && index > 0)) fp->maxrawpow = tmppwr; fp->rawpowers[index] = tmppwr; chunk[jj] = tmppwr; } if (rlo == 0 && ii == 0) { chunk[0] = 1.0; fp->rawpowers[0] = 1.0; } fp->medians[ii] = median(chunk, LOCALCHUNK); fp->normvals[ii] = 1.0 / (1.4426950408889634 * fp->medians[ii]); } return fp; } }
fcomplex *get_fourier_amplitudes(int lobin, int numbins, accelobs * obs) { if (obs->mmap_file || obs->dat_input) { fcomplex *tmpdata = gen_cvect(numbins); int offset = 0; // zero-pad if we try to read before the beginning of the FFT if (lobin - obs->lobin < 0) { fcomplex zeros = {0.0, 0.0}; int ii; offset = abs(lobin - obs->lobin); for (ii = 0 ; ii < offset ; ii++) tmpdata[ii] = zeros; } memcpy(tmpdata + offset, (fcomplex *) (obs->fft + (lobin - obs->lobin) + offset), sizeof(fcomplex) * (numbins - offset)); return tmpdata; } else { return read_fcomplex_file(obs->fftfile, lobin - obs->lobin, numbins); } }
void max_rz_file_harmonics(FILE * fftfile, int num_harmonics, int lobin, double rin, double zin, double *rout, double *zout, rderivs derivs[], double maxpow[]) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power of the candidate in 'fftfile'. */ /* WARNING: not tested */ { int i; double maxz, rin_int, rin_frac; int kern_half_width, filedatalen, extra = 10; int* r_offset; fcomplex** filedata; r_offset = (int*)malloc(sizeof(int)*num_harmonics); filedata = (fcomplex**)malloc(sizeof(fcomplex*)*num_harmonics); maxz = fabs(zin*num_harmonics) + 4.0; kern_half_width = z_resp_halfwidth(maxz, HIGHACC); filedatalen = 2 * kern_half_width + extra; for (i=1;i<=num_harmonics;i++) { rin_frac = modf(rin*i, &rin_int); r_offset[i-1] = (int) rin_int - filedatalen / 2 + lobin; filedata[i-1] = read_fcomplex_file(fftfile, r_offset[i-1], filedatalen); } rin_frac = modf(rin, &rin_int); max_rz_arr_harmonics(filedata, num_harmonics, r_offset, filedatalen, rin_frac + filedatalen / 2, zin, rout, zout, derivs, maxpow); *rout += r_offset[0]; for (i=1;i<=num_harmonics;i++) { vect_free(filedata[i-1]); } free(r_offset); free(filedata); }
double max_rz_file(FILE * fftfile, double rin, double zin, double *rout, double *zout, rderivs * derivs) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power of the candidate in 'fftfile'. */ { double maxz, maxpow, rin_int, rin_frac; int kern_half_width, filedatalen, startbin, extra = 10; fcomplex *filedata; maxz = fabs(zin) + 4.0; rin_frac = modf(rin, &rin_int); kern_half_width = z_resp_halfwidth(maxz, HIGHACC); filedatalen = 2 * kern_half_width + extra; startbin = (int) rin_int - filedatalen / 2; filedata = read_fcomplex_file(fftfile, startbin, filedatalen); maxpow = max_rz_arr(filedata, filedatalen, rin_frac + filedatalen / 2, zin, rout, zout, derivs); *rout += startbin; vect_free(filedata); return maxpow; }
int main(int argc, char *argv[]) /* dftfold: Does complex plane vector addition of a DFT freq */ /* Written by Scott Ransom on 31 Aug 00 based on Ransom and */ /* Eikenberry paper I (to be completed sometime...). */ { FILE *infile; char infilenm[200], outfilenm[200]; int dataperread; unsigned long N; double T, rr = 0.0, norm = 1.0; dftvector dftvec; infodata idata; Cmdline *cmd; /* Call usage() if we have no command line arguments */ if (argc == 1) { Program = argv[0]; usage(); exit(1); } /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); #ifdef DEBUG showOptionValues(); #endif printf("\n\n"); printf(" DFT Vector Folding Routine\n"); printf(" by Scott M. Ransom\n"); printf(" 31 August, 2000\n\n"); /* Open the datafile and read the info file */ sprintf(infilenm, "%s.dat", cmd->argv[0]); infile = chkfopen(infilenm, "rb"); readinf(&idata, cmd->argv[0]); /* The number of points in datafile */ N = chkfilelen(infile, sizeof(float)); dataperread = N / cmd->numvect; /* N = cmd->numvect * dataperread; */ T = N * idata.dt; /* Calculate the Fourier frequency */ if (!cmd->rrP) { if (cmd->ffP) rr = cmd->ff; else if (cmd->ppP) rr = T / cmd->pp; else { printf("\n You must specify a frequency to fold! Exiting.\n\n"); } } else rr = cmd->rr; /* Calculate the amplitude normalization if required */ if (cmd->normP) norm = 1.0 / sqrt(cmd->norm); else if (cmd->fftnormP) { FILE *fftfile; int kern_half_width, fftdatalen, startbin; double rrfrac, rrint; char fftfilenm[200]; fcomplex *fftdata; sprintf(fftfilenm, "%s.fft", cmd->argv[0]); fftfile = chkfopen(fftfilenm, "rb"); kern_half_width = r_resp_halfwidth(HIGHACC); fftdatalen = 2 * kern_half_width + 10; rrfrac = modf(rr, &rrint); startbin = (int) rrint - fftdatalen / 2; fftdata = read_fcomplex_file(fftfile, startbin, fftdatalen); norm = 1.0 / sqrt(get_localpower3d(fftdata, fftdatalen, rrfrac + fftdatalen / 2, 0.0, 0.0)); vect_free(fftdata); fclose(fftfile); } /* Initialize the dftvector */ init_dftvector(&dftvec, dataperread, cmd->numvect, idata.dt, rr, norm, T); /* Show our folding values */ printf("\nFolding data from '%s':\n", infilenm); printf(" Folding Fourier Freq = %.5f\n", rr); printf(" Folding Freq (Hz) = %-.11f\n", rr / T); printf(" Folding Period (s) = %-.14f\n", T / rr); printf(" Points per sub-vector = %d\n", dftvec.n); printf(" Number of sub-vectors = %d\n", dftvec.numvect); printf(" Normalization constant = %g\n", norm * norm); /* Perform the actual vector addition */ { int ii, jj; float *data; double real, imag, sumreal = 0.0, sumimag = 0.0; double theta, aa, bb, cc, ss, dtmp; double powargr, powargi, phsargr, phsargi, phstmp; data = gen_fvect(dftvec.n); theta = -TWOPI * rr / (double) N; dtmp = sin(0.5 * theta); aa = -2.0 * dtmp * dtmp; bb = sin(theta); cc = 1.0; ss = 0.0; for (ii = 0; ii < dftvec.numvect; ii++) { chkfread(data, sizeof(float), dftvec.n, infile); real = 0.0; imag = 0.0; for (jj = 0; jj < dftvec.n; jj++) { real += data[jj] * cc; imag += data[jj] * ss; cc = aa * (dtmp = cc) - bb * ss + cc; ss = aa * ss + bb * dtmp + ss; } dftvec.vector[ii].r = norm * real; dftvec.vector[ii].i = norm * imag; sumreal += dftvec.vector[ii].r; sumimag += dftvec.vector[ii].i; } vect_free(data); printf("\nDone:\n"); printf(" Vector sum = %.3f + %.3fi\n", sumreal, sumimag); printf(" Total phase (deg) = %.2f\n", PHASE(sumreal, sumimag)); printf(" Total power = %.2f\n", POWER(sumreal, sumimag)); printf("\n"); } fclose(infile); /* Write the output structure */ sprintf(outfilenm, "%s_%.3f.dftvec", cmd->argv[0], rr); write_dftvector(&dftvec, outfilenm); /* Free our vector and return */ free_dftvector(&dftvec); return (0); }
int main(int argc, char *argv[]) { FILE *fftfile, *candfile = NULL, *psfile = NULL; char filenm[100], candnm[100], psfilenm[120]; float locpow, norm, powargr, powargi; float *powr, *spreadpow, *minizoompow, *freqs; fcomplex *data, *minifft, *minizoom, *spread; fcomplex *resp, *kernel; double T, dr, ftobinp; int ii, nbins, ncands, candnum, lofreq = 0, nzoom, numsumpow = 1; int numbetween, numkern, kern_half_width; binaryprops binprops; infodata idata; if (argc < 3 || argc > 6) { usage(); exit(1); } printf("\n\n"); printf(" Binary Candidate Display Routine\n"); printf(" by Scott M. Ransom\n\n"); /* Initialize the filenames: */ sprintf(filenm, "%s.fft", argv[1]); sprintf(candnm, "%s_bin.cand", argv[1]); /* Read the info file */ readinf(&idata, argv[1]); if (idata.object) { printf("Plotting a %s candidate from '%s'.\n", idata.object, filenm); } else { printf("Plotting a candidate from '%s'.\n", filenm); } T = idata.N * idata.dt; /* Open the FFT file and get its length */ fftfile = chkfopen(filenm, "rb"); nbins = chkfilelen(fftfile, sizeof(fcomplex)); /* Open the candidate file and get its length */ candfile = chkfopen(candnm, "rb"); ncands = chkfilelen(candfile, sizeof(binaryprops)); /* The candidate number to examine */ candnum = atoi(argv[2]); /* Check that candnum is in range */ if ((candnum < 1) || (candnum > ncands)) { printf("\nThe candidate number is out of range.\n\n"); exit(1); } /* The lowest freq present in the FFT file */ if (argc >= 4) { lofreq = atoi(argv[3]); if ((lofreq < 0) || (lofreq > nbins - 1)) { printf("\n'lofreq' is out of range.\n\n"); exit(1); } } /* Is the original FFT a sum of other FFTs with the amplitudes added */ /* in quadrature? (i.e. an incoherent sum) */ if (argc >= 5) { numsumpow = atoi(argv[4]); if (numsumpow < 1) { printf("\nNumber of summed powers must be at least one.\n\n"); exit(1); } } /* Initialize PGPLOT using Postscript if requested */ if ((argc == 6) && (!strcmp(argv[5], "ps"))) { sprintf(psfilenm, "%s_bin_cand_%d.ps", argv[1], candnum); cpgstart_ps(psfilenm, "landscape"); } else { cpgstart_x("landscape"); } /* Read the binary candidate */ chkfileseek(candfile, (long) (candnum - 1), sizeof(binaryprops), SEEK_SET); chkfread(&binprops, sizeof(binaryprops), 1, candfile); fclose(candfile); /* Output the binary candidate */ print_bin_candidate(&binprops, 2); /* Allocate some memory */ powr = gen_fvect(binprops.nfftbins); minifft = gen_cvect(binprops.nfftbins / 2); spread = gen_cvect(binprops.nfftbins); spreadpow = gen_fvect(binprops.nfftbins); nzoom = 2 * ZOOMFACT * ZOOMNEIGHBORS; minizoom = gen_cvect(nzoom); minizoompow = gen_fvect(nzoom); /* Allocate and initialize our interpolation kernel */ numbetween = 2; kern_half_width = r_resp_halfwidth(LOWACC); numkern = 2 * numbetween * kern_half_width; resp = gen_r_response(0.0, numbetween, numkern); kernel = gen_cvect(binprops.nfftbins); place_complex_kernel(resp, numkern, kernel, binprops.nfftbins); COMPLEXFFT(kernel, binprops.nfftbins, -1); /* Read the data from the FFT file */ data = read_fcomplex_file(fftfile, binprops.lowbin - lofreq, binprops.nfftbins); /* Turn the Fourier amplitudes into powers */ for (ii = 0; ii < binprops.nfftbins; ii++) powr[ii] = POWER(data[ii].r, data[ii].i); /* Chop the powers that are way above the median level */ prune_powers(powr, binprops.nfftbins, numsumpow); /* Perform the minifft */ memcpy((float *) minifft, powr, sizeof(float) * binprops.nfftbins); realfft((float *) minifft, binprops.nfftbins, -1); /* Calculate the normalization constant */ norm = sqrt((double) binprops.nfftbins * (double) numsumpow) / minifft[0].r; locpow = minifft[0].r / binprops.nfftbins; /* Divide the original power spectrum by the local power level */ for (ii = 0; ii < binprops.nfftbins; ii++) powr[ii] /= locpow; /* Now normalize the miniFFT */ minifft[0].r = 1.0; minifft[0].i = 1.0; for (ii = 1; ii < binprops.nfftbins / 2; ii++) { minifft[ii].r *= norm; minifft[ii].i *= norm; } /* Interpolate the minifft and convert to power spectrum */ corr_complex(minifft, binprops.nfftbins / 2, RAW, kernel, binprops.nfftbins, FFT, spread, binprops.nfftbins, kern_half_width, numbetween, kern_half_width, CORR); for (ii = 0; ii < binprops.nfftbins; ii++) spreadpow[ii] = POWER(spread[ii].r, spread[ii].i); /* Plot the initial data set */ freqs = gen_freqs(binprops.nfftbins, binprops.lowbin / T, 1.0 / T); xyline(binprops.nfftbins, freqs, powr, "Pulsar Frequency (hz)", "Power / Local Power", 1); vect_free(freqs); printf("The initial data set (with high power outliers removed):\n\n"); /* Plot the miniFFT */ freqs = gen_freqs(binprops.nfftbins, 0.0, T / (2 * binprops.nfftbins)); xyline(binprops.nfftbins, freqs, spreadpow, "Binary Period (sec)", "Normalized Power", 1); vect_free(freqs); printf("The miniFFT:\n\n"); /* Interpolate and plot the actual candidate peak */ ftobinp = T / binprops.nfftbins; freqs = gen_freqs(nzoom, (binprops.rdetect - ZOOMNEIGHBORS) * ftobinp, ftobinp / (double) ZOOMFACT); for (ii = 0; ii < nzoom; ii++) { dr = -ZOOMNEIGHBORS + (double) ii / ZOOMFACT; rz_interp(minifft, binprops.nfftbins / 2, binprops.rdetect + dr, 0.0, kern_half_width, &minizoom[ii]); minizoompow[ii] = POWER(minizoom[ii].r, minizoom[ii].i); } xyline(nzoom, freqs, minizoompow, "Binary Period (sec)", "Normalized Power", 1); vect_free(freqs); printf("The candidate itself:\n\n"); printf("Done.\n\n"); /* Cleanup */ cpgend(); vect_free(data); vect_free(powr); vect_free(resp); vect_free(kernel); vect_free(minifft); vect_free(spread); vect_free(spreadpow); vect_free(minizoom); vect_free(minizoompow); fclose(fftfile); if ((argc == 6) && (!strcmp(argv[5], "ps"))) { fclose(psfile); } return (0); }
int main(int argc, char *argv[]) { FILE *fftfile; double flook, dt, nph, t, maxz, pwr, hipow = 0.0; double zlo = -30.0, zhi = 30.0, dr, dz = 2.0; double hir = 0.0, hiz = 0.0, newhir, newhiz; fcomplex **ffdotplane, *data; float powargr, powargi; int startbin, numdata, nextbin, nr, nz, numkern; int i, j, realpsr, kernel_half_width, numbetween = 4; int n, corrsize = 1024; char filenm[80], compare[200]; rderivs derivs; fourierprops props; infodata idata; struct tms runtimes; double ttim, utim, stim, tott; tott = times(&runtimes) / (double) CLK_TCK; if (argc != 3) { printf("\nUsage: 'quicklook filename fftfreq dt'\n\n"); printf(" 'filename' = a string containing the FFT file's name.\n"); printf(" (do not include the '.fft' suffix)\n"); printf(" 'fftfreq' = the central fourier frequency to examine.\n"); printf(" Quicklook will search a region of the f-fdot plane\n"); printf(" of a file containing a long, single precision FFT\n"); printf(" using the Correlation method (i.e. Ransom and \n"); printf(" Eikenberry, 1997, unpublished as of yet).\n"); printf(" The search uses a spacing of 0.5 frequency bins in\n"); printf(" the fourier frequency (r) direction, and 2 'bins' in\n"); printf(" the fdot (z) direction. The routine will output\n"); printf(" statistics for the best candidate in the region.\n\n"); printf(" The routine was written as a quick but useful hack\n"); printf(" to show the power of the Correlation method, and the\n"); printf(" forthcoming power of Scott Ransom's Pulsar Finder\n"); printf(" Software.\n"); printf(" 2 March 2001\n\n"); exit(0); } printf("\n\n"); printf(" Quick-Look Pulsation Search\n"); printf(" With database lookup.\n"); printf(" by Scott M. Ransom\n"); printf(" 2 March, 2001\n\n"); /* Initialize our data: */ sprintf(filenm, "%s.fft", argv[1]); readinf(&idata, argv[1]); flook = atof(argv[2]); dt = idata.dt; dr = 1.0 / (double) numbetween; fftfile = chkfopen(filenm, "r"); nph = get_numphotons(fftfile); n = chkfilelen(fftfile, sizeof(float)); t = n * dt; nz = (int) ((zhi - zlo) / dz) + 1; /* Determine our starting frequency and get the data */ maxz = (fabs(zlo) < fabs(zhi)) ? zhi : zlo; kernel_half_width = z_resp_halfwidth(maxz, HIGHACC); numkern = 2 * numbetween * kernel_half_width; while (numkern > 2 * corrsize) corrsize *= 2; startbin = (int) (flook) - corrsize / (2 * numbetween); numdata = corrsize / numbetween; data = read_fcomplex_file(fftfile, startbin, numdata); /* Do the f-fdot plane correlations: */ ffdotplane = corr_rz_plane(data, numdata, numbetween, kernel_half_width, zlo, zhi, nz, corrsize, LOWACC, &nextbin); nr = corrsize - 2 * kernel_half_width * numbetween; /* Search the resulting data set: */ for (i = 0; i < nz; i++) { for (j = 0; j < nr; j++) { pwr = POWER(ffdotplane[i][j].r, ffdotplane[i][j].i); if (pwr > hipow) { hir = j * dr + kernel_half_width; hiz = i * dz + zlo; hipow = pwr; } } } /* Maximize the best candidate: */ hipow = max_rz_arr(data, numdata, hir, hiz, &newhir, &newhiz, &derivs); newhir += startbin; calc_props(derivs, newhir, newhiz, 0.0, &props); printf("Searched %d pts ", nz * nr); printf("(r: %.1f to %.1f, ", (double) startbin + kernel_half_width, (double) startbin + kernel_half_width + dr * (nr - 1)); printf("z: %.1f to %.1f)\n\n", zlo, zhi); printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf(" CPU time: %.3f sec (User: %.3f sec, System: %.3f sec)\n", ttim, utim, stim); printf(" Total time: %.3f sec\n\n", tott); printf("The best candidate is:\n"); print_candidate(&props, dt, n, nph, 2); realpsr = comp_psr_to_cand(&props, &idata, compare, 1); printf("%s\n", compare); fclose(fftfile); /* Cleanup and exit */ free(ffdotplane[0]); free(ffdotplane); free(data); exit(0); }
int main(int argc, char *argv[]) { FILE *fftfile, *candfile; float powargr, powargi, *powers = NULL, *minifft; float norm, numchunks, *powers_pos; int nbins, newncand, nfftsizes, fftlen, halffftlen, binsleft; int numtoread, filepos = 0, loopct = 0, powers_offset, ncand2; int ii, ct, newper = 0, oldper = 0, numsumpow = 1; double T, totnumsearched = 0.0, minsig = 0.0, min_orb_p, max_orb_p; char *rootfilenm, *notes; fcomplex *data = NULL; rawbincand tmplist[MININCANDS], *list; infodata idata; struct tms runtimes; double ttim, utim, stim, tott; Cmdline *cmd; fftwf_plan fftplan; /* Prep the timer */ tott = times(&runtimes) / (double) CLK_TCK; /* Call usage() if we have no command line arguments */ if (argc == 1) { Program = argv[0]; printf("\n"); usage(); exit(1); } /* Parse the command line using the excellent program Clig */ cmd = parseCmdline(argc, argv); #ifdef DEBUG showOptionValues(); #endif printf("\n\n"); printf(" Phase Modulation Pulsar Search Routine\n"); printf(" by Scott M. Ransom\n\n"); { int hassuffix = 0; char *suffix; hassuffix = split_root_suffix(cmd->argv[0], &rootfilenm, &suffix); if (hassuffix) { if (strcmp(suffix, "fft") != 0) { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", cmd->argv[0]); free(suffix); exit(0); } free(suffix); } else { printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", cmd->argv[0]); exit(0); } } /* Read the info file */ readinf(&idata, rootfilenm); T = idata.N * idata.dt; if (strlen(remove_whitespace(idata.object)) > 0) { printf("Analyzing '%s' data from '%s'.\n\n", remove_whitespace(idata.object), cmd->argv[0]); } else { printf("Analyzing data from '%s'.\n\n", cmd->argv[0]); } min_orb_p = MINORBP; if (cmd->noaliasP) max_orb_p = T / 2.0; else max_orb_p = T / 1.2; /* open the FFT file and get its length */ fftfile = chkfopen(cmd->argv[0], "rb"); nbins = chkfilelen(fftfile, sizeof(fcomplex)); /* Check that cmd->maxfft is an acceptable power of 2 */ ct = 4; ii = 1; while (ct < MAXREALFFT || ii) { if (ct == cmd->maxfft) ii = 0; ct <<= 1; } if (ii) { printf("\n'maxfft' is out of range or not a power-of-2.\n\n"); exit(1); } /* Check that cmd->minfft is an acceptable power of 2 */ ct = 4; ii = 1; while (ct < MAXREALFFT || ii) { if (ct == cmd->minfft) ii = 0; ct <<= 1; } if (ii) { printf("\n'minfft' is out of range or not a power-of-2.\n\n"); exit(1); } /* Low and high Fourier freqs to check */ if (cmd->floP) { cmd->rlo = floor(cmd->flo * T); if (cmd->rlo < cmd->lobin) cmd->rlo = cmd->lobin; if (cmd->rlo > cmd->lobin + nbins - 1) { printf("\nLow frequency to search 'flo' is greater than\n"); printf(" the highest available frequency. Exiting.\n\n"); exit(1); } } else { cmd->rlo = 1.0; if (cmd->rlo < cmd->lobin) cmd->rlo = cmd->lobin; if (cmd->rlo > cmd->lobin + nbins - 1) { printf("\nLow frequency to search 'rlo' is greater than\n"); printf(" the available number of points. Exiting.\n\n"); exit(1); } } if (cmd->fhiP) { cmd->rhi = ceil(cmd->fhi * T); if (cmd->rhi > cmd->lobin + nbins - 1) cmd->rhi = cmd->lobin + nbins - 1; if (cmd->rhi < cmd->rlo) { printf("\nHigh frequency to search 'fhi' is less than\n"); printf(" the lowest frequency to search 'flo'. Exiting.\n\n"); exit(1); } } else if (cmd->rhiP) { if (cmd->rhi > cmd->lobin + nbins - 1) cmd->rhi = cmd->lobin + nbins - 1; if (cmd->rhi < cmd->rlo) { printf("\nHigh frequency to search 'rhi' is less than\n"); printf(" the lowest frequency to search 'rlo'. Exiting.\n\n"); exit(1); } } /* Determine how many different mini-fft sizes we will use */ nfftsizes = 1; ii = cmd->maxfft; while (ii > cmd->minfft) { ii >>= 1; nfftsizes++; } /* Allocate some memory and prep some variables. */ /* For numtoread, the 6 just lets us read extra data at once */ numtoread = 6 * cmd->maxfft; if (cmd->stack == 0) powers = gen_fvect(numtoread); minifft = (float *) fftwf_malloc(sizeof(float) * (cmd->maxfft * cmd->numbetween + 2)); ncand2 = 2 * cmd->ncand; list = (rawbincand *) malloc(sizeof(rawbincand) * ncand2); for (ii = 0; ii < ncand2; ii++) list[ii].mini_sigma = 0.0; for (ii = 0; ii < MININCANDS; ii++) tmplist[ii].mini_sigma = 0.0; filepos = cmd->rlo - cmd->lobin; numchunks = (float) (cmd->rhi - cmd->rlo) / numtoread; printf("Searching...\n"); printf(" Amount complete = %3d%%", 0); fflush(stdout); /* Prep FFTW */ read_wisdom(); /* Loop through fftfile */ while ((filepos + cmd->lobin) < cmd->rhi) { /* Calculate percentage complete */ newper = (int) (loopct / numchunks * 100.0); if (newper > oldper) { newper = (newper > 99) ? 100 : newper; printf("\r Amount complete = %3d%%", newper); oldper = newper; fflush(stdout); } /* Adjust our search parameters if close to end of zone to search */ binsleft = cmd->rhi - (filepos + cmd->lobin); if (binsleft < cmd->minfft) break; if (binsleft < numtoread) { /* Change numtoread */ numtoread = cmd->maxfft; while (binsleft < numtoread) { cmd->maxfft /= 2; numtoread = cmd->maxfft; } } fftlen = cmd->maxfft; /* Read from fftfile */ if (cmd->stack == 0) { data = read_fcomplex_file(fftfile, filepos, numtoread); for (ii = 0; ii < numtoread; ii++) powers[ii] = POWER(data[ii].r, data[ii].i); numsumpow = 1; } else { powers = read_float_file(fftfile, filepos, numtoread); numsumpow = cmd->stack; } if (filepos == 0) powers[0] = 1.0; /* Chop the powers that are way above the median level */ prune_powers(powers, numtoread, numsumpow); /* Loop through the different small FFT sizes */ while (fftlen >= cmd->minfft) { halffftlen = fftlen / 2; powers_pos = powers; powers_offset = 0; /* Create the appropriate FFT plan */ fftplan = fftwf_plan_dft_r2c_1d(cmd->interbinP ? fftlen : 2 * fftlen, minifft, (fftwf_complex *) minifft, FFTW_PATIENT); /* Perform miniffts at each section of the powers array */ while ((numtoread - powers_offset) > (int) ((1.0 - cmd->overlap) * cmd->maxfft + DBLCORRECT)) { /* Copy the proper amount and portion of powers into minifft */ memcpy(minifft, powers_pos, fftlen * sizeof(float)); /* For Fourier interpolation use a zeropadded FFT */ if (cmd->numbetween > 1 && !cmd->interbinP) { for (ii = fftlen; ii < cmd->numbetween * fftlen; ii++) minifft[ii] = 0.0; } /* Perform the minifft */ fftwf_execute(fftplan); /* Normalize and search the miniFFT */ norm = sqrt(fftlen * numsumpow) / minifft[0]; for (ii = 0; ii < (cmd->interbinP ? fftlen + 1 : 2 * fftlen + 1); ii++) minifft[ii] *= norm; search_minifft((fcomplex *) minifft, halffftlen, min_orb_p, max_orb_p, tmplist, MININCANDS, cmd->harmsum, cmd->numbetween, idata.N, T, (double) (powers_offset + filepos + cmd->lobin), cmd->interbinP ? INTERBIN : INTERPOLATE, cmd->noaliasP ? NO_CHECK_ALIASED : CHECK_ALIASED); /* Check if the new cands should go into the master cand list */ for (ii = 0; ii < MININCANDS; ii++) { if (tmplist[ii].mini_sigma > minsig) { /* Check to see if another candidate with these properties */ /* is already in the list. */ if (not_already_there_rawbin(tmplist[ii], list, ncand2)) { list[ncand2 - 1] = tmplist[ii]; minsig = percolate_rawbincands(list, ncand2); } } else { break; } /* Mini-fft search for loop */ } totnumsearched += fftlen; powers_pos += (int) (cmd->overlap * fftlen); powers_offset = powers_pos - powers; /* Position of mini-fft in data set while loop */ } fftwf_destroy_plan(fftplan); fftlen >>= 1; /* Size of mini-fft while loop */ } if (cmd->stack == 0) vect_free(data); else vect_free(powers); filepos += (numtoread - (int) ((1.0 - cmd->overlap) * cmd->maxfft)); loopct++; /* File position while loop */ } /* Print the final percentage update */ printf("\r Amount complete = %3d%%\n\n", 100); /* Print the number of frequencies searched */ printf("Searched %.0f pts (including interbins).\n\n", totnumsearched); printf("Timing summary:\n"); tott = times(&runtimes) / (double) CLK_TCK - tott; utim = runtimes.tms_utime / (double) CLK_TCK; stim = runtimes.tms_stime / (double) CLK_TCK; ttim = utim + stim; printf(" CPU time: %.3f sec (User: %.3f sec, System: %.3f sec)\n", ttim, utim, stim); printf(" Total time: %.3f sec\n\n", tott); printf("Writing result files and cleaning up.\n"); /* Count how many candidates we actually have */ ii = 0; while (ii < ncand2 && list[ii].mini_sigma != 0) ii++; newncand = (ii > cmd->ncand) ? cmd->ncand : ii; /* Set our candidate notes to all spaces */ notes = malloc(sizeof(char) * newncand * 18 + 1); for (ii = 0; ii < newncand; ii++) strncpy(notes + ii * 18, " ", 18); /* Check the database for possible known PSR detections */ if (idata.ra_h && idata.dec_d) { for (ii = 0; ii < newncand; ii++) { comp_rawbin_to_cand(&list[ii], &idata, notes + ii * 18, 0); } } /* Compare the candidates with each other */ compare_rawbin_cands(list, newncand, notes); /* Send the candidates to the text file */ file_rawbin_candidates(list, notes, newncand, cmd->harmsum, rootfilenm); /* Write the binary candidate file */ { char *candnm; candnm = (char *) calloc(strlen(rootfilenm) + 15, sizeof(char)); sprintf(candnm, "%s_bin%d.cand", rootfilenm, cmd->harmsum); candfile = chkfopen(candnm, "wb"); chkfwrite(list, sizeof(rawbincand), (unsigned long) newncand, candfile); fclose(candfile); free(candnm); } /* Free our arrays and close our files */ if (cmd->stack == 0) vect_free(powers); free(list); fftwf_free(minifft); free(notes); free(rootfilenm); fclose(fftfile); printf("Done.\n\n"); return (0); }