gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master ac2a821 103/113: Imported recent work in maste


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master ac2a821 103/113: Imported recent work in master, conflicts fixed
Date: Fri, 16 Apr 2021 10:34:00 -0400 (EDT)

branch: master
commit ac2a8218dad0ff94fbc43a00d4c44f2e79672e3a
Merge: b3416de 95d7fc5
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Imported recent work in master, conflicts fixed
    
    Several conflicts came up during the merging of Match and they were fixed.
---
 NEWS                               |  24 ++-
 THANKS                             |   1 +
 bin/arithmetic/arithmetic.c        |  18 +-
 bin/cosmiccal/ui.c                 |   1 -
 bin/crop/main.h                    |   3 +-
 bin/crop/onecrop.c                 |  11 +-
 bin/crop/ui.c                      |   5 +-
 bin/gnuastro.conf                  |   1 +
 bin/match/args.h                   |  14 ++
 bin/match/astmatch.conf            |   4 +-
 bin/match/main.h                   |   3 +-
 bin/match/match.c                  |  99 ++++++++--
 bin/match/ui.c                     | 361 +++++++++++++++++++++++++------------
 bin/match/ui.h                     |   3 +-
 bin/mkprof/ui.c                    |  19 ++
 bin/noisechisel/threshold.c        |   5 +-
 bin/noisechisel/ui.c               |   1 +
 bin/statistics/sky.c               |   5 +-
 bin/statistics/statistics.c        |   1 +
 bin/statistics/ui.c                |   8 +-
 doc/announce-acknowledge.txt       |   1 +
 doc/gnuastro.texi                  | 121 ++++++++++---
 lib/arithmetic.c                   |  91 ++++++++--
 lib/dimension.c                    |  14 +-
 lib/gnuastro-internal/commonopts.h |  16 +-
 lib/gnuastro-internal/options.h    |   6 +
 lib/gnuastro/dimension.h           |   5 +-
 lib/gnuastro/interpolate.h         |  17 +-
 lib/gnuastro/type.h                |   3 +
 lib/interpolate.c                  |  32 +++-
 lib/options.c                      |  50 +++++
 lib/type.c                         |  24 ++-
 tests/match/merged-cols.sh         |   4 +-
 tests/match/positions.sh           |   4 +-
 34 files changed, 758 insertions(+), 217 deletions(-)

diff --git a/NEWS b/NEWS
index ab729be..29a09bc 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,9 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
      different file for reading the WCS of the output. This is useful when
      the default (theh WCS of the first dataset that is read) is not the
      required one.
+   --interpmetric: new option that is necessary with the
+     `interpolate-medianngb' operator. For more, see the description of
+     this option in NoiseChisel.
 
   Fits:
    - Add "title" to group FITS keywords with `--write=/,"title name". This
@@ -49,9 +52,21 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
      contain all the columns from the first input and the 5th column of the
      second input. This greatly simplifies the mergining of different table
      columns into one.
+   --coord: manually specify coordinates to match on the
+     command-line. Until now, if you only wanted to make check a specific
+     coordinate's matching with a catalog. It was necessary to make a
+     single-row catalog as a file and feed that into Match. With this
+     option, you can now specify the coordinates to match against another
+     catalog with the command-line.
 
   NoiseChisel:
-
+   --interpmetric: Set the metric to use to identify the nearest neighbors
+     for tile interpolation (quantile threshold, initial Sky, and final
+     Sky). Until now only the manhattan/taxicab metric was available, which
+     is fast, but could cause 45-degree lines in the interpolation. From
+     this version, with this option, its also possible to use the radial
+     distance (which is now the default). Just note that if there are many
+     tiles over the image, the radial distance will be slower.
    --snthresh: Manually set the signal-to-noise ratio of true
      pseudo-detections. With this option, NoiseChisel will not attempt to
      find pseudo-detections over the noisy regions of the dataset, but will
@@ -67,12 +82,17 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
      --dopening: The number of openings to do after applying `--dthresh'.
      --dopeningngb: The connectivity (4 or 8) to use for `--dopening'.
 
+  Statistics:
+   --interpmetric: Similar to NoiseChisel.
+
   Library:
     GAL_BLANK_LONG: new macro for the `long' type blank value.
     GAL_BLANK_ULONG: new macro for the `unsigned long' type blank value.
     gal_blank_number: Return the number of blank elements in a dataset.
+    gal_dimension_dist_radial: Radial distance between two coordinates.
     gal_statistics_outlier_cumulative: Uses flatness of the cumulative
        distribution to find outliers.
+    gal_type_is_int: to see if we have an integer (any width, any sign).
 
 ** Removed features
 
@@ -117,6 +137,8 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
   bug #55478: Memory mapping crashes when .gnuastro is not writable.
   bug #55491: NoiseChisel crash when no tiles good for quantile thresholding.
   bug #55544: Arithmetic's output WCS with where operator is not as expected.
+  bug #55740: Diamond shapes in nearst-ngb interpolation affecting NoiseChisel.
+  bug #55763: Crop not keeping Blank pixels on unsigned types.
 
 
 
diff --git a/THANKS b/THANKS
index 6f34d21..c803745 100644
--- a/THANKS
+++ b/THANKS
@@ -18,6 +18,7 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Valentina Abril-melgarejo            valentina.abril@lam.fr
     Marjan Akbari                        mrjakbari@gmail.com
     Roland Bacon                         roland.bacon@univ-lyon1.fr
+    Roberto Baena Gallé                  rbaena@iac.es
     Karl Berry                           karl@gnu.org
     Leindert Boogaard                    boogaard@strw.leidenuniv.nl
     Nicolas Bouché                       nicolas.bouche@irap.omp.eu
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 68e3912..b221ce9 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -728,8 +728,9 @@ arithmetic_interpolate(struct arithmeticparams *p, char 
*token)
   num_int = *((int32_t *)(num->array));
 
   /* Call the interpolation function. */
-  interpolated=gal_interpolate_close_neighbors(in, NULL, num_int,
-                                               p->cp.numthreads, 1, 0);
+  interpolated=gal_interpolate_close_neighbors(in, NULL, p->cp.interpmetric,
+                                               num_int, p->cp.numthreads,
+                                               1, 0);
 
   /* Clean up and push the interpolated array onto the stack. */
   gal_data_free(in);
@@ -904,9 +905,9 @@ void
 reversepolish(struct arithmeticparams *p)
 {
   int op=0, nop=0;
-  char *filename, *hdu;
   unsigned int numop, i;
   gal_list_str_t *token;
+  char *hdu, *filename, *printnum;
   gal_data_t *d1=NULL, *d2=NULL, *d3=NULL;
   int flags = ( GAL_ARITHMETIC_INPLACE | GAL_ARITHMETIC_FREE
                 | GAL_ARITHMETIC_NUMOK );
@@ -1255,11 +1256,12 @@ reversepolish(struct arithmeticparams *p)
   d1=p->operands->data;
   if(d1->size==1)
     {
-      /* To simplify the printing process, we will first change it to
-         double, then use printf's `%g' to print it, so integers will be
-         printed as an integer.  */
-      d2=gal_data_copy_to_new_type(d1, GAL_TYPE_FLOAT64);
-      printf("%g\n", *(double *)d2->array);
+      /* Make the string to print the number. */
+      printnum=gal_type_to_string(d1->array, d1->type, 0);
+      printf("%s\n", printnum);
+
+      /* Clean up. */
+      free(printnum);
       if(d2!=d1) gal_data_free(d2);
     }
   else
diff --git a/bin/cosmiccal/ui.c b/bin/cosmiccal/ui.c
index 4b6263f..e52842b 100644
--- a/bin/cosmiccal/ui.c
+++ b/bin/cosmiccal/ui.c
@@ -135,7 +135,6 @@ ui_initialize_options(struct cosmiccalparams *p,
         case GAL_OPTIONS_KEY_QUIET:
         case GAL_OPTIONS_KEY_SEARCHIN:
         case GAL_OPTIONS_KEY_NUMTHREADS:
-        case GAL_OPTIONS_KEY_MINMAPSIZE:
         case GAL_OPTIONS_KEY_IGNORECASE:
         case GAL_OPTIONS_KEY_TABLEFORMAT:
         case GAL_OPTIONS_KEY_STDINTIMEOUT:
diff --git a/bin/crop/main.h b/bin/crop/main.h
index e60d1cc..528645e 100644
--- a/bin/crop/main.h
+++ b/bin/crop/main.h
@@ -112,7 +112,8 @@ struct cropparams
   time_t               rawtime;  /* Starting time of the program.         */
   int            outnameisfile;  /* Output filename is a directory.       */
   int                     type;  /* Type of output(s).                    */
-  void                 *bitnul;  /* Null value for this data-type.        */
+  void           *blankptrread;  /* Null value for reading of output type.*/
+  void          *blankptrwrite;  /* Null value for writing of output type.*/
   struct inputimgs       *imgs;  /* WCS and size information for inputs.  */
   gal_data_t              *log;  /* Log file contents.                    */
 };
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index 4e14bc8..55c85cd 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -642,7 +642,7 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
 
   /* When CFITSIO creates a FITS extension it adds two comments linking to
      the FITS paper. Since we are mentioning the version of CFITSIO and
-     only use its ruitines to read/write from/to FITS files, this is
+     only use its routines to read/write from/to FITS files, this is
      redundant. If `status!=0', then `gal_fits_io_error' will abort, but in
      case CFITSIO doesn't write the comments, status will become
      non-zero. So we are resetting it to zero after these (because not
@@ -671,7 +671,8 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
   /* Write the blank value as a FITS keyword if necessary. */
   if( type!=GAL_TYPE_FLOAT32 && type!=GAL_TYPE_FLOAT64 )
     if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
-                      crp->p->bitnul, "pixels with no data", &status) )
+                      crp->p->blankptrwrite, "Pixels with no data.",
+                      &status) )
       gal_fits_io_error(status, "adding Blank");
   totsize = naxes[0]*naxes[1] * (ndim==3?naxes[2]:1);
   if(fits_write_null_img(ofp, 1, totsize, &status))
@@ -774,7 +775,7 @@ onecrop(struct onecropparams *crp)
       for(i=0;i<ndim;++i) cropsize *= ( lpixel_i[i] - fpixel_i[i] + 1 );
       array=gal_pointer_allocate(p->type, cropsize, 0, __func__, "array");
       if(fits_read_subset(ifp, gal_fits_type_to_datatype(p->type),
-                          fpixel_i, lpixel_i, inc, p->bitnul, array,
+                          fpixel_i, lpixel_i, inc, p->blankptrread, array,
                           &anynul, &status))
         gal_fits_io_error(status, NULL);
 
@@ -928,8 +929,8 @@ onecrop_center_filled(struct onecropparams *crp)
   /* Allocate the array and read in the pixels. */
   array=gal_pointer_allocate(type, size, 0, __func__, "array");
   if( fits_read_subset(ofp, gal_fits_type_to_datatype(type), fpixel, lpixel,
-                       inc, p->bitnul, array, &anynul, &status) )
-     gal_fits_io_error(status, NULL);
+                       inc, p->blankptrread, array, &anynul, &status) )
+    gal_fits_io_error(status, NULL);
   free(array);
 
   /* CFITSIO already checks if there are any blank pixels. If there are,
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index d0c9555..2a00410 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -895,7 +895,8 @@ ui_preparations(struct cropparams *p)
           /* Set the basic information. */
           firsttype = p->type;
           firstndim = img->ndim;
-          p->bitnul = gal_fits_key_img_blank(p->type);
+          p->blankptrread  = gal_blank_alloc_write(p->type);
+          p->blankptrwrite = gal_fits_key_img_blank(p->type);
 
           /* Make sure the number of dimensions is supported. */
           if(firstndim>MAXDIM)
@@ -1090,6 +1091,8 @@ ui_free_report(struct cropparams *p, struct timeval *t1)
   size_t i;
 
   /* Free the simple arrays (if they were set). */
+  free(p->blankptrread);
+  free(p->blankptrwrite);
   gal_data_free(p->center);
   if(p->cp.hdu) free(p->cp.hdu);
   if(p->cathdu) free(p->cathdu);
diff --git a/bin/gnuastro.conf b/bin/gnuastro.conf
index 3652e6a..a901b99 100644
--- a/bin/gnuastro.conf
+++ b/bin/gnuastro.conf
@@ -28,6 +28,7 @@
  numchannels      1,1
  remainderfrac    0.1
  workoverch       0
+ interpmetric     radial
  interpnumngb     9
  interponlyblank  0
 
diff --git a/bin/match/args.h b/bin/match/args.h
index 512d7aa..5dd2424 100644
--- a/bin/match/args.h
+++ b/bin/match/args.h
@@ -129,6 +129,20 @@ struct argp_option program_options[] =
       gal_options_parse_csv_strings
     },
     {
+      "coord",
+      UI_KEY_COORD,
+      "FLT[,FLT]",
+      0,
+      "Manually input coordiantes.",
+      UI_GROUP_CATALOGMATCH,
+      &p->coord,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_float64
+    },
+    {
       "aperture",
       UI_KEY_APERTURE,
       "FLT[,...]",
diff --git a/bin/match/astmatch.conf b/bin/match/astmatch.conf
index 6506993..85a90ec 100644
--- a/bin/match/astmatch.conf
+++ b/bin/match/astmatch.conf
@@ -20,6 +20,4 @@
 # Input
  hdu2            1
 
-# Catalog matching
- ccol1           2,3
- ccol2           2,3
\ No newline at end of file
+# Catalog matching
\ No newline at end of file
diff --git a/bin/match/main.h b/bin/match/main.h
index f9a5a85..1e776a6 100644
--- a/bin/match/main.h
+++ b/bin/match/main.h
@@ -53,8 +53,9 @@ struct matchparams
   char            *input1name;  /* First input filename.                */
   char            *input2name;  /* Second input filename.               */
   char                  *hdu2;  /* Second input's HDU.                  */
-  gal_data_t           *ccol1;  /* Array of firs input column names.    */
+  gal_data_t           *ccol1;  /* Array of first input column names.   */
   gal_data_t           *ccol2;  /* Array of second input column names.  */
+  gal_data_t           *coord;  /* Array of manual coordinate values.   */
   gal_data_t         *outcols;  /* 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/match.c b/bin/match/match.c
index 94132a1..e32a74b 100644
--- a/bin/match/match.c
+++ b/bin/match/match.c
@@ -97,6 +97,57 @@ match_add_all_cols(char *filename, char *extname, 
gal_list_str_t *stdinlines,
 
 
 
+static gal_data_t *
+match_cat_from_coord(struct matchparams *p, gal_list_str_t *cols,
+                     size_t *numcolmatch)
+{
+  void *rptr;
+  gal_list_str_t *col;
+  uint8_t read, readtype;
+  size_t colcounter, counter;
+  gal_data_t *tmp, *ttmp, *out=NULL;
+
+  /* Go over the desired columns and only return the good ones. */
+  colcounter=0;
+  for(col=cols;col!=NULL;col=col->next)
+    {
+      /* In `ui_preparations_out_cols', we have done the necessary sanity
+         checks, so we can safely use the values. */
+      rptr=gal_type_string_to_number(col->v, &readtype);
+      if(readtype!=GAL_TYPE_UINT8)
+        error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+              "the problem. The given string didn't have a `uint8' type",
+              __func__, PACKAGE_BUGREPORT);
+      read=*((uint8_t *)rptr);
+
+      /* Find the proper column in the second input's columns. Just note
+         that column counting starts from 1.*/
+      counter=1;
+      for(tmp=p->cols2;tmp!=NULL;tmp=tmp->next)
+        if(counter++ == read)
+          {
+            ttmp=gal_data_copy(tmp);
+            ttmp->next=NULL;
+            gal_list_data_add(&out, ttmp);
+            ++numcolmatch[colcounter];
+            break;
+          }
+
+      /* Increment the column counter. */
+      ++colcounter;
+    }
+
+  /* Reverse the list. */
+  gal_list_data_reverse(&out);
+
+  /* Return the output columns. */
+  return out;
+}
+
+
+
+
+
 /* Read the catalog in the given file and use the given permutation to keep
    the proper columns. */
 static gal_data_t *
@@ -143,18 +194,21 @@ match_catalog_read_write_all(struct matchparams *p, 
size_t *permutation,
       /* When the output contains columns from both inputs, we need to keep
          the number of columns matched against each column identifier. */
       *numcolmatch=gal_pointer_allocate(GAL_TYPE_SIZE_T,
-                                        gal_list_str_number(cols), 0,
+                                        gal_list_str_number(cols), 1,
                                         __func__, "numcolmatch");
     }
   else cols=incols;
 
 
-  /* Read the full table and free the `cols' array if it was allocated
-     here. */
-  cat=gal_table_read(filename, hdu, filename ? NULL : p->stdinlines, cols,
-                     p->cp.searchin, p->cp.ignorecase, p->cp.minmapsize,
-                     *numcolmatch);
-  origsize=cat->size;
+  /* Read the full table. NOTE that with `--coord', for the second input,
+     both `filename' and `p->stdinlines' will be NULL. */
+  if(filename || p->stdinlines)
+    cat=gal_table_read(filename, hdu, filename ? NULL : p->stdinlines, cols,
+                       p->cp.searchin, p->cp.ignorecase, p->cp.minmapsize,
+                       *numcolmatch);
+  else
+    cat=match_cat_from_coord(p, cols, *numcolmatch);
+  origsize = cat ? cat->size : 0;
 
 
   /* Go over each column and permute its contents. */
@@ -198,10 +252,11 @@ match_catalog_read_write_all(struct matchparams *p, 
size_t *permutation,
           }
       }
 
+
   /* Write the catalog to the output. */
   if(p->outcols)
     return cat;
-  else
+  else if(cat)
     {
       /* Write the catalog to a file. */
       gal_table_write(cat, NULL, p->cp.tableformat, outname, extname, 0);
@@ -227,8 +282,9 @@ match_catalog_read_write_all(struct matchparams *p, size_t 
*permutation,
 
       /* Clean up. */
       gal_list_data_free(cat);
-      return NULL;
     }
+
+  return NULL;
 }
 
 
@@ -380,7 +436,14 @@ match_catalog(struct matchparams *p)
 
   /* Print the number of matches if not in quiet mode. */
   if(!p->cp.quiet)
-    fprintf(stdout, "%zu\n", nummatched);
+    {
+      fprintf(stdout, "Number of maching rows in both catalogs: %zu\n",
+              nummatched);
+      if(p->out2name && strcmp(p->out1name, p->out2name))
+        fprintf(stdout, "Output:\n %s\n %s", p->out1name, p->out2name);
+      else
+        fprintf(stdout, "Output: %s\n", p->out1name);
+    }
 }
 
 
@@ -409,8 +472,16 @@ void
 match(struct matchparams *p)
 {
   /* Do the correct type of matching. */
-  if(p->mode==MATCH_MODE_CATALOG)
-    match_catalog(p);
+  switch(p->mode)
+    {
+    case MATCH_MODE_CATALOG: match_catalog(p); break;
+    case MATCH_MODE_WCS:
+      error(EXIT_FAILURE, 0, "matching by WCS is not yet supported");
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s to fix "
+            "the problem: %d is not a recognized mode",
+            __func__, PACKAGE_BUGREPORT, p->mode);
+    }
 
   /* Write Match's configuration as keywords into the first extension of
      the output. */
@@ -420,7 +491,9 @@ match(struct matchparams *p)
                                               ? p->input1name
                                               : "Standard input" ),
                                   &p->cp.okeys, 1);
-      gal_fits_key_write_filename("input2", p->input2name, &p->cp.okeys, 1);
+      gal_fits_key_write_filename("input2",
+                                  p->input2name?p->input2name:"--coord",
+                                  &p->cp.okeys, 1);
       gal_fits_key_write_config(&p->cp.okeys, "Match configuration",
                                 "MATCH-CONFIG", p->out1name, "0");
     }
diff --git a/bin/match/ui.c b/bin/match/ui.c
index df1fb9b..af1206e 100644
--- a/bin/match/ui.c
+++ b/bin/match/ui.c
@@ -224,24 +224,45 @@ ui_read_check_only_options(struct matchparams *p)
 
 
 
-
+/* Two necessary catalogs: First:  Standard input, or a file.
+                           Second: `--coord',      or a file.
+ */
 static void
 ui_check_options_and_arguments(struct matchparams *p)
 {
-  /* The first input might come from the standard input, in that case, the
-     second input's name is stored in `input1name' and `input2name' will be
-     left to NULL. So we'll first correct for this. */
-  if(p->input1name)
+  /* When `--coord' is given, there should be no second catalog
+     (argument). */
+  if(p->coord)
+    {
+      /* Make sure no second argument is given. */
+      if(p->input2name)
+        error(EXIT_FAILURE, 0, "only one argument can be given with the "
+              "`--coord' option");
+
+      /* No need for `p->input2name' or `p->ccol2'. */
+      gal_data_free(p->ccol2);
+      p->ccol2=NULL;
+    }
+
+  /* `--coord' is not given. */
+  else
     {
+      /* Without `coord' atleast one input is necessary. */
+      if(p->input1name==NULL)
+        error(EXIT_FAILURE, 0, "no inputs!\n\n"
+              "Two inputs are necessary. The first can be a file, or from "
+              "the standard input (e.g., a pipe). The second can be a "
+              "file, or its coordinates can be directly specified on the "
+              "command-line with `--coord'");
+
+      /* If the first input should be read from the standard input, the
+         contents of `input1name' actually belong to `input2name'. */
       if(p->input2name==NULL)
         {
           p->input2name=p->input1name;
           p->input1name=NULL;
         }
     }
-  else
-    error(EXIT_FAILURE, 0, "no inputs! two inputs are necessary. The first "
-          "can be from the standard input (e.g., a pipe)");
 
 
   /* If the first input is a FITS file, make sure its HDU is also given. */
@@ -253,20 +274,13 @@ ui_check_options_and_arguments(struct matchparams *p)
           "`--hdu' (`-h') option and give it the HDU number (starting "
           "from zero), extension name, or anything acceptable by "
           "CFITSIO");
-
-  /* If the second input is a FITS file, make sure its HDU is also
-     given. */
-  if(p->input2name)
-    {
-      if( gal_fits_name_is_fits(p->input2name) && p->hdu2==NULL )
-        error(EXIT_FAILURE, 0, "no HDU for second input. Please use the "
-              "`--hdu2' (`-H') option and give it the HDU number (starting "
-              "from zero), extension name, or anything acceptable by "
-              "CFITSIO");
-    }
-  else
-    error(EXIT_FAILURE, 0, "second input file not specified: two inputs are "
-          "necessary");
+  if( p->input2name
+      && gal_fits_name_is_fits(p->input2name)
+      && p->hdu2==NULL )
+    error(EXIT_FAILURE, 0, "no HDU for second input. Please use "
+          "the `--hdu2' (`-H') option and give it the HDU number "
+          "(starting from zero), extension name, or anything "
+          "acceptable by CFITSIO");
 }
 
 
@@ -294,41 +308,67 @@ ui_check_options_and_arguments(struct matchparams *p)
 static void
 ui_set_mode(struct matchparams *p)
 {
-  /* Check if we are in image or catalog mode. We will base the mode on the
-     first input, then check with the second. */
+  int tin1, tin2;
+  char *t1=NULL, *t2=NULL;
+
+  /* We will base the mode on the first input, then check with the
+     second. Note that when the first is from standard input (it is
+     `NULL'), then we go into catalog mode because currently we assume
+     standard input is only for plain text and WCS matching is not defined
+     on plain text. */
   if( p->input1name && gal_fits_name_is_fits(p->input1name) )
-    p->mode = ( (gal_fits_hdu_format(p->input1name, p->cp.hdu) == IMAGE_HDU)
-                ? MATCH_MODE_WCS
-                : MATCH_MODE_CATALOG );
+    {
+      tin1=gal_fits_hdu_format(p->input1name, p->cp.hdu);
+      p->mode = (tin1 == IMAGE_HDU) ? MATCH_MODE_WCS : MATCH_MODE_CATALOG;
+    }
   else
     p->mode=MATCH_MODE_CATALOG;
 
-  /* Now that the mode is set, check the second input's type. */
-  if( gal_fits_name_is_fits(p->input2name) )
+
+  /* Necessary sanity checks. */
+  if(p->mode==MATCH_MODE_CATALOG && p->cp.searchin==0)
+    error(EXIT_FAILURE, 0, "no `--searchin' option specified. Please run "
+          "the following command for more information:\n\n"
+          "    $ info gnuastro \"selecting table columns\"\n");
+
+
+  /* Now that the mode is set, do some sanity checks on the second
+     catalog. Recall that when `--coord' is given, there is no second input
+     file.*/
+  if(p->input2name)
     {
-      if(gal_fits_hdu_format(p->input2name, p->hdu2) == IMAGE_HDU)
+      if(gal_fits_name_is_fits(p->input2name))
         {
-          if( p->mode==MATCH_MODE_CATALOG)
-            error(EXIT_FAILURE, 0, "%s is a catalog, while %s is an image. "
-                  "Both inputs have to be images or catalogs",
-                  gal_checkset_dataset_name(p->input1name, p->cp.hdu),
-                  gal_checkset_dataset_name(p->input2name, p->hdu2) );
+          tin2=gal_fits_hdu_format(p->input2name, p->hdu2);
+          if(tin1==IMAGE_HDU && tin2!=IMAGE_HDU)
+            {
+              t1 = (tin1==IMAGE_HDU) ? "image" : "catalog";
+              t2 = (tin2==IMAGE_HDU) ? "image" : "catalog";
+            }
+          if(t1)
+            error(EXIT_FAILURE, 0, "%s is a %s, while %s is an "
+                  "%s. Both inputs have to be images or catalogs",
+                  gal_checkset_dataset_name(p->input1name, p->cp.hdu), t1,
+                  gal_checkset_dataset_name(p->input2name, p->hdu2), t2 );
         }
       else
         {
-          if( p->mode==MATCH_MODE_WCS)
-            error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog. "
+          if(p->mode==MATCH_MODE_WCS)
+            error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog! "
                   "Both inputs have to be images or catalogs",
                   gal_checkset_dataset_name(p->input1name, p->cp.hdu),
-                  gal_checkset_dataset_name(p->input2name, p->hdu2));
+                  gal_checkset_dataset_name(p->input2name, p->hdu2) );
         }
     }
   else
-    if(p->mode==MATCH_MODE_WCS)
-      error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog! Both "
-            "inputs have to be images or catalogs",
-            gal_checkset_dataset_name(p->input1name, p->cp.hdu),
-            gal_checkset_dataset_name(p->input2name, p->hdu2));
+    {
+      /* When there is no second-input file name (`--coord' is given), we
+         cannot be in WCS mode (requiring a FITS file). */
+      if(p->mode==MATCH_MODE_WCS)
+        error(EXIT_FAILURE, 0, "%s is an image, while `--coord' is only "
+              "meaningful for catalogs",
+              gal_checkset_dataset_name(p->input1name, p->cp.hdu));
+    }
 }
 
 
@@ -534,6 +574,98 @@ ui_read_columns_aperture_3d(struct matchparams *p)
 
 
 
+static size_t
+ui_set_columns_sanity_check_read_aperture(struct matchparams *p)
+{
+  size_t ccol1n, ccol2n;
+
+  /* Make sure the columns to read are given. */
+  if(p->coord)
+    {
+      if(p->ccol1==NULL)
+        error(EXIT_FAILURE, 0, "no value given to `--ccol1' (necessary with "
+              "`--coord')");
+    }
+  else
+    {
+      if(p->ccol1==NULL || p->ccol2==NULL)
+        error(EXIT_FAILURE, 0, "both `--ccol1' and `--ccol2' must be given. "
+              "They specify the columns containing the coordinates to match");
+    }
+
+  /* Make sure the same number of columns is given to both. */
+  ccol1n = p->ccol1->size;
+  ccol2n = p->coord ? p->coord->size : p->ccol2->size;
+  if(ccol1n!=ccol2n)
+    error(EXIT_FAILURE, 0, "number of coordinates given to `--ccol1' "
+          "(%zu) and `--%s' (%zu) must be equal.\n\n"
+          "If you didn't call these options, run with `--checkconfig' to "
+          "see which configuration file is responsible. You can always "
+          "override the configuration file values by calling the option "
+          "manually on the command-line",
+          ccol1n, p->coord ? "coord" : "ccol2", ccol2n);
+
+  /* Read/check the aperture values. */
+  if(p->aperture)
+    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;
+      case 3: ui_read_columns_aperture_3d(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' (or `--coord') and `--ccol2'", ccol1n);
+      }
+  else
+    error(EXIT_FAILURE, 0, "no matching aperture specified. Please use "
+          "the `--aperture' option to define the acceptable aperture for "
+          "matching the coordinates (in the same units as each "
+          "dimension). Please run the following command for more "
+          "information.\n\n    $ info %s\n", PROGRAM_EXEC);
+
+  /* Return the number of dimensions. */
+  return ccol1n;
+}
+
+
+
+
+
+/* Save the manually given coordinates (with `--coord') in column format (a
+   list of datasets). */
+static gal_data_t *
+ui_set_columns_from_coord(struct matchparams *p)
+{
+  size_t i, one=1;
+  gal_data_t *out=NULL;
+  double *coord=p->coord->array;
+
+  /* Write each given value as a one-row table column (single element
+     datasets that are linked) */
+  for(i=0;i<p->coord->size;++i)
+    {
+      gal_list_data_add_alloc(&out, NULL, GAL_TYPE_FLOAT64, 1, &one, NULL,
+                              0, -1, NULL, NULL, NULL);
+      *((double *)(out->array))=coord[i];
+    }
+  gal_list_data_reverse(&out);
+
+  /* Return the list. */
+  return out;
+}
+
+
+
+
+
 /* We want to keep the columns as double type. So what-ever their original
    type is, convert it. */
 static gal_data_t *
@@ -599,69 +731,32 @@ ui_read_columns_to_double(struct matchparams *p, char 
*filename, char *hdu,
 static void
 ui_read_columns(struct matchparams *p)
 {
-  size_t i;
-  size_t ccol1n=p->ccol1->size;
-  size_t ccol2n=p->ccol2->size;
+  size_t i, ndim;
+  char **strarr1, **strarr2;
   gal_list_str_t *cols1=NULL, *cols2=NULL;
-  char **strarr1=p->ccol1->array, **strarr2=p->ccol2->array;
-
-  /* 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)
-    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;
-      case 3: ui_read_columns_aperture_3d(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 "
-          "matching the coordinates (in the same units as each "
-          "dimension). Please run the following command for more "
-          "information.\n\n    $ info %s\n", PROGRAM_EXEC);
 
+  /* Basic sanity checks and reading of aperture values. */
+  ndim=ui_set_columns_sanity_check_read_aperture(p);
 
   /* Convert the array of strings to a list of strings for the column
      names. */
-  for(i=0;i<ccol1n;++i)
+  strarr1=p->ccol1->array;
+  strarr2=p->coord?NULL:p->ccol2->array;
+  for(i=0;i<ndim;++i)
     {
       gal_list_str_add(&cols1, strarr1[i], 1);
-      gal_list_str_add(&cols2, strarr2[i], 1);
+      if(strarr2) gal_list_str_add(&cols2, strarr2[i], 1);
     }
   gal_list_str_reverse(&cols1);
-  gal_list_str_reverse(&cols2);
+  if(cols2) gal_list_str_reverse(&cols2);
 
-
-  /* Read the columns. */
-  if(p->cp.searchin)
-    {
-      /* Read the first dataset. */
-      p->cols1=ui_read_columns_to_double(p, p->input1name, p->cp.hdu,
-                                         cols1, ccol1n);
-      p->cols2=ui_read_columns_to_double(p, p->input2name, p->hdu2,
-                                         cols2, ccol2n);
-    }
-  else
-    error(EXIT_FAILURE, 0, "no `--searchin' option specified. Please run "
-          "the following command for more information:\n\n"
-          "    $ info gnuastro \"selecting table columns\"\n");
+  /* Read-in the columns. */
+  p->cols1=ui_read_columns_to_double(p, p->input1name, p->cp.hdu,
+                                     cols1, ndim);
+  p->cols2=( p->coord
+             ? ui_set_columns_from_coord(p)
+             : ui_read_columns_to_double(p, p->input2name, p->hdu2,
+                                         cols2, ndim) );
 
   /* Free the extra spaces. */
   gal_list_str_free(cols1, 1);
@@ -675,27 +770,65 @@ ui_read_columns(struct matchparams *p)
 static void
 ui_preparations_out_cols(struct matchparams *p)
 {
-  size_t i;
-  char **strarr=p->outcols->array;
+  void *rptr;
+  int goodvalue;
+  gal_data_t *read;
+  uint8_t readtype;
+  char *col, **strarr=p->outcols->array;
+  size_t i, one=1, ndim=p->coord?p->coord->size:0;
 
   /* Go over all the values and put the respective column identifier in the
      proper list. */
   for(i=0;i<p->outcols->size;++i)
-    switch(strarr[i][0])
-      {
-      case 'a': gal_list_str_add(&p->acols, strarr[i]+1, 0); break;
-      case 'b': gal_list_str_add(&p->bcols, strarr[i]+1, 0); break;
-      default:
-        error(EXIT_FAILURE, 0, "`%s' is not a valid value for `--outcols'. "
-              "The first character of each value to this option must be "
-              "either `a' or `b'. The former specifies a column from the "
-              "first input and the latter a column from the second. The "
-              "characters after them can be any column identifier (number, "
-              "name, or regular expression). For more on column selection, "
-              "please run this command:\n\n"
-              "    $ info gnuastro \"Selecting table columns\"\n",
-              strarr[i]);
-      }
+    {
+      col=strarr[i];
+      switch(col[0])
+        {
+        case 'a': gal_list_str_add(&p->acols, col+1, 0); break;
+        case 'b':
+          /* With `--coord', only numbers that are smaller than the number
+             of the dimensions are acceptable. */
+          if(p->coord)
+            {
+              goodvalue=0;
+              rptr=gal_type_string_to_number(col+1, &readtype);
+              if(rptr)
+                {
+                  read=gal_data_alloc(rptr, readtype, 1, &one, NULL, 0, -1,
+                                      NULL, NULL, NULL);
+                  if(gal_type_is_int(readtype))
+                    {
+                      read=gal_data_copy_to_new_type_free(read,GAL_TYPE_LONG);
+                      if( *((long *)(read->array)) <= ndim )
+                        goodvalue=1;
+                    }
+                  gal_data_free(read);
+                }
+              if(goodvalue==0)
+                error(EXIT_FAILURE, 0, "bad value to second catalog "
+                      "column (%s) of `--outcols'.\n\n"
+                      "With the `--coord' option, the second catalog is "
+                      "assumed to have a single row and the given number "
+                      "of columns. Therefore when using `--outcols', only "
+                      "integers that are less than the number of "
+                      "dimensions (%zu in this case) are acceptable", col+1,
+                      ndim);
+            }
+          gal_list_str_add(&p->bcols, col+1, 0);
+          break;
+        default:
+          error(EXIT_FAILURE, 0, "`%s' is not a valid value for "
+                "`--outcols'.\n\n"
+                "The first character of each value to this option must be "
+                "either `a' or `b'. The former specifies a column from the "
+                "first input and the latter a column from the second. The "
+                "characters after them can be any column identifier (number, "
+                "name, or regular expression). For more on column selection, "
+                "please run this command:\n\n"
+                "    $ info gnuastro \"Selecting table columns\"\n",
+                col);
+        }
+    }
 
   /* Revere the lists so they correspond to the input order. */
   gal_list_str_reverse(&p->acols);
@@ -738,7 +871,7 @@ ui_preparations_out_name(struct matchparams *p)
     }
   else
     {
-      if(p->outcols)
+      if(p->outcols || p->coord)
         {
           if(p->cp.output)
             gal_checkset_allocate_copy(p->cp.output, &p->out1name);
diff --git a/bin/match/ui.h b/bin/match/ui.h
index e949fb4..6d66082 100644
--- a/bin/match/ui.h
+++ b/bin/match/ui.h
@@ -40,7 +40,7 @@ enum program_args_groups
 
 /* Available letters for short options:
 
-   b d e f g i j k m n p r s t u v w x y z
+   b e f g i j k m n p r s t u v w x y z
    A B E G J L O Q R W X Y
 */
 enum option_keys_enum
@@ -51,6 +51,7 @@ enum option_keys_enum
   UI_KEY_LOGASOUTPUT     = 'l',
   UI_KEY_CCOL1           = 'c',
   UI_KEY_CCOL2           = 'C',
+  UI_KEY_COORD           = 'd',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 207389e..f3408b3 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -825,6 +825,25 @@ ui_read_cols_2d(struct mkprofparams *p)
           gal_data_free(corrtype);
         }
     }
+
+  /* Multi-column sanity checks. */
+  counter=0;
+  if( !p->cp.quiet && (p->mforflatpix || p->mcolisbrightness) )
+    for(i=0;i<p->num;++i)
+      if( p->m[i]==0.0 && ( p->f[i]==PROFILE_POINT
+                            || p->f[i]==PROFILE_FLAT
+                            || p->f[i]==PROFILE_CIRCUMFERENCE ) )
+        {
+          error(0, 0, "WARNING: atleast one single-valued profile (point, "
+                "flat, or circumference profiles) has a magnitude column "
+                "value of 0.0 while `--mforflatpix' or "
+                "`--mcolforbrightness' have also been given. In such cases "
+                "the profile's pixels will have a value of zero and thus "
+                "they will not be identifiable from the zero-valued "
+                "background. If this behavior is intended, this warning "
+                "can be supressed with the `--quiet' (or `-q') option.\n");
+          break;
+        }
 }
 
 
diff --git a/bin/noisechisel/threshold.c b/bin/noisechisel/threshold.c
index 47dcd19..4fe408a 100644
--- a/bin/noisechisel/threshold.c
+++ b/bin/noisechisel/threshold.c
@@ -282,8 +282,9 @@ threshold_interp_smooth(struct noisechiselparams *p, 
gal_data_t **first,
   /* Do the interpolation of both arrays. */
   (*first)->next = *second;
   if(third) (*second)->next = *third;
-  tmp=gal_interpolate_close_neighbors(*first, tl, cp->interpnumngb,
-                                      cp->numthreads, cp->interponlyblank, 1);
+  tmp=gal_interpolate_close_neighbors(*first, tl, cp->interpmetric,
+                                      cp->interpnumngb, cp->numthreads,
+                                      cp->interponlyblank, 1);
   gal_data_free(*first);
   gal_data_free(*second);
   if(third) gal_data_free(*third);
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index 7a6a438..66df6e6 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -135,6 +135,7 @@ ui_initialize_options(struct noisechiselparams *p,
         case GAL_OPTIONS_KEY_TILESIZE:
         case GAL_OPTIONS_KEY_MINMAPSIZE:
         case GAL_OPTIONS_KEY_NUMCHANNELS:
+        case GAL_OPTIONS_KEY_INTERPMETRIC:
         case GAL_OPTIONS_KEY_INTERPNUMNGB:
         case GAL_OPTIONS_KEY_REMAINDERFRAC:
           cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
diff --git a/bin/statistics/sky.c b/bin/statistics/sky.c
index 6d6a3fe..865cfc4 100644
--- a/bin/statistics/sky.c
+++ b/bin/statistics/sky.c
@@ -220,8 +220,9 @@ sky(struct statisticsparams *p)
   /* Interpolate the Sky and its standard deviation. */
   if(!cp->quiet) gettimeofday(&t1, NULL);
   p->sky_t->next=p->std_t;
-  tmp=gal_interpolate_close_neighbors(p->sky_t, tl, cp->interpnumngb,
-                                      cp->numthreads, cp->interponlyblank, 1);
+  tmp=gal_interpolate_close_neighbors(p->sky_t, tl, cp->interpmetric,
+                                      cp->interpnumngb, cp->numthreads,
+                                      cp->interponlyblank, 1);
   gal_data_free(p->sky_t);
   gal_data_free(p->std_t);
   p->sky_t=tmp;
diff --git a/bin/statistics/statistics.c b/bin/statistics/statistics.c
index c92ca8b..333b432 100644
--- a/bin/statistics/statistics.c
+++ b/bin/statistics/statistics.c
@@ -251,6 +251,7 @@ statistics_interpolate_and_write(struct statisticsparams *p,
       && !(p->cp.interponlyblank && gal_blank_present(values, 1)==0) )
     {
       interpd=gal_interpolate_close_neighbors(values, &cp->tl,
+                                              cp->interpmetric,
                                               cp->interpnumngb,
                                               cp->numthreads,
                                               cp->interponlyblank, 0);
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index dfa3c21..4e1c7d4 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -418,10 +418,10 @@ ui_read_check_only_options(struct statisticsparams *p)
     {
       /* Mandatory options. */
       if( isnan(p->meanmedqdiff) || isnan(p->sclipparams[0])
-          || p->cp.interpnumngb==0 )
-        error(EXIT_FAILURE, 0, "`--meanmedqdiff', `--sclipparams' and "
-              "`--interpnumngb' are mandatory when requesting Sky "
-              "measurement (`--sky')");
+          || p->cp.interpmetric==0 || p->cp.interpnumngb==0 )
+        error(EXIT_FAILURE, 0, "`--meanmedqdiff', `--sclipparams', "
+              "`--interpmetric' and `--interpnumngb' are mandatory when "
+              "requesting Sky measurement (`--sky')");
 
       /* If mode and median distance is a reasonable value. */
       if(p->meanmedqdiff>0.5)
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index 8e5463a..02c7b76 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -1,5 +1,6 @@
 Alphabetically ordered list to acknowledge in the next release.
 
+Roberto Baena Gallé
 Leindert Boogaard
 Raúl Infante Sainz
 David Valls-Gabaud
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index b7b6537..c01fa0e 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -7816,6 +7816,22 @@ is desirable).
 When values are to be interpolated, only change the values of the blank
 elements, keep the non-blank elements untouched.
 
+@item --interpmetric=STR
+@cindex Radial metric
+@cindex Taxicab metric
+@cindex Manhattan metric
+@cindex Metric: Manhattan, Taxicab, Radial
+The metric to use for finding nearest neighbors. Currently it only accepts
+the Manhattan (or taxicab) metric with @code{manhattan}, or the radial
+metric with @code{radial}.
+
+The Manhattan distance between two points is defined with
+@mymath{|\Delta{x}|+|\Delta{y}|}. Thus the Manhattan metric has the
+advantage of being fast, but at the expense of being less accurate. The
+radial distance is the standard definition of distance in a Euclidean
+space: @mymath{\sqrt{\Delta{x}^2+\Delta{y}^2}}. It is accurate, but the
+multiplication and square root can slow down the processing.
+
 @item --interpnumngb=INT
 The number of nearby non-blank neighbors to use for interpolation.
 @end table
@@ -12146,18 +12162,17 @@ non-zero decimals) put an @code{f} after it.
 
 @item sqrt
 The square root of the first operand, so ``@command{5 sqrt}'' is equivalent
-to @mymath{\sqrt{5}}. The output type is determined from the input, so the
-output of this example will be @command{2} (since @command{5} doesn't have
-any non-zero decimal digits). If you want @command{2.23607}, run
-@command{5f sqrt} instead, the @command{f} will ensure that a number will
-be read as a floating point number, even if it doesn't have decimal
-digits. If the input image has an integer type, you should explicitly
-convert the image to floating point, for example @command{a.fits float
-sqrt}, see the type conversion operators below.
+to @mymath{\sqrt{5}}. The output will have a floating point type, but its
+precision is determined from the input: if the input is a 64-bit floating
+point, the output will also be 64-bit. Otherwise, the output will be 32-bit
+floating point (see @ref{Numeric data types} for the respective
+precision). Therefore if you require 64-bit precision in estimating the
+square root, convert the input to 64-bit floating point first, for example
+with @code{5 float64 sqrt}.
 
 @item log
 Natural logarithm of first operand, so ``@command{4 log}'' is equivalent to
-@mymath{\ln(4)}. The output type is determined from the input, see the
+@mymath{ln(4)}. The output type is determined from the input, see the
 explanation under @command{sqrt} for more.
 
 @item log10
@@ -19926,10 +19941,14 @@ $ astmatch --ccol1=2,3,4 --ccol2=2,3,4 
-a0.5/3600,0.5/3600,5e-10 \
            in1.fits in2.txt
 @end example
 
-Two inputs are necessary for Match to start processing. The inputs can be
-plain text tables or FITS tables, see @ref{Tables}. If only one argument is
-provided, Match will assume look for the first input in Standard input (see
-@ref{Standard input}).
+Match will find the rows that are nearest to each other in two catalogs
+(given some coordinate columns). Therefore two catalogs are necessary for
+input. However, they don't necessarily have to be files: 1) the first
+catalog can also come from the standard input (for example a pipe, see
+@ref{Standard input}); 2) when only one point is needed, you can use the
+@option{--coord} option to avoid creating a file for the second
+catalog. When the inputs are files, they can be plain text tables or FITS
+tables, for more see @ref{Tables}.
 
 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
@@ -20022,6 +20041,15 @@ re-arrange the necessary columns and it will write a 
single output
 table. Combined with regular expressions in large tables, this can be a
 very powerful and convenient way to merge various tables into one.
 
+When @option{--coord} is given, no second catalog will be read. The second
+catalog will be created internally based on the values given to
+@option{--coord}. So column names aren't defined and you can only request
+integer column numbers that are less than the number of coordinates given
+to @option{--coord}. For example if you want to find the row matching RA of
+1.2345 and Dec of 6.7890, then you should use
+@option{--coord=1.2345,6.7890}. But when using @option{--outcols}, you
+can't give @code{bRA}, or @code{b25}.
+
 @item -l
 @itemx --logasoutput
 The output file will have the contents of the log file: indexes in the two
@@ -20051,8 +20079,27 @@ columns}. See the one-line examples above for some 
usages of this option.
 The coordinate columns of the second input. See the example in
 @option{--ccol1} for more.
 
-@item -a FLT[,...]
-@itemx --aperture=FLT[,...]
+@item -d FLT[,FLT]
+@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 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. 2) By default (when
+@option{--outcols} isn't used), only the matching row of the first table
+will be output (a single file), not two separate files (one for each
+table).
+
+This option is good when you have a (large) catalog and only want to match
+a single coordinate to it (for example to find the nearest catalog entry to
+your desired point). With this option, you can write the coordinates on the
+command-line and thus avoid the need to make a single-row file.
+
+@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 when the position columns are in units of
 degrees, @option{1/3600} can be used to ask for one arcsecond. The
@@ -23944,6 +23991,10 @@ Note: Do not use the maximum value for a blank value 
of a general
 @ref{Library blank values} for the definition and usage of blank values.
 @end deftypefun
 
+@deftypefun int gal_type_is_int (uint8_t @code{type})
+Return 1 if the type is an integer (any width and any sign).
+@end deftypefun
+
 @deftypefun int gal_type_is_list (uint8_t @code{type})
 Return 1 if the type is a linked list and zero otherwise.
 @end deftypefun
@@ -24861,6 +24912,11 @@ the two coordinates @code{a} and @code{b} (each an 
array of @code{ndim}
 elements).
 @end deftypefun
 
+@deftypefun float gal_dimension_dist_radial (size_t @code{*a}, size_t 
@code{*b}, size_t @code{ndim})
+Return the radial distance between the two coordinates @code{a} and
+@code{b} (each an array of @code{ndim} elements).
+@end deftypefun
+
 @deftypefun {gal_data_t *} gal_dimension_collapse_sum (gal_data_t @code{*in}, 
size_t @code{c_dim}, gal_data_t @code{*weight})
 Collapse the input dataset (@code{in}) along the given dimension
 (@code{c_dim}, in C definition: starting from zero, from the slowest
@@ -26265,17 +26321,29 @@ typedef struct gal_fits_list_key_t
 @end deftp
 
 @deftypefun {void *} gal_fits_key_img_blank (uint8_t @code{type})
-Returns a pointer to an allocated space for the FITS @code{BLANK} header
-keyword when the input array has a type of @code{type}.
+Returns a pointer to an allocated space containing the value to the FITS
+@code{BLANK} header keyword, when the input array has a type of
+@code{type}. This is useful when you want to write the @code{BLANK} keyword
+using CFITSIO's @code{fits_write_key} function.
 
 According to the FITS standard: ``If the @code{BSCALE} and @code{BZERO}
 keywords do not have the default values of 1.0 and 0.0, respectively, then
 the value of the @code{BLANK} keyword must equal the actual value in the
 FITS data array that is used to represent an undefined pixel and not the
 corresponding physical value''. Therefore a special @code{BLANK} value is
-needed for datasets containing signed 8-bit integers and unsigned 16-bit,
-32-bit and 64-bit integers (types that are defined with @code{BSCALE} and
-@code{BZERO} in the FITS standard).
+needed for datasets containing signed 8-bit, unsigned 16-bit, unsigned
+32-bit, and unsigned 64-bit integers (types that are defined with
+@code{BSCALE} and @code{BZERO} in the FITS standard).
+
+@cartouche
+@noindent
+@strong{Not usable when reading a dataset:} As quoted from the FITS
+standard above, the value returned by this function can only be generically
+used for the writing of the @code{BLANK} keyword header. It @emph{must not}
+be used as the blank pointer when when reading a FITS array using
+CFITSIO. When reading an array with CFITSIO, you can use
+@code{gal_blank_alloc_write} to generate the necessary pointer.
+@end cartouche
 @end deftypefun
 
 @deftypefun void gal_fits_key_clean_str_value (char @code{*string})
@@ -27336,11 +27404,14 @@ polish notation}).
 @deffnx Macro GAL_ARITHMETIC_OP_LOG10
 Unary operator functions for calculating the square root
 (@mymath{\sqrt{i}}), @mymath{ln(i)} and @mymath{log(i)} mathematic
-operators on each element of the input dataset. The output will have the
-same type as the input, so if your inputs are integer types be careful.
-
-If you want your output to be floating point but your input is an integer
-type, you can convert the input to a floating point type with
+operators on each element of the input dataset. The returned dataset will
+have a floating point type, but its precision is determined from the input:
+if the input is a 64-bit floating point, the output will also be
+64-bit. Otherwise, the returned dataset will be 32-bit floating point. See
+@ref{Numeric data types} for the respective precision.
+
+If you want your output to be 64-bit floating point but your input is a
+different type, you can convert the input to a floating point type with
 @code{gal_data_copy_to_new_type} or
 @code{gal_data_copy_to_new_type_free}(see @ref{Copying datasets}).
 @end deffn
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index d24e960..aba3df2 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -350,43 +350,82 @@ arithmetic_abs(int flags, gal_data_t *in)
 
 
 
-#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT(IT, OP){                        \
-    IT *ia=in->array, *oa=o->array, *iaf=ia + in->size;                 \
+#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT(OT, IT, OP){                    \
+    OT *oa=o->array;                                                    \
+    IT *ia=in->array, *iaf=ia + in->size;                               \
     do *oa++ = OP(*ia++); while(ia<iaf);                                \
   }
 
+#define UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(IT, OP)                   \
+  switch(o->type)                                                       \
+    {                                                                   \
+    case GAL_TYPE_UINT8:                                                \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t,  IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_INT8:                                                 \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t,   IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_UINT16:                                               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_INT16:                                                \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t,  IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_UINT32:                                               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_INT32:                                                \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t,  IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_UINT64:                                               \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_INT64:                                                \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t,  IT, OP)                 \
+        break;                                                          \
+    case GAL_TYPE_FLOAT32:                                              \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float,    IT, OP)                 \
+      break;                                                            \
+    case GAL_TYPE_FLOAT64:                                              \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double,   IT, OP)                 \
+      break;                                                            \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "%s: type code %d not recognized",         \
+            "UNIARY_FUNCTION_ON_ELEMENT", in->type);                    \
+    }
+
 #define UNIARY_FUNCTION_ON_ELEMENT(OP)                                  \
   switch(in->type)                                                      \
     {                                                                   \
     case GAL_TYPE_UINT8:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t, OP)                      \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint8_t,  OP)               \
         break;                                                          \
     case GAL_TYPE_INT8:                                                 \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t, OP)                       \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int8_t,   OP)               \
         break;                                                          \
     case GAL_TYPE_UINT16:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, OP)                     \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint16_t, OP)               \
         break;                                                          \
     case GAL_TYPE_INT16:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t, OP)                      \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int16_t,  OP)               \
         break;                                                          \
     case GAL_TYPE_UINT32:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, OP)                     \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint32_t, OP)               \
         break;                                                          \
     case GAL_TYPE_INT32:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t, OP)                      \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int32_t,  OP)               \
         break;                                                          \
     case GAL_TYPE_UINT64:                                               \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, OP)                     \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(uint64_t, OP)               \
         break;                                                          \
     case GAL_TYPE_INT64:                                                \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t, OP)                      \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(int64_t,  OP)               \
         break;                                                          \
     case GAL_TYPE_FLOAT32:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float, OP)                        \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(float,    OP)               \
       break;                                                            \
     case GAL_TYPE_FLOAT64:                                              \
-      UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double, OP)                       \
+      UNIFUNC_RUN_FUNCTION_ON_ELEMENT_INSET(double,   OP)               \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "%s: type code %d not recognized",         \
@@ -396,15 +435,31 @@ arithmetic_abs(int flags, gal_data_t *in)
 static gal_data_t *
 arithmetic_unary_function(int operator, int flags, gal_data_t *in)
 {
+  uint8_t otype;
+  int inplace=0;
   gal_data_t *o;
 
-  /* If we want inplace output, set the output pointer to the input
-     pointer, for every pixel, the operation will be independent. */
-  if(flags & GAL_ARITHMETIC_INPLACE)
-    o = in;
+  /* See if the operation should be done in place. Note that so far, the
+     output of these operators is defined in the real space (floating
+     point). So even if the user requested inplace opereation, if its not a
+     floating point type, its not useful.*/
+  if( (flags & GAL_ARITHMETIC_INPLACE)
+      && (in->type==GAL_TYPE_FLOAT32 || in->type==GAL_TYPE_FLOAT64) )
+    inplace=1;
+
+  if(inplace)
+    {
+      o = in;
+      otype=in->type;
+    }
   else
-    o = gal_data_alloc(NULL, in->type, in->ndim, in->dsize, in->wcs,
-                       0, in->minmapsize, NULL, NULL, NULL);
+    {
+      otype = ( in->type==GAL_TYPE_FLOAT64
+                ? GAL_TYPE_FLOAT64
+                : GAL_TYPE_FLOAT32 );
+      o = gal_data_alloc(NULL, otype, in->ndim, in->dsize, in->wcs,
+                         0, in->minmapsize, NULL, NULL, NULL);
+    }
 
   /* Start setting the operator and operands. */
   switch(operator)
diff --git a/lib/dimension.c b/lib/dimension.c
index 070265e..310b5cb 100644
--- a/lib/dimension.c
+++ b/lib/dimension.c
@@ -263,7 +263,7 @@ gal_dimension_index_to_coord(size_t index, size_t ndim, 
size_t *dsize,
 /************************************************************************/
 /********************           Distances          **********************/
 /************************************************************************/
-size_t
+float
 gal_dimension_dist_manhattan(size_t *a, size_t *b, size_t ndim)
 {
   size_t i, out=0;
@@ -275,6 +275,18 @@ gal_dimension_dist_manhattan(size_t *a, size_t *b, size_t 
ndim)
 
 
 
+float
+gal_dimension_dist_radial(size_t *a, size_t *b, size_t ndim)
+{
+  size_t i, out=0;
+  for(i=0;i<ndim;++i) out += (a[i]-b[i])*(a[i]-b[i]);
+  return sqrt(out);
+}
+
+
+
+
+
 
 
 
diff --git a/lib/gnuastro-internal/commonopts.h 
b/lib/gnuastro-internal/commonopts.h
index 4420947..cadd541 100644
--- a/lib/gnuastro-internal/commonopts.h
+++ b/lib/gnuastro-internal/commonopts.h
@@ -199,6 +199,20 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_NOT_SET
     },
     {
+      "interpmetric",
+      GAL_OPTIONS_KEY_INTERPMETRIC,
+      "INT",
+      0,
+      "Interpolation metric (radial, manhattan).",
+      GAL_OPTIONS_GROUP_TESSELLATION,
+      &cp->interpmetric,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+      gal_options_read_interpmetric
+    },
+    {
       "interpnumngb",
       GAL_OPTIONS_KEY_INTERPNUMNGB,
       "INT",
@@ -252,7 +266,7 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_KEY_TABLEFORMAT,
       "STR",
       0,
-      "Table format: `fits-ascii', `fits-binary'.",
+      "Table fmt: `fits-ascii', `fits-binary', `txt'.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &cp->tableformat,
       GAL_TYPE_STRING,
diff --git a/lib/gnuastro-internal/options.h b/lib/gnuastro-internal/options.h
index 294e96f..3ba3da8 100644
--- a/lib/gnuastro-internal/options.h
+++ b/lib/gnuastro-internal/options.h
@@ -122,6 +122,7 @@ enum options_common_keys
   GAL_OPTIONS_KEY_CHECKTILES,
   GAL_OPTIONS_KEY_ONEELEMPERTILE,
   GAL_OPTIONS_KEY_INTERPONLYBLANK,
+  GAL_OPTIONS_KEY_INTERPMETRIC,
   GAL_OPTIONS_KEY_INTERPNUMNGB,
 };
 
@@ -180,6 +181,7 @@ struct gal_options_common_params
   /* Tessellation. */
   struct gal_tile_two_layer_params tl; /* Two layer tessellation params.  */
   uint8_t      interponlyblank; /* Only interpolate over blank values.    */
+  uint8_t         interpmetric; /* Metric to use for nearest-ngb interp.  */
   size_t          interpnumngb; /* Number of neighbors for interpolation. */
 
   /* Input. */
@@ -275,6 +277,10 @@ void *
 gal_options_read_tableformat(struct argp_option *option, char *arg,
                              char *filename, size_t lineno, void *junk);
 
+void *
+gal_options_read_interpmetric(struct argp_option *option, char *arg,
+                              char *filename, size_t lineno, void *junk);
+
 gal_data_t *
 gal_options_parse_list_of_numbers(char *string, char *filename,
                                   size_t lineno);
diff --git a/lib/gnuastro/dimension.h b/lib/gnuastro/dimension.h
index 205820a..2bdc9c4 100644
--- a/lib/gnuastro/dimension.h
+++ b/lib/gnuastro/dimension.h
@@ -89,10 +89,11 @@ gal_dimension_index_to_coord(size_t index, size_t ndim, 
size_t *dsize,
 /************************************************************************/
 /********************           Distances          **********************/
 /************************************************************************/
-size_t
+float
 gal_dimension_dist_manhattan(size_t *a, size_t *b, size_t ndim);
 
-
+float
+gal_dimension_dist_radial(size_t *a, size_t *b, size_t ndim);
 
 
 
diff --git a/lib/gnuastro/interpolate.h b/lib/gnuastro/interpolate.h
index 1c72730..5f1ec26 100644
--- a/lib/gnuastro/interpolate.h
+++ b/lib/gnuastro/interpolate.h
@@ -46,6 +46,18 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
+
+/* Metrics to use for nearest-neighbor  */
+enum gal_interpolate_close_metric
+{
+ GAL_INTERPOLATE_CLOSE_METRIC_INVALID,
+
+ GAL_INTERPOLATE_CLOSE_METRIC_RADIAL,
+ GAL_INTERPOLATE_CLOSE_METRIC_MANHATTAN,
+};
+
+
+
 /* Types of interpolation. */
 enum gal_interpolate_1D_types
 {
@@ -65,8 +77,9 @@ enum gal_interpolate_1D_types
 gal_data_t *
 gal_interpolate_close_neighbors(gal_data_t *input,
                                 struct gal_tile_two_layer_params *tl,
-                                size_t numneighbors, size_t numthreads,
-                                int onlyblank, int aslinkedlist);
+                                uint8_t metric, size_t numneighbors,
+                                size_t numthreads, int onlyblank,
+                                int aslinkedlist);
 
 gsl_spline *
 gal_interpolate_1d_make_gsl_spline(gal_data_t *X, gal_data_t *Y, int type_1d);
diff --git a/lib/gnuastro/type.h b/lib/gnuastro/type.h
index a57214e..195cfce 100644
--- a/lib/gnuastro/type.h
+++ b/lib/gnuastro/type.h
@@ -138,6 +138,9 @@ void
 gal_type_max(uint8_t type, void *in);
 
 int
+gal_type_is_int(uint8_t type);
+
+int
 gal_type_is_list(uint8_t type);
 
 int
diff --git a/lib/interpolate.c b/lib/interpolate.c
index 8cd99c5..bdc4f50 100644
--- a/lib/interpolate.c
+++ b/lib/interpolate.c
@@ -67,6 +67,8 @@ struct interpolate_params
   uint8_t                *thread_flags;
   int                        onlyblank;
   gal_list_void_t            *ngb_vals;
+  float (*metric)(size_t *, size_t *, size_t );
+
   struct gal_tile_two_layer_params *tl;
 };
 
@@ -87,11 +89,11 @@ interpolate_close_neighbors_on_thread(void *in_prm)
 
   /* Rest of variables. */
   void *nv;
-  float pdist;
+  float dist, pdist;
   uint8_t *b, *bf, *bb;
   gal_list_void_t *tvll;
   gal_list_dosizet_t *lQ, *sQ;
-  size_t ngb_counter, dist, pind, *dinc;
+  size_t ngb_counter, pind, *dinc;
   size_t i, index, fullind, chstart=0, ndim=input->ndim;
   gal_data_t *median, *tin, *tout, *tnear, *nearest=NULL;
   size_t size = (correct_index ? tl->tottilesinch : input->size);
@@ -233,7 +235,7 @@ interpolate_close_neighbors_on_thread(void *in_prm)
                  gal_dimension_index_to_coord(nind, ndim, dsize, ncoord);
 
                  /* Distance of this neighbor to the one to be filled. */
-                 dist=gal_dimension_dist_manhattan(icoord, ncoord, ndim);
+                 dist=prm->metric(icoord, ncoord, ndim);
 
                  /* Add this neighbor to the list. */
                  gal_list_dosizet_add(&lQ, &sQ, nind, dist);
@@ -257,7 +259,9 @@ interpolate_close_neighbors_on_thread(void *in_prm)
       tout=prm->out;
       for(tnear=nearest; tnear!=NULL; tnear=tnear->next)
         {
-          /* Find the median and copy it. */
+          /* Find the median and copy it, but first, reset the flags (which
+             remain from the last time). */
+          tnear->flag &= ~(GAL_DATA_FLAG_SORT_CH | GAL_DATA_FLAG_BLANK_CH);
           median=gal_statistics_median(tnear, 1);
           memcpy(gal_pointer_increment(tout->array, fullind, tout->type),
                  median->array, gal_type_sizeof(tout->type));
@@ -326,8 +330,9 @@ interpolate_copy_input(gal_data_t *input, int aslinkedlist)
 gal_data_t *
 gal_interpolate_close_neighbors(gal_data_t *input,
                                 struct gal_tile_two_layer_params *tl,
-                                size_t numneighbors, size_t numthreads,
-                                int onlyblank, int aslinkedlist)
+                                uint8_t metric, size_t numneighbors,
+                                size_t numthreads, int onlyblank,
+                                int aslinkedlist)
 {
   gal_data_t *tin, *tout;
   struct interpolate_params prm;
@@ -352,6 +357,21 @@ gal_interpolate_close_neighbors(gal_data_t *input,
   prm.num          = aslinkedlist ? gal_list_data_number(input) : 1;
 
 
+  /* Set the metric. */
+  switch(metric)
+    {
+    case GAL_INTERPOLATE_CLOSE_METRIC_RADIAL:
+      prm.metric=gal_dimension_dist_radial;
+      break;
+    case GAL_INTERPOLATE_CLOSE_METRIC_MANHATTAN:
+      prm.metric=gal_dimension_dist_manhattan;
+      break;
+    default:
+      error(EXIT_FAILURE, 0, "%s: %d is not a valid metric identifier",
+            __func__, metric);
+    }
+
+
   /* Flag the blank values. */
   prm.blanks=gal_blank_flag(input);
 
diff --git a/lib/options.c b/lib/options.c
index 5e286e9..d962789 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -38,6 +38,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/threads.h>
 #include <gnuastro/pointer.h>
 #include <gnuastro/arithmetic.h>
+#include <gnuastro/interpolate.h>
 
 #include <gnuastro-internal/timing.h>
 #include <gnuastro-internal/options.h>
@@ -511,6 +512,55 @@ gal_options_read_tableformat(struct argp_option *option, 
char *arg,
 
 
 
+void *
+gal_options_read_interpmetric(struct argp_option *option, char *arg,
+                              char *filename, size_t lineno, void *junk)
+{
+  char *str;
+  if(lineno==-1)
+    {
+      switch(*(uint8_t *)(option->value))
+        {
+        case GAL_INTERPOLATE_CLOSE_METRIC_RADIAL:
+          gal_checkset_allocate_copy("radial", &str);
+          break;
+        case GAL_INTERPOLATE_CLOSE_METRIC_MANHATTAN:
+          gal_checkset_allocate_copy("manhattan", &str);
+          break;
+        default:
+          error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to "
+                "fix the problem. The code %u is not recognized as a "
+                "nearest-neighbor interpolation metric", __func__,
+                PACKAGE_BUGREPORT, *(uint8_t *)(option->value));
+        }
+      return str;
+    }
+  else
+    {
+      /* If the option is already set, just return. */
+      if(option->set) return NULL;
+
+      /* Set the value. */
+      if(       !strcmp(arg, "radial") )
+        *(uint8_t *)(option->value) = GAL_INTERPOLATE_CLOSE_METRIC_RADIAL;
+      else if ( !strcmp(arg, "manhattan") )
+        *(uint8_t *)(option->value) = GAL_INTERPOLATE_CLOSE_METRIC_MANHATTAN;
+      else
+        error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to "
+                      "`%s' option) isn't valid. Currently only `radial' "
+                      "and `manhattan' metrics are recognized for nearest "
+                      "neighbor interpolation", arg, option->name);
+
+      /* For no un-used variable warning. This function doesn't need the
+         pointer. */
+      return junk=NULL;
+    }
+}
+
+
+
+
+
 /* 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
diff --git a/lib/type.c b/lib/type.c
index 560a305..af21dec 100644
--- a/lib/type.c
+++ b/lib/type.c
@@ -280,7 +280,29 @@ gal_type_max(uint8_t type, void *in)
     case GAL_TYPE_FLOAT32:      *(float *)    in = FLT_MAX;      break;
     case GAL_TYPE_FLOAT64:      *(double *)   in = DBL_MAX;      break;
     default:
-      error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__, 
type);
+      error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__,
+            type);
+    }
+}
+
+
+
+
+
+int
+gal_type_is_int(uint8_t type)
+{
+  switch(type)
+    {
+    case GAL_TYPE_UINT8:  return 1;
+    case GAL_TYPE_INT8:   return 1;
+    case GAL_TYPE_UINT16: return 1;
+    case GAL_TYPE_INT16:  return 1;
+    case GAL_TYPE_UINT32: return 1;
+    case GAL_TYPE_INT32:  return 1;
+    case GAL_TYPE_UINT64: return 1;
+    case GAL_TYPE_INT64:  return 1;
+    default:              return 0;
     }
 }
 
diff --git a/tests/match/merged-cols.sh b/tests/match/merged-cols.sh
index 3e4ac2a..9a21aa3 100755
--- a/tests/match/merged-cols.sh
+++ b/tests/match/merged-cols.sh
@@ -53,6 +53,6 @@ if [ ! -f $execname ]; then echo "$execname not created."; 
exit 77; fi
 # `check_with_program' can be something like `Valgrind' or an empty
 # string. Such programs will execute the command if present and help in
 # debugging when the developer doesn't have access to the user's system.
-$check_with_program $execname $cat1 $cat2 --aperture=0.5             \
-                              -omatch-merged-cols.txt                \
+$check_with_program $execname $cat1 $cat2 --aperture=0.5 --ccol1=2,3   \
+                               --ccol2=2,3 -omatch-merged-cols.txt     \
                               --outcols=a1,aEFGH,bACCU1,aIJKL,bACCU2
diff --git a/tests/match/positions.sh b/tests/match/positions.sh
index 2622750..e9b51c9 100755
--- a/tests/match/positions.sh
+++ b/tests/match/positions.sh
@@ -53,5 +53,5 @@ if [ ! -f $execname ]; then echo "$execname not created."; 
exit 77; fi
 # `check_with_program' can be something like `Valgrind' or an empty
 # string. Such programs will execute the command if present and help in
 # debugging when the developer doesn't have access to the user's system.
-$check_with_program $execname $cat1 $cat2 --aperture=0.5 --log    \
-                              --output=match-positions.fits
+$check_with_program $execname $cat1 $cat2 --aperture=0.5 --log --ccol1=2,3 \
+                              --ccol2=2,3 --output=match-positions.fits



reply via email to

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