diff options
Diffstat (limited to 'wcs/hput.c')
-rw-r--r-- | wcs/hput.c | 1316 |
1 files changed, 1316 insertions, 0 deletions
diff --git a/wcs/hput.c b/wcs/hput.c new file mode 100644 index 0000000..7ec81ab --- /dev/null +++ b/wcs/hput.c @@ -0,0 +1,1316 @@ +/*** File libwcs/hput.c + *** September 9, 2011 + *** By Jessica Mink, jmink@cfa.harvard.edu + *** Harvard-Smithsonian Center for Astrophysics + *** Copyright (C) 1995-2011 + *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Correspondence concerning WCSTools should be addressed as follows: + Internet email: jmink@cfa.harvard.edu + Postal address: Jessica Mink + Smithsonian Astrophysical Observatory + 60 Garden St. + Cambridge, MA 02138 USA + + * Module: hput.c (Put FITS Header parameter values) + * Purpose: Implant values for parameters into FITS header string + * Subroutine: hputi4 (hstring,keyword,ival) sets int ival + * Subroutine: hputr4 (hstring,keyword,rval) sets real*4 rval + * Subroutine: hputr8 (hstring,keyword,dval) sets real*8 dval + * Subroutine: hputnr8 (hstring,keyword,ndec,dval) sets real*8 dval + * Subroutine: hputra (hstring,keyword,lval) sets right ascension as string + * Subroutine: hputdec (hstring,keyword,lval) sets declination as string + * Subroutine: hputl (hstring,keyword,lval) sets logical lval + * Subroutine: hputs (hstring,keyword,cval) sets character string adding '' + * Subroutine: hputm (hstring,keyword,cval) sets multi-line character string + * Subroutine: hputc (hstring,keyword,cval) sets character string cval + * Subroutine: hdel (hstring,keyword) deletes entry for keyword keyword + * Subroutine: hadd (hplace,keyword) adds entry for keyword at hplace + * Subroutine: hchange (hstring,keyword1,keyword2) changes keyword for entry + * Subroutine: hputcom (hstring,keyword,comment) sets comment for parameter keyword + * Subroutine: ra2str (out, lstr, ra, ndec) converts RA from degrees to string + * Subroutine: dec2str (out, lstr, dec, ndec) converts Dec from degrees to string + * Subroutine: deg2str (out, lstr, deg, ndec) converts degrees to string + * Subroutine: num2str (out, num, field, ndec) converts number to string + * Subroutine: getltime () returns current local time as ISO-style string + * Subroutine: getutime () returns current UT as ISO-style string + */ +#include <sys/time.h> +#include <string.h> /* NULL, strlen, strstr, strcpy */ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "fitshead.h" + +static int verbose=0; /* Set to 1 to print error messages and other info */ + +static void fixnegzero(); + + +/* HPUTI4 - Set int keyword = ival in FITS header string */ + +int +hputi4 (hstring,keyword,ival) + +char *hstring; /* FITS-style header information in the format + <keyword>= <value> {/ <comment>} + each entry is padded with spaces to 80 characters */ + +const char *keyword; /* Name of the variable in header to be returned. + If no line begins with this string, one is created. + The first 8 characters of keyword must be unique. */ +int ival; /* int number */ +{ + char value[30]; + + /* Translate value from binary to ASCII */ + sprintf (value,"%d",ival); + + /* Put value into header string */ + return (hputc (hstring,keyword,value)); +} + + +/* HPUTR4 - Set float keyword = rval in FITS header string */ + +int +hputr4 (hstring, keyword, rval) + +char *hstring; /* FITS header string */ +const char *keyword; /* Keyword name */ +const float *rval; /* float number */ + +{ + char value[30]; + + /* Translate value from binary to ASCII */ + sprintf (value, "%f", *rval); + + /* Remove sign if string is -0 or extension thereof */ + fixnegzero (value); + + /* Put value into header string */ + return (hputc (hstring, keyword, value)); +} + + +/* HPUTR8 - Set double keyword = dval in FITS header string */ + +int +hputr8 (hstring, keyword, dval) + +char *hstring; /* FITS header string */ +const char *keyword; /* Keyword name */ +const double dval; /* double number */ +{ + char value[30]; + + /* Translate value from binary to ASCII */ + sprintf (value, "%g", dval); + + /* Remove sign if string is -0 or extension thereof */ + fixnegzero (value); + + /* Put value into header string */ + return (hputc (hstring, keyword, value)); +} + + +/* HPUTNR8 - Set double keyword = dval in FITS header string */ + +int +hputnr8 (hstring, keyword, ndec, dval) + +char *hstring; /* FITS header string */ +const char *keyword; /* Keyword name */ +const int ndec; /* Number of decimal places to print */ +const double dval; /* double number */ +{ + char value[30]; + char format[8]; + int i, lval; + + /* Translate value from binary to ASCII */ + if (ndec < 0) { + sprintf (format, "%%.%dg", -ndec); + sprintf (value, format, dval); + lval = (int) strlen (value); + for (i = 0; i < lval; i++) + if (value[i] == 'e') value[i] = 'E'; + } + else { + sprintf (format, "%%.%df", ndec); + sprintf (value, format, dval); + } + + /* Remove sign if string is -0 or extension thereof */ + fixnegzero (value); + + /* Put value into header string */ + return (hputc (hstring, keyword, value)); +} + + +/* HPUTRA - Set double keyword = hh:mm:ss.sss in FITS header string */ + +int +hputra (hstring, keyword, ra) + +char *hstring; /* FITS header string */ +const char *keyword; /* Keyword name */ +const double ra; /* Right ascension in degrees */ +{ + char value[30]; + + /* Translate value from binary to ASCII */ + ra2str (value, 30, ra, 3); + + /* Remove sign if string is -0 or extension thereof */ + fixnegzero (value); + + /* Put value into header string */ + return (hputs (hstring, keyword, value)); +} + + +/* HPUTDEC - Set double keyword = dd:mm:ss.sss in FITS header string */ + +int +hputdec (hstring, keyword, dec) + +char *hstring; /* FITS header string */ +const char *keyword; /* Keyword name */ +const double dec; /* Declination in degrees */ +{ + char value[30]; + + /* Translate value from binary to ASCII */ + dec2str (value, 30, dec, 2); + + /* Remove sign if string is -0 or extension thereof */ + fixnegzero (value); + + /* Put value into header string */ + return (hputs (hstring, keyword, value)); +} + + +/* FIXNEGZERO -- Drop - sign from beginning of any string which is all zeros */ + +static void +fixnegzero (string) + +char *string; +{ + int i, lstr; + + if (string[0] != '-') + return; + + /* Drop out if any non-zero digits in this string */ + lstr = (int) strlen (string); + for (i = 1; i < lstr; i++) { + if (string[i] > '0' && string[i] <= '9') + return; + if (string[i] == 'd' || string[i] == 'e' || string[i] == ' ') + break; + } + + /* Drop - from start of string; overwrite string in place */ + for (i = 1; i < lstr; i++) + string[i-1] = string[i]; + string[lstr-1] = (char) 0; + + return; +} + + + +/* HPUTL - Set keyword = F if lval=0, else T, in FITS header string */ + +int +hputl (hstring, keyword,lval) + +char *hstring; /* FITS header */ +const char *keyword; /* Keyword name */ +const int lval; /* logical variable (0=false, else true) */ +{ + char value[8]; + + /* Translate value from binary to ASCII */ + if (lval) + strcpy (value, "T"); + else + strcpy (value, "F"); + + /* Put value into header string */ + return (hputc (hstring,keyword,value)); +} + + +/* HPUTM - Set multi-line character string in FITS header string */ +/* return number of keywords written */ + +int +hputm (hstring,keyword,cval) + +char *hstring; /* FITS header */ +const char *keyword; /* Keyword name root (6 characters or less) */ +const char *cval; /* character string containing the value for variable + keyword. trailing and leading blanks are removed. */ +{ + int lroot, lcv, i, ii, nkw, lkw, lval; + int comment = 0; + const char *v; + char keyroot[8], newkey[12], value[80]; + char squot = 39; + + /* If COMMENT or HISTORY, use the same keyword on every line */ + lkw = (int) strlen (keyword); + if (lkw == 7 && (strncmp (keyword,"COMMENT",7) == 0 || + strncmp (keyword,"HISTORY",7) == 0)) { + comment = 1; + lroot = 0; + } + + /* Set up keyword root, shortening it to 6 characters, if necessary */ + else { + comment = 0; + strcpy (keyroot, keyword); + lroot = (int) strlen (keyroot); + if (lroot > 6) { + keyroot[6] = (char) 0; + lroot = 6; + } + } + + /* Write keyword value one line of up to 67 characters at a time */ + ii = '1'; + nkw = 0; + lcv = (int) strlen (cval); + if (!comment) { + strcpy (newkey, keyroot); + strcat (newkey, "_"); + newkey[lroot+2] = (char) 0; + } + v = cval; + while (lcv > 0) { + if (lcv > 67) + lval = 67; + else + lval = lcv; + value[0] = squot; + for (i = 1; i <= lval; i++) + value[i] = *v++; + + /* Pad short strings to 8 characters */ + if (lval < 8) { + for (i = lval+1; i < 9; i++) + value[i] = ' '; + lval = 8; + } + value[lval+1] = squot; + value[lval+2] = (char) 0; + + /* Add this line to the header */ + if (comment) + i = hputc (hstring, keyroot, value); + else { + newkey[lroot+1] = ii; + ii++; + i = hputc (hstring, newkey, value); + } + if (i != 0) return (i); + nkw++; + if (lcv > 67) + lcv = lcv - 67; + else + break; + } + return (nkw); +} + + +/* HPUTS - Set character string keyword = 'cval' in FITS header string */ + +int +hputs (hstring,keyword,cval) + +char *hstring; /* FITS header */ +const char *keyword; /* Keyword name */ +const char *cval; /* character string containing the value for variable + keyword. trailing and leading blanks are removed. */ +{ + char squot = 39; + char value[80]; + int lcval, i, lkeyword; + + /* If COMMENT or HISTORY, just add it as is */ + lkeyword = (int) strlen (keyword); + if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || + strncmp (keyword,"HISTORY",7) == 0)) + return (hputc (hstring,keyword,cval)); + + /* find length of variable string */ + lcval = (int) strlen (cval); + if (lcval > 67) + lcval = 67; + + /* Put single quote at start of string */ + value[0] = squot; + strncpy (&value[1],cval,lcval); + + /* If string is less than eight characters, pad it with spaces */ + if (lcval < 8) { + for (i = lcval; i < 8; i++) { + value[i+1] = ' '; + } + lcval = 8; + } + + /* Add single quote and null to end of string */ + value[lcval+1] = squot; + value[lcval+2] = (char) 0; + + /* Put value into header string */ + return (hputc (hstring,keyword,value)); +} + + +/* HPUTC - Set character string keyword = value in FITS header string */ +/* Return -1 if error, 0 if OK */ + +int +hputc (hstring,keyword,value) + +char *hstring; +const char *keyword; +const char *value; /* character string containing the value for variable + keyword. trailing and leading blanks are removed. */ +{ + char squot = 39; + char line[100]; + char newcom[50]; + char *vp, *v1, *v2, *q1, *q2, *c1, *ve; + int lkeyword, lcom, lval, lc, lv1, lhead, lblank, ln, nc, i; + + /* Find length of keyword, value, and header */ + lkeyword = (int) strlen (keyword); + lval = (int) strlen (value); + lhead = gethlength (hstring); + + /* If COMMENT or HISTORY, always add it just before the END */ + if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || + strncmp (keyword,"HISTORY",7) == 0)) { + + /* First look for blank lines before END */ + v1 = blsearch (hstring, "END"); + + /* Otherwise, create a space for it at the end of the header */ + if (v1 == NULL) { + + /* Find end of header */ + v1 = ksearch (hstring,"END"); + + /* Align pointer at start of 80-character line */ + lc = v1 - hstring; + ln = lc / 80; + nc = ln * 80; + v1 = hstring + nc; + v2 = v1 + 80; + + /* If header length is exceeded, return error code */ + if (v2 - hstring > lhead) { + return (-1); + } + + /* Move END down 80 characters */ + strncpy (v2, v1, 80); + } + else + v2 = v1 + 80; + + /* Insert keyword */ + strncpy (v1,keyword,7); + + /* Pad with spaces */ + for (vp = v1+lkeyword; vp < v2; vp++) + *vp = ' '; + + if (lval > 71) + lv1 = 71; + else + lv1 = lval; + + /* Insert comment */ + strncpy (v1+9,value,lv1); + return (0); + } + + /* Otherwise search for keyword */ + else + v1 = ksearch (hstring,keyword); + + /* If parameter is not found, find a place to put it */ + if (v1 == NULL) { + + /* First look for blank lines before END */ + v1 = blsearch (hstring, "END"); + + /* Otherwise, create a space for it at the end of the header */ + if (v1 == NULL) { + ve = ksearch (hstring,"END"); + v1 = ve; + + /* Align pointer at start of 80-character line */ + lc = v1 - hstring; + ln = lc / 80; + nc = ln * 80; + v1 = hstring + nc; + v2 = v1 + 80; + + /* If header length is exceeded, return error code */ + if (v2 - hstring > lhead) { + return (-1); + } + + strncpy (v2, ve, 80); + } + else + v2 = v1 + 80; + lcom = 0; + newcom[0] = 0; + } + + /* Otherwise, extract the entry for this keyword from the header */ + else { + + /* Align pointer at start of 80-character line */ + lc = v1 - hstring; + ln = lc / 80; + nc = ln * 80; + v1 = hstring + nc; + v2 = v1 + 80; + + strncpy (line, v1, 80); + line[80] = 0; + v2 = v1 + 80; + + /* check for quoted value */ + q1 = strchr (line, squot); + if (q1 != NULL) { + q2 = strchr (q1+1,squot); + if (q2 != NULL) + c1 = strchr (q2,'/'); + else + c1 = strrchr (line+79,'/'); + } + else + c1 = strchr (line,'/'); + + /* extract comment and discount trailing spaces */ + if (c1 != NULL) { + lcom = 80 - (c1 + 2 - line); + strncpy (newcom, c1+2, lcom); + vp = newcom + lcom - 1; + while (vp-- > newcom && *vp == ' ') + lcom--; + } + else { + newcom[0] = 0; + lcom = 0; + } + } + + /* Fill new entry with spaces */ + for (vp = v1; vp < v2; vp++) + *vp = ' '; + + /* Copy keyword to new entry */ + strncpy (v1, keyword, lkeyword); + + /* Add parameter value in the appropriate place */ + vp = v1 + 8; + *vp = '='; + vp = v1 + 9; + *vp = ' '; + vp = vp + 1; + if (*value == squot) { + strncpy (vp, value, lval); + if (lval+12 > 31) + lc = lval + 12; + else + lc = 30; + } + else { + vp = v1 + 30 - lval; + strncpy (vp, value, lval); + lc = 30; + } + + /* Add comment in the appropriate place */ + if (lcom > 0) { + if (lc+2+lcom > 80) + lcom = 77 - lc; + vp = v1 + lc; /* Jul 16 1997: was vp = v1 + lc * 2 */ + *vp++ = ' '; + *vp++ = '/'; + *vp++ = ' '; + lblank = v2 - vp; + for (i = 0; i < lblank; i++) + vp[i] = ' '; + if (lcom > lblank) + lcom = lblank; + strncpy (vp, newcom, lcom); + } + + if (verbose) { + if (lcom > 0) + fprintf (stderr,"HPUT: %s = %s / %s\n",keyword, value, newcom); + else + fprintf (stderr,"HPUT: %s = %s\n",keyword, value); + } + + return (0); +} + + +/* HPUTCOM - Set comment for keyword or on line in FITS header string */ + +int +hputcom (hstring,keyword,comment) + + char *hstring; + const char *keyword; + const char *comment; +{ + char squot, slash, space; + char line[100]; + int lkeyword, lcom, lhead, i, lblank, ln, nc, lc; + char *vp, *v1, *v2, *c0, *c1, *q1, *q2; + + squot = (char) 39; + slash = (char) 47; + space = (char) 32; + + /* Find length of variable name */ + lkeyword = (int) strlen (keyword); + lhead = gethlength (hstring); + lcom = (int) strlen (comment); + + /* If COMMENT or HISTORY, always add it just before the END */ + if (lkeyword == 7 && (strncmp (keyword,"COMMENT",7) == 0 || + strncmp (keyword,"HISTORY",7) == 0)) { + + /* Find end of header */ + v1 = ksearch (hstring,"END"); + + /* Align pointer at start of 80-character line */ + lc = v1 - hstring; + ln = lc / 80; + nc = ln * 80; + v1 = hstring + nc; + v2 = v1 + 80; + + /* If header length is exceeded, return error code */ + if (v2 - hstring > lhead) { + return (-1); + } + + /* Move END down 80 characters */ + strncpy (v2, v1, 80); + + /* blank out new line and insert keyword */ + for (vp = v1; vp < v2; vp++) + *vp = ' '; + strncpy (v1, keyword, lkeyword); + c0 = v1 + lkeyword; + } + + /* Search header string for variable name */ + else { + v1 = ksearch (hstring,keyword); + + /* If parameter is not found, return without doing anything */ + if (v1 == NULL) { + if (verbose) + fprintf (stderr,"HPUTCOM: %s not found\n",keyword); + return (-1); + } + + /* Align pointer at start of 80-character line */ + lc = v1 - hstring; + ln = lc / 80; + nc = ln * 80; + v1 = hstring + nc; + v2 = v1 + 80; + + /* Extract entry for this variable from the header */ + strncpy (line, v1, 80); + line[80] = '\0'; /* Null-terminate line before strchr call */ + + /* check for quoted value */ + q1 = strchr (line,squot); + c1 = strchr (line,slash); + if (q1 != NULL) { + if (c1 != NULL && q1 < c1) { + q2 = strchr (q1+1, squot); + if (q2 == NULL) { + q2 = c1 - 1; + while (*q2 == space) + q2--; + q2++; + } + else if (c1 < q2) + c1 = strchr (q2, slash); + } + else if (c1 == NULL) { + q2 = strchr (q1+1, squot); + if (q2 == NULL) { + q2 = line + 79; + while (*q2 == space) + q2--; + q2++; + } + } + else + q1 = NULL; + q2 = NULL; + } + + else + q2 = NULL; + + if (c1 != NULL) + c0 = v1 + (c1 - line) - 1; + else if (q2 == NULL || q2-line < 30) + c0 = v1 + 30; + else + c0 = v1 + (q2 - line) + 1; /* allan: 1997-09-30, was c0=q2+2 */ + + /* If comment will not fit at all, return */ + if (c0 - v1 > 77) + return (-1); + strncpy (c0, " / ",3); + } + + /* Create new entry */ + if (lcom > 0) { + c1 = c0 + 3; + lblank = v1 + 79 - c1; + if (lcom > lblank) + lcom = lblank; + for (i = 0; i < lblank; i++) + c1[i] = ' '; + strncpy (c1, comment, lcom); + } + + if (verbose) { + fprintf (stderr,"HPUTCOM: %s / %s\n",keyword,comment); + } + return (0); +} + + +static int leaveblank = 0; /* If 1, leave blank line when deleting */ +void +setleaveblank (lb) +int lb; { leaveblank = lb; return; } + +static int headshrink=1; /* Set to 1 to drop line after deleting keyword */ +void +setheadshrink (hsh) +int hsh; +{headshrink = hsh; return;} + +/* HDEL - Set character string keyword = value in FITS header string + * returns 1 if entry deleted, else 0 + */ + +int +hdel (hstring,keyword) + +char *hstring; /* FITS header */ +const char *keyword; /* Keyword of entry to be deleted */ +{ + char *v, *v1, *v2, *ve; + + /* Search for keyword */ + v1 = ksearch (hstring,keyword); + + /* If keyword is not found, return header unchanged */ + if (v1 == NULL) { + return (0); + } + + /* Find end of header */ + ve = ksearch (hstring,"END"); + + /* If headshrink is 0, leave END where it is */ + if (!leaveblank && !headshrink) + ve = ve - 80; + + /* Cover deleted keyword line with spaces */ + if (leaveblank) { + v2 = v1 + 80; + for (v = ve; v < v2; v++) + *v = ' '; + } + + /* Shift rest of header up one line */ + else { + for (v = v1; v < ve; v = v + 80) { + v2 = v + 80; + strncpy (v, v2, 80); + } + + /* Cover former last line with spaces */ + v2 = ve + 80; + for (v = ve; v < v2; v++) + *v = ' '; + } + + return (1); +} + + +/* HADD - Add character string keyword = value to FITS header string + * returns 1 if entry added, else 0 + * Call hputx() to put value into entry + */ + +int +hadd (hplace, keyword) + +char *hplace; /* FITS header position for new keyword */ +const char *keyword; /* Keyword of entry to be deleted */ +{ + char *v, *v1, *v2, *ve; + int i, lkey; + + /* Find end of header */ + ve = ksearch (hplace,"END"); + + /* If END is not found, return header unchanged */ + if (ve == NULL) { + return (0); + } + + v1 = hplace; + + /* Shift rest of header down one line */ + /* limit bug found by Paolo Montegriffo fixed 2000-04-19 */ + for (v = ve; v >= v1; v = v - 80) { + v2 = v + 80; + strncpy (v2, v, 80); + } + + /* Cover former first line with new keyword */ + lkey = (int) strlen (keyword); + strncpy (hplace, keyword, lkey); + if (lkey < 8) { + for (i = lkey; i < 8; i++) + hplace[i] = ' '; + hplace[8] = '='; + } + for (i = 9; i < 80; i++) + hplace[i] = ' '; + + return (1); +} + + +/* HCHANGE - Changes keyword for entry from keyword1 to keyword2 in FITS + header string + * returns 1 if entry changed, else 0 + */ + +int +hchange (hstring, keyword1, keyword2) + +char *hstring; /* FITS header */ +const char *keyword1; /* Keyword to be changed */ +const char *keyword2; /* New keyword name */ +{ + char *v, *v1; + const char *v2; + int lv2, i; + + /* Search for keyword */ + v1 = ksearch (hstring,keyword1); + + /* If keyword is not found, return header unchanged */ + if (!v1) + return (0); + + else { + lv2 = (int) strlen (keyword2); + v = v1; + v2 = keyword2; + for (i = 0; i < 8; i++) { + if (i < lv2) + v[i] = v2[i]; + else + v[i] = ' '; + } + } + + return (1); +} + + +/* Write the right ascension ra in sexagesimal format into string*/ + +void +ra2str (string, lstr, ra, ndec) + +char *string; /* Character string (returned) */ +int lstr; /* Maximum number of characters in string */ +double ra; /* Right ascension in degrees */ +int ndec; /* Number of decimal places in seconds */ + +{ + double a,b; + double seconds; + char tstring[64]; + int hours; + int minutes; + int isec, ltstr; + double dsgn; + + /* Keep RA between 0 and 360 */ + if (ra < 0.0 ) { + ra = -ra; + dsgn = -1.0; + } + else + dsgn = 1.0; + ra = fmod(ra, 360.0); + ra *= dsgn; + if (ra < 0.0) + ra = ra + 360.0; + + a = ra / 15.0; + + /* Convert to hours */ + hours = (int) a; + + /* Compute minutes */ + b = (a - (double)hours) * 60.0; + minutes = (int) b; + + /* Compute seconds */ + seconds = (b - (double)minutes) * 60.0; + + if (ndec > 5) { + if (seconds > 59.999999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%09.6f",hours,minutes,seconds); + } + else if (ndec > 4) { + if (seconds > 59.99999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%08.5f",hours,minutes,seconds); + } + else if (ndec > 3) { + if (seconds > 59.9999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%07.4f",hours,minutes,seconds); + } + else if (ndec > 2) { + if (seconds > 59.999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%06.3f",hours,minutes,seconds); + } + else if (ndec > 1) { + if (seconds > 59.99) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%05.2f",hours,minutes,seconds); + } + else if (ndec > 0) { + if (seconds > 59.9) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%04.1f",hours,minutes,seconds); + } + else { + isec = (int)(seconds + 0.5); + if (isec > 59) { + isec = 0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + hours = hours + 1; + } + hours = hours % 24; + (void) sprintf (tstring,"%02d:%02d:%02d",hours,minutes,isec); + } + + /* Move formatted string to returned string */ + ltstr = (int) strlen (tstring); + if (ltstr < lstr-1) + strcpy (string, tstring); + else { + strncpy (string, tstring, lstr-1); + string[lstr-1] = 0; + } + return; +} + + +/* Write the variable a in sexagesimal format into string */ + +void +dec2str (string, lstr, dec, ndec) + +char *string; /* Character string (returned) */ +int lstr; /* Maximum number of characters in string */ +double dec; /* Declination in degrees */ +int ndec; /* Number of decimal places in arcseconds */ + +{ + double a, b, dsgn, deg1; + double seconds; + char sign; + int degrees; + int minutes; + int isec, ltstr; + char tstring[64]; + + /* Keep angle between -180 and 360 degrees */ + deg1 = dec; + if (deg1 < 0.0 ) { + deg1 = -deg1; + dsgn = -1.0; + } + else + dsgn = 1.0; + deg1 = fmod(deg1, 360.0); + deg1 *= dsgn; + if (deg1 <= -180.0) + deg1 = deg1 + 360.0; + + a = deg1; + + /* Set sign and do all the rest with a positive */ + if (a < 0) { + sign = '-'; + a = -a; + } + else + sign = '+'; + + /* Convert to degrees */ + degrees = (int) a; + + /* Compute minutes */ + b = (a - (double)degrees) * 60.0; + minutes = (int) b; + + /* Compute seconds */ + seconds = (b - (double)minutes) * 60.0; + + if (ndec > 5) { + if (seconds > 59.999999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%09.6f",sign,degrees,minutes,seconds); + } + else if (ndec > 4) { + if (seconds > 59.99999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%08.5f",sign,degrees,minutes,seconds); + } + else if (ndec > 3) { + if (seconds > 59.9999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%07.4f",sign,degrees,minutes,seconds); + } + else if (ndec > 2) { + if (seconds > 59.999) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%06.3f",sign,degrees,minutes,seconds); + } + else if (ndec > 1) { + if (seconds > 59.99) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%05.2f",sign,degrees,minutes,seconds); + } + else if (ndec > 0) { + if (seconds > 59.9) { + seconds = 0.0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%04.1f",sign,degrees,minutes,seconds); + } + else { + isec = (int)(seconds + 0.5); + if (isec > 59) { + isec = 0; + minutes = minutes + 1; + } + if (minutes > 59) { + minutes = 0; + degrees = degrees + 1; + } + (void) sprintf (tstring,"%c%02d:%02d:%02d",sign,degrees,minutes,isec); + } + + /* Move formatted string to returned string */ + ltstr = (int) strlen (tstring); + if (ltstr < lstr-1) + strcpy (string, tstring); + else { + strncpy (string, tstring, lstr-1); + string[lstr-1] = 0; + } + return; +} + + +/* Write the angle a in decimal format into string */ + +void +deg2str (string, lstr, deg, ndec) + +char *string; /* Character string (returned) */ +int lstr; /* Maximum number of characters in string */ +double deg; /* Angle in degrees */ +int ndec; /* Number of decimal places in degree string */ + +{ + char degform[8]; + int field, ltstr; + char tstring[64]; + double deg1; + double dsgn; + + /* Keep angle between -180 and 360 degrees */ + deg1 = deg; + if (deg1 < 0.0 ) { + deg1 = -deg1; + dsgn = -1.0; + } + else + dsgn = 1.0; + deg1 = fmod(deg1, 360.0); + deg1 *= dsgn; + if (deg1 <= -180.0) + deg1 = deg1 + 360.0; + + /* Write angle to string, adding 4 digits to number of decimal places */ + field = ndec + 4; + if (ndec > 0) { + sprintf (degform, "%%%d.%df", field, ndec); + sprintf (tstring, degform, deg1); + } + else { + sprintf (degform, "%%%4d", field); + sprintf (tstring, degform, (int)deg1); + } + + /* Move formatted string to returned string */ + ltstr = (int) strlen (tstring); + if (ltstr < lstr-1) + strcpy (string, tstring); + else { + strncpy (string, tstring, lstr-1); + string[lstr-1] = 0; + } + return; +} + + +/* Write the variable a in decimal format into field-character string */ + +void +num2str (string, num, field, ndec) + +char *string; /* Character string (returned) */ +double num; /* Number */ +int field; /* Number of characters in output field (0=any) */ +int ndec; /* Number of decimal places in degree string */ + +{ + char numform[8]; + + if (field > 0) { + if (ndec > 0) { + sprintf (numform, "%%%d.%df", field, ndec); + sprintf (string, numform, num); + } + else { + sprintf (numform, "%%%dd", field); + sprintf (string, numform, (int)num); + } + } + else { + if (ndec > 0) { + sprintf (numform, "%%.%df", ndec); + sprintf (string, numform, num); + } + else { + sprintf (string, "%d", (int)num); + } + } + return; +} + +/* Dec 14 1995 Original subroutines + + * Feb 5 1996 Added HDEL to delete keyword entry from FITS header + * Feb 7 1996 Add EOS to LINE in HPUTC + * Feb 21 1996 Add RA2STR and DEC2STR string routines + * Jul 19 1996 Add HPUTRA and HPUTDEC + * Jul 22 1996 Add HCHANGE to change keywords + * Aug 5 1996 Add HPUTNR8 to save specific number of decimal places + * Oct 15 1996 Fix spelling + * Nov 1 1996 Add DEG2STR to set specific number of decimal places + * Nov 1 1996 Allow DEC2STR to handle upt to 6 decimal places + * + * Mar 20 1997 Fix format error in DEG2STR + * Jul 7 1997 Fix 2 errors in HPUTCOM found by Allan Brighton + * Jul 16 1997 Fix error in HPUTC found by Allan Brighton + * Jul 17 1997 Fix error in HPUTC found by Allan Brighton + * Sep 30 1997 Fix error in HPUTCOM found by Allan Brighton + * Dec 15 1997 Fix minor bugs after lint + * Dec 31 1997 Always put two hour digits in RA2STR + * + * Feb 25 1998 Add HADD to insert keywords at specific locations + * Mar 27 1998 If n is negative, write g format in HPUTNR8() + * Apr 24 1998 Add NUM2STR() for easy output formatting + * Apr 30 1998 Use BLSEARCH() to overwrite blank lines before END + * May 27 1998 Keep Dec between -90 and +90 in DEC2STR() + * May 28 1998 Keep RA between 0 and 360 in RA2STR() + * Jun 2 1998 Fix bug when filling in blank lines before END + * Jun 24 1998 Add string length to ra2str(), dec2str(), and deg2str() + * Jun 25 1998 Make string converstion subroutines more robust + * Aug 31 1998 Add getltime() and getutime() + * Sep 28 1998 Null-terminate comment in HPUTCOM (Allan Brighton) + * Oct 1 1998 Change clock declaration in getltime() from int (Allan Brighton) + * + * Jan 28 1999 Fix bug to avoid writing HISTORY or COMMENT past 80 characters + * Jul 14 1999 Pad string in hputs() to minimum of 8 characters + * Aug 16 1999 Keep angle between -180 and +360 in dec2str() + * Oct 6 1999 Reallocate header buffer if it is too small in hputc() + * Oct 14 1999 Do not reallocate header; return error if not successful + * + * Mar 2 2000 Do not add quotes if adding HISTORY or COMMENT with hputs() + * Mar 22 2000 Move getutime() and getltime() to dateutil.c + * Mar 27 2000 Add hputm() for muti-line keywords + * Mar 27 2000 Fix bug testing for space to fit comment in hputcom() + * Apr 19 2000 Fix bug in hadd() which overwrote line + * Jun 2 2000 Dropped unused variable lv in hputm() after lint + * Jul 20 2000 Drop unused variables blank and i in hputc() + * + * Jan 11 2001 Print all messages to stderr + * Jan 18 2001 Drop declaration of blsearch(); it is in fitshead.h + * + * Jan 4 2002 Fix placement of comments + * + * Jul 1 2004 Add headshrink to optionally keep blank lines in header + * Sep 3 2004 Fix bug so comments are not pushed onto next line if long value + * Sep 16 2004 Add fixnegzero() to avoid putting signed zero values in header + * + * May 22 2006 Add option to leave blank line when deleting a keyword + * Jun 15 2006 Fix comment alignment in hputc() and hputcom() + * Jun 20 2006 Initialized uninitialized variables in hputm() and hputcom() + * + * Jan 4 2007 Declare keyword to be const + * Jan 4 2007 Drop unused subroutine hputi2() + * Jan 5 2007 Drop ksearch() declarations; it is now in fitshead.h + * Jan 16 2007 Fix bugs in ra2str() and dec2str() so ndec=0 works + * Aug 20 2007 Fix bug so comments after quoted keywords work + * Aug 22 2007 If closing quote not found, make one up + * + * Sep 9 2011 Always initialize q2 and lroot + */ |