gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 48ecc0d: Library (txt.h): floating point colum


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 48ecc0d: Library (txt.h): floating point columns, accept sexagesimal values
Date: Sun, 13 Sep 2020 00:06:40 -0400 (EDT)

branch: master
commit 48ecc0dba11fee4f0ae0088e55a89186580a82ff
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (txt.h): floating point columns, accept sexagesimal values
    
    Until now, it was not easily possible to convert a single sexagesimal
    coordiante into degrees on a single command (without making a new file to
    add the string metadata). Also, in plain-text tables that had sexagesimal
    coordinates, we needed to add the column metadata for the conversion.
    
    With this commit, if the sexagesimal coordinates are written in the
    standard format ('_h_m_s' for RA and '_d_m_s' for Dec), they can be present
    in a column that is mean to be 32-bit or 64-bit floating point. The
    sexagesimal values will be directly converted to a single floating point
    number and stored in memory like that.
    
    This couldn't be done in the old sexagesimal format of '_:_:_' because its
    ambiguous. So the lower-level unit conversion functions were also changed
    to always return the non-ambiguous format, but they can optionally return
    the colon-based format with an argument.
---
 NEWS                 | 31 +++++++++++++++++-
 doc/gnuastro.texi    | 62 +++++++++++++++++++++++++++---------
 lib/arithmetic.c     | 15 +++++++--
 lib/gnuastro/units.h |  4 +--
 lib/txt.c            | 49 ++++++++++++++++++++++++++---
 lib/units.c          | 89 ++++++++++++++++------------------------------------
 6 files changed, 162 insertions(+), 88 deletions(-)

diff --git a/NEWS b/NEWS
index 95beb5e..ed8cd9e 100644
--- a/NEWS
+++ b/NEWS
@@ -14,12 +14,41 @@ See the end of the file for license conditions.
      database's query statement yourself, or use Query's high-level
      interface to avoid having to learn it.
 
+  All programs:
+   - Plain text table inputs can have floating point columns that are in
+     sexagesimal format of '_h_m_s' or '_d_m_s' (where '_' is a
+     number). These are the classical format to respectively represent
+     Right Ascension (RA) and Declination (Dec). They will be directly read
+     as a single floating point number (in units of degrees) into
+     memory. Therefore the same column of a plain-text table, can be
+     degrees in some rows and sexagesimal in others. Besides large tables,
+     with this feature, conversion to sexagesimal coordinates to degrees
+     becomes very easy, for example:
+         echo "7h34m35.5498 31d53m14.352s" | asttable
+     Recall that the inverse can also be done with the more general column
+     arithmetic:
+         echo "113.64812416667 31.88732" \
+              | asttable -c'arith $1 degree-to-ra $2 degree-to-dec'
+
 ** Removed features
 
 ** Changed features
 
-** Bugs fixed
+  Table:
+   - Column arithmetic operators 'degree-to-ra' and 'degree-to-dec' will
+     return the sexagesimal format of '_h_m_s' and '_d_m_s'
+     respectively. Until this version, they would both use colons as
+     delimiters ('_:_:_').
 
+  Library:
+   - gal_units_degree_to_ra: new 'usecolon' argument to optionally format
+     output string with colons as delimiters ('_:_:_'). When this option is
+     zero, the string will be in the '_h_m_s' format.
+   - gal_units_degree_to_dec: similar to 'gal_units_degree_to_ra', but when
+     'usecolon' is zero, the string will be in the '_d_m_s' format.
+
+** Bugs fixed
+  bug #59105: Column arithmetic operator degree-to-ra, returning to dec
 
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 7548d3b..0d73ae9 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -9527,8 +9527,8 @@ The distance (along a great circle) on a sphere between 
two points is calculated
 @dispmath {\cos(d)=\sin(d_1)\sin(d_2)+\cos(d_1)\cos(d_2)\cos(r_1-r_2)}
 
 @item ra-to-degree
-Convert the hour-wise Right Ascension (RA) string, in the format of 
@code{HH:MM:SS}, to degrees.
-Note that the input column has to be an string format.
+Convert the hour-wise Right Ascension (RA) string, in the sexagesimal format 
of @code{_h_m_s} or @code{_:_:_}, to degrees.
+Note that the input column has to have a string format.
 In FITS tables, string columns are well-defined.
 For plain-text tables, please follow the standards defined in @ref{Gnuastro 
text table format}, otherwise the string column won't be read.
 @example
@@ -9537,19 +9537,20 @@ $ asttable catalog.fits -c'arith $5 ra-to-degree'
 @end example
 
 @item dec-to-degree
-Convert the Declination (Dec) string, in the format of @code{DD:MM:SS}, to 
degrees (a single floating point number).
+Convert the sexagesimal Declination (Dec) string, in the format of 
@code{_d_m_s} or @code{_:_:_}, to degrees (a single floating point number).
 For more details please see the @option{ra-to-degree} operator.
 
 @item degree-to-ra
+@cindex Sexagesimal
 @cindex Right Ascension
-Convert degrees (a column with a single floating point number) to the Right 
Ascension, RA, string (in the format of @code{HH:MM:SS}).
+Convert degrees (a column with a single floating point number) to the Right 
Ascension, RA, string (in the sexagesimal format hours, minutes and seconds, 
written as @code{_h_m_s}).
 The output will be a string column so no further mathematical operations can 
be done on it.
-The output can be in any format (for example FITS or plain-text).
-If its plain-text, the string column will be written following the standards 
described in @ref{Gnuastro text table format}.
+The output file can be in any format (for example FITS or plain-text).
+If it is plain-text, the string column will be written following the standards 
described in @ref{Gnuastro text table format}.
 
 @item degree-to-dec
 @cindex Declination
-Convert degrees (a column with a single floating point number) to the 
Declination, Dec, string (in the format of @code{DD:MM:SS}).
+Convert degrees (a column with a single floating point number) to the 
Declination, Dec, string (in the format of @code{_d_m_s}).
 See the @option{degree-to-ra} for more on the format of the output.
 @end table
 
@@ -9599,6 +9600,15 @@ $ asttable bintab.fits --sort=3 -ooutput.txt
 ## Subtract the first column from the second in `cat.fits' (can also
 ## be a text table) and keep the third and fourth columns.
 $ asttable cat.txt -c'arith $2 $1 -',3,4 -ocat.fits
+
+## Convert sexagesimal coordiantes to degrees (same can be done in a
+## large table given as argument).
+$ echo "7h34m35.5498 31d53m14.352s" | asttable
+
+## Convert RA and Dec in degrees to sexagesimal (same can be done in a
+## large table given as argument).
+echo "113.64812416667 31.88732" \
+     | asttable -c'arith $1 degree-to-ra $2 degree-to-dec'
 @end example
 
 Table's input dataset can be given either as a file or from Standard input 
(see @ref{Standard input}).
@@ -9615,6 +9625,25 @@ Options can also be stored in directory, user or 
system-wide configuration files
 Table does not follow Automatic output that is common in most Gnuastro 
programs, see @ref{Automatic output}.
 Thus, in the absence of an output file, the selected columns will be printed 
on the command-line with no column information, ready for redirecting to other 
tools like AWK or sort, similar to the examples above.
 
+@cartouche
+@noindent
+@strong{Sexagesimal coordinates as floats in plain-text tables:}
+When a column is determined to be a floating point type (32-bit or 64-bit) in 
a plain-text table, it can contain sexagesimal values in the format of 
`@code{_h_m_s}' (for RA) and `@code{_d_m_s}' (for Dec).
+In this case, the string will be immediately converted to a single floating 
point number (in units of degrees) and stored in memory with the rest of the 
column or table.
+Besides being useful in large tables, with this feature, conversion to 
sexagesimal coordinates to degrees becomes very easy, for example:
+@example
+echo "7h34m35.5498 31d53m14.352s" | asttable
+@end example
+
+@noindent
+The inverse can also be done with the more general column arithmetic
+operators:
+@example
+echo "113.64812416667 31.88732" \
+     | asttable -c'arith $1 degree-to-ra $2 degree-to-dec'
+@end example
+@end cartouche
+
 @table @option
 
 @item -i
@@ -23280,10 +23309,11 @@ different type, you can convert the input to a 
floating point type with
 @deffnx Macro GAL_ARITHMETIC_OP_DEC_TO_DEGREE
 @deffnx Macro GAL_ARITHMETIC_OP_DEGREE_TO_RA
 @deffnx Macro GAL_ARITHMETIC_OP_DEGREE_TO_DEC
+@cindex Sexagesimal
 @cindex Declination
 @cindex Right Ascension
-Unary operators to convert between degrees (as a single floating point number) 
to the standard Right Ascension and Declination notation (as strings, 
respectively in the format of @code{HH:MM:SS} and @code{DD:MM:SS}).
-The first two operators expect a string operand and will return a 
double-precision floating point operand.
+Unary operators to convert between degrees (as a single floating point number) 
to the sexagesimal Right Ascension and Declination format (as strings, 
respectively in the format of @code{_h_m_s} and @code{_d_m_s}).
+The first two operators expect a string operand (in the sexagesimal formats 
mentioned above, but also in the @code{_:_:_}) and will return a 
double-precision floating point operand.
 The latter two are the opposite.
 @end deffn
 
@@ -25899,22 +25929,24 @@ If the number of values parsed in the string is 
different from @code{n}, this fu
 
 @deftypefun double gal_units_ra_to_degree (char @code{*convert})
 @cindex Right Ascension
-Convert the input Right Ascension (RA) string (in the format of 
@code{HH:MM:SS}) to degrees (a single floating point number).
+Convert the input Right Ascension (RA) string (in the format of hours, minutes 
and seconds either as @code{_h_m_s} or @code{_:_:_}) to degrees (a single 
floating point number).
 @end deftypefun
 
 @deftypefun double gal_units_dec_to_degree (char @code{*convert})
 @cindex Declination
-Convert the input Declination (Dec) string (in the format of @code{DD:MM:SS}) 
to degrees (a single floating point number).
+Convert the input Declination (Dec) string (in the format of degrees, 
arc-minutes and arc-seconds either as @code{_d_m_s} or @code{_:_:_}) to degrees 
(a single floating point number).
 @end deftypefun
 
-@deftypefun {char *} gal_units_degree_to_ra (double @code{decimal})
+@deftypefun {char *} gal_units_degree_to_ra (double @code{decimal}, int 
@code{usecolon})
 @cindex Right Ascension
-Convert the input Right Ascension (RA) degree (a single floating point number) 
to old/standard notation (in the format of @code{HH:MM:SS}).
+Convert the input Right Ascension (RA) degree (a single floating point number) 
to old/standard notation (in the format of hours, minutes and seconds of 
@code{_h_m_s}).
+If @code{usecolon!=0}, then the delimiters between the components will be 
colons: @code{_:_:_}.
 @end deftypefun
 
-@deftypefun {char *} gal_units_degree_to_dec (double @code{decimal})
+@deftypefun {char *} gal_units_degree_to_dec (double @code{decimal}, int 
@code{usecolon})
 @cindex Declination
-Convert the input Declination (RA) degree (a single floating point number) to 
old/standard notation (in the format of @code{HH:MM:SS}).
+Convert the input Declination (Dec) degree (a single floating point number) to 
old/standard notation (in the format of degrees, arc-minutes and arc-seconds of 
@code{_d_m_s}).
+If @code{usecolon!=0}, then the delimiters between the components will be 
colons: @code{_:_:_}.
 @end deftypefun
 
 @node Spectral lines library, Cosmology library, Unit conversion library 
(@file{units.h}), Gnuastro library
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 744b7b1..fb33c6b 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -353,6 +353,15 @@ arithmetic_abs(int flags, gal_data_t *in)
 
 
 
+/* Wrapper functions for RA/Dec strings. */
+static char *
+arithmetic_units_degree_to_ra(double decimal)
+{ return gal_units_degree_to_ra(decimal, 0); }
+
+static char *
+arithmetic_units_degree_to_dec(double decimal)
+{ return gal_units_degree_to_dec(decimal, 0); }
+
 #define UNIFUNC_RUN_FUNCTION_ON_ELEMENT(OT, IT, OP){                    \
     OT *oa=o->array;                                                    \
     IT *ia=in->array, *iaf=ia + in->size;                               \
@@ -548,11 +557,11 @@ arithmetic_unary_function(int operator, int flags, 
gal_data_t *in)
       break;
 
     case GAL_ARITHMETIC_OP_DEGREE_TO_RA:
-      UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(gal_units_degree_to_ra);
+      UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(arithmetic_units_degree_to_ra);
       break;
 
     case GAL_ARITHMETIC_OP_DEGREE_TO_DEC:
-      UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(gal_units_degree_to_dec);
+      UNIARY_FUNCTION_ON_ELEMENT_OUTPUT_STRING(arithmetic_units_degree_to_dec);
       break;
 
     default:
@@ -1837,7 +1846,7 @@ gal_arithmetic_set_operator(char *string, size_t 
*num_operands)
   else if (!strcmp(string, "dec-to-degree"))
     { op=GAL_ARITHMETIC_OP_DEC_TO_DEGREE;  *num_operands=1;  }
   else if (!strcmp(string, "degree-to-ra"))
-    { op=GAL_ARITHMETIC_OP_DEGREE_TO_DEC;  *num_operands=1;  }
+    { op=GAL_ARITHMETIC_OP_DEGREE_TO_RA;   *num_operands=1;  }
   else if (!strcmp(string, "degree-to-dec"))
     { op=GAL_ARITHMETIC_OP_DEGREE_TO_DEC;  *num_operands=1;  }
 
diff --git a/lib/gnuastro/units.h b/lib/gnuastro/units.h
index 8220999..885a0f0 100644
--- a/lib/gnuastro/units.h
+++ b/lib/gnuastro/units.h
@@ -68,10 +68,10 @@ double
 gal_units_dec_to_degree (char *convert);
 
 char *
-gal_units_degree_to_ra (double decimal);
+gal_units_degree_to_ra (double decimal, int usecolon);
 
 char *
-gal_units_degree_to_dec (double decimal);
+gal_units_degree_to_dec (double decimal, int usecolon);
 
 __END_C_DECLS    /* From C++ preparations */
 
diff --git a/lib/txt.c b/lib/txt.c
index 9c1977e..8158f3e 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -33,6 +33,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include <gnuastro/txt.h>
 #include <gnuastro/list.h>
+#include <gnuastro/units.h>
 #include <gnuastro/blank.h>
 #include <gnuastro/table.h>
 
@@ -720,7 +721,7 @@ static void
 txt_read_token(gal_data_t *data, gal_data_t *info, char *token,
                size_t i, char *filename, size_t lineno, size_t colnum)
 {
-  char   *tailptr;
+  char   *tailptr, emptystr[1]="\0";
   char     **str = data->array, **strb;
   uint8_t    *uc = data->array,   *ucb;
   int8_t      *c = data->array,    *cb;
@@ -831,13 +832,31 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
              compare the values. */
         case GAL_TYPE_FLOAT32:
           f[i]=strtod(token, &tailptr);
+          if( (*tailptr=='h' || *tailptr=='d') && isdigit(*(tailptr+1)) )
+            {
+              f[i] = ( *tailptr=='h'
+                       ? gal_units_ra_to_degree(token)
+                       : gal_units_dec_to_degree(token) );
+              if( !isnan(f[i]) ) tailptr=emptystr;
+            }
           if( (fb=info->array)
               && ( (isnan(*fb) && isnan(f[i])) || *fb==f[i] ) )
-            f[i]=GAL_BLANK_FLOAT64;
+            f[i]=GAL_BLANK_FLOAT32;
           break;
 
+        /* In astronomical datasets, it can happen that a column is in the
+           format of __h__m__s or __d__m__s (where every '_' is a digit),
+           in these cases, they are actually coordinates (RA for first, Dec
+           for second). */
         case GAL_TYPE_FLOAT64:
           d[i]=strtod(token, &tailptr);
+          if( (*tailptr=='h' || *tailptr=='d') && isdigit(*(tailptr+1)) )
+            {
+              d[i] = ( *tailptr=='h'
+                       ? gal_units_ra_to_degree(token)
+                       : gal_units_dec_to_degree(token) );
+              if( !isnan(d[i]) ) tailptr=emptystr;
+            }
           if( (db=info->array)
               && ( (isnan(*db) && isnan(d[i])) || *db==d[i] ) )
             d[i]=GAL_BLANK_FLOAT64;
@@ -850,9 +869,29 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
 
       /* If a number couldn't be read properly, then report an error. */
       if(data->type!=GAL_TYPE_STRING && *tailptr!='\0')
-        error_at_line(EXIT_FAILURE, 0, filename, lineno, "column %zu "
-                      "('%s') couldn't be read as a '%s' number",
-                      colnum, token, gal_type_name(data->type, 1) );
+        {
+          if( tailptr!=token
+              && isdigit(*(tailptr-1))
+              && *tailptr==':'
+              && isdigit(*(tailptr+1)) )
+            error_at_line(EXIT_FAILURE, 0, filename, lineno, "column %zu "
+                          "('%s') couldn't be read as a '%s' number.\n\n"
+                          "If it was meant to be celestial coordinates (RA "
+                          "or Dec), please use the '_h_m_s' format for RA "
+                          "or '_d_m_s' for Dec. The '_:_:_' format is "
+                          "ambiguous (can be used for both RA and Dec). "
+                          "Alternatively, you can use the column arithmetic "
+                          "operators 'ra-to-degree' or 'dec-to-degree' of "
+                          "'asttable' which also accept the '_:_:_' "
+                          "format. For more, please run this command\n\n"
+                          "   $ info gnuastro \"column arithmetic\"",
+                          colnum, token,
+                          gal_type_name(data->type, 1) );
+          else
+            error_at_line(EXIT_FAILURE, 0, filename, lineno, "column %zu "
+                          "('%s') couldn't be read as a '%s' number",
+                          colnum, token, gal_type_name(data->type, 1) );
+        }
     }
 }
 
diff --git a/lib/units.c b/lib/units.c
index 4a67861..753af0e 100644
--- a/lib/units.c
+++ b/lib/units.c
@@ -69,9 +69,11 @@ gal_units_extract_decimal(char *convert, const char 
*delimiter,
           args[i++] = strtod (token, &end);
           if (*end && *end != *delimiter)
             {
-              free(copy);
+              /* In case a warning is necessary
               error(0, 0, "%s: unable to parse element %zu in '%s'\n",
                     __func__, i, convert);
+              */
+              free(copy);
               return 0;
             }
         }
@@ -82,8 +84,10 @@ gal_units_extract_decimal(char *convert, const char 
*delimiter,
   /* Check if the number of elements parsed. */
   if (i != n)
     {
-      error (0, 0, "%s: input '%s' must contain %lu numbers, but has "
-             "%lu numbers\n", __func__, convert, n, i);
+      /* In case a warning is necessary
+      error(0, 0, "%s: input '%s' must contain %lu numbers, but has "
+            "%lu numbers\n", __func__, convert, n, i);
+      */
       return 0;
     }
 
@@ -121,44 +125,25 @@ gal_units_ra_to_degree(char *convert)
   double decimal=0.0;
 
   /* Check whether the string is successfully parsed */
-  if(gal_units_extract_decimal (convert, ":", val, 3))
+  if(gal_units_extract_decimal(convert, ":hms", val, 3))
     {
       /* Check whether the first value is in within limits, and add it. */
-      if(val[0]<0.0 || val[0]>24.0)
-        {
-          error(0, 0, "%s: value of first decimal (%g) in '%s' should be "
-                "between 0 and 24", __func__, val[0], convert);
-          return NAN;
-        }
+      if(val[0]<0.0 || val[0]>24.0) return NAN;
       decimal += val[0];
 
-      /* Check whether value of minutes is in within limits, and add it. */
-      if(val[1]<0.0 || val[1]>60.0)
-        {
-          error(0, 0, "%s: value of second decimal (%g) in '%s' should be "
-                "between 0 and 60", __func__, val[0], convert);
-          return NAN;
-        }
+      /* Check whether value of minutes is within limits, and add it. */
+      if(val[1]<0.0 || val[1]>60.0) return NAN;
       decimal += val[1] / 60;
 
       /* Check whether value of seconds is in within limits, and add it. */
-      if(val[2]<0.0 || val[2]>60.0)
-        {
-          error(0, 0, "%s: value of third decimal (%g) in '%s' should be "
-                "between 0 and 60", __func__, val[0], convert);
-          return NAN;
-        }
+      if(val[2]<0.0 || val[2]>60.0) return NAN;
       decimal += val[2] / 3600;
 
       /* Convert value to degrees and return. */
       decimal *= 15.0;
       return decimal;
     }
-  else
-    {
-      error(0, 0, "%s: input '%s' couldn't be parsed", __func__, convert);
-      return NAN;
-    }
+  else return NAN;
 
   /* Control shouldn't reach this point. If it does, its a bug! */
   error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
@@ -174,21 +159,16 @@ gal_units_ra_to_degree(char *convert)
 /* Parse the declination input as a string in form of dd:mm:ss to a decimal
  * calculated by (dd + mm / 60 + ss / 3600 ). */
 double
-gal_units_dec_to_degree (char *convert)
+gal_units_dec_to_degree(char *convert)
 {
   int sign;
   double val[3], decimal=0.0;
 
   /* Parse the values in the input string. */
-  if(gal_units_extract_decimal (convert, ":", val, 3))
+  if(gal_units_extract_decimal(convert, ":dms", val, 3))
     {
       /* Check whether the first value is in within limits. */
-      if(val[0]<-90.0 || val[0]>90.0)
-        {
-          error(0, 0, "%s: value of first decimal (%g) in '%s' should be "
-                "between -90 and 90", __func__, val[0], convert);
-          return NAN;
-        }
+      if(val[0]<-90.0 || val[0]>90.0) return NAN;
 
       /* If declination is negative, the first value in the array will be
          negative and all other values will be positive. In that case, we
@@ -199,35 +179,18 @@ gal_units_dec_to_degree (char *convert)
       decimal += val[0] * sign;
 
       /* Check whether value of arc-minutes is in within limits. */
-      if(val[1]<0.0 || val[1]>60.0)
-        {
-          error(0, 0, "%s: value of second decimal (%g) in '%s' should be "
-                "between 0 and 60", __func__, val[1], convert);
-          return NAN;
-        }
-      /* Convert arc-minutes to decimal and add to the decimal value */
+      if(val[1]<0.0 || val[1]>60.0) return NAN;
       decimal += val[1] / 60;
 
       /* Check whether value of arc-seconds is in within limits */
-      if (val[2] < 0.0 || val[2] > 60.0)
-        {
-          error(0, 0, "%s: value of third decimal (%g) in '%s' should be "
-                "between 0 and 60", __func__, val[2], convert);
-          return NAN;
-        }
-
-      /* Convert arc-seconds to decimal and add to the decimal value */
+      if (val[2] < 0.0 || val[2] > 60.0) return NAN;
       decimal += val[2] / 3600;
 
       /* Make the sign of the decimal value same as input and return. */
       decimal *= sign;
       return decimal;
     }
-  else
-    {
-      error(0, 0, "%s: input '%s' couldn't be parsed", __func__, convert);
-      return NAN;
-    }
+  else return NAN;
 
   /* Control shouldn't reach this point. If it does, its a bug! */
   error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
@@ -265,14 +228,14 @@ gal_units_dec_to_degree (char *convert)
 /* Parse the right ascension input as a decimal to a string in form of
    hh:mm:ss.ss . */
 char *
-gal_units_degree_to_ra(double decimal)
+gal_units_degree_to_ra(double decimal, int usecolon)
 {
   size_t nchars;
   int hours=0, minutes=0;
   float seconds=0.0; /* For sub-second accuracy */
 
-  /* Allocate string of length 15 which is large enough for string of
-     format hh:mm:ss.ss and sign */
+  /* Allocate a long string which is large enough for string of format
+     hh:mm:ss.ss and sign */
   char *ra=gal_pointer_allocate(GAL_TYPE_UINT8, UNITS_RADECSTR_MAXLENGTH,
                                 0, __func__, "ra");
 
@@ -299,7 +262,8 @@ gal_units_degree_to_ra(double decimal)
 
   /* Format the extracted hours, minutes and seconds as a string with
      leading zeros if required, in hh:mm:ss format */
-  nchars = snprintf(ra, UNITS_RADECSTR_MAXLENGTH-1, "%02d:%02d:%g",
+  nchars = snprintf(ra, UNITS_RADECSTR_MAXLENGTH-1,
+                    usecolon ? "%02d:%02d:%g" : "%02dh%02dm%gs",
                     hours, minutes, seconds);
   if(nchars>UNITS_RADECSTR_MAXLENGTH)
     error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to address "
@@ -316,7 +280,7 @@ gal_units_degree_to_ra(double decimal)
 
 /* Parse the declination input as a decimal to a string in form of dd:mm:ss*/
 char *
-gal_units_degree_to_dec(double decimal)
+gal_units_degree_to_dec(double decimal, int usecolon)
 {
   size_t nchars;
   float arc_seconds=0.0;
@@ -356,7 +320,8 @@ gal_units_degree_to_dec(double decimal)
   /* Format the extracted degrees, arc-minutes and arc-seconds as a string
      with leading zeros if required, in hh:mm:ss format with correct
      sign. */
-  nchars = snprintf(dec, UNITS_RADECSTR_MAXLENGTH-1, "%s%02d:%02d:%g",
+  nchars = snprintf(dec, UNITS_RADECSTR_MAXLENGTH-1,
+                    usecolon ? "%s%02d:%02d:%g" : "%s%02dd%02dm%gs",
                     sign<0?"-":"+", degrees, arc_minutes, arc_seconds);
   if(nchars>UNITS_RADECSTR_MAXLENGTH)
     error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to address "



reply via email to

[Prev in Thread] Current Thread [Next in Thread]