/***************************************************************************** *File: fits_hdr.c *Programmers: Anne Raugh * Dorian Winterfeld *Institution: PDS/Small Bodies Node * University of Maryland *Date: March 28, 1995 *Last revision: *Abstract: Routines to OUTPUT the FITS data structure to the * FITS HEADER FILE *****************************************************************************/ #include #include #include #include #include "fits_obj.h" #include "fits_hdr.h" #include "pdserror.h" #include "pds_util.h" #include "pds.h" extern FILE *FITS_file; extern FILE *log_file; /************************************************************************** * Function: write_FITS_header * Abstract: Routine to translate and output the object definitions and * keyword values. * Description: * Input * main_object: pointer to FITS object. * Return * TRUE on success, FALSE on failure. ***************************************************************************/ int write_FITS_header(FITS_object *main_object) { FITS_object *object; /* pointer to FITS object */ FITS_keyword *key; /* pointer to FITS keyword object */ int status = OK; /* return value */ int key_status = OK; /* for error messages */ object = main_object; /* set object pointer */ while (object != NULL) { /* traverse FITS object list */ key = object->keyword_list; /* set key pointer */ while (key != NULL) { /* traverse keyword list */ key_status = write_keyword(key,object); if (key_status == -1) fprintf(log_file,"WARNING: Required keyword %s has no value!\n", key->name); if (key_status == -2){ fprintf(log_file,"WARNING: keyword %s has more than eight", key->name); fprintf(log_file," characters in it's name!\n"); } key = key->next; } fprintf(FITS_file,"END"); append_blanks(); object = object->next; } return status; } /* end write_FITS_header */ /************************************************************************** * Function: append_blanks * Abstract: pads the end of a FITS file to the nearest 2880 bytes ***************************************************************************/ void append_blanks() { long curr; /* current position in file */ long bytes; /* offset to nearest multiple of 2880 */ long i; /* index */ curr = ftell(FITS_file); if (curr < 2880l) bytes = 2880l - curr; else { bytes = 2880l - (curr % 2880l); } if (bytes != 2880l) { for (i = 0l; i < bytes; i++) fprintf(FITS_file," "); } } /* end append_blanks */ /************************************************************************** * Function: write_keyword * Abstract: Routine to write one keyword and its value to the output file. * The value of the keyword is first converted from the string to * the output type, then verified. * Description: * Input * main_object: pointer to FITS object. * * Return * 1 on success, 0 on failure. ***************************************************************************/ int write_keyword(FITS_keyword *key, FITS_object *object) { int status = OK; /* return status */ char blank = ' '; /* blank character */ /* check for required keywords with no value string */ if ((key->required) && (key->value == NULL)) return -1; /* write keyword unless it has type DUMMY or has NULL value */ if ((key->value != NULL) && (strcmp(key->type,"DUMMY"))){ if (!strcmp(key->name,"HISTORY")|| !strcmp(key->name,"COMMENT")) status = write_comment(key); else { format_value(key,object); if (!strcmp(key->value,"T")||!strcmp(key->value,"F")) fprintf(FITS_file,"%-8s=%20c%-51s",key->name,blank,key->value); else if (!strcmp(key->type,"ALPHABET") || !strcmp(key->type,"ALPHANUMERIC") || !strcmp(key->type,"CHARACTER")) fprintf(FITS_file,"%-8s= %-70s",key->name,key->value); else if (!strcmp(key->type,"REAL") || !strcmp(key->type,"EXPONENTIAL") || !strcmp(key->type,"INTEGER")) fprintf(FITS_file,"%-8s=%21s%-50c",key->name,key->value,blank); else fprintf(FITS_file,"%-8s= %-70s",key->name,key->value); } } return status; } /* end write_keyword */ /************************************************************************** * Function: format_value * Abstract: formats the output value string * Description: * Input * key: pointer to FITS keyword object * object: pointer to FITS object * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_value(FITS_keyword *key, FITS_object *object) { int status = OK; /* return status */ int len; char fits_date[10]; /* used for date string */ char fits_time[10]; /* used for time string */ char *time_ptr; /* TIME keyword */ FITS_keyword *time_key; /* date keyword object */ /* format characer string */ if (!strcmp(key->type,"ALPHABET") || !strcmp(key->type,"ALPHANUMERIC") || !strcmp(key->type,"CHARACTER")) status = format_string(key); else /* format date */ if (!strcmp(key->type,"DATE")){ status = format_date(key); strcpy(key->type,"CHARACTER"); } else /* format time; name must be DATE:TIME */ if (!strcmp(key->type,"TIME")) { if (isdigit(key->value[1])){ status = format_time(key, fits_date, fits_time); time_ptr = strtok(key->name,":"); time_ptr = strtok(NULL,":"); strcpy(key->value,fits_date); strcpy(key->type,"DATE"); time_key = find_FITS_keyword(time_ptr,object); len = strlen(fits_time); time_key->value = (char *)malloc(len + 1); strcpy(time_key->value,fits_time); strcpy(time_key->type,"REAL"); } else { strtok(key->name,":"); strcpy(key->type,"CHARACTER"); } } else /* format real */ if (!strcmp(key->type,"REAL") || !strcmp(key->type,"EXPONENTIAL")) status = format_real(key); else /* format integer */ if (!strcmp(key->type,"INTEGER")) status = format_integer(key); else status = TYPE_WARNING; return status; } /* end format_value */ /************************************************************************** * Function: format_string * Abstract: format character string * Description: * Input * pointer to FITS keyword object * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_string(FITS_keyword *key) { int len; /* string length */ int diff; /* difference less than eight characters */ int i; /* index */ int index = 0; char *temp; /* temporary string */ /* get string length */ len = strlen(key->value); /* strip quotes */ if ((key->value[0] == '\"') || (key->value[0] == '\'')) { key->value[0] = ' '; key->value[len-1] = ' '; eat_white(key->value); len = strlen(key->value); } /* check for single quote in string as in A'Hearn */ for (i=0; ivalue[i] == '\'') index = i; if (index){ if ((temp = (char *)malloc(len + 2)) == NULL) return MALLOC_ERROR; strncpy(temp,key->value,index); temp[index+1] = '\''; for (i=index+1;ivalue[i]; temp[len+2] = '\0'; free(key->value); if ((key->value = (char *)malloc(len+2)) == NULL) return MALLOC_ERROR; strcpy(key->value,temp); len = strlen(key->value); } /* if less than 8 char pad to eight */ if (len < 8){ diff = 8 - len; if ((temp = (char *)malloc(11)) == NULL) return MALLOC_ERROR; strcpy(temp,"\'"); strcat(temp,key->value); for (i=0; ivalue); if ((key->value = (char *)malloc(11)) == NULL) return MALLOC_ERROR; strcpy(key->value,temp); } else { if ((temp = (char *)malloc(len+4)) == NULL) return MALLOC_ERROR; strcpy(temp,"\'"); strcat(temp,key->value); strcat(temp,"\'"); free(key->value); if ((key->value = (char *)malloc(len+4)) == NULL) return MALLOC_ERROR; strcpy(key->value,temp); } return OK; } /* end format_string */ /************************************************************************** * Function: format_date * Abstract: format keyword of type date * Input * key: pointer to FITS keyword * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_date(FITS_keyword *key) { int status = OK; /* return value */ char fits_date[30]; /* FITS date string */ status = p2f_date(key->value,fits_date); strcpy(key->value,fits_date); return status; } /* end format_date */ /************************************************************************** * Function: format_time * Abstract: format key of type time * Description: * Input * key: pointer to FITS keyword * Output * fits_date: holds FITS date string * fits_time: holds FITS time string * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_time(FITS_keyword *key, char *fits_date, char *fits_time) { int status = OK; /* return value */ char buffer[30]; /* holds PDS time string */ char *date_ptr; /* pointer to date portion of PDS time string */ char *time_ptr; /* pointer to time portion of PDS time string */ strcpy(buffer, key->value); date_ptr = strtok(buffer,"T"); time_ptr = strtok(NULL,"T"); status = p2f_date(date_ptr,fits_date); status = p2f_time(time_ptr,fits_time); return status;; } /* end format_time */ /************************************************************************** * Function: format_real * Abstract: format real value * Description: * Input * key: pointer to FITS keyword object * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_real(FITS_keyword *key) { int status = OK; /* return value */ if (key->value[0] == '\"') { key->value[0] = ' '; strtok(key->value,"\""); } return status; } /* end format_real */ /************************************************************************** * Function: format_integer * Abstract: format integer value * Description: * Input * key: pointer to FITS keyword object * Return * 1 on success, 0 on failure. ***************************************************************************/ int format_integer(FITS_keyword *key) { int status = OK; /* return value */ if (key->value[0] == '\"') { key->value[0] = ' '; strtok(key->value,"\""); } return status; } /* end format_integer */ /************************************************************************** * Function: write_comment * Abstract: format a comment or * Description: * Input * Return * 1 on success, 0 on failure. ***************************************************************************/ int write_comment(FITS_keyword *key) { char *line_ptr; char line[73]; char line2[73]; int status = OK; int len; int index; eat_white(key->value); len = strlen(key->value); if (key->value[0] == '\"') { key->value[0] = ' '; eat_white(key->value); len = strlen(key->value); } if (key->value[len-1] == '\"') { key->value[len-1] = ' '; eat_white(key->value); } line_ptr = strtok(key->value,"\n"); while (line_ptr) { len = strlen(line_ptr); if (len < 73){ strncpy(line,line_ptr,72); fprintf(FITS_file,"%-8s%-72s",key->name,line); } else{ index = 72; while (!isspace(line_ptr[index])) index--; strncpy(line,line_ptr,index); line[index] = '\0'; sub_strcpy(line2,line_ptr,index,len-index); eat_white(line2); len = strlen(line2); fprintf(FITS_file,"%-8s%-72s",key->name,line); if (len) fprintf(FITS_file,"%-8s%-72s",key->name,line2); } line_ptr = strtok(NULL,"\n"); } return status; } /* write_comment */