Beispiel #1
0
static datapart *get_datapart(int nlo, int numn)
{
   datapart *dp;

   if (nlo + numn > Ndat)
      return NULL;
   else {
      dp = (datapart *) malloc(sizeof(datapart));
      dp->nn = numn;
      dp->nlo = nlo;
      dp->tlo = idata.dt * nlo;
#ifdef USEMMAP
      dp->data = (float *) mmap(0, sizeof(float) * numn, PROT_READ,
                                MAP_SHARED, mmap_file, 0);
#else
      dp->data = read_float_file(datfile, nlo, numn);
#endif
      return dp;
   }
}
Beispiel #2
0
void create_accelobs(accelobs * obs, infodata * idata, Cmdline * cmd, int usemmap)
{
   int ii, rootlen, input_shorts = 0;

   {
      int hassuffix = 0;
      char *suffix;

      hassuffix = split_root_suffix(cmd->argv[0], &(obs->rootfilenm), &suffix);
      if (hassuffix) {
         if (strcmp(suffix, "fft") != 0 &&
             strcmp(suffix, "dat") != 0 && strcmp(suffix, "sdat") != 0) {
            printf("\nInput file ('%s') must be an '.fft' or '.[s]dat' file!\n\n",
                   cmd->argv[0]);
            free(suffix);
            exit(0);
         }
         /* If the input file is a time series */
         if (strcmp(suffix, "dat") == 0 || strcmp(suffix, "sdat") == 0) {
            obs->dat_input = 1;
            obs->mmap_file = 0;
            if (strcmp(suffix, "sdat") == 0)
               input_shorts = 1;
         } else {
            obs->dat_input = 0;
         }
         free(suffix);
      } else {
         printf("\nInput file ('%s') must be an '.fft' or '.[s]dat' file!\n\n",
                cmd->argv[0]);
         exit(0);
      }
   }

   if (cmd->noharmpolishP)
       obs->use_harmonic_polishing = 0;
   else
       obs->use_harmonic_polishing = 1;  // now default

   /* Read the info file */

   readinf(idata, obs->rootfilenm);
   if (idata->object) {
      printf("Analyzing %s data from '%s'.\n\n",
             remove_whitespace(idata->object), cmd->argv[0]);
   } else {
      printf("Analyzing data from '%s'.\n\n", cmd->argv[0]);
   }

   /* Prepare the input time series if required */

   if (obs->dat_input) {
      FILE *datfile;
      long long filelen;
      float *ftmp;

      printf("Reading and FFTing the time series...");
      fflush(NULL);
      datfile = chkfopen(cmd->argv[0], "rb");

      /* Check the length of the file to see if we can handle it */
      filelen = chkfilelen(datfile, sizeof(float));
      if (input_shorts)
         filelen *= 2;
      if (filelen > 67108864) { /* Small since we need memory for the templates */
         printf("\nThe input time series is too large.  Use 'realfft' first.\n\n");
         exit(0);
      }

      /* Read the time series into a temporary buffer */
      /* Note:  The padding allows us to search very short time series */
      /*        using correlations without having to worry about       */
      /*        accessing data before or after the valid FFT freqs.    */
      if (input_shorts) {
         short *stmp = gen_svect(filelen);
         ftmp = gen_fvect(filelen+2*ACCEL_PADDING);
         for (ii = 0; ii < ACCEL_PADDING; ii++) {
             ftmp[ii] = 0.0;
             ftmp[ii+filelen+ACCEL_PADDING] = 0.0;
         }
         chkfread(stmp, sizeof(short), filelen, datfile);
         for (ii = 0; ii < filelen; ii++)
            ftmp[ii+ACCEL_PADDING] = (float) stmp[ii];
         free(stmp);
      } else {
         ftmp = read_float_file(datfile, -ACCEL_PADDING, filelen+2*ACCEL_PADDING);
      }
      /* Now, offset the pointer so that we are pointing at the first */
      /* bits of valid data.                                          */
      ftmp += ACCEL_PADDING;
      fclose(datfile);

      /* FFT it */
      realfft(ftmp, filelen, -1);
      obs->fftfile = NULL;
      obs->fft = (fcomplex *) ftmp;
      obs->numbins = filelen / 2;
      printf("done.\n");

      /* De-redden it */
      printf("Removing red-noise...");
      deredden(obs->fft, obs->numbins);
      printf("done.\n\n");
   }

   /* Determine the output filenames */

   rootlen = strlen(obs->rootfilenm) + 25;
   obs->candnm = (char *) calloc(rootlen, 1);
   obs->accelnm = (char *) calloc(rootlen, 1);
   obs->workfilenm = (char *) calloc(rootlen, 1);
   sprintf(obs->candnm, "%s_ACCEL_%d.cand", obs->rootfilenm, cmd->zmax);
   sprintf(obs->accelnm, "%s_ACCEL_%d", obs->rootfilenm, cmd->zmax);
   sprintf(obs->workfilenm, "%s_ACCEL_%d.txtcand", obs->rootfilenm, cmd->zmax);

   /* Open the FFT file if it exists appropriately */
   if (!obs->dat_input) {
      obs->fftfile = chkfopen(cmd->argv[0], "rb");
      obs->numbins = chkfilelen(obs->fftfile, sizeof(fcomplex));
      if (usemmap) {
         fclose(obs->fftfile);
         obs->fftfile = NULL;
         printf("Memory mapping the input FFT.  This may take a while...\n");
         obs->mmap_file = open(cmd->argv[0], O_RDONLY);
         if (obs->mmap_file == -1) {
            perror("\nError in open() in accel_utils.c");
            printf("\n");
            exit(-1);
         }
         obs->fft = (fcomplex *) mmap(0, sizeof(fcomplex) * obs->numbins, PROT_READ,
                                      MAP_SHARED, obs->mmap_file, 0);
         if (obs->fft == MAP_FAILED) {
            perror("\nError in mmap() in accel_utils.c");
            printf("Falling back to a non-mmaped approach\n");
            obs->fftfile = chkfopen(cmd->argv[0], "rb");
            obs->mmap_file = 0;
         }
      } else {
         obs->mmap_file = 0;
      }
   }

   /* Determine the other parameters */

   if (cmd->zmax % ACCEL_DZ)
      cmd->zmax = (cmd->zmax / ACCEL_DZ + 1) * ACCEL_DZ;
   if (!obs->dat_input)
      obs->workfile = chkfopen(obs->workfilenm, "w");
   obs->N = (long long) idata->N;
   if (cmd->photonP) {
      if (obs->mmap_file || obs->dat_input) {
         obs->nph = obs->fft[0].r;
      } else {
         obs->nph = get_numphotons(obs->fftfile);
      }
      printf("Normalizing powers using %.0f photons.\n\n", obs->nph);
   } else {
      obs->nph = 0.0;
      /* For short FFTs insure that we don't pick up the DC */
      /* or Nyquist component as part of the interpolation  */
      /* for higher frequencies.                            */
      if (cmd->locpowP) {
          obs->norm_type = 1;
          printf("Normalizing powers using local-power determination.\n\n");
      } else if (cmd->medianP) {
          obs->norm_type = 0;
          printf("Normalizing powers using median-blocks.\n\n");
      } else {
          obs->norm_type = 0;
          printf("Normalizing powers using median-blocks (default).\n\n");
      }
      if (obs->dat_input) {
         obs->fft[0].r = 1.0;
         obs->fft[0].i = 1.0;
      }
   }
   obs->lobin = cmd->lobin;
   if (obs->lobin > 0) {
      obs->nph = 0.0;
      if (cmd->lobin > obs->numbins - 1) {
         printf("\n'lobin' is greater than the total number of\n");
         printf("   frequencies in the data set.  Exiting.\n\n");
         exit(1);
      }
   }
   if (cmd->numharm != 1 &&
       cmd->numharm != 2 &&
       cmd->numharm != 4 && cmd->numharm != 8 && cmd->numharm != 16) {
      printf("\n'numharm' = %d must be a power-of-two!  Exiting\n\n", cmd->numharm);
      exit(1);
   }
   obs->numharmstages = twon_to_index(cmd->numharm) + 1;
   obs->dz = ACCEL_DZ;
   obs->numz = cmd->zmax * 2 + 1;
   obs->numbetween = ACCEL_NUMBETWEEN;
   obs->dt = idata->dt;
   obs->T = idata->dt * idata->N;
   if (cmd->floP) {
      obs->rlo = floor(cmd->flo * obs->T);
      if (obs->rlo < obs->lobin)
         obs->rlo = obs->lobin;
      if (obs->rlo > obs->numbins - 1) {
         printf("\nLow frequency to search 'flo' is greater than\n");
         printf("   the highest available frequency.  Exiting.\n\n");
         exit(1);
      }
   } else {
      if (cmd->rloP)
         obs->rlo = cmd->rlo;
      else
         obs->rlo = 1.0;
      if (obs->rlo < obs->lobin)
         obs->rlo = obs->lobin;
      if (obs->rlo > obs->numbins - 1) {
         printf("\nLow frequency to search 'rlo' is greater than\n");
         printf("   the available number of points.  Exiting.\n\n");
         exit(1);
      }
   }
   obs->highestbin = obs->numbins - 1;
   if (cmd->fhiP) {
      obs->highestbin = ceil(cmd->fhi * obs->T);
      if (obs->highestbin > obs->numbins - 1)
         obs->highestbin = obs->numbins - 1;
      obs->rhi = obs->highestbin;
      if (obs->highestbin < obs->rlo) {
         printf("\nHigh frequency to search 'fhi' is less than\n");
         printf("   the lowest frequency to search 'flo'.  Exiting.\n\n");
         exit(1);
      }
   } else if (cmd->rhiP) {
      obs->highestbin = cmd->rhi;
      if (obs->highestbin > obs->numbins - 1)
         obs->highestbin = obs->numbins - 1;
      obs->rhi = obs->highestbin;
      if (obs->highestbin < obs->rlo) {
         printf("\nHigh frequency to search 'rhi' is less than\n");
         printf("   the lowest frequency to search 'rlo'.  Exiting.\n\n");
         exit(1);
      }
   }
   obs->dr = ACCEL_DR;
   obs->zhi = cmd->zmax;
   obs->zlo = -cmd->zmax;
   obs->sigma = cmd->sigma;
   obs->powcut = (float *) malloc(obs->numharmstages * sizeof(float));
   obs->numindep = (long long *) malloc(obs->numharmstages * sizeof(long long));
   for (ii = 0; ii < obs->numharmstages; ii++) {
      if (obs->numz == 1)
         obs->numindep[ii] = (obs->rhi - obs->rlo) / index_to_twon(ii);
      else
         /* The numz+1 takes care of the small amount of  */
         /* search we get above zmax and below zmin.      */
         obs->numindep[ii] = (obs->rhi - obs->rlo) * (obs->numz + 1) *
             (obs->dz / 6.95) / index_to_twon(ii);
      obs->powcut[ii] = power_for_sigma(obs->sigma,
                                        index_to_twon(ii), obs->numindep[ii]);
   }
   obs->numzap = 0;
   /*
      if (zapfile!=NULL)
      obs->numzap = get_birdies(cmd->zapfile, obs->T, obs->baryv, 
      &(obs->lobins), &(obs->hibins));
      else
      obs->numzap = 0;
    */
}
Beispiel #3
0
int main(int argc, char *argv[])
{
   FILE *fftfile, *candfile;
   float powargr, powargi, *powers = NULL, *minifft;
   float norm, numchunks, *powers_pos;
   int nbins, newncand, nfftsizes, fftlen, halffftlen, binsleft;
   int numtoread, filepos = 0, loopct = 0, powers_offset, ncand2;
   int ii, ct, newper = 0, oldper = 0, numsumpow = 1;
   double T, totnumsearched = 0.0, minsig = 0.0, min_orb_p, max_orb_p;
   char *rootfilenm, *notes;
   fcomplex *data = NULL;
   rawbincand tmplist[MININCANDS], *list;
   infodata idata;
   struct tms runtimes;
   double ttim, utim, stim, tott;
   Cmdline *cmd;
   fftwf_plan fftplan;

   /* Prep the timer */

   tott = times(&runtimes) / (double) CLK_TCK;

   /* 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("     Phase Modulation Pulsar Search Routine\n");
   printf("              by Scott M. Ransom\n\n");

   {
      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);
   T = idata.N * idata.dt;
   if (strlen(remove_whitespace(idata.object)) > 0) {
      printf("Analyzing '%s' data from '%s'.\n\n",
             remove_whitespace(idata.object), cmd->argv[0]);
   } else {
      printf("Analyzing data from '%s'.\n\n", cmd->argv[0]);
   }
   min_orb_p = MINORBP;
   if (cmd->noaliasP)
      max_orb_p = T / 2.0;
   else
      max_orb_p = T / 1.2;

   /* open the FFT file and get its length */

   fftfile = chkfopen(cmd->argv[0], "rb");
   nbins = chkfilelen(fftfile, sizeof(fcomplex));

   /* Check that cmd->maxfft is an acceptable power of 2 */

   ct = 4;
   ii = 1;
   while (ct < MAXREALFFT || ii) {
      if (ct == cmd->maxfft)
         ii = 0;
      ct <<= 1;
   }
   if (ii) {
      printf("\n'maxfft' is out of range or not a power-of-2.\n\n");
      exit(1);
   }

   /* Check that cmd->minfft is an acceptable power of 2 */

   ct = 4;
   ii = 1;
   while (ct < MAXREALFFT || ii) {
      if (ct == cmd->minfft)
         ii = 0;
      ct <<= 1;
   }
   if (ii) {
      printf("\n'minfft' is out of range or not a power-of-2.\n\n");
      exit(1);
   }

   /* Low and high Fourier freqs to check */

   if (cmd->floP) {
      cmd->rlo = floor(cmd->flo * T);
      if (cmd->rlo < cmd->lobin)
         cmd->rlo = cmd->lobin;
      if (cmd->rlo > cmd->lobin + nbins - 1) {
         printf("\nLow frequency to search 'flo' is greater than\n");
         printf("   the highest available frequency.  Exiting.\n\n");
         exit(1);
      }
   } else {
      cmd->rlo = 1.0;
      if (cmd->rlo < cmd->lobin)
         cmd->rlo = cmd->lobin;
      if (cmd->rlo > cmd->lobin + nbins - 1) {
         printf("\nLow frequency to search 'rlo' is greater than\n");
         printf("   the available number of points.  Exiting.\n\n");
         exit(1);
      }
   }
   if (cmd->fhiP) {
      cmd->rhi = ceil(cmd->fhi * T);
      if (cmd->rhi > cmd->lobin + nbins - 1)
         cmd->rhi = cmd->lobin + nbins - 1;
      if (cmd->rhi < cmd->rlo) {
         printf("\nHigh frequency to search 'fhi' is less than\n");
         printf("   the lowest frequency to search 'flo'.  Exiting.\n\n");
         exit(1);
      }
   } else if (cmd->rhiP) {
      if (cmd->rhi > cmd->lobin + nbins - 1)
         cmd->rhi = cmd->lobin + nbins - 1;
      if (cmd->rhi < cmd->rlo) {
         printf("\nHigh frequency to search 'rhi' is less than\n");
         printf("   the lowest frequency to search 'rlo'.  Exiting.\n\n");
         exit(1);
      }
   }

   /* Determine how many different mini-fft sizes we will use */

   nfftsizes = 1;
   ii = cmd->maxfft;
   while (ii > cmd->minfft) {
      ii >>= 1;
      nfftsizes++;
   }

   /* Allocate some memory and prep some variables.             */
   /* For numtoread, the 6 just lets us read extra data at once */

   numtoread = 6 * cmd->maxfft;
   if (cmd->stack == 0)
      powers = gen_fvect(numtoread);
   minifft = (float *) fftwf_malloc(sizeof(float) *
                                    (cmd->maxfft * cmd->numbetween + 2));
   ncand2 = 2 * cmd->ncand;
   list = (rawbincand *) malloc(sizeof(rawbincand) * ncand2);
   for (ii = 0; ii < ncand2; ii++)
      list[ii].mini_sigma = 0.0;
   for (ii = 0; ii < MININCANDS; ii++)
      tmplist[ii].mini_sigma = 0.0;
   filepos = cmd->rlo - cmd->lobin;
   numchunks = (float) (cmd->rhi - cmd->rlo) / numtoread;
   printf("Searching...\n");
   printf("   Amount complete = %3d%%", 0);
   fflush(stdout);

   /* Prep FFTW */
   read_wisdom();

   /* Loop through fftfile */

   while ((filepos + cmd->lobin) < cmd->rhi) {

      /* Calculate percentage complete */

      newper = (int) (loopct / numchunks * 100.0);

      if (newper > oldper) {
         newper = (newper > 99) ? 100 : newper;
         printf("\r   Amount complete = %3d%%", newper);
         oldper = newper;
         fflush(stdout);
      }

      /* Adjust our search parameters if close to end of zone to search */

      binsleft = cmd->rhi - (filepos + cmd->lobin);
      if (binsleft < cmd->minfft)
         break;
      if (binsleft < numtoread) {       /* Change numtoread */
         numtoread = cmd->maxfft;
         while (binsleft < numtoread) {
            cmd->maxfft /= 2;
            numtoread = cmd->maxfft;
         }
      }
      fftlen = cmd->maxfft;

      /* Read from fftfile */

      if (cmd->stack == 0) {
         data = read_fcomplex_file(fftfile, filepos, numtoread);
         for (ii = 0; ii < numtoread; ii++)
            powers[ii] = POWER(data[ii].r, data[ii].i);
         numsumpow = 1;
      } else {
         powers = read_float_file(fftfile, filepos, numtoread);
         numsumpow = cmd->stack;
      }
      if (filepos == 0)
         powers[0] = 1.0;

      /* Chop the powers that are way above the median level */

      prune_powers(powers, numtoread, numsumpow);

      /* Loop through the different small FFT sizes */

      while (fftlen >= cmd->minfft) {

         halffftlen = fftlen / 2;
         powers_pos = powers;
         powers_offset = 0;

         /* Create the appropriate FFT plan */

         fftplan = fftwf_plan_dft_r2c_1d(cmd->interbinP ? fftlen : 2 * fftlen,
                                         minifft, (fftwf_complex *) minifft,
                                         FFTW_PATIENT);

         /* Perform miniffts at each section of the powers array */

         while ((numtoread - powers_offset) >
                (int) ((1.0 - cmd->overlap) * cmd->maxfft + DBLCORRECT)) {

            /* Copy the proper amount and portion of powers into minifft */

            memcpy(minifft, powers_pos, fftlen * sizeof(float));
            /* For Fourier interpolation use a zeropadded FFT */
            if (cmd->numbetween > 1 && !cmd->interbinP) {
               for (ii = fftlen; ii < cmd->numbetween * fftlen; ii++)
                  minifft[ii] = 0.0;
            }

            /* Perform the minifft */

            fftwf_execute(fftplan);

            /* Normalize and search the miniFFT */

            norm = sqrt(fftlen * numsumpow) / minifft[0];
            for (ii = 0; ii < (cmd->interbinP ? fftlen + 1 : 2 * fftlen + 1); ii++)
               minifft[ii] *= norm;
            search_minifft((fcomplex *) minifft, halffftlen, min_orb_p,
                           max_orb_p, tmplist, MININCANDS, cmd->harmsum,
                           cmd->numbetween, idata.N, T,
                           (double) (powers_offset + filepos + cmd->lobin),
                           cmd->interbinP ? INTERBIN : INTERPOLATE,
                           cmd->noaliasP ? NO_CHECK_ALIASED : CHECK_ALIASED);

            /* Check if the new cands should go into the master cand list */

            for (ii = 0; ii < MININCANDS; ii++) {
               if (tmplist[ii].mini_sigma > minsig) {

                  /* Check to see if another candidate with these properties */
                  /* is already in the list.                                 */

                  if (not_already_there_rawbin(tmplist[ii], list, ncand2)) {
                     list[ncand2 - 1] = tmplist[ii];
                     minsig = percolate_rawbincands(list, ncand2);
                  }
               } else {
                  break;
               }
               /* Mini-fft search for loop */
            }

            totnumsearched += fftlen;
            powers_pos += (int) (cmd->overlap * fftlen);
            powers_offset = powers_pos - powers;

            /* Position of mini-fft in data set while loop */
         }

         fftwf_destroy_plan(fftplan);
         fftlen >>= 1;

         /* Size of mini-fft while loop */
      }

      if (cmd->stack == 0)
         vect_free(data);
      else
         vect_free(powers);
      filepos += (numtoread - (int) ((1.0 - cmd->overlap) * cmd->maxfft));
      loopct++;

      /* File position while loop */
   }

   /* Print the final percentage update */

   printf("\r   Amount complete = %3d%%\n\n", 100);

   /* Print the number of frequencies searched */

   printf("Searched %.0f pts (including interbins).\n\n", totnumsearched);

   printf("Timing summary:\n");
   tott = times(&runtimes) / (double) CLK_TCK - tott;
   utim = runtimes.tms_utime / (double) CLK_TCK;
   stim = runtimes.tms_stime / (double) CLK_TCK;
   ttim = utim + stim;
   printf("    CPU time: %.3f sec (User: %.3f sec, System: %.3f sec)\n",
          ttim, utim, stim);
   printf("  Total time: %.3f sec\n\n", tott);

   printf("Writing result files and cleaning up.\n");

   /* Count how many candidates we actually have */

   ii = 0;
   while (ii < ncand2 && list[ii].mini_sigma != 0)
      ii++;
   newncand = (ii > cmd->ncand) ? cmd->ncand : ii;

   /* Set our candidate notes to all spaces */

   notes = malloc(sizeof(char) * newncand * 18 + 1);
   for (ii = 0; ii < newncand; ii++)
      strncpy(notes + ii * 18, "                     ", 18);

   /* Check the database for possible known PSR detections */

   if (idata.ra_h && idata.dec_d) {
      for (ii = 0; ii < newncand; ii++) {
         comp_rawbin_to_cand(&list[ii], &idata, notes + ii * 18, 0);
      }
   }

   /* Compare the candidates with each other */

   compare_rawbin_cands(list, newncand, notes);

   /* Send the candidates to the text file */

   file_rawbin_candidates(list, notes, newncand, cmd->harmsum, rootfilenm);

   /* Write the binary candidate file */
   {
      char *candnm;

      candnm = (char *) calloc(strlen(rootfilenm) + 15, sizeof(char));
      sprintf(candnm, "%s_bin%d.cand", rootfilenm, cmd->harmsum);
      candfile = chkfopen(candnm, "wb");
      chkfwrite(list, sizeof(rawbincand), (unsigned long) newncand, candfile);
      fclose(candfile);
      free(candnm);
   }

   /* Free our arrays and close our files */

   if (cmd->stack == 0)
      vect_free(powers);
   free(list);
   fftwf_free(minifft);
   free(notes);
   free(rootfilenm);
   fclose(fftfile);
   printf("Done.\n\n");
   return (0);
}