static int calc_fftlen(int numharm, int harmnum, int max_zfull) /* The fft length needed to properly process a subharmonic */ { int bins_needed, end_effects; double harm_fract; harm_fract = (double) harmnum / (double) numharm; bins_needed = (ACCEL_USELEN * harmnum) / numharm + 2; end_effects = 2 * ACCEL_NUMBETWEEN * z_resp_halfwidth(calc_required_z(harm_fract, max_zfull), LOWACC); return next2_to_n(bins_needed + end_effects); }
static void init_kernel(int z, int fftlen, kernel * kern) { int numkern; fcomplex *tempkern; kern->z = z; kern->fftlen = fftlen; kern->numbetween = ACCEL_NUMBETWEEN; kern->kern_half_width = z_resp_halfwidth((double) z, LOWACC); numkern = 2 * kern->numbetween * kern->kern_half_width; kern->numgoodbins = kern->fftlen - numkern; kern->data = gen_cvect(kern->fftlen); tempkern = gen_z_response(0.0, kern->numbetween, kern->z, numkern); place_complex_kernel(tempkern, numkern, kern->data, kern->fftlen); free(tempkern); COMPLEXFFT(kern->data, kern->fftlen, -1); }
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[]) { 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); }
double max_rz_arr(fcomplex * data, int numdata, double rin, double zin, double *rout, double *zout, rderivs * derivs) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power. */ { double y[3], x[3][2], step = 0.4; float locpow; int numeval; maxdata = data; nummaxdata = numdata; locpow = get_localpower3d(data, numdata, rin, zin, 0.0); /* Now prep the maximization at LOWACC for speed */ /* Use a slightly larger working value for 'z' just incase */ /* the true value of z is a little larger than z. This */ /* keeps a little more accuracy. */ max_kern_half_width = z_resp_halfwidth(fabs(zin) + 4.0, LOWACC); /* Initialize the starting simplex */ x[0][0] = rin - step; x[0][1] = zin / ZSCALE - step; x[1][0] = rin - step; x[1][1] = zin / ZSCALE + step; x[2][0] = rin + step; x[2][1] = zin / ZSCALE; /* Initialize the starting function values */ y[0] = power_call_rz(x[0]); y[1] = power_call_rz(x[1]); y[2] = power_call_rz(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-7, power_call_rz, &numeval); /* Restart at minimum using HIGHACC to get a better result */ max_kern_half_width = z_resp_halfwidth(fabs(x[0][1]) + 4.0, HIGHACC); /* Re-Initialize some of the starting simplex */ x[1][0] = x[0][0] + 0.01; x[1][1] = x[0][1]; x[2][0] = x[0][0]; x[2][1] = x[0][1] + 0.01; /* Re-Initialize the starting function values */ y[0] = power_call_rz(x[0]); y[1] = power_call_rz(x[1]); y[2] = power_call_rz(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-10, power_call_rz, &numeval); /* The following calculates derivatives at the peak */ *rout = x[0][0]; *zout = x[0][1] * ZSCALE; locpow = get_localpower3d(data, numdata, *rout, *zout, 0.0); get_derivs3d(data, numdata, *rout, *zout, 0.0, locpow, derivs); return -y[0]; }
void max_rz_arr_harmonics(fcomplex* data[], int num_harmonics, int r_offset[], int numdata, double rin, double zin, double *rout, double *zout, rderivs derivs[], double power[]) /* Return the Fourier frequency and Fourier f-dot that */ /* maximizes the power. */ { double y[3], x[3][2], step = 0.4; float *locpow; int numeval; int i; locpow = gen_fvect(num_harmonics); maxlocpow = gen_fvect(num_harmonics); maxr_offset = r_offset; maxdata_harmonics = data; //FIXME: z needs to be multiplied by i everywhere for (i=1;i<=num_harmonics;i++) { locpow[i-1] = get_localpower3d(data[i-1], numdata, (r_offset[i-1]+rin)*i-r_offset[i-1], zin*i, 0.0); maxlocpow[i-1]=locpow[i-1]; } nummaxdata = numdata; max_num_harmonics = num_harmonics; /* Now prep the maximization at LOWACC for speed */ /* Use a slightly larger working value for 'z' just incase */ /* the true value of z is a little larger than z. This */ /* keeps a little more accuracy. */ max_kern_half_width = z_resp_halfwidth(fabs(zin*num_harmonics) + 4.0, LOWACC); /* Initialize the starting simplex */ x[0][0] = rin - step; x[0][1] = zin / ZSCALE - step; x[1][0] = rin - step; x[1][1] = zin / ZSCALE + step; x[2][0] = rin + step; x[2][1] = zin / ZSCALE; /* Initialize the starting function values */ y[0] = power_call_rz_harmonics(x[0]); y[1] = power_call_rz_harmonics(x[1]); y[2] = power_call_rz_harmonics(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-7, power_call_rz_harmonics, &numeval); /* Restart at minimum using HIGHACC to get a better result */ max_kern_half_width = z_resp_halfwidth(fabs(x[0][1]*num_harmonics) + 4.0, HIGHACC); /* Re-Initialize some of the starting simplex */ x[1][0] = x[0][0] + 0.01; x[1][1] = x[0][1]; x[2][0] = x[0][0]; x[2][1] = x[0][1] + 0.01; /* Re-Initialize the starting function values */ y[0] = power_call_rz_harmonics(x[0]); y[1] = power_call_rz_harmonics(x[1]); y[2] = power_call_rz_harmonics(x[2]); /* Call the solver: */ numeval = 0; amoeba(x, y, 1.0e-10, power_call_rz_harmonics, &numeval); /* The following calculates derivatives at the peak */ *rout = x[0][0]; *zout = x[0][1] * ZSCALE; for (i=1; i<=num_harmonics; i++) { locpow[i-1] = get_localpower3d(data[i-1], numdata, (r_offset[i-1]+*rout)*i-r_offset[i-1], (*zout)*i, 0.0); x[0][0] = (r_offset[i-1]+*rout)*i-r_offset[i-1]; x[0][1] = *zout/ZSCALE * i; maxdata = data[i-1]; power[i-1] = -power_call_rz(x[0]); get_derivs3d(data[i-1], numdata, (r_offset[i-1]+*rout)*i-r_offset[i-1], (*zout)*i, 0.0, locpow[i-1], &(derivs[i-1])); } vect_free(locpow); vect_free(maxlocpow); }