gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master cd39401: Option parsing: all coordinate column


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master cd39401: Option parsing: all coordinate columns accept sexagesimal
Date: Wed, 17 Nov 2021 20:25:12 -0500 (EST)

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

    Option parsing: all coordinate columns accept sexagesimal
    
    Until now, the coordinate parsing options of all the programs would only
    accept RA and Dec in degrees (a single number). However, in many contexts,
    we are provided with sexagesimal RAs and Decs and having to convert them to
    degrees before calling the programs was annoying.
    
    With this commit, the low-level option parsing options have been edited to
    attempt to read the given value as a sexagesimal coordinate also (in case
    they can't be read as a single number).
    
    Besides convenience on the command-line, with this feature, users don't
    have to worry about how DS9 records the polygon vertices in its region file
    (by default DS9 saves values in sexagesimal, and this would cause a crash).
    
    This was initially suggested by Alessandro Ederoclite for the '--center'
    option of Crop, and also related to the DS9 region file parsing bug that
    was reported by Juan Antonio Fernández Ontiveros and Alejandro Lumbreras
    Calle.
    
    This fixes bug #61468.
---
 NEWS                         |  10 +++
 THANKS                       |   3 +
 bin/crop/ui.c                |   3 +-
 doc/announce-acknowledge.txt |   3 +
 doc/gnuastro.texi            |  47 ++++++++---
 lib/options.c                | 185 +++++++++++++++++++++++++++++++++++++++----
 lib/units.c                  |   4 +-
 7 files changed, 225 insertions(+), 30 deletions(-)

diff --git a/NEWS b/NEWS
index 54c3080..5d2283c 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,13 @@ See the end of the file for license conditions.
 ** New features
 
   All programs:
+   - Coordinate-related columns in all programs now also accept sexagesimal
+     values, not just degrees. Therefore, '--center=113.8729761,31.9027152'
+     and '--center=07h35m29.51,31d54m9.77' are now equivalent in the Crop
+     or Query programs that have this option! Other improved options
+     include the '--polygon' options of Table and Crop (that also take
+     region files produced by DS9), the '--coord' option of Match, the
+     '--crval' option of MakeProfiles.
    - Columns of FITS tables are now read in parallel (when '--numthreads'
      isn't set to '1', and if the dependency CFITSIO library was built with
      '--enable-reentrant'). In scenarios where many columns may be
@@ -82,6 +89,9 @@ See the end of the file for license conditions.
               and fixed with the help of Sebastian Luna-Valero.
   bug #61378: Table crash when input is sexagesimal RA/DEC and no metadata.
   bug #61462: Crash on FITS binary table colums with repeat of 0.
+  bug #61468: DS9 region file can't be read in sexagesimal coordinates,
+              reported by Juan Antonio Fernández Ontiveros and Alejandro
+              Lumbreras Calle.
   bug #61490: Extra columns in the metadata causes crash in plain-text
               tables, found by Zohre Ghaffari.
   bug #61493: NoiseChisel's --checksn not showing pseudos equal to
diff --git a/THANKS b/THANKS
index ede64b2..158c509 100644
--- a/THANKS
+++ b/THANKS
@@ -40,9 +40,11 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Antonio Diaz Diaz                    antonio@gnu.org
     Alexey Dokuchaev                     danfe@freebsd.org
     Pierre-Alain Duc                     pierre-alain.duc@astro.unistra.fr
+    Alessandro Ederoclite                aederocl@gmail.com
     Elham Eftekhari                      elhamea@iac.es
     Paul Eggert                          eggert@cs.ucla.edu
     Sepideh Eskandarlou                  sepideh.eskandarlou@gmail.com
+    Juan Antonio Fernández Ontiveros     jafernandez@cefca.es
     Gaspar Galaz                         ggalaz@astro.puc.cl
     Andrés García-Serra Romero           alu0101451923@ull.edu.es
     Zohreh Ghaffari                      zoh.ghaffari@gmail.com
@@ -68,6 +70,7 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Floriane Leclercq                    floriane.leclercq@univ-lyon1.fr
     Alan Lefor                           alefor@astr.tohoku.ac.jp
     Javier Licandro                      jlicandr@iac.es
+    Alejandro Lumbreras Calle            alumbreras@cefca.es
     Sebastián Luna Valero                sluna@iaa.es
     Alberto Madrigal                     brt.madrigal@gmail.com
     Guillaume Mahler                     guillaume.mahler@univ-lyon1.fr
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index f264668..1f7ef07 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -939,8 +939,7 @@ ui_preparations_to_img_mode(struct cropparams *p)
               if(pixwidth>UI_WIDTH_TOO_LARGE_SIZE)
                 ui_warning_width_is_too_large(darr[i], i+1, pixwidth,
                                               pixscale[i]);
-              else
-                darr[i]=pixscale[i];
+              darr[i]=pixwidth;
             }
           free(pixscale);
         }
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index 100a1e2..b67d639 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -1,10 +1,13 @@
 Alphabetically ordered list to acknowledge in the next release.
 
 Andres Del Pino Molina
+Alessandro Ederoclite
 Sepideh Eskandarlou
+Juan Antonio Fernández Ontiveros
 Zohreh Ghaffari
 Zahra Hosseini
 Raúl Infante-Sainz
+Alejandro Lumbreras Calle
 Sebastian Luna-Valero
 Manuel Sánchez-Benavente
 Peter Teuben
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index ba6c6b9..2d3dae2 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -2276,6 +2276,10 @@ $ for f in f105w f125w f160w; do \
 
 Please open these images and inspect them with the same @command{ds9} command 
you used above.
 You will see how it is nicely flat now and doesn't have varying depths.
+In the example above, the polygon vertices are in degrees, but you can also 
replace them with sexagesimal coordinates (for example using 
@code{03h32m44.9794} or @code{03:32:44.9794} instead of @code{53.187414} 
instead of the first RA and @code{-27d46m44.9472} or @code{-27:46:44.9472} 
instead of the first Dec).
+To futher simplify things, you can even define your polygon visually as a DS9 
``region'', save it as a ``region file'' and give that file to crop.
+But we need to continue, so if you are interested to learn more, see 
@ref{Crop}.
+
 Another important result of this crop is that regions with no data now have a 
NaN (Not-a-Number, or a blank value) value.
 In the downloaded files, such regions had a value of zero.
 However, zero is a number, and is thus meaningful, especially when you later 
want to NoiseChisel@footnote{As you will see below, unlike most other detection 
algorithms, NoiseChisel detects the objects from their faintest parts, it 
doesn't start with their high signal-to-noise ratio peaks.
@@ -11414,7 +11418,7 @@ This option is very similar to the @option{--inpolygon} 
option, so see the descr
 @item --polygon=STR
 @itemx --polygon=FLT,FLT:FLT,FLT:...
 The polygon to use for the @code{--inpolygon} and @option{--outpolygon} 
options.
-This option behaves identically to the same option in the Crop program, so for 
more information on how to use it, see @ref{Crop options}.
+This option is parsed in an identical way to the same option in the Crop 
program, so for more information on how to use it, see @ref{Crop options}.
 
 @item -e STR,INT/FLT,...
 @itemx --equal=STR,INT/FLT,...
@@ -11884,8 +11888,9 @@ $ astquery vizier --dataset=I/350/gaiaedr3 
--output=my-gaia.fits \
 
 ## Similar to above, but only ID, RA and Dec columns for objects with
 ## magnitude range 10 to 15. In VizieR, this column is called 'Gmag'.
+## Also, using sexagesimal coordinates instead of degrees for center.
 $ astquery vizier --dataset=I/350/gaiaedr3 --output=my-gaia.fits \
-           --center=113.8729761,31.9027152 --radius=1/60 \
+           --center=07h35m29.51,31d54m9.77 --radius=1/60 \
            --range=Gmag,10:15 -cEDR3Name,RAJ2000,DEJ2000
 @end example
 
@@ -12001,6 +12006,8 @@ Therefore the resulting catalog may not overlap, or 
correspond to a larger/small
 @item -C FLT,FLT
 @itemx --center=FLT,FLT
 The spatial center position (mostly RA and Dec) to use for the automatically 
generated query (not compatible with @option{--query}).
+The comma-separated values can either be in degrees (a single number), or 
sexagesimal (@code{_h_m_} for RA, @code{_d_m_} for Dec, or @code{_:_:_} for 
both).
+
 The given values will be compared to two columns in the database to 
find/return rows within a certain region around this center position will be 
requested and downloaded.
 Pre-defined RA and Dec column names are defined in Query for every database, 
however you can use @option{--ccol} to select other columns to use instead.
 The region can either be a circle and the point (configured with 
@option{--radius}) or a box/rectangle around the point (configured with 
@option{--width}).
@@ -12315,6 +12322,10 @@ $ astcrop --section=10:*-10,10:*-10 --hdu=2 image.fits
 ## Crop region around RA and Dec of (189.16704, 62.218203):
 $ astcrop --mode=wcs --center=189.16704,62.218203 goodsnorth.fits
 
+## Same crop above, but coordinates given in sexagesimal (you can
+## also use ':' between the sexagesimal components).
+$ astcrop --mode=wcs --center=12h36m40.08,62d13m5.53 goodsnorth.fits
+
 ## Crop region around pixel coordinate (568.342, 2091.719):
 $ astcrop --mode=img --center=568.342,2091.719 --width=201 image.fits
 @end example
@@ -12400,6 +12411,8 @@ Crop box parameters:
 @itemx --center=FLT[,FLT[,...]]
 The central position of the crop in the input image.
 The positions along each dimension must be separated by a comma (@key{,}) and 
fractions are also acceptable.
+The comma-separated values can either be in degrees (a single number), or 
sexagesimal (@code{_h_m_} for RA, @code{_d_m_} for Dec, or @code{_:_:_} for 
both).
+
 The number of values given to this option must be the same as the dimensions 
of the input dataset.
 The width of the crop should be set with @code{--width}.
 The units of the coordinates are read based on the value to the 
@option{--mode} option, see below.
@@ -12429,7 +12442,10 @@ This is useful when you want a fixed crop size in 
pixels, even though your cente
 @itemx -l FLT:FLT,...
 @itemx --polygon=STR
 @itemx --polygon=FLT,FLT:FLT,FLT:...
+@cindex Sexagesimal
 Polygon vertice coordinates (when value is in @option{FLT,FLT:FLT,FLT:...} 
format) or the filename of a SAO DS9 region file (when the value has no 
@file{,} or @file{:} characters).
+Each vertice can either be in degrees (a single floating point number) or 
sexagesimal (in formats of `@code{_h_m_}' for RA and `@code{_d_m_}' for Dec, or 
simply `@code{_:_:_}' for either of them).
+
 The vertices are used to define the polygon: in the same order given to this 
option.
 When the vertices are not necessarily ordered in the proper order (for example 
one vertice in a square comes after its diagonal opposite), you can add the 
@option{--polygonsort} option which will attempt to sort the vertices before 
cropping.
 Note that for concave polygons, sorting is not recommended because there is no 
unique solution, for more, see the description under @option{--polygonsort}.
@@ -20089,6 +20105,7 @@ $ astmatch --aperture=5e-10 --ccol1=5 --ccol2=10 
in1.fits in2.txt
 
 ## Find the row that is closest to (RA,DEC) of (12.3456,6.7890)
 ## with a maximum distance of 1 arcseconds (1/3600 degrees).
+## The coordinates can also be given in sexagesimal.
 $ astmatch input1.txt --ccol1=ra,dec --coord=12.3456,6.7890 \
            --aperture=1/3600
 
@@ -20295,6 +20312,7 @@ See the example in @option{--ccol1} for more.
 @itemx --coord=FLT[,FLT]
 Manually specify the coordinates to match against the given catalog.
 With this option, Match will not look for a second input file/table and will 
directly use the coordinates given to this option.
+When the coordinates are RA and Dec, the comma-separated values can either be 
in degrees (a single number), or sexagesimal (@code{_h_m_} for RA, @code{_d_m_} 
for Dec, or @code{_:_:_} for both).
 
 When this option is called, the output changes in the following ways:
 1) when @option{--outcols} is specified, for the second input, it can only 
accept integer numbers that are less than the number of values given to this 
option, see description of that option for more.
@@ -21347,6 +21365,8 @@ Fractions are acceptable for the values of this option.
 @item --crval=FLT,FLT
 The WCS coordinates of the Reference point.
 Fractions are acceptable for the values of this option.
+The comma-separated values can either be in degrees (a single number), or 
sexagesimal (@code{_h_m_} for RA, @code{_d_m_} for Dec, or @code{_:_:_} for 
both).
+In any case, the final value that will be written in the @code{CRVAL} keyword 
will be a floating point number in degrees (according to the FITS standard).
 
 @item --cdelt=FLT,FLT
 The resolution (size of one data-unit or pixel in WCS units) of the 
non-oversampled dataset.
@@ -24191,19 +24211,18 @@ above easier. In the functions below, the constants 
above can be used for
 the @code{type} input argument.
 
 @deftypefun size_t gal_type_sizeof (uint8_t @code{type})
-Return the number of bytes occupied by @code{type}. Internally, this
-function uses C's @code{sizeof} operator to measure the size of each type.
+Return the number of bytes occupied by @code{type}.
+Internally, this function uses C's @code{sizeof} operator to measure the size 
of each type.
+For strings, this function will return the size of @code{char *}.
 @end deftypefun
 
 @deftypefun {char *} gal_type_name (uint8_t @code{type}, int @code{long_name})
-Return a string literal that contains the name of @code{type}. It can
-return both short and long formats of the type names (for example
-@code{f32} and @code{float32}). If @code{long_name} is non-zero, the long
-format will be returned, otherwise the short name will be returned. The
-output string is statically allocated, so it should not be freed. This
-function is the inverse of the @code{gal_type_from_name} function. For the
-full list of names/strings that this function will return, see @ref{Numeric
-data types}.
+Return a string literal that contains the name of @code{type}.
+It can return both short and long formats of the type names (for example 
@code{f32} and @code{float32}).
+If @code{long_name} is non-zero, the long format will be returned, otherwise 
the short name will be returned.
+The output string is statically allocated, so it should not be freed.
+This function is the inverse of the @code{gal_type_from_name} function.
+For the full list of names/strings that this function will return, see 
@ref{Numeric data types}.
 @end deftypefun
 
 @deftypefun uint8_t gal_type_from_name (char @code{*str})
@@ -24378,7 +24397,11 @@ types}).
 @deftypefun {void *} gal_pointer_allocate (uint8_t @code{type}, size_t 
@code{size}, int @code{clear}, const char @code{*funcname}, const char 
@code{*varname})
 Allocate an array of type @code{type} with @code{size} elements in RAM (for 
the type codes, see @ref{Library data types}).
 If @code{clear!=0}, then the allocated space is set to zero (cleared).
+
 This is effectively just a wrapper around C's @code{malloc} or @code{calloc} 
functions but takes Gnuastro's integer type codes and will also abort with a 
clear error if there the allocation was not successful.
+The number of allocated bytes is the value given to @code{size} that is 
multiplied by the returned value of @code{gal_type_sizeof} for the given type.
+So if you want to allocate space for an array of strings you should pass the 
type @code{GAL_TYPE_STRING}.
+Otherwise, if you just want space for one string (for example 6 bytes for 
@code{hello}, including the string-termination character), you should se the 
type @code{GAL_TYPE_UINT8}.
 
 @cindex C99
 When space cannot be allocated, this function will abort the program with a 
message containing the reason for the failure.
diff --git a/lib/options.c b/lib/options.c
index 61115f6..fd89456 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -37,6 +37,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/data.h>
 #include <gnuastro/table.h>
 #include <gnuastro/blank.h>
+#include <gnuastro/units.h>
 #include <gnuastro/threads.h>
 #include <gnuastro/pointer.h>
 #include <gnuastro/arithmetic.h>
@@ -611,6 +612,148 @@ gal_options_read_interpmetric(struct argp_option *option, 
char *arg,
 
 
 
+/* If the current token (in a 'colon'-separated list) is a sexagesimal
+   number, or a normal number, read it as a double, and return the pointer
+   to the end of the string (to continue parsing). We have three types of
+   strings at this phase:
+
+      12.34,56.78:90.12,34.56:...                   Normal number.
+           ^     ^     ^
+
+      1h2m3.45,6d7m8.90:2h3m4.56,7d8m9.01:...       Sexagesimal (hd)
+       ^        ^        ^        ^
+
+      1:2:3.45,6:7:8.90:2:3:4.56,7:8:9.01:...       Sexagesimal (colon)
+       ^        ^        ^        ^
+
+  This function is called while trying to tokenize such a string and it
+  will stop at the highlighed points. Its job is to determine if the token
+  its on is sexagesimal string, or if its a normal number. If its a normal
+  number, then just return NULL. But if its a sexagesimal string, it should
+  return a copy of the string without any futher components (like the comma
+  or colon of the full string).
+
+  HOWEVER, this function may also be given a normal colon-separted list,
+  like below. In such cases, it will return a NULL (to let the caller know
+  that the ':' in the 'tailptr' was a false alarm, and it can use the
+  number before the ':' without worrying about it being a sexagesimal
+  number.
+
+      ':0.123,4.567'    which is part of    '1.2345,6.789:0.123,4.567' */
+static double
+gal_options_read_sexagesimal(size_t dim, char *str, char **tailptr)
+{
+  double out;
+  char *c, *cc, *copy;
+  size_t stlen=0, coloncounter;
+  int ishd=0, iscolon=0, isra=0, isdec=0;
+
+  /* A small sanity check. */
+  if(dim>1)
+    error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at '%s', "
+          "to find the cause of the problem. The value of 'dim' at "
+          "this point should be 0 or 1, but it has a value of %zu",
+          __func__, PACKAGE_BUGREPORT, dim);
+
+  /* Parse the start of this string, until you find find exactly what it
+     is. */
+  c=str;
+  while( *c!='\0' && ishd==0 && iscolon==0 )
+    switch(*c++)
+      {
+      case 'h': ishd=1; isra=1;  break;
+      case 'd': ishd=1; isdec=1; break;
+      case ':':
+        /* A single colon isn't enough to be sure that this is a
+           colon-based sexagesimal number. We need at least one more before
+           we reach the end of the string, or the next comma. */
+        cc=c; /* 'c' is already on the next character! */
+        coloncounter=1; /* We have already passed the first colon! */
+        while(*cc!='\0' && *cc!=',')
+          switch(*cc++) { case ':': coloncounter++; break; }
+
+        /* If the loop above ended in a comma, then it stops and its time
+           to check if this is actually a sexagesimal string or not. If we
+           have reached the end of the string, and there was only two
+           colons, then this is indeed a colon-based sexagesimal string.*/
+        if( (*cc=='\0' || *cc==',')
+            && coloncounter>=2 )
+          iscolon=1;
+
+        /* If 'iscolon' is still zero until we reach this point, then we
+           should simply return with a NaN, letting the user know that the
+           'tailptr' was a false alarm and it can continue with parsing the
+           string. */
+        if(iscolon==0) return NAN;
+
+        /* Everything is good, continue */
+        if(dim==0) isra=1; else isdec=1;
+        break;
+      }
+
+  /* Make sure the string could be identified properly */
+  if( (isra==0 && isdec==0) || (ishd==0 && iscolon==0) )
+    error(EXIT_FAILURE, 0, "the first token in the string '%s' "
+          "couldn't be parsed as a sexagesimal string", str);
+
+  /* Check if the hd-type is given for the proper dimension. */
+  if( (isra && dim!=0) || (isdec && dim!=1) )
+    error(EXIT_FAILURE, 0, "the order of sexagesimal coordinates "
+          "is wrong! The first should be RA (with a format like "
+          "'__h__m__'), and the second should be Dec ('__d__m__')");
+
+  /* Depending on the mode, find the length of the full string into a new
+     string to give to the unit conversion functions. Note that the
+     delimiters are ':', ','. However, if we are on a colon-based
+     sexagesimal, we should keep the first two colons and only use the
+     third as a delimiter. */
+  c=str;
+  coloncounter=0;
+  while( *c!='\0' && stlen==0)
+    switch(*c++)
+      {
+      case ':':
+        if(iscolon)
+          { if(++coloncounter == 3) stlen=c-str; }
+        else stlen=c-str;
+        break;
+      case ',': stlen=c-str;
+      }
+
+  /* If 'stlen==0', then we are on the last token, and we can simply use
+     the 'strlen' function, but because we are assuming the last extra
+     character in the loop above, we should add one to 'strlen' to be
+     consistant. */
+  if(stlen==0) stlen=strlen(str)+1;
+
+  /* Copy the string of this sexagesimal coordinate into a new string to
+     pass to the unit conversion function. */
+  copy=gal_pointer_allocate(GAL_TYPE_UINT8, stlen+1, 0, __func__,
+                            "copy");
+  memcpy(copy, str, stlen-1);
+  copy[stlen-1]='\0';
+
+  /* Convert the string to degrees and set the 'tailptr' pointer. */
+  out = ( isra
+          ? gal_units_ra_to_degree(copy)
+          : gal_units_dec_to_degree(copy) );
+  *tailptr=str+stlen-1;
+
+  /* Sanity check: */
+  if(isnan(out))
+    error(EXIT_FAILURE, 0, "%s: '%s' couldn't be parsed as a "
+          "sexagesimal representation of %s", __func__, copy,
+          isra?"RA (right ascension)":"DEC (Declination)");
+
+  /* Clean up, set the 'tailptr' pointer, and return. */
+  free(copy);
+  return out;
+}
+
+
+
+
+
 /* The input to this function is a string of any number of numbers
    separated by a comma (',') and possibly containing fractions, for
    example: '1,2/3, 4.95'. The output 'gal_data_t' contains the array of
@@ -623,7 +766,7 @@ gal_options_parse_list_of_numbers(char *string, char 
*filename, size_t lineno)
   gal_data_t *out;
   char *c=string, *tailptr;
   gal_list_f64_t *list=NULL, *tdll;
-  double numerator=NAN, denominator=NAN, tmp;
+  double numerator=NAN, denominator=NAN, tmp, ttmp;
 
   /* The nature of the arrays/numbers read here is very small, so since
      'p->cp.minmapsize' might not have been read yet, we will set it to -1
@@ -672,23 +815,29 @@ gal_options_parse_list_of_numbers(char *string, char 
*filename, size_t lineno)
         /* Extra dot is an error (cases like 2.5.5). Valid '.'s will be
            read by 'strtod'. */
         case '.':
-          error_at_line(EXIT_FAILURE, 0, filename, lineno, "extra '.' in "
-                        "'%s'", string);
+          error_at_line(EXIT_FAILURE, 0, filename, lineno,
+                        "extra '.' in '%s'", string);
           break;
 
         /* Read the number. */
         default:
 
           /* Parse the string. */
+          ttmp=NAN;
           tmp=strtod(c, &tailptr);
-          if(tailptr==c)
-            error_at_line(EXIT_FAILURE, 0, filename, lineno, "the first "
-                          "part of '%s' couldn't be read as a number. This "
-                          "was part of '%s'", c, string);
+          if(*tailptr!=',' && *tailptr!='/' && *tailptr!='\0')
+            {
+              ttmp=gal_options_read_sexagesimal(num%2, c, &tailptr);
+              if(isnan(ttmp))
+                error_at_line(EXIT_FAILURE, 0, filename, lineno, "the "
+                              "'%s' component of '%s' couldn't be parsed "
+                              "as a usable number", c, string);
+              else tmp=ttmp;
+            }
 
           /* See if the number should be put in the numerator or
              denominator. */
-          if(isnan(numerator)) numerator=tmp;
+          if( isnan(numerator) ) numerator=tmp;
           else
             {
               if(isnan(denominator)) denominator=tmp;
@@ -711,7 +860,6 @@ gal_options_parse_list_of_numbers(char *string, char 
*filename, size_t lineno)
                        ? numerator : numerator/denominator);
     }
 
-
   /* Allocate the output data structure and fill it up. */
   if(num)
     {
@@ -1392,14 +1540,14 @@ gal_data_t *
 gal_options_parse_colon_sep_csv_raw(char *instring, char *filename,
                                     size_t lineno)
 {
-  char *tailptr;
   gal_data_t *out;
-  char *pt=instring;
   size_t dim=0, size;
-  double read, *array;
+  char *pt, *tailptr;
+  double read, sread, *array;
   gal_list_f64_t *vertices=NULL;
 
   /* Parse the string. */
+  pt=instring;
   while(*pt!='\0')
     {
       switch(*pt)
@@ -1415,7 +1563,7 @@ gal_options_parse_colon_sep_csv_raw(char *instring, char 
*filename,
           if(dim==0)
             error_at_line(EXIT_FAILURE, 0, filename, lineno,
                           "not enough coordinates for at least "
-                          "one polygon vertex (in %s)", instring);
+                          "one polygon vertex (in '%s')", instring);
           dim=0;
           ++pt;
           break;
@@ -1452,12 +1600,21 @@ gal_options_parse_colon_sep_csv_raw(char *instring, 
char *filename,
              results, so its best to abort and inform the user. */
           if( *tailptr!='\0'
               && !isspace(*tailptr)
-              && strchr(":,", *tailptr)==NULL )
+              && strchr(":,hd", *tailptr)==NULL )
             error_at_line(EXIT_FAILURE, 0, filename, lineno,
                           "'%s' is an invalid floating point number "
                           "sequence in the value to the '--polygon' "
                           "option, error detected at '%s'", pt, tailptr);
 
+          /* Here we need to check if we are dealing with a sexagesimal
+             string, or just a normal number. If its just a normal
+             number. Note that 'sread' must be initialized to NaN in case
+             'tailptr' is either ',' or '\0'. */
+          sread=NAN;
+          if(*tailptr!=',' && *tailptr!='\0')
+            sread=gal_options_read_sexagesimal(dim, pt, &tailptr);
+          if(!isnan(sread)) read=sread;
+
           /* Add the read coordinate to the list of coordinates. */
           gal_list_f64_add(&vertices, read);
 
diff --git a/lib/units.c b/lib/units.c
index 6a311e5..6b3fad9 100644
--- a/lib/units.c
+++ b/lib/units.c
@@ -263,7 +263,7 @@ gal_units_degree_to_ra(double decimal, int usecolon)
   /* 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,
-                    usecolon ? "%02d:%02d:%g" : "%02dh%02dm%gs",
+                    usecolon ? "%02d:%02d:%g" : "%02dh%02dm%g",
                     hours, minutes, seconds);
   if(nchars>UNITS_RADECSTR_MAXLENGTH)
     error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to address "
@@ -321,7 +321,7 @@ gal_units_degree_to_dec(double decimal, int usecolon)
      with leading zeros if required, in hh:mm:ss format with correct
      sign. */
   nchars = snprintf(dec, UNITS_RADECSTR_MAXLENGTH-1,
-                    usecolon ? "%s%02d:%02d:%g" : "%s%02dd%02dm%gs",
+                    usecolon ? "%s%02d:%02d:%g" : "%s%02dd%02dm%g",
                     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]