예제 #1
0
파일: uvsubs_old.c 프로젝트: guille-c/VIR
int get_fqtable(fitsfile *fptr, int hdu, struct uvf_header *header)
{
  int status = 0, i;
  int hdutype, col_iff, type_iff;
  long nrows, rpt_iff, wid_iff;
  double f;

  fits_movabs_hdu(fptr, hdu, &hdutype, &status);
  fits_get_num_rows(fptr, &nrows,  &status);
  fits_get_colnum(fptr, CASEINSEN, "IF FREQ", &col_iff, &status);
  fits_get_coltype(fptr, col_iff, &type_iff, &rpt_iff, &wid_iff,
		   &status);
  if (status || type_iff != TDOUBLE || nrows != 1 || rpt_iff !=
      header->nif)
    fprintf(stderr, "    Warning: Invalid AIPS frequency table\n");
  for (i=0; i < rpt_iff; i++) {
    fits_read_col(fptr, TDOUBLE, col_iff, 1, i+1, 1,
		  NULL, &f, NULL, &status);
    header->iffreq[i] = header->freq + f;
  }
  fprintf(stderr, "    %d IFs ", header->nif);
  for (i=0; i < header->nif; i++)
    fprintf(stderr, " %.2f", header->iffreq[i]*1e-9);
  fprintf(stderr, "\n");
  return status ? 1 : 0;
}
예제 #2
0
int FitsFile::GetTableColumnArraySize(int columnIndex)
{
	CheckOpen();
	int typecode = 0, status = 0;
	long repeat = 0, width = 0;
	fits_get_coltype(_fptr, columnIndex, &typecode, &repeat, &width, &status);
	CheckStatus(status);
	return repeat;
}
예제 #3
0
int FitsFile::GetColumnType(int colNumber)
{
	CheckOpen();
	int typecode, status = 0;
	long repeat, width;
	fits_get_coltype(_fptr, colNumber, &typecode, &repeat, &width, &status);
	CheckStatus(status);
	return typecode;
}
예제 #4
0
float *
supcam_read_data( fitsfile * fits, size_t * numRows, size_t * numChans, int * status ) {

  int colnum = 0;    /* DATA column */
  int fitsStatus = 0; /* CFITSIO status */
  long nRows = 0;
  long nChans = 0;
  long dummy;
  float * data = NULL;
  int typecode = 0;

  /* Initialise the return values */
  *numChans = 0;
  *numRows = 0;

  if (*status != SAI__OK) return NULL;

  /* Prepare to read the Binary Table */
  /* Check number of rows */
  CALLCFITSIO( fits_get_num_rows(fits, &nRows, &fitsStatus), "Error getting number of rows" );

  /* Find DATA column and check its repeat count */
  /* cast because cfitsio does not use const */
  CALLCFITSIO( fits_get_colnum(fits, CASEINSEN, (char *)"DATA", &colnum, &fitsStatus),
               "Error getting column number for DATA" );
  CALLCFITSIO( fits_get_coltype(fits, colnum, &typecode, &nChans, &dummy, &fitsStatus),
               "Error getting column information" );
  if (*status != SAI__OK) return NULL;

  /* Get some memory */
  data = astMalloc( nChans * nRows * sizeof(*data) );

  /* Read DATA column */
  CALLCFITSIO( fits_read_col(fits, TFLOAT, colnum, 1, 1,
                             nChans*nRows, NULL, data, NULL, &fitsStatus),
               "Error reading spectra from Binary Column DATA" );

  if (*status == SAI__OK) {

    /* It looks like there is a bad value of (-1)*VAL__BADI */
    size_t i;
    size_t nelems = nChans * nRows;
    for (i = 0; i < nelems; i++ ) {
      if (data[i] >= (float)(VAL__MAXI - 1)) {
        data[i] = VAL__BADR;
      }
    }

    *numChans = nChans;
    *numRows = nRows;
  }

  return data;
}
예제 #5
0
파일: uvsubs_old.c 프로젝트: guille-c/VIR
int get_antable(fitsfile *fptr, int hdu, struct uvf_header *header)
{
  int status = 0, i;
  int hdutype, col_name, col_xyz, type_name, type_xyz;
  long nrows, rpt_name, rpt_xyz, wid_name, wid_xyz;
  char *string[1];
  int anynull;

  fits_movabs_hdu(fptr, hdu, &hdutype, &status);
  fits_get_num_rows(fptr, &nrows,  &status);
  header->n_antennas = (int) nrows;
  fits_get_colnum(fptr, CASEINSEN, "ANNAME", &col_name, &status);
  fits_get_coltype(fptr, col_name, &type_name, &rpt_name, &wid_name,
		   &status);
  fits_get_colnum(fptr, CASEINSEN, "STABXYZ", &col_xyz, &status);
  fits_get_coltype(fptr, col_xyz, &type_xyz, &rpt_xyz, &wid_xyz,
		   &status);
  if (status || type_name != TSTRING ||
                type_xyz != TDOUBLE || rpt_xyz != 3)
    fprintf(stderr, "    Warning: Invalid AIPS antenna table: %d %ld %d %ld\n",
	    type_name, rpt_name, type_xyz, rpt_xyz);
  for (i=0; i < nrows; i++) {
    string[0] = header->antenna[i].name;
    fits_read_col(fptr, TSTRING, col_name, i+1, 1, 1,
		  "NONAME", string, &anynull, &status);
    fits_read_col(fptr, TDOUBLE, col_xyz, i+1, 1, 1,
		  NULL, &(header->antenna[i].x), NULL, &status);
    fits_read_col(fptr, TDOUBLE, col_xyz, i+1, 2, 1,
		  NULL, &(header->antenna[i].y), NULL, &status);
    fits_read_col(fptr, TDOUBLE, col_xyz, i+1, 3, 1,
		  NULL, &(header->antenna[i].z), NULL, &status);
    if (DEBUG)
      fprintf(stderr, "    %s %8.3f %8.3f %8.3f\n", header->antenna[i].name,
	      header->antenna[i].x, header->antenna[i].y, header->antenna[i].z);
  }
  fprintf(stderr, "    %d antennas ", (int) nrows);
  for (i=0; i < nrows; i++)
    fprintf(stderr, " %s", header->antenna[i].name);
  fprintf(stderr, "\n");
  return status ? 1 : 0;
}
예제 #6
0
void WMAPSource::addToMetadata( fitsfile *ffits, const int iNumCols, int &iStatus )
{
  QString str;
  char charTemplate[ FLEN_CARD ];
  char charName[ FLEN_CARD ];
  long lRepeat;
  long lWidth;
  int iTypeCode;
  int iColNumber;
  int iResult;
  int entry;
  int col;

  for( col=0; col<iNumCols; col++ )
  {
    iResult = fits_get_coltype( ffits, col+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
    if( iResult == 0 )
    {
      sprintf( charTemplate, "%d", col+1 );
      iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
      if( iResult == 0 )
      {
        if( lRepeat == 3 )
        {
          QString strValue;
          double dNan = strtod( "nan", NULL );
          double value;
          int iAnyNull;

          for( entry=0; entry<lRepeat; entry++ )
          {
            iResult = fits_read_col( ffits, TDOUBLE, iColNumber, 1, entry+1, 1, &dNan, &value, &iAnyNull, &iStatus );
            if( iResult == 0 )
            {
              KstString *metaString;
              QString keyname = QString("%1_%2").arg(charName).arg(QChar('X'+entry));
              KstObjectTag newTag( keyname, tag( ) );

              strValue = QString("%1").arg(value);
              metaString = new KstString( newTag, this, strValue );
              _metaData.insert( keyname, metaString );
            }
          }
        }
      }
    }
  }
}
예제 #7
0
int cfits_get_repeat_count (int *nelems, const char *colname, cfitsfile *fptr)
{
   int status = 0, colnum;
   long ne;

   if (-1 == cfits_get_colnum (&colnum, colname, fptr))
     return -1;

   (void) fits_get_coltype((fitsfile *) fptr, colnum, NULL, &ne, NULL, &status);
   cfits_report_error (status);

   *nelems = ne;

   if (status != 0) return -1;
   return 0;
}
예제 #8
0
void PLANCKIDEFSource::addToFieldList( fitsfile *ffits, const int iNumCols, int &iStatus )
{
  QString str;
  char charTemplate[ FLEN_CARD ];
  char charName[ FLEN_CARD ];
  long lRepeat;
  long lWidth;
  int iHDUNumber;
  int iTypeCode;
  int iColNumber;
  int iResult;
  int table;
  int col;

  table = fits_get_hdu_num( ffits, &iHDUNumber );

  for( col=0; col<iNumCols; col++ )
  {
    iResult = fits_get_coltype( ffits, col+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
    if( iResult == 0 )
    {
      sprintf( charTemplate, "%d", col+1 );
      iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
      if( iResult == 0 )
      {
        if( lRepeat == 1 )
        {
          field *fld = new field;

          fld->table = table;
          fld->column = iColNumber;

          str = charName;
          if( _fields.find( str ) != 0L )
          {
            str += QString("_%1").arg( iHDUNumber );
          }
          _fields.insert( str, fld );
          _fieldList.append( str );
        }
      }
    }
  }
}
예제 #9
0
Kst::Object::UpdateType LFIIOSource::update() {

  Kst::Object::UpdateType updateType = Kst::Object::NO_CHANGE;
  QString               strTemplate;
  QString               strName;
  fitsfile*             ffits;
  char                  charTemplate[FLEN_CARD];
  char                  charName[FLEN_CARD];
  long                  lNumFrames;
  long                  lMaxRepeat = 1;
  long                  lRepeat;
  long                  lWidth;
  int                   iColNumber;
  int                   iNumCols;
  int                   iStatus = 0;
  int                   iResult = 0;
  int                   iTypeCode;
  int                   i;
  int                   newNF = 0;

  _valid  = false;

  if(!_filename.isNull() && !_filename.isEmpty()) {
    iResult = fits_open_table( &ffits, _filename.ascii(), READONLY, &iStatus );
    if(iResult == 0) {
      // determine size of data...
      iResult = fits_get_num_cols( ffits, &iNumCols, &iStatus );
      if(iResult == 0) {
        iResult = fits_get_num_rows( ffits, &lNumFrames, &iStatus );
        if(iResult == 0) {
          _fieldList.clear();
          _fieldList.append("INDEX");

          _valid = true;
          _bHasTime = false;

          // need to multiply lNumFrames by the maximum value of the vector repeat value...
          for(i = 0; i<iNumCols; i++) {
            iStatus = 0;

            sprintf(charTemplate, "%d", i+1);
            iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
            if(iResult == 0) {
              int iOffset = i;
              strName = charName;

              // ensure that we don't add duplicates to the _fieldList...
              while(_fieldList.findIndex(strName) != -1) {
                strName = QString("%1[%2]").arg(charName).arg(iOffset);
                iOffset++;
              }
            } else {
              strName.setNum(i);
            }

            _fieldList.append(strName);

            iStatus = 0;
            iResult = fits_get_coltype( ffits, i+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
            if(iResult == 0) {
              if(lRepeat > lMaxRepeat) {
                lMaxRepeat = lRepeat;
              }
            }
          }

          // check if we have a time field defined by the header keys TIMEZERO and DELTA_T.
          //  If so then we create a new field called $TIME_FIELD, unless such a field already
          //  exists, in which case we do nothing...
          char charTimeZero[] = "TIMEZERO";

          iStatus = 0;
          iResult = fits_read_key( ffits, TDOUBLE, charTimeZero, &_dTimeZero, 0L, &iStatus );
          if(iResult == 0) {
            char charTimeDelta[] = "DELTA_T";

            iResult = fits_read_key( ffits, TDOUBLE, charTimeDelta, &_dTimeDelta, 0L, &iStatus );
            if(iResult == 0) {
              if(_fieldList.find(QString(TIME_FIELD)) == _fieldList.end()) {
                _bHasTime = true;
                _fieldList.append(TIME_FIELD);
              }
            }
          }

          if(lNumFrames * lMaxRepeat != _numFrames) {
            _numCols   = iNumCols;
            newNF = lNumFrames * lMaxRepeat;
            updateType = Kst::Object::UPDATE;
          }
        }
      }
      iStatus = 0;
      fits_close_file( ffits, &iStatus );
    }
  }

  bool isnew = newNF != _numFrames;

  _numFrames = newNF;

  return (isnew ? Kst::Object::UPDATE : Kst::Object::NO_CHANGE);
}
예제 #10
0
파일: pfits.c 프로젝트: SixByNine/pfits
// Return the number of channels
int readBandpass(fitsfile *fp,float *bpass)
{
  int status=0;
  int samplesperbyte;
  long nrows;
  int colnum;
  int j,pol,subint;
  int initflag=0;
  float val=1;
  float nval = 0;
  long npts;
  int start,end;
  int i,anynul;
  float dat_offs,dat_scl;
  float freq,bw,chanbw;
  long nchan;
  int naxis;
  int typecode;
  long repeat,width;

  // Go to bandpass table
  fits_movnam_hdu(fp,BINARY_TBL,"BANDPASS",1,&status);
  if (status) {
    printf("Unable to move to bandpass table in FITS file\n");
    exit(1);
  }

  fits_get_colnum(fp,CASEINSEN,"DAT_OFFS",&colnum,&status);
  fits_read_col(fp,TFLOAT,colnum,1,1,1,&nval,&dat_offs,&anynul,&status);
  if (status){
    printf("Error in bandpass header 1\n");
    fits_report_error(stderr,status);
    exit(1);
  }
  fits_get_colnum(fp,CASEINSEN,"DAT_SCL",&colnum,&status);
  fits_read_col(fp,TFLOAT,colnum,1,1,1,&nval,&dat_scl,&anynul,&status);
  if (status){
    printf("Error in bandpass header\n");
    fits_report_error(stderr,status);
    exit(1);
    }

  fits_get_colnum(fp,CASEINSEN,"DATA",&colnum,&status);
  if (status){
    fits_report_error(stderr,status);
    exit(1);
  }
  fits_get_coltype(fp,colnum,&typecode,&repeat,&width,&status);
  nchan = (int)repeat-1; // Don't read the first channel
  printf("nc = %d, na = %d\n",(int)nchan,(int)naxis);
  for (i=1;i<(int)nchan;i++)
    {
      fits_read_col(fp,TFLOAT,colnum,1,i+1,1,&nval,&val,&anynul,&status);
      bpass[i-1] = val*dat_scl + dat_offs;
      if (status){
	fits_report_error(stderr,status);
	exit(1);
      }
    }
  fits_close_file(fp,&status);  
  return nchan;
}
예제 #11
0
파일: putcold.c 프로젝트: geechee/iraf
/*--------------------------------------------------------------------------*/
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;
    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 */

    repeat = colptr->trepeat;  /* repeat count for this column */
    fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status);

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

    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;

            /* call ffpcluc, not ffpclu, in case we are writing to a
	       complex ('C') binary table column */
            if (ffpcluc(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) {
		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 */
      large_first_elem_val = fstelm;

      ffpcld(fptr, colnum, fstrow, firstelem, 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 */
      large_first_elem_val = fstelm;
      ffpcluc(fptr, colnum, fstrow, firstelem, nbad, status);
    }

    return(*status);
}
예제 #12
0
int HEALPixIn(struct healpix *hpxdat)

{
  char   crdsys[32], ordering[32];
  int    anynul, hdutype, iaxis, nfound, status;
  long   firstpix, ipix, lastpix, naxis, *naxes = 0x0, nside = 0, repeat;
  float  *datap, nulval;
  LONGLONG firstelem, irow, nelem, npix = 0, nrow = 0;
  fitsfile *fptr;

  status = 0;
  hpxdat->data = 0x0;

  /* Open the FITS file and move to the first HDU with NAXIS != 0. */
  if (fits_open_data(&fptr, hpxdat->infile, READONLY, &status)) goto fitserr;

  /* Is this the primary HDU or an extension? */
  if (fits_get_hdu_type(fptr, &hdutype, &status)) goto fitserr;
  if (!(hdutype == IMAGE_HDU || hdutype == BINARY_TBL)) {
    fprintf(stderr, "ERROR: %s does not contain HEALPix data.\n",
            hpxdat->infile);
    return 1;
  }


  /* Get the image size. */
  if (fits_read_key_lng(fptr, "NAXIS", &naxis, 0x0, &status)) goto fitserr;
  naxes = malloc(naxis*sizeof(long));
  if (fits_read_keys_lng(fptr, "NAXIS", 1, (int)naxis, naxes, &nfound,
                         &status)) goto fitserr;

  if (hdutype == IMAGE_HDU) {
    /* Look for the first non-degenerate image axis. */
    for (iaxis = 0; iaxis < nfound; iaxis++) {
      if (naxes[iaxis] > 1) {
        /* Assume for now that it is the total number of pixels. */
        npix = naxes[iaxis];
        break;
      }
    }

  } else if (hdutype == BINARY_TBL) {
    /* Binary tables are simpler. */
    if (nfound > 1) nrow = naxes[1];

    /* (Note that fits_get_coltypell() is not available in cfitsio 2.x.) */
    if (fits_get_coltype(fptr, hpxdat->col, 0x0, &repeat, 0x0, &status)) {
      goto fitserr;
    }
    nelem = (LONGLONG)repeat;
  }

  if (!npix && !nrow) {
    fprintf(stderr, "ERROR: Could not determine image size.\n");
    goto cleanup;
  }


  /* Number of pixels per side of each base-resolution pixel. */
  if (fits_read_key_lng(fptr, "NSIDE", &nside, 0x0, &status)) {
    /* Some HEALPix files, e.g. SFD dust maps, don't record NSIDE. */
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  /* FIRSTPIX and LASTPIX, if present, record the 0-relative pixel numbers of
   * the first and last pixels stored in the data. */
  firstpix = -1;
  if (fits_read_key_lng(fptr, "FIRSTPIX", &firstpix, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  lastpix = -1;
  if (fits_read_key_lng(fptr, "LASTPIX", &lastpix, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  }

  if (!nside) {
    /* Deduce NSIDE. */
    if (lastpix >= 0) {
      /* If LASTPIX is present without NSIDE we can only assume it's npix. */
      nside = (int)(sqrt((double)((lastpix+1) / 12)) + 0.5);
    } else if (npix) {
      nside = (int)(sqrt((double)(npix / 12)) + 0.5);
    } else if (nrow) {
      nside = (int)(sqrt((double)((nrow * nelem) / 12)) + 0.5);
    }
  }

  hpxdat->nside = (int)nside;
  hpxdat->npix  = 12*nside*nside;

  /* Ensure that FIRSTPIX and LASTPIX are set. */
  if (firstpix < 0) firstpix = 0;
  if (lastpix  < 0) lastpix  = hpxdat->npix - 1;


  /* Any sign of a coordinate system identifier? */
  if (fits_read_key_str(fptr, "COORDSYS", crdsys, 0x0, &status)) {
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;
  } else if (crdsys[0] == 'G') {
    hpxdat->crdsys = 'G';
  } else if (crdsys[0] == 'E') {
    hpxdat->crdsys = 'E';
  } else if (crdsys[0] == 'C') {
    /* ("celestial") */
    hpxdat->crdsys = 'Q';
  }

  /* Nested or ring ordering? */
  if (fits_read_key_str(fptr, "ORDERING", ordering, 0x0, &status)) {
    /* Some HEALPix files, e.g. SFD dust maps, don't record ORDERING. */
    if (status != KEY_NO_EXIST) goto fitserr;
    status = 0;

  } else if (strcmp(ordering, "NESTED") == 0) {
    hpxdat->ordering = 'N';

  } else if (strcmp(ordering, "RING") == 0) {
    hpxdat->ordering = 'R';

  } else {
    fprintf(stderr, "WARNING: Invalid ORDERING keyword: %s.\n", ordering);
  }


  /* Allocate memory and read the data. */
  if ((hpxdat->data = malloc((hpxdat->npix)*sizeof(float))) == NULL) {
    perror("HPXcvt");
    goto cleanup;
  }

  nulval = HEALPIX_NULLVAL;
  datap = hpxdat->data;
  for (ipix = 0; ipix < firstpix; ipix++) {
    *(datap++) = nulval;
  }

  firstelem = (LONGLONG)1;
  if (hdutype == IMAGE_HDU) {
    if (fits_read_img_flt(fptr, 0l, firstelem, npix, nulval, datap, &anynul,
        &status)) goto fitserr;

  } else if (hdutype == BINARY_TBL) {
    for (irow = 0; irow < nrow; irow++) {
      if (fits_read_col_flt(fptr, hpxdat->col, irow+1, firstelem, nelem,
          nulval, datap, &anynul, &status)) goto fitserr;
      datap += nelem;
    }
  }

  datap = hpxdat->data + (lastpix + 1);
  for (ipix = (lastpix+1); ipix < hpxdat->npix; ipix++) {
    *(datap++) = nulval;
  }

  /* Clean up. */
  fits_close_file(fptr, &status);
  status = 0;
  return 0;

fitserr:
  fits_report_error(stderr, status);
cleanup:
  if (naxes) free(naxes);
  if (hpxdat->data) free(hpxdat->data);
  hpxdat->data = 0x0;
  return 1;
}
예제 #13
0
int psrfits_write_ephem(struct psrfits *pf, FILE *parfile) {
    // Read a pulsar ephemeris (par file) and put it into
    // the psrfits PSREPHEM table.  Only minimal checking
    // is done.
   
    // Get status
    int *status = &(pf->status);

    // Save current HDU, move to psrephem table
    int hdu;
    fits_get_hdu_num(pf->fptr, &hdu);
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "PSREPHEM", 0, status);

    // Loop over lines in par file
    int row=1, col, dtype;
    double dval;
    int ival;
    long double ldval;
    char line[256], *ptr, *saveptr, *key, *val;
    while (fgets(line, 256, parfile)!=NULL) {

        // Convert tabs to spaces
        while ((ptr=strchr(line,'\t'))!=NULL) { *ptr=' '; }

        // strip leading whitespace
        ptr = line;
        while (*ptr==' ') { ptr++; }

        // Identify comments or blank lines
        if (line[0]=='\n' || line[0]=='#' || 
                (line[0]=='C' && line[1]==' '))
            continue;

        // Split into key/val (ignore fit flag and error)
        key = strtok_r(line,  " ", &saveptr);
        val = strtok_r(NULL, " ", &saveptr);
        if (key==NULL || val==NULL) continue; // TODO : complain?

        // Deal with any special cases here
        if (strncmp(key, "PSR", 3)==0)  {

            // PSR(J) -> PSR_NAME
            fits_get_colnum(pf->fptr,CASEINSEN,"PSR_NAME",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "RA", 2)==0) {

            // RA -> RAJ
            fits_get_colnum(pf->fptr,CASEINSEN,"RAJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (strncmp(key, "DEC", 3)==0) {

            // DEC -> DECJ
            fits_get_colnum(pf->fptr,CASEINSEN,"DECJ",&col,status);
            fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);

        } else if (key[0]=='E' && key[1]=='\0') {

            // E -> ECC
            dval = atof(val);
            fits_get_colnum(pf->fptr,CASEINSEN,"ECC",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "F0", 2)==0) {

            // F is converted to mHz and split into int/frac
            ldval = strtold(val,NULL) * 1000.0; // Hz->mHz
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"IF0",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"FF0",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else if (strncmp(key, "TZRMJD", 6)==0) {

            // TZRMJD is split into int/frac
            ldval = strtold(val,NULL);
            ival = (int)ldval;
            dval = ldval - (long double)ival;
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRIMJD",&col,status);
            fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            fits_get_colnum(pf->fptr,CASEINSEN,"TZRFMJD",&col,status);
            fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);

        } else {

            // Find column, skip/warn if this one isn't present
            fits_get_colnum(pf->fptr,CASEINSEN,key,&col,status);
            if (*status==COL_NOT_FOUND) {
#if (DEBUGOUT)
                fprintf(stderr, 
                        "psrfits_write_epherm warning: Couldn't find keyword %s "
                        "in ephemeris table.\n",
                        key);
#endif
                *status=0;
                continue;
            }

            // Need to convert string to appropriate column data type
            // and then write it to the column.  These should all be
            // either double int or string.
            fits_get_coltype(pf->fptr,col,&dtype,NULL,NULL,status);
            if (dtype==TDOUBLE || dtype==TFLOAT) { 
                dval = atof(val);
                fits_write_col(pf->fptr,TDOUBLE,col,row,1,1,&dval,status);
            } else if (dtype==TINT || dtype==TLONG || dtype==TSHORT) {
                ival = atoi(val);
                fits_write_col(pf->fptr,TINT,col,row,1,1,&ival,status);
            } else if (dtype==TSTRING) {
                fits_write_col(pf->fptr,TSTRING,col,row,1,1,&val,status);
            } else {
                fprintf(stderr, "psrfits_write_ephem warning: "
                        "Unhandled column datatype (key=%s)\n", key);
                continue;
            }
        }

        // sucess/failure
        if (*status) {
            fprintf(stderr, "psrfits_write_ephem failed: key=%s val=%s\n",
                    key, val);
            fits_report_error(stderr, *status);
            *status=0;
        } 
#if 0  // DEBUG
        else {
            fprintf(stderr, "psrfits_write_ephem success: key=%s val=%s\n",
                    key, val);
        }
#endif

    }

    // Go back to orig HDU
    fits_movabs_hdu(pf->fptr, hdu, NULL, status);

    return *status;
}
예제 #14
0
/* This function is similar to psrfits_create, except it
 * deals with reading existing files.  It is assumed that
 * basename and filenum are filled in correctly to point to 
 * the first file in the set.
 */
int psrfits_open(struct psrfits *pf, int iomode)
{

    int itmp;
    double dtmp;
    char ctmp[256];

    struct hdrinfo *hdr = &(pf->hdr);
    struct subint *sub = &(pf->sub);

    int *status = &(pf->status);

    sprintf(pf->filename, "%s%0*d.fits", pf->basefilename, pf->fnamedigits,
            pf->filenum);
    //fprintf(stderr,"%s\n",pf->filename);
    fits_open_file(&(pf->fptr), pf->filename, iomode, status);

    // If file does not exist, exit now
    if (*status) {
        return *status;
    }
    fprintf(stderr, "Opened file '%s'\n", pf->filename);

    // Move to main HDU
    fits_movabs_hdu(pf->fptr, 1, NULL, status);

    // Figure out obs mode
    fits_read_key(pf->fptr, TSTRING, "OBS_MODE", hdr->obs_mode, NULL, status);
    int mode = psrfits_obs_mode(hdr->obs_mode);

    // Read some stuff
    fits_read_key(pf->fptr, TSTRING, "TELESCOP", hdr->telescope, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "OBSERVER", hdr->observer, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "PROJID", hdr->project_id, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "FRONTEND", hdr->frontend, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "BACKEND", hdr->backend, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "FD_POLN", hdr->poln_type, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "DATE-OBS", hdr->date_obs, NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "OBSFREQ", &(hdr->fctr), NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "OBSBW", &(hdr->BW), NULL, status);
    fits_read_key(pf->fptr, TINT, "OBSNCHAN", &(hdr->orig_nchan), NULL, status);
    fits_read_key(pf->fptr, TSTRING, "SRC_NAME", hdr->source, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "TRK_MODE", hdr->track_mode, NULL, status);
    // TODO warn if not TRACK?
    fits_read_key(pf->fptr, TSTRING, "RA", hdr->ra_str, NULL, status);
    fits_read_key(pf->fptr, TSTRING, "DEC", hdr->dec_str, NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "BMAJ", &(hdr->beam_FWHM), NULL, status);
    fits_read_key(pf->fptr, TSTRING, "CAL_MODE", hdr->cal_mode, NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "CAL_FREQ", &(hdr->cal_freq), NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "CAL_DCYC", &(hdr->cal_dcyc), NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "CAL_PHS", &(hdr->cal_phs), NULL, status);
    fits_read_key(pf->fptr, TSTRING, "FD_MODE", hdr->feed_mode, NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "FA_REQ", &(hdr->feed_angle), NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "SCANLEN", &(hdr->scanlen), NULL, status);

    fits_read_key(pf->fptr, TINT, "STT_IMJD", &itmp, NULL, status);
    hdr->MJD_epoch = (long double) itmp;
    fits_read_key(pf->fptr, TDOUBLE, "STT_SMJD", &dtmp, NULL, status);
    hdr->MJD_epoch += dtmp / 86400.0L;
    fits_read_key(pf->fptr, TDOUBLE, "STT_OFFS", &dtmp, NULL, status);
    hdr->MJD_epoch += dtmp / 86400.0L;

    fits_read_key(pf->fptr, TDOUBLE, "STT_LST", &(hdr->start_lst), NULL, status);

    // Move to pdev bintab to see if blanking enabled
    //
    int blankSel, adcThr;
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "PDEV", 0, status);
    fits_read_key(pf->fptr, TINT, "PHBLKSEL", &(blankSel), NULL, status);
    fits_read_key(pf->fptr, TINT, "PHADCTHR", &(adcThr), NULL, status);
    fits_read_key(pf->fptr, TINT, "PHFFTACC", &(hdr->fftAccum), NULL, status);
    hdr->blankingOn = (blankSel != 15) || (adcThr != 65535);

    // Move to first subint
    fits_movnam_hdu(pf->fptr, BINARY_TBL, "SUBINT", 0, status);

    // Read some more stuff
    fits_read_key(pf->fptr, TINT, "NPOL", &(hdr->npol), NULL, status);
    fits_read_key(pf->fptr, TSTRING, "POL_TYPE", ctmp, NULL, status);
    if (strncmp(ctmp, "AA+BB", 6) == 0)
        hdr->summed_polns = 1;
    else
        hdr->summed_polns = 0;
    fits_read_key(pf->fptr, TDOUBLE, "TBIN", &(hdr->dt), NULL, status);
    fits_read_key(pf->fptr, TINT, "NBIN", &(hdr->nbin), NULL, status);
    fits_read_key(pf->fptr, TINT, "NSUBOFFS", &(hdr->offset_subint), NULL, status);
    fits_read_key(pf->fptr, TINT, "NCHAN", &(hdr->nchan), NULL, status);
    fits_read_key(pf->fptr, TDOUBLE, "CHAN_BW", &(hdr->df), NULL, status);
    fits_read_key(pf->fptr, TINT, "NSBLK", &(hdr->nsblk), NULL, status);
    fits_read_key(pf->fptr, TINT, "NBITS", &(hdr->nbits), NULL, status);

    if (mode == SEARCH_MODE) {
        sub->bytes_per_subint =
            (hdr->nbits * hdr->nchan * hdr->npol * hdr->nsblk) / 8;
        sub->statbytes_per_subint = hdr->nsblk * AO_NUM_SH_STAT_1DMP * sizeof(short);
    } else if (mode == FOLD_MODE) {
        sub->bytes_per_subint = (hdr->nbin * hdr->nchan * hdr->npol) * hdr->nbits / 8;  //XXX data type??
    }
    //  to tell us the end of the good data in file.
    pf->hdr.numBlksTot = (pf->hdr.scanlen / pf->hdr.dt + .5);
    // Init counters
    pf->rownum = 1;

    fits_read_key(pf->fptr, TINT, "NAXIS2", &(pf->rows_per_file), NULL, status);
    if (!pf->initialized) {
        fits_get_colnum(pf->fptr, 1, "TSUBINT", &pf->subcols.tsubint, status);
        fits_get_colnum(pf->fptr, 1, "OFFS_SUB", &pf->subcols.offs_sub, status);
        fits_get_colnum(pf->fptr, 1, "LST_SUB", &pf->subcols.lst_sub, status);
        fits_get_colnum(pf->fptr, 1, "RA_SUB", &pf->subcols.ra_sub, status);
        fits_get_colnum(pf->fptr, 1, "DEC_SUB", &pf->subcols.dec_sub, status);
        fits_get_colnum(pf->fptr, 1, "GLON_SUB", &pf->subcols.glon_sub, status);
        fits_get_colnum(pf->fptr, 1, "GLAT_SUB", &pf->subcols.glat_sub, status);
        fits_get_colnum(pf->fptr, 1, "FD_ANG", &pf->subcols.fd_ang, status);
        fits_get_colnum(pf->fptr, 1, "POS_ANG", &pf->subcols.pos_ang, status);
        fits_get_colnum(pf->fptr, 1, "PAR_ANG", &pf->subcols.par_ang, status);
        fits_get_colnum(pf->fptr, 1, "TEL_AZ", &pf->subcols.tel_az, status);
        fits_get_colnum(pf->fptr, 1, "TEL_ZEN", &pf->subcols.tel_zen, status);
        fits_get_colnum(pf->fptr, 1, "DAT_FREQ", &pf->subcols.dat_freq, status);
        fits_get_colnum(pf->fptr, 1, "DAT_WTS", &pf->subcols.dat_wts, status);
        fits_get_colnum(pf->fptr, 1, "DAT_OFFS", &pf->subcols.dat_offs, status);
        fits_get_colnum(pf->fptr, 1, "DAT_SCL", &pf->subcols.dat_scl, status);
        fits_get_colnum(pf->fptr, 1, "DATA", &pf->subcols.data, status);
        fits_get_colnum(pf->fptr, 1, "STAT", &pf->subcols.stat, status);

        long repeat;
        long width;
        fits_get_coltype(pf->fptr, pf->subcols.data, &sub->typecode, &repeat,
                         &width, status);
        sub->bytesPerDatum = width;
        if (sub->typecode == TINT32BIT)
            sub->typecode = TINT;
        sub->data = malloc(sizeof(char) * sub->bytes_per_subint);
        sub->dataBytesAlloced = sub->bytes_per_subint;
        sub->stat = (unsigned short *) malloc(sub->statbytes_per_subint);
        pf->initialized = 1;
    }
    return *status;
}
예제 #15
0
/*--------------------------------------------------------------------------*/
int ffpclu( 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               */
            int  *status)    /* IO - error status                           */
/*
  Set elements of a table column to the appropriate null value for the column
  The column number may refer to a real column in an ASCII or binary table, 
  or it may refer to a virtual column in a 1 or more grouped FITS primary
  array.  FITSIO treats a primary array as a binary table
  with 2 vector columns: the first column contains the group parameters (often
  with length = 0) and the second column contains the array of image pixels.
  Each row of the table represents a group in the case of multigroup FITS
  images.
*/
{
    int tcode, maxelem, hdutype, lennull, nwrite = 0, writemode = 2;
    short i2null;
    INT32BIT i4null;
    long twidth, incre, rownum, remain, next, ntodo;
    long tnull, ii;
    OFF_T repeat, startpos, elemnum, large_elem, wrtptr, rowlen;
    double scale, zero;
    unsigned char i1null, lognul = 0;
    char tform[20], cstring[50];
    char message[FLEN_ERRMSG];
    char snull[20];   /*  the FITS null value  */
    long   jbuff[2] = { -1, -1};  /* all bits set is equivalent to a NaN */

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

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

    /*---------------------------------------------------*/
    /*  Check input and get parameters about the column: */
    /*---------------------------------------------------*/

    /* note that writemode = 2 by default (not 1), so that the returned */
    /* repeat and incre values will be the actual values for this column. */

    /* If writing nulls to a variable length column then dummy data values  */
    /* must have already been written to the heap. */
    /* We just have to overwrite the previous values with null values. */
    /* Set writemode = 0 in this case, to test that values have been written */

    fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status);
    if (tcode < 0)
         writemode = 0;  /* this is a variable length column */

    if (ffgcpr( fptr, colnum, firstrow, large_elem, nelem, writemode, &scale,
       &zero, tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);

    if (tcode == TSTRING)
    {
      if (snull[0] == ASCII_NULL_UNDEFINED)
      {
        ffpmsg(
        "Null value string for ASCII table column is not defined (FTPCLU).");
        return(*status = NO_NULL);
      }

      strcpy(cstring, snull);          /* copy null string to temp buffer */
      lennull = strlen(cstring);

      if (hdutype == BINARY_TBL)
      {  /* write up to and including null terminator into BINTABLE column */
         nwrite = minvalue(twidth, lennull + 1);
      }
      else
      {  /* write up to 20 chars to ASCII table column; pad with blanks */
         nwrite = minvalue(twidth, 20);

         for (ii = lennull; ii < nwrite; ii++)
            cstring[ii] = ' ';  
      }
    }
    else if ( tcode == TBYTE ||
              tcode == TSHORT ||
              tcode == TLONG ) 
    {
      if (tnull == NULL_UNDEFINED)
      {
        ffpmsg(
        "Null value for integer table column is not defined (FTPCLU).");
        return(*status = NO_NULL);
      }

      if (tcode == TBYTE)
         i1null = tnull;
      else if (tcode == TSHORT)
      {
         i2null = tnull;
#if BYTESWAPPED
         ffswap2(&i2null, 1); /* reverse order of bytes */
#endif
      }
      else
      {
         i4null = tnull;
#if BYTESWAPPED
         ffswap4(&i4null, 1); /* reverse order of bytes */
#endif
      }
    }

    /*---------------------------------------------------------------------*/
    /*  Now write the pixels to the FITS column.                           */
    /*---------------------------------------------------------------------*/
    remain = nelem;           /* remaining number of values to write  */
    next = 0;                 /* next element in array to be written  */
    rownum = 0;               /* row number, relative to firstrow     */
    ntodo = remain;           /* number of elements to write at one time */

    while (ntodo)
    {
        /* 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 = minvalue(ntodo, (repeat - elemnum));
        wrtptr = startpos + ((OFF_T)rownum * rowlen) + (elemnum * incre);

        ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */

        switch (tcode) 
        {
            case (TBYTE):
 
                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 1,  &i1null, status);
                break;

            case (TSHORT):

                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 2, &i2null, status);
                break;

            case (TLONG):

                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 4, &i4null, status);
                break;

            case (TFLOAT):

                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 4, jbuff, status);
                break;

            case (TDOUBLE):

                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 8, jbuff, status);
                break;

            case (TLOGICAL):
 
                for (ii = 0; ii < ntodo; ii++)
                  ffpbyt(fptr, 1, &lognul, status);
                break;

            case (TSTRING):  /* an ASCII table column */
                /* repeat always = 1, so ntodo is also guaranteed to = 1 */
                ffpbyt(fptr, nwrite, cstring, status);
                break;

            default:  /*  error trap  */
                sprintf(message, 
                   "Cannot write null value to column %d which has format %s",
                     colnum,tform);
                ffpmsg(message);
                return(*status);

        } /* End of switch block */

        /*-------------------------*/
        /*  Check for fatal error  */
        /*-------------------------*/
        if (*status > 0)  /* test for error during previous write operation */
        {
           sprintf(message,
             "Error writing %ld thru %ld of null values (ffpclu).",
              next+1, next+ntodo);
           ffpmsg(message);
           return(*status);
        }

        /*--------------------------------------------*/
        /*  increment the counters for the next loop  */
        /*--------------------------------------------*/
        remain -= ntodo;
        if (remain)
        {
            next += ntodo;
            elemnum += ntodo;
            if (elemnum == repeat)  /* completed a row; start on next row */
            {
                elemnum = 0;
                rownum++;
            }
        }
        ntodo = remain;  /* this is the maximum number to do in next loop */

    }  /*  End of main while Loop  */

    return(*status);
}
예제 #16
0
int hpic_fits_vec_test(char *filename, size_t * nvecs, size_t * length,
                       int *filetype, int *tabtype)
{

  size_t i, j, k, m;
  fitsfile *fp;
  int ret = 0;
  int ttype;
  long nrows;
  long rowlen;
  long pcount;
  char extname[HPIC_STRNL];
  int tfields;
  long repeat;
  long width;

  /* open file */
  if (fits_open_file(&fp, filename, READONLY, &ret)) {
    return 0;
  }

  /* check extension type, number of columns */
  if (fits_movabs_hdu(fp, 2, &ttype, &ret)) {
    ret = 0;
    fits_close_file(fp, &ret);
    return 0;
  }
  if (ttype == ASCII_TBL) {
    (*tabtype) = HPIC_FITS_ASCII;
    if (fits_read_atblhdr
        (fp, HPIC_FITS_MAXCOL, &rowlen, &nrows, &tfields, NULL, NULL, NULL, NULL, extname,
         &ret)) {
      ret = 0;
      fits_close_file(fp, &ret);
      return 0;
    }
  } else {
    (*tabtype) = HPIC_FITS_BIN;
    if (fits_read_btblhdr
        (fp, HPIC_FITS_MAXCOL, &nrows, &tfields, NULL, NULL, NULL, extname, &pcount,
         &ret)) {
      ret = 0;
      fits_close_file(fp, &ret);
      return 0;
    }
  }

  /* determine the types of vectors */

  if (fits_get_coltype(fp, 1, &ttype, &repeat, &width, &ret)) {
    ret = 0;
    fits_close_file(fp, &ret);
    return 0;
  }
  if ((ttype == TINT) || (ttype == TINT32BIT) || (ttype == TLONG) ||
      (ttype == TSHORT)) {
    (*filetype) = HPIC_FITS_VEC_INDX;
  } else if ((ttype == TFLOAT) || (ttype == TDOUBLE)) {
    (*filetype) = HPIC_FITS_VEC;
  } else {
    ret = 0;
    fits_close_file(fp, &ret);
    return 0;
  }
  for (i = 1; i < (size_t) tfields; i++) {
    if (fits_get_coltype(fp, (int)(i + 1), &ttype, &repeat, &width, &ret)) {
      ret = 0;
      fits_close_file(fp, &ret);
      return 0;
    }
    if ((ttype != TFLOAT) && (ttype != TDOUBLE)) {
      ret = 0;
      fits_close_file(fp, &ret);
      return 0;
    }
  }

  if ((*filetype) == HPIC_FITS_VEC_INDX) {
    (*nvecs) = (size_t) tfields - 1;
  } else {
    (*nvecs) = (size_t) tfields;
  }
  (*length) = (size_t) nrows;

  fits_close_file(fp, &ret);
  return 1;
}
예제 #17
0
int main(int argc, char *argv[])
{
  fitsfile *infptr = 0, *outfptr = 0;  /* FITS file pointers */
  int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
  int icol = 0, incols = 0, outcols = 0, intype = 0, outtype = 0, check = 1;
  long inrep = 0, outrep = 0, width = 0, inrows = 0, outrows = 0, ii = 0, jj = 0;
  unsigned char *buffer = 0;

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 3) {
    fprintf(stderr, "Usage:  %s infile1[ext][filter] outfile[ext]\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Merge 2 tables by copying all the rows from the 1st table\n");
    fprintf(stderr, "into the 2nd table.  The  2 tables must have identical\n");
    fprintf(stderr, "structure, with the same number of columns with the same\n");
    fprintf(stderr, "datatypes.  This program modifies the output file in place,\n");
    fprintf(stderr, "rather than creating a whole new output file.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Examples: \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "1. %s intab.fit+1 outtab.fit+2\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    merge the table in the 1st extension of intab.fit with\n");
    fprintf(stderr, "    the table in the 2nd extension of outtab.fit.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "2. %s 'intab.fit+1[PI > 45]' outab.fits+2\n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "    Same as the 1st example, except only rows that have a PI\n");
    fprintf(stderr, "    column value > 45 will be merged into the output table.\n");
    fprintf(stderr, "\n");
    return (0);
  }

  /* open both input and output files and perform validity checks */
  if (fits_open_file(&infptr,  argv[1], READONLY,  &status) ||
      fits_open_file(&outfptr, argv[2], READWRITE, &status)) {
    fprintf(stderr, " Couldn't open both files\n");
  }

  else if (fits_get_hdu_type(infptr,  &intype,  &status) ||
           fits_get_hdu_type(outfptr, &outtype, &status)) {
    fprintf(stderr, "couldn't get the type of HDU for the files\n");
  }

  else if (intype == IMAGE_HDU) {
    fprintf(stderr, "The input HDU is an image, not a table\n");
  }

  else if (outtype == IMAGE_HDU) {
    fprintf(stderr, "The output HDU is an image, not a table\n");
  }

  else if (outtype != intype) {
    fprintf(stderr, "Input and output HDUs are not the same type of table.\n");
  }

  else if (fits_get_num_cols(infptr,  &incols,  &status) ||
           fits_get_num_cols(outfptr, &outcols, &status)) {
    fprintf(stderr, "Couldn't get number of columns in the tables\n");
  }

  else if (incols != outcols) {
    fprintf(stderr, "Input and output HDUs don't have same # of columns.\n");
  }

  else if (fits_read_key(infptr, TLONG, "NAXIS1", &width, NULL, &status)) {
    fprintf(stderr, "Couldn't get width of input table\n");
  }

  else if (!(buffer = (unsigned char *) malloc(width))) {
    fprintf(stderr, "memory allocation error\n");
  }

  else if (fits_get_num_rows(infptr,  &inrows,  &status) ||
           fits_get_num_rows(outfptr, &outrows, &status)) {
    fprintf(stderr, "Couldn't get the number of rows in the tables\n");
  }

  else  {
    /* check that the corresponding columns have the same datatypes */
    for (icol = 1; icol <= incols; icol++) {
      fits_get_coltype(infptr,  icol, &intype,  &inrep,  NULL, &status);
      fits_get_coltype(outfptr, icol, &outtype, &outrep, NULL, &status);
      if (intype != outtype || inrep != outrep) {
        fprintf(stderr, "Column %d is not the same in both tables\n", icol);
        check = 0;
      }
    }

    if (check && !status) {
      /* insert 'inrows' empty rows at the end of the output table */
      fits_insert_rows(outfptr, outrows, inrows, &status);

      for (ii = 1, jj = outrows +1; ii <= inrows; ii++, jj++) {
        /* read row from input and write it to the output table */
        fits_read_tblbytes(infptr,  ii, 1, width, buffer, &status);
        fits_write_tblbytes(outfptr, jj, 1, width, buffer, &status);
        if (status) {
          break;  /* jump out of loop if error occurred */
        }
      }

      /* all done; now free memory and close files */
      fits_close_file(outfptr, &status);
      fits_close_file(infptr,  &status);
    }
  }

  if (buffer) {
    free(buffer);
  }

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
예제 #18
0
int table::get_coltype(int id){
  int typecode;
  long width, repeat;
  fits_get_coltype(fptr, id, &typecode, &repeat, &width, &status);
  return typecode;
}
예제 #19
0
/*--------------------------------------------------------------------------*/
int ffpclu( 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  nelempar,     /* I - number of values to write               */
            int  *status)    /* IO - error status                           */
/*
  Set elements of a table column to the appropriate null value for the column
  The column number may refer to a real column in an ASCII or binary table,
  or it may refer to a virtual column in a 1 or more grouped FITS primary
  array.  FITSIO treats a primary array as a binary table
  with 2 vector columns: the first column contains the group parameters (often
  with length = 0) and the second column contains the array of image pixels.
  Each row of the table represents a group in the case of multigroup FITS
  images.

  This routine support COMPLEX and DOUBLE COMPLEX binary table columns, and
  sets both the real and imaginary components of the element to a NaN.
*/
{
    int tcode, maxelem, hdutype, writemode = 2, leng;
    short i2null;
    INT32BIT i4null;
    long twidth, incre;
    long ii;
    LONGLONG largeelem, nelem, tnull, i8null;
    LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, ntodo;
    double scale, zero;
    unsigned char i1null, lognul = 0;
    char tform[20], *cstring = 0;
    char message[FLEN_ERRMSG];
    char snull[20];   /*  the FITS null value  */
    long   jbuff[2] = { -1, -1};  /* all bits set is equivalent to a NaN */
    size_t buffsize;

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

    nelem = nelempar;

    largeelem = firstelem;

    /*---------------------------------------------------*/
    /*  Check input and get parameters about the column: */
    /*---------------------------------------------------*/

    /* note that writemode = 2 by default (not 1), so that the returned */
    /* repeat and incre values will be the actual values for this column. */

    /* If writing nulls to a variable length column then dummy data values  */
    /* must have already been written to the heap. */
    /* We just have to overwrite the previous values with null values. */
    /* Set writemode = 0 in this case, to test that values have been written */

    fits_get_coltype(fptr, colnum, &tcode, NULL, NULL, status);
    if (tcode < 0)
        writemode = 0;  /* this is a variable length column */

    if (abs(tcode) >= TCOMPLEX)
    {   /* treat complex columns as pairs of numbers */
        largeelem = (largeelem - 1) * 2 + 1;
        nelem *= 2;
    }

    if (ffgcprll( fptr, colnum, firstrow, largeelem, nelem, writemode, &scale,
                  &zero, tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
                  &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);

    if (tcode == TSTRING)
    {
        if (snull[0] == ASCII_NULL_UNDEFINED)
        {
            ffpmsg(
                "Null value string for ASCII table column is not defined (FTPCLU).");
            return(*status = NO_NULL);
        }

        /* allocate buffer to hold the null string.  Must write the entire */
        /* width of the column (twidth bytes) to avoid possible problems */
        /* with uninitialized FITS blocks, in case the field spans blocks */

        buffsize = maxvalue(20, twidth);
        cstring = (char *) malloc(buffsize);
        if (!cstring)
            return(*status = MEMORY_ALLOCATION);

        memset(cstring, ' ', buffsize);  /* initialize  with blanks */

        leng = strlen(snull);
        if (hdutype == BINARY_TBL)
            leng++;        /* copy the terminator too in binary tables */

        strncpy(cstring, snull, leng);  /* copy null string to temp buffer */
    }
    else if ( tcode == TBYTE  ||
              tcode == TSHORT ||
              tcode == TLONG  ||
              tcode == TLONGLONG)
    {
        if (tnull == NULL_UNDEFINED)
        {
            ffpmsg(
                "Null value for integer table column is not defined (FTPCLU).");
            return(*status = NO_NULL);
        }

        if (tcode == TBYTE)
            i1null = (unsigned char) tnull;
        else if (tcode == TSHORT)
        {
            i2null = (short) tnull;
#if BYTESWAPPED
            ffswap2(&i2null, 1); /* reverse order of bytes */
#endif
        }
        else if (tcode == TLONG)
        {
            i4null = (INT32BIT) tnull;
#if BYTESWAPPED
            ffswap4(&i4null, 1); /* reverse order of bytes */
#endif
        }
        else
        {
            i8null = tnull;
#if BYTESWAPPED
            ffswap8((double *)(&i8null), 1);  /* reverse order of bytes */
#endif
        }
    }

    /*---------------------------------------------------------------------*/
    /*  Now write the pixels to the FITS column.                           */
    /*---------------------------------------------------------------------*/
    remain = nelem;           /* remaining number of values to write  */
    next = 0;                 /* next element in array to be written  */
    rownum = 0;               /* row number, relative to firstrow     */
    ntodo = remain;           /* number of elements to write at one time */

    while (ntodo)
    {
        /* 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 = minvalue(ntodo, (repeat - elemnum));
        wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre);

        ffmbyt(fptr, wrtptr, IGNORE_EOF, status); /* move to write position */

        switch (tcode)
        {
        case (TBYTE):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 1,  &i1null, status);
            break;

        case (TSHORT):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 2, &i2null, status);
            break;

        case (TLONG):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 4, &i4null, status);
            break;

        case (TLONGLONG):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 8, &i8null, status);
            break;

        case (TFLOAT):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 4, jbuff, status);
            break;

        case (TDOUBLE):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 8, jbuff, status);
            break;

        case (TLOGICAL):

            for (ii = 0; ii < ntodo; ii++)
                ffpbyt(fptr, 1, &lognul, status);
            break;

        case (TSTRING):  /* an ASCII table column */
            /* repeat always = 1, so ntodo is also guaranteed to = 1 */
            ffpbyt(fptr, twidth, cstring, status);
            break;

        default:  /*  error trap  */
            sprintf(message,
                    "Cannot write null value to column %d which has format %s",
                    colnum,tform);
            ffpmsg(message);
            return(*status);

        } /* End of switch block */

        /*-------------------------*/
        /*  Check for fatal error  */
        /*-------------------------*/
        if (*status > 0)  /* test for error during previous write operation */
        {
            sprintf(message,
                    "Error writing %.0f thru %.0f of null values (ffpclu).",
                    (double) (next+1), (double) (next+ntodo));
            ffpmsg(message);

            if (cstring)
                free(cstring);

            return(*status);
        }

        /*--------------------------------------------*/
        /*  increment the counters for the next loop  */
        /*--------------------------------------------*/
        remain -= ntodo;
        if (remain)
        {
            next += ntodo;
            elemnum += ntodo;
            if (elemnum == repeat)  /* completed a row; start on next row */
            {
                elemnum = 0;
                rownum++;
            }
        }
        ntodo = remain;  /* this is the maximum number to do in next loop */

    }  /*  End of main while Loop  */

    if (cstring)
        free(cstring);

    return(*status);
}
예제 #20
0
KstObject::UpdateType LFIIOSource::update( int u ) 
{
  Q_UNUSED( u )

  KstObject::UpdateType updateType =  KstObject::NO_CHANGE;
  QString               strTemplate;
  QString               strName;
  fitsfile*             ffits;
  char                  charTemplate[ FLEN_CARD ];
  char                  charName[ FLEN_CARD ];
  long                  lNumFrames;
  long                  lMaxRepeat = 1;
  long                  lRepeat;
  long                  lWidth;
  int                   iColNumber;
  int                   iNumCols;
  int                   iStatus = 0;
  int                   iResult = 0;
  int                   iTypeCode;
  int                   i;

  _valid  = false;

  if( !_filename.isNull( ) && !_filename.isEmpty( ) )
  {
    iResult = fits_open_table( &ffits, _filename.ascii( ), READONLY, &iStatus );
    if( iResult == 0 )
    {
      //
      // determine size of data...
      //
      iResult = fits_get_num_cols( ffits, &iNumCols, &iStatus );
      if( iResult == 0 )
      {
        iResult = fits_get_num_rows( ffits, &lNumFrames, &iStatus );
        if( iResult == 0 )
        {
          _strListColNames.clear( );

          _valid = true;

          //
	        // need to multiply lNumFrames by the maximum value of the vector repeat value...
	        //
          for( i=0; i<iNumCols; i++ )
          {
            iStatus = 0;
            
            sprintf( charTemplate, "%d", i+1 );
            iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
            if( iResult == 0 )
            { 
              strName = charName;
              _strListColNames.append( strName );
            }
            else
            {
              strName.setNum( i );
              _strListColNames.append( strName );
            }
              
            iStatus = 0;
            iResult = fits_get_coltype( ffits, i+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
            if( iResult == 0 )
            {
              if( lRepeat > lMaxRepeat )
              {
                lMaxRepeat = lRepeat;
              }
            }
          }

          if( lNumFrames * lMaxRepeat != _numFrames )
	        {
            _numCols   = iNumCols;
            _numFrames = lNumFrames * lMaxRepeat;
            updateType = KstObject::UPDATE;
          }
        }
      }
      iStatus = 0;
      fits_close_file( ffits, &iStatus );   
    }
  }
  
  return updateType;
}
예제 #21
0
void WMAPSource::addToFieldList( fitsfile *ffits, const int iNumCols, const long lNumRows, const long lNumBaseRows, int &iStatus )
{
  QString str;
  char charTemplate[ FLEN_CARD ];
  char charName[ FLEN_CARD ];
  long lRepeat;
  long lWidth;
  int iHDUNumber;
  int iTypeCode;
  int iColNumber;
  int iResult;
  int table;
  int entry;
  int col;

  table = fits_get_hdu_num( ffits, &iHDUNumber );

  for( col=0; col<iNumCols; col++ )
  {
    iResult = fits_get_coltype( ffits, col+1, &iTypeCode, &lRepeat, &lWidth, &iStatus );
    if( iResult == 0 )
    {
      sprintf( charTemplate, "%d", col+1 );
      iResult = fits_get_colname( ffits, CASEINSEN, charTemplate, charName, &iColNumber, &iStatus );
      if( iResult == 0 )
      {
        if( lRepeat == 1 )
        {
          field *fld = new field;

          fld->table = table;
          fld->column = iColNumber;
          fld->entry = 1;
          fld->entries = lRepeat;
          fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
          fld->numFrames = lNumBaseRows;

          str = charName;
          if( _fields.find( str ) != 0L )
          {
            str += QString("_%1").arg( iHDUNumber );
          }
          _fields.insert( str, fld );
          _fieldList.append( str );
        }
        else if( lRepeat == 3 )
        {
          for( entry=0; entry<lRepeat; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = lRepeat;
            fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(QChar('X'+entry));
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
        else if( strcmp( charName, "QUATERN" ) == 0 )
        {
          for( entry=0; entry<4; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = 4;
            fld->numSamplesPerFrame = ( lRepeat / 4 ) - 3;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(QChar('a'+entry));
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
        else
        {
          for( entry=0; entry<lRepeat; entry++ )
          {
            field *fld = new field;

            fld->table = table;
            fld->column = iColNumber;
            fld->entry = entry+1;
            fld->entries = lRepeat;
            fld->numSamplesPerFrame = lNumRows / lNumBaseRows;
            fld->numFrames = lNumBaseRows;

            str = QString("%1_%2").arg(charName).arg(entry);
            _fields.insert( str, fld );
            _fieldList.append( str );
          }
        }
      }
    }
  }
}
예제 #22
0
파일: fits.c 프로젝트: lajus/monetinr
str FITSloadTable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
	mvc *m = NULL;
	sql_schema *sch;
	sql_table *fits_fl, *fits_tbl, *tbl = NULL;
	sql_column *col;
	sql_subtype tpe;
	fitsfile *fptr;
	str tname = *(str*)getArgReference(stk, pci, 1);
	str fname;
	str msg = MAL_SUCCEED;
	oid rid = oid_nil, frid = oid_nil;
	int status = 0, cnum = 0, fid, hdu, hdutype, i, j, anynull = 0, mtype;
	int *tpcode = NULL;
	long *rep = NULL, *wid = NULL, rows;
	char keywrd[80], **cname, nm[FLEN_VALUE];
	ptr nilptr;

	msg = getSQLContext(cntxt, mb, &m, NULL);
	if (msg)
		return msg;
	sch = mvc_bind_schema(m, "sys");

	fits_tbl = mvc_bind_table(m, sch, "fits_tables");
	if (fits_tbl == NULL) {
		msg = createException(MAL, "fits.loadtable", "FITS catalog is missing.\n");
		return msg;
	}

	tbl = mvc_bind_table(m, sch, tname);
	if (tbl) {
		msg = createException(MAL, "fits.loadtable", "Table %s is already created.\n", tname);
		return msg;
	}

	col = mvc_bind_column(m, fits_tbl, "name");
	rid = table_funcs.column_find_row(m->session->tr, col, tname, NULL);
	if (rid == oid_nil) {
		msg = createException(MAL, "fits.loadtable", "Table %s is unknown in FITS catalog. Attach first the containing file\n", tname);
		return msg;
	}

	/* Open FITS file and move to the table HDU */
	col = mvc_bind_column(m, fits_tbl, "file_id");
	fid = *(int*)table_funcs.column_find_value(m->session->tr, col, rid);

	fits_fl = mvc_bind_table(m, sch, "fits_files");
	col = mvc_bind_column(m, fits_fl, "id");
	frid = table_funcs.column_find_row(m->session->tr, col, (void *)&fid, NULL);
	col = mvc_bind_column(m, fits_fl, "name");
	fname = (char *)table_funcs.column_find_value(m->session->tr, col, frid);
	if (fits_open_file(&fptr, fname, READONLY, &status)) {
		msg = createException(MAL, "fits.loadtable", "Missing FITS file %s.\n", fname);
		return msg;
	}

	col = mvc_bind_column(m, fits_tbl, "hdu");
	hdu = *(int*)table_funcs.column_find_value(m->session->tr, col, rid);
	fits_movabs_hdu(fptr, hdu, &hdutype, &status);
	if (hdutype != ASCII_TBL && hdutype != BINARY_TBL) {
		msg = createException(MAL, "fits.loadtable", "HDU %d is not a table.\n", hdu);
		fits_close_file(fptr, &status);
		return msg;
	}

	/* create a SQL table to hold the FITS table */
	/*	col = mvc_bind_column(m, fits_tbl, "columns");
	   cnum = *(int*) table_funcs.column_find_value(m->session->tr, col, rid); */
	fits_get_num_cols(fptr, &cnum, &status);
	tbl = mvc_create_table(m, sch, tname, tt_table, 0, SQL_PERSIST, 0, cnum);

	tpcode = (int *)GDKzalloc(sizeof(int) * cnum);
	rep = (long *)GDKzalloc(sizeof(long) * cnum);
	wid = (long *)GDKzalloc(sizeof(long) * cnum);
	cname = (char **)GDKzalloc(sizeof(char *) * cnum);

	for (j = 1; j <= cnum; j++) {
		/*		fits_get_acolparms(fptr, j, cname, &tbcol, tunit, tform, &tscal, &tzero, tnull, tdisp, &status); */
		snprintf(keywrd, 80, "TTYPE%d", j);
		fits_read_key(fptr, TSTRING, keywrd, nm, NULL, &status);
		if (status) {
			snprintf(nm, FLEN_VALUE, "column_%d", j);
			status = 0;
		}
		cname[j - 1] = GDKstrdup(toLower(nm));
		fits_get_coltype(fptr, j, &tpcode[j - 1], &rep[j - 1], &wid[j - 1], &status);
		fits2subtype(&tpe, tpcode[j - 1], rep[j - 1], wid[j - 1]);

		/*		mnstr_printf(cntxt->fdout,"#%d %ld %ld - M: %s\n", tpcode[j-1], rep[j-1], wid[j-1], tpe.type->sqlname); */

		mvc_create_column(m, tbl, cname[j - 1], &tpe);
	}

	/* data load */
	fits_get_num_rows(fptr, &rows, &status);
	mnstr_printf(cntxt->fdout,"#Loading %ld rows in table %s\n", rows, tname);
	for (j = 1; j <= cnum; j++) {
		BAT *tmp = NULL;
		int time0 = GDKms();
		mtype = fits2mtype(tpcode[j - 1]);
		nilptr = ATOMnil(mtype);
		col = mvc_bind_column(m, tbl, cname[j - 1]);

		tmp = BATnew(TYPE_void, mtype, rows);
		if ( tmp == NULL){
			GDKfree(tpcode);
			GDKfree(rep);
			GDKfree(wid);
			GDKfree(cname);
			throw(MAL,"fits.load", MAL_MALLOC_FAIL);
		}
		BATseqbase(tmp, 0);
		if (rows > (long)REMAP_PAGE_MAXSIZE)
			BATmmap(tmp, STORE_MMAP, STORE_MMAP, STORE_MMAP, STORE_MMAP, 0);
		if (mtype != TYPE_str) {
			fits_read_col(fptr, tpcode[j - 1], j, 1, 1, rows, nilptr, (void *)BUNtloc(bat_iterator(tmp), BUNfirst(tmp)), &anynull, &status);
			BATsetcount(tmp, rows);
			tmp->tsorted = 0;
			tmp->trevsorted = 0;
		} else {
/*			char *v = GDKzalloc(wid[j-1]);*/
			int bsize = 50;
			int tm0, tloadtm = 0, tattachtm = 0;
			int batch = bsize, k;
			char **v = (char **) GDKzalloc(sizeof(char *) * bsize);
			for(i = 0; i < bsize; i++)
				v[i] = GDKzalloc(wid[j-1]);
			for(i = 0; i < rows; i += batch) {
				batch = rows - i < bsize ? rows - i: bsize;
				tm0 = GDKms();
				fits_read_col(fptr, tpcode[j - 1], j, 1 + i, 1, batch, nilptr, (void *)v, &anynull, &status);
				tloadtm += GDKms() - tm0;
				tm0 = GDKms();
				for(k = 0; k < batch ; k++)
					BUNappend(tmp, v[k], TRUE);
				tattachtm += GDKms() - tm0;
			}
			for(i = 0; i < bsize ; i++)
				GDKfree(v[i]);
			GDKfree(v);
			mnstr_printf(cntxt->fdout,"#String column load %d ms, BUNappend %d ms\n", tloadtm, tattachtm);
		}

		if (status) {
			char buf[FLEN_ERRMSG + 1];
			fits_read_errmsg(buf);
			msg = createException(MAL, "fits.loadtable", "Cannot load column %s of %s table: %s.\n", cname[j - 1], tname, buf);
			break;
		}
		mnstr_printf(cntxt->fdout,"#Column %s loaded for %d ms\t", cname[j-1], GDKms() - time0);
		store_funcs.append_col(m->session->tr, col, tmp, TYPE_bat);
		mnstr_printf(cntxt->fdout,"#Total %d ms\n", GDKms() - time0);
		BBPunfix(tmp->batCacheid);
	}

	GDKfree(tpcode);
	GDKfree(rep);
	GDKfree(wid);
	GDKfree(cname);

	fits_close_file(fptr, &status);
	return msg;
}
예제 #23
0
void read_PSRFITS_files(struct spectra_info *s)
// Read and convert PSRFITS information from a group of files 
// and place the resulting info into a spectra_info structure.
{
    int IMJD, SMJD, itmp, ii, status = 0;
    double OFFS, dtmp;
    long double MJDf;
    char ctmp[80], comment[120];
    
    s->datatype = PSRFITS;
    s->fitsfiles = (fitsfile **)malloc(sizeof(fitsfile *) * s->num_files);
    s->start_subint = gen_ivect(s->num_files);
    s->num_subint = gen_ivect(s->num_files);
    s->start_spec = (long long *)malloc(sizeof(long long) * s->num_files);
    s->num_spec = (long long *)malloc(sizeof(long long) * s->num_files);
    s->num_pad = (long long *)malloc(sizeof(long long) * s->num_files);
    s->start_MJD = (long double *)malloc(sizeof(long double) * s->num_files);
    s->N = 0;
    s->num_beams = 1;
    s->get_rawblock = &get_PSRFITS_rawblock;
    s->offset_to_spectra = &offset_to_PSRFITS_spectra;

    // By default, don't flip the band.  But don't change
    // the input value if it is aleady set to flip the band always
    if (s->apply_flipband==-1) s->apply_flipband = 0;

    // Step through the other files
    for (ii = 0 ; ii < s->num_files ; ii++) {

        // Is the file a PSRFITS file?
        if (!is_PSRFITS(s->filenames[ii])) {
            fprintf(stderr, 
                    "\nError!  File '%s' does not appear to be PSRFITS!\n", 
                    s->filenames[ii]);
            exit(1);
        }
        
        // Open the PSRFITS file
        fits_open_file(&(s->fitsfiles[ii]), s->filenames[ii], READONLY, &status);

        // Is the data in search mode?
        fits_read_key(s->fitsfiles[ii], TSTRING, "OBS_MODE", ctmp, comment, &status);
        // Quick fix for Parkes DFB data (SRCH?  why????)...
        if (strcmp("SRCH", ctmp)==0) {
            strncpy(ctmp, "SEARCH", 40);
        }
        if (strcmp(ctmp, "SEARCH")) {
            fprintf(stderr, 
                    "\nError!  File '%s' does not contain SEARCH-mode data!\n", 
                    s->filenames[ii]);
            exit(1);
        }

        // Now get the stuff we need from the primary HDU header
        fits_read_key(s->fitsfiles[ii], TSTRING, "TELESCOP", ctmp, comment, &status); \
        // Quick fix for MockSpec data...
        if (strcmp("ARECIBO 305m", ctmp)==0) {
            strncpy(ctmp, "Arecibo", 40);
        }
        // Quick fix for Parkes DFB data...
        {
            char newctmp[80];

            // Copy ctmp first since strlower() is in-place
            strcpy(newctmp, ctmp);
            if (strcmp("parkes", strlower(remove_whitespace(newctmp)))==0) {
                strncpy(ctmp, "Parkes", 40);
            }
        }
        if (status) {
            printf("Error %d reading key %s\n", status, "TELESCOP");
            if (ii==0) s->telescope[0]='\0';
            if (status==KEY_NO_EXIST) status=0;
        } else {
            if (ii==0) strncpy(s->telescope, ctmp, 40);
            else if (strcmp(s->telescope, ctmp)!=0)
                printf("Warning!:  %s values don't match for files 0 and %d!\n",
                       "TELESCOP", ii);
        }

        get_hdr_string("OBSERVER", s->observer);
        get_hdr_string("SRC_NAME", s->source);
        get_hdr_string("FRONTEND", s->frontend);
        get_hdr_string("BACKEND", s->backend);
        get_hdr_string("PROJID", s->project_id);
        get_hdr_string("DATE-OBS", s->date_obs);
        get_hdr_string("FD_POLN", s->poln_type);
        get_hdr_string("RA", s->ra_str);
        get_hdr_string("DEC", s->dec_str);
        get_hdr_double("OBSFREQ", s->fctr);
        get_hdr_int("OBSNCHAN", s->orig_num_chan);
        get_hdr_double("OBSBW", s->orig_df);
        //get_hdr_double("CHAN_DM", s->chan_dm);
        get_hdr_double("BMIN", s->beam_FWHM);

        /* This is likely not in earlier versions of PSRFITS so */
        /* treat it a bit differently                           */
        fits_read_key(s->fitsfiles[ii], TDOUBLE, "CHAN_DM", 
                      &(s->chan_dm), comment, &status);
        if (status==KEY_NO_EXIST) {
            status = 0;
            s->chan_dm = 0.0;
        }

        // Don't use the macros unless you are using the struct!
        fits_read_key(s->fitsfiles[ii], TINT, "STT_IMJD", &IMJD, comment, &status);
        s->start_MJD[ii] = (long double) IMJD;
        fits_read_key(s->fitsfiles[ii], TINT, "STT_SMJD", &SMJD, comment, &status);
        fits_read_key(s->fitsfiles[ii], TDOUBLE, "STT_OFFS", &OFFS, comment, &status);
        s->start_MJD[ii] += ((long double) SMJD + (long double) OFFS) / SECPERDAY;

        // Are we tracking?
        fits_read_key(s->fitsfiles[ii], TSTRING, "TRK_MODE", ctmp, comment, &status);
        itmp = (strcmp("TRACK", ctmp)==0) ? 1 : 0;
        if (ii==0) s->tracking = itmp;
        else if (s->tracking != itmp)
            printf("Warning!:  TRK_MODE values don't match for files 0 and %d!\n", ii);

        // Now switch to the SUBINT HDU header
        fits_movnam_hdu(s->fitsfiles[ii], BINARY_TBL, "SUBINT", 0, &status);
        get_hdr_double("TBIN", s->dt);
        get_hdr_int("NCHAN", s->num_channels);
        get_hdr_int("NPOL", s->num_polns);
        get_hdr_string("POL_TYPE", s->poln_order);
        fits_read_key(s->fitsfiles[ii], TINT, "NCHNOFFS", &itmp, comment, &status);
        if (itmp > 0)
            printf("Warning!:  First freq channel is not 0 in file %d!\n", ii);
        get_hdr_int("NSBLK", s->spectra_per_subint);
        get_hdr_int("NBITS", s->bits_per_sample);
        fits_read_key(s->fitsfiles[ii], TINT, "NAXIS2", 
                      &(s->num_subint[ii]), comment, &status);
        fits_read_key(s->fitsfiles[ii], TINT, "NSUBOFFS", 
                      &(s->start_subint[ii]), comment, &status);
        s->time_per_subint = s->dt * s->spectra_per_subint;

        /* This is likely not in earlier versions of PSRFITS so */
        /* treat it a bit differently                           */
        fits_read_key(s->fitsfiles[ii], TFLOAT, "ZERO_OFF", 
                      &(s->zero_offset), comment, &status);
        if (status==KEY_NO_EXIST) {
            status = 0;
            s->zero_offset = 0.0;
        }
        s->zero_offset = fabs(s->zero_offset);

        // Get the time offset column info and the offset for the 1st row
        {
            double offs_sub;
            int colnum, anynull, numrows;

            // Identify the OFFS_SUB column number
            fits_get_colnum(s->fitsfiles[ii], 0, "OFFS_SUB", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the OFFS_SUB column!\n");
                status = 0; // Reset status
            } else {
                if (ii==0) {
                    s->offs_sub_col = colnum;
                } else if (colnum != s->offs_sub_col) {
                    printf("Warning!:  OFFS_SUB column changes between files!\n");
                }
            }

            // Read the OFFS_SUB column value for the 1st row
            fits_read_col(s->fitsfiles[ii], TDOUBLE,
                          s->offs_sub_col, 1L, 1L, 1L,
                          0, &offs_sub, &anynull, &status);

            numrows = (int)((offs_sub - 0.5 * s->time_per_subint) /
                            s->time_per_subint + 1e-7);
            // Check to see if any rows have been deleted or are missing
            if (numrows > s->start_subint[ii]) {
                printf("Warning: NSUBOFFS reports %d previous rows\n"
                       "         but OFFS_SUB implies %d.  Using OFFS_SUB.\n"
                       "         Will likely be able to correct for this.\n",
                       s->start_subint[ii], numrows);
            }
            s->start_subint[ii] = numrows;
        }

        // This is the MJD offset based on the starting subint number
        MJDf = (s->time_per_subint * s->start_subint[ii]) / SECPERDAY;
        // The start_MJD values should always be correct
        s->start_MJD[ii] += MJDf;

        // Compute the starting spectra from the times
        MJDf = s->start_MJD[ii] - s->start_MJD[0];
        if (MJDf < 0.0) {
            fprintf(stderr, "Error!: File %d seems to be from before file 0!\n", ii); 
            exit(1);
        }
        s->start_spec[ii] = (long long)(MJDf * SECPERDAY / s->dt + 0.5);

        // Now pull stuff from the other columns
        {
            float ftmp;
            long repeat, width;
            int colnum, anynull;
            
            // Identify the data column and the data type
            fits_get_colnum(s->fitsfiles[ii], 0, "DATA", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the DATA column!\n");
                status = 0; // Reset status
            } else {
                if (ii==0) {
                    s->data_col = colnum;
                    fits_get_coltype(s->fitsfiles[ii], colnum, &(s->FITS_typecode), 
                                     &repeat, &width, &status);
                } else if (colnum != s->data_col) {
                    printf("Warning!:  DATA column changes between files!\n");
                }
            }
            
            // Telescope azimuth
            fits_get_colnum(s->fitsfiles[ii], 0, "TEL_AZ", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                s->azimuth = 0.0;
                status = 0; // Reset status
            } else {
                fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 
                              1L, 1L, 1L, 0, &ftmp, &anynull, &status);
                if (ii==0) s->azimuth = (double) ftmp;
            }
            
            // Telescope zenith angle
            fits_get_colnum(s->fitsfiles[ii], 0, "TEL_ZEN", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                s->zenith_ang = 0.0;
                status = 0; // Reset status
            } else {
                fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 
                              1L, 1L, 1L, 0, &ftmp, &anynull, &status);
                if (ii==0) s->zenith_ang = (double) ftmp;
            }
            
            // Observing frequencies
            fits_get_colnum(s->fitsfiles[ii], 0, "DAT_FREQ", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the channel freq column!\n");
                status = 0; // Reset status
            } else {
                int jj;
                float *freqs = (float *)malloc(sizeof(float) * s->num_channels);
                fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 
                              s->num_channels, 0, freqs, &anynull, &status);
                
                if (ii==0) {
                    s->df = freqs[1]-freqs[0];
                    s->lo_freq = freqs[0];
                    s->hi_freq = freqs[s->num_channels-1];
                    // Now check that the channel spacing is the same throughout
                    for (jj = 0 ; jj < s->num_channels - 1 ; jj++) {
                        ftmp = freqs[jj+1] - freqs[jj];
                        if (fabs(ftmp - s->df) > 1e-7)
                            printf("Warning!:  Channel spacing changes in file %d!\n", ii);
                    }
                } else {
                    ftmp = fabs(s->df-(freqs[1]-freqs[0]));
                    if (ftmp > 1e-7)
                        printf("Warning!:  Channel spacing changes between files!\n");
                    ftmp = fabs(s->lo_freq-freqs[0]);
                    if (ftmp > 1e-7)
                        printf("Warning!:  Low channel changes between files!\n");
                    ftmp = fabs(s->hi_freq-freqs[s->num_channels-1]);
                    if (ftmp > 1e-7)
                        printf("Warning!:  High channel changes between files!\n");
                }
                free(freqs);
            }
            
            // Data weights
            fits_get_colnum(s->fitsfiles[ii], 0, "DAT_WTS", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the channel weights!\n");
                status = 0; // Reset status
            } else {
                if (s->apply_weight < 0) { // Use the data to decide
                    int jj;
                    if (ii==0) {
                        s->dat_wts_col = colnum;
                    } else if (colnum != s->dat_wts_col) {
                        printf("Warning!:  DAT_WTS column changes between files!\n");
                    }
                    float *fvec = (float *)malloc(sizeof(float) * s->num_channels);
                    fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_wts_col, 1L, 1L, 
                                  s->num_channels, 0, fvec, &anynull, &status);
                    for (jj = 0 ; jj < s->num_channels ; jj++) {
                        // If the weights are not 1, apply them
                        if (fvec[jj] != 1.0) {
                            s->apply_weight = 1;
                            break;
                        }
                    }
                    free(fvec);
                }
                if (s->apply_weight < 0) s->apply_weight = 0;  // not needed
            }
            
            // Data offsets
            fits_get_colnum(s->fitsfiles[ii], 0, "DAT_OFFS", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the channel offsets!\n");
                status = 0; // Reset status
            } else {
                if (s->apply_offset < 0) { // Use the data to decide
                    int jj;
                    if (ii==0) {
                        s->dat_offs_col = colnum;
                    } else if (colnum != s->dat_offs_col) {
                        printf("Warning!:  DAT_OFFS column changes between files!\n");
                    }
                    float *fvec = (float *)malloc(sizeof(float) * 
                                                  s->num_channels * s->num_polns);
                    fits_read_col(s->fitsfiles[ii], TFLOAT, s->dat_offs_col, 1L, 1L, 
                                  s->num_channels * s->num_polns, 
                                  0, fvec, &anynull, &status);
                    for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) {
                        // If the offsets are not 0, apply them
                        if (fvec[jj] != 0.0) {
                            s->apply_offset = 1;
                            break;
                        }
                    }
                    free(fvec);
                }
                if (s->apply_offset < 0) s->apply_offset = 0; // not needed
            }
            
            // Data scalings
            fits_get_colnum(s->fitsfiles[ii], 0, "DAT_SCL", &colnum, &status);
            if (status==COL_NOT_FOUND) {
                printf("Warning!:  Can't find the channel scalings!\n");
                status = 0; // Reset status
            } else {
                if (s->apply_scale < 0) { // Use the data to decide
                    int jj;
                    if (ii==0) {
                        s->dat_scl_col = colnum;
                    } else if (colnum != s->dat_scl_col) {
                        printf("Warning!:  DAT_SCL column changes between files!\n");
                    }
                    float *fvec = (float *)malloc(sizeof(float) * 
                                                  s->num_channels * s->num_polns);
                    fits_read_col(s->fitsfiles[ii], TFLOAT, colnum, 1L, 1L, 
                                  s->num_channels * s->num_polns, 
                                  0, fvec, &anynull, &status);
                    for (jj = 0 ; jj < s->num_channels * s->num_polns ; jj++) {
                        // If the scales are not 1, apply them
                        if (fvec[jj] != 1.0) {
                            s->apply_scale = 1;
                            break;
                        }
                    }
                    free(fvec);
                }
                if (s->apply_scale < 0) s->apply_scale = 0; // not needed
            }
        }
        
        // Compute the samples per file and the amount of padding
        // that the _previous_ file has
        s->num_pad[ii] = 0;
        s->num_spec[ii] = s->spectra_per_subint * s->num_subint[ii];
        if (ii > 0) {
            if (s->start_spec[ii] > s->N) { // Need padding
                s->num_pad[ii-1] = s->start_spec[ii] - s->N;
                s->N += s->num_pad[ii-1];
            }
        }
        s->N += s->num_spec[ii];
    }

    // Convert the position strings into degrees
    {
        int d, h, m;
        double sec;
        ra_dec_from_string(s->ra_str, &h, &m, &sec);
        s->ra2000 = hms2rad(h, m, sec) * RADTODEG;
        ra_dec_from_string(s->dec_str, &d, &m, &sec);
        s->dec2000 = dms2rad(d, m, sec) * RADTODEG;
    }

    // Are the polarizations summed?
    if ((strncmp("AA+BB", s->poln_order, 5)==0) ||
        (strncmp("INTEN", s->poln_order, 5)==0))
        s->summed_polns = 1;
    else
        s->summed_polns = 0;

    // Calculate some others
    s->T = s->N * s->dt;
    s->orig_df /= (double) s->orig_num_chan;
    s->samples_per_spectra = s->num_polns * s->num_channels;
    // Note:  the following is the number of bytes that will be in
    //        the returned array from CFITSIO.
    //        CFITSIO turns bits into bytes when FITS_typecode=1
    //        and we turn 2-bits or 4-bits into bytes if bits_per_sample < 8
    if (s->bits_per_sample < 8)
        s->bytes_per_spectra = s->samples_per_spectra;
    else
        s->bytes_per_spectra = (s->bits_per_sample * s->samples_per_spectra) / 8;
    s->samples_per_subint = s->samples_per_spectra * s->spectra_per_subint;
    s->bytes_per_subint = s->bytes_per_spectra * s->spectra_per_subint;
    
    // Flip the band?
    if (s->hi_freq < s->lo_freq) {
        float ftmp = s->hi_freq;
        s->hi_freq = s->lo_freq;
        s->lo_freq = ftmp;
        s->df *= -1.0;
        s->apply_flipband = 1;
    }
    // Compute the bandwidth
    s->BW = s->num_channels * s->df;

    // Flip the bytes for Parkes FB_1BIT data
    if (s->bits_per_sample==1 &&
        strcmp(s->telescope, "Parkes")==0 &&
        strcmp(s->backend, "FB_1BIT")==0) {
        printf("Flipping bit ordering since Parkes FB_1BIT data.\n");
        s->flip_bytes = 1;
    } else {
        s->flip_bytes = 0;
    }

    // Allocate the buffers
    cdatabuffer = gen_bvect(s->bytes_per_subint);
    // Following is twice as big because we use it as a ringbuffer too
    fdatabuffer = gen_fvect(2 * s->spectra_per_subint * s->num_channels);
    s->padvals = gen_fvect(s->num_channels);
    for (ii = 0 ; ii < s->num_channels ; ii++)
        s->padvals[ii] = 0.0;
    offsets = gen_fvect(s->num_channels * s->num_polns);
    scales = gen_fvect(s->num_channels * s->num_polns);
    weights = gen_fvect(s->num_channels);
    // Initialize these if we won't be reading them from the file
    if (s->apply_offset==0) 
        for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++)
            offsets[ii] = 0.0;
    if (s->apply_scale==0)
        for (ii = 0 ; ii < s->num_channels * s->num_polns ; ii++)
            scales[ii] = 1.0;
    if (s->apply_weight==0)
        for (ii = 0 ; ii < s->num_channels ; ii++)
            weights[ii] = 1.0;
}
예제 #24
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);
}