Example #1
0
GSList *search_ffdotpows(ffdotpows * ffdot, int numharm,
                         accelobs * obs, GSList * cands)
{
   int ii, jj;
   float powcut;
   long long numindep;

   powcut = obs->powcut[twon_to_index(numharm)];
   numindep = obs->numindep[twon_to_index(numharm)];

   for (ii = 0; ii < ffdot->numzs; ii++) {
      for (jj = 0; jj < ffdot->numrs; jj++) {
         if (ffdot->powers[ii][jj] > powcut) {
            float pow, sig;
            double rr, zz;
            int added = 0;

            pow = ffdot->powers[ii][jj];
            sig = candidate_sigma(pow, numharm, numindep);
            rr = (ffdot->rlo + jj * (double) ACCEL_DR) / (double) numharm;
            zz = (ffdot->zlo + ii * (double) ACCEL_DZ) / (double) numharm;
            cands = insert_new_accelcand(cands, pow, sig, numharm, rr, zz, &added);
            if (added && !obs->dat_input)
               fprintf(obs->workfile,
                       "%-7.2f  %-7.4f  %-2d  %-14.4f  %-14.9f  %-10.4f\n",
                       pow, sig, numharm, rr, rr / obs->T, zz);
         }
      }
   }
   return cands;
}
Example #2
0
void output_harmonics(GSList * list, accelobs * obs, infodata * idata)
{
   int ii, jj, numcols = 13, numcands;
   int widths[13] = { 5, 4, 5, 15, 11, 18, 13, 12, 9, 12, 10, 10, 20 };
   int errors[13] = { 0, 0, 0, 2, 0, 2, 0, 2, 0, 2, 2, 2, 0 };
   char tmpstr[30], ctrstr[30], notes[21], *command;
   accelcand *cand;
   GSList *listptr;
   fourierprops props;
   rzwerrs errs;
   static char *titles1[] = { "", "", "", "Power /", "Raw",
      "FFT 'r'", "Pred 'r'", "FFT 'z'", "Pred 'z'",
      "Phase", "Centroid", "Purity", ""
   };
   static char *titles2[] = { "Cand", "Harm", "Sigma", "Loc Pow", "Power",
      "(bin)", "(bin)", "(bins)", "(bins)",
      "(rad)", "(0-1)", "<p> = 1", "Notes"
   };

   numcands = g_slist_length(list);
   listptr = list;

   /* Print the header */

   for (ii = 0; ii < numcols - 1; ii++) {
      center_string(ctrstr, titles1[ii], widths[ii]);
      fprintf(obs->workfile, "%s  ", ctrstr);
   }
   center_string(ctrstr, titles1[ii], widths[ii]);
   fprintf(obs->workfile, "%s\n", ctrstr);
   for (ii = 0; ii < numcols - 1; ii++) {
      if (obs->nph > 0.0 && ii == 3)    /*  HAAACK!!! */
         center_string(ctrstr, "NumPhot", widths[ii]);
      else
         center_string(ctrstr, titles2[ii], widths[ii]);
      fprintf(obs->workfile, "%s  ", ctrstr);
   }
   center_string(ctrstr, titles2[ii], widths[ii]);
   fprintf(obs->workfile, "%s\n", ctrstr);
   for (ii = 0; ii < numcols - 1; ii++) {
      memset(tmpstr, '-', widths[ii]);
      tmpstr[widths[ii]] = '\0';
      fprintf(obs->workfile, "%s--", tmpstr);
   }
   memset(tmpstr, '-', widths[ii]);
   tmpstr[widths[ii]] = '\0';
   fprintf(obs->workfile, "%s\n", tmpstr);

   /* Print the fundamentals */

   for (ii = 0; ii < numcands; ii++) {
      cand = (accelcand *) (listptr->data);
      for (jj = 0; jj < cand->numharm; jj++) {
         if (obs->nph > 0.0) {
            double tmp_locpow;

            tmp_locpow = cand->derivs[jj].locpow;
            cand->derivs[jj].locpow = obs->nph;
            calc_props(cand->derivs[jj], cand->hirs[jj],
                       cand->hizs[jj], 0.0, &props);
            cand->derivs[jj].locpow = tmp_locpow;
         } else {
            calc_props(cand->derivs[jj], cand->hirs[jj],
                       cand->hizs[jj], 0.0, &props);
         }
         calc_rzwerrs(&props, obs->T, &errs);
         comp_psr_to_cand(&props, idata, notes, 0);
         if (jj == 0)
            sprintf(tmpstr, " %-4d", ii + 1);
         else
            sprintf(tmpstr, "     ");
         center_string(ctrstr, tmpstr, widths[0]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         sprintf(tmpstr, "%-4d", jj + 1);
         center_string(ctrstr, tmpstr, widths[1]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         sprintf(tmpstr, "%.2f", candidate_sigma(props.pow, 1, 1));
         center_string(ctrstr, tmpstr, widths[2]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         write_val_with_err(obs->workfile, props.pow, props.powerr,
                            errors[3], widths[3]);
         sprintf(tmpstr, "%.3g", props.rawpow);
         center_string(ctrstr, tmpstr, widths[4]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         write_val_with_err(obs->workfile, props.r, props.rerr,
                            errors[5], widths[5]);
         sprintf(tmpstr, "%.2f", cand->r * (jj + 1));
         center_string(ctrstr, tmpstr, widths[6]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         write_val_with_err(obs->workfile, props.z, props.zerr,
                            errors[7], widths[7]);
         sprintf(tmpstr, "%.2f", cand->z * (jj + 1));
         center_string(ctrstr, tmpstr, widths[8]);
         fprintf(obs->workfile, "%s  ", ctrstr);
         write_val_with_err(obs->workfile, props.phs, props.phserr,
                            errors[9], widths[9]);
         write_val_with_err(obs->workfile, props.cen, props.cenerr,
                            errors[10], widths[10]);
         write_val_with_err(obs->workfile, props.pur, props.purerr,
                            errors[11], widths[11]);
         fprintf(obs->workfile, "  %.20s\n", notes);
         fflush(obs->workfile);
      }
      listptr = listptr->next;
   }
   fprintf(obs->workfile, "\n\n");
   fclose(obs->workfile);
   command = malloc(strlen(obs->rootfilenm) + strlen(obs->accelnm) + 20);
   sprintf(command, "cat %s.inf >> %s", obs->rootfilenm, obs->accelnm);
   system(command);
   free(command);
}
Example #3
0
// FIXME: this shouldn't be a #define, or it shouldn't be here
void optimize_accelcand(accelcand * cand, accelobs * obs)
{
   int ii;
   int *r_offset;
   fcomplex **data;
   double r, z;

   cand->pows = gen_dvect(cand->numharm);
   cand->hirs = gen_dvect(cand->numharm);
   cand->hizs = gen_dvect(cand->numharm);
   r_offset = (int*) malloc(sizeof(int)*cand->numharm);
   data = (fcomplex**) malloc(sizeof(fcomplex*)*cand->numharm);
   cand->derivs = (rderivs *) malloc(sizeof(rderivs) * cand->numharm);

   if (obs->use_harmonic_polishing) {
       if (obs->mmap_file || obs->dat_input) {
           for(ii=0;ii<cand->numharm;ii++) {
               r_offset[ii]=obs->lobin;
               data[ii] = obs->fft;
           }
           max_rz_arr_harmonics(data,
                                cand->numharm,
                                r_offset,
                                obs->numbins,
                                cand->r-obs->lobin,
                                cand->z,
                                &r,
                                &z,
                                cand->derivs,
                                cand->pows);
       } else {
           max_rz_file_harmonics(obs->fftfile,
                                 cand->numharm,
                                 obs->lobin,
                                 cand->r-obs->lobin,
                                 cand->z,
                                 &r,
                                 &z,
                                 cand->derivs,
                                 cand->pows);
       }
       for(ii=0;ii<cand->numharm;ii++) {
           cand->hirs[ii]=(r+obs->lobin)*(ii+1);
           cand->hizs[ii]=z*(ii+1);
       }
   } else {
       for (ii = 0; ii < cand->numharm; ii++) {
          if (obs->mmap_file || obs->dat_input)
             cand->pows[ii] = max_rz_arr(obs->fft,
                                         obs->numbins,
                                         cand->r * (ii + 1) - obs->lobin,
                                         cand->z * (ii + 1),
                                         &(cand->hirs[ii]),
                                         &(cand->hizs[ii]), &(cand->derivs[ii]));
          else
             cand->pows[ii] = max_rz_file(obs->fftfile,
                                          cand->r * (ii + 1) - obs->lobin,
                                          cand->z * (ii + 1),
                                          &(cand->hirs[ii]),
                                          &(cand->hizs[ii]), &(cand->derivs[ii]));
          cand->hirs[ii] += obs->lobin;
       }
   }
   free(r_offset);
   free(data);

   cand->sigma = candidate_sigma(cand->power, cand->numharm,
                                 obs->numindep[twon_to_index(cand->numharm)]);
}
Example #4
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;
   }
}
Example #5
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;
}