Beispiel #1
0
void nodedelete (node* target)
{
  if (target != NULL)
  {
  node* y;
  if (target->left == NULL)
  {
    transplant(target,target->right);
  }
  else
  {
    if (target->right == NULL)
    {
      transplant(target,target->left);
    }
    else
    {
      y = minvalue(target->right);
      if (y->up != target)
      {
        transplant(y,y->right);
        y->right = target->right;
        y->right->up = y;
      }
      transplant(target,y);
      y->left = target->left;
      y->left->up = y;
    }
  }
  
  free(target);
  }
}
 size_t determine_upsample_ratio (const Image::Info& info, const float step_size, const float ratio)
 {
   size_t upsample_ratio = 1;
   if (step_size && std::isfinite (step_size))
     upsample_ratio = std::ceil (step_size / (minvalue (info.vox(0), info.vox(1), info.vox(2)) * ratio));
   return upsample_ratio;
 }
Beispiel #3
0
node* minvalue (node* root)
{
  if (root->left != NULL)
  { return minvalue (root->left); }
  else
  { return root; }
}
int alphabeta(struct game *state,int alpha, int beta)
{

  /*  printf("minimax: Calculating minimax for board '%s' with player %c\n",state->board,state->player); */

  /* loop through next states getting minimax values */

  char outcome = isTerminal(state->board);

  switch(outcome)
  {
	case 'x':
	  return 1;
	case 'o':
	  return -1;
	case 'd':
	  return 0;
	case ' ':
	  if (state->player == 'x') {
		return maxvalue(gennextstates(state),alpha,beta);
	  } else {
		return minvalue(gennextstates(state),alpha,beta);
	  }
  }

}
Beispiel #5
0
void uprint (node* root)
{
  node* sth;
  sth = minvalue (root);
  while ( sth != NULL )
  {
    printsingle (sth);
    sth = bstsucc (sth);
  }
}
Beispiel #6
0
/*--------------------------------------------------------------------------*/
int fits_get_col_minmax(fitsfile *fptr, int colnum, float *datamin, 
                     float *datamax, int *status)
/* 
   Simple utility routine to compute the min and max value in a column
*/
{
    int anynul;
    long nrows, ntodo, firstrow, ii;
    float array[1000], nulval;

    ffgky(fptr, TLONG, "NAXIS2", &nrows, NULL, status); /* no. of rows */

    firstrow = 1;
    nulval = FLOATNULLVALUE;
    *datamin =  9.0E36F;
    *datamax = -9.0E36F;

    while(nrows)
    {
        ntodo = minvalue(nrows, 100);
        ffgcv(fptr, TFLOAT, colnum, firstrow, 1, ntodo, &nulval, array,
              &anynul, status);

        for (ii = 0; ii < ntodo; ii++)
        {
            if (array[ii] != nulval)
            {
                *datamin = minvalue(*datamin, array[ii]);
                *datamax = maxvalue(*datamax, array[ii]);
            }
        }

        nrows -= ntodo;
        firstrow += ntodo;
    }
    return(*status);
}
Beispiel #7
0
node* bstsucc (node* what)
{
  node* succ;
  succ = what->up;
  if (what == NULL)
  { return NULL; }
  if (what->right != NULL)
  { return minvalue(what->right); }
  while(succ != NULL && succ->right == what)
  {
    what = succ;
    succ = succ->up;
  }
  return succ;
}
void countingsort(int *A, int n){
    int k = maxvalue(A, n);
    int m = minvalue(A, n);
    int sep = m < 0 ? -m : 0;
    int *B = new int[n];
    int *C = new int[k+sep+1];
    for(int i = 0; i < k+sep+1; i++)
        C[i] = 0;
    for(int i = 0; i < n; i++)
        C[A[i]+sep]++;
    for(int i = 1; i < k+1+sep; i++)
        C[i] += C[i-1];
    for(int i = n-1; i >= 0; i--){
        B[C[A[i]+sep]-1] = A[i];
        C[A[i]+sep]--;
    }
    for(int i = 0; i < n; i++){
        A[i]=B[i];
    }
    delete [] B;
    delete [] C;
}
Beispiel #9
0
/*--------------------------------------------------------------------------*/
int ffpcld( fitsfile *fptr,  /* I - FITS file pointer                       */
            int  colnum,     /* I - number of column to write (1 = 1st col) */
            LONGLONG  firstrow,  /* I - first row to write (1 = 1st row)        */
            LONGLONG  firstelem, /* I - first vector element to write (1 = 1st) */
            LONGLONG  nelem,     /* I - number of values to write               */
            double *array,   /* I - array of values to write                */
            int  *status)    /* IO - error status                           */
/*
  Write an array of values to a column in the current FITS HDU.
  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.

  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.
*/
{
    int tcode, maxelem, hdutype, writeraw;
    long twidth, incre;
    long ntodo;
    LONGLONG repeat, startpos, elemnum, wrtptr, rowlen, rownum, remain, next, tnull;
    double scale, zero;
    char tform[20], cform[20];
    char message[FLEN_ERRMSG];

    char snull[20];   /*  the FITS null value  */

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

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

    buffer = cbuff;

    /*---------------------------------------------------*/
    /*  Check input and get parameters about the column: */
    /*---------------------------------------------------*/
    if (ffgcprll( fptr, colnum, firstrow, firstelem, nelem, 1, &scale, &zero,
        tform, &twidth, &tcode, &maxelem, &startpos,  &elemnum, &incre,
        &repeat, &rowlen, &hdutype, &tnull, snull, status) > 0)
        return(*status);

    if (tcode == TSTRING)   
         ffcfmt(tform, cform);     /* derive C format for writing strings */

    /*
      if there is no scaling and the native machine format is not byteswapped,
      then we can simply write the raw data bytes into the FITS file if the
      datatype of the FITS column is the same as the input values.  Otherwise,
      we must convert the raw values into the scaled and/or machine dependent
      format in a temporary buffer that has been allocated for this purpose.
    */
    if (scale == 1. && zero == 0. && 
       MACHINE == NATIVE && tcode == TDOUBLE)
    {
        writeraw = 1;
        maxelem = (int) nelem;  /* we can write the entire array at one time */
    }
    else
        writeraw = 0;

    /*---------------------------------------------------------------------*/
    /*  Now write the pixels to the FITS column.                           */
    /*  First call the ffXXfYY routine to  (1) convert the datatype        */
    /*  if necessary, and (2) scale the values by the FITS TSCALn and      */
    /*  TZEROn linear scaling parameters into a temporary buffer.          */
    /*---------------------------------------------------------------------*/
    remain = nelem;           /* remaining number of values to write  */
    next = 0;                 /* next element in array to be written  */
    rownum = 0;               /* row number, relative to firstrow     */

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

        wrtptr = startpos + ((LONGLONG)rownum * rowlen) + (elemnum * incre);

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

        switch (tcode) 
        {
            case (TDOUBLE):
              if (writeraw)
              {
                /* write raw input bytes without conversion */
                ffpr8b(fptr, ntodo, incre, &array[next], status);
              }
              else
              {
                /* convert the raw data before writing to FITS file */
                ffr8fr8(&array[next], ntodo, scale, zero,
                        (double *) buffer, status);
                ffpr8b(fptr, ntodo, incre, (double *) buffer, status);
              }

              break;

            case (TLONGLONG):

                ffr8fi8(&array[next], ntodo, scale, zero,
                        (LONGLONG *) buffer, status);
                ffpi8b(fptr, ntodo, incre, (long *) buffer, status);
                break;

            case (TBYTE):
 
                ffr8fi1(&array[next], ntodo, scale, zero, 
                        (unsigned char *) buffer, status);
                ffpi1b(fptr, ntodo, incre, (unsigned char *) buffer, status);
                break;

            case (TSHORT):

                ffr8fi2(&array[next], ntodo, scale, zero, 
                       (short *) buffer, status);
                ffpi2b(fptr, ntodo, incre, (short *) buffer, status);
                break;

            case (TLONG):

                ffr8fi4(&array[next], ntodo, scale, zero,
                        (INT32BIT *) buffer, status);
                ffpi4b(fptr, ntodo, incre, (INT32BIT *) buffer, status);
                break;

            case (TFLOAT):
                ffr8fr4(&array[next], ntodo, scale, zero,
                        (float *) buffer, status);
                ffpr4b(fptr, ntodo, incre, (float *) buffer, status);
                break;

            case (TSTRING):  /* numerical column in an ASCII table */

                if (cform[1] != 's')  /*  "%s" format is a string */
                {
                  ffr8fstr(&array[next], ntodo, scale, zero, cform,
                          twidth, (char *) buffer, status);

                  if (incre == twidth)    /* contiguous bytes */
                     ffpbyt(fptr, ntodo * twidth, buffer, status);
                  else
                     ffpbytoff(fptr, twidth, ntodo, incre - twidth, buffer,
                            status);

                  break;
                }
                /* can't write to string column, so fall thru to default: */

            default:  /*  error trap  */
                sprintf(message, 
                      "Cannot write numbers to column %d which has format %s",
                       colnum,tform);
                ffpmsg(message);
                if (hdutype == ASCII_TBL)
                    return(*status = BAD_ATABLE_FORMAT);
                else
                    return(*status = BAD_BTABLE_FORMAT);

        } /* End of switch block */

        /*-------------------------*/
        /*  Check for fatal error  */
        /*-------------------------*/
        if (*status > 0)  /* test for error during previous write operation */
        {
          sprintf(message,
          "Error writing elements %.0f thru %.0f of input data array (ffpcld).",
              (double) (next+1), (double) (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++;
            }
        }
    }  /*  End of main while Loop  */


    /*--------------------------------*/
    /*  check for numerical overflow  */
    /*--------------------------------*/
    if (*status == OVERFLOW_ERR)
    {
        ffpmsg(
        "Numerical overflow during type conversion while writing FITS data.");
        *status = NUM_OVERFLOW;
    }

    return(*status);
}
Beispiel #10
0
/*--------------------------------------------------------------------------*/
int ffiter(int n_cols,
           iteratorCol *cols,
           long offset,
           long n_per_loop,
           int (*work_fn)(long total_n,
                          long offset,
                          long first_n,
                          long n_values,
                          int n_cols,
                          iteratorCol *cols,
                          void *userPointer),
           void *userPointer,
           int *status)
/*
   The iterator function.  This function will pass the specified
   columns from a FITS table or pixels from a FITS image to the 
   user-supplied function.  Depending on the size of the table
   or image, only a subset of the rows or pixels may be passed to the
   function on each call, in which case the function will be called
   multiple times until all the rows or pixels have been processed.
*/
{
    typedef struct  /* structure to store the column null value */
    {  
        int      nullsize;    /* length of the null value, in bytes */
        union {   /*  default null value for the column */
            char   *stringnull;
            unsigned char   charnull;
            int    intnull;
            short  shortnull;
            long   longnull;
            unsigned int   uintnull;
            unsigned short ushortnull;
            unsigned long  ulongnull;
            float  floatnull;
            double doublenull;
        } null;
    } colNulls;

    void *dataptr, *defaultnull;
    colNulls *col;
    int ii, jj, tstatus;
    int typecode, hdutype, jtype, type, anynul, nfiles, nbytes;
    long totaln, nleft, frow, felement, n_optimum, i_optimum, ntodo;
    long rept, width, tnull;
    double zeros = 0.;
    char message[FLEN_ERRMSG], keyname[FLEN_KEYWORD], nullstr[FLEN_VALUE];
    char **stringptr, *nullptr, *cptr;

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

    if (n_cols  < 0 || n_cols > 999 )
    {
        ffpmsg("Illegal number of columms (ffiter)");
        return(*status = BAD_COL_NUM);  /* negative number of columns */
    }

    col = calloc(n_cols, sizeof(colNulls) ); /* memory for the null values */

    /*------------------------------------------------------------*/
    /* Make sure column numbers and datatypes are in legal range  */
    /* and column numbers and datatypes are legal.                */ 
    /* Also fill in other parameters in the column structure.     */
    /*------------------------------------------------------------*/

    ffghdt(cols[0].fptr, &hdutype, status);  /* type of first HDU */

    for (jj = 0; jj < n_cols; jj++)
    {
        /* check that output datatype code value is legal */
        type = cols[jj].datatype;  
        if (type != 0 &&
            type != TBYTE  && type != TLOGICAL && type != TSTRING &&
            type != TSHORT && type != TINT     && type != TLONG && 
            type != TFLOAT && type != TDOUBLE  && type != TCOMPLEX &&
            type != TULONG && type != TUSHORT  && type != TDBLCOMPLEX)
        {
            sprintf(message,
                   "Illegal datatype for column number %d: %d  (ffiter)",
                    jj + 1, cols[jj].datatype);
            ffpmsg(message);
            return(*status = BAD_DATATYPE);
        }

        /* initialize TLMINn, TLMAXn, column name, and display format */
        cols[jj].tlmin = 0;
        cols[jj].tlmax = 0;
        cols[jj].tunit[0] = '\0';
        cols[jj].tdisp[0] = '\0';

        ffghdt(cols[jj].fptr, &jtype, status);  /* get HDU type */

        if (hdutype == IMAGE_HDU)
        {
            if (jtype != IMAGE_HDU)
            {
                sprintf(message,
                "File %d not positioned to an image extension (ffiter)",
                    jj + 1);
                return(*status = NOT_IMAGE);
            }

            /* images are stored in column 2; ignore the input value */
            cols[jj].colnum = 2;
            strcpy(cols[jj].colname, "IMAGE");  /* dummy name for images */

            tstatus = 0;
            ffgkys(cols[jj].fptr, "BUNIT", cols[jj].tunit, 0, &tstatus);
        }
        else
        {
            if (jtype == IMAGE_HDU)
            {
                sprintf(message,
                "File %d not positioned to a table extension (ffiter)",
                    jj + 1);
                return(*status = NOT_TABLE);
            }

            if (cols[jj].colnum < 1)
            {
                /* find the column number for the named column */
                if (ffgcno(cols[jj].fptr, CASEINSEN, cols[jj].colname,
                           &cols[jj].colnum, status) )
                {
                    sprintf(message,
                      "Column '%s' not found for column number %d  (ffiter)",
                       cols[jj].colname, jj + 1);
                    ffpmsg(message);
                    return(*status);
                }
            }

            if (cols[jj].colnum < 1 || 
                cols[jj].colnum > ((cols[jj].fptr)->Fptr)->tfield)
            {
                sprintf(message,
                  "Column %d has illegal table position number: %d  (ffiter)",
                    jj + 1, cols[jj].colnum);
                ffpmsg(message);
                return(*status = BAD_COL_NUM);
            }

            /* look for column description keywords and update structure */
            tstatus = 0;
            ffkeyn("TLMIN", cols[jj].colnum, keyname, &tstatus);
            ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmin, 0, &tstatus);

            tstatus = 0;
            ffkeyn("TLMAX", cols[jj].colnum, keyname, &tstatus);
            ffgkyj(cols[jj].fptr, keyname, &cols[jj].tlmax, 0, &tstatus);

            tstatus = 0;
            ffkeyn("TTYPE", cols[jj].colnum, keyname, &tstatus);
            ffgkys(cols[jj].fptr, keyname, cols[jj].colname, 0, &tstatus);
            if (tstatus)
                cols[jj].colname[0] = '\0';

            tstatus = 0;
            ffkeyn("TUNIT", cols[jj].colnum, keyname, &tstatus);
            ffgkys(cols[jj].fptr, keyname, cols[jj].tunit, 0, &tstatus);

            tstatus = 0;
            ffkeyn("TDISP", cols[jj].colnum, keyname, &tstatus);
            ffgkys(cols[jj].fptr, keyname, cols[jj].tdisp, 0, &tstatus);
        }
    }

    /*-----------------------------------------------------------------*/
    /* use the first file to set the total number of values to process */
    /*-----------------------------------------------------------------*/

    offset = maxvalue(offset, 0L);  /* make sure offset is legal */

    if (hdutype == IMAGE_HDU)   /* get total number of pixels in the image */
    {
      ffgtcl(cols[0].fptr, cols[0].colnum, NULL, &totaln, &width, status);
      frow = 1;
      felement = 1 + offset;
    }
    else   /* get total number or rows in the table */
    {
      ffgkyj(cols[0].fptr, "NAXIS2", &totaln, 0, status);
      frow = 1 + offset;
      felement = 1;
    }

    /*  adjust total by the input starting offset value */
    totaln -= offset;
    totaln = maxvalue(totaln, 0L);   /* don't allow negative number */

    /*------------------------------------------------------------------*/
    /* Determine number of values to pass to work function on each loop */
    /*------------------------------------------------------------------*/

    if (n_per_loop == 0)
    {
        /* Determine optimum number of values for each iteration.    */
        /* Look at all the fitsfile pointers to determine the number */
        /* of unique files.                                          */

        nfiles = 1;
        ffgrsz(cols[0].fptr, &n_optimum, status);

        for (jj = 1; jj < n_cols; jj++)
        {
            for (ii = 0; ii < jj; ii++)
            {
                if (cols[ii].fptr == cols[jj].fptr)
                   break;
            }

            if (ii == jj)  /* this is a new file */
            {
                nfiles++;
                ffgrsz(cols[jj].fptr, &i_optimum, status);
                n_optimum = minvalue(n_optimum, i_optimum);
            }
        }

        n_optimum = n_optimum / nfiles;
    }
    else if (n_per_loop < 0)  /* must pass all the values at one time */
    {
        n_optimum = totaln;
    }
    else /* calling routine specified how many values to pass at a time */
    {
        n_optimum = minvalue(n_per_loop, totaln);
    }

    /*--------------------------------------*/
    /* allocate work arrays for each column */
    /* and determine the null pixel value   */
    /*--------------------------------------*/

    for (jj = 0; jj < n_cols; jj++)
    {
        /* get column datatype and vector length */
        if (ffgtcl(cols[jj].fptr, cols[jj].colnum, &typecode, &rept,
                  &width, status) > 0)
            goto cleanup;

        /* special case where sizeof(long) = 8: use TINT instead of TLONG */
        if (typecode == TLONG && sizeof(long) == 8 && sizeof(int) == 4)
            typecode = TINT;

        /* Special case: interprete 'X' column as 'B' */
        if (abs(typecode) == TBIT)
        {
            typecode  = typecode / TBIT * TBYTE;
            rept = (rept + 7) / 8;
        }

        if (cols[jj].datatype == 0)    /* output datatype not specified? */
        {
            /* special case if sizeof(long) = 8: use TINT instead of TLONG */
            if (typecode == TLONG && sizeof(long) == 8 && sizeof(int) == 4)
                cols[jj].datatype = TINT;
            else
                cols[jj].datatype = typecode;
        }

        /* calc total number of elements to do on each iteration */
        if (hdutype == IMAGE_HDU || cols[jj].datatype == TSTRING)
        {
            ntodo = n_optimum; 
            cols[jj].repeat = 1;

            /* get the BLANK keyword value, if it exists */
            if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
            {
                tstatus = 0;
                ffgkyj(cols[jj].fptr, "BLANK", &tnull, 0, &tstatus);
                if (tstatus)
                {
                    tnull = 0L;  /* no null values */
                }
            }
        }
        else
        {
            ntodo = n_optimum * rept;   /* vector columns */
            cols[jj].repeat = rept;

            /* get the TNULL keyword value, if it exists */
            if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
            {
                tstatus = 0;
                if (hdutype == ASCII_TBL) /* TNULLn value is a string */
                {
                    ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
                    ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
                    if (tstatus)
                    {
                        tnull = 0L; /* keyword doesn't exist; no null values */
                    }
                    else
                    {
                        cptr = nullstr;
                        while (*cptr == ' ')  /* skip over leading blanks */
                           cptr++;

                        if (*cptr == '\0')  /* TNULLn is all blanks? */
                            tnull = LONG_MIN;
                        else
                        {                                                
                            /* attempt to read TNULLn string as an integer */
                            ffc2ii(nullstr, &tnull, &tstatus);

                            if (tstatus)
                                tnull = LONG_MIN;  /* choose smallest value */
                        }                          /* to represent nulls */
                    }
                }
                else  /* Binary table; TNULLn value is an integer */
                {
                    ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
                    ffgkyj(cols[jj].fptr, keyname, &tnull, 0, &tstatus);
                    if (tstatus)
                    {
                        tnull = 0L; /* keyword doesn't exist; no null values */
                    }
                    else if (tnull == 0)
                    {
                        /* worst possible case: a value of 0 is used to   */
                        /* represent nulls in the FITS file.  We have to  */
                        /* use a non-zero null value here (zero is used to */
                        /* mean there are no null values in the array) so we */
                        /* will use the smallest possible integer instead. */

                        tnull = LONG_MIN;  /* choose smallest possible value */
                    }
                }
            }
        }

        /* Note that the data array starts with 2nd element;  */
        /* 1st element of the array gives the null data value */

        switch (cols[jj].datatype)
        {
         case TBYTE:
          cols[jj].array = calloc(ntodo + 1, sizeof(char));
          col[jj].nullsize  = sizeof(char);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              tnull = minvalue(tnull, 255);
              tnull = maxvalue(tnull, 0);
              col[jj].null.charnull = (unsigned char) tnull;
          }
          else
          {
              col[jj].null.charnull = (unsigned char) 255; /* use 255 as null */
          }
          break;

         case TSHORT:
          cols[jj].array = calloc(ntodo + 1, sizeof(short));
          col[jj].nullsize  = sizeof(short);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              tnull = minvalue(tnull, SHRT_MAX);
              tnull = maxvalue(tnull, SHRT_MIN);
              col[jj].null.shortnull = (short) tnull;
          }
          else
          {
              col[jj].null.shortnull = SHRT_MIN;  /* use minimum as null */
          }
          break;

         case TUSHORT:
          cols[jj].array = calloc(ntodo + 1, sizeof(unsigned short));
          col[jj].nullsize  = sizeof(unsigned short);  /* bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              tnull = minvalue(tnull, USHRT_MAX);
              tnull = maxvalue(tnull, 0);  /* don't allow negative value */
              col[jj].null.ushortnull = (unsigned short) tnull;
          }
          else
          {
              col[jj].null.ushortnull = USHRT_MAX;   /* use maximum null */
          }
          break;

         case TINT:
          cols[jj].array = calloc(ntodo + 1, sizeof(int));
          col[jj].nullsize  = sizeof(int);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              tnull = minvalue(tnull, INT_MAX);
              tnull = maxvalue(tnull, INT_MIN);
              col[jj].null.intnull = (int) tnull;
          }
          else
          {
              col[jj].null.intnull = INT_MIN;  /* use minimum as null */
          }
          break;

         case TUINT:
          cols[jj].array = calloc(ntodo + 1, sizeof(unsigned int));
          col[jj].nullsize  = sizeof(unsigned int);  /* bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              tnull = minvalue(tnull, INT32_MAX);
              tnull = maxvalue(tnull, 0);
              col[jj].null.uintnull = (unsigned int) tnull;
          }
          else
          {
              col[jj].null.intnull = UINT_MAX;  /* use maximum as null */
          }
          break;

         case TLONG:
          cols[jj].array = calloc(ntodo + 1, sizeof(long));
          col[jj].nullsize  = sizeof(long);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              col[jj].null.longnull = tnull;
          }
          else
          {
              col[jj].null.longnull = LONG_MIN;   /* use minimum as null */
          }
          break;

         case TULONG:
          cols[jj].array = calloc(ntodo + 1, sizeof(unsigned long));
          col[jj].nullsize  = sizeof(unsigned long);  /* bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              if (tnull < 0)  /* can't use a negative null value */
                  col[jj].null.ulongnull = LONG_MAX;
              else
                  col[jj].null.ulongnull = (unsigned long) tnull;
          }
          else
          {
              col[jj].null.ulongnull = LONG_MAX;   /* use maximum as null */
          }
          break;

         case TFLOAT:
          cols[jj].array = calloc(ntodo + 1, sizeof(float));
          col[jj].nullsize  = sizeof(float);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              col[jj].null.floatnull = (float) tnull;
          }
          else
          {
              col[jj].null.floatnull = FLOATNULLVALUE;  /* special value */
          }
          break;

         case TCOMPLEX:
          cols[jj].array = calloc((ntodo * 2) + 1, sizeof(float));
          col[jj].nullsize  = sizeof(float);  /* number of bytes per value */
          col[jj].null.floatnull = FLOATNULLVALUE;  /* special value */
          break;

         case TDOUBLE:
          cols[jj].array = calloc(ntodo + 1, sizeof(double));
          col[jj].nullsize  = sizeof(double);  /* number of bytes per value */

          if (typecode == TBYTE || typecode == TSHORT || typecode == TLONG)
          {
              col[jj].null.doublenull = (double) tnull;
          }
          else
          {
              col[jj].null.doublenull = DOUBLENULLVALUE;  /* special value */
          }
          break;

         case TDBLCOMPLEX:
          cols[jj].array = calloc((ntodo * 2) + 1, sizeof(double));
          col[jj].nullsize  = sizeof(double);  /* number of bytes per value */
          col[jj].null.doublenull = DOUBLENULLVALUE;  /* special value */
          break;

         case TSTRING:
          /* allocate array of pointers to all the strings  */
	  if( hdutype==ASCII_TBL ) rept = width;
          stringptr = calloc((ntodo + 1) , sizeof(stringptr));
          cols[jj].array = stringptr;
          col[jj].nullsize  = rept + 1;  /* number of bytes per value */

          if (stringptr)
          {
            /* allocate string to store the null string value */
            col[jj].null.stringnull = calloc(rept + 1, sizeof(char) );
            col[jj].null.stringnull[1] = 1; /* to make sure string != 0 */

            /* allocate big block for the array of table column strings */
            stringptr[0] = calloc((ntodo + 1) * (rept + 1), sizeof(char) );

            if (stringptr[0])
            {
              for (ii = 1; ii <= ntodo; ii++)
              {   /* pointer to each string */
                stringptr[ii] = stringptr[ii - 1] + (rept + 1);
              }

              /* get the TNULL keyword value, if it exists */
              tstatus = 0;
              ffkeyn("TNULL", cols[jj].colnum, keyname, &tstatus);
              ffgkys(cols[jj].fptr, keyname, nullstr, 0, &tstatus);
              if (!tstatus)
                  strncat(col[jj].null.stringnull, nullstr, rept);
            }
            else
            {
              ffpmsg("ffiter failed to allocate memory arrays");
              *status = MEMORY_ALLOCATION;  /* memory allocation failed */
              goto cleanup;
            }
          }
          break;

         case TLOGICAL:

          cols[jj].array = calloc(ntodo + 1, sizeof(char));
          col[jj].nullsize  = sizeof(char);  /* number of bytes per value */

          /* use value = 2 to flag null values in logical columns */
          col[jj].null.charnull = 2;
          break;

         default:
          sprintf(message,
                  "Column %d datatype currently not supported: %d:  (ffiter)",
                   jj + 1, cols[jj].datatype);
          ffpmsg(message);
          *status = BAD_DATATYPE;
          goto cleanup;

        }   /* end of switch block */

        /* check that all the arrays were allocated successfully */
        if (!cols[jj].array)
        {
            ffpmsg("ffiter failed to allocate memory arrays");
            *status = MEMORY_ALLOCATION;  /* memory allocation failed */
            goto cleanup;
        }
    }
 
    /*--------------------------------------------------*/
    /* main loop while there are values left to process */
    /*--------------------------------------------------*/

    nleft = totaln;

    while (nleft)
    {
      ntodo = minvalue(nleft, n_optimum); /* no. of values for this loop */

      /*  read input columns from FITS file(s)  */
      for (jj = 0; jj < n_cols; jj++)
      {
        if (cols[jj].iotype != OutputCol)
        {
          if (cols[jj].datatype == TSTRING)
          {
            stringptr = cols[jj].array;
            dataptr = stringptr + 1;
            defaultnull = col[jj].null.stringnull; /* ptr to the null value */
          }
          else
          {
            dataptr = (char *) cols[jj].array + col[jj].nullsize;
            defaultnull = &col[jj].null.charnull; /* ptr to the null value */
          }
          if (ffgcv(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum,
                    frow, felement, cols[jj].repeat * ntodo, defaultnull,
                    dataptr,  &anynul, status) > 0)
          {
            break;
          }

          /* copy the appropriate null value into first array element */

          if (anynul)   /* are there any nulls in the data? */
          {   
            if (cols[jj].datatype == TSTRING)
            {
              stringptr = cols[jj].array;
              memcpy(*stringptr, col[jj].null.stringnull, col[jj].nullsize);
            }
            else
            {
              memcpy(cols[jj].array, defaultnull, col[jj].nullsize);
            }
          }
          else /* no null values so copy zero into first element */
          {
            if (cols[jj].datatype == TSTRING)
            {
              stringptr = cols[jj].array;
              memset(*stringptr, 0, col[jj].nullsize);  
            }
            else
            {
              memset(cols[jj].array, 0, col[jj].nullsize);  
            }
          }
        }
      }

      if (*status > 0) 
         break;   /* looks like an error occurred; quit immediately */

      /* call work function */

      if (hdutype == IMAGE_HDU) 
          *status = work_fn(totaln, offset, felement, ntodo, n_cols, cols,
                    userPointer);
      else
          *status = work_fn(totaln, offset, frow, ntodo, n_cols, cols,
                    userPointer);

      if (*status > 0 || *status < -1 ) 
         break;   /* looks like an error occurred; quit immediately */

      /*  write output columns  before quiting if status = -1 */
      tstatus = 0;
      for (jj = 0; jj < n_cols; jj++)
      {
        if (cols[jj].iotype != InputCol)
        {
          if (cols[jj].datatype == TSTRING)
          {
            stringptr = cols[jj].array;
            dataptr = stringptr + 1;
            nullptr = *stringptr;
            nbytes = 2;
          }
          else
          {
            dataptr = (char *) cols[jj].array + col[jj].nullsize;
            nullptr = (char *) cols[jj].array;
            nbytes = col[jj].nullsize;
          }

          if (memcmp(nullptr, &zeros, nbytes) ) 
          {
            /* null value flag not zero; must check for and write nulls */
            if (ffpcn(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
                      felement, cols[jj].repeat * ntodo, dataptr,
                      nullptr, &tstatus) > 0)
              break;
          }
          else
          { 
            /* no null values; just write the array */
            if (ffpcl(cols[jj].fptr, cols[jj].datatype, cols[jj].colnum, frow,
                      felement, cols[jj].repeat * ntodo, dataptr,
                      &tstatus) > 0)
              break;
          }
        }
      }

      if (*status == 0)
         *status = tstatus;   /* propagate any error status from the writes */

      if (*status) 
         break;   /* exit on any error */

      nleft -= ntodo;

      if (hdutype == IMAGE_HDU)
          felement += ntodo;
      else
          frow  += ntodo;
    }

cleanup:

    /*----------------------------------*/
    /* free work arrays for the columns */
    /*----------------------------------*/

    for (jj = 0; jj < n_cols; jj++)
    {
        if (cols[jj].datatype == TSTRING)
        {
            if (cols[jj].array)
            {
                stringptr = cols[jj].array;
                free(*stringptr);     /* free the block of strings */
                free(col[jj].null.stringnull); /* free the null string */
            }
        }
        free(cols[jj].array); /* memory for the array of values from the col */
    }
    free(col);   /* the structure containing the null values */
    return(*status);
}
Beispiel #11
0
static float xMedian (float x[], int n) {

/* arguments:
float x[]     io: the array (will be scrambled and possibly modified)
int n         i: number of elements in x (modified locally)
*/

	int i, j;
	int next_n;
	int npix;
	int done;
	float median = 0.;

	if (n < 1) {
            ffpmsg("xMedian: no data");
	    return (0.);
	}
	if (n == 1)
	    return (x[0]);
	if (n == 2)
	    return ((x[0] + x[1]) / 2.);

	done = 0;
	while (!done) {

	    if (n < SORT_CUTOFF) {
		qsort (x, n, sizeof (float), FqCompare);
		if (n / 2 * 2 == n)
		    median = (x[n/2-1] + x[n/2]) / 2.;
		else
		    median = x[n/2];
		return (median);
	    }

	    /* ignore trailing groups of less than three elements */
	    next_n = (n + NELEM-3) / NELEM;

	    for (j = 0;  j < next_n;  j++) {

		i = j * NELEM;
		npix = minvalue (NELEM, n - j*NELEM);

		InsertionSort (&x[i], npix);

		switch (npix) {
		case 1:
		    median = x[i];
		    break;
		case 2:
		    median = (x[i] + x[i+1]) / 2.;
		    break;
		case 3:
		    median = x[i+1];
		    break;
		case 4:
		    median = (x[i+1] + x[i+2]) / 2.;
		    break;
		case 5:				/* NELEM = 5 */
		    median = x[i+2];
		    break;
		default:
                    ffpmsg("npix should be 1..5");
		}

		x[j] = median;
	    }

	    if (next_n <= 1)
		done = 1;
	    else
		n = next_n;
	}

	return (x[0]);
}
Beispiel #12
0
int fits_quantize_float (float fdata[], int nx, float in_null_value,
                  int noise_bits, int idata[], double *bscale,
                  double *bZero, int *iminval, int *imaxval) {

/* arguments:
float fdata[]       i: array of image pixels to be compressed
int nx              i: length of fdata array
float in_null_value i: value used to represent undefined pixels in fdata
int noise_bits      i: quantization level (number of bits)
int idata[]         o: values of fdata after applying bZero and bscale
double bscale       o: scale factor
double bZero        o: zero offset
int iminval         o: minimum quantized value that is returned
int imaxval         o: maximum quantized value that is returned

The function value will be one if the input fdata were copied to idata;
in this case the parameters bscale and bZero can be used to convert back to
nearly the original floating point values:  fdata ~= idata * bscale + bZero.
If the function value is zero, the data were not copied to idata.
*/

	float *diff;		/* difference array */
	int ndiff;		/* size of diff array */
	int intflag;		/* true if data are really integer */
	int i, j, iter;		/* loop indices */
        int anynulls = 0;       /* set if fdata contains any null values */
        int nshift;
        int first_nonnull = 0;
	double mean, stdev;	/* mean and RMS of differences */
	double minval = 0., maxval = 0.;  /* min & max of fdata */
	double delta;		/* bscale, 1 in idata = delta in fdata */
	double zeropt;	        /* bZero */
	double median;		/* median of diff array */
	double temp;

	if (nx <= 1) {
	    *bscale = 1.;
	    *bZero  = 0.;
	    return (0);
	}

        *iminval = INT32_MAX;
        *imaxval = INT32_MIN;

	/* Check to see if data are "floating point integer." */
        /* This also catches the case where all the pixels are null */
	intflag = 1;		/* initial value */
	for (i = 0;  i < nx;  i++) {
            if (fdata[i] == in_null_value) {
                idata[i] = NULL_VALUE;
                anynulls = 1;
            }
	    else if (fdata[i] > INT32_MAX || 
                     fdata[i] < NULL_VALUE + N_RESERVED_VALUES) {
		intflag = 0;	/* not integer */
		break;
	    }
            else {
  	        idata[i] = (int)(fdata[i] + 0.5);
                *iminval = minvalue(idata[i], *iminval);
                *imaxval = maxvalue(idata[i], *imaxval);

	        if (idata[i] != fdata[i]) {
		    intflag = 0;	/* not integer */
		    break;
                }
	    }
	}
	if (intflag) {  /* data are "floating point integer" */
            if (anynulls) {
                /* Shift the range of values so they lie close to NULL_VALUE. */
                /* This will make the compression more efficient.             */
                nshift = *iminval - NULL_VALUE - N_RESERVED_VALUES;
                for (i = 0;  i < nx;  i++) {
                    if (idata[i] != NULL_VALUE) {
                        idata[i] -= nshift;
                    }
                }
                *iminval = *iminval - nshift;
                *imaxval = *imaxval - nshift;
  	        *bscale = 1.;
	        *bZero = (double) nshift;
            }
            else {
                /* there were no null values, so no need to shift the range */
  	        *bscale = 1.;
	        *bZero = 0.;
            }
	    return (1);
	}

        /* data are not "floating point integer"; need to quantize them */

        /* find first non-null pixel, and initialize min and max values */
	for (i = 0;  i < nx;  i++) {
	    if (fdata[i] != in_null_value) {
               minval = fdata[i];
               maxval = fdata[i];
               first_nonnull = i;
               break;
            }
        }

        /* allocate temporary buffer for differences */
	ndiff = nx - first_nonnull - 1;
	if ((diff = malloc (ndiff * sizeof (float))) == NULL) {
            ffpmsg("Out of memory in 'fits_quantize_float'.");  
	    return (0);
	}

        /* calc ABS difference between successive non-null pixels */
        j = first_nonnull;
        ndiff = 0;
	for (i = j + 1 ;  i < nx;  i++) {
            if (fdata[i] != in_null_value) {
 	        diff[ndiff] = fabs (fdata[i] - fdata[j]);
                j = i;
                ndiff++;
                minval = minvalue(minval, fdata[i]);
                maxval = maxvalue(maxval, fdata[i]);
            }
        }

        /* check if there were any null values */
        if (ndiff + 1 == nx)
            anynulls = 0;
        else
            anynulls = 1;

	/* use median of absolute deviations */

	median = xMedian (diff, ndiff);
	stdev = median * MEDIAN_TO_RMS;
	/* substitute sigma-clipping if median is zero */
	if (stdev == 0.0) {

            /* calculate differences between non-null pixels */
            j = first_nonnull;
            ndiff = 0;
	    for (i = j + 1 ;  i < nx;  i++) {
                if (fdata[i] != in_null_value) {
 	            diff[ndiff] = fdata[i] - fdata[j];
                    j = i;
                    ndiff++;
                }
            }

	    FqMean (diff, ndiff, &mean, &stdev);

	    for (iter = 0;  iter < NITER;  iter++) {
		j = 0;
		for (i = 0;  i < ndiff;  i++) {
		    if (fabs (diff[i] - mean) < SIGMA_CLIP * stdev) {
			if (j < i)
			    diff[j] = diff[i];
			j++;
		    }
		}
		if (j == ndiff)
		    break;
		ndiff = j;
		FqMean (diff, ndiff, &mean, &stdev);
	    }
	}
	free (diff);

	delta = stdev / pow (2., (double)noise_bits);
	if (delta == 0. && ndiff > 0)
	    return (0);	/* Zero variance in differences!  Don't quantize. */

        /* check that the range of quantized levels is not > range of int */
	if ((maxval - minval) / delta > 2. * 2147483647. - N_RESERVED_VALUES )
	    return (0);			/* don't quantize */

        if (!anynulls) {   /* don't have to check for nulls */
            /* return all positive values, if possible since some */
            /* compression algorithms either only work for positive integers, */
            /* or are more efficient.  */
            if ((maxval - minval) / delta < 2147483647. - N_RESERVED_VALUES )
            {
                zeropt = minval;
            }
            else
            {
                /* center the quantized levels around zero */
                zeropt = (minval + maxval) / 2.;
            }

       	    for (i = 0;  i < nx;  i++) {
	        temp = (fdata[i] - zeropt) / delta;
	        idata[i] = NINT (temp);
            }
        }
        else {
            /* data contains null values; shift the range to be */
            /* close to the value used to represent null values */
            zeropt = minval - delta * (NULL_VALUE + N_RESERVED_VALUES);
	    for (i = 0;  i < nx;  i++) {
                if (fdata[i] != in_null_value) {
	            temp = (fdata[i] - zeropt) / delta;
	            idata[i] = NINT (temp);
                }
                else
                    idata[i] = NULL_VALUE;
            }
	}

        /* calc min and max values */
        temp = (minval - zeropt) / delta;
        *iminval =  NINT (temp);
        temp = (maxval - zeropt) / delta;
        *imaxval =  NINT (temp);

	*bscale = delta;
	*bZero = zeropt;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

      buffer = (char *) cbuff;

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

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

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

         next++;
      }

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

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

         if (blanks)
           free(blanks);

         return(*status);
      }

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

    if (blanks)
      free(blanks);

    return(*status);
}
/*--------------------------------------------------------------------------*/
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);
}
Beispiel #16
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);
}