
/*
 *  photom: a package to perform photometric calibration
 *  Copyright (C) 2001  Michael William Richmond
 *
 *  Contact: Michael William Richmond
 *           Physics Department
 *           Rochester Institute of Technology
 *           85 Lomb Memorial Drive
 *           Rochester, NY  14623-5603
 *           E-mail: mwrsps@rit.edu
 *
 *  
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */




   /*
    * functions which read data from ASCII multi-column files
    *   for the "merge" program.  Similar to, but not identical,
    *   with the functions in the "readlist.c" file -- those are
    *   for the "photom" program.
    */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include "misc.h"
#include "collate.h"
#include "mergelist.h"


static int is_blank(char *line);
#if 0
static int get_value(char *str, double *val);
#endif



/*********************************************************************
 * ROUTINE: read_coo_file
 *
 * Given the name of a ".coo" file, 
 * go through the file, creating an "S_PRE" structure for each line.
 * Place all "S_PRE" structures in a big array, and return a pointer
 * to the head of the array, and the number of stars in the array
 *
 * usage: read_coo_file          filename filter num_stars star_array
 *
 * where
 *            filename        is name of .coo file
 *            filter          is the filter in which measurements made
 *            num_stars       will hold number of stars read from file
 *            star_array      will hold an array of all the stars
 *
 * Ignore any line which starts with a COMMENT_CHAR, and any
 * completely empty line (one with whitespace only).
 *
 * The columns in which each bit of information appears is hard-coded
 * into this routine.  We assume each line looks like this:
 *
 *        1    2.30    585.68    1171    2.549     0.007    0.540 
 *
 * where
 *       first col        is ID of star within file
 *       second           is row position
 *       third            is col position
 *       fourth           is peak pixel val (with sky subtracted)
 *       fifth            is FWHM
 *       sixth            is roundness parameter
 *       seventh          is sharpness parameter
 *
 *
 * RETURNS:
 *      SH_SUCCESS         if all goes well
 *      SH_GENERIC_ERROR   if not
 */

int
read_coo_file
   (
   char *filename,           /* I: name of file */
   char *filter,             /* I: filter through which image taken */
   int *num_stars,           /* O: number of stars in array goes here */
   S_PRE **pre_array         /* O: head of array will be placed here */
   )
{
   FILE *fp;
   char line[LINELEN];
   int num, nlines, ncol;
   int id;
   double rowpos, colpos, peak, fwhm, round, sharp;
   S_PRE *star;

   /* sanity checks */
   shAssert(filter != NULL);
   shAssert(num_stars != NULL);
   shAssert(pre_array != NULL);

   if ((fp = fopen(filename, "r")) == NULL) {
      shError("read_coo_file: can't open file %s\n", filename);
      return(SH_GENERIC_ERROR);
   }

   /* count the number of lines in the file */
   if ((nlines = lines_in_file(fp)) < 0) {
      shError("read_coo_file: no lines in file %s\n", filename);
      return(SH_GENERIC_ERROR);
   }

   /* 
    * allocate space for the array 
    *   we allocate 'nlines' structures, even though we probably need
    *   fewer (since some lines in file may be comments)
    */
   *pre_array = (S_PRE *) shMalloc(nlines*sizeof(S_PRE));
   
   num = 0;
   while (fgets(line, LINELEN, fp) != NULL) {
      if (line[0] == COMMENT_CHAR) {
         continue;
      }
      if (is_blank(line)) {
         continue;
      }
      ncol = sscanf(line, "%d %lf %lf %lf %lf %lf %lf", 
              &id, &rowpos, &colpos, &peak, &fwhm, &round, &sharp);
      if (ncol != 7) {
         shError("read_coo_file: not enough entries in following line; skipping");
         shError("  %s", line);
         continue;
      }
        
      /* okay, it's safe to fill in an S_PRE struct with info from this line */
      star = &((*pre_array)[num]);
      spreFill(star, id, filter, fwhm, round, sharp);
      num++;
   }

   *num_stars = num;

   return(SH_SUCCESS);
}



/*********************************************************************
 * ROUTINE: read_ast_file
 *
 * Given the name of a file, and integers which specify the
 * columns in which data of interest appear, go through
 * the file, creating an "s_cat" structure for each line.
 * Place all the stars in an array, and return a pointer
 * to the head of the array, and the number of stars in the array.
 *
 * usage: read_catalog_file   filename num_stars star_array
 *
 * where
 *            filename        is name of the .ast file
 *            num_stars       is the number of stars in the array
 *                                (which ought to match the number of 
 *                                 stars in the file)
 *            star_array      is the array of stars, already created
 *                                 but not yet filled with all data
 *
 * Ignore any line which starts with a COMMENT_CHAR, and any
 * completely empty line (one with whitespace only).
 *
 * The columns in which each bit of information appears is hard-coded
 * into this routine.  We assume each line looks like this:
 *
 *        478  229.59422    0.93971 2465 10.16 10.510 0.002  2
 *
 * where
 *       first col        is ID of star within file
 *                              (the same as ID of the corresponding star
 *                              in the array)
 *       second           is RA  (decimal degrees)
 *       third            is Dec (decimal degrees)
 *       fourth           is local sky value (DN)
 *       fifth            is local sky uncertainty (DN)
 *       sixth            is instrumental mag
 *       seventh          is uncertainty in instrumental mag
 *       eighth           is quality flag
 *
 *
 * RETURNS:
 *      SH_SUCCESS         if all goes well
 *      SH_GENERIC_ERROR   if not
 */

int
read_ast_file
   (
   char *filename,           /* I: name of file */
   int num_stars,            /* I: number of stars in array, as read from */
                             /*        the .coo file for this field */
   S_PRE *pre_array          /* I/O: array of stars, into which we'll put */
                             /*        some additional information */
   )
{
   FILE *fp;
   char line[LINELEN];
   int nlines, num, ncol;
   int id;
   int quality_flag;
   S_PRE *star;
   double ra, dec, sky, skysig, mag, magerr;

   /* sanity checks */
   shAssert(filename != NULL);
   shAssert(num_stars >= 0);
   shAssert(pre_array != NULL);


   if ((fp = fopen(filename, "r")) == NULL) {
      shError("read_ast_file: can't open file %s\n", filename);
      return(SH_GENERIC_ERROR);
   }

   /* count the number of lines in the file */
   if ((nlines = lines_in_file(fp)) < 0) {
      shError("read_ast_file: no lines in file %s\n", filename);
      return(SH_GENERIC_ERROR);
   }

   num = 0;
   while (fgets(line, LINELEN, fp) != NULL) {
      if (line[0] == COMMENT_CHAR) {
         continue;
      }
      if (is_blank(line)) {
         continue;
      }
      ncol = sscanf(line, "%d %lf %lf %lf %lf %lf %lf %d", 
              &id, &ra, &dec, &sky, &skysig, &mag, &magerr, &quality_flag);
      if (ncol != 8) {
         shError("read_ast_file: bad format for line; skipping");
         shError("  %s", line);
         continue;
      }

      /* find the element of pre_array which corresponds to this star */
      if (id < 0) {
         shError("read_ast_file: ast file ID %d negative?  Skipping", id);
         continue;
      }
      if (id > num_stars) {
         shError("read_ast_file: ast file ID %d > num_stars %d?  Skipping", 
                             id, num_stars);
         continue;
      }
      if (pre_array[id-1].id != id) {
         shError("read_ast_file: ast file ID %d, array id %d?  Skipping", 
                             id, pre_array[id-1].id);
         continue;
      }
        
      /* okay, it's safe to fill information for this star */
      star = &(pre_array[num]);
      star->ra = ra;
      star->dec = dec;
      star->mag = mag;
      star->magerr = magerr;
      star->quality_flag = quality_flag;

      num++;
      if (num > num_stars) {
        shError("read_ast_file: num %d > num_stars %d?", num, num_stars);
      }
   }

   return(SH_SUCCESS);
}





/**********************************************************************
 * ROUTINE: is_blank
 *
 * If the given string consists only of whitespace, return 1.
 * Otherwise, return 0.
 */

static int 
is_blank
   (
   char *line                /* I: string to be checked */
   )
{
   char *p;

   for (p = line; (*p != '\0') && (isspace(*p)); p++) {
      ;
   }
   if (p == '\0') {
      return(1);
   }
   else {
      return(0);
   }
}


#if 0

/**********************************************************************
 * ROUTINE: get_value
 *
 * Given a string containing a numerical value, read the numerical
 * value and place it into the given double argument.  
 *
 * Return 0 if all goes well.
 * Return 1 if there is an error.
 */

static int 
get_value
   (
   char *str,                /* I: string to be converted to double */
   double *val               /* O: place value here */
   )
{
   if (sscanf(str, "%lf", val) != 1) {
      return(1);
   } 
   else {
      return(0);
   }
}
 
#endif
