Exemple #1
0
void read_dftvector(dftvector * data, char *filename)
/* Read a dftvector data structure from a binary file */
{
   FILE *infile;
   int ii;
   double dtmp;

   infile = chkfopen(filename, "rb");
   chkfread(&dtmp, sizeof(double), 1, infile);
   data->n = (int) dtmp;
   chkfread(&dtmp, sizeof(double), 1, infile);
   data->numvect = (int) dtmp;
   chkfread(&data->dt, sizeof(double), 1, infile);
   chkfread(&data->r, sizeof(double), 1, infile);
   chkfread(&data->norm, sizeof(double), 1, infile);
   chkfread(&data->T, sizeof(double), 1, infile);
   data->vector = gen_cvect(data->n);
   for (ii = 0; ii < data->numvect; ii++) {
      chkfread(&dtmp, sizeof(double), 1, infile);
      data->vector[ii].r = (float) dtmp;
      chkfread(&dtmp, sizeof(double), 1, infile);
      data->vector[ii].i = (float) dtmp;
   }
   fclose(infile);
}
Exemple #2
0
void init_dftvector(dftvector * data, int n, int numvect,
                    double dt, double r, double norm, double T)
/* Initialize a dftvector and allocate its vector part */
{
   data->n = n;
   data->numvect = numvect;
   data->dt = dt;
   data->r = r;
   data->norm = norm;
   data->T = T;
   data->vector = gen_cvect(n);
}
Exemple #3
0
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);
}
Exemple #4
0
void prep_eventdft(double *events, int numevts, int maxnumharmsum, 
                   double lof, double df)
/* Prepare the static variables and vectors for efficient calculation
   of DFT points based on events.  The FT will begin at frequency
   'lof' (Hz) and continue upwards in frquency by stepsize 'df'.
   There are 'numevents' input events with times 'events' (s).  Up to
   'maxharmsum' harmonics will be summed.  */
{
    int ii, jj;
    double delta, theta, temp, midtime, time;
    
    if (initialized){
        printf("Re-initializing eventdft variables and arrays...\n");
        free_eventdft();
    }
    numevents = numevts;
    maxharmsum = maxnumharmsum;
    numfreqs = 0;
    normconst = 1.0 / sqrt((double) numevents);
    lofreq = lof;
    dfreq = df;
    coss = gen_dmatrix(maxharmsum, numevents);
    sins = gen_dmatrix(maxharmsum, numevents);
    alph = gen_dmatrix(maxharmsum, numevents);
    beta = gen_dmatrix(maxharmsum, numevents);
    amplitudes = gen_cvect(maxharmsum);
    totaltime = events[numevents-1] - events[0];
    midtime = 0.5 * totaltime;
    for (ii = 0; ii < maxharmsum; ii++){
        for (jj = 0; jj < numevents; jj++){
            time = events[jj] - midtime;
            temp = -TWOPI * (ii + 1) * time;
            delta = temp * df;
            theta = temp * lofreq;
            temp = sin(0.5 * delta);
            alph[ii][jj] = -2.0 * temp * temp;
            beta[ii][jj] = sin(delta);
            coss[ii][jj] = cos(theta);
            sins[ii][jj] = sin(theta);
        }
    }
    initialized = 1;
}
Exemple #5
0
fcomplex *eventdft(double *events, int numevents, 
                   double lof, double df, int numf)
/* Return a set of normalized Fourier amplitudes/ calculated using an
   event DFT for a set of 'nn' events 'tt'.  The returned array is
   allocated.  */
{
    int ii;
    double freq;
    fcomplex *famp, *amps;
    
    amps = gen_cvect(numf);
    prep_eventdft(events, numevents, 1, lof, df);
    for (ii = 0; ii < numf; ii++){
        famp = calc_eventdft_point(&freq);
        amps[ii].r = famp->r;
        amps[ii].i = famp->i;
    }
    free_eventdft();
    return amps;
}
Exemple #6
0
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);
    }
}
Exemple #7
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;
}
Exemple #8
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);
}
Exemple #9
0
static void process_bird(double basebin, int harm, double *lofreq, double *hifreq)
{
   int ii, plotnumpts = 1000, not_done_yet = 1, plotoffset;
   int lodatabin, firstcorrbin, numgoodpts, replot = 1;
   char inchar;
   float med, xx[2], yy[2], inx, iny;
   float powargr, powargi, pwr, maxpow = 0.0, maxbin = 0.0;
   double truebin, pred_freq, average;
   double firstbin = 0.0, lastbin = 0.0, numbins = 0.0;
   fcomplex *data, *result;

   /* 'bin' means normal resolution FFT amplitude */
   /* 'pt'  means an interpolated FFT amplitude   */
   /* 'pts'=='bins' only if NUMBETWEEN==1         */

   *lofreq = *hifreq = 0.0;
   truebin = basebin * harm;
   pred_freq = truebin / T;
   xx[0] = xx[1] = pred_freq;
   data = get_rawbins(fftfile, truebin, BINSTOGET, &med, &lodatabin);
   if (lodatabin <= 0) {
      data[abs(lodatabin)].r = 1.0;
      data[abs(lodatabin)].i = 1.0;
   }
   firstcorrbin = (int) truebin - MAXBINSTOSHOW / 2;
   average = med / -log(0.5);
   result = gen_cvect(FFTLEN);
   numgoodpts = corr_complex(data, BINSTOGET, RAW,
                             kernel, FFTLEN, FFT,
                             result, MAXPTSTOSHOW,
                             firstcorrbin - lodatabin, NUMBETWEEN, khw, CORR);
   for (ii = 0; ii < numgoodpts; ii++) {
      pwr = POWER(result[ii].r, result[ii].i) / average;
      if (pwr > maxpow) {
         maxpow = pwr;
         maxbin = firstcorrbin + dr * ii;
      }
   }
   printf("\nHarmonic %d of %.15g Hz (%.15g Hz, bin = %.15g)\n",
          harm, basebin / T, pred_freq, truebin);
   printf("  Max power = %.2f at %.15g Hz (bin = %.15g)\n",
          maxpow, maxbin / T, maxbin);
   do {
      cpgsci(1);
      if (replot) {
         plotoffset = MAXPTSTOSHOW / 2 - plotnumpts / 2;
         firstbin = firstcorrbin + dr * plotoffset;
         numbins = dr * plotnumpts;
         lastbin = firstbin + numbins;
         plot_spectrum(result + plotoffset, plotnumpts, firstbin, dr, T, average);
         cpgswin(0.0, 1.0, 0.0, 1.0);
         xx[0] = xx[1] = (truebin - firstbin) / numbins;
         yy[0] = 0.0;
         yy[1] = 1.0;
         cpgsci(2);             /* red */
         cpgline(2, xx, yy);    /* Predicted freq */
         cpgsci(7);             /* yellow */
         if (*lofreq) {
            xx[0] = xx[1] = ((*lofreq * T) - firstbin) / numbins;
            cpgline(2, xx, yy); /* Boundary */
         }
         if (*hifreq) {
            xx[0] = xx[1] = ((*hifreq * T) - firstbin) / numbins;
            cpgline(2, xx, yy); /* Boundary */
         }
      }
      replot = 1;
      cpgsci(7);                /* yellow */
      cpgcurs(&inx, &iny, &inchar);
      switch (inchar) {
      case ' ':
      case 'A':
      case 'a':
         xx[0] = xx[1] = inx;
         cpgline(2, xx, yy);    /* New boundary */
         if (*lofreq == 0.0) {
            *lofreq = (inx * numbins + firstbin) / T;
            printf("  Added 1st boundary at %.12g Hz\n", *lofreq);
         } else {
            *hifreq = (inx * numbins + firstbin) / T;
            printf("  Added 2nd boundary at %.12g Hz\n", *hifreq);
         }
         replot = 0;
         break;
      case 'I':                /* Zoom in */
      case 'i':
         plotnumpts /= 2;
         if (plotnumpts <= 8)
            plotnumpts = 8;
         printf("  Zooming in...\n");
         break;
      case 'O':                /* Zoom out */
      case 'o':
         plotnumpts *= 2;
         if (plotnumpts > MAXPTSTOSHOW)
            plotnumpts = MAXPTSTOSHOW;
         printf("  Zooming out...\n");
         break;
      case 'C':                /* Clear/Delete the points */
      case 'c':
      case 'D':
      case 'd':
      case 'X':
      case 'x':
         *lofreq = *hifreq = 0.0;
         printf("  Clearing boundaries.\n");
         break;
      case 'Q':                /* Quit/Next birdie */
      case 'q':
      case 'N':
      case 'n':
         *lofreq = *hifreq = 0.0;
         free(data);
         vect_free(result);
         printf("  Skipping to next harmonic.\n");
         return;
      default:
         printf("  Unrecognized option '%c'.\n", inchar);
         break;
      }
      if (*lofreq && *hifreq)
         not_done_yet = 0;
   } while (not_done_yet);
   if (*hifreq < *lofreq) {
      double tmpfreq;
      tmpfreq = *lofreq;
      *lofreq = *hifreq;
      *hifreq = tmpfreq;
   }
   free(data);
   vect_free(result);
}
Exemple #10
0
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;
}
Exemple #11
0
void search_minifft(fcomplex * minifft, int numminifft,
                    double min_orb_p, double max_orb_p,
                    rawbincand * cands, int numcands, int numharmsum,
                    int numbetween, double numfullfft, double timefullfft,
                    double lorfullfft, presto_interptype interptype,
                    presto_checkaliased checkaliased)
  /* This routine searches a short FFT (usually produced using the   */
  /* MiniFFT binary search method) and returns a candidte vector     */
  /* containing information about the best binary candidates found.  */
  /* The routine uses either interbinning or interpolation as well   */
  /* as harmonic summing during the search.                          */
  /* Arguments:                                                      */
  /*   'minifft' is the FFT to search (complex valued)               */
  /*   'numminifft' is the number of complex points in 'minifft'     */
  /*   'min_orb_p' is the minimum orbital period (s) to search       */
  /*   'max_orb_p' is the maximum orbital period (s) to search       */
  /*   'cands' is a pre-allocated vector of rawbincand type in which */
  /*      the sorted (in decreasing sigma) candidates are returned   */
  /*   'numcands' is the length of the 'cands' vector                */
  /*   'numharmsum' the number of harmonics to sum during the search */
  /*   'numbetween' the points to interpolate per bin                */
  /*   'numfullfft' the number of points in the original long FFT    */
  /*   'timefullfft' the duration of the original time series (s)    */
  /*   'lorfullfft' the 1st bin of the long FFT that was miniFFT'd   */
  /*   'interptype' is either INTERBIN or INTERPOLATE.               */
/*      INTERBIN = (interbinning) is fast but less sensitive.        */
/*         NOTE:  INTERBINNING is conducted by this routine!         */
/*      INTERPOLATE = (Fourier interpolation) is slower but more     */
/*        sensitive.                                                 */
/*         NOTE:  The interpolation is assumed to ALREADY have been  */
/*                completed by the calling function!  The easiest    */
/*                way is by zero-padding to 2*numminifft and FFTing. */
/*                If you use this method, make sure numminifft is the*/
/*                original length rather than the interpolated       */
/*                length and also make sure numbetween is correct.   */
  /*   'checkaliased' is either CHECK_ALIASED or NO_CHECK_ALIASED.   */
  /*      NO_CHECK_ALIASED = harmonic summing does not include       */
  /*        aliased freqs making it faster but less sensitive.       */
  /*      CHECK_ALIASED = harmonic summing includes aliased freqs    */
  /*        making it slower but more sensitive.                     */
{
   int ii, jj, fftlen, offset, numtosearch = 0, lobin, hibin, numspread = 0;
   float powargr, powargi, *fullpows = NULL, *sumpows;
   double twobypi, minpow, minsig, dr, numindep;
   fcomplex *spread;

   /* Override the value of numbetween if interbinning */

   if (interptype == INTERBIN)
      numbetween = 2;

   /* Prep some other values we will need */

   dr = 1.0 / (double) numbetween;
   twobypi = 2.0 / PI;
   fftlen = numminifft * numbetween;
   for (ii = 0; ii < numcands; ii++) {
      cands[ii].mini_sigma = 0.0;
      cands[ii].mini_power = 0.0;
   }
   lobin = ceil(2 * numminifft * min_orb_p / timefullfft);
   if (lobin <= 0)
      lobin = 1;
   hibin = floor(2 * numminifft * max_orb_p / timefullfft);
   if (hibin >= 2 * numminifft)
      hibin = 2 * numminifft - 1;
   lobin *= numbetween;
   hibin *= numbetween;

   /* Spread and interpolate the fft */

   numtosearch = (checkaliased == CHECK_ALIASED) ? 2 * fftlen : fftlen;
   numspread = numminifft * numbetween + 1;
   if (interptype == INTERPOLATE) {     /* INTERPOLATE */
      spread = minifft;
   } else {                     /* INTERBIN */
      spread = gen_cvect(numspread);
      spread_with_pad(minifft, numminifft, spread, numspread, numbetween, 0);
      for (ii = 1; ii < fftlen; ii += 2) {
         spread[ii].r = twobypi * (spread[ii - 1].r - spread[ii + 1].r);
         spread[ii].i = twobypi * (spread[ii - 1].i - spread[ii + 1].i);
      }
   }
   spread[0].r = spread[fftlen].r = 1.0;
   spread[0].i = spread[fftlen].i = 0.0;

   fullpows = gen_fvect(numtosearch);
   fullpows[0] = 1.0;
   if (checkaliased == CHECK_ALIASED)
      fullpows[fftlen] = 1.0;   /* used to be nyquist^2 */

   /* The following wraps the data around the Nyquist freq such that */
   /* we consider aliased frequencies as well (If CHECK_ALIASED).    */

   if (checkaliased == CHECK_ALIASED)
      for (ii = 1, jj = numtosearch - 1; ii < fftlen; ii++, jj--)
         fullpows[ii] = fullpows[jj] = POWER(spread[ii].r, spread[ii].i);
   else
      for (ii = 1; ii < numtosearch; ii++)
         fullpows[ii] = POWER(spread[ii].r, spread[ii].i);
   if (interptype == INTERBIN)
      vect_free(spread);

   /* Search the raw powers */

   numindep = hibin - lobin + 1.0;
   minpow = power_for_sigma(MINRETURNSIG, 1, numindep);
   for (ii = lobin; ii < hibin; ii++) {
      if (fullpows[ii] > minpow) {
         cands[numcands - 1].mini_r = dr * (double) ii;
         cands[numcands - 1].mini_power = fullpows[ii];
         cands[numcands - 1].mini_numsum = 1.0;
         cands[numcands - 1].mini_sigma = candidate_sigma(fullpows[ii], 1, numindep);
         minsig = percolate_rawbincands(cands, numcands);
         if (cands[numcands - 1].mini_power > minpow)
            minpow = cands[numcands - 1].mini_power;
      }
   }

   /* If needed, sum and search the harmonics */

   if (numharmsum > 1) {
      sumpows = gen_fvect(numtosearch);
      memcpy(sumpows, fullpows, sizeof(float) * numtosearch);
      for (ii = 2; ii <= numharmsum; ii++) {
         offset = ii / 2;
         numindep = (hibin - lobin + 1.0) / (double) ii;
         if (cands[numcands - 1].mini_sigma < MINRETURNSIG)
            minsig = MINRETURNSIG;
         else
            minsig = cands[numcands - 1].mini_sigma;
         minpow = power_for_sigma(minsig, ii, numindep);
         for (jj = lobin * ii; jj < hibin; jj++) {
            sumpows[jj] += fullpows[(jj + offset) / ii];
            if (sumpows[jj] > minpow) {
               cands[numcands - 1].mini_r = (dr * (double) jj) / ii;
               cands[numcands - 1].mini_power = sumpows[jj];
               cands[numcands - 1].mini_numsum = (double) ii;
               cands[numcands - 1].mini_sigma =
                   candidate_sigma(sumpows[jj], ii, numindep);
               minsig = percolate_rawbincands(cands, numcands);
               if (minsig > MINRETURNSIG)
                  minpow = power_for_sigma(minsig, ii, numindep);
            }
         }
      }
      vect_free(sumpows);
   }
   vect_free(fullpows);

   /* Add the rest of the rawbincand data to the candidate array */

   for (ii = 0; ii < numcands; ii++) {
      cands[ii].full_N = numfullfft;
      cands[ii].full_T = timefullfft;
      cands[ii].full_lo_r = lorfullfft;
      cands[ii].mini_N = 2 * numminifft;        /* # of real points */
      cands[ii].psr_p = timefullfft / (lorfullfft + numminifft);
      cands[ii].orb_p = timefullfft * cands[ii].mini_r / cands[ii].mini_N;
   }
}
Exemple #12
0
fftcand *search_fft(fcomplex * fft, int numfft, int lobin, int hibin,
                    int numharmsum, int numbetween,
                    presto_interptype interptype,
                    float norm, float sigmacutoff, int *numcands,
                    float *powavg, float *powvar, float *powmax)
/* This routine searches a short FFT of 'numfft' complex freqs      */
/* and returns a candidate vector of fftcand structures containing  */
/* information about the best candidates found.                     */
/* The routine uses either interbinning or interpolation as well    */
/* as harmonic summing during the search.                           */
/* The number of candidates returned is either 'numcands' if != 0,  */
/* or is determined automatically by 'sigmacutoff' -- which         */
/* takes into account the number of bins searched.                  */
/* The returned vector is sorted in order of decreasing power.      */
/* Arguments:                                                       */
/*   'fft' is the FFT to search (complex valued)                    */
/*   'numfft' is the number of complex points in 'fft'              */
/*   'lobin' is the lowest Fourier freq to search                   */
/*   'hibin' is the highest Fourier freq to search                  */
/*   'numharmsum' the number of harmonics to sum during the search  */
/*   'numbetween' the points to interpolate per bin                 */
/*   'interptype' is either INTERBIN or INTERPOLATE.                */
/*      INTERBIN = (interbinning) is fast but less sensitive.       */
/*         NOTE:  INTERBINNING is conducted by this routine!        */
/*      INTERPOLATE = (Fourier interpolation) is slower but more    */
/*        sensitive.                                                */
/*         NOTE:  The interpolation is assumed to ALREADY have been */
/*                completed by the calling function!  The easiest   */
/*                way is by zero-padding to 2*numfft and FFTing.    */
/*                If you use this method, make sure numfft is the   */
/*                original length rather than the interpolated      */
/*                length and also make sure numbetween is correct.  */
/*   'norm' is the normalization constant to multiply each power by */
/*   'sigmacutoff' if the number of candidates will be determined   */
/*      automatically, is the minimum Gaussian significance of      */
/*      candidates to keep -- taking into account the number of     */
/*      bins searched                                               */
/*   'numcands' if !0, is the number of candates to return.         */
/*      if 0, is a return value giving the number of candidates.    */
/*   'powavg' is a return value giving the average power level      */
/*   'powvar' is a return value giving the power level variance     */
/*   'powmax' is a return value giving the maximum power            */
{
   int ii, jj, offset, numtosearch, dynamic = 0;
   int numspread = 0, nc = 0, startnc = 10;
   float powargr, powargi, *fullpows = NULL, *sumpows, ftmp;
   double twobypi, minpow = 0.0, tmpminsig = 0.0, dr, davg, dvar;
   fftcand *cands, newcand;
   fcomplex *spread;

   /* Override the value of numbetween if interbinning */

   if (interptype == INTERBIN)
      numbetween = 2;
   norm = 1.0 / norm;
   *powmax = 0.0;

   /* Decide if we will manage the number of candidates */

   if (*numcands > 0)
      startnc = *numcands;
   else {
      dynamic = 1;
      minpow = power_for_sigma(sigmacutoff, 1, hibin - lobin);
   }
   cands = (fftcand *) malloc(startnc * sizeof(fftcand));
   for (ii = 0; ii < startnc; ii++)
      cands[ii].sig = 0.0;

   /* Prep some other values we will need */

   dr = 1.0 / (double) numbetween;
   twobypi = 2.0 / PI;
   numtosearch = numfft * numbetween;

   /* Spread and interpolate the fft */

   numspread = numfft * numbetween + 1;
   if (interptype == INTERPOLATE) {     /* INTERPOLATE */
      spread = fft;
   } else {                     /* INTERBIN */
      spread = gen_cvect(numspread);
      spread_with_pad(fft, numfft, spread, numspread, numbetween, 0);
      for (ii = 1; ii < numtosearch; ii += 2) {
         spread[ii].r = twobypi * (spread[ii - 1].r - spread[ii + 1].r);
         spread[ii].i = twobypi * (spread[ii - 1].i - spread[ii + 1].i);
      }
   }
   spread[0].r = spread[numtosearch].r = 1.0;
   spread[0].i = spread[numtosearch].i = 0.0;

   /* First generate the original powers in order to         */
   /* calculate the statistics.  Yes, this is inefficient... */

   fullpows = gen_fvect(numtosearch);
   for (ii = lobin, jj = 0; ii < hibin; ii++, jj++) {
      ftmp = POWER(fft[ii].r, fft[ii].i) * norm;
      fullpows[jj] = ftmp;
      if (ftmp > *powmax)
         *powmax = ftmp;
   }
   avg_var(fullpows, hibin - lobin, &davg, &dvar);
   *powavg = davg;
   *powvar = dvar;
   fullpows[0] = 1.0;
   for (ii = 1; ii < numtosearch; ii++)
      fullpows[ii] = POWER(spread[ii].r, spread[ii].i) * norm;
   if (interptype == INTERBIN)
      vect_free(spread);

   /* Search the raw powers */

   for (ii = lobin * numbetween; ii < hibin * numbetween; ii++) {
      if (fullpows[ii] > minpow) {
         newcand.r = dr * (double) ii;
         newcand.p = fullpows[ii];
         newcand.sig = candidate_sigma(fullpows[ii], 1, hibin - lobin);
         newcand.nsum = 1;
         cands[startnc - 1] = newcand;
         tmpminsig = percolate_fftcands(cands, startnc);
         if (dynamic) {
            nc++;
            if (nc == startnc) {
               startnc *= 2;
               cands = (fftcand *) realloc(cands, startnc * sizeof(fftcand));
               for (jj = nc; jj < startnc; jj++)
                  cands[jj].sig = 0.0;
            }
         } else {
            minpow = cands[startnc - 1].p;
            if (nc < startnc)
               nc++;
         }
      }
   }

   /* If needed, sum and search the harmonics */

   if (numharmsum > 1) {
      sumpows = gen_fvect(numtosearch);
      memcpy(sumpows, fullpows, sizeof(float) * numtosearch);
      for (ii = 2; ii <= numharmsum; ii++) {
         offset = ii / 2;
         if (dynamic)
            minpow = power_for_sigma(sigmacutoff, ii, hibin - lobin);
         else
            minpow = power_for_sigma(tmpminsig, ii, hibin - lobin);
         for (jj = lobin * numbetween; jj < numtosearch; jj++) {
            sumpows[jj] += fullpows[(jj + offset) / ii];
            if (sumpows[jj] > minpow) {
               newcand.r = dr * (double) jj;
               newcand.p = sumpows[jj];
               newcand.sig = candidate_sigma(sumpows[jj], ii, hibin - lobin);
               newcand.nsum = ii;
               cands[startnc - 1] = newcand;
               tmpminsig = percolate_fftcands(cands, startnc);
               if (dynamic) {
                  nc++;
                  if (nc == startnc) {
                     startnc *= 2;
                     cands = (fftcand *) realloc(cands, startnc * sizeof(fftcand));
                     for (jj = nc; jj < startnc; jj++)
                        cands[jj].sig = 0.0;
                  }
               } else {
                  minpow = power_for_sigma(tmpminsig, ii, hibin - lobin);
                  if (nc < startnc)
                     nc++;
               }
            }
         }
      }
      vect_free(sumpows);
   }
   vect_free(fullpows);

   /* Chop off the unused parts of the dynamic array */

   if (dynamic)
      cands = (fftcand *) realloc(cands, nc * sizeof(fftcand));
   *numcands = nc;
   return cands;
}