gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e59c4bc: Matching in 1D and columns specified


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e59c4bc: Matching in 1D and columns specified in one option call
Date: Sun, 3 Dec 2017 15:17:35 -0500 (EST)

branch: master
commit e59c4bcb8d243eece5a252ec4f855ccc8ffb7a8f
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Matching in 1D and columns specified in one option call
    
    Until now match would only work on 2D positions, but now it also matches 1
    dimensional positions. This can be handy for example when you want to match
    spectral features.
    
    Until now, it was necessary to call `--ccol1' and `--ccol2' multiple times
    to determine the coordinate columns. But this would make it hard to deal
    with possibly many dimensions. Because for a default behavior, other calls
    to these options would be given in a configuration file. It was also
    confusing and buggy to call `--ccol1' and `--ccol2' many times.
    
    So now, the (possibly) multiple column identifiers must be given in a
    comma-separated list and one call to these options. With this change, the
    dimensionality of the match can easily be determined from the value to the
    first column identifier option and it is also possible to have these
    options in a configuration file.
---
 bin/match/args.h        |  14 ++++---
 bin/match/astmatch.conf |   6 +--
 bin/match/main.h        |   4 +-
 bin/match/ui.c          |  93 ++++++++++++++++++++++++-----------------
 doc/gnuastro.texi       | 108 +++++++++++++++++++++++++++---------------------
 lib/match.c             |  97 +++++++++++++++++++++++++++++++------------
 lib/options.c           |  34 +++++++++++----
 7 files changed, 224 insertions(+), 132 deletions(-)

diff --git a/bin/match/args.h b/bin/match/args.h
index 979870f..ab95b57 100644
--- a/bin/match/args.h
+++ b/bin/match/args.h
@@ -76,28 +76,30 @@ struct argp_option program_options[] =
     {
       "ccol1",
       UI_KEY_CCOL1,
-      "STR",
+      "STR[,STR]",
       0,
       "Column name/number of first catalog.",
       UI_GROUP_CATALOGMATCH,
       &p->ccol1,
-      GAL_TYPE_STRLL,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_strings
     },
     {
       "ccol2",
       UI_KEY_CCOL2,
-      "STR",
+      "STR[,STR]",
       0,
       "Column name/number of second catalog.",
       UI_GROUP_CATALOGMATCH,
       &p->ccol2,
-      GAL_TYPE_STRLL,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_strings
     },
     {
       "aperture",
diff --git a/bin/match/astmatch.conf b/bin/match/astmatch.conf
index 5946c69..6506993 100644
--- a/bin/match/astmatch.conf
+++ b/bin/match/astmatch.conf
@@ -21,7 +21,5 @@
  hdu2            1
 
 # Catalog matching
- ccol1           2
- ccol1           3
- ccol2           2
- ccol2           3
\ No newline at end of file
+ ccol1           2,3
+ ccol2           2,3
\ No newline at end of file
diff --git a/bin/match/main.h b/bin/match/main.h
index f0becfe..6d065f7 100644
--- a/bin/match/main.h
+++ b/bin/match/main.h
@@ -53,8 +53,8 @@ struct matchparams
   char            *input1name;  /* First input filename.                */
   char            *input2name;  /* Second input filename.               */
   char                  *hdu2;  /* Second input's HDU.                  */
-  gal_list_str_t       *ccol1;  /* Column names/numbers of first cat.   */
-  gal_list_str_t       *ccol2;  /* Column names/numbers of first cat.   */
+  gal_data_t           *ccol1;  /* Array of firs input column names.    */
+  gal_data_t           *ccol2;  /* Array of second input column names.  */
   gal_data_t        *aperture;  /* Acceptable matching aperture.        */
   uint8_t         logasoutput;  /* Don't rearrange inputs, out is log.  */
 
diff --git a/bin/match/ui.c b/bin/match/ui.c
index 41adc1e..b625545 100644
--- a/bin/match/ui.c
+++ b/bin/match/ui.c
@@ -323,7 +323,7 @@ ui_set_mode(struct matchparams *p)
        p->aperture[1]: Axis ratio.
        p->aperture[2]: Position angle (relative to first dim).     */
 static void
-ui_read_columns_aperture(struct matchparams *p, size_t numcols)
+ui_read_columns_aperture_2d(struct matchparams *p)
 {
   size_t apersize=3;
   gal_data_t *newaper=NULL;
@@ -369,7 +369,7 @@ ui_read_columns_aperture(struct matchparams *p, size_t 
numcols)
       break;
 
     default:
-      error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. This "
+      error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. In 2D, this "
             "option can only take 1, 2, or 3 values", p->aperture->size);
     }
 
@@ -390,49 +390,45 @@ ui_read_columns_aperture(struct matchparams *p, size_t 
numcols)
 static void
 ui_read_columns(struct matchparams *p)
 {
+  size_t i;
+  size_t ccol1n=p->ccol1->size;
+  size_t ccol2n=p->ccol2->size;
+  gal_list_str_t *cols1=NULL, *cols2=NULL;
   struct gal_options_common_params *cp=&p->cp;
-  size_t ccol1n=gal_list_str_number(p->ccol1);
-  size_t ccol2n=gal_list_str_number(p->ccol2);
+  char **strarr1=p->ccol1->array, **strarr2=p->ccol2->array;
   char *diff_cols_error="%s: the number of columns matched (%zu) "
     "differs from the number of usable calls to `--ccol1' (%zu). "
     "Please give more specific values to `--ccol1' (column "
     "numberes are the only identifiers guaranteed to be unique).";
 
-  /* First check the number of columns given. It might happen that extra
-     columns are present in configuration files, so we will only abort if
-     the total number isn't enough. When it is too much, we'll just free
-     the rest of the list.*/
-  if(ccol1n<2 || ccol2n<2)
-    error(EXIT_FAILURE, 0, "at least two coordinate columns from each "
-          "catalog must be given for the match. Please use repeated "
-          "calls to `--ccol1' and `--ccol2' to specify the columns by "
-          "name (if they have one) or number (starting from 1).\n\n"
-          "You can use this command to list the column information of "
-          "a table in the N-th extension/HDU of a FITS file:\n\n"
-          "    $ asttable filename.fits -hN -i\n\n"
-          "For more information on selecting table columns in Gnuastro, "
-          "please run the following command:\n\n"
-          "    $ info gnuastro \"selecting table columns\"\n");
-  else if(ccol1n>2 || ccol2n>2)
-    {
-      if(ccol1n>2)
-        {
-          gal_list_str_free(p->ccol1->next->next, 1);
-          p->ccol1->next->next=NULL;
-          ccol1n=2;             /* Will be used later. */
-        }
-      if(ccol2n>2)
-        {
-          gal_list_str_free(p->ccol2->next->next, 1);
-          p->ccol2->next->next=NULL;
-          ccol2n=2;             /* Will be used later. */
-        }
-    }
+  /* Make sure the same number of columns is given to both. */
+  if(ccol1n!=ccol2n)
+    error(EXIT_FAILURE, 0, "the number of values given to `--ccol1' and "
+          "`--ccol2' (%zu and %zu) are not equal", ccol1n, ccol2n);
 
 
   /* Read/check the aperture values. */
   if(p->aperture)
-    ui_read_columns_aperture(p, ccol1n);
+    switch(ccol1n)
+      {
+      case 1:
+        if(p->aperture->size>1)
+          error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. In a 1D "
+                "match, this option can only take one value",
+                p->aperture->size);
+        break;
+
+      case 2:
+        ui_read_columns_aperture_2d(p);
+        break;
+
+      default:
+
+        error(EXIT_FAILURE, 0, "%zu dimensional matches are not currently "
+              "supported (maximum is 2 dimensions). The number of "
+              "dimensions is deduced from the number of values given to "
+              "`--ccol1' and `--ccol2'", ccol1n);
+      }
   else
     error(EXIT_FAILURE, 0, "no matching aperture specified. Please use "
           "the `--aperture' option to define the acceptable aperture for "
@@ -441,20 +437,32 @@ ui_read_columns(struct matchparams *p)
           "information.\n\n    $ info %s\n", PROGRAM_EXEC);
 
 
+  /* Convert the array of strings to a list of strings for the column
+     names. */
+  for(i=0;i<ccol1n;++i)
+    {
+      gal_list_str_add(&cols1, strarr1[i], 0);
+      gal_list_str_add(&cols2, strarr2[i], 0);
+      strarr1[i]=strarr2[i]=NULL;  /* So they are not freed later. */
+    }
+  gal_list_str_reverse(&cols1);
+  gal_list_str_reverse(&cols2);
+
+
   /* Read the columns. */
   if(cp->searchin)
     {
       /* Read the first dataset. */
-      p->cols1=gal_table_read(p->input1name, cp->hdu, p->ccol1, cp->searchin,
-                              cp->ignorecase, cp->minmapsize);
+      p->cols1=gal_table_read(p->input1name, cp->hdu, cols1,
+                              cp->searchin, cp->ignorecase, cp->minmapsize);
       if(gal_list_data_number(p->cols1)!=ccol1n)
         error(EXIT_FAILURE, 0, diff_cols_error,
               gal_checkset_dataset_name(p->input1name, cp->hdu),
               gal_list_data_number(p->cols1), ccol1n);
 
       /* Read the second dataset. */
-      p->cols2=gal_table_read(p->input2name, p->hdu2, p->ccol2, cp->searchin,
-                              cp->ignorecase, cp->minmapsize);
+      p->cols2=gal_table_read(p->input2name, p->hdu2, cols2,
+                              cp->searchin, cp->ignorecase, cp->minmapsize);
       if(gal_list_data_number(p->cols2)!=ccol2n)
         error(EXIT_FAILURE, 0, diff_cols_error,
               gal_checkset_dataset_name(p->input2name, p->hdu2),
@@ -464,6 +472,13 @@ ui_read_columns(struct matchparams *p)
     error(EXIT_FAILURE, 0, "no `--searchin' option specified. Please run "
           "the following command for more information:\n\n"
           "    $ info gnuastro \"selecting table columns\"\n");
+
+  /* Free the extra spaces. */
+  gal_list_str_free(cols1, 1);
+  gal_list_str_free(cols2, 1);
+  gal_data_free(p->ccol1);
+  gal_data_free(p->ccol2);
+  p->ccol1=p->ccol2=NULL;
 }
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index a806252..b1f63a6 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15605,9 +15605,9 @@ orientation.
 @node Invoking astmatch,  , Match, Match
 @subsection Invoking Match
 
-When given two catalogs, Match find which rows correspond to each other
-given an input aperture. The executable name is @file{astmatch} with the
-following general template
+When given two catalogs, Match finds the rows that are nearest to each
+other within an input aperture. The executable name is @file{astmatch} with
+the following general template
 
 @example
 $ astmatch [OPTION ...] input-1 input-2
@@ -15617,18 +15617,24 @@ $ astmatch [OPTION ...] input-1 input-2
 One line examples:
 
 @example
+## 1D wavelength match (within 5 angestroms) of the two inputs.
+## The wavelengths are in the 5th and 10th columns respectively.
+$ astmatch --aperture=5e-10 --ccol1=5 --ccol2=10 in1.fits in2.txt
+
 ## Match the two catalogs with a circular aperture of width 2.
-## (Units same as given positional columns)
+## (Units same as given positional columns).
+## (By default two columns are given for `--ccol1' and `--ccol2',
+##  The number of values to these determines the dimensionality).
 $ astmatch --aperture=2 input1.txt input2.fits
 
 ## Match the two catalogs within an elliptical aperture of 1 and 2
 ## arcseconds along RA and Dec respectively.
 $ astmatch --aperture=1/3600,2/3600 in1.fits in2.txt
 
-## Match the RA and DEC columns of the two inputs within an
-## aperture of 0.5 arcseconds.
-$ astmatch --aperture0.5/3600 in1.fits in2.fits             \
-           --ccol1=RA --ccol1=DEC --ccol2=RA --ccol2=DEC
+## Match the RA and DEC columns of the first input with the RA_D
+## and DEC_D columns of the second within a 0.5 arcseconds aperture.
+$ astmatch --ccol1=RA,DEC --ccol2=RA_D,DEC_D --aperture0.5/3600  \
+           in1.fits in2.fits
 @end example
 
 Two inputs are necessary for Match to start processing. The inputs can be
@@ -15637,38 +15643,39 @@ is not called, Match will print the number of matches 
found in standard
 output (on the command-line). If no match was found, no output file will be
 created (table or log file). When matches are found, the output file(s)
 will be the re-arranged input tables such that the rows match each other:
-both output tables will have the same number of rows which are matched. If
-the @option{--logasoutput} option is called, the output will be a single
-table with the contents of the log file, see below.
+both output tables will have the same number of rows which are matched with
+each other. If the @option{--logasoutput} option is called, the output will
+be a single table with the contents of the log file, see below.
 
 Match follows the same basic behavior of all Gnuastro programs as fully
 described in @ref{Common program behavior}. If the first input is a FITS
 file, the common @option{--hdu} option (see @ref{Input output options})
-should be used to identify the extension. For the second input, the
-extension can be specified with @option{--hdu2}.
-
-When the @option{--log} option is called (see @ref{Operating mode
-options}), Match will also create a file named @file{astmatch.log} in the
-directory it is run in. This log table will have three columns. The first
-and second column shows the rows/record number (counting from 1) of the
-first and second input catalogs respectively. The third column is the
-distance between the two matched positions. The units of this distance are
-the same as the given coordinates. When @option{--logasoutput} is called,
-no log file (with a fixed name) will be created. In this case, the output
-file (possibly given by the @option{--output} option) will have the
-contents of this log file.
+should be used to identify the extension. When the second input is FITS,
+the extension can be specified with @option{--hdu2}.
 
 If no output file name is given with the @option{--output} option, then
 automatic output @ref{Automatic output} will be used to determine the
 output names. Depending on @option{--tableformat} (see @ref{Input output
-options}), the output will then be a FITS table or a plain text table.
+options}), the output will then be a multi-extension FITS file or two plain
+text files.
 
-When the output name is a FITS file, and @option{--logasoutput} is not
-called, the re-arranged inputs will be two extensions of the output FITS
-file. If the output name is a text file, then two files will be created
-with a @file{_matched_1.txt} and @file{_matched_2.txt} suffix.
+When @option{--output} is a FITS file (and @option{--logasoutput} is not
+called, see below), the re-arranged inputs will be two extensions of the
+output FITS file. If the output name is a text file, then two files will be
+created with a @file{_matched_1.txt} and @file{_matched_2.txt} suffix.
 
-If there is no match could be found
+When the @option{--log} option is called (see @ref{Operating mode
+options}), Match will also create a file named @file{astmatch.fits} (or
address@hidden, depending on @option{--tableformat}, see @ref{Input
+output options}) in the directory it is run in. This log table will have
+three columns. The first and second columns show the matching row/record
+number (counting from 1) of the first and second input catalogs
+respectively. The third column is the distance between the two matched
+positions. The units of the distance are the same as the given coordinates
+(given the possible ellipticity, see description of @option{--aperture}
+below). When @option{--logasoutput} is called, no log file (with a fixed
+name) will be created. In this case, the output file (possibly given by the
address@hidden option) will have the contents of this log file.
 
 @table @option
 @item -H STR
@@ -15685,32 +15692,36 @@ description above. When this option is called, a log 
file called
 @file{astmatch.txt} will not be created. With this option, the default
 output behavior (two tables containing the re-arranged inputs) will be
 
address@hidden --ccol1=INT/STR
-The coordinate column of the first input. This option must be called
-multiple times to specify all the coordinate columns of the first
-input.
-
-For example, to match the RA and Dec columns of the first catalog with the
-same named columns of the second, you need to call this option (along with
address@hidden) two times:
-
address@hidden
-$ astmatch --ccol1=RA --ccol1=DEC --ccol2=RA --ccol2=DEC   \
-           input-1.fits input-2.fits
address@hidden example
address@hidden --ccol1=INT/STR[,INT/STR]
+The coordinate columns of the first input. The number of dimensions for the
+match is determined by the number of comma-separated values given to this
+option. The values can be the column number (counting from 1), exact column
+name or a regular expression. For more, see @ref{Selecting table
+columns}. See the one-line examples above for some usages of this option.
 
 @item --ccol2=INT/STR
-The coordinate column of the second input. This option must be called
-multiple times to specify all the coordinate columns of the second
-input. See the example in @option{--ccol1} for more.
+The coordinate columns of the second input. See the example in
address@hidden for more.
 
 @item -a FLT[,FLT[,FLT]]
 @itemx --aperture=FLT[,FLT[,FLT]]
 Parameters of the aperture for matching. The values given to this option
-can be fractions, for example @option{1/3600} can be used to ask for one
-arcsecond. The interpretation of the values depends on how many are given:
+can be fractions, for example when the position columns are in units of
+degrees, @option{1/3600} can be used to ask for one arcsecond. The
+interpretation of the values depends on the requested dimensionality
+(determined from @option{--ccol1} and @code{--ccol2}) and how many values
+are given to this option.
 
 @table @asis
address@hidden 1D match
+The aperture/interval can only take one value: half of the interval around
+each point (maximum distance from each point).
+
address@hidden 2D match
+In a 2D match, the aperture can be a circle, an ellipse aligned in the axes
+or an ellipse with a rotated major axis. To simply the usage, you can
+determine the shape based on the number of free parameters for each.
address@hidden @asis
 @item 1 number
 For example @option{--aperture=2}. The aperture will be a circle of the
 given radius. The value will be in the same units as the columns in
@@ -15736,6 +15747,7 @@ degrees). If multiple matches are found within the 
ellipse, the distance
 space, see @ref{Defining an ellipse}.
 @end table
 @end table
address@hidden table
 
 
 
diff --git a/lib/match.c b/lib/match.c
index f2a60d4..17de927 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -159,10 +159,10 @@ match_coordinaes_sanity_check(gal_data_t *coord1, 
gal_data_t *coord2,
 
 
   /* This function currently only works for 2 dimensions. */
-  if(ncoord1!=2)
-    error(EXIT_FAILURE, 0, "%s: inputs correspond to %zu dimensions, this "
-          "function currently only works on 2 dimensional datasets",
-          __func__, ncoord1);
+  if(ncoord1>2)
+    error(EXIT_FAILURE, 0, "%s: %zu dimension matching requested, this "
+          "function currently only matches datasets with a maximum of 2 "
+          "dimensions", __func__, ncoord1);
 
   /* Check the column properties. */
   match_coordinate_sanity_check_columns(coord1, "first");
@@ -170,13 +170,13 @@ match_coordinaes_sanity_check(gal_data_t *coord1, 
gal_data_t *coord2,
 
   /* Check the aperture values. */
   if(aperture[0]<=0)
-    error(EXIT_FAILURE, 0, "%s: the first value in the aperture (%g) is the "
-          "semi-major axis and thus not be zero or negative", __func__,
-          aperture[0]);
-  if(aperture[1]<=0 || aperture[1]>1)
-    error(EXIT_FAILURE, 0, "%s: the second value in the aperture (%g) is "
-          "the axis ratio, so it must be larger than zero and less than 1",
-          __func__, aperture[1]);
+    error(EXIT_FAILURE, 0, "%s: the first value in the aperture (%g) cannot "
+          "be zero or negative", __func__, aperture[0]);
+  if(ncoord1==2)
+    if(aperture[1]<=0 || aperture[1]>1)
+      error(EXIT_FAILURE, 0, "%s: the second value in the aperture (%g) "
+            "is the axis ratio, so it must be larger than zero and less "
+            "than 1", __func__, aperture[1]);
 }
 
 
@@ -289,8 +289,8 @@ match_coordinates_prepare(gal_data_t *coord1, gal_data_t 
*coord2,
 /*************            Coordinate matching           *************/
 /********************************************************************/
 static double
-match_coordinates_elliptical_r(double d1, double d2, double *ellipse,
-                               double c, double s)
+match_coordinates_elliptical_r_2d(double d1, double d2, double *ellipse,
+                                  double c, double s)
 {
   double Xr = d1 * ( c       )     +   d2 * ( s );
   double Yr = d1 * ( -1.0f*s )     +   d2 * ( c );
@@ -301,6 +301,39 @@ match_coordinates_elliptical_r(double d1, double d2, 
double *ellipse,
 
 
 
+static double
+match_coordinates_distance(double *delta, int iscircle, size_t ndim,
+                           double *aperture, double c, double s)
+{
+  /* In a one dimensional case, the distance is just the absolute value of
+     delta[0]. */
+  if(ndim==1) return fabs(delta[0]);
+
+  /* For more than one dimension, we'll need to calculate the distance from
+     the deltas (differences) in each dimension. */
+  switch(ndim)
+    {
+    case 2:
+      return ( iscircle
+               ? sqrt( delta[0]*delta[0] + delta[1]*delta[1] )
+               : match_coordinates_elliptical_r_2d(delta[0], delta[1],
+                                                   aperture, c, s) );
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+            "the problem. The value %zu is not recognized for ndim",
+            __func__, PACKAGE_BUGREPORT, ndim);
+    }
+
+  /* Control should not reach this point. */
+  error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
+        "problem. Control should not reach the end of this function",
+        __func__, PACKAGE_BUGREPORT);
+  return NAN;
+}
+
+
+
+
 
 /* Go through both catalogs and find which records/rows in the second
    catalog (catalog b) are within the acceptable distance of each record in
@@ -314,15 +347,28 @@ match_coordinates_second_in_first(gal_data_t *A, 
gal_data_t *B,
      with an `a' and things related to catalog 2 are marked with a `b'. The
      redundant variables (those that equal a previous value) are only
      defined to make it easy to read the code.*/
-  double r, c, s, dist[2];
-  size_t ar=A->size, br=B->size;
+  int iscircle=0;
+  double delta[2];
+  double r, c=NAN, s=NAN, dist[2];
   size_t ai, bi, blow, prevblow=0;
-  int iscircle=aperture[1]==1 ? 1 : 0;
-  double *a[2]={A->array, A->next->array};
-  double *b[2]={B->array, B->next->array};
+  size_t i, ar=A->size, br=B->size;
+  size_t ndim=gal_list_data_number(A);
+  double *a[2]={A->array, A->next ? A->next->array : NULL};
+  double *b[2]={B->array, B->next ? B->next->array : NULL};
+
+  /* See if the aperture is a circle or not. */
+  switch(ndim)
+    {
+    case 1: iscircle = 0; /* Irrelevant for 1D. */  break;
+    case 2: iscircle = aperture[1]==1 ? 1 : 0;      break;
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+            "the problem. The value %zu is not recognized for ndim",
+            __func__, PACKAGE_BUGREPORT, ndim);
+    }
 
   /* Preparations for the shape of the aperture. */
-  if(iscircle)
+  if(ndim==1 || iscircle)
     dist[0]=dist[1]=aperture[0];
   else
     {
@@ -384,7 +430,9 @@ match_coordinates_second_in_first(gal_data_t *A, gal_data_t 
*B,
             axis coordinates have EXACTLY the same floating point
             value as each other to easily define an independent
             sorting in the second axis. */
-         if( b[1][bi] >= a[1][ai]-dist[1] && b[1][bi] <= a[1][ai]+dist[1] )
+         if( ndim==1
+              || ( b[1][bi] >= a[1][ai]-dist[1]
+                   && b[1][bi] <= a[1][ai]+dist[1] ) )
            {
              /* Now, `bi' is within the rectangular range of `ai'. But
                 this is not enough to consider the two objects matched for
@@ -414,12 +462,9 @@ match_coordinates_second_in_first(gal_data_t *A, 
gal_data_t *B,
 
                 The next two problems will be solved with the list after
                 parsing of the whole catalog is complete.*/
-              r = ( iscircle
-                    ? sqrt( (b[0][bi]-a[0][ai])*(b[0][bi]-a[0][ai])
-                            + (b[1][bi]-a[1][ai])*(b[1][bi]-a[1][ai]) )
-                    : match_coordinates_elliptical_r(b[0][bi]-a[0][ai],
-                                                     b[1][bi]-a[1][ai],
-                                                     aperture, c, s));
+              for(i=0;i<ndim;++i) delta[i]=b[i][bi]-a[i][ai];
+              r=match_coordinates_distance(delta, iscircle, ndim, aperture,
+                                           c, s);
              if(r<aperture[0])
                match_coordinate_add_to_sfll(&bina[ai], bi, r);
            }
diff --git a/lib/options.c b/lib/options.c
index 2f5d893..01dd1c0 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -618,15 +618,15 @@ gal_options_parse_csv_strings_raw(char *string, char 
*filename, size_t lineno)
 
 /* `arg' is the value given to an option. It contains multiple strings
    separated by a comma (`,'). This function will parse `arg' and make a
-   `gal_data_t' that contains all the strings separately. The output
-   `gal_data_t' will be put in `option->value'. */
+   `gal_data_t' array of strings from it. The output `gal_data_t' will be
+   put in `option->value'. */
 void *
 gal_options_parse_csv_strings(struct argp_option *option, char *arg,
                               char *filename, size_t lineno, void *junk)
 {
-  int i;
   size_t nc;
-  char **strarr;
+  char *c, **strarr;
+  int i, has_space=0;
   gal_data_t *values;
   char *str, sstr[GAL_OPTIONS_STATIC_MEM_FOR_VALUES];
 
@@ -636,10 +636,26 @@ gal_options_parse_csv_strings(struct argp_option *option, 
char *arg,
       /* Set the pointer to the values dataset. */
       values = *(gal_data_t **)(option->value);
 
-      /* Write each string into the output string */
-      nc=0;
+      /* See if there are any space characters in the final string. */
       strarr=values->array;
       for(i=0;i<values->size;++i)
+        if(has_space==0)
+        {
+          for(c=strarr[i];*c!='\0';++c)
+            if(*c==' ' || *c=='\t')
+              {
+                has_space=1;
+                break;
+              }
+        }
+
+      /* If there is a space, the string must start wth quotation marks. */
+      nc = has_space ? 1 : 0;
+      if(has_space) {sstr[0]='"'; sstr[1]='\0';}
+
+
+      /* Write each string into the output string */
+      for(i=0;i<values->size;++i)
         {
           if( nc > GAL_OPTIONS_STATIC_MEM_FOR_VALUES-100 )
             error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s so we "
@@ -649,7 +665,11 @@ gal_options_parse_csv_strings(struct argp_option *option, 
char *arg,
                   GAL_OPTIONS_STATIC_MEM_FOR_VALUES);
           nc += sprintf(sstr+nc, "%s,", strarr[i]);
         }
-      sstr[nc-1]='\0';
+
+      /* If there was a space, we need a quotation mark at the end of the
+         string. */
+      if(has_space) { sstr[nc-1]='"'; sstr[nc]='\0'; }
+      else            sstr[nc-1]='\0';
 
       /* Copy the string into a dynamically allocated space, because it
          will be freed later.*/



reply via email to

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