Exemple #1
0
int main(int argc, char *argv[])
{
    fitsfile *infptr, *outfptr;   /* FITS file pointers defined in fitsio.h */
    int status = 0;       /* status must always be initialized = 0  */

    if (argc != 3)
    {
 printf("Usage:  fitscopy inputfile outputfile\n");
 printf("\n");
 printf("Copy an input file to an output file, optionally filtering\n");
 printf("the file in the process.  This seemingly simple program can\n");
 printf("apply powerful filters which transform the input file as\n");
 printf("it is being copied.  Filters may be used to extract a\n");
 printf("subimage from a larger image, select rows from a table,\n");
 printf("filter a table with a GTI time extension or a SAO region file,\n");
 printf("create or delete columns in a table, create an image by\n");
 printf("binning (histogramming) 2 table columns, and convert IRAF\n");
 printf("format *.imh or raw binary data files into FITS images.\n");
 printf("See the CFITSIO User's Guide for a complete description of\n");
 printf("the Extended File Name filtering syntax.\n");
 printf("\n");
 printf("Examples:\n");
 printf("\n");
 printf("fitscopy in.fit out.fit                   (simple file copy)\n");
 printf("fitscopy - -                              (stdin to stdout)\n");
 printf("fitscopy in.fit[11:50,21:60] out.fit      (copy a subimage)\n");
 printf("fitscopy iniraf.imh out.fit               (IRAF image to FITS)\n");
 printf("fitscopy in.dat[i512,512] out.fit         (raw array to FITS)\n");
 printf("fitscopy in.fit[events][pi>35] out.fit    (copy rows with pi>35)\n");
 printf("fitscopy in.fit[events][bin X,Y] out.fit  (bin an image) \n");
 printf("fitscopy in.fit[events][col x=.9*y] out.fit        (new x column)\n");
 printf("fitscopy in.fit[events][gtifilter()] out.fit       (time filter)\n");
 printf("fitscopy in.fit[2][regfilter(\"pow.reg\")] out.fit (spatial filter)\n");
 printf("\n");
 printf("Note that it may be necessary to enclose the input file name\n");
 printf("in single quote characters on the Unix command line.\n");
      return(0);
    }
    /* Open the input file */
    if ( !fits_open_file(&infptr, argv[1], READONLY, &status) )
    {
      /* Create the output file */
      if ( !fits_create_file(&outfptr, argv[2], &status) )
      {
 
        /* copy the previous, current, and following HDUs */
        fits_copy_file(infptr, outfptr, 1, 1, 1, &status);

        fits_close_file(outfptr,  &status);
      }
      fits_close_file(infptr, &status);
    }

    /* if error occured, print out error message */
    if (status) fits_report_error(stderr, status);
    return(status);
}
int FITSImage::saveFITS( const QString &newFilename )
{
    int status=0;
    long fpixel[2], nelements;
    fitsfile *new_fptr;

    nelements = stats.dim[0] * stats.dim[1];
    fpixel[0] = 1;
    fpixel[1] = 1;


    /* Create a new File, overwriting existing*/
    if (fits_create_file(&new_fptr, newFilename.toAscii(), &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* Copy ALL contents */
    if (fits_copy_file(fptr, new_fptr, 1, 1, 1, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* close current file */
    if (fits_close_file(fptr, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    if (tempFile)
    {
        QFile::remove(filename);
        tempFile = false;
    }

    filename = newFilename;

    fptr = new_fptr;

    /* Write Data */
    if (fits_write_pix(fptr, TFLOAT, fpixel, nelements, image_buffer, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* Write keywords */

    // Minimum
    if (fits_update_key(fptr, TDOUBLE, "DATAMIN", &(stats.min), "Minimum value", &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    // Maximum
    if (fits_update_key(fptr, TDOUBLE, "DATAMAX", &(stats.max), "Maximum value", &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    // ISO Date
    if (fits_write_date(fptr, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    QString history = QString("Modified by KStars on %1").arg(QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"));
    // History
    if (fits_write_history(fptr, history.toAscii(), &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    return status;
}
Exemple #3
0
void newfits_(int nx, int ny, int** pic, char* w_file, int get_head, char* r_file){

     int lverb = tune14_.lverb;
     int fio_err = 0; // for reporting file opening and writing errors
     char* force_file = malloc((strlen(w_file)+2)*sizeof(char));
     force_file[0] = '!';
     strncpy(force_file+1, w_file, strlen(w_file));
     force_file[strlen(w_file)+1] = '\0';

     //opening a old file if requested
     fitsfile* old_fptr;
     int old_img_type = 0;
     if(get_head == 1){
          if (lverb > 10){
               fprintf(logfile, 
                    "newfits: copying header from %s to %s \n", w_file, r_file);
          }
          fits_open_file(&(old_fptr), r_file, 0, &fio_err);
          if (fio_err != 0){
               printf("newfits_ fitsio error in open_file: %d\n", fio_err);
               printf("     proceeding with minimal fits header in output\n");
               fits_close_file(old_fptr, &fio_err);
               fio_err = 0;
               get_head = 0;
          }
          fits_get_img_type(old_fptr, &old_img_type, &fio_err);
          if( (old_img_type != (-32)) && (old_img_type != (32)) ){
               printf("newfits_ old img is different size than new img");
               printf("     bitpix old = %d\n", old_img_type);
               printf("     proceeding with minimal fits header in output\n");
               fits_close_file(old_fptr, &fio_err);
               fio_err = 0;
               get_head = 0;
          }
     }
     else{
          if (lverb > 10){
               fprintf(logfile, 
                    "newfits: creating minimal header for %s \n", w_file);
          }
          get_head = 0;
     }
     
     //opening a new file
     fitsfile* fptr;
     fits_create_file(&(fptr), force_file, &fio_err);
     if (fio_err != 0){
          printf("newfits_ fitsio error in create_file: %d\n", fio_err);
          fits_close_file(fptr, &fio_err); 
          if(get_head == 1) fits_close_file(old_fptr, &fio_err);
          return;
     }          
     free(force_file);

     //copy image or create image
     //copy image
     if (get_head == 1){
          fits_copy_file(old_fptr, fptr, 1, 1, 1, &fio_err);
          if (fio_err != 0){
               printf("newfits_ fitsio error in copy_image: %d\n", fio_err);
               printf("     proceeding with minimal fits header in output\n");
               if (lverb > 10){
                    fprintf(logfile, 
                         "newfits: creating minimal header for %s \n", w_file);
               }
               fits_close_file(old_fptr, &fio_err);
               fio_err = 0;
               get_head = 0;
          } 
          fits_close_file(old_fptr, &fio_err); 
          if (fio_err != 0){
               printf("newfits_ fitsio error in close_file (old): %d\n", fio_err);
               return;
          }          
     } 

     //create image
     short int fpixel = 1;
     short int naxis = 2; //number of axes
     long int nelements = (long int)(nx*ny);
     long int naxes[2] = {nx, ny};
     if(get_head == 0){
          fits_create_img(fptr, LONG_IMG, naxis, naxes, &fio_err);
          if (fio_err != 0){
               printf("newfits_ fitsio error in create_image: %d\n", fio_err);
               fits_close_file(fptr, &fio_err); 
               if(get_head == 1) fits_close_file(old_fptr, &fio_err);
               return;
          } 
     }         
   
     //recast 2d to 1d array so it is done properly
     int* pic_ptr = malloc_int_1darr(nx*ny);
     recast_int_2dto1darr(ny, nx, pic_ptr, pic);

     //write the array
     fits_write_img(fptr, TINT, fpixel, nelements, 
                    pic_ptr, &fio_err); 
     if (fio_err != 0){
          printf("newfits_ fitsio error in write_image: %d\n", fio_err);
          fits_close_file(fptr, &fio_err); 
          if(get_head == 1) fits_close_file(old_fptr, &fio_err);
          return;
     }          

     free(pic_ptr);

     fits_close_file(fptr, &fio_err); 
     if (fio_err != 0){
          printf("newfits_ fitsio error in close_file (new): %d\n", fio_err);
          return;
     }          

     return;
}
Exemple #4
0
int main(int argc, char *argv[])
{
    char opt, *framename, *listname, *outname, *e_outname, buffer[BUFSIZ];
    int n, row, col, cX, cY, npatch, npxi, npxt, nprof;
    int flag_autoname, flag_verbose, status, bitmask[YAR][XAR];
    long xsize, ysize, lowleft[DIM], upright[DIM], increment[DIM] = {1L, 1L}, framesize[DIM];
    float mask_val, cutoff, framefragment[YAR][XAR];
    struct star* patchstars;
    FILE *listfile;
    fitsfile *frame, *maskedframe;
    extern char *optarg;
    extern int opterr;


    framename = NULL;
    listname = NULL;
    outname = NULL;
    mask_val = DEFAULT_MASK;
    cutoff = DEFAULT_CUTOFF;
    flag_autoname = 1;
    flag_verbose = 0;

    opterr = 0;
    while ((opt=getopt(argc, argv, "f:l:o:m:c:v")) != -1) {
        switch (opt) {
            case 'f':
                framename = optarg;
                break;
            case 'l':
                listname = optarg;
                break;
            case 'o':
                flag_autoname = 0;
                outname = optarg;
                break;
            case 'm':
                mask_val = atof(optarg);
                break;
            case 'c':
                cutoff = atof(optarg);
                break;
            case 'v':
                flag_verbose = 1;
                break;
            default:
                usage(argv);
        }
    }

    /* check mandatory parameters: */
    if (framename == NULL || listname == NULL)
        usage(argv);

    if (cutoff < 0.0) {
        fprintf(stderr, " WARNING: invalid cut-off value (%.1f ADU), using default (%.1f ADU)\n",
            cutoff, DEFAULT_CUTOFF);
        cutoff = DEFAULT_CUTOFF;
    }

    /* read ID and coordinates from any single-lined Daophot output, detect and skip the header if necessary: */
    if ((listfile=fopen(listname, "r")) == NULL) {
        file_read_error(listname);
    } else {
        npatch = line_count(listfile);

        if (has_daophot_header(listfile) == 1) {
            npatch -= DAO_HEADER_SIZE;
            line_skip(listfile, DAO_HEADER_SIZE);
        }

        if (npatch <= 0) {
            fclose(listfile);
            fprintf(stderr, " couldn't read contents of '%s', exiting.\n\n", listname);
            exit(EXIT_FAILURE);
        }

        patchstars = calloc(npatch, sizeof(struct star));
        if (patchstars == NULL) {
            fclose(listfile);
            memory_error();
        }

        for (n=0; n < npatch; n++) {
            fgets(buffer, BUFSIZ, listfile);
            sscanf(buffer, "%d %lf %lf", &patchstars[n].num, &patchstars[n].X, &patchstars[n].Y);
        }

        fclose(listfile);
    }

    status = 0;

    fits_open_file(&frame, framename, READONLY, &status);
    if (status != 0) {
        free(patchstars);
        file_read_error(framename);
    }

    fits_get_img_size(frame, DIM, framesize, &status); fits_print_error(status);
    xsize = framesize[0];
    ysize = framesize[1];
    printf(" %s: %ld x %ld pixels\n", framename, xsize, ysize);
    printf(" %s: %d stars in the list\n", listname, npatch);
    printf(" mask value: %.1f ADU\n", mask_val);
    printf(" cut-off level: %.1f ADU\n", cutoff);

    if (flag_autoname == 1) {
        outname = expand_filename(framename, "-msk", 0, 0);
        if (outname == NULL) {
            free(patchstars);
            fits_close_file(frame, &status);
            memory_error();
        }
    }
    printf(" output file: %s\n", outname);

    /* force cfitsio to overwrite already existing file (prepend ! to the filename) */
    e_outname = prepend_bang(outname);
    if (e_outname == NULL) {
        free(patchstars);
        fits_close_file(frame, &status);
        memory_error();
    }

    /* create output (masked) frame: */
    fits_create_file(&maskedframe, e_outname, &status); fits_print_error(status);

    free(e_outname);
    if (flag_autoname == 1)  /* only necessary if outname was created automatically */
        free(outname);

    fits_copy_file(frame, maskedframe, 1, 1, 1, &status); fits_print_error(status);

    npxt = 0;
    nprof = 0;

    /* process the stars in the list: */
    for (n=0; n < npatch; n++)
    {
        if (flag_verbose == 1)
            printf("\n star #%d:\n", patchstars[n].num);

        /* cfitsio doesn't understand fractional pixels, round the coordinates to nearest integer: */
        cX = rint(patchstars[n].X);
        cY = rint(patchstars[n].Y);

        /* make sure center is in the picture, skip this star if it is not: */
        if (cX < 1 || cY < 1 || cX > xsize || cY > ysize) {
            printf(" star #%d is outside the frame (%d,%d), skipping.\n", patchstars[n].num, cX, cY);
            continue;
        }
       /*
        *  in fitsio pixel index runs from 1 to N, not from 0 to N-1.
        *  consider XAR=21 (reading 10 pixels right and left from center), XSIZE=2044.
        *  example 1: star with x=10. fitsio will reach and try to read pixel at x=0, ILLEGAL.
        *  example 2: star with x=2034. fitsio will reach and try to read pixel at x=2044, LEGAL.
        *  we have to use LESS OR EQUAL when checking lower and left boundary,
        *  for upper and right boundary only using GREATER is fine
        */
        else if (cX <= (XAR-1)/2 || cY <= (YAR-1)/2 || cX > xsize-(XAR-1)/2 || cY > ysize-(YAR-1)/2) {
            printf(" star #%d is too close to the edge or partially outside the frame (%d,%d), skipping.\n",
                patchstars[n].num, cX, cY);
            continue;
        }

        if (flag_verbose == 1)
            printf(" coordinates of star #%d center in current frame: (%d,%d)\n", patchstars[n].num, cX, cY);

        /* compute the coordinates of lower left and upper right pixel: */
        lowleft[0] = cX - (XAR-1)/2;
        lowleft[1] = cY - (YAR-1)/2;
        upright[0] = cX + (XAR-1)/2;
        upright[1] = cY + (YAR-1)/2;

        /* load frame fragment with the star into table: */
        fits_read_subset(frame, TFLOAT, lowleft, upright, increment, 0, framefragment, 0, &status); fits_print_error(status);

        /* initialise the bitmask with zeros: */
        for (row=0; row < YAR; row++)
            for (col=0; col < XAR; col++)
                bitmask[row][col] = 0;

        /* detect holes and write to bitmask: */
        for (row=YAR-1; row >= 0; row--)
            examine_row(framefragment, bitmask, row, cutoff);

        for (col=0; col < XAR; col++)
            examine_col(framefragment, bitmask, col, cutoff);

        npxi = apply_bitmask(framefragment, bitmask, mask_val);
        npxt += npxi;
        if (npxi > 0)
            ++nprof;

        if (flag_verbose == 1) {
            printf("\n");
            print_bitmask(bitmask);
            printf("\n star %d: %d pixels masked\n", patchstars[n].num, npxi);
        }

        /* write the modified frame subsection to output frame: */
        fits_write_subset(maskedframe, TFLOAT, lowleft, upright, framefragment, &status); fits_print_error(status);
    }

    printf(" %d pixels were masked in %d stars.\n", npxt, nprof);

    fits_close_file(frame, &status); fits_print_error(status);
    fits_close_file(maskedframe, &status); fits_print_error(status);

    free(patchstars);

    return 0;
}
int main(int argc, char *argv[])
{
    int numfiles, ii, numrows, rownum, ichan, itsamp, datidx;
    int spec_per_row, status, maxrows;
    unsigned long int maxfilesize;
    float offset, scale, datum, packdatum, maxval, fulltsubint;
    float *datachunk;
    FILE **infiles;
    struct psrfits pfin, pfout;
    Cmdline *cmd;
    fitsfile *infits, *outfits;
    char outfilename[128], templatename[128], tform[8];
    char *pc1, *pc2;
    int first = 1, dummy = 0, nclipped;
    short int *inrowdata;
    unsigned char *outrowdata;

    if (argc == 1) {
        Program = argv[0];
        usage();
        exit(1);
    }
    // Parse the command line using the excellent program Clig
    cmd = parseCmdline(argc, argv);
    numfiles = cmd->argc;
    infiles = (FILE **) malloc(numfiles * sizeof(FILE *));

    //Set the max. total size (in bytes) of all rows in an output file,
    //leaving some room for PSRFITS header
    maxfilesize = (unsigned long int)(cmd->numgb * GB);
    maxfilesize = maxfilesize - 1000*KB;
    //fprintf(stderr,"cmd->numgb: %f maxfilesize: %ld\n",cmd->numgb,maxfilesize);

#ifdef DEBUG
    showOptionValues();
#endif

    printf("\n         PSRFITS 16-bit to 4-bit Conversion Code\n");
    printf("         by J. Deneva, S. Ransom, & S. Chatterjee\n\n");

    // Open the input files
    status = 0;                 //fits_close segfaults if this is not initialized
    printf("Reading input data from:\n");
    for (ii = 0; ii < numfiles; ii++) {
        printf("  '%s'\n", cmd->argv[ii]);

        //Get the file basename and number from command-line argument
        //(code taken from psrfits2fil)
        pc2 = strrchr(cmd->argv[ii], '.');      // at .fits
        *pc2 = 0;               // terminate string
        pc1 = pc2 - 1;
        while ((pc1 >= cmd->argv[ii]) && isdigit(*pc1))
            pc1--;
        if (pc1 <= cmd->argv[ii]) {     // need at least 1 char before filenum
            puts("Illegal input filename. must have chars before the filenumber");
            exit(1);
        }
        pc1++;                  // we were sitting on "." move to first digit
        pfin.filenum = atoi(pc1);
        pfin.fnamedigits = pc2 - pc1;   // how many digits in filenumbering scheme.
        *pc1 = 0;               // null terminate the basefilename
        strcpy(pfin.basefilename, cmd->argv[ii]);
        pfin.initialized = 0;   // set to 1 in  psrfits_open()
        pfin.status = 0;
        //(end of code taken from psrfits2fil)

        //Open the existing psrfits file
        if (psrfits_open(&pfin, READONLY) != 0) {
            fprintf(stderr, "error opening file\n");
            fits_report_error(stderr, pfin.status);
            exit(1);
        }
        // Create the subint arrays
        if (first) {
            pfin.sub.dat_freqs = (float *) malloc(sizeof(float) * pfin.hdr.nchan);
            pfin.sub.dat_weights = (float *) malloc(sizeof(float) * pfin.hdr.nchan);
            pfin.sub.dat_offsets =
                (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol);
            pfin.sub.dat_scales =
                (float *) malloc(sizeof(float) * pfin.hdr.nchan * pfin.hdr.npol);
            //first is set to 0 after data buffer allocation further below
        }

        infits = pfin.fptr;
        spec_per_row = pfin.hdr.nsblk;
	fits_read_key(infits, TINT, "NAXIS2", &dummy, NULL, &status);
	pfin.tot_rows = dummy;
        numrows = dummy;

	//If dealing with 1st input file, create output template
	if (ii == 0) {
	  sprintf(templatename, "%s.template.fits",cmd->outfile);
	  fits_create_file(&outfits, templatename, &status);
	  //fprintf(stderr,"pfin.basefilename: %s\n", pfin.basefilename);
	  //fprintf(stderr,"status: %d\n", status);
	  
	  //Instead of copying HDUs one by one, can move to the SUBINT
	  //HDU, and copy all the HDUs preceding it
	  fits_movnam_hdu(infits, BINARY_TBL, "SUBINT", 0, &status);
	  fits_copy_file(infits, outfits, 1, 0, 0, &status);
	  
	  //Copy the SUBINT table header
	  fits_copy_header(infits, outfits, &status);
	  fits_flush_buffer(outfits, 0, &status);
	  
	  //Set NAXIS2 in the output SUBINT table to 0 b/c we haven't 
	  //written any rows yet
	  dummy = 0;
	  fits_update_key(outfits, TINT, "NAXIS2", &dummy, NULL, &status);
	  
	  //Edit the NBITS key
	  if (DEBUG) {
	    dummy = 8;
	    fits_update_key(outfits, TINT, "NBITS", &dummy, NULL, &status);
	  } else {
	    fits_update_key(outfits, TINT, "NBITS", &(cmd->numbits), NULL,
			    &status);
	  }
	  
	  //Edit the TFORM17 column: # of data bytes per row 
	  //fits_get_colnum(outfits,1,"DATA",&dummy,&status);
	  if (DEBUG)
	    sprintf(tform, "%dB",
		    pfin.hdr.nsblk * pfin.hdr.nchan * pfin.hdr.npol);
	  else
	    sprintf(tform, "%dB", pfin.hdr.nsblk * pfin.hdr.nchan *
		    pfin.hdr.npol * cmd->numbits / 8);
	  
	  fits_update_key(outfits, TSTRING, "TTYPE17", "DATA", NULL, &status);
	  fits_update_key(outfits, TSTRING, "TFORM17", tform, NULL, &status);
	  
	  //Edit NAXIS1: row width in bytes
	  fits_read_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status);
	  if (DEBUG) {
	    dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan *
	      pfin.hdr.npol * (pfin.hdr.nbits - 8) / 8;
	  } else {
	    dummy = dummy - pfin.hdr.nsblk * pfin.hdr.nchan *
	      pfin.hdr.npol * (pfin.hdr.nbits - cmd->numbits) / 8;
	  }
	  fits_update_key(outfits, TINT, "NAXIS1", &dummy, NULL, &status);
	  
	  //Set the max # of rows per file, based on the requested 
	  //output file size
	  maxrows = maxfilesize / dummy;
	  //fprintf(stderr,"maxrows: %d\n",maxrows);

	  fits_close_file(outfits, &status);
	  
	  rownum = 0;
	}
	
        while (psrfits_read_subint(&pfin, first) == 0) {
	  fprintf(stderr, "Working on row %d\n", ++rownum);
	  
	  //If this is the first row, store the length of a full subint
	  if (ii == 0 && rownum == 1)
	    fulltsubint = pfin.sub.tsubint;

	  //If this is the last row and it's partial, drop it.
	  //(It's pfin.rownum-1 below because the rownum member of the psrfits struct seems to be intended to indicate at the *start* of what row we are, i.e. a row that has not yet been read. In contrast, pfout.rownum indicates how many rows have been written, i.e. at the *end* of what row we are in the output.)
	  
	  if (pfin.rownum-1 == numrows && fabs(pfin.sub.tsubint - fulltsubint) > pfin.hdr.dt) {
	    fprintf(stderr,
		    "Dropping partial row of length %f s (full row is %f s)\n",
		    pfin.sub.tsubint, fulltsubint);
	    break;
	  }
	  
	  //If we just read in the 1st row, or if we already wrote the last row in the current output file, create a new output file
	  if ((ii == 0 && rownum == 1) || pfout.rownum == maxrows) {
	    //Create new output file from the template
	    pfout.fnamedigits = pfin.fnamedigits;
	    if(ii == 0)
	      pfout.filenum = pfin.filenum;
	    else
	      pfout.filenum++;
	    
	    sprintf(outfilename, "%s.%0*d.fits", cmd->outfile, pfout.fnamedigits, pfout.filenum);
	    fits_create_template(&outfits, outfilename, templatename, &status);
	    //fprintf(stderr,"After fits_create_template, status: %d\n",status);
	    fits_close_file(outfits, &status);
	    
	    //Now reopen the file so that the pfout structure is initialized
	    pfout.status = 0;
	    pfout.initialized = 0;
	    
	    sprintf(pfout.basefilename, "%s.", cmd->outfile);
	    
            if (psrfits_open(&pfout, READWRITE) != 0) {
	      fprintf(stderr, "error opening file\n");
	      fits_report_error(stderr, pfout.status);
	      exit(1);
            }
            outfits = pfout.fptr;
            maxval = pow(2, cmd->numbits) - 1;
	    pfout.rows_per_file = maxrows;
	    
            //fprintf(stderr, "maxval: %f\n", maxval);
	    //fprintf(stderr, "pfout.rows_per_file: %d\n",pfout.rows_per_file);
	    
            //These are not initialized in psrfits_open but are needed 
            //in psrfits_write_subint (not obvious what are the corresponding 
            //fields in any of the psrfits table headers)
            pfout.hdr.ds_freq_fact = 1;
            pfout.hdr.ds_time_fact = 1;
	  }

            //Copy the subint struct from pfin to pfout, but correct 
            //elements that are not the same 
            pfout.sub = pfin.sub;       //this copies array pointers too
            pfout.sub.bytes_per_subint =
                pfin.sub.bytes_per_subint * pfout.hdr.nbits / pfin.hdr.nbits;
            pfout.sub.dataBytesAlloced = pfout.sub.bytes_per_subint;
            pfout.sub.FITS_typecode = TBYTE;

            if (first) {
                //Allocate scaling buffer and output buffer
                datachunk = gen_fvect(spec_per_row);
                outrowdata = gen_bvect(pfout.sub.bytes_per_subint);

                first = 0;
            }
            pfout.sub.data = outrowdata;

            inrowdata = (short int *) pfin.sub.data;
            nclipped = 0;

            // Loop over all the channels:
            for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol; ichan++) {
                // Populate datachunk[] by picking out all time samples for ichan
                for (itsamp = 0; itsamp < spec_per_row; itsamp++)
                    datachunk[itsamp] = (float) (inrowdata[ichan + itsamp *
                                                           pfout.hdr.nchan *
                                                           pfout.hdr.npol]);

                // Compute the statistics here, and put the offsets and scales in
                // pf.sub.dat_offsets[] and pf.sub.dat_scales[]

                if (rescale(datachunk, spec_per_row, cmd->numbits, &offset, &scale)
                    != 0) {
                    printf("Rescale routine failed!\n");
                    return (-1);
                }
                pfout.sub.dat_offsets[ichan] = offset;
                pfout.sub.dat_scales[ichan] = scale;

                // Since we have the offset and scale ready, rescale the data:
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datum = (scale == 0.0) ? 0.0 :
                        roundf((datachunk[itsamp] - offset) / scale);
                    if (datum < 0.0) {
                        datum = 0;
                        nclipped++;
                    } else if (datum > maxval) {
                        datum = maxval;
                        nclipped++;
                    }

                    inrowdata[ichan + itsamp * pfout.hdr.nchan * pfout.hdr.npol] =
                        (short int) datum;

                }
                // Now inrowdata[ichan] contains rescaled ints.
            }

            // Then do the conversion and store the
            // results in pf.sub.data[] 
            if (cmd->numbits == 8 || DEBUG) {
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol;
                    for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol;
                         ichan++, datidx++) {
                        pfout.sub.data[datidx] = (unsigned char) inrowdata[datidx];
                    }
                }
            } else if (cmd->numbits == 4) {
                for (itsamp = 0; itsamp < spec_per_row; itsamp++) {
                    datidx = itsamp * pfout.hdr.nchan * pfout.hdr.npol;
                    for (ichan = 0; ichan < pfout.hdr.nchan * pfout.hdr.npol;
                         ichan += 2, datidx += 2) {

                        packdatum = inrowdata[datidx] * 16 + inrowdata[datidx + 1];
                        pfout.sub.data[datidx / 2] = (unsigned char) packdatum;
                    }
                }
            } else {
                fprintf(stderr, "Only 4 or 8-bit output formats supported.\n");
                fprintf(stderr, "Bits per sample requested: %d\n", cmd->numbits);
                exit(1);
            }


            //pfout.sub.offs = (pfout.tot_rows+0.5) * pfout.sub.tsubint;
            fprintf(stderr, "nclipped: %d fraction clipped: %f\n", nclipped,
                    (float) nclipped / (pfout.hdr.nchan * pfout.hdr.npol *
                                        pfout.hdr.nsblk));

            // Now write the row. 
            status = psrfits_write_subint(&pfout);
            if (status) {
                printf("\nError (%d) writing PSRFITS...\n\n", status);
                break;
            }

	    //If current output file has reached the max # of rows, close it
	    if (pfout.rownum == maxrows)
	      fits_close_file(outfits, &status);
        }

        //Close the files 
        fits_close_file(infits, &status);
    }

    fits_close_file(outfits, &status);

    // Free the structure arrays too...
    free(datachunk);
    free(infiles);

    free(pfin.sub.dat_freqs);
    free(pfin.sub.dat_weights);
    free(pfin.sub.dat_offsets);
    free(pfin.sub.dat_scales);

    free(pfin.sub.data);
    free(pfout.sub.data);
    free(pfin.sub.stat);

    return 0;
}