Beispiel #1
0
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);
}
Beispiel #2
0
static dataview *get_dataview(int centern, int zoomlevel, datapart * dp)
{
   int ii, jj, offset;
   double tmpavg, tmpvar;
   float *tmpchunk;
   dataview *dv;

   dv = (dataview *) malloc(sizeof(dataview));
   dv->zoomlevel = zoomlevel;
   dv->numsamps = (1 << (LOGMAXDISPNUM - zoomlevel));
   if (dv->numsamps > dp->nn)
      dv->numsamps = next2_to_n(dp->nn) / 2;
   dv->chunklen = (zoomlevel < -LOGMINCHUNKLEN) ?
       (1 << abs(zoomlevel)) : (1 << LOGMINCHUNKLEN);
   dv->dispnum = (dv->numsamps > MAXDISPNUM) ? MAXDISPNUM : dv->numsamps;
   if (DEBUGOUT)
      printf("zoomlevel = %d  numsamps = %d  chunklen = %d  dispnum %d  nn = %d\n",
             dv->zoomlevel, dv->numsamps, dv->chunklen, dv->dispnum, dp->nn);
   dv->numchunks = dv->numsamps / dv->chunklen;
   dv->centern = centern;
   dv->lon = centern - dv->numsamps / 2;
   dv->vdt = dv->chunklen * idata.dt;
   dv->maxval = SMALLNUM;
   dv->minval = LARGENUM;
   if (dv->lon < 0) {
      dv->lon = 0;
      dv->centern = dv->lon + dv->numsamps / 2;
   }
   if (dv->lon + dv->numsamps >= dp->nn) {
      dv->lon = dp->nn - dv->numsamps;
      dv->centern = dv->lon + dv->numsamps / 2;
   }
   tmpchunk = gen_fvect(dv->chunklen);
   for (ii = 0; ii < dv->numchunks; ii++) {
      float tmpmin = LARGENUM, tmpmax = SMALLNUM, tmpval;
      offset = dv->lon + ii * dv->chunklen;
      memcpy(tmpchunk, dp->data + offset, sizeof(float) * dv->chunklen);
      avg_var(dp->data + offset, dv->chunklen, &tmpavg, &tmpvar);
      if (usemedian)
         dv->avgmeds[ii] = median(tmpchunk, dv->chunklen);
      else
         dv->avgmeds[ii] = tmpavg;
      dv->stds[ii] = sqrt(tmpvar);
      for (jj = 0; jj < dv->chunklen; jj++, offset++) {
         tmpval = dp->data[offset];
         if (tmpval > tmpmax)
            tmpmax = tmpval;
         if (tmpval < tmpmin)
            tmpmin = tmpval;
      }
      dv->maxs[ii] = tmpmax;
      if (tmpmax > dv->maxval)
         dv->maxval = tmpmax;
      dv->mins[ii] = tmpmin;
      if (tmpmin < dv->minval)
         dv->minval = tmpmin;
   }
   vect_free(tmpchunk);
   offset = dv->lon;
   if (zoomlevel > 0) {
      for (ii = 0, offset = dv->lon; ii < dv->numsamps; ii++, offset++)
         *(dv->vals + ii) = *(dp->data + offset);
   }
   return dv;
}
Beispiel #3
0
ffdotpows *subharm_ffdot_plane(int numharm, int harmnum,
                               double fullrlo, double fullrhi,
                               subharminfo * shi, accelobs * obs)
{
   int ii, lobin, hibin, numdata, nice_numdata, nrs, fftlen, binoffset;
   static int numrs_full = 0, numzs_full = 0;
   float powargr, powargi;
   double drlo, drhi, harm_fract;
   ffdotpows *ffdot;
   fcomplex *data, **result;
   presto_datainf datainf;

   if (numrs_full == 0) {
      if (numharm == 1 && harmnum == 1) {
         numrs_full = ACCEL_USELEN;
         numzs_full = shi->numkern;
      } else {
         printf("You must call subharm_ffdot_plane() with numharm=1 and\n");
         printf("harnum=1 before you use other values!  Exiting.\n\n");
         exit(0);
      }
   }
   ffdot = (ffdotpows *) malloc(sizeof(ffdotpows));

   /* Calculate and get the required amplitudes */

   harm_fract = (double) harmnum / (double) numharm;
   drlo = calc_required_r(harm_fract, fullrlo);
   drhi = calc_required_r(harm_fract, fullrhi);
   ffdot->rlo = (int) floor(drlo);
   ffdot->zlo = calc_required_z(harm_fract, obs->zlo);

   /* Initialize the lookup indices */
   if (numharm > 1) {
      double rr, subr;
      for (ii = 0; ii < numrs_full; ii++) {
         rr = fullrlo + ii * ACCEL_DR;
         subr = calc_required_r(harm_fract, rr);
         shi->rinds[ii] = index_from_r(subr, ffdot->rlo);
      }
   }
   ffdot->rinds = shi->rinds;
   ffdot->numrs = (int) ((ceil(drhi) - floor(drlo))
                         * ACCEL_RDR + DBLCORRECT) + 1;
   if (numharm == 1 && harmnum == 1) {
      ffdot->numrs = ACCEL_USELEN;
   } else {
      if (ffdot->numrs % ACCEL_RDR) {
         ffdot->numrs = (ffdot->numrs / ACCEL_RDR + 1) * ACCEL_RDR;
      }
   }
   ffdot->numzs = shi->numkern;
   binoffset = shi->kern[0].kern_half_width;
   fftlen = shi->kern[0].fftlen;
   lobin = ffdot->rlo - binoffset;
   hibin = (int) ceil(drhi) + binoffset;
   numdata = hibin - lobin + 1;
   nice_numdata = next2_to_n(numdata);  // for FFTs
   data = get_fourier_amplitudes(lobin, nice_numdata, obs);
   if (!obs->mmap_file && !obs->dat_input && 0)
       printf("This is newly malloc'd!\n");

   // Normalize the Fourier amplitudes

   if (obs->nph > 0.0) {
       //  Use freq 0 normalization if requested (i.e. photons)
       double norm = 1.0 / sqrt(obs->nph);
       for (ii = 0; ii < numdata; ii++) {
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
   } else if (obs->norm_type == 0) {
       //  old-style block median normalization
       float *powers;
       double norm;

       powers = gen_fvect(numdata);
       for (ii = 0; ii < numdata; ii++)
           powers[ii] = POWER(data[ii].r, data[ii].i);
       norm = 1.0 / sqrt(median(powers, numdata)/log(2.0));
       free(powers);
       for (ii = 0; ii < numdata; ii++) {
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
   } else {
       //  new-style running double-tophat local-power normalization
       float *powers, *loc_powers;

       powers = gen_fvect(nice_numdata);
       for (ii = 0; ii < nice_numdata; ii++) {
           powers[ii] = POWER(data[ii].r, data[ii].i);
       }
       loc_powers = corr_loc_pow(powers, nice_numdata);
       for (ii = 0; ii < numdata; ii++) {
           float norm = invsqrt(loc_powers[ii]);
           data[ii].r *= norm;
           data[ii].i *= norm;
       }
       free(powers);
       free(loc_powers);
   }

   /* Perform the correlations */

   result = gen_cmatrix(ffdot->numzs, ffdot->numrs);
   datainf = RAW;
   for (ii = 0; ii < ffdot->numzs; ii++) {
      nrs = corr_complex(data, numdata, datainf,
                         shi->kern[ii].data, fftlen, FFT,
                         result[ii], ffdot->numrs, binoffset,
                         ACCEL_NUMBETWEEN, binoffset, CORR);
      datainf = SAME;
   }

   // Always free data
   free(data);

   /* Convert the amplitudes to normalized powers */

   ffdot->powers = gen_fmatrix(ffdot->numzs, ffdot->numrs);
   for (ii = 0; ii < (ffdot->numzs * ffdot->numrs); ii++)
      ffdot->powers[0][ii] = POWER(result[0][ii].r, result[0][ii].i);
   free(result[0]);
   free(result);
   return ffdot;
}
Beispiel #4
0
int main(int argc, char *argv[])
{
   float maxpow = 0.0, inx = 0.0, iny = 0.0;
   double centerr, offsetf;
   int zoomlevel, maxzoom, minzoom, xid, psid;
   char *rootfilenm, inchar;
   fftpart *lofp;
   fftview *fv;

   if (argc == 1) {
      printf("\nusage:  explorefft fftfilename\n\n");
      exit(0);
   }

   printf("\n\n");
   printf("      Interactive FFT Explorer\n");
   printf("         by Scott M. Ransom\n");
   printf("            October, 2001\n");
   print_help();

   {
      int hassuffix = 0;
      char *suffix;

      hassuffix = split_root_suffix(argv[1], &rootfilenm, &suffix);
      if (hassuffix) {
         if (strcmp(suffix, "fft") != 0) {
            printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", argv[1]);
            free(suffix);
            exit(0);
         }
         free(suffix);
      } else {
         printf("\nInput file ('%s') must be a FFT file ('.fft')!\n\n", argv[1]);
         exit(0);
      }
   }

   /* Read the info file */

   readinf(&idata, rootfilenm);
   if (strlen(remove_whitespace(idata.object)) > 0) {
      printf("Examining %s data from '%s'.\n\n",
             remove_whitespace(idata.object), argv[1]);
   } else {
      printf("Examining data from '%s'.\n\n", argv[1]);
   }
   N = idata.N;
   T = idata.dt * idata.N;
#ifdef USEMMAP
   printf("Memory mapping the input FFT.  This may take a while...\n");
   mmap_file = open(argv[1], O_RDONLY);
   {
      int rt;
      struct stat buf;

      rt = fstat(mmap_file, &buf);
      if (rt == -1) {
         perror("\nError in fstat() in explorefft.c");
         printf("\n");
         exit(-1);
      }
      Nfft = buf.st_size / sizeof(fcomplex);
   }
   lofp = get_fftpart(0, Nfft);
#else
   {
      int numamps;

      fftfile = chkfopen(argv[1], "rb");
      Nfft = chkfilelen(fftfile, sizeof(fcomplex));
      numamps = (Nfft > MAXBINS) ? (int) MAXBINS : (int) Nfft;
      lofp = get_fftpart(0, numamps);
   }
#endif

   /* Plot the initial data */

   {
      int initnumbins = INITIALNUMBINS;

      if (initnumbins > Nfft) {
         initnumbins = next2_to_n(Nfft) / 2;
         zoomlevel = LOGDISPLAYNUM - (int) (log(initnumbins) / log(2.0));
         minzoom = zoomlevel;
      } else {
         zoomlevel = LOGDISPLAYNUM - LOGINITIALNUMBINS;
         minzoom = LOGDISPLAYNUM - LOGMAXBINS;
      }
      maxzoom = LOGDISPLAYNUM - LOGMINBINS;
      centerr = initnumbins / 2;
   }
   fv = get_fftview(centerr, zoomlevel, lofp);

   /* Prep the XWIN device for PGPLOT */

   xid = cpgopen("/XWIN");
   if (xid <= 0) {
      free(fv);
#ifdef USEMMAP
      close(mmap_file);
#else
      fclose(fftfile);
#endif
      free_fftpart(lofp);
      exit(EXIT_FAILURE);
   }
   cpgscr(15, 0.4, 0.4, 0.4);
   cpgask(0);
   cpgpage();
   offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);

   do {
      cpgcurs(&inx, &iny, &inchar);
      if (DEBUGOUT)
         printf("You pressed '%c'\n", inchar);

      switch (inchar) {
      case 'A':                /* Zoom in */
      case 'a':
         centerr = (inx + offsetf) * T;
      case 'I':
      case 'i':
         if (DEBUGOUT)
            printf("  Zooming in  (zoomlevel = %d)...\n", zoomlevel);
         if (zoomlevel < maxzoom) {
            zoomlevel++;
            free(fv);
            fv = get_fftview(centerr, zoomlevel, lofp);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         } else
            printf("  Already at maximum zoom level (%d).\n", zoomlevel);
         break;
      case 'X':                /* Zoom out */
      case 'x':
      case 'O':
      case 'o':
         if (DEBUGOUT)
            printf("  Zooming out  (zoomlevel = %d)...\n", zoomlevel);
         if (zoomlevel > minzoom) {
            zoomlevel--;
            free(fv);
            fv = get_fftview(centerr, zoomlevel, lofp);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         } else
            printf("  Already at minimum zoom level (%d).\n", zoomlevel);
         break;
      case '<':                /* Shift left 1 full screen */
         centerr -= fv->numbins + fv->numbins / 8;
      case ',':                /* Shift left 1/8 screen */
         if (DEBUGOUT)
            printf("  Shifting left...\n");
         centerr -= fv->numbins / 8;
         {                      /* Should probably get the previous chunk from the fftfile... */
            double lowestr;

            lowestr = 0.5 * fv->numbins;
            if (centerr < lowestr)
               centerr = lowestr;
         }
         free(fv);
         fv = get_fftview(centerr, zoomlevel, lofp);
         cpgpage();
         offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         break;
      case '>':                /* Shift right 1 full screen */
         centerr += fv->numbins - fv->numbins / 8;
      case '.':                /* Shift right 1/8 screen */
         if (DEBUGOUT)
            printf("  Shifting right...\n");
         centerr += fv->numbins / 8;
         {                      /* Should probably get the next chunk from the fftfile... */
            double highestr;

            highestr = lofp->rlo + lofp->numamps - 0.5 * fv->numbins;
            if (centerr > highestr)
               centerr = highestr;
         }
         free(fv);
         fv = get_fftview(centerr, zoomlevel, lofp);
         cpgpage();
         offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         break;
      case '+':                /* Increase height of powers */
      case '=':
         if (maxpow == 0.0) {
            printf("  Auto-scaling is off.\n");
            maxpow = 1.1 * fv->maxpow;
         }
         maxpow = 3.0 / 4.0 * maxpow;
         cpgpage();
         offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         break;
      case '-':                /* Decrease height of powers */
      case '_':
         if (maxpow == 0.0) {
            printf("  Auto-scaling is off.\n");
            maxpow = 1.1 * fv->maxpow;
         }
         maxpow = 4.0 / 3.0 * maxpow;
         cpgpage();
         offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         break;
      case 'S':                /* Auto-scale */
      case 's':
         if (maxpow == 0.0)
            break;
         else {
            printf("  Auto-scaling is on.\n");
            maxpow = 0.0;
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
            break;
         }
      case 'G':                /* Goto a frequency */
      case 'g':
         {
            char freqstr[50];
            double freq = -1.0;

            while (freq < 0.0) {
               printf("  Enter the frequency (Hz) to go to:\n");
               fgets(freqstr, 50, stdin);
               freqstr[strlen(freqstr) - 1] = '\0';
               freq = atof(freqstr);
            }
            offsetf = 0.0;
            centerr = freq * T;
            printf("  Moving to frequency %.15g.\n", freq);
            free(fv);
            fv = get_fftview(centerr, zoomlevel, lofp);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2);
         }
         break;
      case 'H':                /* Show harmonics */
      case 'h':
         {
            double retval;

            retval = harmonic_loop(xid, centerr, zoomlevel, lofp);
            if (retval > 0.0) {
               offsetf = 0.0;
               centerr = retval;
               free(fv);
               fv = get_fftview(centerr, zoomlevel, lofp);
               cpgpage();
               offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2);
            }
         }
         break;
      case '?':                /* Print help screen */
         print_help();
         break;
      case 'D':                /* Show details about a selected point  */
      case 'd':
         {
            double newr;

            printf("  Searching for peak near freq = %.7g Hz...\n", (inx + offsetf));
            newr = find_peak(inx + offsetf, fv, lofp);
            centerr = newr;
            free(fv);
            fv = get_fftview(centerr, zoomlevel, lofp);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, centerr, 2);
         }
         break;
      case 'L':                /* Load a zaplist */
      case 'l':
         {
            int ii, len;
            char filename[200];
            double *lobins, *hibins;

            printf("  Enter the filename containing the zaplist to load:\n");
            fgets(filename, 199, stdin);
            len = strlen(filename) - 1;
            filename[len] = '\0';
            numzaplist = get_birdies(filename, T, 0.0, &lobins, &hibins);
            lenzaplist = numzaplist + 20;       /* Allow some room to add more */
            if (lenzaplist)
               free(zaplist);
            zaplist = (bird *) malloc(sizeof(bird) * lenzaplist);
            for (ii = 0; ii < numzaplist; ii++) {
               zaplist[ii].lobin = lobins[ii];
               zaplist[ii].hibin = hibins[ii];
            }
            vect_free(lobins);
            vect_free(hibins);
            printf("\n");
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         }
         break;
      case 'Z':                /* Add a birdie to a zaplist */
      case 'z':
         {
            int badchoice = 2;
            float lox, hix, loy, hiy;
            double rs[2];
            char choice;

            if (numzaplist + 1 > lenzaplist) {
               lenzaplist += 10;
               zaplist = (bird *) realloc(zaplist, sizeof(bird) * lenzaplist);
            }
            cpgqwin(&lox, &hix, &loy, &hiy);
            printf("  Click the left mouse button on the first frequency limit.\n");
            while (badchoice) {
               cpgcurs(&inx, &iny, &choice);
               if (choice == 'A' || choice == 'a') {
                  rs[2 - badchoice] = ((double) inx + offsetf) * T;
                  cpgsave();
                  cpgsci(7);
                  cpgmove(inx, 0.0);
                  cpgdraw(inx, hiy);
                  cpgunsa();
                  badchoice--;
                  if (badchoice == 1)
                     printf
                         ("  Click the left mouse button on the second frequency limit.\n");
               } else {
                  printf("  Option not recognized.\n");
               }
            };
            if (rs[1] > rs[0]) {
               zaplist[numzaplist].lobin = rs[0];
               zaplist[numzaplist].hibin = rs[1];
            } else {
               zaplist[numzaplist].lobin = rs[1];
               zaplist[numzaplist].hibin = rs[0];
            }
            printf("    The new birdie has:  f_avg = %.15g  f_width = %.15g\n\n",
                   0.5 * (zaplist[numzaplist].hibin + zaplist[numzaplist].lobin) / T,
                   (zaplist[numzaplist].hibin - zaplist[numzaplist].lobin) / T);
            numzaplist++;
            qsort(zaplist, numzaplist, sizeof(bird), compare_birds);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         }
         break;
      case 'P':                /* Print the current plot */
      case 'p':
         {
            int len;
            char filename[200];

            printf("  Enter the filename to save the plot as:\n");
            fgets(filename, 196, stdin);
            len = strlen(filename) - 1;
            filename[len + 0] = '/';
            filename[len + 1] = 'P';
            filename[len + 2] = 'S';
            filename[len + 3] = '\0';
            psid = cpgopen(filename);
            cpgslct(psid);
            cpgpap(10.25, 8.5 / 11.0);
            cpgiden();
            cpgscr(15, 0.8, 0.8, 0.8);
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
            cpgclos();
            cpgslct(xid);
            cpgscr(15, 0.4, 0.4, 0.4);
            filename[len] = '\0';
            printf("  Wrote the plot to the file '%s'.\n", filename);
         }
         break;
      case 'N':                /* Changing power normalization */
      case 'n':
         {
            float inx2 = 0.0, iny2 = 0.0;
            char choice;
            unsigned char badchoice = 1;

            printf("  Specify the type of power normalization:\n"
                   "       m,M  :  Median values determined locally\n"
                   "       d,D  :  DC frequency amplitude\n"
                   "       r,R  :  Raw powers (i.e. no normalization)\n"
                   "       u,U  :  User specified interval (the average powers)\n");
            while (badchoice) {
               cpgcurs(&inx2, &iny2, &choice);
               switch (choice) {
               case 'M':
               case 'm':
                  norm_const = 0.0;
                  maxpow = 0.0;
                  badchoice = 0;
                  printf
                      ("  Using local median normalization.  Autoscaling is on.\n");
                  break;
               case 'D':
               case 'd':
                  norm_const = 1.0 / r0;
                  maxpow = 0.0;
                  badchoice = 0;
                  printf
                      ("  Using DC frequency (%f) normalization.  Autoscaling is on.\n",
                       r0);
                  break;
               case 'R':
               case 'r':
                  norm_const = 1.0;
                  maxpow = 0.0;
                  badchoice = 0;
                  printf
                      ("  Using raw powers (i.e. no normalization).  Autoscaling is on.\n");
                  break;
               case 'U':
               case 'u':
                  {
                     char choice2;
                     float xx = inx, yy = iny;
                     int lor, hir, numr;
                     double avg, var;

                     printf
                         ("  Use the left mouse button to select a left and right boundary\n"
                          "  of a region to calculate the average power.\n");
                     do {
                        cpgcurs(&xx, &yy, &choice2);
                     } while (choice2 != 'A' && choice2 != 'a');
                     lor = (int) ((xx + offsetf) * T);
                     cpgsci(7);
                     cpgmove(xx, 0.0);
                     cpgdraw(xx, 10.0 * fv->maxpow);
                     do {
                        cpgcurs(&xx, &yy, &choice2);
                     } while (choice2 != 'A' && choice2 != 'a');
                     hir = (int) ((xx + offsetf) * T);
                     cpgmove(xx, 0.0);
                     cpgdraw(xx, 10.0 * fv->maxpow);
                     cpgsci(1);
                     if (lor > hir) {
                        int tempr;
                        tempr = hir;
                        hir = lor;
                        lor = tempr;
                     }
                     numr = hir - lor + 1;
                     avg_var(lofp->rawpowers + lor - lofp->rlo, numr, &avg, &var);
                     printf("  Selection has:  average = %.5g\n"
                            "                  std dev = %.5g\n", avg, sqrt(var));
                     norm_const = 1.0 / avg;
                     maxpow = 0.0;
                     badchoice = 0;
                     printf
                         ("  Using %.5g as the normalization constant.  Autoscaling is on.\n",
                          avg);
                     break;
                  }
               default:
                  printf("  Unrecognized choice '%c'.\n", choice);
                  break;
               }
            }
            free(fv);
            fv = get_fftview(centerr, zoomlevel, lofp);
            cpgpage();
            offsetf = plot_fftview(fv, maxpow, 1.0, 0.0, 0);
         }
         break;
      case 'Q':                /* Quit */
      case 'q':
         printf("  Quitting...\n");
         free(fv);
         cpgclos();
         break;
      default:
         printf("  Unrecognized option '%c'.\n", inchar);
         break;
      }
   } while (inchar != 'Q' && inchar != 'q');

   free_fftpart(lofp);
#ifdef USEMMAP
   close(mmap_file);
#else
   fclose(fftfile);
#endif
   if (lenzaplist)
      free(zaplist);
   printf("Done\n\n");
   return 0;
}