void write_padding(FILE * outfiles[], int numfiles, float value, int numtowrite)
{
    int ii;

    if (numtowrite <= 0) {
        return;
    } else if (numtowrite == 1) {
        for (ii = 0; ii < numfiles; ii++)
            chkfwrite(&value, sizeof(float), 1, outfiles[ii]);
    } else {
        int maxatonce = 8192, veclen, jj;
        float *buffer;
        veclen = (numtowrite > maxatonce) ? maxatonce : numtowrite;
        buffer = gen_fvect(veclen);
        for (ii = 0; ii < veclen; ii++)
            buffer[ii] = value;
        if (veclen == numtowrite) {
            for (ii = 0; ii < numfiles; ii++)
                chkfwrite(buffer, sizeof(float), veclen, outfiles[ii]);
        } else {
            for (ii = 0; ii < numtowrite / veclen; ii++) {
                for (jj = 0; jj < numfiles; jj++)
                    chkfwrite(buffer, sizeof(float), veclen, outfiles[jj]);
            }
            for (jj = 0; jj < numfiles; jj++)
                chkfwrite(buffer, sizeof(float), numtowrite % veclen, outfiles[jj]);
        }
        vect_free(buffer);
    }
}
Beispiel #2
0
int fwrite_multifile(void *data, size_t type, size_t number, multifile * mfile)
/* Write binary data to a multifile.                         */
/*   'data' is an array of data to write                     */
/*   'type' is the size of each nugget of data to write      */
/*   'number' is the number of nuggets to write              */
/*   'mfile' is a pointer to a valid multifile structure     */
{
   int findex;
   unsigned long long bytesleft;
   size_t writebytes, tmpwritebytes, byteswritten, tmpbyteswritten;

   findex = mfile->currentfile;
   writebytes = number * type;
   bytesleft = mfile->maxfilelen - mfile->currentpos;
   tmpwritebytes = (writebytes > bytesleft) ? bytesleft : writebytes;
   byteswritten = chkfwrite((char *) data, 1, tmpwritebytes,
                            mfile->fileptrs[findex]);
   mfile->currentpos += byteswritten;
   if (mfile->currentpos > mfile->filelens[findex]) {
      mfile->length += (mfile->currentpos - mfile->filelens[findex]);
      mfile->filelens[findex] = mfile->currentpos;
   }
   mfile->position += byteswritten;
   writebytes -= byteswritten;
   while (writebytes) {
      if (mfile->currentpos == mfile->maxfilelen) {
         if (findex < mfile->numfiles - 1) {
            findex++;
            mfile->currentfile++;
            mfile->currentpos = 0;
            bytesleft = mfile->maxfilelen;
            tmpwritebytes = (writebytes > bytesleft) ? bytesleft : writebytes;
            tmpbyteswritten = chkfwrite((char *) data + byteswritten,
                                        1, tmpwritebytes, mfile->fileptrs[findex]);
            byteswritten += tmpbyteswritten;
            mfile->currentpos += tmpbyteswritten;
            if (mfile->currentpos > mfile->filelens[findex]) {
               mfile->length += (mfile->currentpos - mfile->filelens[findex]);
               mfile->filelens[findex] = mfile->currentpos;
            }
            mfile->position += tmpbyteswritten;
            writebytes -= tmpbyteswritten;
         } else {
            printf("\nWrite error in write_multifile():\n");
            printf("\tMultifile is maximum length!\n\n");
            return byteswritten / type;
         }
      } else {
         printf("\nWrite error in write_multifile():\n");
         printf("\tTried to write %zd bytes, only wrote %zd!\n\n",
                number * type, byteswritten);
         return byteswritten / type;
      }
   }
   return byteswritten / type;
}
void write_data(FILE * outfiles[], int numfiles, float **outdata,
                int startpoint, int numtowrite)
{
    int ii;

    for (ii = 0; ii < numfiles; ii++)
        chkfwrite(outdata[ii] + startpoint, sizeof(float), numtowrite, outfiles[ii]);
}
Beispiel #4
0
static void write_subs(FILE * outfiles[], int numfiles, short **subsdata,
                       int startpoint, int numtowrite)
{
    int ii;

    for (ii = 0; ii < numfiles; ii++)
        chkfwrite(subsdata[ii] + startpoint, sizeof(short), numtowrite,
                  outfiles[ii]);
}
Beispiel #5
0
static void write_statsfile(char *statsfilenm, float *datapow,
                            float *dataavg, float *datastd,
                            int numchan, int numint, int ptsperint,
                            int lobin, int numbetween)
{
   FILE *outfile;

   outfile = chkfopen(statsfilenm, "wb");
   chkfwrite(&numchan, sizeof(int), 1, outfile);
   chkfwrite(&numint, sizeof(int), 1, outfile);
   chkfwrite(&ptsperint, sizeof(int), 1, outfile);
   chkfwrite(&lobin, sizeof(int), 1, outfile);
   chkfwrite(&numbetween, sizeof(int), 1, outfile);
   chkfwrite(datapow, sizeof(float), numchan * numint, outfile);
   chkfwrite(dataavg, sizeof(float), numchan * numint, outfile);
   chkfwrite(datastd, sizeof(float), numchan * numint, outfile);
   fclose(outfile);
}
Beispiel #6
0
static void write_rfifile(char *rfifilenm, rfi * rfivect, int numrfi,
                          int numchan, int numint, int ptsperint,
                          int lobin, int numbetween, int harmsum,
                          float fracterror, float freqsigma)
{
   FILE *outfile;
   int ii;

   outfile = chkfopen(rfifilenm, "wb");
   chkfwrite(&numchan, sizeof(int), 1, outfile);
   chkfwrite(&numint, sizeof(int), 1, outfile);
   chkfwrite(&ptsperint, sizeof(int), 1, outfile);
   chkfwrite(&lobin, sizeof(int), 1, outfile);
   chkfwrite(&numbetween, sizeof(int), 1, outfile);
   chkfwrite(&harmsum, sizeof(int), 1, outfile);
   chkfwrite(&numrfi, sizeof(int), 1, outfile);
   chkfwrite(&fracterror, sizeof(float), 1, outfile);
   chkfwrite(&freqsigma, sizeof(float), 1, outfile);
   for (ii = 0; ii < numrfi; ii++)
      write_rfi(outfile, rfivect + ii, numchan, numint);
   fclose(outfile);
}
Beispiel #7
0
void write_dftvector(dftvector * data, char *filename)
/* Write a dftvector data structure to a binary file */
{
   FILE *outfile;
   int ii;
   double dtmp;

   outfile = chkfopen(filename, "wb");
   dtmp = (double) data->n;
   chkfwrite(&dtmp, sizeof(double), 1, outfile);
   dtmp = (double) data->numvect;
   chkfwrite(&dtmp, sizeof(double), 1, outfile);
   chkfwrite(&data->dt, sizeof(double), 1, outfile);
   chkfwrite(&data->r, sizeof(double), 1, outfile);
   chkfwrite(&data->norm, sizeof(double), 1, outfile);
   chkfwrite(&data->T, sizeof(double), 1, outfile);
   for (ii = 0; ii < data->numvect; ii++) {
      dtmp = (double) data->vector[ii].r;
      chkfwrite(&dtmp, sizeof(double), 1, outfile);
      dtmp = (double) data->vector[ii].i;
      chkfwrite(&dtmp, sizeof(double), 1, outfile);
   }
   fclose(outfile);
}
Beispiel #8
0
void write_mask(char *maskfilenm, mask * obsmask)
/* Write the contents of an mask structure to a file */
{
   FILE *outfile;
   int ii;

   outfile = chkfopen(maskfilenm, "wb");
   chkfwrite(&(obsmask->timesigma), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->freqsigma), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->mjd), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->dtint), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->lofreq), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->dfreq), sizeof(double), 1, outfile);
   chkfwrite(&(obsmask->numchan), sizeof(int), 1, outfile);
   chkfwrite(&(obsmask->numint), sizeof(int), 1, outfile);
   chkfwrite(&(obsmask->ptsperint), sizeof(int), 1, outfile);
   chkfwrite(&(obsmask->num_zap_chans), sizeof(int), 1, outfile);
   if (obsmask->num_zap_chans)
      chkfwrite(obsmask->zap_chans, sizeof(int), obsmask->num_zap_chans, outfile);
   chkfwrite(&(obsmask->num_zap_ints), sizeof(int), 1, outfile);
   if (obsmask->num_zap_ints)
      chkfwrite(obsmask->zap_ints, sizeof(int), obsmask->num_zap_ints, outfile);
   chkfwrite(obsmask->num_chans_per_int, sizeof(int), obsmask->numint, outfile);
   for (ii = 0; ii < obsmask->numint; ii++) {
      if (obsmask->num_chans_per_int[ii] > 0 &&
          obsmask->num_chans_per_int[ii] < obsmask->numchan) {
         chkfwrite(obsmask->chans[ii], sizeof(int),
                   obsmask->num_chans_per_int[ii], outfile);
      }
   }
   fclose(outfile);
}
Beispiel #9
0
int main(int argc, char *argv[])
{
   FILE *bytemaskfile;
   float **dataavg = NULL, **datastd = NULL, **datapow = NULL;
   float *chandata = NULL, powavg, powstd, powmax;
   float inttime, norm, fracterror = RFI_FRACTERROR;
   float *rawdata = NULL;
   unsigned char **bytemask = NULL;
   short *srawdata = NULL;
   char *outfilenm, *statsfilenm, *maskfilenm;
   char *bytemaskfilenm, *rfifilenm;
   int numchan = 0, numint = 0, newper = 0, oldper = 0, good_padvals = 0;
   int blocksperint, ptsperint = 0, ptsperblock = 0, padding = 0;
   int numcands, candnum, numrfi = 0, numrfivect = NUM_RFI_VECT;
   int ii, jj, kk, slen, numread = 0, insubs = 0;
   int harmsum = RFI_NUMHARMSUM, lobin = RFI_LOBIN, numbetween = RFI_NUMBETWEEN;
   double davg, dvar, freq;
   struct spectra_info s;
   presto_interptype interptype;
   rfi *rfivect = NULL;
   mask oldmask, newmask;
   fftcand *cands;
   infodata idata;
   Cmdline *cmd;

   /* Call usage() if we have no command line arguments */

   if (argc == 1) {
      Program = argv[0];
      printf("\n");
      usage();
      exit(0);
   }

   /* Parse the command line using the excellent program Clig */

   cmd = parseCmdline(argc, argv);
   spectra_info_set_defaults(&s);
   s.filenames = cmd->argv;
   s.num_files = cmd->argc;
   s.clip_sigma = cmd->clip;
   // -1 causes the data to determine if we use weights, scales, & 
   // offsets for PSRFITS or flip the band for any data type where
   // we can figure that out with the data
   s.apply_flipband = (cmd->invertP) ? 1 : -1;
   s.apply_weight = (cmd->noweightsP) ? 0 : -1;
   s.apply_scale  = (cmd->noscalesP) ? 0 : -1;
   s.apply_offset = (cmd->nooffsetsP) ? 0 : -1;
   s.remove_zerodm = (cmd->zerodmP) ? 1 : 0;
   if (cmd->noclipP) {
       cmd->clip = 0.0;
       s.clip_sigma = 0.0;
   }
   if (cmd->ifsP) {
       // 0 = default or summed, 1-4 are possible also
       s.use_poln = cmd->ifs;
   }
   slen = strlen(cmd->outfile) + 20;

#ifdef DEBUG
   showOptionValues();
#endif

   printf("\n\n");
   printf("               Pulsar Data RFI Finder\n");
   printf("                 by Scott M. Ransom\n\n");

   /* The following is the root of all the output files */

   outfilenm = (char *) calloc(slen, sizeof(char));
   sprintf(outfilenm, "%s_rfifind", cmd->outfile);

   /* And here are the output file names */

   maskfilenm = (char *) calloc(slen, sizeof(char));
   sprintf(maskfilenm, "%s.mask", outfilenm);
   bytemaskfilenm = (char *) calloc(slen, sizeof(char));
   sprintf(bytemaskfilenm, "%s.bytemask", outfilenm);
   rfifilenm = (char *) calloc(slen, sizeof(char));
   sprintf(rfifilenm, "%s.rfi", outfilenm);
   statsfilenm = (char *) calloc(slen, sizeof(char));
   sprintf(statsfilenm, "%s.stats", outfilenm);
   sprintf(idata.name, "%s", outfilenm);

   if (RAWDATA) {
       if (cmd->filterbankP) s.datatype = SIGPROCFB;
       else if (cmd->psrfitsP) s.datatype = PSRFITS;
       else if (cmd->pkmbP) s.datatype = SCAMP;
       else if (cmd->bcpmP) s.datatype = BPP;
       else if (cmd->wappP) s.datatype = WAPP;
       else if (cmd->spigotP) s.datatype = SPIGOT;
   } else {  // Attempt to auto-identify the data
       identify_psrdatatype(&s, 1);
       if (s.datatype==SIGPROCFB) cmd->filterbankP = 1;
       else if (s.datatype==PSRFITS) cmd->psrfitsP = 1;
       else if (s.datatype==SCAMP) cmd->pkmbP = 1;
       else if (s.datatype==BPP) cmd->bcpmP = 1;
       else if (s.datatype==WAPP) cmd->wappP = 1;
       else if (s.datatype==SPIGOT) cmd->spigotP = 1;
       else if (s.datatype==SUBBAND) insubs = 1;
       else {
           printf("Error:  Unable to identify input data files.  Please specify type.\n\n");
           exit(1);
       }
   }

   if (!cmd->nocomputeP) {

       if (RAWDATA || insubs) {
           char description[40];
           psrdatatype_description(description, s.datatype);
           if (s.num_files > 1)
               printf("Reading %s data from %d files:\n", description, s.num_files);
           else
               printf("Reading %s data from 1 file:\n", description);
           if (insubs) s.files = (FILE **)malloc(sizeof(FILE *) * s.num_files);
           for (ii = 0; ii < s.num_files; ii++) {
               printf("  '%s'\n", cmd->argv[ii]);
               if (insubs) s.files[ii] = chkfopen(cmd->argv[ii], "rb");
           }
           printf("\n");
       }           

       if (RAWDATA) {
           read_rawdata_files(&s);
           print_spectra_info_summary(&s);
           spectra_info_to_inf(&s, &idata);
           ptsperblock = s.spectra_per_subint;
           numchan = s.num_channels;
           idata.dm = 0.0;
       }
       
       if (insubs) {
           /* Set-up values if we are using subbands */
           char *tmpname, *root, *suffix;
           if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) {
               printf("Error:  The input filename (%s) must have a suffix!\n\n", s.filenames[0]);
               exit(1);
           }
           if (strncmp(suffix, "sub", 3) == 0) {
               tmpname = calloc(strlen(root) + 6, 1);
               sprintf(tmpname, "%s.sub", root);
               readinf(&idata, tmpname);
               free(tmpname);
           } else {
               printf("\nThe input files (%s) must be subbands!  (i.e. *.sub##)\n\n",
                      s.filenames[0]);
               exit(1);
           }
           free(root);
           free(suffix);
           ptsperblock = 1;
           /* Compensate for the fact that we have subbands and not channels */
           idata.freq = idata.freq - 0.5 * idata.chan_wid +
               0.5 * idata.chan_wid * (idata.num_chan / s.num_files);
           idata.chan_wid = idata.num_chan / s.num_files * idata.chan_wid;
           idata.num_chan = numchan = s.num_files;
           idata.dm = 0.0;
           sprintf(idata.name, "%s", outfilenm);
           writeinf(&idata);
           s.padvals = gen_fvect(s.num_files);
           for (ii = 0 ; ii < s.num_files ; ii++)
               s.padvals[ii] = 0.0;
       }

       /* Read an input mask if wanted */
       if (cmd->maskfileP) {
           read_mask(cmd->maskfile, &oldmask);
           printf("Read old mask information from '%s'\n\n", cmd->maskfile);
           good_padvals = determine_padvals(cmd->maskfile, &oldmask, s.padvals);
       } else {
           oldmask.numchan = oldmask.numint = 0;
       }

      /* The number of data points and blocks to work with at a time */

      if (cmd->blocksP) {
         blocksperint = cmd->blocks;
         cmd->time = blocksperint * ptsperblock * idata.dt;
      } else {
         blocksperint = (int) (cmd->time / (ptsperblock * idata.dt) + 0.5);
      }
      ptsperint = blocksperint * ptsperblock;
      numint = (long long) idata.N / ptsperint;
      if ((long long) idata.N % ptsperint)
         numint++;
      inttime = ptsperint * idata.dt;
      printf("Analyzing data sections of length %d points (%.6g sec).\n",
             ptsperint, inttime);
      {
         int *factors, numfactors;

         factors = get_prime_factors(ptsperint, &numfactors);
         printf("  Prime factors are:  ");
         for (ii = 0; ii < numfactors; ii++)
            printf("%d ", factors[ii]);
         printf("\n");
         if (factors[numfactors - 1] > 13) {
            printf("  WARNING:  The largest prime factor is pretty big!  This will\n"
                   "            cause the FFTs to take a long time to compute.  I\n"
                   "            recommend choosing a different -time value.\n");
         }
         printf("\n");
         free(factors);
      }

      /* Allocate our workarrays */

      if (RAWDATA)
          rawdata = gen_fvect(idata.num_chan * ptsperblock * blocksperint);
      else if (insubs)
          srawdata = gen_svect(idata.num_chan * ptsperblock * blocksperint);
      dataavg = gen_fmatrix(numint, numchan);
      datastd = gen_fmatrix(numint, numchan);
      datapow = gen_fmatrix(numint, numchan);
      chandata = gen_fvect(ptsperint);
      bytemask = gen_bmatrix(numint, numchan);
      for (ii = 0; ii < numint; ii++)
         for (jj = 0; jj < numchan; jj++)
            bytemask[ii][jj] = GOODDATA;
      rfivect = rfi_vector(rfivect, numchan, numint, 0, numrfivect);
      if (numbetween == 2)
         interptype = INTERBIN;
      else
         interptype = INTERPOLATE;

      /* Main loop */

      printf("Writing mask data  to '%s'.\n", maskfilenm);
      printf("Writing  RFI data  to '%s'.\n", rfifilenm);
      printf("Writing statistics to '%s'.\n\n", statsfilenm);
      printf("Massaging the data ...\n\n");
      printf("Amount Complete = %3d%%", oldper);
      fflush(stdout);

      for (ii = 0; ii < numint; ii++) { /* Loop over the intervals */
         newper = (int) ((float) ii / numint * 100.0 + 0.5);
         if (newper > oldper) {
            printf("\rAmount Complete = %3d%%", newper);
            fflush(stdout);
            oldper = newper;
         }

         /* Read a chunk of data */

         if (RAWDATA)
             numread = read_rawblocks(rawdata, blocksperint, &s, &padding);
         else if (insubs)
             numread = read_subband_rawblocks(s.files, s.num_files,
                                              srawdata, blocksperint, &padding);

         if (padding)
            for (jj = 0; jj < numchan; jj++)
               bytemask[ii][jj] |= PADDING;

         for (jj = 0; jj < numchan; jj++) {     /* Loop over the channels */

             if (RAWDATA)
                 get_channel(chandata, jj, blocksperint, rawdata, &s);
             else if (insubs)
                 get_subband(jj, chandata, srawdata, blocksperint);

            /* Calculate the averages and standard deviations */
            /* for each point in time.                        */

            if (padding) {
                dataavg[ii][jj] = 0.0;
                datastd[ii][jj] = 0.0;
                datapow[ii][jj] = 1.0;
            } else {
               avg_var(chandata, ptsperint, &davg, &dvar);
               dataavg[ii][jj] = davg;
               datastd[ii][jj] = sqrt(dvar);
               realfft(chandata, ptsperint, -1);
               numcands = 0;
               norm = datastd[ii][jj] * datastd[ii][jj] * ptsperint;
               if (norm == 0.0)
                  norm = (chandata[0] == 0.0) ? 1.0 : chandata[0];
               cands = search_fft((fcomplex *) chandata, ptsperint / 2,
                                  lobin, ptsperint / 2, harmsum,
                                  numbetween, interptype, norm, cmd->freqsigma,
                                  &numcands, &powavg, &powstd, &powmax);
               datapow[ii][jj] = powmax;

               /* Record the birdies */

               if (numcands) {
                  for (kk = 0; kk < numcands; kk++) {
                     freq = cands[kk].r / inttime;
                     candnum = find_rfi(rfivect, numrfi, freq, RFI_FRACTERROR);
                     if (candnum >= 0) {
                        update_rfi(rfivect + candnum, freq, cands[kk].sig, jj, ii);
                     } else {
                        update_rfi(rfivect + numrfi, freq, cands[kk].sig, jj, ii);
                        numrfi++;
                        if (numrfi == numrfivect) {
                           numrfivect *= 2;
                           rfivect = rfi_vector(rfivect, numchan, numint,
                                                numrfivect / 2, numrfivect);
                        }
                     }
                  }
                  free(cands);
               }
            }
         }
      }
      printf("\rAmount Complete = 100%%\n");

      /* Write the data to the output files */

      write_rfifile(rfifilenm, rfivect, numrfi, numchan, numint,
                    ptsperint, lobin, numbetween, harmsum,
                    fracterror, cmd->freqsigma);
      write_statsfile(statsfilenm, datapow[0], dataavg[0], datastd[0],
                      numchan, numint, ptsperint, lobin, numbetween);

   } else {                     /* If "-nocompute" */
      float freqsigma;

      /* Read the data from the output files */

      printf("Reading  RFI data  from '%s'.\n", rfifilenm);
      printf("Reading statistics from '%s'.\n", statsfilenm);
      readinf(&idata, outfilenm);
      read_rfifile(rfifilenm, &rfivect, &numrfi, &numchan, &numint,
                   &ptsperint, &lobin, &numbetween, &harmsum,
                   &fracterror, &freqsigma);
      numrfivect = numrfi;
      read_statsfile(statsfilenm, &datapow, &dataavg, &datastd,
                     &numchan, &numint, &ptsperint, &lobin, &numbetween);
      bytemask = gen_bmatrix(numint, numchan);
      printf("Reading  bytemask  from '%s'.\n\n", bytemaskfilenm);
      bytemaskfile = chkfopen(bytemaskfilenm, "rb");
      chkfread(bytemask[0], numint * numchan, 1, bytemaskfile);
      fclose(bytemaskfile);
      for (ii = 0; ii < numint; ii++)
         for (jj = 0; jj < numchan; jj++)
            bytemask[ii][jj] &= PADDING;        /* Clear all but the PADDING bits */
      inttime = ptsperint * idata.dt;
   }

   /* Make the plots and set the mask */

   {
      int *zapints, *zapchan;
      int numzapints = 0, numzapchan = 0;

      if (cmd->zapintsstrP) {
         zapints = ranges_to_ivect(cmd->zapintsstr, 0, numint - 1, &numzapints);
         zapints = (int *) realloc(zapints, (size_t) (sizeof(int) * numint));
      } else {
         zapints = gen_ivect(numint);
      }
      if (cmd->zapchanstrP) {
         zapchan = ranges_to_ivect(cmd->zapchanstr, 0, numchan - 1, &numzapchan);
         zapchan = (int *) realloc(zapchan, (size_t) (sizeof(int) * numchan));
      } else {
         zapchan = gen_ivect(numchan);
      }
      rfifind_plot(numchan, numint, ptsperint, cmd->timesigma, cmd->freqsigma,
                   cmd->inttrigfrac, cmd->chantrigfrac,
                   dataavg, datastd, datapow, zapchan, numzapchan,
                   zapints, numzapints, &idata, bytemask,
                   &oldmask, &newmask, rfivect, numrfi,
                   cmd->rfixwinP, cmd->rfipsP, cmd->xwinP);

      vect_free(zapints);
      vect_free(zapchan);
   }

   /* Write the new mask and bytemask to the file */

   write_mask(maskfilenm, &newmask);
   bytemaskfile = chkfopen(bytemaskfilenm, "wb");
   chkfwrite(bytemask[0], numint * numchan, 1, bytemaskfile);
   fclose(bytemaskfile);

   /* Determine the percent of good and bad data */

   {
      int numpad = 0, numbad = 0, numgood = 0;

      for (ii = 0; ii < numint; ii++) {
         for (jj = 0; jj < numchan; jj++) {
            if (bytemask[ii][jj] == GOODDATA) {
               numgood++;
            } else {
               if (bytemask[ii][jj] & PADDING)
                  numpad++;
               else
                  numbad++;
            }
         }
      }
      printf("\nTotal number of intervals in the data:  %d\n\n", numint * numchan);
      printf("  Number of padded intervals:  %7d  (%6.3f%%)\n",
             numpad, (float) numpad / (float) (numint * numchan) * 100.0);
      printf("  Number of  good  intervals:  %7d  (%6.3f%%)\n",
             numgood, (float) numgood / (float) (numint * numchan) * 100.0);
      printf("  Number of  bad   intervals:  %7d  (%6.3f%%)\n\n",
             numbad, (float) numbad / (float) (numint * numchan) * 100.0);
      qsort(rfivect, numrfi, sizeof(rfi), compare_rfi_sigma);
      printf("  Ten most significant birdies:\n");
      printf("#  Sigma     Period(ms)      Freq(Hz)       Number \n");
      printf("----------------------------------------------------\n");
      for (ii = 0; ii < 10; ii++) {
         double pperr;
         char temp1[40], temp2[40];

         if (rfivect[ii].freq_var == 0.0) {
            pperr = 0.0;
            sprintf(temp1, " %-14g", rfivect[ii].freq_avg);
            sprintf(temp2, " %-14g", 1000.0 / rfivect[ii].freq_avg);
         } else {
            pperr = 1000.0 * sqrt(rfivect[ii].freq_var) /
                (rfivect[ii].freq_avg * rfivect[ii].freq_avg);
            nice_output_2(temp1, rfivect[ii].freq_avg, sqrt(rfivect[ii].freq_var),
                          -15);
            nice_output_2(temp2, 1000.0 / rfivect[ii].freq_avg, pperr, -15);
         }
         printf("%-2d %-8.2f %13s %13s %-8d\n", ii + 1, rfivect[ii].sigma_avg,
                temp2, temp1, rfivect[ii].numobs);
      }
      qsort(rfivect, numrfi, sizeof(rfi), compare_rfi_numobs);
      printf("\n  Ten most numerous birdies:\n");
      printf("#  Number    Period(ms)      Freq(Hz)       Sigma \n");
      printf("----------------------------------------------------\n");
      for (ii = 0; ii < 10; ii++) {
         double pperr;
         char temp1[40], temp2[40];

         if (rfivect[ii].freq_var == 0.0) {
            pperr = 0.0;
            sprintf(temp1, " %-14g", rfivect[ii].freq_avg);
            sprintf(temp2, " %-14g", 1000.0 / rfivect[ii].freq_avg);
         } else {
            pperr = 1000.0 * sqrt(rfivect[ii].freq_var) /
                (rfivect[ii].freq_avg * rfivect[ii].freq_avg);
            nice_output_2(temp1, rfivect[ii].freq_avg, sqrt(rfivect[ii].freq_var),
                          -15);
            nice_output_2(temp2, 1000.0 / rfivect[ii].freq_avg, pperr, -15);
         }
         printf("%-2d %-8d %13s %13s %-8.2f\n", ii + 1, rfivect[ii].numobs,
                temp2, temp1, rfivect[ii].sigma_avg);
      }
      printf("\nDone.\n\n");
   }

   /* Close the files and cleanup */

   free_rfi_vector(rfivect, numrfivect);
   free_mask(newmask);
   if (cmd->maskfileP)
      free_mask(oldmask);
   free(outfilenm);
   free(statsfilenm);
   free(bytemaskfilenm);
   free(maskfilenm);
   free(rfifilenm);
   vect_free(dataavg[0]);
   vect_free(dataavg);
   vect_free(datastd[0]);
   vect_free(datastd);
   vect_free(datapow[0]);
   vect_free(datapow);
   vect_free(bytemask[0]);
   vect_free(bytemask);
   if (!cmd->nocomputeP) {
       //  Close all the raw files and free their vectors
       close_rawfiles(&s);
       vect_free(chandata);
       if (insubs)
           vect_free(srawdata);
       else
           vect_free(rawdata);
   }
   return (0);
}
Beispiel #10
0
int main(int argc, char *argv[])
{
   float *data;
   int status, isign;
   unsigned long numdata;
/*   unsigned long next2ton; */
   FILE *datafile, *scratchfile;
   char datafilenm[100], scratchfilenm[100], resultfilenm[100];
   char command[80];
   struct tms runtimes;
   double ttim, stim, utim, tott;

   tott = times(&runtimes) / (double) CLK_TCK;
   printf("\n\n");
   printf("   Real-Valued Data FFT Program v2.0\n");
   printf("        by Scott M. Ransom\n");
   printf("           8 June, 1997\n\n");

   if ((argc > 1) && (argc < 7)) {

      /*      Open and check data file.    */

      if (argc == 3) {
         sprintf(datafilenm, "%s.", argv[2]);
         sprintf(scratchfilenm, "%s.tmp", argv[2]);
         sprintf(resultfilenm, "%s.", argv[2]);
      }
      if (argc == 4) {
         sprintf(datafilenm, "%s/%s.", argv[3], argv[2]);
         sprintf(scratchfilenm, "%s/%s.tmp", argv[3], argv[2]);
         sprintf(resultfilenm, "%s/%s.", argv[3], argv[2]);
      }
      if (argc == 5) {
         sprintf(datafilenm, "%s/%s.", argv[3], argv[2]);
         sprintf(scratchfilenm, "%s/%s.tmp", argv[4], argv[2]);
         sprintf(resultfilenm, "%s/%s.", argv[3], argv[2]);
      }
      isign = atoi(argv[1]);

      /*  Add the appropriate suffix to the filenames. */

      if (isign == 1) {
         strcat(datafilenm, "fft");
         strcat(resultfilenm, "dat");
      } else {
         strcat(datafilenm, "dat");
         strcat(resultfilenm, "fft");
      }

      /*  Check the input data set...  */

      printf("Checking data in \"%s\".\n", datafilenm);
      datafile = chkfopen(datafilenm, "rb");

      /* # of real data points */

      numdata = chkfilelen(datafile, sizeof(float));
/*     next2ton = next2_to_n(numdata); */
/*     if (numdata != next2ton) { */
/*       printf("\nNumber of data pts must be an integer power of two,\n"); */
/*       printf("     or data must be single precision floats.\n"); */
/*       printf("Exiting.\n\n"); */
/*       fclose(datafile); */
/*       exit(1); */
/*     } */
      printf("Data OK.  There are %ld points.\n\n", numdata);
      fclose(datafile);
   } else {
      printf("\nUsage:  realfft sign datafilename [ data path] ");
      printf("[scratch path]\n\n");
      printf("  This program calculates the FFT of a file containing\n");
      printf("  a power-of-two number of floats representing\n");
      printf("  real numbers.  (i.e. a normal time series)\n\n");
      printf("  THE INPUT FILE WILL BE OVERWRITTEN.\n\n");
      printf("  \"sign\" is the sign of the exponential during the FFT. \n");
      printf("  (i.e. -1 is the standard forward transform, 1 is the\n");
      printf("  inverse transform times N (the number of floats))\n");
      printf("  If both paths are omitted, the data is assumed to be\n");
      printf("  located in the working directory, and the scratch space\n");
      printf("  if needed will be located there. If only one path is\n");
      printf("  given, both input and scratch files will reside there.\n\n");
      printf("  Notes:\n");
      printf("    - datafilename must not include \".dat\" or \".fft\"\n");
      printf("        suffix. It will be added by the program.\n");
      printf("    - Do not end paths in \"/\".\n");
      printf("    - The scratch file is the same size as the input file.\n");
      printf("    - If \"sign\"=1, the file to be transformed should end\n");
      printf("        with \".fft\".  Otherwise, it should end with\n");
      printf("        \".dat\".\n\n");
      exit(0);
   }

   /*     Start the transform sequence               */

   if (numdata > MAXREALFFT) {

      /*  Perform Two-Pass, Out-of-Core, FFT  */

      printf("Performing Out-of-Core Two-Pass FFT on data.\n\n");
      printf("Result will be stored in the file \"%s\".\n", resultfilenm);

      /*  Initialize files. */

      datafile = chkfopen(datafilenm, "rb+");
      scratchfile = chkfopen(scratchfilenm, "wb+");

      printf("\nTransforming...\n");

      /*     Call Two-Pass routine  */

      if (isign == 1) {
         realfft_scratch_inv(datafile, scratchfile, numdata);
      } else {
         realfft_scratch_fwd(datafile, scratchfile, numdata);
      }

      fclose(scratchfile);

      sprintf(command, "rm -f %s\n", scratchfilenm);
      if ((status = (system(command))) == -1 || status == 127) {
         perror("\nSystem call (rm) failed");
         printf("\n");
         exit(1);
      }
      printf("Finished.\n\n");

      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 usage: %.3f sec total (%.3f sec user, %.3f sec system)\n",
             ttim, utim, stim);
      printf("Total time elapsed:  %.3f sec.\n\n", tott);

   } else {

      /* Perform standard FFT for real functions  */

      printf("Performing in-core FFT for real functions on data.\n\n");
      printf("FFT will be stored in the file \"%s\".\n\n", resultfilenm);

      /* Open the data and fft results files.    */

      datafile = chkfopen(datafilenm, "rb+");

      /* Read data from file to data array   */

      printf("Reading data.\n\n");
      data = gen_fvect(numdata);
      chkfread(data, sizeof(float), (unsigned long) numdata, datafile);
      chkfileseek(datafile, 0L, sizeof(char), SEEK_SET);

      /* Start and time the transform   */

      printf("Transforming...\n");
      realfft(data, numdata, isign);
      printf("Finished.\n\n");

      /* Write data from FFT array to file  */

      printf("Writing FFT data.\n\n");
      chkfwrite(data, sizeof(float), (unsigned long) numdata, datafile);
      vect_free(data);

      /* Output the timing information */

      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 usage: %.3f sec total (%.3f sec user, %.3f sec system)\n",
             ttim, utim, stim);
      printf("Total time elapsed:  %.3f sec.\n\n", tott);

   }

   sprintf(command, "mv %s %s\n", datafilenm, resultfilenm);
   if ((status = (system(command))) == -1 || status == 127) {
      perror("\nSystem call (mv) failed");
      printf("\n");
      exit(1);
   }
   fclose(datafile);
   /*
      fftw_print_max_memory_usage();
      fftw_check_memory_leaks();
    */
   exit(0);
}
Beispiel #11
0
int main(int argc, char *argv[])
{
   FILE *infile, *outfile;
   int ii, jj, bufflen = 10000, numread;
   long long N = 0;
   float *inbuffer = NULL, *outbuffer = NULL;
   short useshorts = 0, *sinbuffer = NULL, *soutbuffer = NULL;
   char *rootfilenm, *outname;
   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("     Time Series Downsampling Routine\n");
   printf("               Sept, 2002\n\n");

   {
      int hassuffix = 0;
      char *suffix;

      hassuffix = split_root_suffix(cmd->argv[0], &rootfilenm, &suffix);
      if (hassuffix) {
         if (strcmp(suffix, "sdat") == 0)
            useshorts = 1;
         if (strcmp(suffix, "dat") != 0 && strcmp(suffix, "sdat") != 0) {
            printf
                ("\nInput file ('%s') must be a time series ('.dat' or '.sdat')!\n\n",
                 cmd->argv[0]);
            free(suffix);
            exit(0);
         }
         free(suffix);
      } else {
         printf("\nInput file ('%s') must be a time series ('.dat' or '.sdat')!\n\n",
                cmd->argv[0]);
         exit(0);
      }
      if (cmd->outfileP) {
         outname = cmd->outfile;
      } else {
         outname = (char *) calloc(strlen(rootfilenm) + 11, sizeof(char));
         if (useshorts)
            sprintf(outname, "%s_D%d.sdat", rootfilenm, cmd->factor);
         else
            sprintf(outname, "%s_D%d.dat", rootfilenm, cmd->factor);
      }
   }

   /* Read the info file */

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

   /* Open files and create arrays */

   infile = chkfopen(argv[1], "rb");
   outfile = chkfopen(outname, "wb");

   /* Read and downsample */

   if (useshorts) {
      sinbuffer = gen_svect(bufflen * cmd->factor);
      soutbuffer = gen_svect(bufflen);
      while ((numread =
              chkfread(sinbuffer, sizeof(short), bufflen * cmd->factor, infile))) {
         for (ii = 0; ii < numread / cmd->factor; ii++) {
            soutbuffer[ii] = 0;
            for (jj = 0; jj < cmd->factor; jj++)
               soutbuffer[ii] += sinbuffer[cmd->factor * ii + jj];
         }
         chkfwrite(soutbuffer, sizeof(short), numread / cmd->factor, outfile);
         N += numread / cmd->factor;
      }
      vect_free(sinbuffer);
      vect_free(soutbuffer);
   } else {
      inbuffer = gen_fvect(bufflen * cmd->factor);
      outbuffer = gen_fvect(bufflen);
      while ((numread =
              chkfread(inbuffer, sizeof(float), bufflen * cmd->factor, infile))) {
         for (ii = 0; ii < numread / cmd->factor; ii++) {
            outbuffer[ii] = 0;
            for (jj = 0; jj < cmd->factor; jj++)
               outbuffer[ii] += inbuffer[cmd->factor * ii + jj];
         }
         chkfwrite(outbuffer, sizeof(float), numread / cmd->factor, outfile);
         N += numread / cmd->factor;
      }
      vect_free(inbuffer);
      vect_free(outbuffer);
   }
   printf("Done.  Wrote %lld points.\n\n", N);

   /* Write the new info file */

   idata.dt = idata.dt * cmd->factor;
   idata.numonoff = 0;
   idata.N = (double) N;
   strncpy(idata.name, outname, strlen(outname) - 4);
   if (useshorts)
      idata.name[strlen(outname) - 5] = '\0';
   else
      idata.name[strlen(outname) - 4] = '\0';
   writeinf(&idata);

   fclose(infile);
   fclose(outfile);
   free(rootfilenm);
   if (!cmd->outfileP)
      free(outname);
   exit(0);
}
int main(int argc, char *argv[])
{
   FILE **infiles, *outfile = NULL, *scalingfile;
   int filenum, argnum = 1, ii = 0, ptsperblock, numlags, numfiles;
   int bytes_per_read, scaling = 0, numscalings, output = 1;
   long long N;
   char *path, *filenm;
   char outfilenm[200], filenmbase[200], scalingnm[200], rawlags[4096];
   unsigned char output_samples[2048];
   float *scalings = NULL;
   double dt, T;
   SPIGOT_INFO *spigots;
   sigprocfb fb;
   infodata idata;

   if (argc == 1) {
      fprintf(stderr, "Usage: spigotSband2filterbank [-stdout] SPIGOT_files\n");
      exit(0);
   }

   if (!strcmp(argv[argnum], "-stdout")) {      /* Use STDOUT */
      argnum++;
      output = 0;
      outfile = stdout;
   } else {
      printf
          ("\nConverting raw SPIGOT S-band FITs data into SIGPROC\n"
           "filterbank format and throwing out the bottom 200MHz...\n\n");
   }

   /* Attempt to read a file with lag scalings in it */
   sprintf(scalingnm, "%s.scaling", filenmbase);
   if ((scalingfile = fopen(scalingnm, "rb"))) {
      /* Determine the length of the file */
      numscalings = (int) chkfilelen(scalingfile, sizeof(float));
      /* Create the array and read 'em */
      scalings = gen_fvect(numscalings);
      chkfread(scalings, sizeof(float), numscalings, scalingfile);
      scaling = 1;
      /* close the scaling file */
      fclose(scalingfile);
      if (outfile != stdout)
         printf("Scaling the lags with the %d values found in '%s'\n\n",
                numscalings, scalingnm);
   }

   /* Read and convert the basic SPIGOT file information */

   numfiles = argc - 1;
   if (outfile == stdout)
      numfiles--;
   else
      printf("Spigot card input file information:\n");
   spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles);
   infiles = (FILE **) malloc(sizeof(FILE *) * numfiles);
   for (filenum = 0; filenum < numfiles; filenum++, argnum++) {
      if (outfile != stdout)
         printf("  '%s'\n", argv[argnum]);
      infiles[filenum] = chkfopen(argv[argnum], "rb");
      read_SPIGOT_header(argv[argnum], spigots + filenum);
      rewind(infiles[filenum]);
   }
   if (outfile != stdout)
      printf("\n");

   /* The following is necessary in order to initialize all the */
   /* static variables in spigot.c                              */
   get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N,
                        &ptsperblock, &numlags, &dt, &T, &idata, output);

   /* Step through the SPIGOT files */
   ii = 0;
   if (outfile == stdout)
      argnum = 2;
   else
      argnum = 1;
   for (filenum = 0; filenum < numfiles; filenum++, argnum++) {
      split_path_file(argv[argnum], &path, &filenm);
      strncpy(filenmbase, filenm, strlen(filenm) - 5);
      filenmbase[strlen(filenm) - 5] = '\0';
      sprintf(outfilenm, "%s.fil", filenmbase);
      if (outfile != stdout){
         printf("Reading S-band Spigot lags from '%s'\n", argv[argnum]);
         printf("Writing filterbank spectra to   '%s'\n\n", outfilenm);
         outfile = chkfopen(outfilenm, "wb");
      }
      // Update the filterbank header information for each file
      spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase);
      write_filterbank_header(&fb, outfile);
      chkfseek(infiles[filenum], spigots[filenum].header_len, SEEK_SET);
      bytes_per_read = numlags * spigots[filenum].bits_per_lag / 8;

      /* Loop over the samples in the file */
      while (chkfread(rawlags, bytes_per_read, 1, infiles[filenum])) {
         if (scaling)
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, scalings[ii]);
         else
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0);
         ii++;
         /* Invert the band so that the high freqs are first */
         /* This is how SIGPROC stores its data.             */
         {
            int jj;
            unsigned char tempzz = 0.0, *loptr, *hiptr;
            loptr = output_samples + 0;
            hiptr = output_samples + numlags - 1;
            for (jj = 0; jj < numlags / 2; jj++, loptr++, hiptr--) {
               SWAP(*loptr, *hiptr);
            }
         }
         chkfwrite(output_samples, sizeof(unsigned char), fb.nchans, outfile);
      }
      fclose(infiles[filenum]);
      if (outfile != stdout)
         fclose(outfile);
   }
   if (outfile != stdout)
      fprintf(stderr, "Converted and wrote %d samples.\n\n", ii);
   if (scaling)
      vect_free(scalings);
   free(spigots);
   free(path);
   free(filenm);
   free(infiles);
   return 0;
}
Beispiel #13
0
void write_prepfoldinfo(prepfoldinfo * in, char *filename)
/* Write a prepfoldinfo data structure to a binary file */
{
   FILE *outfile;
   int itmp;

   outfile = chkfopen(filename, "wb");
   chkfwrite(&in->numdms, sizeof(int), 1, outfile);
   chkfwrite(&in->numperiods, sizeof(int), 1, outfile);
   chkfwrite(&in->numpdots, sizeof(int), 1, outfile);
   chkfwrite(&in->nsub, sizeof(int), 1, outfile);
   chkfwrite(&in->npart, sizeof(int), 1, outfile);
   chkfwrite(&in->proflen, sizeof(int), 1, outfile);
   chkfwrite(&in->numchan, sizeof(int), 1, outfile);
   chkfwrite(&in->pstep, sizeof(int), 1, outfile);
   chkfwrite(&in->pdstep, sizeof(int), 1, outfile);
   chkfwrite(&in->dmstep, sizeof(int), 1, outfile);
   chkfwrite(&in->ndmfact, sizeof(int), 1, outfile);
   chkfwrite(&in->npfact, sizeof(int), 1, outfile);
   itmp = strlen(in->filenm);
   chkfwrite(&itmp, sizeof(int), 1, outfile);
   chkfwrite(in->filenm, sizeof(char), itmp, outfile);
   itmp = strlen(in->candnm);
   chkfwrite(&itmp, sizeof(int), 1, outfile);
   chkfwrite(in->candnm, sizeof(char), itmp, outfile);
   itmp = strlen(in->telescope);
   chkfwrite(&itmp, sizeof(int), 1, outfile);
   chkfwrite(in->telescope, sizeof(char), itmp, outfile);
   itmp = strlen(in->pgdev);
   chkfwrite(&itmp, sizeof(int), 1, outfile);
   chkfwrite(in->pgdev, sizeof(char), itmp, outfile);
   chkfwrite(in->rastr, sizeof(char), 16, outfile);
   chkfwrite(in->decstr, sizeof(char), 16, outfile);
   chkfwrite(&in->dt, sizeof(double), 1, outfile);
   chkfwrite(&in->startT, sizeof(double), 1, outfile);
   chkfwrite(&in->endT, sizeof(double), 1, outfile);
   chkfwrite(&in->tepoch, sizeof(double), 1, outfile);
   chkfwrite(&in->bepoch, sizeof(double), 1, outfile);
   chkfwrite(&in->avgvoverc, sizeof(double), 1, outfile);
   chkfwrite(&in->lofreq, sizeof(double), 1, outfile);
   chkfwrite(&in->chan_wid, sizeof(double), 1, outfile);
   chkfwrite(&in->bestdm, sizeof(double), 1, outfile);
   chkfwrite(&(in->topo.pow), sizeof(double), 1, outfile);
   chkfwrite(&(in->topo.p1), sizeof(double), 1, outfile);
   chkfwrite(&(in->topo.p2), sizeof(double), 1, outfile);
   chkfwrite(&(in->topo.p3), sizeof(double), 1, outfile);
   chkfwrite(&(in->bary.pow), sizeof(double), 1, outfile);
   chkfwrite(&(in->bary.p1), sizeof(double), 1, outfile);
   chkfwrite(&(in->bary.p2), sizeof(double), 1, outfile);
   chkfwrite(&(in->bary.p3), sizeof(double), 1, outfile);
   chkfwrite(&(in->fold.pow), sizeof(double), 1, outfile);
   chkfwrite(&(in->fold.p1), sizeof(double), 1, outfile);
   chkfwrite(&(in->fold.p2), sizeof(double), 1, outfile);
   chkfwrite(&(in->fold.p3), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.p), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.e), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.x), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.w), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.t), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.pd), sizeof(double), 1, outfile);
   chkfwrite(&(in->orb.wd), sizeof(double), 1, outfile);
   chkfwrite(in->dms, sizeof(double), in->numdms, outfile);
   chkfwrite(in->periods, sizeof(double), in->numperiods, outfile);
   chkfwrite(in->pdots, sizeof(double), in->numpdots, outfile);
   chkfwrite(in->rawfolds, sizeof(double), in->nsub *
             in->npart * in->proflen, outfile);
   chkfwrite(in->stats, sizeof(foldstats), in->nsub * in->npart, outfile);
   fclose(outfile);
}
Beispiel #14
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);
}
Beispiel #15
0
int main(int argc, char *argv[])
{
   FILE **infiles, *outfile = NULL, *scalingfile, *zerolagfile = NULL;
   int filenum, ptsperblock, numlags, numfiles, outnumlags;
   int bytes_per_read, scaling = 0, numscalings, firstfile, firstspec;
   int write_data = 1, update_posn = 0;
   long long N, numconverted = 0, numwritten = 0;
   char *path, *filenm, rawlags[4096];
   char outfilenm[200], filenmbase[200], zerolagnm[200], scalingnm[200];
   unsigned char output_samples[2048];
   float *scalings = NULL, lags[2048], tmp_floats[2048];
   double dt, T, time_offset;
   SPIGOT_INFO *spigots;
   sigprocfb fb;
   infodata idata;
   Cmdline *cmd;

   /* Call usage() if we have no command line arguments */
   if (argc == 1) {
      Program = argv[0];
      usage();
      exit(0);
   }

   /* Parse the command line using the excellent program Clig */
   cmd = parseCmdline(argc, argv);
   // showOptionValues();
   numfiles = cmd->argc;

   /* If requesting that we skip values or only write          */
   /* a specific number of values, require an output file name */
   if ((cmd->skip > 0) || cmd->numoutP){
      if (!cmd->outfileP && !cmd->stdoutP) {
         fprintf(stderr,
                 "\nspigot2filterbank ERROR:  You need to specify an output\n"
                 "     filename (or -stdout) when using the -skip and/or \n"
                 "     -numout options!\n\n");
         exit(1);
      }
   }

   /* Give an error if specifying stdout and an output file */
   if (cmd->stdoutP && cmd->outfileP){
      fprintf(stderr, 
              "\nspigot2filterbank ERROR:  You cannot specify both an output\n"
              "     file and that the data should go to STDOUT!\n\n");
      exit(1);
   }

   if (!cmd->stdoutP)
      printf("\nConverting SPIGOT FITs lags into SIGPROC filterbank format...\n\n");
   
   /* Determine the filename base from the first spigot file */
   split_path_file(cmd->argv[0], &path, &filenm);
   strncpy(filenmbase, filenm, strlen(filenm) - 5);
   filenmbase[strlen(filenm) - 5] = '\0';
   free(path);
   free(filenm);

   /* Open a file to store the zerolags */
   if (cmd->zerolagsP) {
      if (cmd->outfileP) {
         sprintf(zerolagnm, "%s.zerolags", cmd->outfile);
      } else {
         sprintf(zerolagnm, "%s.zerolags", filenmbase);
      }
      zerolagfile = chkfopen(zerolagnm, "wb");
   }

   /* Attempt to read a file with lag scalings in it */
   sprintf(scalingnm, "%s.scaling", filenmbase);
   if ((scalingfile = fopen(scalingnm, "rb"))) {
      /* Determine the length of the file */
      numscalings = (int) chkfilelen(scalingfile, sizeof(float));
      /* Create the array and read 'em */
      scalings = gen_fvect(numscalings);
      chkfread(scalings, sizeof(float), numscalings, scalingfile);
      scaling = 1;
      /* close the scaling file */
      fclose(scalingfile);
      if (!cmd->stdoutP)
         printf("Scaling the lags with the %d values found in '%s'\n\n",
                numscalings, scalingnm);
   }

   /* Read and convert the basic SPIGOT file information */
   if (!cmd->stdoutP)
      printf("Spigot card input file information:\n");
   spigots = (SPIGOT_INFO *) malloc(sizeof(SPIGOT_INFO) * numfiles);
   infiles = (FILE **) malloc(sizeof(FILE *) * numfiles);
   for (filenum = 0; filenum < numfiles; filenum++) {
      if (!cmd->stdoutP)
         printf("  '%s'\n", cmd->argv[filenum]);
      infiles[filenum] = chkfopen(cmd->argv[filenum], "rb");
      read_SPIGOT_header(cmd->argv[filenum], spigots + filenum);
      rewind(infiles[filenum]);
   }
   if (!cmd->stdoutP) 
      printf("\n");

   /* The following is necessary in order to initialize all the */
   /* static variables in spigot.c                              */
   get_SPIGOT_file_info(infiles, spigots, numfiles, 0, 0, &N,
                        &ptsperblock, &numlags, &dt, &T, &idata, 
                        !cmd->stdoutP);
   
   /* Compute the first file required */
   firstfile = cmd->skip / spigots[0].samples_per_file;
   firstspec = cmd->skip % spigots[0].samples_per_file;
   if (!cmd->numoutP) {
      cmd->numout = (N - cmd->skip) / cmd->downsamp;
   }
   bytes_per_read = numlags * spigots[0].bits_per_lag / 8;
   outnumlags = numlags - cmd->lokill - cmd->hikill;

   /* Step through the SPIGOT files */
   filenum = firstfile;
   while (numwritten < cmd->numout){
      split_path_file(cmd->argv[filenum], &path, &filenm);
      strncpy(filenmbase, filenm, strlen(filenm) - 5);
      filenmbase[strlen(filenm) - 5] = '\0';
      if (cmd->outfileP) {
         if (filenum==firstfile) {
            sprintf(outfilenm, "%s", cmd->outfile);
            outfile = chkfopen(outfilenm, "wb");
         }
      } else {
         sprintf(outfilenm, "%s.fil", filenmbase);
         if (cmd->stdoutP) {
            outfile = stdout;
         } else {
            outfile = chkfopen(outfilenm, "wb");
         }
      }
      if (!cmd->stdoutP) {
         if (filenum==firstfile)
            printf("Reading Spigot lags from '%s' (starting at sample %d)\n", 
                   cmd->argv[filenum], firstspec);
         else
            printf("Reading Spigot lags from '%s'\n", 
                   cmd->argv[filenum]);
         printf("Writing filterbank spectra to   '%s'\n\n", outfilenm);
      }
      
      /* Update the filterbank header information for each file */
      if (!spigots[filenum].tracking) {
         if (cmd->outfileP || cmd->stdoutP) {
            time_offset = 0.5 * cmd->numout *                   \
               spigots[filenum].dt_us * 1e-6 * cmd->downsamp;
         } else { // Just normal files
            time_offset = 0.5 * spigots[filenum].file_duration;
         }
         update_posn = 1;
      } else {
         update_posn = 0;
         time_offset = 0.0;
      }
      /* Adjust the Spigot start time for the skip */
      spigots[filenum].elapsed_time += cmd->skip * spigots[filenum].dt_us * 1e-6;
      /* Determine the SIGPROC header */
      spigot2sigprocfb(&(spigots[filenum]), &fb, filenmbase, 
                       cmd->lokill, cmd->hikill, cmd->downsamp, 
                       update_posn, time_offset);
      /* Correct the structure if we are using floats */
      if (cmd->floatsP) fb.nbits = 32;
      
      /* Write a filterbank header if we have not been told not to.   */
      /* Don't write it, though, if using stdio or a specified output */
      /* file and the input file is not the first.                    */
      if (!cmd->nohdrP) {
         if ((!cmd->stdoutP && !cmd->outfileP) ||
             ((cmd->stdoutP || cmd->outfileP) && filenum==firstfile)) {
            write_filterbank_header(&fb, outfile);
         }
      }

      /* Go to the correct autocorrelation in the correct first FITs file */
      chkfseek(infiles[filenum], 
               spigots[filenum].header_len + bytes_per_read*firstspec,
               SEEK_SET);
      
      /* Loop over the samples in the file */
      while ((numwritten < cmd->numout) && 
             (chkfread(rawlags, bytes_per_read, 1, infiles[filenum]))) {
         if (cmd->zerolagsP) {
            /* Correct the lags so we can write the zerolag */
            get_calibrated_lags(rawlags, lags);
            chkfwrite(lags, sizeof(float), 1, zerolagfile);
         }
         if (scaling) {
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 
                                 scalings[cmd->skip+numconverted]);
         } else {
            convert_SPIGOT_point(rawlags, output_samples, SUMIFS, 1.0);
         }
         /* If downsampling, average the current spectra */
         if (cmd->downsamp > 1) {
            int ii;
            if (numconverted % cmd->downsamp == 0) {
               write_data = 0;
               /* Zero the array used for averaging */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] = 0.0;
            } else {
               /* Add the current data to the array used for averaging */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] += (float) output_samples[ii+cmd->lokill];
               /* If that was the last sample to be added, average them */
               /* and put them back into output_samples */
               if (numconverted % cmd->downsamp == (cmd->downsamp-1)) {
                  write_data = 1;
                  for (ii = 0; ii < outnumlags; ii++) {
                     tmp_floats[ii] /= (float) cmd->downsamp;
                     output_samples[ii+cmd->lokill] = \
                        (unsigned char)(tmp_floats[ii]+0.5);
                  }
               }
            }
         }
         numconverted++;

         if (write_data) {
            int ii;

            /* Invert the band so that the high freqs are first */
            /* This is how SIGPROC stores its data.             */
            if (cmd->floatsP) {
               float tempzz = 0.0, *loptr, *hiptr;
               loptr = tmp_floats;  //  killed channels are already gone
               hiptr = tmp_floats + outnumlags - 1;
               for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
                  SWAP(*loptr, *hiptr);
               }
            } else {
               unsigned char tempzz = 0.0, *loptr, *hiptr;
               loptr = output_samples + cmd->lokill;
               hiptr = output_samples + cmd->lokill + outnumlags - 1;
               for (ii = 0; ii < outnumlags / 2; ii++, loptr++, hiptr--) {
                  SWAP(*loptr, *hiptr);
               }
            }

            /* Now actually write the data */
            if (cmd->floatsP) {
               /* Copy the bytes to floats */
               for (ii = 0; ii < outnumlags; ii++)
                  tmp_floats[ii] = (float) output_samples[ii+cmd->lokill];
               chkfwrite(tmp_floats, sizeof(float), fb.nchans, outfile);
            } else {
               chkfwrite(output_samples+cmd->lokill, 
                         sizeof(unsigned char), fb.nchans, outfile);
            }
            numwritten++;
         }
      }
      if ((!cmd->stdoutP) && (!cmd->outfileP))
         fclose(outfile);
      fclose(infiles[filenum]);
      firstspec = 0;
      filenum++;
      free(path);
      free(filenm);
   }
   if ((!cmd->stdoutP) && (cmd->outfileP))
      fclose(outfile);
   if (cmd->zerolagsP)
      fclose(zerolagfile);
   if (!cmd->stdoutP)
      fprintf(stderr, "Converted %lld samples and wrote %lld.\n\n", 
              numconverted, numwritten);
   if (scaling)
      free(scalings);
   free(spigots);
   free(infiles);
   return 0;
}
Beispiel #16
0
int main(int argc, char *argv[])
{
   int ii;
   double ttim, utim, stim, tott;
   struct tms runtimes;
   subharminfo **subharminfs;
   accelobs obs;
   infodata idata;
   GSList *cands = NULL;
   Cmdline *cmd;

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

   /* Create the accelobs structure */
   create_accelobs(&obs, &idata, cmd, 1);

   /* Zap birdies if requested and if in memory */
   if (cmd->zaplistP && !obs.mmap_file && obs.fft) {
      int numbirds;
      double *bird_lobins, *bird_hibins, hibin;

      /* Read the Standard bird list */
      numbirds = get_birdies(cmd->zaplist, obs.T, cmd->baryv,
                             &bird_lobins, &bird_hibins);

      /* Zap the birdies */
      printf("Zapping them using a barycentric velocity of %.5gc.\n\n", cmd->baryv);
      hibin = obs.N / 2;
      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], NULL, obs.fft);
      }

      free(bird_lobins);
      free(bird_hibins);
   }

   printf("Searching with up to %d harmonics summed:\n",
          1 << (obs.numharmstages - 1));
   printf("  f = %.1f to %.1f Hz\n", obs.rlo / obs.T, obs.rhi / obs.T);
   printf("  r = %.1f to %.1f Fourier bins\n", obs.rlo, obs.rhi);
   printf("  z = %.1f to %.1f Fourier bins drifted\n\n", obs.zlo, obs.zhi);

   /* Generate the correlation kernels */

   printf("Generating correlation kernels:\n");
   subharminfs = create_subharminfos(obs.numharmstages, (int) obs.zhi);
   printf("Done generating kernels.\n\n");
   printf("Starting the search.\n");
   /* Don't use the *.txtcand files on short in-memory searches */
   if (!obs.dat_input) {
      printf("  Working candidates in a test format are in '%s'.\n\n",
             obs.workfilenm);
   }

   /* Start the main search loop */

   {
      double startr = obs.rlo, lastr = 0, nextr = 0;
      ffdotpows *fundamental;

      while (startr + ACCEL_USELEN * ACCEL_DR < obs.highestbin) {
         /* Search the fundamental */
         print_percent_complete(startr - obs.rlo,
                                obs.highestbin - obs.rlo, "search", 0);
         nextr = startr + ACCEL_USELEN * ACCEL_DR;
         lastr = nextr - ACCEL_DR;
         fundamental = subharm_ffdot_plane(1, 1, startr, lastr,
                                           &subharminfs[0][0], &obs);
         cands = search_ffdotpows(fundamental, 1, &obs, cands);

         if (obs.numharmstages > 1) {   /* Search the subharmonics */
            int stage, harmtosum, harm;
            ffdotpows *subharmonic;

            for (stage = 1; stage < obs.numharmstages; stage++) {
               harmtosum = 1 << stage;
               for (harm = 1; harm < harmtosum; harm += 2) {
                  subharmonic = subharm_ffdot_plane(harmtosum, harm, startr, lastr,
                                                    &subharminfs[stage][harm - 1],
                                                    &obs);
                  add_ffdotpows(fundamental, subharmonic, harmtosum, harm);
                  free_ffdotpows(subharmonic);
               }
               cands = search_ffdotpows(fundamental, harmtosum, &obs, cands);
            }
         }
         free_ffdotpows(fundamental);
         startr = nextr;
      }
      print_percent_complete(obs.highestbin - obs.rlo,
                             obs.highestbin - obs.rlo, "search", 0);
   }

   printf("\n\nDone searching.  Now optimizing each candidate.\n\n");
   free_subharminfos(obs.numharmstages, subharminfs);

   {                            /* Candidate list trimming and optimization */
      int numcands;
      GSList *listptr;
      accelcand *cand;
      fourierprops *props;


      numcands = g_slist_length(cands);

      if (numcands) {

         /* Sort the candidates according to the optimized sigmas */

         cands = sort_accelcands(cands);

         /* Eliminate (most of) the harmonically related candidates */
         if ((cmd->numharm > 1) && !(cmd->noharmremoveP))
             eliminate_harmonics(cands, &numcands);

         /* Now optimize each candidate and its harmonics */

         print_percent_complete(0, 0, NULL, 1);
         listptr = cands;
         for (ii = 0; ii < numcands; ii++) {
            print_percent_complete(ii, numcands, "optimization", 0);
            cand = (accelcand *) (listptr->data);
            optimize_accelcand(cand, &obs);
            listptr = listptr->next;
         }
         print_percent_complete(ii, numcands, "optimization", 0);

         /* Calculate the properties of the fundamentals */

         props = (fourierprops *) malloc(sizeof(fourierprops) * numcands);
         listptr = cands;
         for (ii = 0; ii < numcands; ii++) {
            cand = (accelcand *) (listptr->data);
            /* In case the fundamental harmonic is not significant,  */
            /* send the originally determined r and z from the       */
            /* harmonic sum in the search.  Note that the derivs are */
            /* not used for the computations with the fundamental.   */
            calc_props(cand->derivs[0], cand->r, cand->z, 0.0, props + ii);
            /* Override the error estimates based on power */
            props[ii].rerr = (float) (ACCEL_DR) / cand->numharm;
            props[ii].zerr = (float) (ACCEL_DZ) / cand->numharm;
            listptr = listptr->next;
         }

         /* Write the fundamentals to the output text file */

         output_fundamentals(props, cands, &obs, &idata);

         /* Write the harmonics to the output text file */

         output_harmonics(cands, &obs, &idata);

         /* Write the fundamental fourierprops to the cand file */

         obs.workfile = chkfopen(obs.candnm, "wb");
         chkfwrite(props, sizeof(fourierprops), numcands, obs.workfile);
         fclose(obs.workfile);
         free(props);
         printf("\n\n");
      } else {
         printf("No candidates above sigma = %.2f were found.\n\n", obs.sigma);
      }
   }

   /* Finish up */

   printf("Searched the following approx numbers of independent points:\n");
   printf("  %d harmonic:   %9lld\n", 1, obs.numindep[0]);
   for (ii = 1; ii < obs.numharmstages; ii++)
      printf("  %d harmonics:  %9lld\n", 1 << ii, obs.numindep[ii]);

   printf("\nTiming 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("Final candidates in binary format are in '%s'.\n", obs.candnm);
   printf("Final Candidates in a text format are in '%s'.\n\n", obs.accelnm);

   free_accelobs(&obs);
   g_slist_foreach(cands, free_accelcand, NULL);
   g_slist_free(cands);
   return (0);
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    /* Any variable that begins with 't' means topocentric */
    /* Any variable that begins with 'b' means barycentric */
    FILE *outfile;
    float *outdata = NULL;
    double tdf = 0.0, dtmp = 0.0, barydispdt = 0.0, dsdt = 0.0;
    double *dispdt, *tobsf = NULL, tlotoa = 0.0, blotoa = 0.0;
    double max = -9.9E30, min = 9.9E30, var = 0.0, avg = 0.0;
    char obs[3], ephem[10], *datafilenm, *outinfonm;
    char rastring[50], decstring[50];
    int numchan = 1, newper = 0, oldper = 0, nummasked = 0, useshorts = 0;
    int numadded = 0, numremoved = 0, padding = 0, *maskchans = NULL, offset = 0;
    long slen, ii, numbarypts = 0, worklen = 65536;
    long numread = 0, numtowrite = 0, totwrote = 0, datawrote = 0;
    long padwrote = 0, padtowrite = 0, statnum = 0;
    int numdiffbins = 0, *diffbins = NULL, *diffbinptr = NULL, good_padvals = 0;
    int *idispdt;
    struct spectra_info s;
    infodata idata;
    Cmdline *cmd;
    mask obsmask;

    /* Call usage() if we have no command line arguments */
    if (argc == 1) {
        Program = argv[0];
        printf("\n");
        usage();
        exit(0);
    }

    /* Parse the command line using the excellent program Clig */
    cmd = parseCmdline(argc, argv);
    spectra_info_set_defaults(&s);
    s.filenames = cmd->argv;
    s.num_files = cmd->argc;
    // If we are zeroDMing, make sure that clipping is off.
    if (cmd->zerodmP)
        cmd->noclipP = 1;
    s.clip_sigma = cmd->clip;
    // -1 causes the data to determine if we use weights, scales, &
    // offsets for PSRFITS or flip the band for any data type where
    // we can figure that out with the data
    s.apply_flipband = (cmd->invertP) ? 1 : -1;
    s.apply_weight = (cmd->noweightsP) ? 0 : -1;
    s.apply_scale = (cmd->noscalesP) ? 0 : -1;
    s.apply_offset = (cmd->nooffsetsP) ? 0 : -1;
    s.remove_zerodm = (cmd->zerodmP) ? 1 : 0;
    if (cmd->noclipP) {
        cmd->clip = 0.0;
        s.clip_sigma = 0.0;
    }
    if (cmd->ifsP) {
        // 0 = default or summed, 1-4 are possible also
        s.use_poln = cmd->ifs + 1;
    }

    if (cmd->ncpus > 1) {
#ifdef _OPENMP
        int maxcpus = omp_get_num_procs();
        int openmp_numthreads = (cmd->ncpus <= maxcpus) ? cmd->ncpus : maxcpus;
        // Make sure we are not dynamically setting the number of threads
        omp_set_dynamic(0);
        omp_set_num_threads(openmp_numthreads);
        printf("Using %d threads with OpenMP\n\n", openmp_numthreads);
#endif
    } else {
#ifdef _OPENMP
        omp_set_num_threads(1); // Explicitly turn off OpenMP
#endif
    }

#ifdef DEBUG
    showOptionValues();
#endif

    printf("\n\n");
    printf("           Pulsar Data Preparation Routine\n");
    printf("    Type conversion, de-dispersion, barycentering.\n");
    printf("                 by Scott M. Ransom\n\n");

    if (RAWDATA) {
        if (cmd->filterbankP)
            s.datatype = SIGPROCFB;
        else if (cmd->psrfitsP)
            s.datatype = PSRFITS;
    } else {                    // Attempt to auto-identify the data
        identify_psrdatatype(&s, 1);
        if (s.datatype == SIGPROCFB)
            cmd->filterbankP = 1;
        else if (s.datatype == PSRFITS)
            cmd->psrfitsP = 1;
        else if (s.datatype == SDAT)
            useshorts = 1;
        else if (s.datatype != DAT) {
            printf
                ("Error:  Unable to identify input data files.  Please specify type.\n\n");
            exit(1);
        }
    }

    if (!RAWDATA) {
        char *root, *suffix;
        /* Split the filename into a rootname and a suffix */
        if (split_root_suffix(s.filenames[0], &root, &suffix) == 0) {
            printf("\nThe input filename (%s) must have a suffix!\n\n",
                   s.filenames[0]);
            exit(1);
        }
        printf("Reading input data from '%s'.\n", s.filenames[0]);
        printf("Reading information from '%s.inf'.\n\n", root);
        /* Read the info file if available */
        readinf(&idata, root);
        free(root);
        free(suffix);
        s.files = (FILE **) malloc(sizeof(FILE *));
        s.files[0] = chkfopen(s.filenames[0], "rb");
    } else {
        char description[40];
        psrdatatype_description(description, s.datatype);
        if (s.num_files > 1)
            printf("Reading %s data from %d files:\n", description, s.num_files);
        else
            printf("Reading %s data from 1 file:\n", description);
        for (ii = 0; ii < s.num_files; ii++) {
            printf("  '%s'\n", cmd->argv[ii]);
        }
        printf("\n");
    }

    /* Determine the other file names and open the output data file */
    slen = strlen(cmd->outfile) + 8;
    datafilenm = (char *) calloc(slen, 1);
    sprintf(datafilenm, "%s.dat", cmd->outfile);
    outfile = chkfopen(datafilenm, "wb");
    sprintf(idata.name, "%s", cmd->outfile);
    outinfonm = (char *) calloc(slen, 1);
    sprintf(outinfonm, "%s.inf", cmd->outfile);

    if (RAWDATA) {
        read_rawdata_files(&s);
        if (cmd->ignorechanstrP) {
            s.ignorechans = get_ignorechans(cmd->ignorechanstr, 0, s.num_channels-1,
                                            &s.num_ignorechans, &s.ignorechans_str);
            if (s.ignorechans_str==NULL) {
                s.ignorechans_str = (char *)malloc(strlen(cmd->ignorechanstr)+1);
                strcpy(s.ignorechans_str, cmd->ignorechanstr);
            }
        }
        print_spectra_info_summary(&s);
        spectra_info_to_inf(&s, &idata);
        /* Finish setting up stuff common to all raw formats */
        idata.dm = cmd->dm;
        worklen = s.spectra_per_subint;

        /* If we are offsetting into the file, change inf file start time */
        if (cmd->start > 0.0 || cmd->offset > 0) {
            if (cmd->start > 0.0) /* Offset in units of worklen */
                cmd->offset = (long) (cmd->start *
                                      idata.N / worklen) * worklen;
            add_to_inf_epoch(&idata, cmd->offset * idata.dt);
            offset_to_spectra(cmd->offset, &s);
            printf("Offsetting into the input files by %ld spectra (%.6g sec)\n",
                   cmd->offset, cmd->offset * idata.dt);
        }
        if (cmd->maskfileP)
            maskchans = gen_ivect(idata.num_chan);

        /* Compare the size of the data to the size of output we request */
        if (cmd->numoutP) {
            dtmp = idata.N;
            idata.N = cmd->numout;
            writeinf(&idata);
            idata.N = dtmp;
        } else {
        /* Set the output length to a good number if it wasn't requested */
            cmd->numoutP = 1;
            cmd->numout = choose_good_N((long long)(idata.N/cmd->downsamp));
            writeinf(&idata);
            printf("Setting a 'good' output length of %ld samples\n", cmd->numout);
        }

        /* The number of topo to bary time points to generate with TEMPO */
        numbarypts = (long) (idata.dt * idata.N * 1.1 / TDT + 5.5) + 1;

        // Identify the TEMPO observatory code
        {
            char *outscope = (char *) calloc(40, sizeof(char));
            telescope_to_tempocode(idata.telescope, outscope, obs);
            free(outscope);
        }
    }

    /* Read an input mask if wanted */
    if (cmd->maskfileP) {
        read_mask(cmd->maskfile, &obsmask);
        printf("Read mask information from '%s'\n\n", cmd->maskfile);
        good_padvals = determine_padvals(cmd->maskfile, &obsmask, s.padvals);
    } else {
        obsmask.numchan = obsmask.numint = 0;
    }

    /* Determine our initialization data if we do _not_ have Parkes, */
    /* Green Bank BCPM, or Arecibo WAPP data sets.                   */
    if (!RAWDATA) {

        /* If we will be barycentering... */
        if (!cmd->nobaryP) {
            /* The number of topo to bary time points to generate with TEMPO */
            numbarypts = (long) (idata.dt * idata.N * 1.1 / TDT + 5.5) + 1;
            // Identify the TEMPO observatory code
            {
                char *outscope = (char *) calloc(40, sizeof(char));
                telescope_to_tempocode(idata.telescope, outscope, obs);
                free(outscope);
            }
        }

        /* The number of data points to work with at a time */
        if (worklen > idata.N)
            worklen = idata.N;
        worklen = (long) (worklen / 1024) * 1024;

        /* If we are offsetting into the file, change inf file start time */
        if (cmd->start > 0.0 || cmd->offset > 0) {
            if (cmd->start > 0.0) /* Offset in units of worklen */
                cmd->offset = (long) (cmd->start *
                                      idata.N / worklen) * worklen;
            add_to_inf_epoch(&idata, cmd->offset * idata.dt);
            printf("Offsetting into the input files by %ld samples (%.6g sec)\n",
                   cmd->offset, cmd->offset * idata.dt);
            if (useshorts) {
                chkfileseek(s.files[0], cmd->offset, sizeof(short), SEEK_SET);
            } else {
                chkfileseek(s.files[0], cmd->offset, sizeof(float), SEEK_SET);
            }
        }

        /* Set the output length to a good number if it wasn't requested */
        if (!cmd->numoutP) {
            cmd->numoutP = 1;
            cmd->numout = choose_good_N((long long)(idata.N/cmd->downsamp));
            printf("Setting a 'good' output length of %ld samples\n", cmd->numout);
        }
    }

    /* Check if we are downsampling */
    dsdt = idata.dt * cmd->downsamp;
    if (cmd->downsamp > 1) {
        printf("Downsampling by a factor of %d\n", cmd->downsamp);
        printf("New sample dt = %.10g\n\n", dsdt);
        if (worklen % cmd->downsamp) {
            printf("Error:  The downsample factor (%d) must be a factor of the\n",
                   cmd->downsamp);
            printf("        worklength (%ld).  Exiting.\n\n", worklen);
            exit(1);
        }
    }
    printf("Writing output data to '%s'.\n", datafilenm);
    printf("Writing information to '%s'.\n\n", outinfonm);

    /* The topocentric epoch of the start of the data */
    tlotoa = (double) idata.mjd_i + idata.mjd_f;

    if (!strcmp(idata.band, "Radio") && RAWDATA) {

        /* The topocentric spacing between channels */
        tdf = idata.chan_wid;
        numchan = idata.num_chan;

        /* The topocentric observation frequencies */
        tobsf = gen_dvect(numchan);
        tobsf[0] = idata.freq;
        for (ii = 0; ii < numchan; ii++)
            tobsf[ii] = tobsf[0] + ii * tdf;

        /* The dispersion delays (in time bins) */
        dispdt = gen_dvect(numchan);    // full float bins
        idispdt = gen_ivect(numchan);   // nearest integer bins

        if (cmd->nobaryP) {

            /* Determine our dispersion time delays for each channel */
            for (ii = 0; ii < numchan; ii++)
                dispdt[ii] = delay_from_dm(cmd->dm, tobsf[ii]);

            /* The highest frequency channel gets no delay                 */
            /* All other delays are positive fractions of bin length (dt)  */
            dtmp = dispdt[numchan - 1];
            for (ii = 0; ii < numchan; ii++) {
                dispdt[ii] = (dispdt[ii] - dtmp) / idata.dt;
                idispdt[ii] = (int) (dispdt[ii] + 0.5);
            }
            worklen *= ((int) (fabs(dispdt[0])) / worklen) + 1;
        }

    } else {                    /* For unknown radio raw data (Why is this here?) */
        tobsf = gen_dvect(numchan);
        dispdt = gen_dvect(numchan);
        idispdt = gen_ivect(numchan);
        dispdt[0] = 0.0;
        idispdt[0] = 0;
        if (!strcmp(idata.band, "Radio")) {
            tobsf[0] = idata.freq + (idata.num_chan - 1) * idata.chan_wid;
            cmd->dm = idata.dm;
        } else {
            tobsf[0] = 0.0;
            cmd->dm = 0.0;
        }
    }

    if (cmd->nobaryP) {         /* Main loop if we are not barycentering... */

        /* Allocate our data array */
        outdata = gen_fvect(worklen);

        printf("Massaging the data ...\n\n");
        printf("Amount Complete = 0%%");

        do {
            if (RAWDATA)
                numread = read_psrdata(outdata, worklen, &s, idispdt, &padding,
                                       maskchans, &nummasked, &obsmask);
            else if (useshorts)
                numread = read_shorts(s.files[0], outdata, worklen, numchan);
            else
                numread = read_floats(s.files[0], outdata, worklen, numchan);
            if (numread == 0)
                break;

            /* Downsample if requested */
            if (cmd->downsamp > 1)
                numread = downsample(outdata, numread, cmd->downsamp);

            /* Print percent complete */
            newper = (int) ((float) totwrote / cmd->numout * 100.0) + 1;
            if (newper > oldper) {
                printf("\rAmount Complete = %3d%%", newper);
                fflush(stdout);
                oldper = newper;
            }

            /* Write the latest chunk of data, but don't   */
            /* write more than cmd->numout points.         */
            numtowrite = numread;
            if ((totwrote + numtowrite) > cmd->numout)
                numtowrite = cmd->numout - totwrote;
            chkfwrite(outdata, sizeof(float), numtowrite, outfile);
            totwrote += numtowrite;

            /* Update the statistics */
            if (!padding) {
                for (ii = 0; ii < numtowrite; ii++)
                    update_stats(statnum + ii, outdata[ii], &min, &max, &avg, &var);
                statnum += numtowrite;
            }

            /* Stop if we have written out all the data we need to */
            if (totwrote == cmd->numout)
                break;

        } while (numread);

        datawrote = totwrote;

    } else {                    /* Main loop if we are barycentering... */

        double avgvoverc = 0.0, maxvoverc = -1.0, minvoverc = 1.0, *voverc = NULL;
        double *bobsf = NULL, *btoa = NULL, *ttoa = NULL;

        /* What ephemeris will we use?  (Default is DE405) */
        strcpy(ephem, "DE405");

        /* Define the RA and DEC of the observation */
        ra_dec_to_string(rastring, idata.ra_h, idata.ra_m, idata.ra_s);
        ra_dec_to_string(decstring, idata.dec_d, idata.dec_m, idata.dec_s);

        /* Allocate some arrays */
        bobsf = gen_dvect(numchan);
        btoa = gen_dvect(numbarypts);
        ttoa = gen_dvect(numbarypts);
        voverc = gen_dvect(numbarypts);
        for (ii = 0; ii < numbarypts; ii++)
            ttoa[ii] = tlotoa + TDT * ii / SECPERDAY;

        /* Call TEMPO for the barycentering */
        printf("Generating barycentric corrections...\n");
        barycenter(ttoa, btoa, voverc, numbarypts, rastring, decstring, obs, ephem);
        for (ii = 0; ii < numbarypts; ii++) {
            if (voverc[ii] > maxvoverc)
                maxvoverc = voverc[ii];
            if (voverc[ii] < minvoverc)
                minvoverc = voverc[ii];
            avgvoverc += voverc[ii];
        }
        avgvoverc /= numbarypts;
        vect_free(voverc);
        blotoa = btoa[0];

        printf("   Average topocentric velocity (c) = %.7g\n", avgvoverc);
        printf("   Maximum topocentric velocity (c) = %.7g\n", maxvoverc);
        printf("   Minimum topocentric velocity (c) = %.7g\n\n", minvoverc);
        printf("Collecting and barycentering %s...\n\n", cmd->argv[0]);

        /* Determine the initial dispersion time delays for each channel */
        for (ii = 0; ii < numchan; ii++) {
            bobsf[ii] = doppler(tobsf[ii], avgvoverc);
            dispdt[ii] = delay_from_dm(cmd->dm, bobsf[ii]);
        }

        /* The highest frequency channel gets no delay                   */
        /* All other delays are positive fractions of bin length (dt)    */
        barydispdt = dispdt[numchan - 1];
        for (ii = 0; ii < numchan; ii++) {
            dispdt[ii] = (dispdt[ii] - barydispdt) / idata.dt;
            idispdt[ii] = (int) (dispdt[ii] + 0.5);
        }
        if (RAWDATA)
            worklen *= ((int) (dispdt[0]) / worklen) + 1;

        /* If the data is de-dispersed radio data... */
        if (!strcmp(idata.band, "Radio")) {
            printf("The DM of %.2f at the barycentric observing freq of %.3f MHz\n",
                   idata.dm, bobsf[numchan - 1]);
            printf("   causes a delay of %f seconds compared to infinite freq.\n",
                   barydispdt);
            printf("   This delay is removed from the barycented times.\n\n");
        }
        printf("Topocentric epoch (at data start) is:\n");
        printf("   %17.11f\n\n", tlotoa);
        printf("Barycentric epoch (infinite obs freq at data start) is:\n");
        printf("   %17.11f\n\n", blotoa - (barydispdt / SECPERDAY));

        /* Convert the bary TOAs to differences from the topo TOAs in  */
        /* units of bin length (dsdt) rounded to the nearest integer.  */
        dtmp = (btoa[0] - ttoa[0]);
        for (ii = 0; ii < numbarypts; ii++)
            btoa[ii] = ((btoa[ii] - ttoa[ii]) - dtmp) * SECPERDAY / dsdt;

        {                       /* Find the points where we need to add or remove bins */

            int oldbin = 0, currentbin;
            double lobin, hibin, calcpt;

            numdiffbins = abs(NEAREST_LONG(btoa[numbarypts - 1])) + 1;
            diffbins = gen_ivect(numdiffbins);
            diffbinptr = diffbins;
            for (ii = 1; ii < numbarypts; ii++) {
                currentbin = NEAREST_LONG(btoa[ii]);
                if (currentbin != oldbin) {
                    if (currentbin > 0) {
                        calcpt = oldbin + 0.5;
                        lobin = (ii - 1) * TDT / dsdt;
                        hibin = ii * TDT / dsdt;
                    } else {
                        calcpt = oldbin - 0.5;
                        lobin = -((ii - 1) * TDT / dsdt);
                        hibin = -(ii * TDT / dsdt);
                    }
                    while (fabs(calcpt) < fabs(btoa[ii])) {
                        /* Negative bin number means remove that bin */
                        /* Positive bin number means add a bin there */
                        *diffbinptr = NEAREST_LONG(LININTERP(calcpt, btoa[ii - 1],
                                                             btoa[ii], lobin,
                                                             hibin));
                        diffbinptr++;
                        calcpt = (currentbin > 0) ? calcpt + 1.0 : calcpt - 1.0;
                    }
                    oldbin = currentbin;
                }
            }
            *diffbinptr = cmd->numout;  /* Used as a marker */
        }
        diffbinptr = diffbins;

        /* Now perform the barycentering */

        printf("Massaging the data...\n\n");
        printf("Amount Complete = 0%%");

        /* Allocate our data array */

        outdata = gen_fvect(worklen);

        do {                    /* Loop to read and write the data */
            int numwritten = 0;
            double block_avg, block_var;

            if (RAWDATA)
                numread = read_psrdata(outdata, worklen, &s, idispdt, &padding,
                                       maskchans, &nummasked, &obsmask);
            else if (useshorts)
                numread = read_shorts(s.files[0], outdata, worklen, numchan);
            else
                numread = read_floats(s.files[0], outdata, worklen, numchan);
            if (numread == 0)
                break;

            /* Downsample if requested */
            if (cmd->downsamp > 1)
                numread = downsample(outdata, numread, cmd->downsamp);

            /* Determine the approximate local average */
            avg_var(outdata, numread, &block_avg, &block_var);

            /* Print percent complete */

            newper = (int) ((float) totwrote / cmd->numout * 100.0) + 1;
            if (newper > oldper) {
                printf("\rAmount Complete = %3d%%", newper);
                fflush(stdout);
                oldper = newper;
            }

            /* Simply write the data if we don't have to add or */
            /* remove any bins from this batch.                 */
            /* OR write the amount of data up to cmd->numout or */
            /* the next bin that will be added or removed.      */

            numtowrite = abs(*diffbinptr) - datawrote;
            /* FIXME: numtowrite+totwrote can wrap! */
            if ((totwrote + numtowrite) > cmd->numout)
                numtowrite = cmd->numout - totwrote;
            if (numtowrite > numread)
                numtowrite = numread;
            chkfwrite(outdata, sizeof(float), numtowrite, outfile);
            datawrote += numtowrite;
            totwrote += numtowrite;
            numwritten += numtowrite;

            /* Update the statistics */

            if (!padding) {
                for (ii = 0; ii < numtowrite; ii++)
                    update_stats(statnum + ii, outdata[ii], &min, &max, &avg, &var);
                statnum += numtowrite;
            }

            if ((datawrote == abs(*diffbinptr)) && (numwritten != numread) && (totwrote < cmd->numout)) {       /* Add/remove a bin */
                float favg;
                int skip, nextdiffbin;

                skip = numtowrite;

                do {            /* Write the rest of the data after adding/removing a bin  */

                    if (*diffbinptr > 0) {

                        /* Add a bin */

                        favg = (float) block_avg;
                        chkfwrite(&favg, sizeof(float), 1, outfile);
                        numadded++;
                        totwrote++;
                    } else {

                        /* Remove a bin */

                        numremoved++;
                        datawrote++;
                        numwritten++;
                        skip++;
                    }
                    diffbinptr++;

                    /* Write the part after the diffbin */

                    numtowrite = numread - numwritten;
                    if ((totwrote + numtowrite) > cmd->numout)
                        numtowrite = cmd->numout - totwrote;
                    nextdiffbin = abs(*diffbinptr) - datawrote;
                    if (numtowrite > nextdiffbin)
                        numtowrite = nextdiffbin;
                    chkfwrite(outdata + skip, sizeof(float), numtowrite, outfile);
                    numwritten += numtowrite;
                    datawrote += numtowrite;
                    totwrote += numtowrite;

                    /* Update the statistics and counters */

                    if (!padding) {
                        for (ii = 0; ii < numtowrite; ii++)
                            update_stats(statnum + ii, outdata[skip + ii],
                                         &min, &max, &avg, &var);
                        statnum += numtowrite;
                    }
                    skip += numtowrite;

                    /* Stop if we have written out all the data we need to */

                    if (totwrote == cmd->numout)
                        break;
                } while (numwritten < numread);
            }
            /* Stop if we have written out all the data we need to */

            if (totwrote == cmd->numout)
                break;

        } while (numread);

        /* Free the arrays used in barycentering */

        vect_free(bobsf);
        vect_free(btoa);
        vect_free(ttoa);
    }

    /* Calculate what the amount of padding we need  */

    if (cmd->numout > totwrote)
        padwrote = padtowrite = cmd->numout - totwrote;


    /* Write the new info file for the output data */

    if (!cmd->nobaryP) {
        idata.bary = 1;
        idata.mjd_i = (int) floor(blotoa - (barydispdt / SECPERDAY));
        idata.mjd_f = blotoa - (barydispdt / SECPERDAY) - idata.mjd_i;
    }
    if (cmd->downsamp > 1)
        idata.dt = dsdt;
    update_infodata(&idata, totwrote, padtowrite, diffbins, numdiffbins);
    writeinf(&idata);

    /* Set the padded points equal to the average data point */

    if (idata.numonoff >= 1) {
        int jj, index, startpad, endpad;

        for (ii = 0; ii < worklen; ii++)
            outdata[ii] = avg;
        fclose(outfile);
        outfile = chkfopen(datafilenm, "rb+");
        for (ii = 0; ii < idata.numonoff; ii++) {
            index = 2 * ii;
            startpad = idata.onoff[index + 1];
            if (ii == idata.numonoff - 1)
                endpad = idata.N - 1;
            else
                endpad = idata.onoff[index + 2];
            chkfseek(outfile, (startpad + 1) * sizeof(float), SEEK_SET);
            padtowrite = endpad - startpad;
            for (jj = 0; jj < padtowrite / worklen; jj++)
                chkfwrite(outdata, sizeof(float), worklen, outfile);
            chkfwrite(outdata, sizeof(float), padtowrite % worklen, outfile);
        }
    }
    vect_free(outdata);

    //  Close all the raw files and free their vectors
    close_rawfiles(&s);

    /* Print simple stats and results */

    var /= (datawrote - 1);

    /* Conver the '.dat' file to '.sdat' if requested */

    if (cmd->shortsP) {
        FILE *infile;
        int safe_convert = 1, bufflen = 65536;
        char *sdatafilenm;
        float *fbuffer;
        short *sbuffer;

        offset = (int) (floor(avg));
        if ((max - min) > (SHRT_MAX - SHRT_MIN)) {
            if ((max - min) < 1.5 * (SHRT_MAX - SHRT_MIN)) {
                printf("Warning:  There is more dynamic range in the data\n"
                       "          than can be handled perfectly:\n"
                       "               max - min = %.2f - %.2f = %.2f\n"
                       "          Clipping the low values...\n\n", max, min,
                       max - min);
                offset = max - SHRT_MAX;
            } else {
                printf("Error:  There is way too much dynamic range in the data:\n"
                       "               max - min = %.2f - %.2f = %.2f\n"
                       "        Not converting to shorts.\n\n", max, min, max - min);
                safe_convert = 0;
            }
        }

        if (safe_convert) {
            fbuffer = gen_fvect(bufflen);
            sbuffer = gen_svect(bufflen);
            sdatafilenm = (char *) calloc(slen, 1);
            sprintf(sdatafilenm, "%s.sdat", cmd->outfile);
            printf("\n\nConverting floats in '%s' to shorts in '%s'.",
                   datafilenm, sdatafilenm);
            fflush(NULL);

            infile = chkfopen(datafilenm, "rb");
            outfile = chkfopen(sdatafilenm, "wb");
            while ((numread = chkfread(fbuffer, sizeof(float), bufflen, infile))) {
                for (ii = 0; ii < numread; ii++)
                    sbuffer[ii] = (short) (fbuffer[ii] + 1e-20 - offset);
                chkfwrite(sbuffer, sizeof(short), numread, outfile);
            }
            fclose(infile);
            fclose(outfile);
            remove(datafilenm);
            vect_free(fbuffer);
            vect_free(sbuffer);
        }
    }

    printf("\n\nDone.\n\nSimple statistics of the output data:\n");
    printf("             Data points written:  %ld\n", totwrote);
    if (padwrote)
        printf("          Padding points written:  %ld\n", padwrote);
    if (!cmd->nobaryP) {
        if (numadded)
            printf("    Bins added for barycentering:  %d\n", numadded);
        if (numremoved)
            printf("  Bins removed for barycentering:  %d\n", numremoved);
    }
    printf("           Maximum value of data:  %.2f\n", max);
    printf("           Minimum value of data:  %.2f\n", min);
    printf("              Data average value:  %.2f\n", avg);
    printf("         Data standard deviation:  %.2f\n", sqrt(var));
    if (cmd->shortsP && offset != 0)
        printf("          Offset applied to data:  %d\n", -offset);
    printf("\n");

    /* Cleanup */

    if (cmd->maskfileP) {
        free_mask(obsmask);
        vect_free(maskchans);
    }
    vect_free(tobsf);
    vect_free(dispdt);
    vect_free(idispdt);
    free(outinfonm);
    free(datafilenm);
    if (!cmd->nobaryP)
        vect_free(diffbins);
    return (0);
}