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 twopassfft_scratch(multifile * infile, multifile * scratch, long long nn, int isign) { long long n1, n2, bb, fp, ii, jj, kk, kind, df; int move_size; unsigned char *move; rawtype *data, *dp; double tmp1, tmp2, wtemp, wpi, wpr, wi, wr, delta; if (nn < 2) return; /* Treat the input data as a n1 (rows) x n2 (cols) */ /* matrix. Make sure that n2 >= n1. */ n1 = good_factor(nn); if (n1 == 0) { printf("\nLength of FFT in twopassfft_scratch() must be factorable\n\n"); exit(1); } n2 = nn / n1; bb = find_blocksize(n1, n2); if (bb == 0) { printf("\nCan't factor the FFT length in twopassfft_scratch()\n"); printf(" into useful sizes.\n\n"); exit(1); } data = gen_rawvect(bb * n2); move_size = (bb + n2) / 2; move = (unsigned char *) malloc(move_size); /* First do n2 transforms of length n1 by */ /* fetching size bb x n1 blocks in memory. */ for (ii = 0; ii < n2; ii += bb) { /* Read a n1 (rows) x bb (cols) block of data */ dp = data; fp = sizeof(rawtype) * ii; df = sizeof(rawtype) * n2; for (jj = 0; jj < n1; jj++) { fseek_multifile(infile, fp, SEEK_SET); fread_multifile(dp, sizeof(rawtype), bb, infile); dp += bb; /* Data ptr */ fp += df; /* File ptr */ } /* Transpose the n1 (rows) x bb (cols) block of data */ transpose_fcomplex(data, n1, bb, move, move_size); /* Do bb transforms of length n1 */ for (jj = 0; jj < bb; jj++) COMPLEXFFT(data + jj * n1, n1, isign); /* Multiply the matrix A(ii,jj) by exp(isign 2 pi i jj ii / nn). */ /* Use recursion formulas from Numerical Recipes. */ for (jj = 0; jj < bb; jj++) { delta = isign * TWOPI * (ii + jj) / nn; wr = cos(delta); wi = sin(delta); wtemp = sin(0.5 * delta); wpr = -2.0 * wtemp * wtemp; wpi = wi; kind = jj * n1 + 1; for (kk = 1; kk < n1; kk++, kind++) { tmp1 = data[kind].r; tmp2 = data[kind].i; data[kind].r = tmp1 * wr - tmp2 * wi; data[kind].i = tmp2 * wr + tmp1 * wi; wtemp = wr; wr = wtemp * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } } fwrite_multifile(data, sizeof(rawtype), bb * n1, scratch); } /* Now do n1 transforms of length n2 by fetching */ /* groups of size n2 (rows) x bb (cols) blocks. */ for (ii = 0; ii < n1; ii += bb) { /* Read two n2 (rows) x bb (cols) blocks from the file */ dp = data; fp = sizeof(rawtype) * ii; df = sizeof(rawtype) * n1; for (jj = 0; jj < n2; jj++) { fseek_multifile(scratch, fp, SEEK_SET); fread_multifile(dp, sizeof(rawtype), bb, scratch); dp += bb; /* Data ptr */ fp += df; /* File ptr */ } /* Transpose the n2 (rows) x bb (cols) block of data */ transpose_fcomplex(data, n2, bb, move, move_size); /* Do bb transforms of length n2 */ for (jj = 0; jj < bb; jj++) COMPLEXFFT(data + jj * n2, n2, isign); /* Transpose the bb (rows) x n2 (cols) block of data */ transpose_fcomplex(data, bb, n2, move, move_size); /* Scale the data if needed */ if (isign == 1) { tmp1 = 1.0 / (double) nn; for (jj = 0; jj < n2 * bb; jj++) { data[jj].r *= tmp1; data[jj].i *= tmp1; } } /* Write n2 (rows) x bb (cols) blocks to the file */ dp = data; fp = sizeof(rawtype) * ii; df = sizeof(rawtype) * n1; for (jj = 0; jj < n2; jj++) { fseek_multifile(infile, fp, SEEK_SET); fwrite_multifile(dp, sizeof(rawtype), bb, infile); dp += bb; /* Data ptr */ fp += df; /* File ptr */ } } free(move); vect_free(data); }
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); }
fcomplex *complex_corr_conv(fcomplex * data, fcomplex * kernel, int numdata, presto_ffts ffts, presto_optype type) /* Perform and return a complex correlation or convolution. */ /* Arguments: */ /* 'data' is the complex array to correlate/convolve. */ /* 'kernel' is the correlation/convolution kernel. */ /* 'numdata' is the length of 'data', 'kernel' and the result. */ /* 'ffts' describes how to perform the convolution/correlation. */ /* 'ffts' = FFTDK: FFT both the 'data' and the 'kernel'. */ /* 'ffts' = FFTD: FFT only the 'data' not the 'kernel'. */ /* 'ffts' = FFTK: FFT only the 'kernel' not the 'data'. */ /* 'ffts' = NOFFTS: Don't FFT the 'data' or the 'kernel'. */ /* 'type' is the type of operation to perform. */ /* 'type' = CONV: return a convolution in a new vector. */ /* 'type' = CORR: return a correlation in a new vector. */ /* 'type' = INPLACE_CONV: convolution over-writes 'data'. */ /* 'type' = INPLACE_CORR: correlation over-writes 'data'. */ { int ii; float normal, tmpd, tmpk; fcomplex *tmpdat; /* Get the normalization factor */ normal = 1.0 / numdata; /* Set up all our parameters */ if (ffts > 3) { printf("\nIllegal 'ffts' option (%d) in complex_corr_conv().\n", ffts); printf("Exiting.\n\n"); exit(1); } if (type > 3) { printf("\nIllegal 'type' option (%d) in complex_corr_conv().\n", type); printf("Exiting.\n\n"); exit(1); } if (type == INPLACE_CONV || type == INPLACE_CORR) { tmpdat = data; } else { tmpdat = gen_cvect(numdata); memcpy(tmpdat, data, sizeof(fcomplex) * numdata); } if (ffts == FFTDK || ffts == FFTD) { COMPLEXFFT(tmpdat, numdata, -1); } if (ffts == FFTDK || ffts == FFTK) { COMPLEXFFT(kernel, numdata, -1); } /* Do the complex multiplications */ if (type == CORR || type == INPLACE_CORR) { for (ii = 0; ii < numdata; ii++) { tmpd = tmpdat[ii].r; tmpk = kernel[ii].r; tmpdat[ii].r = (tmpd * tmpk + tmpdat[ii].i * kernel[ii].i) * normal; tmpdat[ii].i = (tmpdat[ii].i * tmpk - kernel[ii].i * tmpd) * normal; } } else { for (ii = 0; ii < numdata; ii++) { tmpd = tmpdat[ii].r; tmpk = kernel[ii].r; tmpdat[ii].r = (tmpd * tmpk - tmpdat[ii].i * kernel[ii].i) * normal; tmpdat[ii].i = (tmpdat[ii].i * tmpk + kernel[ii].i * tmpd) * normal; } } /* Perform the inverse FFT on the result and return */ COMPLEXFFT(tmpdat, numdata, 1); return tmpdat; }
int main(int argc, char *argv[]) { int ii, jj, numbirds; double lofreq, hifreq; char *rootfilenm; birdie *newbird; GSList *zapped = NULL; infodata idata; Cmdline *cmd; /* 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(" Interactive/Automatic Birdie Zapping Program\n"); printf(" by Scott M. Ransom\n"); printf(" January, 2001\n\n"); if (!cmd->zapP && !cmd->inzapfileP && !cmd->outzapfileP) { printf("You must specify '-in' and '-out' if you are not\n"); printf("automatically zapping a file (with '-zap').\n\n"); exit(0); } { 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); if (idata.object) { printf("Examining %s data from '%s'.\n\n", remove_whitespace(idata.object), cmd->argv[0]); } else { printf("Examining data from '%s'.\n\n", cmd->argv[0]); } T = idata.dt * idata.N; dr = 1.0 / NUMBETWEEN; if (cmd->zapP) { /* Automatic */ double *bird_lobins, *bird_hibins, hibin; if (!cmd->zapfileP) { printf("You must specify a 'zapfile' containing freqs\n"); printf("and widths if you want to write to the FFT file.\n\n"); free(rootfilenm); exit(0); } hibin = idata.N / 2; /* Read the Standard bird list */ numbirds = get_birdies(cmd->zapfile, T, cmd->baryv, &bird_lobins, &bird_hibins); /* Zap the birdies */ fftfile = chkfopen(cmd->argv[0], "rb+"); for (ii = 0; ii < numbirds; ii++) { if (bird_lobins[ii] >= hibin) break; if (bird_hibins[ii] >= hibin) bird_hibins[ii] = hibin - 1; zapbirds(bird_lobins[ii], bird_hibins[ii], fftfile, NULL); } vect_free(bird_lobins); vect_free(bird_hibins); } else { /* Interactive */ int *bird_numharms; double *bird_basebins; /* Read the Standard bird list */ numbirds = get_std_birds(cmd->inzapfile, T, cmd->baryv, &bird_basebins, &bird_numharms); /* Create our correlation kernel */ { int numkern; fcomplex *resp; khw = r_resp_halfwidth(LOWACC); numkern = 2 * NUMBETWEEN * khw; resp = gen_r_response(0.0, NUMBETWEEN, numkern); kernel = gen_cvect(FFTLEN); place_complex_kernel(resp, numkern, kernel, FFTLEN); COMPLEXFFT(kernel, FFTLEN, -1); vect_free(resp); } /* Loop over the birdies */ fftfile = chkfopen(cmd->argv[0], "rb"); cpgstart_x("landscape"); cpgask(0); for (ii = 0; ii < numbirds; ii++) { for (jj = 0; jj < bird_numharms[ii]; jj++) { process_bird(bird_basebins[ii], jj + 1, &lofreq, &hifreq); if (lofreq && hifreq) { newbird = birdie_create(lofreq, hifreq, cmd->baryv); zapped = g_slist_insert_sorted(zapped, newbird, birdie_compare); } } } cpgclos(); /* Output the birdies */ { FILE *outfile; outfile = chkfopen(cmd->outzapfile, "w"); fprintf(outfile, "#\n"); fprintf(outfile, "# Topocentric birdies found using 'zapbirds' for '%s'\n", cmd->argv[0]); fprintf(outfile, "#\n"); fprintf(outfile, "# Frequency (Hz) Width (Hz)\n"); fprintf(outfile, "#\n"); g_slist_foreach(zapped, birdie_print, outfile); fclose(outfile); } printf("\nOutput birdie file is '%s'.\n\n", cmd->outzapfile); /* Free the memory */ g_slist_foreach(zapped, birdie_free, NULL); g_slist_free(zapped); vect_free(kernel); vect_free(bird_numharms); vect_free(bird_basebins); } fclose(fftfile); free(rootfilenm); printf("Done\n\n"); return 0; }