示例#1
0
/*--------------------------------------------------------------------------*/
int ffcpfl(fitsfile *infptr,    /* I - FITS file pointer to input file  */
           fitsfile *outfptr,   /* I - FITS file pointer to output file */
           int previous,        /* I - copy any previous HDUs?   */
           int current,         /* I - copy the current HDU?     */
           int following,       /* I - copy any following HDUs?   */
           int *status)         /* IO - error status     */
/*
  copy all or part of the input file to the output file.
*/
{
    int hdunum, ii;

    if (*status > 0)
        return(*status);

    if (infptr == outfptr)
        return(*status = SAME_FILE);

    ffghdn(infptr, &hdunum);

    if (previous) {   /* copy any previous HDUs */
        for (ii=1; ii < hdunum; ii++) {
            ffmahd(infptr, ii, NULL, status);
            ffcopy(infptr, outfptr, 0, status);
        }
    }

    if (current && (*status <= 0) ) {  /* copy current HDU */
        ffmahd(infptr, hdunum, NULL, status);
        ffcopy(infptr, outfptr, 0, status);
    }

    if (following && (*status <= 0) ) { /* copy any remaining HDUs */
        ii = hdunum + 1;
        while (1)
        { 
            if (ffmahd(infptr, ii, NULL, status) ) {
                 /* reset expected end of file status */
                 if (*status == END_OF_FILE)
                    *status = 0;
                 break;
            }

            if (ffcopy(infptr, outfptr, 0, status))
                 break;  /* quit on unexpected error */

            ii++;
        }
    }

    ffmahd(infptr, hdunum, NULL, status);  /* restore initial position */
    return(*status);
}
示例#2
0
/*--------------------------------------------------------------------------*/
int ffpextn( fitsfile *fptr,        /* I - FITS file pointer                        */
            LONGLONG  offset,      /* I - byte offset from start of extension data */
            LONGLONG  nelem,       /* I - number of elements to write              */
            void *buffer,          /* I - stream of bytes to write                 */
            int  *status)          /* IO - error status                            */
/*
  Write a stream of bytes to the current FITS HDU.  This primative routine is mainly
  for writing non-standard "conforming" extensions and should not be used
  for standard IMAGE, TABLE or BINTABLE extensions.
*/
{
    if (*status > 0)           /* inherit input status value if > 0 */
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    /* rescan header if data structure is undefined */
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
        if ( ffrdef(fptr, status) > 0)               
            return(*status);

    /* move to write position */
    ffmbyt(fptr, (fptr->Fptr)->datastart+ offset, IGNORE_EOF, status);
    
    /* write the buffer */
    ffpbyt(fptr, nelem, buffer, status); 

    return(*status);
}
示例#3
0
/*--------------------------------------------------------------------------*/
int ffpthp(fitsfile *fptr,      /* I - FITS file pointer */
           long theap,          /* I - starting addrss for the heap */
           int *status)         /* IO - error status     */
/*
  Define the starting address for the heap for a binary table.
  The default address is NAXIS1 * NAXIS2.  It is in units of
  bytes relative to the beginning of the regular binary table data.
  This routine also writes the appropriate THEAP keyword to the
  FITS header.
*/
{
    if (*status > 0 || theap < 1)
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    (fptr->Fptr)->heapstart = theap;

    ffukyj(fptr, "THEAP", theap, "byte offset to heap area", status);

    return(*status);
}
示例#4
0
/*--------------------------------------------------------------------------*/
int ffpcnd( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
            LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
            LONGLONG  nelem,     /* I - number of values to write               */
            double *array,   /* I - array of values to write                */
            double nulvalue, /* I - value used to flag undefined pixels     */
            int  *status)    /* IO - error status                           */
/*
  Write an array of elements to the specified column of a table.  Any input
  pixels equal to the value of nulvalue will be replaced by the appropriate
  null value in the output FITS file. 

  The input array of values will be converted to the datatype of the column 
  and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary
*/
{
    tcolumn *colptr;
    long  ngood = 0, nbad = 0, ii;
    LONGLONG repeat, first, fstelm, fstrow;
    int tcode, overflow = 0;

    if (*status > 0)
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
    {
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
    }
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
    {
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
            return(*status);
    }

    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
    colptr += (colnum - 1);     /* offset to correct column structure */

    tcode  = colptr->tdatatype;

    if (tcode > 0)
       repeat = colptr->trepeat;  /* repeat count for this column */
    else
       repeat = firstelem -1 + nelem;  /* variable length arrays */

    if (abs(tcode) >= TCOMPLEX)
    { /* treat complex columns as pairs of numbers */
        repeat *= 2;
    }

    /* if variable length array, first write the whole input vector, 
       then go back and fill in the nulls */
    if (tcode < 0) {
      if (ffpcld(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0) {
	if (*status == NUM_OVERFLOW) 
	{
	  /* ignore overflows, which are possibly the null pixel values */
	  /*  overflow = 1;   */
	  *status = 0;
	} else { 
          return(*status);
	}
      }
    }

    /* absolute element number in the column */
    first = (firstrow - 1) * repeat + firstelem;

    for (ii = 0; ii < nelem; ii++)
    {
      if (array[ii] != nulvalue)  /* is this a good pixel? */
      {
         if (nbad)  /* write previous string of bad pixels */
         {
            fstelm = ii - nbad + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

            /* call ffpcluc, not ffpclu, in case we are writing to a
	       complex ('C') binary table column */
            if (ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status) > 0)
                return(*status);

            nbad=0;
         }

         ngood = ngood +1;  /* the consecutive number of good pixels */
      }
      else
      {
         if (ngood)  /* write previous string of good pixels */
         {
            fstelm = ii - ngood + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

            if (tcode > 0) {  /* variable length arrays have already been written */
              if (ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood],
                status) > 0) {
		if (*status == NUM_OVERFLOW) 
		{
		  overflow = 1;
		  *status = 0;
		} else {
                  return(*status);
		}
	      }
            }
            ngood=0;
         }

         nbad = nbad +1;  /* the consecutive number of bad pixels */
      }
    }

    /* finished loop;  now just write the last set of pixels */

    if (ngood)  /* write last string of good pixels */
    {
      fstelm = ii - ngood + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

      if (tcode > 0) {  /* variable length arrays have already been written */
        ffpcld(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status);
      }
    }
    else if (nbad) /* write last string of bad pixels */
    {
      fstelm = ii - nbad + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
      ffpcluc(fptr, colnum, fstrow, fstelm, nbad, status);
    }

    if (*status <= 0) {
      if (overflow) {
        *status = NUM_OVERFLOW;
      }
    }

    return(*status);
}
示例#5
0
/*--------------------------------------------------------------------------*/
int ffpcnd( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            long  firstrow,  /* I - first row to write (1 = 1st row)        */
            long  firstelem, /* I - first vector element to write (1 = 1st) */
            long  nelem,     /* I - number of values to write               */
            double *array,   /* I - array of values to write                */
            double nulvalue, /* I - value used to flag undefined pixels     */
            int  *status)    /* IO - error status                           */
/*
  Write an array of elements to the specified column of a table.  Any input
  pixels equal to the value of nulvalue will be replaced by the appropriate
  null value in the output FITS file. 

  The input array of values will be converted to the datatype of the column 
  and will be inverse-scaled by the FITS TSCALn and TZEROn values if necessary
*/
{
    tcolumn *colptr;
    long  ngood = 0, nbad = 0, ii, fstrow;
    OFF_T large_elem, repeat, first, fstelm;

    if (*status > 0)
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
    {
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
    }
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
    {
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
            return(*status);
    }

    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
    colptr += (colnum - 1);     /* offset to correct column structure */

    repeat = colptr->trepeat;  /* repeat count for this column */

    if (firstelem == USE_LARGE_VALUE)
        large_elem = large_first_elem_val;
    else
        large_elem = firstelem;

    /* hereafter, pass first element parameter via global variable */
    firstelem = USE_LARGE_VALUE;

    /* absolute element number in the column */
    first = (firstrow - 1) * repeat + large_elem;

    for (ii = 0; ii < nelem; ii++)
    {
      if (array[ii] != nulvalue)  /* is this a good pixel? */
      {
         if (nbad)  /* write previous string of bad pixels */
         {
            fstelm = ii - nbad + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
            large_first_elem_val = fstelm;

            if (ffpclu(fptr, colnum, fstrow, firstelem, nbad, status) > 0)
                return(*status);

            nbad=0;
         }

         ngood = ngood +1;  /* the consecutive number of good pixels */
      }
      else
      {
         if (ngood)  /* write previous string of good pixels */
         {
            fstelm = ii - ngood + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
            large_first_elem_val = fstelm;

            if (ffpcld(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood],
                status) > 0)
                return(*status);

            ngood=0;
         }

         nbad = nbad +1;  /* the consecutive number of bad pixels */
      }
    }

    /* finished loop;  now just write the last set of pixels */

    if (ngood)  /* write last string of good pixels */
    {
      fstelm = ii - ngood + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
      large_first_elem_val = fstelm;

      ffpcld(fptr, colnum, fstrow, firstelem, ngood, &array[ii-ngood], status);
    }
    else  /* write last string of bad pixels */
    {
      fstelm = ii - nbad + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */
      large_first_elem_val = fstelm;

      ffpclu(fptr, colnum, fstrow, firstelem, nbad, status);
    }

    return(*status);
}
示例#6
0
// ffhist3: same as ffhist2, but does not close the original file,
// and/or replace the original file pointer 
fitsfile *ffhist3(fitsfile *fptr, /* I - ptr to table with X and Y cols*/
           char *outfile,    /* I - name for the output histogram file      */
           int imagetype,    /* I - datatype for image: TINT, TSHORT, etc   */
           int naxis,        /* I - number of axes in the histogram image   */
           char colname[4][FLEN_VALUE],   /* I - column names               */
           double *minin,     /* I - minimum histogram value, for each axis */
           double *maxin,     /* I - maximum histogram value, for each axis */
           double *binsizein, /* I - bin size along each axis               */
           char minname[4][FLEN_VALUE], /* I - optional keywords for min    */
           char maxname[4][FLEN_VALUE], /* I - optional keywords for max    */
           char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */
           double weightin,        /* I - binning weighting factor          */
           char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/
           int recip,              /* I - use reciprocal of the weight?     */
           char *selectrow,        /* I - optional array (length = no. of   */
                             /* rows in the table).  If the element is true */
                             /* then the corresponding row of the table will*/
                             /* be included in the histogram, otherwise the */
                             /* row will be skipped.  Ingnored if *selectrow*/
                             /* is equal to NULL.                           */
           int *status)
{
    fitsfile *histptr;
    int   bitpix, colnum[4], wtcolnum;
    long haxes[4];
    float amin[4], amax[4], binsize[4],  weight;

    if (*status > 0)
        return(NULL);

    if (naxis > 4)
    {
        ffpmsg("histogram has more than 4 dimensions");
	*status = BAD_DIMEN;
        return(NULL);
    }

    /* reset position to the correct HDU if necessary */
    if ((fptr)->HDUposition != ((fptr)->Fptr)->curhdu)
        ffmahd(fptr, ((fptr)->HDUposition) + 1, NULL, status);

    if (imagetype == TBYTE)
        bitpix = BYTE_IMG;
    else if (imagetype == TSHORT)
        bitpix = SHORT_IMG;
    else if (imagetype == TINT)
        bitpix = LONG_IMG;
    else if (imagetype == TFLOAT)
        bitpix = FLOAT_IMG;
    else if (imagetype == TDOUBLE)
        bitpix = DOUBLE_IMG;
    else{
        *status = BAD_DATATYPE;
        return(NULL);
    }
    
    /*    Calculate the binning parameters:    */
    /*   columm numbers, axes length, min values,  max values, and binsizes.  */

    if (fits_calc_binning(
      fptr, naxis, colname, minin, maxin, binsizein, minname, maxname, binname,
      colnum, haxes, amin, amax, binsize, status) > 0)
    {
       ffpmsg("failed to determine binning parameters");
        return(NULL);
    }
 
    /* get the histogramming weighting factor, if any */
    if (*wtcol)
    {
        /* first, look for a keyword with the weight value */
        if (fits_read_key(fptr, TFLOAT, wtcol, &weight, NULL, status) )
        {
            /* not a keyword, so look for column with this name */
            *status = 0;

            /* get the column number in the table */
            if (ffgcno(fptr, CASEINSEN, wtcol, &wtcolnum, status) > 0)
            {
               ffpmsg(
               "keyword or column for histogram weights doesn't exist: ");
               ffpmsg(wtcol);
               return(NULL);
            }

            weight = FLOATNULLVALUE;
        }
    }
    else
        weight = (float) weightin;

    if (weight <= 0. && weight != FLOATNULLVALUE)
    {
        ffpmsg("Illegal histogramming weighting factor <= 0.");
	*status = URL_PARSE_ERROR;
        return(NULL);
    }

    if (recip && weight != FLOATNULLVALUE)
       /* take reciprocal of weight */
       weight = (float) (1.0 / weight);

    /* size of histogram is now known, so create temp output file */
    if (fits_create_file(&histptr, outfile, status) > 0)
    {
        ffpmsg("failed to create temp output file for histogram");
        return(NULL);
    }

    /* create output FITS image HDU */
    if (ffcrim(histptr, bitpix, naxis, haxes, status) > 0)
    {
        ffpmsg("failed to create output histogram FITS image");
        return(NULL);
    }

    /* copy header keywords, converting pixel list WCS keywords to image WCS form */
    if (fits_copy_pixlist2image(fptr, histptr, 9, naxis, colnum, status) > 0)
    {
        ffpmsg("failed to copy pixel list keywords to new histogram header");
        return(NULL);
    }

    /* if the table columns have no WCS keywords, then write default keywords */
    fits_write_keys_histo(fptr, histptr, naxis, colnum, status);
    
    /* update the WCS keywords for the ref. pixel location, and pixel size */
    fits_rebin_wcs(histptr, naxis, amin, binsize,  status);      
    
    /* now compute the output image by binning the column values */
    if (fits_make_hist(fptr, histptr, bitpix, naxis, haxes, colnum, amin, amax,
        binsize, weight, wtcolnum, recip, selectrow, status) > 0)
    {
        ffpmsg("failed to calculate new histogram values");
        return(NULL);
    }
              
    return(histptr);
}
示例#7
0
/*--------------------------------------------------------------------------*/
int ffdhdu(fitsfile *fptr,      /* I - FITS file pointer                   */
           int *hdutype,        /* O - type of the new CHDU after deletion */
           int *status)         /* IO - error status                       */
/*
  Delete the CHDU.  If the CHDU is the primary array, then replace the HDU
  with an empty primary array with no data.   Return the
  type of the new CHDU after the old CHDU is deleted.
*/
{
    int tmptype = 0;
    long nblocks, ii, naxes[1];

    if (*status > 0)
        return(*status);

    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    if ((fptr->Fptr)->curhdu == 0) /* replace primary array with null image */
    {
        /* ignore any existing keywords */
        (fptr->Fptr)->headend = 0;
        (fptr->Fptr)->nextkey = 0;

        /* write default primary array header */
        ffphpr(fptr,1,8,0,naxes,0,1,1,status);

        /* calc number of blocks to delete (leave just 1 block) */
        nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - 
                2880 ) / 2880);

        /* ffdblk also updates the starting address of all following HDUs */
        if (nblocks > 0)
        {
            if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */
                return(*status);
        }

        /* this might not be necessary, but is doesn't hurt */
        (fptr->Fptr)->datastart = DATA_UNDEFINED;

        ffrdef(fptr, status);  /* reinitialize the primary array */
    }
    else
    {

        /* calc number of blocks to delete */
        nblocks = (long) (( (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu + 1] - 
                (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] ) / 2880);

        /* ffdblk also updates the starting address of all following HDUs */
        if (ffdblk(fptr, nblocks, status) > 0) /* delete the HDU */
            return(*status);

        /* delete the CHDU from the list of HDUs */
        for (ii = (fptr->Fptr)->curhdu + 1; ii <= (fptr->Fptr)->maxhdu; ii++)
            (fptr->Fptr)->headstart[ii] = (fptr->Fptr)->headstart[ii + 1];

        (fptr->Fptr)->headstart[(fptr->Fptr)->maxhdu + 1] = 0;
        ((fptr->Fptr)->maxhdu)--; /* decrement the known number of HDUs */

        if (ffrhdu(fptr, &tmptype, status) > 0)  /* initialize next HDU */
        {
            /* failed (end of file?), so move back one HDU */
            *status = 0;
            ffcmsg();       /* clear extraneous error messages */
            ffgext(fptr, ((fptr->Fptr)->curhdu) - 1, &tmptype, status);
        }
    }

    if (hdutype)
       *hdutype = tmptype;

    return(*status);
}
示例#8
0
/*--------------------------------------------------------------------------*/
int ffibin(fitsfile *fptr,  /* I - FITS file pointer                        */
           LONGLONG naxis2,     /* I - number of rows in the table              */
           int tfields,     /* I - number of columns in the table           */
           char **ttype,    /* I - name of each column                      */
           char **tform,    /* I - value of TFORMn keyword for each column  */
           char **tunit,    /* I - value of TUNITn keyword for each column  */
           const char *extnmx,     /* I - value of EXTNAME keyword, if any         */
           LONGLONG pcount, /* I - size of special data area (heap)         */
           int *status)     /* IO - error status                            */
/*
  insert a Binary table extension following the current HDU 
*/
{
    int nexthdu, maxhdu, ii, nunit, nhead, datacode;
    LONGLONG naxis1;
    long nblocks, repeat, width;
    LONGLONG datasize, newstart;
    char errmsg[81], extnm[FLEN_VALUE];

    if (*status > 0)
        return(*status);

    extnm[0] = '\0';
    if (extnmx)
      strncat(extnm, extnmx, FLEN_VALUE-1);

    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    maxhdu = (fptr->Fptr)->maxhdu;
    /* if the current header is completely empty ...  */
    if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] )
        /* or, if we are at the end of the file, ... */
    ||  ( (((fptr->Fptr)->curhdu) == maxhdu ) &&
       ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) )
    {
        /* then simply append new image extension */
        ffcrtb(fptr, BINARY_TBL, naxis2, tfields, ttype, tform, tunit,
               extnm, status);
        return(*status);
    }

    if (naxis2 < 0)
        return(*status = NEG_ROWS);
    else if (tfields < 0 || tfields > 999)
    {
        sprintf(errmsg,
        "Illegal value for TFIELDS keyword: %d", tfields);
        ffpmsg(errmsg);
        return(*status = BAD_TFIELDS);
    }

    /* count number of optional TUNIT keywords to be written */
    nunit = 0;
    for (ii = 0; ii < tfields; ii++)
    {
        if (tunit && *tunit && *tunit[ii])
            nunit++;
    }

    if (extnm && *extnm)
         nunit++;     /* add one for the EXTNAME keyword */

    nhead = (9 + (2 * tfields) + nunit + 35) / 36;  /* no. of header blocks */

    /* calculate total width of the table */
    naxis1 = 0;
    for (ii = 0; ii < tfields; ii++)
    {
        ffbnfm(tform[ii], &datacode, &repeat, &width, status);

        if (datacode == TBIT)
            naxis1 = naxis1 + ((repeat + 7) / 8);
        else if (datacode == TSTRING)
            naxis1 += repeat;
        else
            naxis1 = naxis1 + (repeat * width);
    }

    datasize = ((LONGLONG)naxis1 * naxis2) + pcount;         /* size of table in bytes */
    nblocks = (long) ((datasize + 2879) / 2880) + nhead;  /* size of HDU */

    if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */
    {   /* close the CHDU */
        ffrdef(fptr, status);  /* scan header to redefine structure */
        ffpdfl(fptr, status);  /* insure correct data file values */
    }
    else
        return(*status = READONLY_FILE);

    nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */
    newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */

    (fptr->Fptr)->hdutype = BINARY_TBL;  /* so that correct fill value is used */

    /* ffiblk also increments headstart for all following HDUs */
    if (ffiblk(fptr, nblocks, 1, status) > 0)  /* insert the blocks */
        return(*status);

    ((fptr->Fptr)->maxhdu)++;      /* increment known number of HDUs in the file */
    for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--)
        (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */

    (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */

    /* set default parameters for this new empty HDU */
    (fptr->Fptr)->curhdu = nexthdu;   /* we are now located at the next HDU */
    fptr->HDUposition = nexthdu;      /* we are now located at the next HDU */
    (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu];  
    (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu];
    (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880);
    (fptr->Fptr)->hdutype = BINARY_TBL;  /* might need to be reset... */

    /* write the required header keywords. This will write PCOUNT = 0 */
    /* so that the variable length data will be written at the right place */
    ffphbn(fptr, naxis2, tfields, ttype, tform, tunit, extnm, pcount,
           status);

    /* redefine internal structure for this HDU (with PCOUNT = 0) */
    ffrdef(fptr, status);

    return(*status);
}
示例#9
0
文件: histo.c 项目: agnwinds/python
/*--------------------------------------------------------------------------*/
int ffhist(fitsfile **fptr,  /* IO - pointer to table with X and Y cols;    */
                             /*     on output, points to histogram image    */
           char *outfile,    /* I - name for the output histogram file      */
           int imagetype,    /* I - datatype for image: TINT, TSHORT, etc   */
           int naxis,        /* I - number of axes in the histogram image   */
           char colname[4][FLEN_VALUE],   /* I - column names               */
           double *minin,     /* I - minimum histogram value, for each axis */
           double *maxin,     /* I - maximum histogram value, for each axis */
           double *binsizein, /* I - bin size along each axis               */
           char minname[4][FLEN_VALUE], /* I - optional keywords for min    */
           char maxname[4][FLEN_VALUE], /* I - optional keywords for max    */
           char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */
           double weightin,        /* I - binning weighting factor          */
           char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/
           int recip,              /* I - use reciprocal of the weight?     */
           char *selectrow,        /* I - optional array (length = no. of   */
                             /* rows in the table).  If the element is true */
                             /* then the corresponding row of the table will*/
                             /* be included in the histogram, otherwise the */
                             /* row will be skipped.  Ingnored if *selectrow*/
                             /* is equal to NULL.                           */
           int *status)
{
    int ii, datatype, repeat, imin, imax, ibin, bitpix, tstatus, use_datamax = 0;
    long haxes[4];
    fitsfile *histptr;
    char errmsg[FLEN_ERRMSG], keyname[FLEN_KEYWORD], card[FLEN_CARD];
    tcolumn *colptr;
    iteratorCol imagepars[1];
    int n_cols = 1, nkeys;
    long  offset = 0;
    long n_per_loop = -1;  /* force whole array to be passed at one time */
    histType histData;    /* Structure holding histogram info for iterator */
    
    float amin[4], amax[4], binsize[4], maxbin[4];
    float datamin = FLOATNULLVALUE, datamax = FLOATNULLVALUE;
    char svalue[FLEN_VALUE];
    double dvalue;
    char cpref[4][FLEN_VALUE];
    char *cptr;

    if (*status > 0)
        return(*status);

    if (naxis > 4)
    {
        ffpmsg("histogram has more than 4 dimensions");
        return(*status = BAD_DIMEN);
    }

    /* reset position to the correct HDU if necessary */
    if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu)
        ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status);

    histData.tblptr     = *fptr;
    histData.himagetype = imagetype;
    histData.haxis      = naxis;
    histData.rowselector = selectrow;

    if (imagetype == TBYTE)
        bitpix = BYTE_IMG;
    else if (imagetype == TSHORT)
        bitpix = SHORT_IMG;
    else if (imagetype == TINT)
        bitpix = LONG_IMG;
    else if (imagetype == TFLOAT)
        bitpix = FLOAT_IMG;
    else if (imagetype == TDOUBLE)
        bitpix = DOUBLE_IMG;
    else
        return(*status = BAD_DATATYPE);

    /* The CPREF keyword, if it exists, gives the preferred columns. */
    /* Otherwise, assume "X", "Y", "Z", and "T"  */

    tstatus = 0;
    ffgky(*fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus);

    if (!tstatus)
    {
        /* Preferred column names are given;  separate them */
        cptr = cpref[0];

        /* the first preferred axis... */
        while (*cptr != ',' && *cptr != '\0')
           cptr++;

        if (*cptr != '\0')
        {
           *cptr = '\0';
           cptr++;
           while (*cptr == ' ')
               cptr++;

           strcpy(cpref[1], cptr);
           cptr = cpref[1];

          /* the second preferred axis... */
          while (*cptr != ',' && *cptr != '\0')
             cptr++;

          if (*cptr != '\0')
          {
             *cptr = '\0';
             cptr++;
             while (*cptr == ' ')
                 cptr++;

             strcpy(cpref[2], cptr);
             cptr = cpref[2];

            /* the third preferred axis... */
            while (*cptr != ',' && *cptr != '\0')
               cptr++;

            if (*cptr != '\0')
            {
               *cptr = '\0';
               cptr++;
               while (*cptr == ' ')
                   cptr++;

               strcpy(cpref[3], cptr);

            }
          }
        }
    }

    for (ii = 0; ii < naxis; ii++)
    {

      /* get the min, max, and binsize values from keywords, if specified */

      if (*minname[ii])
      {
         if (ffgky(*fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) )
         {
             ffpmsg("error reading histogramming minimum keyword");
             ffpmsg(minname[ii]);
             return(*status);
         }
      }

      if (*maxname[ii])
      {
         if (ffgky(*fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) )
         {
             ffpmsg("error reading histogramming maximum keyword");
             ffpmsg(maxname[ii]);
             return(*status);
         }
      }

      if (*binname[ii])
      {
         if (ffgky(*fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) )
         {
             ffpmsg("error reading histogramming binsize keyword");
             ffpmsg(binname[ii]);
             return(*status);
         }
      }

      if (binsizein[ii] == 0.)
      {
        ffpmsg("error: histogram binsize = 0");
        return(*status = ZERO_SCALE);
      }

      if (*colname[ii] == '\0')
      {
         strcpy(colname[ii], cpref[ii]); /* try using the preferred column */
         if (*colname[ii] == '\0')
         {
           if (ii == 0)
              strcpy(colname[ii], "X");
           else if (ii == 1)
              strcpy(colname[ii], "Y");
           else if (ii == 2)
              strcpy(colname[ii], "Z");
           else if (ii == 3)
              strcpy(colname[ii], "T");
         }
      }

      /* get the column number in the table */
      if (ffgcno(*fptr, CASEINSEN, colname[ii], histData.hcolnum+ii, status)
              > 0)
      {
        strcpy(errmsg, "column for histogram axis doesn't exist: ");
        strcat(errmsg, colname[ii]);
        ffpmsg(errmsg);
        return(*status);
      }

      colptr = ((*fptr)->Fptr)->tableptr;
      colptr += (histData.hcolnum[ii] - 1);

      repeat = (int) colptr->trepeat;  /* vector repeat factor of the column */
      if (repeat > 1)
      {
        strcpy(errmsg, "Can't bin a vector column: ");
        strcat(errmsg, colname[ii]);
        ffpmsg(errmsg);
        return(*status = BAD_DATATYPE);
      }

      /* get the datatype of the column */
      fits_get_coltype(*fptr, histData.hcolnum[ii], &datatype,
         NULL, NULL, status);

      if (datatype < 0 || datatype == TSTRING)
      {
        strcpy(errmsg, "Inappropriate datatype; can't bin this column: ");
        strcat(errmsg, colname[ii]);
        ffpmsg(errmsg);
        return(*status = BAD_DATATYPE);
      }

      /* use TLMINn and TLMAXn keyword values if min and max were not given */
      /* else use actual data min and max if TLMINn and TLMAXn don't exist */
 
      if (minin[ii] == DOUBLENULLVALUE)
      {
        ffkeyn("TLMIN", histData.hcolnum[ii], keyname, status);
        if (ffgky(*fptr, TFLOAT, keyname, amin+ii, NULL, status) > 0)
        {
            /* use actual data minimum value for the histogram minimum */
            *status = 0;
            if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], amin+ii, &datamax, status) > 0)
            {
                strcpy(errmsg, "Error calculating datamin and datamax for column: ");
                strcat(errmsg, colname[ii]);
                ffpmsg(errmsg);
                return(*status);
            }
         }
      }
      else
      {
        amin[ii] = (float) minin[ii];
      }

      if (maxin[ii] == DOUBLENULLVALUE)
      {
        ffkeyn("TLMAX", histData.hcolnum[ii], keyname, status);
        if (ffgky(*fptr, TFLOAT, keyname, &amax[ii], NULL, status) > 0)
        {
          *status = 0;
          if(datamax != FLOATNULLVALUE)  /* already computed max value */
          {
             amax[ii] = datamax;
          }
          else
          {
             /* use actual data maximum value for the histogram maximum */
             if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], &datamin, &amax[ii], status) > 0)
             {
                 strcpy(errmsg, "Error calculating datamin and datamax for column: ");
                 strcat(errmsg, colname[ii]);
                 ffpmsg(errmsg);
                 return(*status);
             }
          }
        }
        use_datamax = 1;  /* flag that the max was determined by the data values */
                          /* and not specifically set by the calling program */
      }
      else
      {
        amax[ii] = (float) maxin[ii];
      }

      /* use TDBINn keyword or else 1 if bin size is not given */
      if (binsizein[ii] == DOUBLENULLVALUE)
      {
         tstatus = 0;
         ffkeyn("TDBIN", histData.hcolnum[ii], keyname, &tstatus);

         if (ffgky(*fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0)
         {
	    /* make at least 10 bins */
            binsizein[ii] = (amax[ii] - amin[ii]) / 10. ;
            if (binsizein[ii] > 1.)
                binsizein[ii] = 1.;  /* use default bin size */
         }
      }

      if ( (amin[ii] > amax[ii] && binsizein[ii] > 0. ) ||
           (amin[ii] < amax[ii] && binsizein[ii] < 0. ) )
          binsize[ii] = (float) -binsizein[ii];  /* reverse the sign of binsize */
      else
          binsize[ii] =  (float) binsizein[ii];  /* binsize has the correct sign */

      ibin = (int) binsize[ii];
      imin = (int) amin[ii];
      imax = (int) amax[ii];

      /* Determine the range and number of bins in the histogram. This  */
      /* depends on whether the input columns are integer or floats, so */
      /* treat each case separately.                                    */

      if (datatype <= TLONG && (float) imin == amin[ii] &&
                               (float) imax == amax[ii] &&
                               (float) ibin == binsize[ii] )
      {
        /* This is an integer column and integer limits were entered. */
        /* Shift the lower and upper histogramming limits by 0.5, so that */
        /* the values fall in the center of the bin, not on the edge. */

        haxes[ii] = (imax - imin) / ibin + 1;  /* last bin may only */
                                               /* be partially full */
        maxbin[ii] = (float) (haxes[ii] + 1.);  /* add 1. instead of .5 to avoid roundoff */

        if (amin[ii] < amax[ii])
        {
          amin[ii] = (float) (amin[ii] - 0.5);
          amax[ii] = (float) (amax[ii] + 0.5);
        }
        else
        {
          amin[ii] = (float) (amin[ii] + 0.5);
          amax[ii] = (float) (amax[ii] - 0.5);
        }
      }
      else if (use_datamax)  
      {
        /* Either the column datatype and/or the limits are floating point, */
        /* and the histogram limits are being defined by the min and max */
        /* values of the array.  Add 1 to the number of histogram bins to */
        /* make sure that pixels that are equal to the maximum or are */
        /* in the last partial bin are included.  */

        maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; 
        haxes[ii] = (long) (maxbin[ii] + 1);
      }
      else  
      {
        /*  float datatype column and/or limits, and the maximum value to */
        /*  include in the histogram is specified by the calling program. */
        /*  The lower limit is inclusive, but upper limit is exclusive    */
        maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii];
        haxes[ii] = (long) maxbin[ii];

        if (amin[ii] < amax[ii])
        {
          if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii])
            haxes[ii]++;   /* need to include another partial bin */
        }
        else
        {
          if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii])
            haxes[ii]++;   /* need to include another partial bin */
        }
      }
    }

       /* get the histogramming weighting factor */
    if (*wtcol)
    {
        /* first, look for a keyword with the weight value */
        if (ffgky(*fptr, TFLOAT, wtcol, &histData.weight, NULL, status) )
        {
            /* not a keyword, so look for column with this name */
            *status = 0;

            /* get the column number in the table */
            if (ffgcno(*fptr, CASEINSEN, wtcol, &histData.wtcolnum, status) > 0)
            {
               ffpmsg(
               "keyword or column for histogram weights doesn't exist: ");
               ffpmsg(wtcol);
               return(*status);
            }

            histData.weight = FLOATNULLVALUE;
        }
    }
    else
        histData.weight = (float) weightin;

    if (histData.weight <= 0. && histData.weight != FLOATNULLVALUE)
    {
        ffpmsg("Illegal histogramming weighting factor <= 0.");
        return(*status = URL_PARSE_ERROR);
    }

    if (recip && histData.weight != FLOATNULLVALUE)
       /* take reciprocal of weight */
       histData.weight = (float) (1.0 / histData.weight);

    histData.wtrecip = recip;
        
    /* size of histogram is now known, so create temp output file */
    if (ffinit(&histptr, outfile, status) > 0)
    {
        ffpmsg("failed to create temp output file for histogram");
        return(*status);
    }

    if (ffcrim(histptr, bitpix, histData.haxis, haxes, status) > 0)
    {
        ffpmsg("failed to create primary array histogram in temp file");
        ffclos(histptr, status);
        return(*status);
    }

    /* copy all non-structural keywords from the table to the image */
    fits_get_hdrspace(*fptr, &nkeys, NULL, status);
    for (ii = 1; ii <= nkeys; ii++)
    {
       fits_read_record(*fptr, ii, card, status);
       if (fits_get_keyclass(card) >= 120)
           fits_write_record(histptr, card, status);
    }           

    /* Set global variables with histogram parameter values.    */
    /* Use separate scalar variables rather than arrays because */
    /* it is more efficient when computing the histogram.       */

    histData.amin1 = amin[0];
    histData.maxbin1 = maxbin[0];
    histData.binsize1 = binsize[0];
    histData.haxis1 = haxes[0];

    if (histData.haxis > 1)
    {
      histData.amin2 = amin[1];
      histData.maxbin2 = maxbin[1];
      histData.binsize2 = binsize[1];
      histData.haxis2 = haxes[1];

      if (histData.haxis > 2)
      {
        histData.amin3 = amin[2];
        histData.maxbin3 = maxbin[2];
        histData.binsize3 = binsize[2];
        histData.haxis3 = haxes[2];

        if (histData.haxis > 3)
        {
          histData.amin4 = amin[3];
          histData.maxbin4 = maxbin[3];
          histData.binsize4 = binsize[3];
          histData.haxis4 = haxes[3];
        }
      }
    }

    /* define parameters of image for the iterator function */
    fits_iter_set_file(imagepars, histptr);        /* pointer to image */
    fits_iter_set_datatype(imagepars, imagetype);  /* image datatype   */
    fits_iter_set_iotype(imagepars, OutputCol);    /* image is output  */

    /* call the iterator function to write out the histogram image */
    if (fits_iterate_data(n_cols, imagepars, offset, n_per_loop,
                          ffwritehisto, (void*)&histData, status) )
         return(*status);

    /* write the World Coordinate System (WCS) keywords */
    /* create default values if WCS keywords are not present in the table */
    for (ii = 0; ii < histData.haxis; ii++)
    {
     /*  CTYPEn  */
       tstatus = 0;
       ffkeyn("TCTYP", histData.hcolnum[ii], keyname, &tstatus);
       ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus);
       if (tstatus)
       {               /* just use column name as the type */
          tstatus = 0;
          ffkeyn("TTYPE", histData.hcolnum[ii], keyname, &tstatus);
          ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus);
       }

       if (!tstatus)
       {
        ffkeyn("CTYPE", ii + 1, keyname, &tstatus);
        ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus);
       }
       else
          tstatus = 0;

     /*  CUNITn  */
       ffkeyn("TCUNI", histData.hcolnum[ii], keyname, &tstatus);
       ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus);
       if (tstatus)
       {         /* use the column units */
          tstatus = 0;
          ffkeyn("TUNIT", histData.hcolnum[ii], keyname, &tstatus);
          ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus);
       }

       if (!tstatus)
       {
        ffkeyn("CUNIT", ii + 1, keyname, &tstatus);
        ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus);
       }
       else
         tstatus = 0;

     /*  CRPIXn  - Reference Pixel  */
       ffkeyn("TCRPX", histData.hcolnum[ii], keyname, &tstatus);
       ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus);
       if (tstatus)
       {
         dvalue = 1.0; /* choose first pixel in new image as ref. pix. */
         tstatus = 0;
       }
       else
       {
           /* calculate locate of the ref. pix. in the new image */
           dvalue = (dvalue - amin[ii]) / binsize[ii] + .5;
       }

       ffkeyn("CRPIX", ii + 1, keyname, &tstatus);
       ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus);

     /*  CRVALn - Value at the location of the reference pixel */
       ffkeyn("TCRVL", histData.hcolnum[ii], keyname, &tstatus);
       ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus);
       if (tstatus)
       {
         /* calculate value at ref. pix. location (at center of 1st pixel) */
         dvalue = amin[ii] + binsize[ii]/2.;
         tstatus = 0;
       }

       ffkeyn("CRVAL", ii + 1, keyname, &tstatus);
       ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus);

     /*  CDELTn - unit size of pixels  */
       ffkeyn("TCDLT", histData.hcolnum[ii], keyname, &tstatus);
       ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus);
       if (tstatus)
       {
         dvalue = 1.0;  /* use default pixel size */
         tstatus = 0;
       }

       dvalue = dvalue * binsize[ii];
       ffkeyn("CDELT", ii + 1, keyname, &tstatus);
       ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus);

     /*  CROTAn - Rotation angle (degrees CCW)  */
     /*  There should only be a CROTA2 keyword, and only for 2+ D images */
       if (ii == 1)
       {
         ffkeyn("TCROT", histData.hcolnum[ii], keyname, &tstatus);
         ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus);
         if (!tstatus && dvalue != 0.)  /* only write keyword if angle != 0 */
         {
           ffkeyn("CROTA", ii + 1, keyname, &tstatus);
           ffpky(histptr, TDOUBLE, keyname, &dvalue,
                 "Rotation angle", &tstatus);
         }
         else
         {
            /* didn't find CROTA for the 2nd axis, so look for one */
            /* on the first axis */
           tstatus = 0;
           ffkeyn("TCROT", histData.hcolnum[0], keyname, &tstatus);
           ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus);
           if (!tstatus && dvalue != 0.)  /* only write keyword if angle != 0 */
           {
             dvalue *= -1.;   /* negate the value, because mirror image */
             ffkeyn("CROTA", ii + 1, keyname, &tstatus);
             ffpky(histptr, TDOUBLE, keyname, &dvalue,
                   "Rotation angle", &tstatus);
           }
         }
       }
    }

    /* convert any TPn_k keywords to PCi_j; the value remains unchanged */
    /* also convert any TCn_k to CDi_j; the value is modified by n binning size */
    /* This is a bit of a kludge, and only works for 2D WCS */

    if (histData.haxis == 2) {

      /* PC1_1 */
      tstatus = 0;
      ffkeyn("TP", histData.hcolnum[0], card, &tstatus);
      strcat(card,"_");
      ffkeyn(card, histData.hcolnum[0], keyname, &tstatus);
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) 
         ffpky(histptr, TDOUBLE, "PC1_1", &dvalue, card, &tstatus);

      tstatus = 0;
      keyname[1] = 'C';
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) {
         dvalue *=  binsize[0];
         ffpky(histptr, TDOUBLE, "CD1_1", &dvalue, card, &tstatus);
      }

      /* PC1_2 */
      tstatus = 0;
      ffkeyn("TP", histData.hcolnum[0], card, &tstatus);
      strcat(card,"_");
      ffkeyn(card, histData.hcolnum[1], keyname, &tstatus);
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) 
         ffpky(histptr, TDOUBLE, "PC1_2", &dvalue, card, &tstatus);
 
      tstatus = 0;
      keyname[1] = 'C';
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) {
        dvalue *=  binsize[0];
        ffpky(histptr, TDOUBLE, "CD1_2", &dvalue, card, &tstatus);
      }
       
      /* PC2_1 */
      tstatus = 0;
      ffkeyn("TP", histData.hcolnum[1], card, &tstatus);
      strcat(card,"_");
      ffkeyn(card, histData.hcolnum[0], keyname, &tstatus);
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) 
         ffpky(histptr, TDOUBLE, "PC2_1", &dvalue, card, &tstatus);
 
      tstatus = 0;
      keyname[1] = 'C';
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) {
         dvalue *=  binsize[1];
         ffpky(histptr, TDOUBLE, "CD2_1", &dvalue, card, &tstatus);
      }
       
       /* PC2_2 */
      tstatus = 0;
      ffkeyn("TP", histData.hcolnum[1], card, &tstatus);
      strcat(card,"_");
      ffkeyn(card, histData.hcolnum[1], keyname, &tstatus);
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) 
         ffpky(histptr, TDOUBLE, "PC2_2", &dvalue, card, &tstatus);
        
      tstatus = 0;
      keyname[1] = 'C';
      ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus);
      if (!tstatus) {
         dvalue *=  binsize[1];
         ffpky(histptr, TDOUBLE, "CD2_2", &dvalue, card, &tstatus);
      }
    }   
       
    /* finally, close the original file and return ptr to the new image */
    ffclos(*fptr, status);
    *fptr = histptr;

    return(*status);
}
示例#10
0
/*--------------------------------------------------------------------------*/
int ffiimgll(fitsfile *fptr,    /* I - FITS file pointer           */
           int bitpix,          /* I - bits per pixel              */
           int naxis,           /* I - number of axes in the array */
           LONGLONG *naxes,     /* I - size of each axis           */
           int *status)         /* IO - error status               */
/*
  insert an IMAGE extension following the current HDU 
*/
{
    int bytlen, nexthdu, maxhdu, ii, onaxis;
    long nblocks;
    LONGLONG npixels, newstart, datasize;
    char errmsg[FLEN_ERRMSG], card[FLEN_CARD], naxiskey[FLEN_KEYWORD];

    if (*status > 0)
        return(*status);

    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    maxhdu = (fptr->Fptr)->maxhdu;

    if (*status != PREPEND_PRIMARY)
    {
      /* if the current header is completely empty ...  */
      if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])
        /* or, if we are at the end of the file, ... */
      ||  ( (((fptr->Fptr)->curhdu) == maxhdu ) &&
       ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) )
      {
        /* then simply append new image extension */
        ffcrimll(fptr, bitpix, naxis, naxes, status);
        return(*status);
      }
    }

    if (bitpix == 8)
        bytlen = 1;
    else if (bitpix == 16)
        bytlen = 2;
    else if (bitpix == 32 || bitpix == -32)
        bytlen = 4;
    else if (bitpix == 64 || bitpix == -64)
        bytlen = 8;
    else
    {
        sprintf(errmsg,
        "Illegal value for BITPIX keyword: %d", bitpix);
        ffpmsg(errmsg);
        return(*status = BAD_BITPIX);  /* illegal bitpix value */
    }
    if (naxis < 0 || naxis > 999)
    {
        sprintf(errmsg,
        "Illegal value for NAXIS keyword: %d", naxis);
        ffpmsg(errmsg);
        return(*status = BAD_NAXIS);
    }

    for (ii = 0; ii < naxis; ii++)
    {
        if (naxes[ii] < 0)
        {
            sprintf(errmsg,
            "Illegal value for NAXIS%d keyword: %ld", ii + 1,  (long) naxes[ii]);
            ffpmsg(errmsg);
            return(*status = BAD_NAXES);
        }
    }

    /* calculate number of pixels in the image */
    if (naxis == 0)
        npixels = 0;
    else 
        npixels = naxes[0];

    for (ii = 1; ii < naxis; ii++)
        npixels = npixels * naxes[ii];

    datasize = npixels * bytlen;          /* size of image in bytes */
    nblocks = (long) (((datasize + 2879) / 2880) + 1);  /* +1 for the header */

    if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */
    {   /* close the CHDU */
        ffrdef(fptr, status);  /* scan header to redefine structure */
        ffpdfl(fptr, status);  /* insure correct data file values */
    }
    else
        return(*status = READONLY_FILE);

    if (*status == PREPEND_PRIMARY)
    {
        /* inserting a new primary array; the current primary */
        /* array must be transformed into an image extension. */

        *status = 0;   
        ffmahd(fptr, 1, NULL, status);  /* move to the primary array */

        ffgidm(fptr, &onaxis, status);
        if (onaxis > 0)
            ffkeyn("NAXIS",onaxis, naxiskey, status);
        else
            strcpy(naxiskey, "NAXIS");

        ffgcrd(fptr, naxiskey, card, status);  /* read last NAXIS keyword */
        
        ffikyj(fptr, "PCOUNT", 0, "required keyword", status); /* add PCOUNT and */
        ffikyj(fptr, "GCOUNT", 1, "required keyword", status); /* GCOUNT keywords */

        if (*status > 0)
            return(*status);

        if (ffdkey(fptr, "EXTEND", status) ) /* delete the EXTEND keyword */
            *status = 0;

        /* redefine internal structure for this HDU */
        ffrdef(fptr, status);


        /* insert space for the primary array */
        if (ffiblk(fptr, nblocks, -1, status) > 0)  /* insert the blocks */
            return(*status);

        nexthdu = 0;  /* number of the new hdu */
        newstart = 0; /* starting addr of HDU */
    }
    else
    {
        nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */
        newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */

        (fptr->Fptr)->hdutype = IMAGE_HDU;  /* so that correct fill value is used */
        /* ffiblk also increments headstart for all following HDUs */
        if (ffiblk(fptr, nblocks, 1, status) > 0)  /* insert the blocks */
            return(*status);
    }

    ((fptr->Fptr)->maxhdu)++;      /* increment known number of HDUs in the file */
    for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--)
        (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */

    if (nexthdu == 0)
       (fptr->Fptr)->headstart[1] = nblocks * 2880; /* start of the old Primary array */

    (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */

    /* set default parameters for this new empty HDU */
    (fptr->Fptr)->curhdu = nexthdu;   /* we are now located at the next HDU */
    fptr->HDUposition = nexthdu;      /* we are now located at the next HDU */
    (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu];  
    (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu];
    (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + 2880;
    (fptr->Fptr)->hdutype = IMAGE_HDU;  /* might need to be reset... */

    /* write the required header keywords */
    ffphprll(fptr, TRUE, bitpix, naxis, naxes, 0, 1, TRUE, status);

    /* redefine internal structure for this HDU */
    ffrdef(fptr, status);
    return(*status);
}
示例#11
0
/*--------------------------------------------------------------------------*/
int ffcphd(fitsfile *infptr,    /* I - FITS file pointer to input file  */
           fitsfile *outfptr,   /* I - FITS file pointer to output file */
           int *status)         /* IO - error status     */
/*
  copy the header keywords from infptr to outfptr.
*/
{
    int nkeys, ii, inPrim = 0, outPrim = 0;
    long naxis, naxes[1];
    char *card, comm[FLEN_COMMENT];
    char *tmpbuff;

    if (*status > 0)
        return(*status);

    if (infptr == outfptr)
        return(*status = SAME_FILE);

    /* set the input pointer to the correct HDU */
    if (infptr->HDUposition != (infptr->Fptr)->curhdu)
        ffmahd(infptr, (infptr->HDUposition) + 1, NULL, status);

    if (ffghsp(infptr, &nkeys, NULL, status) > 0) /* get no. of keywords */
        return(*status);

    /* create a memory buffer to hold the header records */
    tmpbuff = (char*) malloc(nkeys*FLEN_CARD*sizeof(char));
    if (!tmpbuff)
        return(*status = MEMORY_ALLOCATION);

    /* read all of the header records in the input HDU */
    for (ii = 0; ii < nkeys; ii++)
      ffgrec(infptr, ii+1, tmpbuff + (ii * FLEN_CARD), status);

    if (infptr->HDUposition == 0)  /* set flag if this is the Primary HDU */
       inPrim = 1;

    /* if input is an image hdu, get the number of axes */
    naxis = -1;   /* negative if HDU is a table */
    if ((infptr->Fptr)->hdutype == IMAGE_HDU)
        ffgkyj(infptr, "NAXIS", &naxis, NULL, status);

    /* set the output pointer to the correct HDU */
    if (outfptr->HDUposition != (outfptr->Fptr)->curhdu)
        ffmahd(outfptr, (outfptr->HDUposition) + 1, NULL, status);

    /* check if output header is empty; if not create new empty HDU */
    if ((outfptr->Fptr)->headend !=
        (outfptr->Fptr)->headstart[(outfptr->Fptr)->curhdu] )
           ffcrhd(outfptr, status);   

    if (outfptr->HDUposition == 0)
    {
        if (naxis < 0)
        {
            /* the input HDU is a table, so we have to create */
            /* a dummy Primary array before copying it to the output */
            ffcrim(outfptr, 8, 0, naxes, status);
            ffcrhd(outfptr, status); /* create new empty HDU */
        }
        else
        {
            /* set flag that this is the Primary HDU */
            outPrim = 1;
        }
    }

    if (*status > 0)  /* check for errors before proceeding */
    {
        free(tmpbuff);
        return(*status);
    }
    if ( inPrim == 1 && outPrim == 0 )
    {
        /* copying from primary array to image extension */
        strcpy(comm, "IMAGE extension");
        ffpkys(outfptr, "XTENSION", "IMAGE", comm, status);

        /* copy BITPIX through NAXISn keywords */
        for (ii = 1; ii < 3 + naxis; ii++)
        {
            card = tmpbuff + (ii * FLEN_CARD);
            ffprec(outfptr, card, status);
        }

        strcpy(comm, "number of random group parameters");
        ffpkyj(outfptr, "PCOUNT", 0, comm, status);
  
        strcpy(comm, "number of random groups");
        ffpkyj(outfptr, "GCOUNT", 1, comm, status);


        /* copy remaining keywords, excluding EXTEND, and reference COMMENT keywords */
        for (ii = 3 + naxis ; ii < nkeys; ii++)
        {
            card = tmpbuff+(ii * FLEN_CARD);
            if (FSTRNCMP(card, "EXTEND  ", 8) &&
                FSTRNCMP(card, "COMMENT   FITS (Flexible Image Transport System) format is", 58) && 
                FSTRNCMP(card, "COMMENT   and Astrophysics', volume 376, page 3", 47) )
            {
                 ffprec(outfptr, card, status);
            }
        }
    }
    else if ( inPrim == 0 && outPrim == 1 )
    {
        /* copying between image extension and primary array */
        strcpy(comm, "file does conform to FITS standard");
        ffpkyl(outfptr, "SIMPLE", TRUE, comm, status);

        /* copy BITPIX through NAXISn keywords */
        for (ii = 1; ii < 3 + naxis; ii++)
        {
            card = tmpbuff + (ii * FLEN_CARD);
            ffprec(outfptr, card, status);
        }

        /* add the EXTEND keyword */
        strcpy(comm, "FITS dataset may contain extensions");
        ffpkyl(outfptr, "EXTEND", TRUE, comm, status);

      /* write standard block of self-documentating comments */
      ffprec(outfptr,
      "COMMENT   FITS (Flexible Image Transport System) format is defined in 'Astronomy",
      status);
      ffprec(outfptr,
      "COMMENT   and Astrophysics', volume 376, page 359; bibcode: 2001A&A...376..359H",
      status);

        /* copy remaining keywords, excluding pcount, gcount */
        for (ii = 3 + naxis; ii < nkeys; ii++)
        {
            card = tmpbuff+(ii * FLEN_CARD);
            if (FSTRNCMP(card, "PCOUNT  ", 8) && FSTRNCMP(card, "GCOUNT  ", 8))
            {
                 ffprec(outfptr, card, status);
            }
        }
    }
    else
    {
        /* input and output HDUs are same type; simply copy all keywords */
        for (ii = 0; ii < nkeys; ii++)
        {
            card = tmpbuff+(ii * FLEN_CARD);
            ffprec(outfptr, card, status);
        }
    }

    free(tmpbuff);
    return(*status);
}
示例#12
0
/*--------------------------------------------------------------------------*/
int ffpcns( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
            LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
            LONGLONG  nelem,     /* I - number of values to write               */
            char  **array,   /* I - array of values to write                */
            char  *nulvalue, /* I - string representing a null value        */
            int  *status)    /* IO - error status                           */
/*
  Write an array of elements to the specified column of a table.  Any input
  pixels flagged as null will be replaced by the appropriate
  null value in the output FITS file. 
*/
{
    long repeat, width, ngood = 0, nbad = 0, ii;
    LONGLONG first, fstelm, fstrow;

    if (*status > 0)
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
    {
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
    }
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
    {
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
            return(*status);
    }

    /* get the vector repeat length of the column */
    ffgtcl(fptr, colnum, NULL, &repeat, &width, status);

    if ((fptr->Fptr)->hdutype == BINARY_TBL)
        repeat = repeat / width;    /* convert from chars to unit strings */

    /* absolute element number in the column */
    first = (firstrow - 1) * repeat + firstelem;

    for (ii = 0; ii < nelem; ii++)
    {
      if (strcmp(nulvalue, array[ii]))  /* is this a good pixel? */
      {
         if (nbad)  /* write previous string of bad pixels */
         {
            fstelm = ii - nbad + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

            if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0)
                return(*status);
            nbad=0;
         }

         ngood = ngood +1;  /* the consecutive number of good pixels */
      }
      else
      {
         if (ngood)  /* write previous string of good pixels */
         {
            fstelm = ii - ngood + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

            if (ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood],
                status) > 0)
                return(*status);

            ngood=0;
         }

         nbad = nbad +1;  /* the consecutive number of bad pixels */
      }
    }

    /* finished loop;  now just write the last set of pixels */

    if (ngood)  /* write last string of good pixels */
    {
      fstelm = ii - ngood + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

      ffpcls(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status);
    }
    else if (nbad) /* write last string of bad pixels */
    {
      fstelm = ii - nbad + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

      ffpclu(fptr, colnum, fstrow, fstelm, nbad, status);
    }

    return(*status);
}
示例#13
0
/*--------------------------------------------------------------------------*/
int ffpcls( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
            LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
            LONGLONG  nelem,     /* I - number of strings to write              */
            char  **array,   /* I - array of pointers to strings            */
            int  *status)    /* IO - error status                           */
/*
  Write an array of string values to a column in the current FITS HDU.
*/
{
    int tcode, maxelem, hdutype, nchar;
    long twidth, incre;
    long ii, jj, ntodo;
    LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull;
    double scale, zero;
    char tform[20], *blanks;
    char message[FLEN_ERRMSG];
    char snull[20];   /*  the FITS null value  */
    tcolumn *colptr;

    double cbuff[DBUFFSIZE / sizeof(double)]; /* align cbuff on word boundary */
    char *buffer, *arrayptr;

    if (*status > 0)           /* inherit input status value if > 0 */
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
    {
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
    }
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
    {
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
            return(*status);
    }

    /*---------------------------------------------------*/
    /*  Check input and get parameters about the column: */
    /*---------------------------------------------------*/
    if (colnum < 1 || colnum > (fptr->Fptr)->tfield)
    {
        sprintf(message, "Specified column number is out of range: %d",
                colnum);
        ffpmsg(message);
        return(*status = BAD_COL_NUM);
    }

    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
    colptr += (colnum - 1);     /* offset to correct column structure */
    tcode = colptr->tdatatype;

    if (tcode == -TSTRING) /* variable length column in a binary table? */
    {
      /* only write a single string; ignore value of firstelem */
      nchar = maxvalue(1,strlen(array[0])); /* will write at least 1 char */
                                          /* even if input string is null */

      if (ffgcprll( fptr, colnum, firstrow, 1, nchar, 1, &scale, &zero,
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);
	
      /* simply move to write position, then write the string */
      ffmbyt(fptr, startpos, IGNORE_EOF, status); 
      ffpbyt(fptr, nchar, array[0], status);

      if (*status > 0)  /* test for error during previous write operation */
      {
         sprintf(message,
          "Error writing to variable length string column (ffpcls).");
         ffpmsg(message);
      }

      return(*status);
    }
    else if (tcode == TSTRING)
    {
      if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero,
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);

      /* if string length is greater than a FITS block (2880 char) then must */
      /* only write 1 string at a time, to force writein by ffpbyt instead of */
      /* ffpbytoff (ffpbytoff can't handle this case) */
      if (twidth > IOBUFLEN) {
        maxelem = 1;
        incre = twidth;
        repeat = 1;
      }   

      blanks = (char *) malloc(twidth); /* string for blank fill values */
      if (!blanks)
      {
        ffpmsg("Could not allocate memory for string (ffpcls)");
        return(*status = ARRAY_TOO_BIG);
      }

      for (ii = 0; ii < twidth; ii++)
          blanks[ii] = ' ';          /* fill string with blanks */

      remain = nelem;           /* remaining number of values to write  */
    }
    else 
      return(*status = NOT_ASCII_COL);
 
    /*-------------------------------------------------------*/
    /*  Now write the strings to the FITS column.            */
    /*-------------------------------------------------------*/

    next = 0;                 /* next element in array to be written  */
    rownum = 0;               /* row number, relative to firstrow     */

    while (remain)
    {
      /* limit the number of pixels to process at one time to the number that
         will fit in the buffer space or to the number of pixels that remain
         in the current vector, which ever is smaller.
      */
      ntodo = (long) minvalue(remain, maxelem);      
      ntodo = (long) minvalue(ntodo, (repeat - elemnum));

      wrtptr = startpos + (rownum * rowlen) + (elemnum * incre);
      ffmbyt(fptr, wrtptr, IGNORE_EOF, status);  /* move to write position */

      buffer = (char *) cbuff;

      /* copy the user's strings into the buffer */
      for (ii = 0; ii < ntodo; ii++)
      {
         arrayptr = array[next];

         for (jj = 0; jj < twidth; jj++)  /*  copy the string, char by char */
         {
            if (*arrayptr)
            {
              *buffer = *arrayptr;
              buffer++;
              arrayptr++;
            }
            else
              break;
         }

         for (;jj < twidth; jj++)    /* fill field with blanks, if needed */
         {
           *buffer = ' ';
           buffer++;
         }

         next++;
      }

      /* write the buffer full of strings to the FITS file */
      if (incre == twidth)
         ffpbyt(fptr, ntodo * twidth, cbuff, status);
      else
         ffpbytoff(fptr, twidth, ntodo, incre - twidth, cbuff, status);

      if (*status > 0)  /* test for error during previous write operation */
      {
         sprintf(message,
          "Error writing elements %.0f thru %.0f of input data array (ffpcls).",
             (double) (next+1), (double) (next+ntodo));
         ffpmsg(message);

         if (blanks)
           free(blanks);

         return(*status);
      }

      /*--------------------------------------------*/
      /*  increment the counters for the next loop  */
      /*--------------------------------------------*/
      remain -= ntodo;
      if (remain)
      {
          elemnum += ntodo;
          if (elemnum == repeat)  /* completed a row; start on next row */
          {
              elemnum = 0;
              rownum++;
          }
       }
    }  /*  End of main while Loop  */

    if (blanks)
      free(blanks);

    return(*status);
}
示例#14
0
文件: tbfxff.c 项目: joequant/iraf
void FSMAHD_U (fitsfile **fptr, int *hdunum, int *exttype, int *status) {

	ffmahd (*fptr, *hdunum, exttype, status);
}
示例#15
0
/*--------------------------------------------------------------------------*/
int ffpclx( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  frow,      /* I - first row to write (1 = 1st row)        */
            long  fbit,      /* I - first bit to write (1 = 1st)            */
            long  nbit,      /* I - number of bits to write                 */
            char *larray,    /* I - array of logicals corresponding to bits */
            int  *status)    /* IO - error status                           */
/*
  write an array of logical values to a specified bit or byte
  column of the binary table.   If larray is TRUE, then the corresponding
  bit is set to 1, otherwise it is set to 0.
  The binary table column being written to must have datatype 'B' or 'X'. 
*/
{
    LONGLONG offset, bstart, repeat, rowlen, elemnum, rstart, estart, tnull;
    long fbyte, lbyte, nbyte, bitloc, ndone;
    long ii, twidth, incre;
    int tcode, descrp, maxelem, hdutype;
    double dummyd;
    char tform[12], snull[12];
    unsigned char cbuff;
    static unsigned char onbit[8] = {128,  64,  32,  16,   8,   4,   2,   1};
    static unsigned char offbit[8] = {127, 191, 223, 239, 247, 251, 253, 254};
    tcolumn *colptr;

    if (*status > 0)           /* inherit input status value if > 0 */
        return(*status);

    /*  check input parameters */
    if (nbit < 1)
        return(*status);
    else if (frow < 1)
        return(*status = BAD_ROW_NUM);
    else if (fbit < 1)
        return(*status = BAD_ELEM_NUM);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    /* rescan header if data structure is undefined */
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
        if ( ffrdef(fptr, status) > 0)               
            return(*status);

    fbyte = (fbit + 7) / 8;
    lbyte = (fbit + nbit + 6) / 8;
    nbyte = lbyte - fbyte +1;

    /* Save the current heapsize; ffgcprll will increment the value if */
    /* we are writing to a variable length column. */
    offset = (fptr->Fptr)->heapsize;

    /* call ffgcprll in case we are writing beyond the current end of   */
    /* the table; it will allocate more space and shift any following */
    /* HDU's.  Otherwise, we have little use for most of the returned */
    /* parameters, therefore just use dummy parameters.               */

    if (ffgcprll( fptr, colnum, frow, fbyte, nbyte, 1, &dummyd, &dummyd,
        tform, &twidth, &tcode, &maxelem, &bstart, &elemnum, &incre,
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);

    bitloc = fbit - 1 - ((fbit - 1) / 8 * 8);
    ndone = 0;
    rstart = frow - 1;
    estart = fbyte - 1;

    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
    colptr += (colnum - 1);     /* offset to correct column structure */

    tcode = colptr->tdatatype;

    if (abs(tcode) > TBYTE)
        return(*status = NOT_LOGICAL_COL); /* not correct datatype column */

    if (tcode > 0)
    {
        descrp = FALSE;  /* not a variable length descriptor column */
        repeat = colptr->trepeat;

        if (tcode == TBIT)
            repeat = (repeat + 7) / 8; /* convert from bits to bytes */

        if (fbyte > repeat)
            return(*status = BAD_ELEM_NUM);

        /* calc the i/o pointer location to start of sequence of pixels */
        bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) +
               colptr->tbcol + estart;
    }
    else
    {
        descrp = TRUE;  /* a variable length descriptor column */
        /* only bit arrays (tform = 'X') are supported for variable */
        /* length arrays.  REPEAT is the number of BITS in the array. */

        repeat = fbit + nbit -1;

        /* write the number of elements and the starting offset.    */
        /* Note: ffgcprll previous wrote the descripter, but with the */
        /* wrong repeat value  (gave bytes instead of bits).        */

        if (tcode == -TBIT)
            ffpdes(fptr, colnum, frow, (long) repeat, offset, status);

        /* Calc the i/o pointer location to start of sequence of pixels.   */
        /* ffgcprll has already calculated a value for bstart that         */
        /* points to the first element of the vector; we just have to      */
        /* increment it to point to the first element we want to write to. */
        /* Note: ffgcprll also already updated the size of the heap, so we */
        /* don't have to do that again here.                               */

        bstart += estart;
    }

    /* move the i/o pointer to the start of the pixel sequence */
    ffmbyt(fptr, bstart, IGNORE_EOF, status);

    /* read the next byte (we may only be modifying some of the bits) */
    while (1)
    {
      if (ffgbyt(fptr, 1, &cbuff, status) == END_OF_FILE)
      {
        /* hit end of file trying to read the byte, so just set byte = 0 */
        *status = 0;
        cbuff = 0;
      }

      /* move back, to be able to overwrite the byte */
      ffmbyt(fptr, bstart, IGNORE_EOF, status);
 
      for (ii = bitloc; (ii < 8) && (ndone < nbit); ii++, ndone++)
      {
        if(larray[ndone])
          cbuff = cbuff | onbit[ii];
        else
          cbuff = cbuff & offbit[ii];
      }

      ffpbyt(fptr, 1, &cbuff, status); /* write the modified byte */

      if (ndone == nbit)  /* finished all the bits */
        return(*status);

      /* not done, so get the next byte */
      bstart++;
      if (!descrp)
      {
        estart++;
        if (estart == repeat)
        {
          /* move the i/o pointer to the next row of pixels */
          estart = 0;
          rstart = rstart + 1;
          bstart = (fptr->Fptr)->datastart + ((fptr->Fptr)->rowlength * rstart) +
               colptr->tbcol;

          ffmbyt(fptr, bstart, IGNORE_EOF, status);
        }
      }
      bitloc = 0;
    }
}
示例#16
0
/*--------------------------------------------------------------------------*/
int ffpcnl( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
            LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
            LONGLONG  nelem,     /* I - number of values to write               */
            char  *array,    /* I - array of values to write                */
            char  nulvalue,  /* I - array flagging undefined pixels if true */
            int  *status)    /* IO - error status                           */
/*
  Write an array of elements to the specified column of a table.  Any input
  pixels flagged as null will be replaced by the appropriate
  null value in the output FITS file. 
*/
{
    tcolumn *colptr;
    long  ngood = 0, nbad = 0, ii;
    LONGLONG repeat, first, fstelm, fstrow;
    int tcode;

    if (*status > 0)
        return(*status);

    /* reset position to the correct HDU if necessary */
    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
    {
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
    }
    else if ((fptr->Fptr)->datastart == DATA_UNDEFINED)
    {
        if ( ffrdef(fptr, status) > 0)               /* rescan header */
            return(*status);
    }

    colptr  = (fptr->Fptr)->tableptr;   /* point to first column */
    colptr += (colnum - 1);     /* offset to correct column structure */

    tcode  = colptr->tdatatype;

    if (tcode > 0)
       repeat = colptr->trepeat;  /* repeat count for this column */
    else
       repeat = firstelem -1 + nelem;  /* variable length arrays */

    /* first write the whole input vector, then go back and fill in the nulls */
    if (ffpcll(fptr, colnum, firstrow, firstelem, nelem, array, status) > 0)
          return(*status);

    /* absolute element number in the column */
    first = (firstrow - 1) * repeat + firstelem;

    for (ii = 0; ii < nelem; ii++)
    {
      if (array[ii] != nulvalue)  /* is this a good pixel? */
      {
         if (nbad)  /* write previous string of bad pixels */
         {
            fstelm = ii - nbad + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

            if (ffpclu(fptr, colnum, fstrow, fstelm, nbad, status) > 0)
                return(*status);

            nbad=0;
         }

         ngood = ngood +1;  /* the consecutive number of good pixels */
      }
      else
      {
         if (ngood)  /* write previous string of good pixels */
         {
            fstelm = ii - ngood + first;  /* absolute element number */
            fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
            fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

/*  good values have already been written
            if (ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood],
                status) > 0)
                return(*status);
*/
            ngood=0;
         }

         nbad = nbad +1;  /* the consecutive number of bad pixels */
      }
    }

    /* finished loop;  now just write the last set of pixels */

    if (ngood)  /* write last string of good pixels */
    {
      fstelm = ii - ngood + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

/*  these have already been written
      ffpcll(fptr, colnum, fstrow, fstelm, ngood, &array[ii-ngood], status);
*/
    }
    else if (nbad) /* write last string of bad pixels */
    {
      fstelm = ii - nbad + first;  /* absolute element number */
      fstrow = (fstelm - 1) / repeat + 1;  /* starting row number */
      fstelm = fstelm - (fstrow - 1) * repeat;  /* relative number */

      ffpclu(fptr, colnum, fstrow, fstelm, nbad, status);
    }

    return(*status);
}
示例#17
0
/*--------------------------------------------------------------------------*/
int ffitab(fitsfile *fptr,  /* I - FITS file pointer                        */
           LONGLONG naxis1,     /* I - width of row in the table                */
           LONGLONG naxis2,     /* I - number of rows in the table              */
           int tfields,     /* I - number of columns in the table           */
           char **ttype,    /* I - name of each column                      */
           long *tbcol,     /* I - byte offset in row to each column        */
           char **tform,    /* I - value of TFORMn keyword for each column  */
           char **tunit,    /* I - value of TUNITn keyword for each column  */
           const char *extnmx,   /* I - value of EXTNAME keyword, if any         */
           int *status)     /* IO - error status                            */
/*
  insert an ASCII table extension following the current HDU 
*/
{
    int nexthdu, maxhdu, ii, nunit, nhead, ncols, gotmem = 0;
    long nblocks, rowlen;
    LONGLONG datasize, newstart;
    char errmsg[81], extnm[FLEN_VALUE];

    if (*status > 0)
        return(*status);

    extnm[0] = '\0';
    if (extnmx)
      strncat(extnm, extnmx, FLEN_VALUE-1);

    if (fptr->HDUposition != (fptr->Fptr)->curhdu)
        ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);

    maxhdu = (fptr->Fptr)->maxhdu;
    /* if the current header is completely empty ...  */
    if (( (fptr->Fptr)->headend == (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] )
        /* or, if we are at the end of the file, ... */
    ||  ( (((fptr->Fptr)->curhdu) == maxhdu ) &&
       ((fptr->Fptr)->headstart[maxhdu + 1] >= (fptr->Fptr)->logfilesize ) ) )
    {
        /* then simply append new image extension */
        ffcrtb(fptr, ASCII_TBL, naxis2, tfields, ttype, tform, tunit,
               extnm, status);
        return(*status);
    }

    if (naxis1 < 0)
        return(*status = NEG_WIDTH);
    else if (naxis2 < 0)
        return(*status = NEG_ROWS);
    else if (tfields < 0 || tfields > 999)
    {
        sprintf(errmsg,
        "Illegal value for TFIELDS keyword: %d", tfields);
        ffpmsg(errmsg);
        return(*status = BAD_TFIELDS);
    }

    /* count number of optional TUNIT keywords to be written */
    nunit = 0;
    for (ii = 0; ii < tfields; ii++)
    {
        if (tunit && *tunit && *tunit[ii])
            nunit++;
    }

    if (extnm && *extnm)
         nunit++;     /* add one for the EXTNAME keyword */

    rowlen = (long) naxis1;

    if (!tbcol || !tbcol[0] || (!naxis1 && tfields)) /* spacing not defined? */
    {
      /* allocate mem for tbcol; malloc may have problems allocating small */
      /* arrays, so allocate at least 20 bytes */

      ncols = maxvalue(5, tfields);
      tbcol = (long *) calloc(ncols, sizeof(long));

      if (tbcol)
      {
        gotmem = 1;

        /* calculate width of a row and starting position of each column. */
        /* Each column will be separated by 1 blank space */
        ffgabc(tfields, tform, 1, &rowlen, tbcol, status);
      }
    }

    nhead = (9 + (3 * tfields) + nunit + 35) / 36;  /* no. of header blocks */
    datasize = (LONGLONG)rowlen * naxis2;          /* size of table in bytes */
    nblocks = (long) (((datasize + 2879) / 2880) + nhead);  /* size of HDU */

    if ((fptr->Fptr)->writemode == READWRITE) /* must have write access */
    {   /* close the CHDU */
        ffrdef(fptr, status);  /* scan header to redefine structure */
        ffpdfl(fptr, status);  /* insure correct data file values */
    }
    else
        return(*status = READONLY_FILE);

    nexthdu = ((fptr->Fptr)->curhdu) + 1; /* number of the next (new) hdu */
    newstart = (fptr->Fptr)->headstart[nexthdu]; /* save starting addr of HDU */

    (fptr->Fptr)->hdutype = ASCII_TBL;  /* so that correct fill value is used */
    /* ffiblk also increments headstart for all following HDUs */
    if (ffiblk(fptr, nblocks, 1, status) > 0)  /* insert the blocks */
    {
        if (gotmem)
            free(tbcol); 
        return(*status);
    }

    ((fptr->Fptr)->maxhdu)++;      /* increment known number of HDUs in the file */
    for (ii = (fptr->Fptr)->maxhdu; ii > (fptr->Fptr)->curhdu; ii--)
        (fptr->Fptr)->headstart[ii + 1] = (fptr->Fptr)->headstart[ii]; /* incre start addr */

    (fptr->Fptr)->headstart[nexthdu] = newstart; /* set starting addr of HDU */

    /* set default parameters for this new empty HDU */
    (fptr->Fptr)->curhdu = nexthdu;   /* we are now located at the next HDU */
    fptr->HDUposition = nexthdu;      /* we are now located at the next HDU */
    (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[nexthdu];  
    (fptr->Fptr)->headend = (fptr->Fptr)->headstart[nexthdu];
    (fptr->Fptr)->datastart = ((fptr->Fptr)->headstart[nexthdu]) + (nhead * 2880);
    (fptr->Fptr)->hdutype = ASCII_TBL;  /* might need to be reset... */

    /* write the required header keywords */

    ffphtb(fptr, rowlen, naxis2, tfields, ttype, tbcol, tform, tunit,
           extnm, status);

    if (gotmem)
        free(tbcol); 

    /* redefine internal structure for this HDU */

    ffrdef(fptr, status);
    return(*status);
}