gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 5cd3c1e 044/113: Recent work in master merged,


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 5cd3c1e 044/113: Recent work in master merged, small conflicts fixed
Date: Fri, 16 Apr 2021 10:33:41 -0400 (EDT)

branch: master
commit 5cd3c1e2af81b53999e6bc8fca02987a95b43fa7
Merge: 54b099d e59c4bc
Author: Mohammad Akhlaghi <akhlaghi@gnu.org>
Commit: Mohammad Akhlaghi <akhlaghi@gnu.org>

    Recent work in master merged, small conflicts fixed
    
    The many recent fixes, changes and additions to Gnuastro are now also
    available in this branch. Some minor conflicts were also corrected.
---
 .mailmap                                           |    3 +-
 Makefile.am                                        |   11 +-
 NEWS                                               |   21 +-
 README                                             |    3 +
 THANKS                                             |    4 +
 bin/TEMPLATE/astTEMPLATE.conf                      |    2 +-
 bin/TEMPLATE/authors-cite.h                        |    4 +-
 bin/TEMPLATE/ui.c                                  |    3 +-
 bin/arithmetic/authors-cite.h                      |    4 +-
 bin/arithmetic/ui.c                                |    9 +
 bin/buildprog/args.h                               |   14 +
 bin/buildprog/astbuildprog.conf                    |    3 +-
 bin/buildprog/authors-cite.h                       |    4 +-
 bin/buildprog/buildprog.c                          |    8 +-
 bin/buildprog/main.h                               |    1 +
 bin/buildprog/ui.h                                 |    1 +
 bin/convertt/authors-cite.h                        |    4 +-
 bin/convolve/authors-cite.h                        |    4 +-
 bin/cosmiccal/authors-cite.h                       |    4 +-
 bin/cosmiccal/ui.c                                 |    4 +
 bin/crop/args.h                                    |    4 +-
 bin/crop/authors-cite.h                            |    4 +-
 bin/crop/ui.c                                      |   82 +-
 bin/fits/authors-cite.h                            |    4 +-
 bin/fits/ui.c                                      |    2 +-
 bin/match/Makefile.am                              |   41 +
 bin/{buildprog => match}/args.h                    |  138 +-
 .../astbuildprog.conf => match/astmatch.conf}      |   18 +-
 bin/{mknoise => match}/authors-cite.h              |    8 +-
 bin/{mknoise/authors-cite.h => match/main.c}       |   46 +-
 bin/{buildprog => match}/main.h                    |   42 +-
 bin/match/match.c                                  |  180 +++
 bin/{mknoise/authors-cite.h => match/match.h}      |   21 +-
 bin/match/ui.c                                     |  688 +++++++++
 bin/{buildprog => match}/ui.h                      |   34 +-
 bin/mkcatalog/authors-cite.h                       |    2 +-
 bin/mkcatalog/ui.c                                 |    2 +-
 bin/mknoise/authors-cite.h                         |    4 +-
 bin/mkprof/args.h                                  |    8 +-
 bin/mkprof/authors-cite.h                          |    4 +-
 bin/mkprof/main.h                                  |    2 +-
 bin/mkprof/ui.c                                    |   57 -
 bin/noisechisel/authors-cite.h                     |    4 +-
 bin/noisechisel/clumps.c                           |    2 +-
 bin/noisechisel/ui.c                               |    1 -
 bin/statistics/authors-cite.h                      |    4 +-
 bin/table/authors-cite.h                           |    4 +-
 bin/table/ui.c                                     |   90 +-
 bin/warp/authors-cite.h                            |    4 +-
 bootstrap.conf                                     |    2 +-
 configure.ac                                       |   45 +-
 doc/announce-acknowledge.txt                       |    9 +-
 doc/gnuastro.fr.html                               |  483 +++++++
 doc/gnuastro.texi                                  | 1463 +++++++++++++++++++-
 doc/release-checklist.txt                          |   83 +-
 lib/Makefile.am                                    |   30 +-
 lib/box.c                                          |   26 +-
 lib/checkset.c                                     |   22 +
 lib/data.c                                         |   36 +-
 lib/fits.c                                         |   10 +-
 lib/gnuastro-internal/checkset.h                   |    5 +-
 lib/gnuastro-internal/options.h                    |    4 +
 lib/gnuastro/box.h                                 |    4 +
 lib/gnuastro/fits.h                                |    1 +
 lib/gnuastro/{box.h => match.h}                    |   34 +-
 lib/match.c                                        |  798 +++++++++++
 lib/options.c                                      |   93 +-
 lib/permutation.c                                  |    1 +
 lib/table.c                                        |  288 ++--
 lib/txt.c                                          |    5 +-
 lib/wcs.c                                          |   37 +-
 tests/Makefile.am                                  |   40 +-
 tests/match/positions-1.txt                        |    9 +
 tests/match/positions-2.txt                        |    7 +
 tests/match/positions.sh                           |   52 +
 tests/prepconf.sh                                  |    6 +-
 76 files changed, 4483 insertions(+), 721 deletions(-)

diff --git a/.mailmap b/.mailmap
index bccc8e5..c47aba3 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,2 +1,3 @@
 Boud Roukema <boud@cosmo.torun.pl>
-<akhlaghi@gnu.org> <makhlaghi@gmail.com>
\ No newline at end of file
+<akhlaghi@gnu.org> <makhlaghi@gmail.com>
+Lucas MacQuarrie <macquarrielucas@gmail.com>
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 2d2308d..80a01b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,6 +68,9 @@ endif
 if COND_FITS
   MAYBE_FITS = bin/fits
 endif
+if COND_MATCH
+  MAYBE_MATCH = bin/match
+endif
 if COND_MKCATALOG
   MAYBE_MKCATALOG = bin/mkcatalog
 endif
@@ -109,10 +112,10 @@ endif
 ## having an uncommented `MAYBE_TEMPLATE' as a value in `SUBDIRS'.
 SUBDIRS = bootstrapped/lib $(MAYBE_GNULIBCHECK) lib $(MAYBE_ARITHMETIC)  \
   $(MAYBE_BUILDPROG) $(MAYBE_CONVERTT) $(MAYBE_CONVOLVE)                 \
-  $(MAYBE_COSMICCAL) $(MAYBE_CROP) $(MAYBE_FITS) $(MAYBE_MKCATALOG)      \
-  $(MAYBE_MKNOISE) $(MAYBE_MKPROF) $(MAYBE_NOISECHISEL)                  \
-  $(MAYBE_STATISTICS) $(MAYBE_TABLE) $(MAYBE_TEMPLATE) $(MAYBE_WARP) doc \
-  tests
+  $(MAYBE_COSMICCAL) $(MAYBE_CROP) $(MAYBE_FITS) $(MAYBE_MATCH)          \
+  $(MAYBE_MKCATALOG) $(MAYBE_MKNOISE) $(MAYBE_MKPROF)                    \
+  $(MAYBE_NOISECHISEL) $(MAYBE_STATISTICS) $(MAYBE_TABLE)                \
+  $(MAYBE_TEMPLATE) $(MAYBE_WARP) doc tests
 
 
 
diff --git a/NEWS b/NEWS
index 269a79a..5429b65 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,17 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
 ** New features
 
+  Manual/Book: An extended tutorial is added showing some general
+  applications of almost all the programs. This may be a good place to get
+  a feeling of how Gnuastro is intended to be used and some of the
+  programs.
+
+  New Program and library: Match is a new program that will match two given
+  inputs (currently catalogs). Its output is the re-arranged inputs with
+  the same number of rows/records such that all the rows match. The main
+  work is also done with the new `gal_match_catalog' library function which
+  can also be used in other contexts.
+
   All programs: a value of `0' to the `--numthreads' option will use the
   number of threads available to the system at run time.
 
@@ -87,6 +98,9 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
   `gal_txt_write' and `gal_fits_tab_write' now accept an extension name as
   argument to allow a name for the FITS extension they write.
 
+  `gal_box_bound_ellipse_extent' will return the maximum extent of an
+  ellipse along each axis from the ellipse center in floating point.
+
 ** Removed features
 
   MakeCatalog: `--zeropoint' option doesn't have a short option name any
@@ -152,6 +166,11 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
   NoiseChisel leaving unlabeled regions after clump growth (bug #52327).
 
+  Arithmetic crash with no input tokens (bug #52422).
+
+  Libtool checks only in non-current directory (bug #52427).
+
+
 
 
 
@@ -292,7 +311,7 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
   NoiseChisel segfault when detection contains no clumps (bug #51906).
 
-
+  Correct size checking when allocating gal_data_t (bug #52544).
 
 
 
diff --git a/README b/README
index 5d52a6b..45e258e 100644
--- a/README
+++ b/README
@@ -61,6 +61,9 @@ context under categories/chapters.
 
   - Header (astheader): Print and manipulate the header data of a FITS file.
 
+  - Match (astmatch): Given two input catalogs, find the rows that match
+    with each other within a given aperture (may be an ellipse).
+
   - MakeCatalog (astmkcatalog): Make catalog of labeled image (output of
     NoiseChisel). The catalogs are highly customizable and adding new
     calculations/columns is very streightforward.
diff --git a/THANKS b/THANKS
index 1afb512..b094d91 100644
--- a/THANKS
+++ b/THANKS
@@ -24,6 +24,7 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Adrian Bunk                          bunk@debian.org
     Rosa Calvi                           rcalvi@iac.es
     Antonio Diaz Diaz                    antonio@gnu.org
+    Madusha Gunawardhana                 gunawardhana@strw.leidenuniv.nl
     Stephen Hamer                        stephen.hamer@univ-lyon1.fr
     Takashi Ichikawa                     ichikawa@astr.tohoku.ac.jp
     Raúl Infante Sainz                   infantesainz@gmail.com
@@ -31,11 +32,14 @@ support in Gnuastro. The list is ordered alphabetically (by 
family name).
     Aurélien Jarno                       aurelien.jarno@univ-lyon1.fr
     Lee Kelvin                           l.s.kelvin@ljmu.ac.uk
     Mohammad-Reza Khellat                moha.khe@gmail.com
+    Floriane Leclercq                    floriane.leclercq@univ-lyon1.fr
     Alan Lefor                           alefor@astr.tohoku.ac.jp
     Guillaume Mahler                     guillaume.mahler@univ-lyon1.fr
     Francesco Montanari                  francesco.montanari@openmailbox.org
     William Pence                        William.Pence@nasa.gov
     Yahya Sefidbakht                     y.sefidbakht@gmail.com
+    Alejandro Serrano Borlaff            asborlaff@ucm.es
+    Lee Spitler                          lee.spitler@mq.edu.au
     Richard Stallman                     rms@gnu.org
     Ole Streicher                        olebole@debian.org
     Ignacio Trujillo                     trujillo@iac.es
diff --git a/bin/TEMPLATE/astTEMPLATE.conf b/bin/TEMPLATE/astTEMPLATE.conf
index 3e94701..3fe97e1 100644
--- a/bin/TEMPLATE/astTEMPLATE.conf
+++ b/bin/TEMPLATE/astTEMPLATE.conf
@@ -1,5 +1,5 @@
 # Default parameters (System) for TEMPLATE.
-# TEMPLATE is part of GNU Astronomy Utitlies.
+# TEMPLATE is part of GNU Astronomy Utilities.
 #
 # Use the long option name of each parameter followed by a value. The name
 # and value should be separated by atleast one white-space character (for
diff --git a/bin/TEMPLATE/authors-cite.h b/bin/TEMPLATE/authors-cite.h
index 5367ec5..8da944d 100644
--- a/bin/TEMPLATE/authors-cite.h
+++ b/bin/TEMPLATE/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/TEMPLATE/ui.c b/bin/TEMPLATE/ui.c
index f2f6e4f..8f11ebe 100644
--- a/bin/TEMPLATE/ui.c
+++ b/bin/TEMPLATE/ui.c
@@ -252,7 +252,7 @@ ui_check_options_and_arguments(struct TEMPLATEparams *p)
 /**************************************************************/
 /***************       Preparations         *******************/
 /**************************************************************/
-void
+static void
 ui_preparations(struct TEMPLATEparams *p)
 {
 
@@ -279,7 +279,6 @@ ui_preparations(struct TEMPLATEparams *p)
 /**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
-
 void
 ui_read_check_inputs_setup(int argc, char *argv[], struct TEMPLATEparams *p)
 {
diff --git a/bin/arithmetic/authors-cite.h b/bin/arithmetic/authors-cite.h
index 2c56a91..18a278b 100644
--- a/bin/arithmetic/authors-cite.h
+++ b/bin/arithmetic/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 8e591df..6edf638 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -232,6 +232,15 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
   size_t numfits=0, numhdus=0;
   gal_list_str_t *token, *hdu;
 
+  /* First, make sure that any tokens are actually given. */
+  if(p->tokens==NULL)
+    error(EXIT_FAILURE, 0, "no input tokens. Please specify a filename or "
+          "number (as operands) along with operator(s) as input. Please run "
+          "any of the following commands for more information.\n\n"
+          "    $ astarithmetic --help           # Short info.\n"
+          "    $ info astarithmetic             # Full invocation "
+          "documentation.\n");
+
   /* The input tokens are put in a lastin-firstout (simple) linked list, so
      change them to the correct order so the order we pop a token is the
      same order that the user input a value. Note that for the options this
diff --git a/bin/buildprog/args.h b/bin/buildprog/args.h
index a64911d..4961c87 100644
--- a/bin/buildprog/args.h
+++ b/bin/buildprog/args.h
@@ -87,6 +87,20 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_SET
     },
 
+    {
+      "tag",
+      UI_KEY_TAG,
+      "STR",
+      0,
+      "Libtool `--tag': programming language.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->tag,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+
 
 
 
diff --git a/bin/buildprog/astbuildprog.conf b/bin/buildprog/astbuildprog.conf
index 253158a..8eb1386 100644
--- a/bin/buildprog/astbuildprog.conf
+++ b/bin/buildprog/astbuildprog.conf
@@ -20,4 +20,5 @@
 
 # Output
  optimize    3
- warning     all
\ No newline at end of file
+ warning     all
+ tag         CC
diff --git a/bin/buildprog/authors-cite.h b/bin/buildprog/authors-cite.h
index dc63077..819ff91 100644
--- a/bin/buildprog/authors-cite.h
+++ b/bin/buildprog/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/buildprog/buildprog.c b/bin/buildprog/buildprog.c
index a0fc85c..d2f9ea2 100644
--- a/bin/buildprog/buildprog.c
+++ b/bin/buildprog/buildprog.c
@@ -96,9 +96,12 @@ buildprog(struct buildprogparams *p)
   else      asprintf(&fullla, "%s/libgnuastro.la", LIBDIR);
 
   /* Put the command to run into a string. */
-  asprintf(&command, "%s %s --mode=link gcc %s %s %s %s %s %s %s "
-           "-I%s %s -o %s", GAL_CONFIG_GNULIBTOOL_EXEC,
+  asprintf(&command, "%s %s %s%s --mode=link gcc %s %s %s %s %s %s %s "
+           "-I%s %s -o %s",
+           GAL_CONFIG_GNULIBTOOL_EXEC,
            p->cp.quiet ? "--quiet" : "",
+           p->tag      ? "--tag="   : "",
+           p->tag      ? p->tag    : "",
            warning     ? warning   : "",
            p->debug    ? "-g"      : "",
            optimize    ? optimize  : "",
@@ -158,5 +161,6 @@ buildprog(struct buildprogparams *p)
   free(command);
   if(warning) free(warning);
   if(optimize) free(optimize);
+  if(!p->la && fullla) free(fullla);
   return retval;
 }
diff --git a/bin/buildprog/main.h b/bin/buildprog/main.h
index b519f30..4a1f8ff 100644
--- a/bin/buildprog/main.h
+++ b/bin/buildprog/main.h
@@ -50,6 +50,7 @@ struct buildprogparams
   gal_list_str_t     *linklib;    /* Libraries to link against.         */
   char                    *la;    /* Libtool `.la' instead of default.  */
 
+  char                   *tag;    /* Libtool tag (programming language).*/
   char              *optimize;    /* Optimization level.                */
   char                 *debug;    /* Keep debugging information.        */
   char               *warning;    /* Compiler warnings.                 */
diff --git a/bin/buildprog/ui.h b/bin/buildprog/ui.h
index f937df5..bd3b295 100644
--- a/bin/buildprog/ui.h
+++ b/bin/buildprog/ui.h
@@ -50,6 +50,7 @@ enum option_keys_enum
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
   UI_KEY_DETELECOMPILED = 1000,
+  UI_KEY_TAG,
 };
 
 
diff --git a/bin/convertt/authors-cite.h b/bin/convertt/authors-cite.h
index 376124f..edae411 100644
--- a/bin/convertt/authors-cite.h
+++ b/bin/convertt/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/convolve/authors-cite.h b/bin/convolve/authors-cite.h
index 6d526a1..9d961d6 100644
--- a/bin/convolve/authors-cite.h
+++ b/bin/convolve/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/cosmiccal/authors-cite.h b/bin/cosmiccal/authors-cite.h
index a5ac70e..0d27713 100644
--- a/bin/cosmiccal/authors-cite.h
+++ b/bin/cosmiccal/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/cosmiccal/ui.c b/bin/cosmiccal/ui.c
index 00ba91e..adf1cf1 100644
--- a/bin/cosmiccal/ui.c
+++ b/bin/cosmiccal/ui.c
@@ -130,8 +130,12 @@ ui_initialize_options(struct cosmiccalparams *p,
       switch(cp->coptions[i].key)
         {
         case GAL_OPTIONS_KEY_HDU:
+        case GAL_OPTIONS_KEY_LOG:
         case GAL_OPTIONS_KEY_TYPE:
+        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:
           cp->coptions[i].flags=OPTION_HIDDEN;
diff --git a/bin/crop/args.h b/bin/crop/args.h
index 114228e..e2e9c3a 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -150,7 +150,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_width_and_center
+      gal_options_parse_csv_float64
     },
     {
       "center",
@@ -164,7 +164,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_width_and_center
+      gal_options_parse_csv_float64
     },
 
 
diff --git a/bin/crop/authors-cite.h b/bin/crop/authors-cite.h
index 6745c83..aa4cc17 100644
--- a/bin/crop/authors-cite.h
+++ b/bin/crop/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 4f2acfc..3fda416 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -239,73 +239,6 @@ ui_parse_coordinate_mode(struct argp_option *option, char 
*arg,
 
 
 
-/* Parse the width and center coordinates from the comman-line or
-   configuration files. */
-void *
-ui_parse_width_and_center(struct argp_option *option, char *arg,
-                          char *filename, size_t lineno, void *junk)
-{
-  size_t i, nc;
-  double *darray;
-  gal_data_t *values;
-  char *str, sstr[GAL_OPTIONS_STATIC_MEM_FOR_VALUES];
-
-  /* We want to print the stored values. */
-  if(lineno==-1)
-    {
-      /* Set the value pointer to the correct type. */
-      values = *(gal_data_t **)(option->value);
-      darray = values->array;
-
-      /* Write the values into a string. */
-      nc=0;
-      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 "
-                  "can address the problem. The number of necessary "
-                  "characters in the statically allocated string has become "
-                  "too close to %d", __func__, PACKAGE_BUGREPORT,
-                  GAL_OPTIONS_STATIC_MEM_FOR_VALUES);
-          nc += sprintf(sstr+nc, "%g,", darray[i]);
-        }
-      sstr[nc-1]='\0';
-
-      /* Copy the string into a dynamically allocated space, because it
-         will be freed later.*/
-      gal_checkset_allocate_copy(sstr, &str);
-      return str;
-    }
-  else
-    {
-      /* If the option is already set, then ignore it. */
-      if(option->set) return NULL;
-
-      /* Read the values. */
-      values=gal_options_parse_list_of_numbers(arg, filename, lineno);
-      *(gal_data_t **)(option->value) = values;
-
-      /* If we are on the width option, then make sure none of the values
-         are negative or zero. */
-      if(!strcmp(option->name, "width"))
-        {
-          darray=values->array;
-          for(i=0;i<values->size;++i)
-            if(darray[i]<=0.0f)
-              error_at_line(EXIT_FAILURE, 0, filename, lineno, "%g is <=0. "
-                            "The values to the `--width' option must be "
-                            "larger than zero. The complete input to this "
-                            "option was `%s' (%g is input number %zu)",
-                            darray[i], arg, darray[i], i+1);
-        }
-
-      /* The return value is only for printing mode. */
-      return NULL;
-    }
-}
-
-
-
 
 
 
@@ -330,7 +263,8 @@ ui_parse_width_and_center(struct argp_option *option, char 
*arg,
 static void
 ui_read_check_only_options(struct cropparams *p)
 {
-  int checksum;
+  double *darray;
+  int i, checksum;
 
   /* Make sure that only one of the crop definitions is given. */
   checksum = ( (p->center!=NULL)
@@ -360,6 +294,18 @@ ui_read_check_only_options(struct cropparams *p)
     }
 
 
+  /* The width values must not be negative. */
+  if(p->width)
+    {
+      darray=p->width->array;
+      for(i=0;i<p->width->size;++i)
+        if(darray[i]<=0.0f)
+          error(EXIT_FAILURE, 0, "%g is <=0. The values to the `--width' "
+                "option must be larger than zero. %g is input number %d to "
+                "this option", darray[i], darray[i], i+1);
+    }
+
+
   /* Section is currentlyl only defined in Image mode. */
   if(p->section && p->mode!=IMGCROP_MODE_IMG)
     error(EXIT_FAILURE, 0, "The `--section' option is only available in "
diff --git a/bin/fits/authors-cite.h b/bin/fits/authors-cite.h
index 2a674a1..ec4b666 100644
--- a/bin/fits/authors-cite.h
+++ b/bin/fits/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index 880ea35..6713c10 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -224,7 +224,7 @@ ui_read_check_only_options(struct fitsparams *p)
   /* If any of the keyword manipulation options are requested, then set the
      mode flag to keyword-mode. */
   if( p->date || p->comment || p->history || p->asis || p->delete
-      || p->rename || p->rename || p->update || p->write || p->printallkeys )
+      || p->rename || p->update || p->write || p->printallkeys )
     {
       /* Set the mode. */
       p->mode=FITS_MODE_KEY;
diff --git a/bin/match/Makefile.am b/bin/match/Makefile.am
new file mode 100644
index 0000000..59595bc
--- /dev/null
+++ b/bin/match/Makefile.am
@@ -0,0 +1,41 @@
+## Process this file with automake to produce Makefile.inx
+##
+## Original author:
+##     Mohammad Akhlaghi <akhlaghi@gnu.org>
+## Contributing author(s):
+## Copyright (C) 2017, Free Software Foundation, Inc.
+##
+## Gnuastro is free software: you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+##
+## Gnuastro is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+
+
+## Pre-processer flags (for Gnulib's headers). Recall that the compiled
+## Gnulib library was statically linked to (copied in) Gnuastro's library.
+AM_CPPFLAGS = -I\$(top_srcdir)/bootstrapped/lib
+
+
+
+## Program definition (name, linking, sources and headers)
+bin_PROGRAMS = astmatch
+
+astmatch_LDADD = -lgnuastro
+
+astmatch_SOURCES = main.c ui.c match.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h match.h
+
+
+
+## The configuration file (distribute and install).
+## NOTE: the man page is created in doc/Makefile.am
+dist_sysconf_DATA = astmatch.conf
diff --git a/bin/buildprog/args.h b/bin/match/args.h
similarity index 52%
copy from bin/buildprog/args.h
copy to bin/match/args.h
index a64911d..ab95b57 100644
--- a/bin/buildprog/args.h
+++ b/bin/match/args.h
@@ -1,6 +1,6 @@
 /*********************************************************************
-BuildProgram: Compile and run programs using Gnuastro's library
-BuildProgram is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -31,58 +31,35 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Array of acceptable options. */
 struct argp_option program_options[] =
   {
+    /* Input file parameters. */
     {
-      "includedir",
-      UI_KEY_INCLUDE,
-      "STR",
+      "hdu2",
+      GAL_OPTIONS_KEY_HDU,
+      "STR/INT",
       0,
-      "Directories to search for `#include's.",
+      "Extension name or number of second input.",
       GAL_OPTIONS_GROUP_INPUT,
-      &p->include,
-      GAL_TYPE_STRLL,
+      &p->hdu2,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
 
-    {
-      "linkdir",
-      UI_KEY_LINKDIR,
-      "STR",
-      0,
-      "Directory to search for libraries to link.",
-      GAL_OPTIONS_GROUP_INPUT,
-      &p->linkdir,
-      GAL_TYPE_STRLL,
-      GAL_OPTIONS_RANGE_ANY,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
-    },
 
-    {
-      "linklib",
-      UI_KEY_LINKLIB,
-      "STR",
-      0,
-      "Link libraries, e.g., for libgsl: `-lgsl'.",
-      GAL_OPTIONS_GROUP_INPUT,
-      &p->linklib,
-      GAL_TYPE_STRLL,
-      GAL_OPTIONS_RANGE_ANY,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
-    },
 
+
+    /* Outputs. */
     {
-      "la",
-      UI_KEY_LA,
-      "STR",
+      "logasoutput",
+      UI_KEY_LOGASOUTPUT,
       0,
-      "Libtool `.la' to use instead of default.",
-      GAL_OPTIONS_GROUP_INPUT,
-      &p->la,
-      GAL_TYPE_STRING,
-      GAL_OPTIONS_RANGE_ANY,
+      0,
+      "No rearranging of inputs, output is log file",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->logasoutput,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
@@ -90,73 +67,56 @@ struct argp_option program_options[] =
 
 
 
-
+    /* Catalog matching. */
     {
-      "debug",
-      UI_KEY_DEBUG,
-      0,
-      0,
-      "Debugging information in compiled binary.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->debug,
-      GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_ANY,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      0, 0, 0, 0,
+      "Catalog matching",
+      UI_GROUP_CATALOGMATCH
     },
     {
-      "optimize",
-      UI_KEY_OPTIMIZE,
-      "INT",
+      "ccol1",
+      UI_KEY_CCOL1,
+      "STR[,STR]",
       0,
-      "Optimization level: 0, 1, 2, 3.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->optimize,
+      "Column name/number of first catalog.",
+      UI_GROUP_CATALOGMATCH,
+      &p->ccol1,
       GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_strings
     },
     {
-      "warning",
-      UI_KEY_WARNING,
-      "STR",
+      "ccol2",
+      UI_KEY_CCOL2,
+      "STR[,STR]",
       0,
-      "Compilation warnings on command-line.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->warning,
+      "Column name/number of second catalog.",
+      UI_GROUP_CATALOGMATCH,
+      &p->ccol2,
       GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
-    },
-    {
-      "onlybuild",
-      UI_KEY_ONLYBUILD,
-      0,
-      0,
-      "Don't run the built program.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->onlybuild,
-      GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_strings
     },
     {
-      "deletecompiled",
-      UI_KEY_DETELECOMPILED,
-      0,
+      "aperture",
+      UI_KEY_APERTURE,
+      "FLT[,FLT[,FLT]]",
       0,
-      "Delete compiled program after running.",
-      GAL_OPTIONS_GROUP_OUTPUT,
-      &p->deletecompiled,
-      GAL_OPTIONS_NO_ARG_TYPE,
+      "Acceptable aperture for matching.",
+      UI_GROUP_CATALOGMATCH,
+      &p->aperture,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_float64
     },
 
+
     {0}
   };
 
diff --git a/bin/buildprog/astbuildprog.conf b/bin/match/astmatch.conf
similarity index 63%
copy from bin/buildprog/astbuildprog.conf
copy to bin/match/astmatch.conf
index 253158a..6506993 100644
--- a/bin/buildprog/astbuildprog.conf
+++ b/bin/match/astmatch.conf
@@ -1,5 +1,5 @@
-# Default parameters (System) for BuildProgram.
-# BuildProgram is part of GNU Astronomy Utitlies.
+# Default parameters (System) for Match.
+# Match is part of GNU Astronomy Utilities.
 #
 # Use the long option name of each parameter followed by a value. The name
 # and value should be separated by atleast one white-space character (for
@@ -7,9 +7,9 @@
 #
 # For more information, please run these commands:
 #
-#  $ astbuildprog --help                 # Full list of options, short doc.
-#  $ astbuildprog -P                     # Print all options and used values.
-#  $ info astbuildprog                   # All options and input/output.
+#  $ astmatch --help                     # Full list of options, short doc.
+#  $ astmatch -P                         # Print all options and used values.
+#  $ info astmatch                       # All options and input/output.
 #  $ info gnuastro "Configuration files" # How to use configuration files.
 #
 # Copying and distribution of this file, with or without modification, are
@@ -17,7 +17,9 @@
 # this notice are preserved.  This file is offered as-is, without any
 # warranty.
 
+# Input
+ hdu2            1
 
-# Output
- optimize    3
- warning     all
\ No newline at end of file
+# Catalog matching
+ ccol1           2,3
+ ccol2           2,3
\ No newline at end of file
diff --git a/bin/mknoise/authors-cite.h b/bin/match/authors-cite.h
similarity index 88%
copy from bin/mknoise/authors-cite.h
copy to bin/match/authors-cite.h
index 3a4bb5e..8a5efbd 100644
--- a/bin/mknoise/authors-cite.h
+++ b/bin/match/authors-cite.h
@@ -1,6 +1,6 @@
 /*********************************************************************
-MakeNoise - Add noise to a dataset.
-MakeNoise is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/mknoise/authors-cite.h b/bin/match/main.c
similarity index 55%
copy from bin/mknoise/authors-cite.h
copy to bin/match/main.c
index 3a4bb5e..8186ecd 100644
--- a/bin/mknoise/authors-cite.h
+++ b/bin/match/main.c
@@ -1,6 +1,6 @@
 /*********************************************************************
-MakeNoise - Add noise to a dataset.
-MakeNoise is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -20,19 +20,39 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef AUTHORS_CITE_H
-#define AUTHORS_CITE_H
+#include <config.h>
 
-/* When any specific citation is necessary, please add its BibTeX (from ADS
-   hopefully) to this variable along with a title decribing what this
-   paper/book does for the progarm in a short line. In the following line
-   put a row of `-' with the same length and then put the BibTeX.
+#include <stdio.h>
+#include <stdlib.h>
 
-   See the `gnuastro_bibtex' variable in `lib/options' (from the top
-   Gnuastro source code directory) as an example.*/
+#include <gnuastro-internal/timing.h>
 
-#define PROGRAM_BIBTEX "";
+#include "main.h"
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#include "ui.h"
+#include "match.h"
 
-#endif
+
+/* Main function */
+int
+main (int argc, char *argv[])
+{
+  struct timeval t1;
+  struct matchparams p={{{0},0},0};
+
+  /* Set they starting time. */
+  time(&p.rawtime);
+  gettimeofday(&t1, NULL);
+
+  /* Read the input parameters. */
+  ui_read_check_inputs_setup(argc, argv, &p);
+
+  /* Run MakeProfiles */
+  match(&p);
+
+  /* Free all non-freed allocations. */
+  ui_free_report(&p, &t1);
+
+  /* Return successfully.*/
+  return EXIT_SUCCESS;
+}
diff --git a/bin/buildprog/main.h b/bin/match/main.h
similarity index 52%
copy from bin/buildprog/main.h
copy to bin/match/main.h
index b519f30..6d065f7 100644
--- a/bin/buildprog/main.h
+++ b/bin/match/main.h
@@ -1,6 +1,6 @@
 /*********************************************************************
-BuildProgram: Compile and run programs using Gnuastro's library
-BuildProgram is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -29,32 +29,42 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro-internal/options.h>
 
 /* Progarm names.  */
-#define PROGRAM_NAME   "BuildProgram"    /* Program full name.       */
-#define PROGRAM_EXEC   "astbuildprog"    /* Program executable name. */
+#define PROGRAM_NAME   "Match"    /* Program full name.       */
+#define PROGRAM_EXEC   "astmatch" /* Program executable name. */
 #define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
 
+enum match_modes
+{
+  MATCH_MODE_INVALID,           /* ==0 by default. */
+  MATCH_MODE_WCS,
+  MATCH_MODE_CATALOG,
+};
 
 
 
 
 /* Main program parameters structure */
-struct buildprogparams
+struct matchparams
 {
   /* From command-line */
   struct gal_options_common_params     cp; /* Common parameters.        */
-  gal_list_str_t  *sourceargs;    /* Source files and arguments.        */
-  gal_list_str_t     *include;    /* Libraries to link against.         */
-  gal_list_str_t     *linkdir;    /* Libraries to link against.         */
-  gal_list_str_t     *linklib;    /* Libraries to link against.         */
-  char                    *la;    /* Libtool `.la' instead of default.  */
-
-  char              *optimize;    /* Optimization level.                */
-  char                 *debug;    /* Keep debugging information.        */
-  char               *warning;    /* Compiler warnings.                 */
-  uint8_t           onlybuild;    /* Don't run the compiled program.    */
-  uint8_t      deletecompiled;    /* Delete compiled program after running. */
+  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           *ccol2;  /* Array of second input column names.  */
+  gal_data_t        *aperture;  /* Acceptable matching aperture.        */
+  uint8_t         logasoutput;  /* Don't rearrange inputs, out is log.  */
+
+  /* Internal */
+  int                    mode;  /* Mode of operation: image or catalog. */
+  gal_data_t           *cols1;  /* Column values of first input.        */
+  gal_data_t           *cols2;  /* Column values of second input.       */
+  char               *logname;  /* Name of log file.                    */
+  char              *out1name;  /* Name of first matched output.        */
+  char              *out2name;  /* Name of second matched output.       */
 
   /* Output: */
   time_t              rawtime;  /* Starting time of the program.        */
diff --git a/bin/match/match.c b/bin/match/match.c
new file mode 100644
index 0000000..09260b1
--- /dev/null
+++ b/bin/match/match.c
@@ -0,0 +1,180 @@
+/*********************************************************************
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <akhlaghi@gnu.org>
+Contributing author(s):
+Copyright (C) 2017, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gnuastro/match.h>
+#include <gnuastro/table.h>
+#include <gnuastro/permutation.h>
+
+#include <gnuastro-internal/checkset.h>
+
+#include <main.h>
+
+
+
+
+
+/* Read the catalog in the given file and use the given permutation to keep
+   the proper columns. */
+static void
+match_catalog_write(struct matchparams *p, char *filename, char *hdu,
+                    size_t *permutation, size_t nummatched, char *outname,
+                    char *extname)
+{
+  gal_data_t *tmp, *cat;
+
+  /* Read the full table. */
+  cat=gal_table_read(filename, hdu, NULL,p->cp.searchin, p->cp.ignorecase,
+                     p->cp.minmapsize);
+
+  /* Go over each column and permute its contents. */
+  for(tmp=cat; tmp!=NULL; tmp=tmp->next)
+    {
+      /* Do the permutation. */
+      gal_permutation_apply(tmp, permutation);
+
+      /* Correct the size of the array so only the matching columns are
+         saved as output. This is only Gnuastro's convention, it has no
+         effect on later freeing of the array in the memory. */
+      tmp->size=tmp->dsize[0]=nummatched;
+    }
+
+  /* Write the catalog to the output. */
+  gal_table_write(cat, NULL, p->cp.tableformat, outname, extname);
+
+  /* Clean up. */
+  gal_list_data_free(cat);
+}
+
+
+
+
+
+static void
+match_catalog(struct matchparams *p)
+{
+  uint32_t *u, *uf;
+  size_t nummatched;
+  gal_data_t *tmp, *mcols;
+
+  /* Find the matching coordinates. We are doing the processing in
+     place, */
+  mcols=gal_match_coordinates(p->cols1, p->cols2, p->aperture->array, 0, 1,
+                              p->cp.minmapsize, &nummatched);
+
+  /* If a match was found, then make the output files. */
+  if(mcols)
+    {
+      /* Read all the first catalog columns. */
+      if(p->logasoutput==0)
+        {
+          match_catalog_write(p, p->input1name, p->cp.hdu, mcols->array,
+                              nummatched, p->out1name, "INPUT_1");
+          match_catalog_write(p, p->input2name, p->cp.hdu, mcols->next->array,
+                              nummatched, p->out2name, "INPUT_2");
+        }
+
+      /* Write the raw information in a log file if necessary.  */
+      if(p->logname)
+        {
+          /* Note that unsigned 64-bit integers are not recognized in FITS
+             tables. So if the log file is a FITS table, covert the two
+             index columns to uint32. */
+          tmp=gal_data_copy_to_new_type(mcols, GAL_TYPE_UINT32);
+          tmp->next=mcols->next;
+          tmp->size=nummatched;
+          gal_data_free(mcols);
+          mcols=tmp;
+
+          /* We also want everything to be incremented by one. In a C
+             program, counting starts with zero, so `gal_match_coordinates'
+             will return indexs starting from zero. But outside a C
+             program, on the command-line people expect counting to start
+             from 1 (for example with AWK). */
+          uf = (u=mcols->array) + tmp->size; do (*u)++; while(++u<uf);
+
+          /* Same for the second set of indexs. */
+          tmp=gal_data_copy_to_new_type(mcols->next, GAL_TYPE_UINT32);
+          uf = (u=tmp->array) + tmp->size; do (*u)++; while(++u<uf);
+          tmp->next=mcols->next->next;
+          gal_data_free(mcols->next);
+          tmp->size=nummatched;
+          mcols->next=tmp;
+
+          /* Correct the comments. */
+          free(mcols->comment);
+          mcols->comment="Row index in first catalog (counting from 1).";
+          free(mcols->next->comment);
+          mcols->next->comment="Row index in second catalog (counting "
+            "from 1).";
+
+          /* Write them into the table. */
+          gal_table_write(mcols, NULL, p->cp.tableformat, p->logname,
+                          "LOG_INFO");
+
+          /* Set the comment pointer to NULL: they weren't allocated. */
+          mcols->comment=NULL;
+          mcols->next->comment=NULL;
+        }
+      gal_list_data_free(mcols);
+    }
+
+  /* Print the number of matches if not in quiet mode. */
+  if(!p->cp.quiet)
+    fprintf(stdout, "%zu", nummatched);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/*******************************************************************/
+/*************            Top level function           *************/
+/*******************************************************************/
+void
+match(struct matchparams *p)
+{
+  if(p->mode==MATCH_MODE_CATALOG)
+    match_catalog(p);
+}
diff --git a/bin/mknoise/authors-cite.h b/bin/match/match.h
similarity index 58%
copy from bin/mknoise/authors-cite.h
copy to bin/match/match.h
index 3a4bb5e..6911dc4 100644
--- a/bin/mknoise/authors-cite.h
+++ b/bin/match/match.h
@@ -1,6 +1,6 @@
 /*********************************************************************
-MakeNoise - Add noise to a dataset.
-MakeNoise is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -20,19 +20,10 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef AUTHORS_CITE_H
-#define AUTHORS_CITE_H
+#ifndef MATCH_H
+#define MATCH_H
 
-/* When any specific citation is necessary, please add its BibTeX (from ADS
-   hopefully) to this variable along with a title decribing what this
-   paper/book does for the progarm in a short line. In the following line
-   put a row of `-' with the same length and then put the BibTeX.
-
-   See the `gnuastro_bibtex' variable in `lib/options' (from the top
-   Gnuastro source code directory) as an example.*/
-
-#define PROGRAM_BIBTEX "";
-
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+void
+match(struct matchparams *p);
 
 #endif
diff --git a/bin/match/ui.c b/bin/match/ui.c
new file mode 100644
index 0000000..b625545
--- /dev/null
+++ b/bin/match/ui.c
@@ -0,0 +1,688 @@
+/*********************************************************************
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <akhlaghi@gnu.org>
+Contributing author(s):
+Copyright (C) 2017, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <argp.h>
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+
+#include <gnuastro/fits.h>
+
+#include <gnuastro-internal/timing.h>
+#include <gnuastro-internal/options.h>
+#include <gnuastro-internal/checkset.h>
+#include <gnuastro-internal/fixedstringmacros.h>
+
+#include "main.h"
+
+#include "ui.h"
+#include "authors-cite.h"
+
+
+
+
+
+/**************************************************************/
+/*********      Argp necessary global entities     ************/
+/**************************************************************/
+/* Definition parameters for the Argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
+
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
+
+static char
+args_doc[] = "ASTRdata";
+
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" matches catalogs of objects "
+  "and (by default) will return the re-arranged matching inputs. The "
+  "optional log file will return low-level information about the match "
+  "(indexs and distances).\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/*********    Initialize & Parse command-line    **************/
+/**************************************************************/
+static void
+ui_initialize_options(struct matchparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
+{
+  size_t i;
+  struct gal_options_common_params *cp=&p->cp;
+
+
+  /* Set the necessary common parameters structure. */
+  cp->poptions           = program_options;
+  cp->program_name       = PROGRAM_NAME;
+  cp->program_exec       = PROGRAM_EXEC;
+  cp->program_bibtex     = PROGRAM_BIBTEX;
+  cp->program_authors    = PROGRAM_AUTHORS;
+  cp->coptions           = gal_commonopts_options;
+
+
+  /* Modify common options. */
+  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
+    {
+      /* Select individually. */
+      switch(cp->coptions[i].key)
+        {
+        case GAL_OPTIONS_KEY_HDU:
+          cp->coptions[i].doc="Extension name or number of first input.";
+          break;
+        case GAL_OPTIONS_KEY_TYPE:
+        case GAL_OPTIONS_KEY_NUMTHREADS:
+          cp->coptions[i].flags=OPTION_HIDDEN;
+          break;
+        }
+
+      /* Select by group. */
+      switch(cp->coptions[i].group)
+        {
+        case GAL_OPTIONS_GROUP_TESSELLATION:
+          cp->coptions[i].doc=NULL; /* Necessary to remove title. */
+          cp->coptions[i].flags=OPTION_HIDDEN;
+          break;
+        }
+    }
+}
+
+
+
+
+
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+  struct matchparams *p = state->input;
+
+  /* Pass `gal_options_common_params' into the child parser.  */
+  state->child_inputs[0] = &p->cp;
+
+  /* In case the user incorrectly uses the equal sign (for example
+     with a short format or with space in the long format, then `arg`
+     start with (if the short version was called) or be (if the long
+     version was called with a space) the equal sign. So, here we
+     check if the first character of arg is the equal sign, then the
+     user is warned and the program is stopped: */
+  if(arg && arg[0]=='=')
+    argp_error(state, "incorrect use of the equal sign (`=`). For short "
+               "options, `=` should not be used and for long options, "
+               "there should be no space between the option, equal sign "
+               "and value");
+
+  /* Set the key to this option. */
+  switch(key)
+    {
+
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      if(p->input1name)
+        {
+          if(p->input2name)
+            argp_error(state, "only two arguments (input files) should be "
+                       "given");
+          else
+            p->input2name=arg;
+        }
+      else
+        p->input1name=arg;
+      break;
+
+
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
+
+  return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Sanity Check         *******************/
+/**************************************************************/
+/* Read and check ONLY the options. When arguments are involved, do the
+   check in `ui_check_options_and_arguments'. */
+static void
+ui_read_check_only_options(struct matchparams *p)
+{
+
+}
+
+
+
+
+
+static void
+ui_check_options_and_arguments(struct matchparams *p)
+{
+  /* Make sure two input file names were given and if they a FITS file,
+     that a HDU is also given for each. */
+  if(p->input1name)
+    {
+      if( gal_fits_name_is_fits(p->input1name) && p->cp.hdu==NULL )
+        error(EXIT_FAILURE, 0, "no HDU for first input. When the input is "
+              "a FITS file, a HDU must also be specified, you can use the "
+              "`--hdu' (`-h') option and give it the HDU number (starting "
+              "from zero), extension name, or anything acceptable by "
+              "CFITSIO");
+    }
+  else
+    error(EXIT_FAILURE, 0, "no input file is specified: two inputs are "
+          "necessary");
+
+  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");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/***************       Preparations         *******************/
+/**************************************************************/
+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. */
+  if( 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 );
+  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) )
+    {
+      if(gal_fits_hdu_format(p->input2name, p->hdu2) == IMAGE_HDU)
+        {
+          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) );
+        }
+      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));
+        }
+    }
+  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));
+}
+
+
+
+
+
+/* The final aperture must have the following values:
+
+       p->aperture[0]: Major axis length.
+       p->aperture[1]: Axis ratio.
+       p->aperture[2]: Position angle (relative to first dim).     */
+static void
+ui_read_columns_aperture_2d(struct matchparams *p)
+{
+  size_t apersize=3;
+  gal_data_t *newaper=NULL;
+  double *naper, *oaper=p->aperture->array;
+
+  /* A general sanity check: the first two elements of aperture cannot be
+     zero or negative. */
+  if( oaper[0]<=0 )
+    error(EXIT_FAILURE, 0, "the first value of `--aperture' cannot be "
+          "zero or negative");
+  if( p->aperture->size>1 && oaper[1]<=0 )
+    error(EXIT_FAILURE, 0, "the second value of `--aperture' cannot be "
+          "zero or negative");
+
+  /* Will be needed in more than one case. */
+  if(p->aperture->size!=3)
+    {
+      newaper=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &apersize, NULL,
+                             0, -1, NULL, NULL, NULL);
+      naper=newaper->array;
+    }
+
+  /* Different based on  */
+  switch(p->aperture->size)
+    {
+    case 1:
+      naper[0]=oaper[0];
+      naper[1]=1;
+      naper[2]=0;
+      break;
+
+    case 2:
+      naper[0] = oaper[0]>oaper[1] ? oaper[0]          : oaper[1];
+      naper[1] = oaper[0]>oaper[1] ? oaper[1]/oaper[0] : oaper[0]/oaper[1];
+      naper[2] = oaper[0]>oaper[1] ? 0                 : 90;
+      break;
+
+    case 3:
+      if(oaper[1]>1)
+        error(EXIT_FAILURE, 0, "second value to `--aperture' is larger "
+              "than one. When three numbers are given to this option, the "
+              "second is the axis ratio (which must always be less than 1).");
+      break;
+
+    default:
+      error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. In 2D, this "
+            "option can only take 1, 2, or 3 values", p->aperture->size);
+    }
+
+  /* If a new aperture was defined, then replace it with the exitsting
+     one. */
+  if(newaper)
+    {
+      gal_data_free(p->aperture);
+      p->aperture=newaper;
+    }
+}
+
+
+
+
+
+/* Read catalog columns */
+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;
+  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).";
+
+  /* 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;
+
+      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);
+
+
+  /* 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, 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, 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),
+              gal_list_data_number(p->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");
+
+  /* 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;
+}
+
+
+
+
+
+static void
+ui_preparations_out_name(struct matchparams *p)
+{
+  if(p->logasoutput)
+    {
+      /* Set the logname (as output). */
+      if(p->cp.output)
+        gal_checkset_allocate_copy(p->cp.output, &p->logname);
+      else
+        {
+          if(p->cp.tableformat==GAL_TABLE_FORMAT_TXT)
+            p->logname=gal_checkset_automatic_output(&p->cp, p->input1name,
+                                                     "_matched.txt");
+          else
+            p->logname=gal_checkset_automatic_output(&p->cp, p->input1name,
+                                                     "_matched.fits");
+        }
+
+      /* Make sure a file with this name doesn't exist. */
+      gal_checkset_writable_remove(p->out1name, 0, p->cp.dontdelete);
+    }
+  else
+    {
+      /* Set `p->out1name' and `p->out2name'. */
+      if(p->cp.output)
+        {
+          if( gal_fits_name_is_fits(p->cp.output) )
+            {
+              gal_checkset_allocate_copy(p->cp.output, &p->out1name);
+              gal_checkset_allocate_copy(p->cp.output, &p->out2name);
+            }
+          else
+            {
+              p->out1name=gal_checkset_automatic_output(&p->cp, p->cp.output,
+                                                        "_matched_1.txt");
+              p->out2name=gal_checkset_automatic_output(&p->cp, p->cp.output,
+                                                        "_matched_2.txt");
+            }
+        }
+      else
+        {
+          if(p->cp.tableformat==GAL_TABLE_FORMAT_TXT)
+            {
+              p->out1name=gal_checkset_automatic_output(&p->cp, p->input1name,
+                                                        "_matched_1.txt");
+              p->out2name=gal_checkset_automatic_output(&p->cp, p->input2name,
+                                                        "_matched_2.txt");
+            }
+          else
+            {
+              p->out1name=gal_checkset_automatic_output(&p->cp, p->input1name,
+                                                        "_matched.fits");
+              gal_checkset_allocate_copy(p->out1name, &p->out2name);
+            }
+        }
+
+      /* Make sure no file with these names exists. */
+      gal_checkset_writable_remove(p->out1name, 0, p->cp.dontdelete);
+      gal_checkset_writable_remove(p->out2name, 0, p->cp.dontdelete);
+
+      /* If a log file is necessary, set its name here. */
+      if(p->cp.log)
+        {
+          p->logname = ( p->cp.tableformat==GAL_TABLE_FORMAT_TXT
+                         ? PROGRAM_EXEC".txt"
+                         : PROGRAM_EXEC".fits" );
+          gal_checkset_writable_remove(p->logname, 0, p->cp.dontdelete);
+        }
+    }
+}
+
+
+
+
+
+static void
+ui_preparations(struct matchparams *p)
+{
+  /* Set the mode of the program. */
+  ui_set_mode(p);
+
+  /* Currently Match only works on catalogs. */
+  if(p->mode==MATCH_MODE_WCS)
+    error(EXIT_FAILURE, 0, "currently Match only works on catalogs, we will "
+          "implement the WCS matching routines later");
+  else
+    ui_read_columns(p);
+
+  /* Set the output filename. */
+  ui_preparations_out_name(p);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/************         Set the parameters          *************/
+/**************************************************************/
+void
+ui_read_check_inputs_setup(int argc, char *argv[], struct matchparams *p)
+{
+  struct gal_options_common_params *cp=&p->cp;
+
+
+  /* Include the parameters necessary for argp from this program (`args.h')
+     and for the common options to all Gnuastro (`commonopts.h'). We want
+     to directly put the pointers to the fields in `p' and `cp', so we are
+     simply including the header here to not have to use long macros in
+     those headers which make them hard to read and modify. This also helps
+     in having a clean environment: everything in those headers is only
+     available within the scope of this function. */
+#include <gnuastro-internal/commonopts.h>
+#include "args.h"
+
+
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
+
+
+  /* Read the command-line options and arguments. */
+  errno=0;
+  if(argp_parse(&thisargp, argc, argv, 0, 0, p))
+    error(EXIT_FAILURE, errno, "parsing arguments");
+
+
+  /* Read the configuration files and set the common values. */
+  gal_options_read_config_set(&p->cp);
+
+
+  /* Read the options into the program's structure, and check them and
+     their relations prior to printing. */
+  ui_read_check_only_options(p);
+
+
+  /* Print the option values if asked. Note that this needs to be done
+     after the option checks so un-sane values are not printed in the
+     output state. */
+  gal_options_print_state(&p->cp);
+
+
+  /* Check that the options and arguments fit well with each other. Note
+     that arguments don't go in a configuration file. So this test should
+     be done after (possibly) printing the option values. */
+  ui_check_options_and_arguments(p);
+
+
+  /* Read/allocate all the necessary starting arrays. */
+  ui_preparations(p);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
+/************      Free allocated, report         *************/
+/**************************************************************/
+void
+ui_free_report(struct matchparams *p, struct timeval *t1)
+{
+  /* Free the allocated arrays: */
+  free(p->cp.hdu);
+  free(p->out1name);
+  free(p->out2name);
+  free(p->cp.output);
+
+  /* Print the final message.
+  if(!p->cp.quiet)
+    gal_timing_report(t1, PROGRAM_NAME" finished in: ", 0);
+  */
+}
diff --git a/bin/buildprog/ui.h b/bin/match/ui.h
similarity index 66%
copy from bin/buildprog/ui.h
copy to bin/match/ui.h
index f937df5..d5d9d7e 100644
--- a/bin/buildprog/ui.h
+++ b/bin/match/ui.h
@@ -1,6 +1,6 @@
 /*********************************************************************
-BuildProgram: Compile and run programs using Gnuastro's library
-BuildProgram is part of GNU Astronomy Utilities (Gnuastro) package.
+Match - A program to match catalogs and WCS warps
+Match is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
@@ -28,28 +28,32 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
+/* Group codes. */
+enum program_args_groups
+{
+  UI_GROUP_CATALOGMATCH = GAL_OPTIONS_GROUP_AFTER_COMMON,
+};
+
+
+
 
 
 /* Available letters for short options:
 
-   c d e f i j k n p r s t u v w x y z
-   A B C E G H J Q R X Y
+   b c d e f g i j k m n p r s t u v w x y z
+   A B C E G J L O Q R W X Y
 */
 enum option_keys_enum
 {
   /* With short-option version. */
-  UI_KEY_INCLUDE        = 'I',
-  UI_KEY_LINKDIR        = 'L',
-  UI_KEY_LINKLIB        = 'l',
-  UI_KEY_LA             = 'a',
-  UI_KEY_ONLYBUILD      = 'b',
-  UI_KEY_DEBUG          = 'g',
-  UI_KEY_OPTIMIZE       = 'O',
-  UI_KEY_WARNING        = 'W',
+  UI_KEY_HDU2            = 'H',
+  UI_KEY_APERTURE        = 'a',
+  UI_KEY_LOGASOUTPUT     = 'l',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
-  UI_KEY_DETELECOMPILED = 1000,
+  UI_KEY_CCOL1           = 1000,
+  UI_KEY_CCOL2,
 };
 
 
@@ -57,9 +61,9 @@ enum option_keys_enum
 
 
 void
-ui_read_check_inputs_setup(int argc, char *argv[], struct buildprogparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct matchparams *p);
 
 void
-ui_free_report(struct buildprogparams *p);
+ui_free_report(struct matchparams *p, struct timeval *t1);
 
 #endif
diff --git a/bin/mkcatalog/authors-cite.h b/bin/mkcatalog/authors-cite.h
index eaa3427..a6e994c 100644
--- a/bin/mkcatalog/authors-cite.h
+++ b/bin/mkcatalog/authors-cite.h
@@ -49,6 +49,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
   "  adsnote = {Provided by the SAO/NASA Astrophysics Data System}\n"  \
   "};\n"
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/mkcatalog/ui.c b/bin/mkcatalog/ui.c
index e76cb3d..3ad935b 100644
--- a/bin/mkcatalog/ui.c
+++ b/bin/mkcatalog/ui.c
@@ -347,7 +347,7 @@ ui_wcs_info(struct mkcatalogparams *p)
              or where there is a dash. So we can just replace it with an
              end-of-string character. */
           gal_checkset_allocate_copy(p->input->wcs->ctype[i], &p->ctype[i]);
-          for(c=p->ctype[i]; *c!='\0' && *c!='-'; ++c) c=c;
+          c=p->ctype[i]; while(*c!='\0' && *c!='-') ++c;
           *c='\0';
         }
     }
diff --git a/bin/mknoise/authors-cite.h b/bin/mknoise/authors-cite.h
index 3a4bb5e..7bf93f7 100644
--- a/bin/mknoise/authors-cite.h
+++ b/bin/mknoise/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/mkprof/args.h b/bin/mkprof/args.h
index b38b91b..c13308f 100644
--- a/bin/mkprof/args.h
+++ b/bin/mkprof/args.h
@@ -511,7 +511,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_numbers
+      gal_options_parse_csv_float64
     },
     {
       "crval",
@@ -525,7 +525,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_numbers
+      gal_options_parse_csv_float64
     },
     {
       "cdelt",
@@ -539,7 +539,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_numbers
+      gal_options_parse_csv_float64
     },
     {
       "pc",
@@ -553,7 +553,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      ui_parse_numbers
+      gal_options_parse_csv_float64
     },
     {
       "cunit",
diff --git a/bin/mkprof/authors-cite.h b/bin/mkprof/authors-cite.h
index f65b516..d48db6b 100644
--- a/bin/mkprof/authors-cite.h
+++ b/bin/mkprof/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/mkprof/main.h b/bin/mkprof/main.h
index 8ff9c37..17ae8b0 100644
--- a/bin/mkprof/main.h
+++ b/bin/mkprof/main.h
@@ -40,7 +40,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 /* Some constants */
 #define EPSREL_FOR_INTEG   2
-#define DEGREESTORADIANS   M_PI/180.0f
+#define DEGREESTORADIANS   M_PI/180.0
 
 
 /* Modes to interpret coordinates. */
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 3249c17..a6b2dcd 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -447,63 +447,6 @@ ui_parse_kernel(struct argp_option *option, char *arg,
 
 
 
-/* Parse options with values of a list of numbers. */
-void *
-ui_parse_numbers(struct argp_option *option, char *arg,
-                 char *filename, size_t lineno, void *junk)
-{
-  int i;
-  size_t nc;
-  double *darr;
-  gal_data_t *values;
-  char *str, sstr[GAL_OPTIONS_STATIC_MEM_FOR_VALUES];
-
-  /* We want to print the stored values. */
-  if(lineno==-1)
-    {
-      /* Set the pointer to the values dataset. */
-      values = *(gal_data_t **)(option->value);
-
-      /* Write each string into the output string */
-      nc=0;
-      darr=values->array;
-      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 "
-                  "can address the problem. The number of necessary "
-                  "characters in the statically allocated string has become "
-                  "too close to %d", __func__, PACKAGE_BUGREPORT,
-                  GAL_OPTIONS_STATIC_MEM_FOR_VALUES);
-          nc += sprintf(sstr+nc, "%g,", darr[i]);
-        }
-      sstr[nc-1]='\0';
-
-      /* Copy the string into a dynamically allocated space, because it
-         will be freed later.*/
-      gal_checkset_allocate_copy(sstr, &str);
-      return str;
-    }
-
-  /* We want to read the user's string. */
-  else
-    {
-      /* If the option is already set, just return. */
-      if(option->set) return NULL;
-
-      /* Read the values. */
-      values=gal_options_parse_list_of_numbers(arg, filename, lineno);
-
-      /* Put the values into the option. */
-      *(gal_data_t **)(option->value) = values;
-      return NULL;
-    }
-}
-
-
-
-
-
 /* Parse the mode to interpret the given coordinates. */
 void *
 ui_parse_coordinate_mode(struct argp_option *option, char *arg,
diff --git a/bin/noisechisel/authors-cite.h b/bin/noisechisel/authors-cite.h
index caaca75..f588515 100644
--- a/bin/noisechisel/authors-cite.h
+++ b/bin/noisechisel/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/noisechisel/clumps.c b/bin/noisechisel/clumps.c
index 04a5cab..e6ca9cb 100644
--- a/bin/noisechisel/clumps.c
+++ b/bin/noisechisel/clumps.c
@@ -844,7 +844,7 @@ clumps_make_sn_table(struct clumps_thread_params *cltprm)
 
 
   /* If there were no initial clumps, then ignore this function. */
-  if(cltprm->numinitclumps==0) { cltprm->sn=NULL; return; }
+  if(cltprm->numinitclumps==0) { cltprm->snind=cltprm->sn=NULL; return; }
 
 
   /* Allocate the arrays to keep the final S/N table (and possibly S/N
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index 41c561a..222ca56 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -410,7 +410,6 @@ ui_set_output_names(struct noisechiselparams *p)
   if(p->checksegmentation)
     p->segmentationname=gal_checkset_automatic_output(&p->cp, basename,
                                                       "_seg.fits");
-
 }
 
 
diff --git a/bin/statistics/authors-cite.h b/bin/statistics/authors-cite.h
index 185a930..0cdee03 100644
--- a/bin/statistics/authors-cite.h
+++ b/bin/statistics/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/table/authors-cite.h b/bin/table/authors-cite.h
index d3bc2a0..242282a 100644
--- a/bin/table/authors-cite.h
+++ b/bin/table/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bin/table/ui.c b/bin/table/ui.c
index 806b307..f60e708 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -263,68 +263,59 @@ ui_check_options_and_arguments(struct tableparams *p)
 /***************       Preparations         *******************/
 /**************************************************************/
 void
-ui_preparations(struct tableparams *p)
+ui_print_info_exit(struct tableparams *p)
 {
   char *tmp;
   int tableformat;
   gal_data_t *allcols;
   size_t i, numcols, numrows;
-  struct gal_options_common_params *cp=&p->cp;
 
-  /* If there were no columns specified or the user has asked for
-     information on the columns, we want the full set of columns. */
-  if(p->columns==NULL || p->information)
-    {
-      /* Read the table information for the number of columns and rows. */
-      allcols=gal_table_info(p->filename, cp->hdu, &numcols,
-                             &numrows, &tableformat);
+  /* Read the table information for the number of columns and rows. */
+  allcols=gal_table_info(p->filename, p->cp.hdu, &numcols,
+                         &numrows, &tableformat);
 
-      /* If there was no actual data in the file, then inform the user */
-      if(allcols==NULL)
-        error(EXIT_FAILURE, 0, "%s: no usable data rows", p->filename);
+  /* If there was no actual data in the file, then inform the user */
+  if(allcols==NULL)
+    error(EXIT_FAILURE, 0, "%s: no usable data rows", p->filename);
 
 
-      /* If the user just wanted information, then print it. */
-      if(p->information)
-        {
-          /* Print the file information. */
-          printf("--------\n");
-          tmp=gal_fits_name_save_as_string(p->filename, p->cp.hdu);
-          printf("%s\n", tmp);
-          free(tmp);
-
-          /* Print each column's information. */
-          gal_table_print_info(allcols, numcols, numrows);
-        }
+  /* Print the file information. */
+  printf("--------\n");
+  tmp=gal_fits_name_save_as_string(p->filename, p->cp.hdu);
+  printf("%s\n", tmp);
+  free(tmp);
 
 
-      /* Free the information from all the columns. */
-      for(i=0;i<numcols;++i)
-        gal_data_free_contents(&allcols[i]);
-      free(allcols);
+  /* Print each column's information. */
+  gal_table_print_info(allcols, numcols, numrows);
 
 
-      /* If the user just wanted information, then free the allocated
-         spaces and exit. Otherwise, add the number of columns to the list
-         if the user wanted to print the columns (didn't just want their
-         information. */
-      if(p->information)
-        {
-          ui_free_report(p);
-          exit(EXIT_SUCCESS);
-        }
-      else
-        /* The user wants to read the column values, so put all the column
-           numbers into the list (as strings). Note that we will write the
-           column numbers into the list in reverse order. This way, they
-           are read/popped in the proper order. Recall that this is a
-           last-in-first-out list. */
-        for(i=numcols;i>0;--i)
-          {
-            asprintf(&tmp, "%zu", i);
-            gal_list_str_add(&p->columns, tmp, 0);
-          }
-    }
+  /* Free the information from all the columns. */
+  for(i=0;i<numcols;++i)
+    gal_data_free_contents(&allcols[i]);
+  free(allcols);
+
+
+  /* Free the allocated spaces and exit. Otherwise, add the number of
+     columns to the list if the user wanted to print the columns
+     (didn't just want their information. */
+  ui_free_report(p);
+  exit(EXIT_SUCCESS);
+}
+
+
+
+
+
+void
+ui_preparations(struct tableparams *p)
+{
+  struct gal_options_common_params *cp=&p->cp;
+
+  /* If there were no columns specified or the user has asked for
+     information on the columns, we want the full set of columns. */
+  if(p->information)
+    ui_print_info_exit(p);
 
   /* Read in the table columns. */
   p->table=gal_table_read(p->filename, cp->hdu, p->columns, cp->searchin,
@@ -339,6 +330,7 @@ ui_preparations(struct tableparams *p)
   /* Now that the data columns are ready, we can free the string linked
      list. */
   gal_list_str_free(p->columns, 1);
+  p->columns=NULL;
 }
 
 
diff --git a/bin/warp/authors-cite.h b/bin/warp/authors-cite.h
index 79b3705..34c89d5 100644
--- a/bin/warp/authors-cite.h
+++ b/bin/warp/authors-cite.h
@@ -31,8 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    See the `gnuastro_bibtex' variable in `lib/options' (from the top
    Gnuastro source code directory) as an example.*/
 
-#define PROGRAM_BIBTEX "";
+#define PROGRAM_BIBTEX ""
 
-#define PROGRAM_AUTHORS "Mohammad Akhlaghi";
+#define PROGRAM_AUTHORS "Mohammad Akhlaghi"
 
 #endif
diff --git a/bootstrap.conf b/bootstrap.conf
index 790ded0..f593304 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -99,7 +99,7 @@ bootstrap_post_import_hook()
 {
   # List of m4 files we need from the GNU Autoconf Archives (excluding the
   # `ax_' prefix and `.m4' suffix):
-  neededm4s="pthread compare_version"
+  neededm4s="pthread compare_version check_compile_flag"
 
   # Get the necesssary Autoconf-archive macros. It is assumed that
   # autoconf-archives is cloned the same directory as gnulib. Therefore we
diff --git a/configure.ac b/configure.ac
index b2b1946..455d9eb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -114,6 +114,26 @@ CC="$PTHREAD_CC"
 
 
 
+# See if the C++ compiler understands `-Qunused-arguments'. AX_PTHREAD adds
+# this option to LDFLAGS when the C compiler knows this option. But as
+# reported in bug #52490, it can happen that at the same time, the C++
+# compiler doesn't recognize it.
+cpp_Qunused_arguments_problem=no
+for flg in $LDFLAGS; do
+  AS_IF([test "$flg" = \-Qunused-arguments],
+        [ AC_LANG(C++)
+          AX_CHECK_COMPILE_FLAG([-Qunused-arguments],
+                                [cpp_Qunused_arguments_problem=no],
+                                [cpp_Qunused_arguments_problem=yes])
+          AC_LANG(C) ])
+done
+AM_CONDITIONAL([COND_NO_CPP_QUNUSED_ARGUMENTS_PROBLEM],
+               [test "x$cpp_Qunused_arguments_problem" = "xno"])
+
+
+
+
+
 # Check if `malloc(0)' returns valid pointer
 AC_FUNC_MALLOC
 
@@ -129,7 +149,7 @@ AC_DEFINE_UNQUOTED([GAL_CONFIG_SIZEOF_SIZE_T], 
[$ac_cv_sizeof_size_t],
 AC_CHECK_SIZEOF([long])
 AC_SUBST(SIZEOF_LONG, [$ac_cv_sizeof_long])
 AC_DEFINE_UNQUOTED([GAL_CONFIG_SIZEOF_LONG], [$ac_cv_sizeof_long],
-                   [Depends on bit length of system.])
+                   [On 32bit will be 4, on 64 bit, will be 8])
 
 
 
@@ -234,7 +254,8 @@ AC_SUBST(HAVE_LIBGIT2, [$has_libgit2])
 
 
 # Check the libtool executable: needed by BuildProgram.
-AC_CHECK_PROG(has_libtool, libtool, [yes], [no])
+AC_CHECK_PROG(has_libtool, libtool, [yes], [no], ,
+              ./libtool .//libtool $ac_pwd/libtool)
 
 # If Libtool is present, make sure it is GNU Libtool
 AS_IF([test "x$has_libtool" = "xyes"],
@@ -538,9 +559,15 @@ AC_ARG_ENABLE([crop],
 AC_ARG_ENABLE([fits],
               [AS_HELP_STRING([--enable-fits],
                     [Install Fits and other enabled programs.])],
-             [AS_IF([test "x$enable_Fits" != xno],
+             [AS_IF([test "x$enable_fits" != xno],
                      [enable_fits=yes; ayes=true])],
               [enable_fits=notset])
+AC_ARG_ENABLE([match],
+              [AS_HELP_STRING([--enable-match],
+                    [Install Match and other enabled programs.])],
+             [AS_IF([test "x$enable_match" != xno],
+                     [enable_match=yes; ayes=true])],
+              [enable_match=notset])
 AC_ARG_ENABLE([mkcatalog],
               [AS_HELP_STRING([--enable-mkcatalog],
                     [Install MakeCatalog and other enabled programs.])],
@@ -607,6 +634,7 @@ AS_IF([test $ayes = true ],
        AS_IF([test $enable_cosmiccal = notset], [enable_cosmiccal=no])
        AS_IF([test $enable_crop = notset], [enable_crop=no])
        AS_IF([test $enable_fits = notset], [enable_fits=no])
+       AS_IF([test $enable_match = notset], [enable_match=no])
        AS_IF([test $enable_mkcatalog = notset], [enable_mkcatalog=no])
        AS_IF([test $enable_mknoise = notset], [enable_mknoise=no])
        AS_IF([test $enable_mkprof = notset], [enable_mkprof=no])
@@ -625,6 +653,7 @@ AS_IF([test $ayes = true ],
        AS_IF([test $enable_cosmiccal = notset], [enable_cosmiccal=yes])
        AS_IF([test $enable_crop = notset], [enable_crop=yes])
        AS_IF([test $enable_fits = notset], [enable_fits=yes])
+       AS_IF([test $enable_match = notset], [enable_match=yes])
        AS_IF([test $enable_mkcatalog = notset], [enable_mkcatalog=yes])
        AS_IF([test $enable_mknoise = notset], [enable_mknoise=yes])
        AS_IF([test $enable_mkprof = notset], [enable_mkprof=yes])
@@ -656,6 +685,7 @@ AM_CONDITIONAL([COND_CONVOLVE], [test $enable_convolve = 
yes])
 AM_CONDITIONAL([COND_COSMICCAL], [test $enable_cosmiccal = yes])
 AM_CONDITIONAL([COND_CROP], [test $enable_crop = yes])
 AM_CONDITIONAL([COND_FITS], [test $enable_fits = yes])
+AM_CONDITIONAL([COND_MATCH], [test $enable_match = yes])
 AM_CONDITIONAL([COND_MKCATALOG], [test $enable_mkcatalog = yes])
 AM_CONDITIONAL([COND_MKNOISE], [test $enable_mknoise = yes])
 AM_CONDITIONAL([COND_MKPROF], [test $enable_mkprof = yes])
@@ -680,6 +710,7 @@ AC_CONFIG_FILES([Makefile
                  bin/fits/Makefile
                  bin/warp/Makefile
                  bin/table/Makefile
+                 bin/match/Makefile
                  bin/mkprof/Makefile
                  bin/mknoise/Makefile
                  bin/convertt/Makefile
@@ -729,6 +760,7 @@ AC_OUTPUT
 
 
 
+
 # Print a message if necessary
 AS_IF([test x$enable_guide_message = xyes],
 [
@@ -764,7 +796,12 @@ AS_IF([test x$enable_guide_message = xyes],
                AS_ECHO(["    warning is only to let you know that BuildProgram 
will not be"])
                AS_ECHO(["    part of this build. The executable names searched 
were \`libtool'"])
                AS_ECHO(["    and \`glibtool'."])
-               AS_ECHO([]) ])
+               AS_ECHO([])
+               AS_IF([test "x$has_libtool" = "xyes"],
+                     [AS_ECHO(["    -- A libtool implementation was found, but 
it isn't GNU."])
+                      AS_ECHO([])
+                     ])
+              ])
         AS_IF([test "x$has_ghostscript" = "xno"],
               [AS_ECHO(["  - GPL GhostScript version 9.10 or later, with the 
executable"])
                AS_ECHO(["    name \`gs', was not found in your PATH 
environment variable."])
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index c3d8955..7b4c947 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -1,9 +1,14 @@
-This file is meant to keep the names of the people who's help must be
-acknowledged in the next release.
+People who's help must be acknowledged in the next release.
 
 Leindert Boogaard
 Nicolas Bouché
+Madusha Gunawardhana
 Aurélien Jarno
 Takashi Ichikawa
+Raúl Infante Sainz
+Floriane Leclercq
 Alan Lefor
+Alejandro Serrano Borlaff
+Lee Spitler
+Ole Streicher
 David Valls-Gabaud
diff --git a/doc/gnuastro.fr.html b/doc/gnuastro.fr.html
new file mode 100644
index 0000000..3a1fbfe
--- /dev/null
+++ b/doc/gnuastro.fr.html
@@ -0,0 +1,483 @@
+<!--#include virtual="/server/header.html" -->
+<!-- Parent-Version: 1.77 -->
+
+<!-- This is the template document for GNU web pages.  We use
+     server side includes (#include) for common elements, for
+     instance, the very first line of the file.  If you're reading
+     this in its expanded form, you can retrieve the original source,
+     with the SSI statements intact, from
+     
http://web.cvs.savannah.gnu.org/viewvc/*checkout*/www/server/standards/boilerplate.html?root=www&content-type=text%2Fplain
+-->
+
+<!-- Instructions for adapting this boilerplate to a new project: -->
+
+<!-- 1. In the line above starting "Parent-Version:", remove the
+        "$Revision...$" from around the revision number,
+        leaving just Parent-Version: and the number. -->
+
+<!-- 2. Replace "baz" with the name of your project.
+        You should be able to do this with search and replace;
+        making sure that the search is case insensitive and
+        that the case of the replacement matches the case
+        of the string found. In Emacs, query-replace will do this
+        when case-fold-search and case-replace are both non-nil
+        and both search and replacement string are given in lower case. -->
+
+<!-- 3. Of course update the actual information according to your project,
+        such as mailing lists, project locations, and maintainer name.  -->
+
+<!-- 4. You can use the patch-from-parent script to semi-automate
+        merging future changes to the boilerplate with your file:
+        
http://web.cvs.savannah.gnu.org/viewvc/*checkout*/www/server/standards/patch-from-parent?root=www&content-type=text%2Fplain
+        -->
+
+<!-- If you would like to make sure your page validates with HTML5, that
+     would be a good thing.  To do that, change the first line from
+     to /server/html5-header.html before trying the validation.  Maybe
+     someday we will be able to make /server/header be HTML5.  -->
+
+<title>Les Utilités GNU d'Astronomie - Gnuastro -
+  Le Projet GNU - Fondation du Logiciel Libre</title>
+
+<!-- ATTENTION RELECTEUR
+
+ Merci beaucoup pour votre aide. J'ai fait quelques notes avec les
+ traductions que je pensais étaient mal, mais probablement il y a certains
+ qui ont échappé mon oeil. Le format est plus ou moins comme suivant: Note
+ anglais + note français. Original Text: la texte original.
+
+ ATTENTION PROOF READER/TRANSLATOR.
+
+ Thanks a lot for your help. I've made some notes with the translations
+ that I thought were bad but there are probably some that've escaped my
+ eye. The format is more or less as follows: English note + French
+ note. Original Text: the original text.
+
+ Contact me at macquarrielucas@gmail.com if necessary. -->
+
+<style type="text/css"><!--
+#table-of-contents {
+   float: left;
+   margin: 1.3em 0 1.5em 0;
+}
+#content #table-of-contents h4 { margin-top: .8em; }
+#table-of-contents a:hover { text-decoration: underline; }
+#table-of-contents h4 { text-align: center; }
+h3 { clear: both; }
+#content h3 a[href^="#"] {
+   color: #333; text-decoration: none;
+}
+#table-of-contents a { text-decoration: none; }
+@media (min-width: 40em) {
+   h3 { clear: none; }
+   #table-of-contents {
+      float: right;
+      margin: 1.3em 0 1em 1.5em;
+   }
+}
+--></style>
+
+
+
+
+
+
+
+
+<!--#include virtual="/server/gnun/initial-translations-list.html" -->
+<!--#include virtual="/server/banner.html" -->
+<h2>Les Utilités GNU d'Astronomie</h2>
+
+<hr />
+<div id="table-of-contents" class="emph-box">
+<h4>La Table des Matières</h4>
+<ul>
+  <li><a href="#introduction">Introduction</a></li>
+  <li><a href="#download">Télécharger</a></li>
+  <li><a href="#installation">Installation</a></li>
+  <li><a href="#documentation">Le Livre (Les Documents)</a></li>
+  <li><a href="#mail">La Liste de Distribution</a></li>
+  <li><a href="#bug">Rapporter un Bug</a></li>
+  <li><a href="#contribute">Nous-Aider</a></li><!-- Erreur possible/ This is 
probably not correct and needs revision -->
+  <li><a href="#license">Autorisation</a></li><!-- Un autre erreur possible/ 
Another probable error -->
+</ul>
+<hr class="no-display"/>
+</div>
+
+
+
+
+
+<h3 id="introduction">Introduction</h3>
+<p> Les Utilités GNU d'Astronomie(Gnuastro) est un officiel progiciel GNU
+  consister des logiciels séperé pour la manipulation et analyse de données
+  astronomique. Tous les différent utilités utilisent la même interface de
+  ligne de commande pour le confort des utilisatuers et des développeurs.
+  Les Utilités Gnu d'Astronomie est écrit pour se conformer avec
+  <a href="https://www.gnu.org/prep/standards/";>Les Normes de Code GNU</a>
+  donc il va bien avec le systèm d'exploitation de GNU/Linux. Aussi, ce
+  permet les astronomes à s'attendent à <!-- Original Text: 'This also allows 
astronomers to expect a fully familiar...' vraisemblable mal rédigé/ Most 
likely badly worded -->
+  une expérience famillière avec le code source, l'installation, le bâtir, 
<!-- Probablement, il y a un mot mieux pour ça. Bâtir comme Bâtir logiciel. 
Peut-être Bâtirant?/ There is probably another word for this. Building as in 
building software. Possible could be bâtirant -->
+  et l'interaction d'utilisateur de linge de commande, qu'ils ont vu avec tous
+  les autres logiciels de GNU qu'ils utilisent.
+  <!-- Original Text: 'which they have seen with all the other gnu software
+  that they use' Ce semble maladroit en anglais aussi/ This also sounds a
+  bit wierd in English as well --></p>
+
+Au cas où tu ne connais pas Gnuastro, ces liens peuvent t'aider: <!-- Original 
Text: ' You might find these links useful' -->
+<ul>
+
+  <li><a href="manual/html_node/Quick-start.html">Démarrage rapide <!-- 
Original Text: 'Quick start' -->
+    </a>: Installer Gnuastro.</li>
+
+  <li><a href="manual/html_node/GNU-Astronomy-Utilities-list.html">La Liste
+  des Utilités GNU d'Astronomie</a>: Pour une liste complète des
+  utilités. </li>
+
+  <li><a 
href="http://www.gnu.org/software/gnuastro/manual/html_node/Tutorials.html#Tutorials";>Les
+    Tutoriels</a>: pour les exemples amusant de la réalité qui sont
+    facile-à-lire </li>
+
+</ul>
+
+
+
+
+
+<h3 id="download">Télécharger</h3>
+
+<p>La sortie actuelle stable
+  est <a href="http://ftp.gnu.org/gnu/gnuastro/gnuastro-0.4.tar.gz";>Gnuastro
+  0.4</a> (septembre 13, 2017).
+  Utilisez <a href="http://ftpmirror.gnu.org/gnuastro/gnuastro-0.4.tar.gz";>un
+  miroir</a> si possible.
+
+  <br />Nouveaux sorties sont annoncé
+  sur <a 
href="https://lists.gnu.org/mailman/listinfo/info-gnuastro";>info-gnuastro</a>,
+  à tenir à jour, s'il vous plait vous abonnez.
+
+<p>Pour les détails des changements importants, vois le
+fichier <a 
href="http://git.savannah.gnu.org/cgit/gnuastro.git/plain/NEWS?id=gnuastro_v0.4";>NOUVELLES</a></p>
+
+<p>Le
+  canonical <a 
href="http://ftp.gnu.org/gnu/gnuastro/gnuastro-latest.tar.gz";></a><a>http://ftp.gnu.org/gnu/gnuastro/gnuastro-latest.tar.gz</a>
+  serait toujours contenir la version plus récente de Gnuastro. Utilisez le
+  lien miroir
+  (<a 
href="http://ftpmirror.gnu.org/gnuastro/gnuastro-latest.tar.gz";>http://ftpmirror.gnu.org/gnuastro/gnuastro-latest.tar.gz</a>)
+  si possible.</p>
+
+<p>Les versions précédents et signatures PGP sont toujours disponible sur
+  <a 
href="http://ftp.gnu.org/gnu/gnuastro";>http://ftp.gnu.org/gnu/gnuastro</a>. 
Utilizez <a href="http://ftpmirror.gnu.org/gnuastro";>
+  un miroir</a> si possible. </p>
+
+
+<h3 id="installation">Installation</h3>
+
+<p>Voyez  <a href="manual/html_node/Quick-start.html">Démarge rapide</a> pour 
un
+petit rappel des commandes d'installation et bâtir de Gnuastro.</p>
+
+<p>Gnuastro a seulement trois dependencies
+obligatoires: <a href="manual/html_node/GNU-Scientific-Library.html">GNU
+Scientific
+Library</a>, <a href="manual/html_node/CFITSIO.html">CFITSIO</a>, <a 
href="manual/html_node/WCSLIB.html">WCSLIB</a>.</p>
+
+<p>Pour un description moins bref, voyez le chapitre d'
+<a href="manual/html_node/Installation.html">Installation</a>
+du <a href="manual/">livre Gnuastro</a>. Il expliques complètement les
+<a href="manual/html_node/Dependencies.html">dependencies</a>,
+<a href="manual/html_node/Downloading-the-source.html">mode de
+téléchargements</a>, et
+le <a href="manual/html_node/Build-and-install.html">bâtirment et
+installation</a> de Gnuastro.
+
+<h3 id="documentation">Livre de Gnuastro (Les documents)</h3>
+
+<p>Le <a href="manual/">livre de Gnuastro</a> (Les documents de Gnuastro
+  officiel où le manuel) est disponsable en ligne en différent formats, et
+  aussi est <!-- this is definitely wrong/ C'est mauvais, sans aucun
+  doute. Original text: The gnuastro book is available online in different
+  formats, and so is documentation f\ or most gnu software --> les
+  documents <a href="http://www.gnu.org/manual/manual.en.html";>pour la
+  plupart de logiciel GNU</a>. Aprés l'installation, vous pouvez accèder le
+  livre complet, où les parties relié à les utilités individuel sur la
+  linge de commande (en
+  format <a href="../texinfo/manual/info/info.html">Info</a>
+  ). Voir <a href="manual/html_node/Getting-help.html">Trouvant d'aide</a>
+  pour plus d'infomation. En résumé, voici les façons à vous guider à les
+  parties plus important du livre sur la ligne de commande:
+
+
+<ul>
+  <li><code>info gnuastro</code>: Pour voir le livre Gnuastro complet
+    à debut.</li>
+  <li><code>info ProgramName</code>: Pour voir la partie à propos d'un
+    utilité spécifique.Par exemple <code>info NoiseChisel</code>
+    où <code>info ImageCrop</code>.</li>
+  <li><code>info astprogname</code>: Pour voir la sous-section seulement
+    "Invoking ProgramName" du manuel. Chaque programme a une sous-section
+    qu'explique les input(s), les output(s), et les options de la ligne de
+    commande pour cet programme. Par exemple <code>info
+    astnoisechisel</code> où <code>info astimgcrop</code>.</li>
+  <li><code>astprogname --help</code>: Un signalement et liste complète des
+    options (classé par contexte) pour cette programme
+    l'imprimera. <!-- Future tense is tough/ Futur est dur. Original Text:
+    will be printed. --> Par exemeple <code>astnoisechisel --help</code>
+    où <code>astimgcrop --help</code>.</li>
+  <li><code>man astprogname</code>: Une page manuel listant les options et
+    les arguments de la programme l'imprimera. Par exemple
+    <code>man astnoisechisel</code>,
+  où <code>man astimgcrop</code>.</li>
+</ul>
+
+<h3 id="mail">La Liste de distribution</h3>
+
+<p>Gnuastro a les listes de distribution suivantes:</p> <!-- Possible
+error/Erreur possible. Original Text: 'Gnuastro has the following mailing
+lists' -->
+
+<ul>
+
+  <li><a 
href="https://lists.gnu.org/mailman/listinfo/info-gnuastro";>info-gnuastro</a>:
+  Toutes annonces officielle <!-- wrong tout/toutes/tous/toute
+  mal. Original text: all official announcements --> circuleront dans la
+  liste de distribution là.</li>
+
+  <li><a 
href="https://lists.gnu.org/mailman/listinfo/help-gnuastro";>help-gnuastro</a>:
+    Contacter les utilisateurs expérimenté et développeurs sur des
+    problèmes et conseils pour Gnuastro (Il serait utile si vous
+    lisiez <a href="manual/">les documents</a> à l'avance).</li>
+
+  <li><a 
href="https://lists.gnu.org/mailman/listinfo/bug-gnuastro";>bug-gnuastro</a>:
+  Signaler un bug, ou suggérer des nouvelles fonctions.
+  (voir <a href="manual/html_node/Report-a-bug.html">Signalez un bug</a>
+  et <a href="manual/html_node/Suggest-new-feature.html">Suggérer un
+  nouveau fonction </a> dans les documents). </li>
+
+  <li><a 
href="https://lists.gnu.org/mailman/listinfo/gnuastro-devel";>gnuastro-devel</a>:
+Les discussions à propos du développement (Pour l'intérêt des développeurs
+surtout) <!-- Original text: Mostly for gnuastro developers) -->.</li>
+
+  <li><a 
href="https://lists.gnu.org/mailman/listinfo/gnuastro-commits";>gnuastro-commits</a>:
+    À propos des commits git <!-- about git commits --> faisaient aux
+    versions de Gnuastro, contrôlé par l'histoire dans le repository
+    officiel.</li>
+</ul>
+
+<p>Les rapports de securité qui ne devrait pas rendre public <!-- Original
+text: Security reports that should not be made public --> peut-être envoyer
+directement au <!-- au éditeur ou à l'éditor --> éditeur. S'il n'y a pas
+une réponse à une problème urgent, vous pouvez l'envoyer à la liste de
+distribution <a href="http://lists.gnu.org/mailman/listinfo/security";>securité
+général</a> pour des conseils <!-- original text: You can send it to the
+geneeral security mailing list for advice-->.</p>
+
+
+<h3 id="bug">Signaler un bug</h3>
+<p>La section sur <a href="manual/html_node/Report-a-bug.html"> le signalant 
d'un bug
+  <!-- Original text: The section on reporting a bug --> </a> explique
+  complètement le processus de signaler un bug, lisez cette section s'il
+  vous plait!  please read that section. Pour un summaire,
+  voir <a href="https://savannah.gnu.org/bugs/?group=gnuastro";
+  target="_blank">Les archives des bugs Gnuastro</a>. Cliquez sur
+  "<i>Afficher critère</i>" (au-dessus de la liste), choisez "Any" dans le
+  menu déroulant "<i>Ouvert/Fermé</i>" <!-- original text: 'Open/closed' as
+  in the issues are open to improvement/discussion. Comme les problèmes
+  sont ouvert à discussion ou amélioration --> , et au-dessous
+  "<i>Catégorie</i>" choisez la section de Gnuastro qui correspond à votre
+  bug.  En cliquant sur le bouton "Appliquer", seulement les bugs pertinent
+  se listeront. <!-- original text: Only the relevant bugs will be listed
+  --> . Les points verts ont été résoudu et fermé, alors que les points
+  rouges encore sont ouvert. Si ton bug n'est pas listé, prendez un des
+  mesures suivant.  S'il vous plait, essayez d'être plus descripitif autant
+  que possible et incluez le version de Gnuastro que vous
+  fûtes <!-- original text: include the version of gnu astro that you were
+  using... --> utiliser, ainsi que les commandes ou le code qui a créé le
+  bug donc nous pouvons le recréer et le réparer plus rapide. </p>
+
+<ul>
+  <li><a href="https://savannah.gnu.org/support/?func=additem&group=gnuastro";
+         target="_blank">Envoir votre bug</a> par la page web de gestion du
+         projet principal. C'est le façon recommandé à nous informer de ton
+         bug. S'il vous plait reimplissez le meta-data (catégorie, groupe
+         d'articles, etc) autant que possible.</li>
+  <li> Envoyer le courrier
+  à <a href="mailto:bug-gnuastro=at=gnu.org";>bug-gnuastro::at::gnu.org</a>
+  qui est un des <a href="#mail">listes de distribution</a> celles de
+  Gnuastro. <!-- send mail to
+                                                                               
      <emails>
+    which is one of the gnuastro mailing listes --> Ce va être plus
+    lentement comparé à la premiére option. À cause des messages spam en
+    masse, cette liste de distribution est modéré et les autres
+    developpeurs le verraient seulement aprés il est approuvé. Donc, à
+    informer tous les developpeurs immédiatement, utiliser la première
+    option.</li>
+</ul>
+
+
+<h3 id="contribute">Être Impliqué</h3> <!-- Original Text: Getting Involved -->
+
+<p>Le plus importante partie de Gnuastro est la capacité, pour tout le
+  monde, à le pirater (ajouter une nouvelle characteristique, changer une
+  préexistant, réparer un problème, ou à comprendre le logiciel lui-même),
+  voir <a href="manual/html_node/Science-and-its-tools.html">La Science et
+  ses outils</a> . Donner s'il vous intereste; c'est encouragé! Il y a un
+  chapitre dédié au
+  <a href="manual/html_node/Developing.html">Développement</a> pour le
+  rendre aussi facile que possible pour vous implique <!-- Original text:
+  There is also a chapter dedicated to developpment to make it as easy as
+  possible to get involved -->. Aussi
+  voir <a href="http://www.gnu.org/help/";>Comment à Aider GNU</a> pour
+  joindre le projet GNU entier.</p>
+
+<dl>
+<dt>Les Sorties Test</dt>
+
+<dd>Essayez les sorties test (quand disponable) pour nous aider, c'est
+apprécié. <!-- Original Text: It's appreciated --> Les Sorties Test sont
+trouvé aux
+<a 
href="http://alpha.gnu.org/gnu/gnuastro/";>http://alpha.gnu.org/gnu/gnuastro/</a>
+(via HTTP) et
+<a 
href="ftp://alpha.gnu.org/gnu/gnuastro/";>ftp://alpha.gnu.org/gnu/gnuastro/</a>
+(via FTP).</dd>
+
+
+<dt>Développement</dt>
+
+<dd>Les Utilités GNU d'Astronomie est toujours en cours de développement.
+Donc si vous êtez interesté, voir le
+chapitre <a href="manual/html_node/Developing.html">Développement</a> des
+documents et commencer à pirater Gnuastro ou creer tes propres outils. Pour
+les sources
+développement, <a href="https://savannah.gnu.org/bugs/?group=gnuastro";>bug
+trackers</a>, <a href="https://savannah.gnu.org/task/?group=gnuastro";>task
+trackers</a> (les fonctions planifié vont être ajouté), et autre
+information, s'il vous plait voir
+<a href="http://savannah.gnu.org/projects/gnuastro/";>le page de project
+Gnuastro</a> à <a href="http://savannah.gnu.org";>savannah.gnu.org</a>.  Les
+trackers peuvent être un bien point de départ pour le codage.  À rendre
+mise à jour avec le développement de Gnuastro, vous abonner à la liste de
+distribution <a 
href="https://lists.gnu.org/mailman/listinfo/gnuastro-devel";>gnuastro-devel</a>,
+et/ou
+ <a 
href="https://lists.gnu.org/mailman/listinfo/gnuastro-commits";>gnuastro-commits</a>
+.</dd>
+
+<dd>Gnuastro est contrôlé par git avec versions.
+  Les sources contrôlé <a 
href="manual/html_node/Version-controlled-source.html"> par version
+  </a> peut-être
+  <a href="http://git.savannah.gnu.org/cgit/gnuastro.git/tree/";>vu enligne
+  </a>, ou vous pouvez <a 
href="http://git.savannah.gnu.org/cgit/gnuastro.git/log/";> voir le dernier 
histoire</a>.
+  Le cloner pour garder ton propre exemplaire local sur ton système. Utilisez 
une des commandes suivant (Le premier
+  est préféré):
+
+  <pre class="emph-box"><samp>git clone git://git.sv.gnu.org/gnuastro git
+clone http://git.sv.gnu.org/r/gnuastro.git
+</samp></pre></dd>
+
+<dd>Pour configurer et construire le source contrôlé par version, vous allez 
avoir besoin de le
+<a href="manual/html_node/Bootstrapping.html">bootstrap</a> (aussi voir
+<a href="manual/html_node/Bootstrapping-dependencies.html">les dépendance
+de bootstrap</a>).  Voir
+le <a href="manual/html_node/Forking-tutorial.html">tutoriel de fork</a>
+pour une démonstration du workflow du projet Gnuastro</dd>
+
+<dt>Mainteneur</dt>
+
+<dd>Gnuastro etait crée et est maitenant maintenu <!-- Original text: Gnu
+astro was created and is currently maintained by Mohammah--> par
+ <a href="https://cral.univ-lyon1.fr/labo/perso/mohammad.akhlaghi/";>Mohammad
+Akhlaghi</a>
+<a href="mailto:akhlaghi=at=gnu.org";>&lt;akhlaghi::at::gnu.org&gt;</a>. La
+traduction en français de cette page est maintenue par Lucas Macquarrie
+<a 
href="mailto:macquarrielucas=at=gmail.com";>&lt;macquarrielucas::at::gmail.com&gt;</a>.
 S'il
+vous plait, utiliser la liste de distribution pour vous entrer en
+contacte. </dd>
+
+
+</dl>
+
+
+
+
+
+<h3 id="license">Autorisation</h3>
+
+<p>GNU Astronomy Utilities (Gnuastro) est logiciel libre; vous peuvez le
+redistribuer et/ou le modifier selon les termes
+du <a href="http://www.gnu.org/licenses/gpl.html"; rel="license">GNU General
+Public License</a> comme publié par le Fondation du Logiciel Livre (the
+Free Software Foundation); soit version&nbsp;3 de la Licence, ou (si vous
+voulez) une version ultérieure.</p>
+
+</div><!-- for id="content", starts in the include above -->
+<!--#include virtual="/server/footer.html" -->
+<div id="footer">
+<div class="unprintable">
+
+<p>S'il vous plait envoyer FLL general &amp; Les demandes GNU à
+<a href="mailto:gnu@gnu.org";>&lt;gnu@gnu.org&gt;</a>.  Il y a
+aussi <a href="/contact/">des façons différent pour contacter</a> le
+FLL. Les liens cassé, les autres corrections, ou suggestions peuvent être
+envoyer
+à <a href="mailto:bug-gnuastro@gnu.org";>&lt;bug-gnuastro@gnu.org&gt;</a>.</p>
+
+<p><!-- TRANSLATORS: Ignore the original text in this paragraph,
+        replace it with the translation of these two:
+
+        We work hard and do our best to provide accurate, good quality
+        translations.  However, we are not exempt from imperfection.
+        Please send your comments and general suggestions in this regard
+        to <a href="mailto:web-translators@gnu.org";>
+        &lt;web-translators@gnu.org&gt;</a>.</p>
+
+        <p>For information on coordinating and submitting translations of
+        our web pages, see <a
+        href="/server/standards/README.translations.html">Translations
+            README</a>. -->
+
+On travaille fort et faisons de notre mieux pour fournir des traductions
+précis et bonnes qualités.  Cependant, on n'est pas exempt des
+imperfections. S'il vous plait, envoyer vos commentaires et suggestions
+générals à <a href="mailto:web-translators@gnu.org";>
+&lt;web-translators@gnu.org&gt;</a>.</p>
+
+<p>Pour puis d'information à propos du coordination et soumettre des
+traductions de nos cite webs,
+voyez <a href="/server/standards/README.translations.html">Translations
+README</a>.
+
+
+<!-- Regarding copyright, in general, standalone pages (as opposed to
+     files generated as part of manuals) on the GNU web server should
+     be under CC BY-ND 3.0 US.  Please do NOT change or remove this
+     without talking with the webmasters or licensing team first.
+     Please make sure the copyright date is consistent with the
+     document.  For web pages, it is ok to list just the latest year the
+     document was modified, or published.
+
+     If you wish to list earlier years, that is ok too.
+     Either "2001, 2002, 2003" or "2001-2003" are ok for specifying
+     years, as long as each year in the range is in fact a copyrightable
+     year, i.e., a year in which the document was published (including
+     being publicly visible on the web or in a revision control system).
+
+     There is more detail about copyright years in the GNU Maintainers
+     Information document, www.gnu.org/prep/maintain. -->
+
+<p>Copyright &copy; 2015-2016 Free Software Foundation, Inc.</p>
+
+<p>This page is licensed under a <a rel="license"
+href="http://creativecommons.org/licenses/by-nd/3.0/us/";>Creative
+Commons Attribution-NoDerivs 3.0 United States License</a>.</p>
+
+<!--#include virtual="/server/bottom-notes.html" -->
+
+<p class="unprintable">Updated:
+<!-- timestamp start -->
+$Date: 2016/10/19 09:04:37 $
+<!-- timestamp end -->
+</p>
+</div>
+</div>
+</body>
+</html>
+<!-- translated by Lucas MacQuarrie macquarrielucas@gmail.com -->
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index b3e14a1..8fe764b 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -122,8 +122,8 @@ License''.
 @author Mohammad Akhlaghi
 
 @page
-Gnuastro (source code and book) authors (sorted by number of commits
-in project history):
+Gnuastro (source code, book and webpage) authors (sorted by number of
+commits):
 @quotation
 @include authors.texi
 @end quotation
@@ -233,6 +233,7 @@ Tutorials
 
 * Hubble visually checks and classifies his catalog::  Check a catalog.
 * Sufi simulates a detection::  Simulating a detection.
+* General program usage tutorial::  Usage of all programs in a good way.
 
 Installation
 
@@ -422,6 +423,7 @@ Data analysis
 * Statistics::                  Calculate dataset statistics.
 * NoiseChisel::                 Detect objects in an image.
 * MakeCatalog::                 Catalog from input and labeled images.
+* Match::                       Match two datasets.
 
 Statistics
 
@@ -463,6 +465,10 @@ Invoking MakeCatalog
 * Upper-limit magnitude settings::  Necessary to define upper-limit magnitudes.
 * MakeCatalog output columns::  How to specify the columns in the output.
 
+Match
+
+* Invoking astmatch::           Inputs, outputs and options of Match
+
 Modeling and fitting
 
 * MakeProfiles::                Making mock galaxies and stars.
@@ -555,6 +561,7 @@ Gnuastro library
 * Polygons::                    Working with the vertices of a polygon.
 * Qsort functions::             Helper functions for Qsort.
 * Permutations::                Re-order (or permute) the values in a dataset.
+* Matching::                    Matching catalogs based on position.
 * Statistical operations::      Functions for basic statistics.
 * Binary datasets::             Datasets that can only have values of 0 or 1.
 * Convolution functions::       Library functions to do convolution.
@@ -704,24 +711,52 @@ founding basis of the Gnuastro.
 @cindex GNU Tar
 @cindex Uncompress source
 @cindex Source, uncompress
-Gnuastro has three mandatory dependencies and three optional dependencies
-for extra functionality, see @ref{Dependencies}. The latest official
-release tarball is always available as
+The latest official release tarball is always available as
 @url{http://ftp.gnu.org/gnu/gnuastro/gnuastro-latest.tar.gz,
 @file{gnuastro-latest.tar.gz}}. For better compression (faster download),
 and robust archival features, an @url{http://www.nongnu.org/lzip/lzip.html,
 Lzip} compressed tarball is also available at
 @url{http://ftp.gnu.org/gnu/gnuastro/gnuastro-latest.tar.lz,
 @file{gnuastro-latest.tar.lz}}, see @ref{Release tarball} for more details
-on the tarball release. If you have downloaded the tarball in the
-@file{TOPGNUASTRO} directory and the dependencies are installed, you can
-unpack, compile, check and install Gnuastro with the following commands. If
-you use GNU Tar, the same command (@command{$ tar xf}) can also be used to
-unpack @file{.tar.lz} tarballs (the Lzip must already be installed).
+on the tarball release.
 
-@example
+@cindex Gzip
+@cindex Lzip
+@cindex GNU Tar
+The Gzip library and program are commonly available on most
+systems. However, Gnuastro recommends Lzip as described above and the
+beta-releases are also only distributed in @file{tar.lz}. You can download
+and install Lzip's source (in @file{.tar.gz} format) from its webpage and
+follow the same process as below: Lzip has no dependencies, so simply
+decompress, then run @command{./configure}, @command{make}, @command{sudo
+make install}.
+
+Let's assume the downloaded tarball is in the @file{TOPGNUASTRO}
+directory. The first two commands below can be used to decompress the
+source. If you download @file{tar.lz} and your Tar implementation doesn't
+recognize Lzip (the second command fails), run the third and fourth
+lines. Note that lines starting with @code{##} don't need to be typed.
+
+@example
+## Go into the download directory.
 $ cd TOPGNUASTRO
-$ tar xf gnuastro-latest.tar.gz    # This works on `.tar.lz' too.
+
+## Also works on `tar.gz'. GNU Tar recognizes both formats.
+$ tar xf gnuastro-latest.tar.lz
+
+## Only when previous command fails.
+$ lzip -d gnuastro-latest.tar.lz
+$ tar xf gnuastro-latest.tar
+@end example
+
+Gnuastro has three mandatory dependencies and some optional dependencies
+for extra functionality, see @ref{Dependencies} for the full list. Links to
+the dependency sources and instructions on installing each are fully
+described there. When the mandatory dependencies are ready, you can
+configure, compile, check and install Gnuastro on your system with the
+following commands.
+
+@example
 $ cd gnuastro-X.X                  # Replace X.X with version number.
 $ ./configure
 $ make -j8                         # Replace 8 with no. CPU threads.
@@ -733,12 +768,14 @@ $ sudo make install
 
 See @ref{Known issues} if you confront any complications. For each program
 there is an `Invoke ProgramName' sub-section in this book which explains
-how the programs should be run on the command-line. You can read it on the
-command-line by running the command @command{$ info astprogname}, see
-@ref{Naming convention} and @ref{Getting help}. The `Invoke ProgramName'
-sub-section starts with a few examples of each program and goes on to
-explain the invocation details. In @ref{Tutorials} some real life examples
-of how these programs might be used are given.
+how the programs should be run on the command-line (for example
+@ref{Invoking asttable}). You can read the same section on the command-line
+by running @command{$ info astprogname} (for example @command{info
+asttable}). The `Invoke ProgramName' sub-section starts with a few examples
+of each program and goes on to explain the invocation details. See
+@ref{Getting help} for all the options you have to get help. In
+@ref{Tutorials} some real life examples of how these programs might be used
+are given.
 
 
 
@@ -1626,6 +1663,7 @@ Wikipedia.
 @menu
 * Hubble visually checks and classifies his catalog::  Check a catalog.
 * Sufi simulates a detection::  Simulating a detection.
+* General program usage tutorial::  Usage of all programs in a good way.
 @end menu
 
 @node Hubble visually checks and classifies his catalog, Sufi simulates a 
detection, Tutorials, Tutorials
@@ -1857,7 +1895,7 @@ about what these nebulous objects that are outside of the 
Galaxy are.
 
 
 
-@node Sufi simulates a detection,  , Hubble visually checks and classifies his 
catalog, Tutorials
+@node Sufi simulates a detection, General program usage tutorial, Hubble 
visually checks and classifies his catalog, Tutorials
 @section Sufi simulates a detection
 
 It is the year 953 A.D.  and Sufi@footnote{Abd al-rahman Sufi (903 --
@@ -2289,19 +2327,1082 @@ catalog). It was nearly sunset and they had to begin 
preparing for the
 night's measurements on the ecliptic.
 
 
+@node General program usage tutorial,  , Sufi simulates a detection, Tutorials
+@section General program usage tutorial
+
+@cindex HST
+@cindex XDF survey
+@cindex Hubble Space Telescope
+@cindex Extreme Deep Field survey
+Measuring colors of astronomical objects in broad-band or narrow-band
+images is one of the most basic and common steps in astronomical
+analysis. Here, we will use Gnuastro's programs to detect objects in a
+Hubble Space Telescope (HST) image and measure their colors. We will use
+the @url{https://archive.stsci.edu/prepds/xdf, eXtreme Deep Field}
+dataset. Like almost all astronomical surveys, this dataset is free for
+download and usable by the public. You will need the following tools in
+this tutorial: Gnuastro, SAO DS9 @footnote{See @ref{SAO ds9}, available at
+@url{http://ds9.si.edu/site/Home.html}.}, GNU
+Wget@footnote{@url{https://www.gnu.org/software/wget}.}, and AWK (most
+common implementation is GNU
+AWK@footnote{@url{https://www.gnu.org/software/gawk}.}).
+
+@cartouche
+@noindent
+@strong{Type the example commands:} Try to type the example commands on
+your terminal and don't simply copy and paste them. This will help simulate
+future situations when you are processing your own datasets.
+@end cartouche
+
+A handy feature of Gnuastro is that all program names start with
+@code{ast}. This will allow your command-line processor to easily list and
+auto-complete Gnuastro's programs for you.  Try typing the following
+command (press @key{TAB} key when you see @code{<TAB>}) to see the list:
+
+@example
+$ ast<TAB><TAB>
+@end example
+
+@noindent
+Any program that starts with @code{ast} (including all Gnuastro programs)
+will be shown. By choosing the subsequent characters of your desired
+program and pressing @key{<TAB><TAB>} again, the list will narrow down and
+the program name will auto-complete once your input characters are
+unambiguous. In short, you often don't need to type the full name of the
+program you want to run.
+
+Gnuastro contains a large number of programs and it is natural to forget
+the details of each program's options. Therefore, before starting the
+analysis, let's review how you can refresh your memory any time you want on
+the command-line while working (without taking your hands off the
+keyboard). This book comes with your installation, so it will always
+correspond to your installed version of Gnuastro. Please see @ref{Info} for
+more.
+
+@cindex GNU Info
+GNU Info@footnote{GNU Info is already available on almost all Unix-like
+operating systems.} is the program in charge of displaying the manual on
+the command-line. To see this whole book on your command-line, please run
+the following command and subsequent keys. Info has its own
+mini-environment, therefore we'll show the keys that must be pressed in the
+mini-environment after a @code{->} sign. You can also ignore anything after
+the @code{#} sign in the middle of the line, they are only for your
+information.
+
+@example
+$ info gnuastro                # Open the top of the manual.
+-> <SPACE>                     # All the book chapters.
+-> <SPACE>                     # Continue down: show sections.
+-> <SPACE> ...                 # Keep pressing space to go down.
+-> q                           # Quit Info, return to the command-line.
+@end example
+
+The thing that greatly simplifies navigation in Info is the links (regions
+with an underline). You can immediately go to the next link in the page
+with the @key{<TAB>} key and press @key{<ENTER>} on it to go into that part
+of the manual. Try the commands above again, but this time also use
+@key{<TAB>} to go to the links and press @key{<ENTER>} on them to go to the
+respective section of the book. Then follow a few more links and go deeper
+into the book. To return to the previous page, press @key{l} (small L). If
+you are searching for a specific phrase in the whole book (for example an
+option name), press @key{s} and type your search phrase and end it with an
+@key{<ENTER>}.
+
+You don't need to start from the top of the manual every time. For example,
+to get to @ref{Invoking astnoisechisel}, run the following command. In
+general, all programs have such an ``Invoking ProgramName'' section in this
+book. These sections are specifically for the description of inputs,
+outputs and configuration options of each program. You can access them
+directly for each program by giving its executable name to Info.
+
+@example
+$ info astnoisechisel
+@end example
+
+The other sections don't have such shortcuts. To directly access them from
+the command-line, you need to tell Info to look into Gnuastro's manual,
+then look for the specific section (an unambiguous title is necessary). For
+example, if you only want to review/remember NoiseChisel's @ref{Detection
+options} or @ref{Segmentation options}), just run any of these
+commands. Note how case is irrelevant for Info when calling a title in this
+manner.
+
+@example
+$ info gnuastro "Detection options"
+$ info gnuastro "segmentation options"
+@end example
+
+In general, Info is a wonderful and powerfull way to access this whole book
+with detailed information about the programs you are running very fast. If
+you are not already familiar with it, please run the following command and
+just read along and do what it says to learn it. Don't stop until you feel
+have become sufficiently fluent in it. Please invest the half an hour's
+time necessary to start using Info comfortably. It will greatly improve
+your productivity and you will start reaping the rewards of this investment
+very soon.
+
+@example
+$ info info
+@end example
+
+As a good scientist you need to feel comfortable to play with the
+features/options and avoid (be critical to) using default values as much as
+possible. On the other hand, our human memory is very limited, so it is
+important to be able to easily access any part of this book fast and
+remember the option names, what they do and their acceptable values.
+
+If you just want the option names and a short description, calling the
+program with the @option{--help} option might also be a good solution like
+the first example below. If you know a few characters of the option name,
+you can feed the output to @command{grep} like the second or third example
+commands.
 
+@example
+$ astnoisechisel --help
+$ astnoisechisel --help | grep quant
+$ astnoisechisel --help | grep check
+@end example
 
+Let's start the processing. First, to keep things clean, let's create a
+@file{gnuastro-tutorial} directory and continue all future steps in it:
 
+@example
+$ mkdir gnuastro-tutorial
+$ cd gnuastro-tutorial
+@end example
 
+We will be using the near infra-red @url{http://www.stsci.edu/hst/wfc3,
+Wide Field Camera} dataset. If you already have them in another directory
+(for example @file{XDFDIR}), you can set the @file{download} directory to
+be a symbolic link to @file{XDFDIR} with a command like this:
 
+@example
+ln -s XDFDIR download
+@end example
 
+@noindent
+If the following images aren't already present on your system, you can make
+a @file{download} directory and download them there.
 
+@example
+$ mkdir download
+$ cd download
+$ xdfurl=http://archive.stsci.edu/pub/hlsp/xdf
+$ wget $xdfurl/hlsp_xdf_hst_wfc3ir-60mas_hudf_f105w_v1_sci.fits
+$ wget $xdfurl/hlsp_xdf_hst_wfc3ir-60mas_hudf_f160w_v1_sci.fits
+$ cd ..
+@end example
 
+@noindent
+In this tutorial, we'll just use these two filters. Later, you will
+probably need to download more filters, you can use the shell's @code{for}
+loop to download them all in series (one after the other@footnote{Note that
+you only have one port to the internet, so downloading in parallel will
+actually be slower than downloading in series.}) with one command like the
+one below for the WFC3 filters. Put this command instead of the two
+@code{wget} commands above. Recall that all the extra spaces, back-slashes
+(@code{\}), and new lines can be ignored if you are typing on the lines on
+the terminal.
+
+@example
+$ for f in f105w f125w f140w f160w; do                              \
+    wget $xdfurl/hlsp_xdf_hst_wfc3ir-60mas_hudf_"$f"_v1_sci.fits;   \
+  done
+@end example
+
+First, let's visually inspect the dataset. Let's take F160W image as an
+example. Do the steps below with the other image(s) too (and later with any
+dataset that you want to work on). It is very important to understand your
+dataset visually. Note how ds9 doesn't follow the GNU style of options
+where ``long'' and ``short'' options are preceded by @option{--} and
+@option{-} respectively (for example @option{--width} and @option{-w}, see
+@ref{Options}).
+
+Ds9's @option{-zscale} option is a good scaling to highlight the low
+surface brightness regions, and as the name suggests, @option{-zoom to fit}
+will fit the whole dataset in the window. If the window is too small,
+expand it with your mouse, then press the ``zoom'' button on the top row of
+buttons above the image, then in the row below it, press ``zoom fit''. You
+can also zoom in and out by scrolling your mouse or the respective
+operation on your touchpad when your cursor/pointer is over the image.
+
+@example
+$ ds9 download/hlsp_xdf_hst_wfc3ir-60mas_hudf_f160w_v1_sci.fits     \
+      -zscale -zoom to fit
+@end example
+
+The first thing you might notice is that the regions with no data have a
+value of zero in this image. The next thing might be that the dataset
+actually has two ``depth''s (see @ref{Quantifying measurement limits}). The
+exposure time of the inner region is more than 4 times more than the outer
+parts. Fortunately the XDF survey webpage (above) contains the vertices of
+the deep flat WFC3-IR field. You can use those vertices in @ref{Crop} to
+cutout this deep infra-red region from the larger image. We'll make a
+directory called @file{flat-ir} and keep the flat infra-red regions in that
+directory (with a `@file{xdf-}' suffix for a shorter and easier filename).
+
+@example
+$ mkdir flat-ir
+$ astcrop --mode=wcs -h0 --output=flat-ir/xdf-f105w.fits              \
+          --polygon="53.187414,-27.779152 : 53.159507,-27.759633 :    \
+                     53.134517,-27.787144 : 53.161906,-27.807208"     \
+          download/hlsp_xdf_hst_wfc3ir-60mas_hudf_f105w_v1_sci.fits
+$ astcrop --mode=wcs -h0 --output=flat-ir/xdf-f160w.fits              \
+          --polygon="53.187414,-27.779152 : 53.159507,-27.759633 :    \
+                     53.134517,-27.787144 : 53.161906,-27.807208"     \
+          download/hlsp_xdf_hst_wfc3ir-60mas_hudf_f160w_v1_sci.fits
+@end example
+
+The only thing varying in the two calls to Gnuastro's Crop program is the
+filter name. Therefore, to simplify the command, and later allow work on
+more filters, we can use the shell's @code{for} loop. Notice how the two
+places where the filter names (@file{f105w} and @file{f160w}) are used
+above have been replaced with @file{$f} (the shell variable that @code{for}
+is in charge of setting) below. To generalize this for more filters later,
+you can simply add the other filter names in the first line before the
+semi-colon (@code{;}).
+
+@example
+$ for f in f105w f160w; do                                            \
+    astcrop --mode=wcs -h0 --output=flat-ir/xdf-$f.fits               \
+            --polygon="53.187414,-27.779152 : 53.159507,-27.759633 :  \
+                       53.134517,-27.787144 : 53.161906,-27.807208"   \
+            download/hlsp_xdf_hst_wfc3ir-60mas_hudf_"$f"_v1_sci.fits; \
+  done
+@end example
+
+Please open these images and inspect them with the same ds9 commands you
+used above. You will see how it is completely flat now and doesn't have
+varying depths. Another important result of this crop is that regions with
+no data now have a NaN (blank) value, not zero. Zero is a meaningful value
+and especially when using NoiseChisel, the input should have NaN values for
+pixels with no data, not zero.
 
+This is the deepest image we currently have of the sky. The first thing
+that comes to mind may be this: ``How large is this field?''. Let's find
+the answer to this question with the commands below. The lines starting
+with @code{##} are just comments for you to help in following the steps.
+Don't type them on the terminal. The commands are intentionally repetative
+in some places to better understand each step and also to demonstrate the
+beauty of command-line features like variables, pipes and loops. Later, if
+you would like to repeat this process on another dataset, you can just use
+commands 3, 7, and 9.
 
+@cartouche
+@noindent
+@strong{Use shell history:} Don't forget to make effective use of your
+shell's history. This is especially convenient when you just want to make a
+small change to your previous command. Press the ``up'' key on your
+keyboard (possibly multiple times) to see your previous command(s).
+@end cartouche
+
+@example
+## (1)  See the general statistics of non-blank pixel values.
+$ aststatistics flat-ir/xdf-f160w.fits
 
+## (2)  We only want the number of non-blank pixels.
+$ aststatistics flat-ir/xdf-f160w.fits --number
 
+## (3)  Keep the result of the command above in the shell variable `n'.
+$ n=$(aststatistics flat-ir/xdf-f160w.fits --number)
 
+## (4)  See what is stored the shell variable `n'.
+$ echo $n
+
+## (5)  Show all the FITS keywords of this image.
+$ astfits flat-ir/xdf-f160w.fits -h1
+
+## (6)  The resolution (in degrees/pixel) is in the `CDELT' keywords.
+##      Only show lines that contain these characters, by feeding
+##      the output of the previous command to the `grep' program.
+$ astfits flat-ir/xdf-f160w.fits -h1 | grep CDELT
+
+## (7)  Save the resolution (same in both dimensions) in the variable
+##      `r'. The last part uses AWK to print the third `field' of its
+##      input line. The first two fields were `CDELT1' and `='.
+$ r=$(astfits flat-ir/xdf-f160w.fits -h1 | grep CDELT1   \
+              | awk '@{print $3@}')
+
+## (8)  Print the values of `n' and `r'.
+$ echo $n $r
+
+## (9)  Use the number of pixels (first number passed to AWK) and
+##      length of each pixel's edge (second number passed to AWK)
+##      to estimate the area of the field in arc-minutes squared.
+$ area=(echo $n $r | awk '@{print $1 * ($2^2) * 3600@}')
+@end example
+
+The area of this field is 4.03817 (or 4.04) arc-minutes squared. Just for
+comparison, this is roughly 175 times smaller than the average moon's
+angular area (with a diameter of 30arc-minutes or half a degree).
+
+@cindex GNU AWK
+@cartouche
+@noindent
+@strong{AWK for table/value processing:} AWK is a powerful and simple tool
+for text processing. Above (and further below) some simple examples are
+shown. GNU AWK (the most common implementation) comes with a free and
+wonderful @url{https://www.gnu.org/software/gawk/manual/, book} in the same
+format as this book which will allow you to master it nicely. Just like
+this manual, you can also access GNU AWK's manual on the command-line
+whenever necessary without taking your hands off the keyboard as described
+above.
+@end cartouche
+
+This takes us to the second question that you have probably asked yourself
+when you saw the field for the first time: ``How large is this area at
+different redshifts?''. To get a feeling of the tangential area that this
+field covers at redshift 2, you can use @ref{CosmicCalculator}. In
+particular, you need the tangential distance covered by 1 arc-second as raw
+output. Combined with the field's area, we can then calculate the
+tangential distance in Mega Parsecs squared (@mymath{Mpc^2}).
+
+@example
+## Print general cosmological properties at redshift 2.
+$ astcosmiccal -z2
+
+## When given a "Specific calculation" option, CosmicCalculator
+## will just print that particular calculation. See the options
+## under this title in the output of `--help' for more.
+$ astcosmiccal --help
+
+## Only print the "Tangential dist. covered by 1arcsec at z (kpc)".
+## in units of kpc/arc-seconds.
+$ astcosmiccal -z2 --arcsectandist
+
+## Convert this distance to kpc^2/arcmin^2 and save in `k'.
+$ k=$(astcosmiccal -z2 --arcsectandist | awk '@{print ($1*60)^2@}')
+
+## Multiply by the area of the field (in arcmin^2) and divide by
+## 10^6 to return value in Mpc^2.
+$ echo $k $area | awk '@{print $1 * $2 / 1e6@}'
+@end example
+
+@noindent
+At redshift 2, this field therefore covers 1.07145 @mymath{Mpc^2}. If you
+would like to see how this tangential area changes with redshift, you can
+use a shell loop like below.
+
+@example
+$ for z in 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0; do           \
+    k=$(astcosmiccal -z$z --arcsectandist);                      \
+    echo $z $k $area | awk '@{print $1, ($2*60)^2 * $3 / 1e6@}';   \
+  done
+@end example
+
+@noindent
+Fortunately, the shell has a very useful tool/program to print a sequence
+of numbers that is nicely called @code{seq}. You can use it instead of
+typing all the different redshifts in this example. For example the loop
+below will print the same range of redshifts (between 0.5 and 5) but with
+increments of 0.1.
+
+@example
+$ for z in $(seq 0.5 0.1 5); do                                  \
+    k=$(astcosmiccal -z$z --arcsectandist);                      \
+    echo $z $k $area | awk '@{print $1, ($2*60)^2 * $3 / 1e6@}';   \
+  done
+@end example
+
+Let's stop for a moment here. CosmicCalculator has a very limited set of
+parameters and it is fast, so, we'll use it to discuss configuration files
+(@ref{Configuration files}). Once you get comfortable with what is done
+below, you can easily do the same for the options of all Gnuastro
+programs. For example, NoiseChisel has the largest number of options in all
+Gnuastro's programs. Therefore configuration files will be very useful for
+it when you use different datasets (with different noise properties).
+
+As we saw above, the full list of the options in all Gnuastro programs can
+be seen with the @option{--help} option. Try using it with the command
+below. Note how options are grouped by context to make it easier to find
+your desired option. However, in each group, options are ordered
+alphabetically.
+
+@example
+$ astcosmiccal --help
+@end example
+
+@noindent
+The options that need a value have an @key{=} sign after their long version
+and @code{FLT}, @code{INT} or @code{STR} for floating point numbers,
+integer numbers and strings (filenames for example) respectively. All
+options have a long format and some have a (single character) short format,
+see @ref{Options}.
+
+When you are using a program, it is often necessary to check the value the
+option has just before the program starts its processing. In other words,
+after it has parsed the command-line options and all configuration
+files. You can see the values of all options that need one with the
+@option{--printparams} or @code{-P} option that is common to all programs
+(see @ref{Common options}). In the command below, try replacing @code{-P}
+with @option{--printparams} to see how both do the same operation.
+
+@example
+$ astcosmiccal -P
+@end example
+
+None of Gnuastro's programs keep a default value internally. But when you
+ran CosmicCalculator with the @option{-z2} option above, it completed its
+processing. Where did the ``default'' cosmological parameter values come
+from?  The values come from the command-line or a configuration file (see
+@ref{Configuration file precedence}). The highest priority is given to the
+command-line. Let's say you want a different Hubble constant. Try running
+the following command to see how the hubble constant in the output of the
+command above has changed. Then replace the @option{-P} with @option{-z2}
+to confirm the new results.
+
+@example
+$ astcosmiccal --H0=70 -P
+@end example
+
+From the output of the @code{--help} option, note how the option for hubble
+constant has both short (@code{-H}) and long (@code{--H0}) formats. One
+final note is that the equal (@key{=}) sign is not mandatory. In the short
+format, the value can stick to the actual option (the short option name is
+just one character after-all and thus easily identifiable) and in the long
+format, a white-space character is also enough.
+
+@example
+$ astcosmiccal -H70    -z2
+$ astcosmiccal --H0 70 -z2 --arcsectandisk
+@end example
+
+Let's assume that in one project, you want to only use rounded cosmological
+parameters (H0 of 70km/s/Mpc and matter density of 0.3). You should
+therefore run CosmicCalculator like this:
+
+@example
+$ astcosmiccal --H0=70 --olambda=0.7 --omatter=0.3 -z2
+@end example
+
+But having to type these extra options every time you run CosmicCalculator
+will be prone to errors (typos in particular) and also will be frustrating
+and slow. Therefore in Gnuastro, you can put all the options and their
+values in a ``Configuration file'' and tell the programs to read the option
+values from there. Create a file named @file{my-cosmology.conf} (or
+@file{my-cosmology.txt}, the suffix doesn't matter) with these lines. One
+space between the option value and name is enough, the values are just
+under each other to help in readability). Also note that you can only use
+long option names in configuration files.
+
+@example
+H0       70
+olambda  0.7
+omatter  0.3
+@end example
+
+@noindent
+You can now tell CosmicCalculator to read this file for option values
+immediately using the @option{--config} option as shown below. Do you see
+how the output corresponds to the option values in @file{my-cosmology.txt}?
+
+@example
+$ astcosmiccal --config=my-cosmology.conf -z2
+@end example
+
+If you need this cosmology every time you are working in a specific
+directory, you can benefit from Gnuastro's default configuration files to
+avoid having to call the @option{--config} option. Let's assume that you
+want any CosmicCalculator call you make in the @file{my-cosmology}
+directory to use these parameters. You just have to copy the above
+configuration file into a special directory and file. Once you run
+CosmicCalculator, you will see the results implement your desired option
+values without having to type anything extra on the command-line.
+
+@example
+$ mkdir my-cosmology
+$ mkdir my-cosmology/.gnuastro
+$ mv my-cosmology.conf my-cosmology/.gnuastro/astcosmiccal.conf
+$ cd my-cosmology
+$ astcosmiccal -z2
+$ cd ..
+@end example
+
+To further simplify the process, you can use the @option{--setdirconf}
+option. If you are already in your desired directory, calling this option
+with the others will automatically write the final values (along with
+descriptions) in @file{.gnuastro/astcosmiccal.conf}. For example this
+command:
+
+@example
+$ rm -rf my-cosmology         # Make sure the directory doesn't exist.
+$ mkdir my-cosmology
+$ astcosmiccal --H0 70 --olambda=0.7 --omatter=0.3 --setdirconf
+$ cat .gnuastro/astcosmiccal.conf # See the output configuration file.
+$ cd ..
+@end example
+
+Gnuastro's programs also have default configuration files for a specific
+user (when run in any directory). This allows you to set a special behavior
+every time a program is run by a specific user. Only the directory and
+filename differ from the above, the rest of the process is similar to
+before. Finally, there are also system-wide configuration files that can be
+used to define the option values for all users on a system. Please see
+@ref{Configuration file precedence} for where the programs look for default
+user and system wide configuration files.
+
+We are now ready to start processing the downloaded images. Since these
+datasets are already aligned, you don't need to align them to make sure the
+pixel grid covers the same region in all inputs. Gnuastro's Warp program
+has features for such pixel-grid warping (see @ref{Warp}). Therefore, just
+for a demonstration, let's assume one image needs to be rotated by 20
+degrees to correspond to the other. To do that, you can run this command:
+
+@example
+$ astwarp flat-ir/xdf-f160w.fits --rotate=20
+@end example
+
+Warp can generally be used for any kind of pixel grid manipulation. For
+example the outputs of the commands below will respectively have larger
+pixels (new resolution being one quarter the original resolution), get
+shifted by 2.8 (by sub-pixel), get a shear of 2, and be tilted
+(projected).
+
+@example
+$ astwarp flat-ir/xdf-f160w.fits --scale=0.25
+$ astwarp flat-ir/xdf-f160w.fits --translate=2.8
+$ astwarp flat-ir/xdf-f160w.fits --shear=2
+$ astwarp flat-ir/xdf-f160w.fits --project=0.001,0.0005
+@end example
+
+@noindent
+You can also combine multiple warps in one command. For example rotation
+and scaling with the command below.
+
+@example
+$ astwarp flat-ir/xdf-f160w.fits --rotate=20 --scale=0.25
+@end example
+
+If you have multiple warps, do them all in one command. Don't warp them in
+separate commands because the correlated noise will become too strong. As
+you see in the matrix that is printed when you run Warp, it merges all the
+warps into a single warping matrix (see @ref{Warping basics} and
+@ref{Merging multiple warpings}) and simply applies that just once. Recall
+that since this is done through matrix multiplication, order matters in the
+separate operations. Infact through Warp's @option{--matrix} option, you
+can directly request your desired final rotation and don't have to break it
+up into different warps (see @ref{Invoking astwarp}).
+
+Fortunately these datasets are already aligned to the same pixel grid, so
+you don't actually need the files that were just generated. You can safely
+delete them all with the following command. Here, you see why we put the
+processed outputs that we need later into a separate directory. In this
+way, the top directory can be used for temporary files for testing that you
+can simply delete with a generic command like below.
+
+@example
+$ rm *.fits
+@end example
+
+@noindent
+To detect the objects in the image, we'll run NoiseChisel:
+
+@example
+$ mkdir noisechisel
+$ astnoisechisel flat-ir/xdf-f160w.fits -onoisechisel/xdf-f160w.fits
+@end example
+
+Read what NoiseChisel writes on the command-line. The curious thing you
+will notice is that while there were more than 3000 pseudo detections to
+find the pseudo-detection S/N, but there were only slightly more than 100
+clumps to find the false clump S/N. We will see what caused this after a
+short review on the output of NoiseChisel.
+
+NoiseChisel's output is a single file containing multiple extensions. You
+can get basic information about the extensions in a FITS file with
+Gnuastro's Fits program (see @ref{Fits}) as shown below. It contains 6
+extensions and the first (counted as zero) is blank (has no data).
+
+@example
+$ astfits noisechisel/xdf-f160w.fits
+@end example
+
+NoiseChisel puts some general information on its outputs in the FITS header
+of the respective extension. To see the full list of keywords, you can
+again use the Fits program like above, but also give it your desired
+extension/HDU. You can also give the extension number (as listed in the
+output above), for example @option{-h2} instead of @option{-hOBJECTS}.
+
+@example
+$ astfits noisechisel/xdf-f160w.fits -hOBJECTS
+@end example
+
+@cindex GNU Grep
+The @code{NUMLABS} keyword in NoiseChisel's @code{OBJECTS} extension
+contains the number of objects that was found by NoiseChisel in that
+run. Try to visually find it in the header keywords you saw above.
+
+To simplify the process, you can pipe the output of the command above into
+@code{grep} (a program for matching lines which is available on almost all
+Unix-like operating systems).
+
+@example
+$ astfits noisechisel/xdf-f160w.fits -hOBJECTS | grep NUMLABS
+@end example
+
+@cindex GNU Grep
+If you just want the value of the keyword and not the full FITS keyword
+line, you can use AWK. In the example below, AWK will print the third word
+(separated by white space characters) in any line that has a first column
+value of @code{NUMLABS}. You can also try this for the third HDU (called
+@code{CLUMPS}) to see the number of clumps.
+
+@example
+$ astfits noisechisel/xdf-f160w.fits -h2                             \
+          | awk '$1=="NUMLABS" @{print $3@}'
+@end example
+
+Grep and AWK are simple, but very powerfull command-line software for
+processing text files. Learning them properly can greatly simplify your
+processing, while improve your creativity, productivity and speed. When you
+get time, it is highly recommended to master them. The most common
+implementation of both is from GNU. Like almost all GNU software, both GNU
+Grep and GNU AWK have wonderful manuals which come with the program for
+free. You don't have to read the whole manual at once, they both start with
+great generic introductions to get you going fast. As described above, you
+can read both manuals or refresh your memory on your command-line with
+these commands:
+
+@example
+$ info awk
+$ info grep
+@end example
+
+@cindex GNOME
+You can now open NoiseChisel's output with SAO DS9 and visually inspect
+it. Just note that since there are multiple extensions, the easiest way to
+view the whole file is to open it as a ``Multi-extension data cube'' with
+the @option{-mecube} option as shown below. If you use GNOME (another GNU
+software, most common graphic user interface in GNU/Linux operating
+systems), please see @ref{Viewing multiextension FITS images} to open DS9
+in multi-extension cube mode by default when using the GUI (double clicking
+on the file).
+
+@example
+$ ds9 -mecube noisechisel/xdf-f160w.fits -zscale -zoom to fit
+@end example
+
+Using Gnuastro's Fits program, you can also copy a HDU from one FITS file
+to another (for more, see @ref{HDU manipulation}). So if you want to have a
+FITS file with only the detected objects, you can run this command:
+
+@example
+$ astfits noisechisel/xdf-f160w.fits --copy=OBJECTS -oobjects.fits
+@end example
+
+One good way to see if you have missed any signal is to mask all the
+detected pixels and inspect the noise pixels. For this, you can use
+Gnuastro's Arithmetic program (in particular its @code{where} operator as
+shown below, see @ref{Arithmetic operators}). With this command, all input
+pixels that have a value larger than zero in the @code{OBJECTS} extension
+will be set to NaN in the output (written in @file{det-masked.fits}). If
+you change the @code{gt} (for ``greater than'') operator to @code{eq} (for
+``equal''), all the un-detected (sky) pixels will be masked and you can see
+the detections.
+
+@example
+$ astarithmetic noisechisel/xdf-f160w.fits                         \
+                noisechisel/xdf-f160w.fits 0 gt nan where -h1 -h2  \
+                --output=nc-masked.fits
+@end example
+
+In some cases, you might want to use a different kernel with NoiseChisel
+(not the default one). To do that, you can use MakeProfiles (see
+@ref{MakeProfiles}) in the following manner to build a 2D Gaussian kernel
+with a FWHM of 3 pixels that extends 5 times the FWHM. This new kernel can
+later be fed into NoiseChisel with the @option{--kernel} option.
+
+@example
+$ astmkprof --kernel=gaussian,3,5 --oversample=1 -okernel-g-3-5.fits
+$ astnoisechisel flat-ir/xdf-f160w.fits --kernel=kernel-g-3-5.fits   \
+                 --output=nc-my-kernel.fits
+@end example
+
+NoiseChisel can produce ``Check images'' to help you visualize how each
+step is completed. You can see all the check images it can produce with
+this command.
+
+@example
+$ astnoisechisel --help | grep check
+@end example
+
+The check images are also multi-extension FITS files. After each check
+image is produced, open it with ds9 like NoiseChisel's output above and
+flip through the extensions to see each processing in detail. It is
+@emph{strongly} encouraged to play with the different parameters and use
+the respective check images to see which step is affected by your
+change. The three most useful check images are @option{--checkqthresh},
+@option{--checkdetection}, and @option{--checksegmentation}.
+
+We can now get back to the curious situation we noticed after running
+NoiseChisel: the number of false clumps to find an S/N limit was very small
+(given the extent of this image). This is bad, because we use quantiles in
+NoiseChisel and such a small number will result in a relatively large
+scatter. Since this is a segmenation issue, let's see why this happens with
+@option{--checksegmentation}.
+
+@example
+$ astnoisechisel flat-ir/xdf-f160w.fits --checksegmentation
+@end example
+
+To help you get a result faster, when check images are requested,
+NoiseChisel doesn't finish its processing (unless you also call
+@option{--continueaftercheck}). NoiseChisel aborts with an explanation of
+why it stopped without finishing and the file name of the check image that
+it produced. The first five extensions are: the input image, the convolved
+image, the initially labeled detected regions, all the sky region (false)
+clumps, and those that will be used for S/N. The sky clumps are found over
+NoiseChisel's ``large tiles'' independently. When inspecting the fourth
+extension of the check image, it is interesting how NoiseChisel has ignored
+most large tiles and only used the few that we see, mostly on the edge.
+
+The reason that almost all internal large tiles are ignored is that
+galaxies are extended and this is a very deep (and small) image. Thanks to
+the PSF (see @ref{PSF}), no object will have a sharp truncation. We have
+not seen any abrupt break in the light profile of any galaxy: galaxies are
+always larger when we get deeper datasets. Therefore, in a noisy image,
+some light will always be left un-detected. To be less affected by this
+un-detected light, NoiseChisel has the @option{--minskyfrac} option (see
+@ref{General NoiseChisel options}): any tile that has a larger fraction of
+detected pixels will be ignored. So let's see what the default value of
+this option is (recall that with @option{-P}, you can list all the options
+with their values in Gnuastro's programs):
+
+@example
+$ astnoisechisel -P | grep minskyfrac
+@end example
+
+@noindent
+Try decreasing this value and re-running NoiseChisel to see the effect on
+the fraction of large tiles that will be used for finding false/sky
+clumps. Play a little with this parameter (give it different values and
+check the result).
+
+@example
+$ astnoisechisel flat-ir/xdf-f160w.fits --minskyfrac=0.5           \
+                 --checksegmentation
+@end example
+
+The smaller the value to @option{--minskyfrac}, the more probable that
+un-detected light in the wings of galaxies will bias/affect the derived
+false clump S/N. So it is always important to find a good balance between a
+larger @option{--minskyfrac} while having a sufficient number of resulting
+clumps (to avoid scatter).
+
+NoiseChisel doesn't just find the labelled pixels, it also finds the Sky
+value and the Sky standard deviation in the final two extensions of its
+output. To generate a catalog of the colors, we will be using the
+NoiseChisel labeled image from the F160W image. But the Sky and Sky
+standard deviation values for each different filter will also be
+necessary. So we'll run NoiseChisel with our finalized parameters value on
+both filters (you can also put this option's value in a configuration file
+to avoid repeating it).
+
+@example
+$ astnoisechisel flat-ir/xdf-f105w.fits -onoisechisel/xdf-f105w.fits \
+                 --minskyfrac=0.5
+$ astnoisechisel flat-ir/xdf-f160w.fits -onoisechisel/xdf-f160w.fits \
+                 --minskyfrac=0.5
+@end example
+
+Now, we are ready to make a catalog. We want the object and clump labels
+from the F160W image. But the input, Sky and Sky standard deviation images
+should come from each filter. So, we'll run MakeCatalog on NoiseChisel's
+output differently for each filter. When making the F105W catalog, we'll
+use the @option{--objectsfile} and @option{--clumpsfile} options to tell
+MakeCatalog to read the object and clump labels from the F160W NoiseChisel
+output. When these options aren't given, MakeCatalog will look into the
+same input file for object and clump labels.
+
+For both filters, we'll ask for the ID, RA, Dec, Magnitude and
+signal-to-noise ratio (see @ref{Quantifying measurement limits}). To see a
+list of all the parameters that MakeCatalog can measure for you, run it
+with @option{--help} option.
+
+@example
+$ mkdir catalog
+
+$ astmkcatalog noisechisel/xdf-f160w.fits --zeropoint=25.94     \
+               --ids --ra --dec --magnitude --sn                \
+               --output=catalog/xdf-f160w.fits
+
+$ astmkcatalog noisechisel/xdf-f105w.fits --zeropoint=26.27     \
+               --objectsfile=noisechisel/xdf-f160w.fits         \
+               --clumpsfile=noisechisel/xdf-f160w.fits          \
+               --ids --ra --dec --magnitude --sn                \
+               --output=catalog/xdf-f105w.fits
+@end example
+
+MakeCatalog can also produce catalogs in plain text format. Please run the
+MakeCatalog commands above again and replace the @file{.fits} suffix, in
+the value to @option{--output}, with @file{.txt} (we will also be using the
+text file outputs later).
+
+When a clumps image is also given@footnote{MakeCatalog will look at the
+@code{WCLUMPS} keyword in the objects image to see if it should also use a
+clumps image or not.}, like this example, two catalogs will be made. If you
+asked for a plain text file output, two files will be made with the
+@file{_c.txt} and @file{_o.txt} suffixes. If MakeCatalog's output is
+requested to be FITS, the two catalogs will be in separate extensions of a
+single file. You can inspect the separate extensions with the Fits program
+like before (as shown below). Afterwards, you can inspect the table in each
+extension with Gnuastro's Table program (see @ref{Table}) as shown below.
+
+@example
+$ astfits catalog/xdf-f105w.fits             # Extension information
+$ asttable catalog/xdf-f105w.fits -h1 --info # Objects catalog info.
+$ asttable catalog/xdf-f105w.fits -h1        # Objects catalog columns.
+$ asttable catalog/xdf-f105w.fits -h2 -i     # Clumps catalog info.
+$ asttable catalog/xdf-f105w.fits -h2        # Clumps catalog columns.
+@end example
+
+As you see above, to see the column contents of each table, you can just
+remove the @option{--info} (or @option{-i}) option. If you want to print
+the contents of special column(s), just specify the column number(s)
+(counting from @code{1}, same as output of the command above) or the column
+name(s) (if they have one). For example, if you just want the objects and
+clumps magnitude and signal-to-noise ratio in the F160W filter. You can get
+it with the following commands.
+
+@example
+$ asttable catalog/xdf-f160w.fits -h1 -cMAGNITUDE -cSN
+$ asttable catalog/xdf-f160w.fits -h2 -cMAGNITUDE -cSN
+@end example
+
+The clumps catalog has two ID columns (one for the over-all clump ID and
+one for the ID of the clump in its host object), the magnitude column
+numbers differ between the object and clumps catalog. So if you want to
+specify the columns by number, you will need to change the numbers when
+viewing the clump and objects catalogs. This is a useful advantage of
+having/using column names.
+
+@example
+$ asttable catalog/xdf-f160w.fits -h1 -c4 -c5
+$ asttable catalog/xdf-f160w.fits -h2 -c5 -c6
+@end example
+
+Finally, the comments in MakeCatalog's output (in FITS headers or lines
+starting with @code{#} in plain text) contain some important information
+about the dataset that can be useful. Open @file{catalog/xdf-f160w_o.txt}
+in a text editor to see them.
+
+Since we used the same labeled image on both filters, the number of rows in
+both catalogs are the same. So, let's measure the colors of the objects in
+this image. We'll merge the two clump catalogs together into one using the
+@code{paste} program on the command-line. The output file will have each
+line of both catalogs merged into a single line.
+
+@example
+$ paste catalog/xdf-f160w_c.txt catalog/xdf-f105w_c.txt           \
+        > xdf-f160w-f105w_c_p.txt
+@end example
+
+Open @file{xdf-f160w-f105w_c_p.txt} after making it to see how
+@command{paste} has operated. We can now use AWK to find the colors. We'll
+ask AWK to only use lines that don't start with @code{#} and don't have a
+NaN magnitude in the 9th column (F105W magnitude@footnote{Recall that the
+objects and clumps labels were made on the F160W image. On the F105W image,
+there might not be enough signal, so random scatter may give a negative
+total brightness and thus a NaN magnitude.}). We will also ignore columns
+which don't have reliable F105W magnitudes (with a S/N less than
+7@footnote{The value of 7 is taken from the clump S/N threshold in F160W
+(where the clumps were defined).}). For the other lines, AWK will print the
+ID, positional columns and the difference between the respective magnitude
+columns.
+
+@example
+$ awk '!/^#/ && $11!="nan" && $12>7  @{print $1, $2, $3, $4, $11-$5@}' \
+      xdf-f160w-f105w_c_p.txt > catalog/xdf-f105w-f160w_c.txt
+@end example
+
+Gnuastro has a simple program for basic statistical analysis. The command
+below will print some basic information about the distribution (minimum,
+maximum, median and etc), along with a cute little ASCII histogram to
+visually help you understand the distribution on the command-line without
+the need for a graphic user interface (see @ref{Invoking
+aststatistics}). This ASCII histogram can be useful when you just want some
+coarse and general information on the input dataset. It is also useful when
+working on a server (where you may not have graphic user interface), and
+finally, its fast.
+
+@example
+$ aststatistics catalog/xdf-f105w-f160w_c.txt -c5
+@end example
+
+You can later use Gnuastro's Statistics program with the
+@option{--histogram} option to build a much more fine-grained histogram as
+a table to feed into your favorite plotting program for a much more
+accurate/appealing plot. If you just want a specific measure, for example
+the mean, median and standard deviation, you can ask for them specifically:
+
+@example
+$ aststatistics catalog/xdf-f105w-f160w_c.txt -c5 --mean --median --std
+@end example
+
+Some researchers prefer to have colors in a fixed aperture for all the
+objects. The colors we calculated above used a different segmentation map
+for each object. This might not satisfy some science cases. To make a fixed
+aperture catalog, we should make a labeled image which has a fixed label
+for each aperture. That labeled image can be given to MakeCatalog instead
+of NoiseChisel's labeled detection image.
+
+@cindex GNU AWK
+We'll use the objects catalog in the F160W catalog we generated before for
+the positions and set the other parameters of each profile to be a fixed
+circle of radious 5 pixels (we want all apertures to be fixed
+afterall). AWK is a wonderful tool for such jobs as the command below
+shows.
+
+@example
+$ awk '!/^#/@{print $1, $2, $3, 5, 5, 0, 0, 1, $1, 1@}'                \
+      catalog/xdf-f160w_c.txt > catalog/apertures.txt
+@end example
+
+We can now feed this catalog into MakeProfiles to build the apertures for
+us. See @ref{Invoking astmkprof} for a description of the options. The most
+important for this particular job is @option{--mforflatpix}, it tells
+MakeProfiles that the values in the magnitude column should be used for
+each pixel of a flat profile. Without it, MakeProfiles would build the
+profiles such that the @emph{sum} of the pixels of each profile would have
+a @emph{magnitude} (in log-scale) of the value given in that column (what
+you would expect when simulating a galaxy for example).
+
+@example
+$ astmkprof catalog/apertures.txt --background=flat-ir/xdf-f160w.fits \
+            --clearcanvas --replace --type=int16 --mforflatpix        \
+            --mode=wcs
+@end example
+
+The first thing you might notice in the printed information is that the
+profiles are not built in order. This is because MakeProfiles works in
+parallel and parallel CPU operations are asynchronous. Without
+@option{--replace}, the output is the same in any case. You can try running
+MakeProfiles with one thread (using @option{--numthreads=1} to see how
+order is respected in that case.
+
+Open the output @file{apertures.fits} file and see the result. Where the
+apertures overlap, you will notice that one label has replaced the other
+(because of the @option{--replace} option). In the future, MakeCatalog will
+be able to work with overlapping labels, but currently it doesn't. If you
+are interested, please join us in completing Gnuastro with added
+improvements like this (see task 14750
+@footnote{@url{https://savannah.gnu.org/task/index.php?14750}}).
+
+@file{apertures.fits} labeled image can now be fed input into
+MakeCatalog. Similar to how we used the F160W labels for the F105W catalog:
+the labels don't have to be produced by NoiseChisel. In comparison with the
+previous MakeCatalog call, notice how 1) we have no more clumps image, 2)
+that we have set @option{--objectshdu=1} (since @file{apertures.fits} is
+not the output of NoiseChisel where the labeled image is in the third
+extension), and 3) that we are now using @option{--objid} instead of
+@option{--ids} to avoid warnings that some ID columns are only for clumps.
+
+@example
+$ astmkcatalog noisechisel/xdf-f105w.fits --zeropoint=26.27        \
+               --objectsfile=apertures.fits --objectshdu=1         \
+               --objid --ra --dec --magnitude --sn                 \
+               --output=catalog/xdf-f105w-aper.fits
+@end example
+
+Change the filter name and zeropoint magnitudes and run this command again
+to have the fixed aperture magnitude in the F160W filter also. From this
+point on, you can follow the previous steps to derive the color in a fixed
+aperture.
+
+We will now find some of the objects with the strongest color difference
+and make a cutout to inspect them visually: let's see what the objects with
+a color more than two magnitudes look like.
+
+@cindex AWK
+We'll use the @file{catalog/xdf-f105w-f160w_c.txt} file that we produced
+above. With the command below, all lines with a color value more than 2
+will be put in @file{reddest.txt} and inspect it using @command{cat}.
+
+@example
+$ awk '$5>1' catalog/xdf-f105w-f160w_c.txt > reddest.txt
+$ cat reddest.txt
+@end example
+
+We can now feed @file{reddest.txt} into Gnuastro's crop to see what these
+objects look like. To keep things clean, we'll make a directory called
+@file{reddest} and ask Crop to save the crops in this directory. We'll also
+add a @file{-f160w.fits} suffix to the crops.
+
+@example
+$ mkdir crop
+$ astcrop --mode=wcs --coordcol=3 --coordcol=4 flat-ir/xdf-f160w.fits  \
+          --catalog=reddest.txt --width=15/3600,15/3600                \
+          --suffix=-f160w.fits --output=crop
+@end example
+
+Like the MakeProfiles command above, you might notice that the crops aren't
+made in order. Since each crop is independent of the rest, the crops are
+done in parallel and parallel operations are asynchronous. In the command
+above, change @file{f160w} to @file{f105w} to make the crops in both
+filters.
+
+To view the crops more easily (not having to open ds9 for each image), you
+can convert the FITS crops into the JPEG format.
+
+@example
+$ for f in *.fits; do                                                  \
+    astconvertt $f --fluxlow=-0.001 --fluxhigh=0.005 --invert -ojpg;   \
+  done
+@end example
+
+The loop above is in series: each file is processed only after the previous
+ones are complete. If you have @url{https://www.gnu.org/software/parallel,
+GNU Parallel}, you can greatly speed up this conversion. GNU Parallel will
+run the separate commands simultaneously on different CPU threads in
+parallel. For more information on efficiently using your threads, see
+@ref{Multi-threaded operations}.
+
+@example
+$ parallel astconvertt --fluxlow=-0.001 --fluxhigh=0.005 --invert      \
+           -ojpg ::: *.fits
+@end example
+
+You can now easily use your general GUI image viewer to flip through the
+images more easily. On GNOME, you can use the ``Eye of GNOME'' image viewer
+with a command like below and by pressing the @key{<SPACE>} key, you can
+flip through the images and compare them visually more easily. Ofcourse,
+the flux ranges have been chosen generically here for seeing the fainter
+parts. Therefore, brighter objects will be fully black.
+
+@example
+$ eog 1-f105w.jpg
+@end example
+
+Another thing that is commonly needed is to visually mark these objects on
+the image. DS9 has ``Region''s for this purpose. You just have to convert
+your catalog into a ``region file'' to feed into DS9. To do that, you can
+use AWK again as shown below.
+
+@example
+$ cd ..
+$ awk 'BEGIN@{print "# Region file format: DS9 version 4.1";     \
+             print "global color=green width=2";                \
+             print "fk5";@}                                      \
+       @{printf "circle(%s,%s,1\")\n", $3, $4;@}' reddest.txt     \
+       > reddest.reg
+@end example
+
+This region file can be loaded into DS9 with its @option{-regions} option
+as shown below (see above for the other options):
+
+@example
+$ ds9 -mecube noisechisel/xdf-f160w.fits -zscale -zoom to fit    \
+      -regions load all reddest.reg
+@end example
+
+Finally, if this book or any of the programs in Gnuastro have been useful
+for your research, please cite the respective papers. All Gnuastro programs
+have a @option{--cite} option to help you cite the authors' work more
+easily. For example:
+
+@example
+$ astmkcatalog --cite
+@end example
 
 
 
@@ -2792,7 +3893,7 @@ bytes)@footnote{You can also download the DVD iso file at 
a later time to
 keep as a backup for when you don't have internet connection if you need a
 package.}.
 
-After the installation be sure to set the environment variables as
+After the installation, be sure to set the environment variables as
 suggested in the end of the outputs. Any time you confront (need) a package
 you don't have, simply install it with a command like below (similar to how
 you install software from your operating system's package
@@ -11192,6 +12293,7 @@ input dataset (with @ref{MakeCatalog}).
 * Statistics::                  Calculate dataset statistics.
 * NoiseChisel::                 Detect objects in an image.
 * MakeCatalog::                 Catalog from input and labeled images.
+* Match::                       Match two datasets.
 @end menu
 
 @node Statistics, NoiseChisel, Data analysis, Data analysis
@@ -13346,7 +14448,7 @@ function ds9-nc3d-check @{
 @}
 @end example
 
-@node MakeCatalog,  , NoiseChisel, Data analysis
+@node MakeCatalog, Match, NoiseChisel, Data analysis
 @section MakeCatalog
 
 At the lowest level, a dataset (for example an image) is just a collection
@@ -13527,9 +14629,9 @@ measurements discussed here are defined in units of 
magnitudes.
 As we make more observations on one region of the sky, and add the
 observations into one dataset, we are able to decrease the standard
 deviation of the noise in each pixel@footnote{This is true for any noisy
-data, not just astronomical images}. Qualitatively, this decrease manifests
-its self by making fainter (per pixel) parts of the objects in the image
-more visible. Technically, this is known as surface
+data, not just astronomical images.}. Qualitatively, this decrease
+manifests its self by making fainter (per pixel) parts of the objects in
+the image more visible. Technically, this is known as surface
 brightness. Quantitatively, it increases the Signal to noise ratio, since
 the signal increases faster than noise with more data. It is very important
 to have in mind that here, noise is defined per pixel (or in the units of
@@ -14644,8 +15746,171 @@ with the first FITS axis in degrees.
 
 
 
+@node Match,  , MakeCatalog, Data analysis
+@section Match
+
+Data can come come from different telescopes, filters, software and even
+different configurations for a single software. As a result, one of the
+primary things to do after generating catalogs from each of these sources
+(for example with @ref{MakeCatalog}), is to find which sources in one
+catalog correspond to which in the other(s). In other words, to `match' the
+two catalogs with each other.
+
+Gnuastro's Match program is in charge of such operations. The nearest
+objects in the two catalogs, within the given aperture, will be found and
+given as output. The aperture can be a circle or an ellipse with any
+orientation.
+
+@menu
+* Invoking astmatch::           Inputs, outputs and options of Match
+@end menu
+
+@node Invoking astmatch,  , Match, Match
+@subsection Invoking Match
+
+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
+@end example
+
+@noindent
+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).
+## (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 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
+plain text tables or FITS tables, see @ref{Tables}. When @option{--quiet}
+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 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. 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 multi-extension FITS file or two plain
+text files.
+
+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.
+
+When the @option{--log} option is called (see @ref{Operating mode
+options}), Match will also create a file named @file{astmatch.fits} (or
+@file{astmatch.txt}, 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
+@option{--output} option) will have the contents of this log file.
 
+@table @option
+@item -H STR
+@itemx --hdu2=STR
+The extension/HDU of the second input if it is a FITS file. When it isn't a
+FITS file, this option's value is ignored. For the first input, the common
+option @option{--hdu} must be used.
+
+@item -l
+@itemx --logasoutput
+The output file will have the contents of the log file: indexs in the two
+catalogs that match with each other along with their distance. See
+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
+
+@item --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 columns of the second input. See the example in
+@option{--ccol1} 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 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
+@item 1D match
+The aperture/interval can only take one value: half of the interval around
+each point (maximum distance from each point).
+
+@item 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.
+@table @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
+@option{--ccol1} and @option{--ccol2}).
+
+@item 2 numbers
+For example @option{--aperture=3,4e-10}. The aperture will be an ellipse
+(if the two numbers are different) with the respective value along each
+dimension. The numbers are in units of the first and second axis. In the
+example above, the semi-axis value along the first axis will be 3 (in units
+of the first coordinate) and along the second axis will be
+@mymath{4\times10^{-10}} (in units of the second coordinate). Such values
+can happen if you are comparing catalogs of a spectra for example. If more
+than one object exists in the aperture, the nearest will be found along the
+major axis as described in @ref{Defining an ellipse and ellipsoid}.
+
+@item 3 numbers
+For example @option{--aperture=2,0.6,30}. The aperture will be an ellipse
+(if the second value is not 1). The first number is the semi-major axis,
+the second is the axis ratio and the third is the position angle (in
+degrees). If multiple matches are found within the ellipse, the distance
+(to find the nearest) is calculated along the major axis in the elliptical
+space, see @ref{Defining an ellipse and ellipsoid}.
+@end table
+@end table
+@end table
 
 
 
@@ -14771,8 +16036,8 @@ familiar with these concepts.
 @cindex Axis ratio
 @cindex Position angle
 The PSF, see @ref{PSF}, and galaxy radial profiles are generally defined on
-an ellipse so in this section first defining an ellipse on a pixelated 2D
-surface is discussed. Labeling the major axis of an ellipse @mymath{a}, and
+an ellipse. Therefore, in this section we'll start defining an ellipse on a
+pixelated 2D surface. Labeling the major axis of an ellipse @mymath{a}, and
 its minor axis with @mymath{b}, the @emph{axis ratio} is defined as:
 @mymath{q\equiv b/a}. The major axis of an ellipse can be aligned in any
 direction, therefore the angle of the major axis with respect to the
@@ -14784,7 +16049,7 @@ Our aim is to put a radial profile of any functional 
form @mymath{f(r)}
 over an ellipse. Hence we need to associate a radius/distance to every
 point in space. Let's define the radial distance @mymath{r_{el}} as the
 distance on the major axis to the center of an ellipse which is located at
-@mymath{i_c} and @mymath{i_c} (in other words @mymath{r_{el}\equiv{a}}). We
+@mymath{i_c} and @mymath{j_c} (in other words @mymath{r_{el}\equiv{a}}). We
 want to find @mymath{r_{el}} of a point located at @mymath{(i,j)} (in the
 image coordinate system) from the center of the ellipse with axis ratio
 @mymath{q} and position angle @mymath{\theta}. First the coordinate system
@@ -17760,6 +19025,16 @@ list. Some of the most common values to this option 
are: @option{pedantic}
 (Warnings related to standard C) and @option{all} (all issues the compiler
 confronts).
 
+@item --tag=STR
+The language configuration information. Libtool can build objects and
+libraries in many languages. In many cases, it can identify the language
+automatically, but when it doesn't you can use this option to explicitly
+notify Libtool of the language. The acceptable values are: @code{CC} for C,
+@code{CXX} for C++, @code{GCJ} for Java, @code{F77} for Fortran 77,
+@code{FC} for Fortran, @code{GO} for Go and @code{RC} for Windows
+Resource. Note that the Gnuastro library is not yet fully compatible with
+all these languages.
+
 @item -b
 @itemx --onlybuild
 Only build the program, don't run it. By default, the built program is
@@ -17857,6 +19132,7 @@ documentation will correspond to your installed version.
 * Polygons::                    Working with the vertices of a polygon.
 * Qsort functions::             Helper functions for Qsort.
 * Permutations::                Re-order (or permute) the values in a dataset.
+* Matching::                    Matching catalogs based on position.
 * Statistical operations::      Functions for basic statistics.
 * Binary datasets::             Datasets that can only have values of 0 or 1.
 * Convolution functions::       Library functions to do convolution.
@@ -19050,15 +20326,15 @@ converting to a smaller type, it is up to you to make 
sure that the values
 fit into the output type.
 
 @deftypefun {gal_data_t *} gal_data_copy (gal_data_t @code{*in})
-Return a new dataset that is a copy of @code{in}, the main meta-data of the
-input is also copied into the output.
+Return a new dataset that is a copy of @code{in}, all of @code{in}'s
+meta-data will also copied into the output, except for @code{block}.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_data_copy_to_new_type (gal_data_t @code{*in}, 
uint8_t @code{newtype})
 Return a copy of the dataset @code{in}, converted to @code{newtype}, see
 @ref{Library data types} for Gnuastro library's type identifiers. The
-returned dataset will have all meta-data accept their type equal to the
-input's metadata.
+returned dataset will have all meta-data except their type and @code{block}
+equal to the input's metadata.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_data_copy_to_new_type_free (gal_data_t 
@code{*in}, uint8_t @code{newtype})
@@ -19244,8 +20520,8 @@ In many contexts such situations never come up, for 
example you don't want
 to shift all the pixels in an image by one or two pixels from some random
 position in the image: their positions have scientific value. But in other
 contexts you will find your self frequently adding/removing an a-priori
-unknown of elements. Linked lists (or @emph{lists} for short) are the
-data-container of choice in such situations. As in a chain, each
+unknown number of elements. Linked lists (or @emph{lists} for short) are
+the data-container of choice in such situations. As in a chain, each
 @emph{node} in a list is an independent C structure, keeping its own data
 along with pointer(s) to its immediate neighbor(s). Below, you can see one
 simple linked list node structure along with an ASCII art schematic of how
@@ -19270,13 +20546,12 @@ middle, you just have to change two. You initially 
define a variable of
 this type with a @code{NULL} pointer as shown below:
 
 @example
-struct list_float *mylist=NULL
+struct list_float *mylist=NULL;
 @end example
 
 @noindent
-then you use functions provided for that the respective type in the
-sections below to add elements to add or remove/pop an element from the
-list.
+To add or remove/pop a node from the list you can use functions provided
+for the respective type in the sections below.
 
 @cindex last-in-first-out
 @cindex first-in-first-out
@@ -19293,10 +20568,11 @@ the list. If you do that, you will get a 
``first-in-first-out'' list. But
 that will force you to go through the whole list for each new element that
 is created (this will slow down the processing)@footnote{A better way to
 get a first-in-first-out is to first keep the data as last-in-first-out
-until they are all read. Afterwards, pop each node and immediately add it
-to the new list: practically reversing the last-in-first-out list to a
-first-in-first-out one. All the list types discussed in this chapter have a
-@code{_reverse} function.}.
+until they are all read. Afterwards, reverse the list by popping each node
+and immediately add it to the new list. This practically reverses the
+last-in-first-out list to a first-in-first-out one. All the list types
+discussed in this chapter have a function with a @code{_reverse} suffix for
+this job.}.
 
 The node example above creates the simplest kind of a list. We can define
 each node with two pointers to both the next and previous neighbors, this
@@ -21890,6 +23166,15 @@ declared in @file{gnuastro/box.h}. All coordinates in 
this header are in
 the FITS format (first axis is the horizontal and the second axis is
 vertical).
 
+@deftypefun void gal_box_bound_ellipse_extent (double @code{a}, double 
@code{b}, double @code{theta_deg}, double @code{*extent})
+Return the maximum extent along each dimension of the given ellipse from
+the center of the ellipse. Therefore this is half the extent of the box in
+each dimension. @code{a} is the ellipse major axis, @code{b} is the minor
+axis, @code{theta_deg} is the position angle in degrees. The extent in each
+dimension is in floating point format and stored in @code{extent} which
+must already be allocated before this function.
+@end deftypefun
+
 @deftypefun void gal_box_bound_ellipse (double @code{a}, double @code{b}, 
double @code{theta_deg}, long @code{*width})
 Any ellipse can be enclosed into a rectangular box. The purpose of this
 function is to give the height and width of that box assuming the center of
@@ -22127,7 +23412,7 @@ types}, for example @code{gal_qsort_int32_decreasing}, 
or
 
 
 
-@node Permutations, Statistical operations, Qsort functions, Gnuastro library
+@node Permutations, Matching, Qsort functions, Gnuastro library
 @subsection Permutations (@file{permutation.h})
 @cindex permutation
 Permutation is the technical name for re-ordering of values. The need for
@@ -22183,7 +23468,89 @@ Apply the inverse of @code{permutation} on the 
@code{input} dataset (can
 have any type), see above for the definition of permutation.
 @end deftypefun
 
-@node Statistical operations, Binary datasets, Permutations, Gnuastro library
+@node Matching, Statistical operations, Permutations, Gnuastro library
+@subsection Matching (@file{match.h})
+
+Matching is often necessary when the measurements have been done using
+different instruments, different software or different configurations of
+the same software. The functions in this part of Gnuastro's library will be
+growing to allow matching of images and finding a match between different
+catalogs (register them). Currently it only provides the  The high-level
+measurements are stored in tables with positions (commonly in RA and Dec
+with units of degrees).
+
+@deftypefun {gal_data_t *} gal_match_coordinates (gal_data_t @code{*coord1}, 
gal_data_t @code{*coord2}, double @code{*aperture}, int @code{sorted_by_first}, 
int @code{inplace}, size_t @code{minmapsize}, size_t @code{*nummatched})
+
+Return the permutations that when applied, the first @code{nummatched} rows
+of both inputs match with each other (are the nearest within the given
+aperture). The two inputs (@code{coord1} and @code{coord2}) must be
+@ref{List of gal_data_t}. Each @code{gal_data_t} node in the list should be
+a single dimensional dataset (column in a table). The dimensionality of the
+coordinates is determined by the number of @code{gal_data_t} nodes in the
+input lists (which must be equal). Note that the number of rows (or the
+number of elements in each @code{gal_data_t}) in the columns of
+@code{coord1} and @code{coord2} can be different.
+
+The matching aperture is defined by the @code{aperture} array. If several
+points of one catalog lie within this aperture of a point in the other, the
+nearest is defined as the match. In a 2D situation (where the input lists
+have two nodes), for the most generic case, it must have three elements:
+the major axis length, axis ratio and position angle (see @ref{Defining an
+ellipse and ellipsoid}). If @code{aperture[1]==1}, the aperture will be a
+circle of radius @code{aperture[0]} and the third value won't be used. When
+the aperture is an ellipse, distances between the points are also
+calculated in the respective elliptical distances (@mymath{r_{el}} in
+@ref{Defining an ellipse and ellipsoid}).
+
+To speed up the search, this function will sort the input coordinates by
+their first column (first axis). If @emph{both} are already sorted by their
+first column, you can avoid the sorting step by giving a non-zero value to
+@code{sorted_by_first}.
+
+When sorting is necessary and @code{inplace} is non-zero, the actual input
+columns will be sorted. Otherwise, an internal copy of the inputs will be
+made, used (sorted) and later freed before returning. Therefore, when
+@code{inplace==0}, inputs will remain untouched, but this function will
+take more time and memory.
+
+If internal allocation is necessary and the space is larger than
+@code{minmapsize}, the space will be not allocated in the RAM, but in a
+file, see description of @option{--minmapsize} in @ref{Processing options}.
+
+The number of matchs will be put in the space pointed by
+@code{nummatched}. If there wasn't any match, this function will return
+@code{NULL}. If match(s) were found, a list with three @code{gal_data_t}
+nodes will be returned. The top two nodes in the list are the permutations
+that must be applied to the first and second inputs respectively. After
+applying the permutations, the top @code{nummatched} elements will match
+with each other. The third node is the distances between the respective
+match. Note that the three nodes of the list are all one-dimensional (a
+column) and can have different lengths.
+
+@cartouche
+@noindent
+@strong{Output permutations ignore internal sorting}: the output
+permutations will correspond to the initial inputs. Therefore, even when
+@code{inplace!=0} (and this function re-arranges the inputs), the output
+permutation will correspond to original (possibly non-sorted) inputs.
+
+The reason for this is that you rarely want the actual positional columns
+after the match. Usually, you also have other columns (measurements, for
+example magnitudes) for higher-level processing after the match (that
+correspond to the input order before sorting). Once you have the
+permutations, they can be applied to those other columns (see
+@ref{Permutations}) and the higher-level processing can continue.
+@end cartouche
+
+When you read the coordinates from a table using @code{gal_table_read} (see
+@ref{Table input output}), and only ask for the coordinate columns, the
+inputs to this function are the returned @code{gal_data_t *} from two
+different tables.
+
+
+@end deftypefun
+
+@node Statistical operations, Binary datasets, Matching, Gnuastro library
 @subsection Statistical operations (@file{statistics.h})
 
 After reading a dataset into memory from a file or fully simulating it with
@@ -24254,9 +25621,9 @@ $ autoreconf -f
 @cindex Making a distribution package
 @item
 Finally, to make sure everything will be built, installed and checked
-correctly run (after re-configuring, and re-building). To greatly speed up
-the process, use multiple threads (8 in the example below, change it
-appropriately)
+correctly run the following command (after re-configuring, and
+re-building). To greatly speed up the process, use multiple threads (8 in
+the example below, change it appropriately)
 
 @example
 $ make distcheck -j8
@@ -24880,6 +26247,10 @@ image. The central regions of radial profiles are made 
with a configurable
 2D Monte Carlo integration. It can also build the profiles on an
 over-sampled image.
 
+@item Match
+(@file{astmatch}, see @ref{Match}) Given two input catalogs, find the rows
+that match with each other within a given aperture (may be an ellipse).
+
 @item NoiseChisel
 (@file{astnoisechisel}, see @ref{NoiseChisel}) Detect and segment signal in
 noise. It uses a technique to detect very faint and diffuse, irregularly
diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt
index 76dcee7..8411dfa 100644
--- a/doc/release-checklist.txt
+++ b/doc/release-checklist.txt
@@ -21,23 +21,33 @@ all the commits needed for this release have been completed.
  - Check if README includes all the recent updates and important features.
 
 
- - Check if THANKS is up to date and includes recently updated
-   people/institutions.
+ - Check if THANKS and the book's Acknowledgments section have everyone in
+   `doc/announce-acknowledge.txt' in them.
 
 
- - Make sure THANKS corresponds to the acknowledgements in the book.
+ - [STABLE] Correct the links in the webpage (`doc/gnuastro-top.html' and
+   `doc/gnuastro.fr.html').
 
 
- - [STABLE] Update the webpage (`doc/gnuastro-top.html') and correct the
-   links.
+ - Run the following commands to keep the list of people who contributed
+   code and those that must be acknowledged for the announcement (`P.P' is
+   the previous version). Finally, if in a stable release, clean
+   `doc/announce-acknowledge.txt' for the next release. We will use
+   `~/people.txt' in the announcement.
 
+     $ git shortlog gnuastro_vP.P...HEAD --numbered --summary > ~/people.txt
+     $ cat doc/announce-acknowledge.txt >> ~/people.txt
 
- - Commit all these changes and tag the commit:
+     [STABLE]:
+     $ echo "People who's help must be acknowledged in the next release." \
+            > doc/announce-acknowledge.txt
+
+
+ - Commit all these changes:
 
      $ git add -u
      $ git commit
 
-
  - Make sure all the bootstrapping tools are up to date (keep the
    versions in text file to use in the release), then bootstrap and
    rebuild everything:
@@ -100,7 +110,7 @@ all the commits needed for this release have been completed.
        $ cd doc
        $ ./forwebpage /path/to/local/copy/of/webpage
 
-   If any of the files have a `?' infront of them, run these two commands
+   If any of the files have a `?' in front of them, run these two commands
    in the webpage directory:
 
        $ cvs add filename1 filename2 filename3
@@ -131,13 +141,13 @@ all the commits needed for this release have been 
completed.
               --archive-suffix=tar.lz > announcement.txt
 
 
- - After finishing the announcement (adding an intro and NEWS file), run a
-   spell-check on it.
+ - Based on previous announcements, add an intro, the NEWS file and the
+   contents of `~/people.txt' to the announcement.
 
 
- - IMPORTANT: In the announcements, double check the changes in the list of
-   authors and the list in THANKS and make sure everyone's contribution is
-   correctly included.
+ - Run a spell-check on the announcement and remove `~/people.txt'.
+
+     $ rm ~/people.txt
 
 
  - Announce the release on `info-gnuastro@gnu.org', `info-gnu@gnu.org'
@@ -233,34 +243,15 @@ Steps necessary to Package Gnuastro for Debian.
      $ git checkout master
 
 
- - Again, we need to clean everything that already exists here, except
-   `.git' and `debian':
-
-     $ mv debian ../gnuastro-tmp-debian    # We want to keep `debian'.
-     $ mv .git ../gnuastro-tmp-git         # We want to keep `.git'.
-     $ rm -rf ./* ./.*                     # Delete everything.
-     $ mv ../gnuastro-tmp-git .git         # Bring back the `.git' directory.
-     $ mv ../gnuastro-tmp-debian debian    # Bring back the `debian' directory.
-
-
- - Unpack the distribution tarball into the master branch too:
+ - Merge the upstream branch into the master branch to update the Gnuastro
+   files in master also:
 
-     $ tar xf ../gnuastro_$ver.orig.tar.gz --strip-components=1
-
-
- - Update the ChangeLog. But first get all the changes in this version from
-   the NEWS file.
-
-   IMPORTANT: An official release should have `unstable' after the
-   version. But if you just want to making sure Gnuastro builds on all
-   systems, it should be `experimental'.
+     $ git merge upstream
 
-     $ git diff NEWS
-     $ emacs debian/changelog
 
-
- - Check the current Debian policy version at
-   https://www.debian.org/doc/debian-policy/ and update debian/control:
+ - Check the current Debian policy version and update it in
+   `debian/control'. The policy can be found here:
+   https://www.debian.org/doc/debian-policy/
 
      $ emacs debian/control
 
@@ -273,6 +264,18 @@ Steps necessary to Package Gnuastro for Debian.
      - In `debian/control', change all the old sonames to the new value.
 
 
+ - Update `debian/changeLog' with all the Debian-related changes (since
+   merging with the upstream branch). Gnuastro's changes don't need to be
+   mentioned here. If there was no major changes, just say "New upstream
+   version".
+
+   IMPORTANT: An official release should have `unstable' after the
+   version. But if you just want to make sure Gnuastro builds on all
+   systems, it should be `experimental'. If it is experimental, also add
+   this line in `debian/changelog': "Switch to experimental to prepare
+   transition".
+
+
  - Update your version of `pbuilder':
 
      $ sudo pbuilder update
@@ -289,8 +292,8 @@ Steps necessary to Package Gnuastro for Debian.
                /var/cache/pbuilder/result/gnuastro_$ver-1_amd64.changes
 
 
- - Commit the contents of the new release, make sure everything except the
-   `debian' directory is commited (with `git status'):
+ - Commit the contents of the new release (should be just the contents of
+   the `debian' directory).
 
      $ git add --all
      $ git status                         # For a visual check
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9e2bf3c..94319df 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -49,19 +49,18 @@ libgnuastro_la_LIBADD = 
$(top_builddir)/bootstrapped/lib/libgnu.la
 
 
 
+
 # Specify the library .c files
-libgnuastro_la_SOURCES = arithmetic.c arithmetic-binary.c               \
-  arithmetic-onlyint.c binary.c blank.c box.c checkset.c convolve.c     \
-  cosmology.c data.c fits.c git.c interpolate.c list.c options.c        \
-  permutation.c polygon.c qsort.c dimension.c statistics.c table.c      \
+libgnuastro_la_SOURCES = arithmetic.c arithmetic-binary.c                \
+  arithmetic-onlyint.c binary.c blank.c box.c checkset.c convolve.c      \
+  cosmology.c data.c fits.c git.c interpolate.c list.c match.c options.c \
+  permutation.c polygon.c qsort.c dimension.c statistics.c table.c       \
   tableintern.c threads.c tile.c timing.c txt.c type.c wcs.c
 
 
 
 
 
-
-
 # Installed headers, note that we are not blindly including all `.h' files
 # in the $(headersdir) directory. Some of the header files don't need to be
 # installed.
@@ -70,7 +69,7 @@ pkginclude_HEADERS = gnuastro/config.h 
$(headersdir)/arithmetic.h         \
   $(headersdir)/binary.h $(headersdir)/blank.h $(headersdir)/box.h        \
   $(headersdir)/convolve.h $(headersdir)/cosmology.h $(headersdir)/data.h \
   $(headersdir)/dimension.h $(headersdir)/fits.h $(headersdir)/git.h      \
-  $(headersdir)/interpolate.h $(headersdir)/list.h                        \
+  $(headersdir)/interpolate.h $(headersdir)/list.h $(headersdir)/match.h  \
   $(headersdir)/permutation.h $(headersdir)/polygon.h                     \
   $(headersdir)/qsort.h $(headersdir)/statistics.h $(headersdir)/table.h  \
   $(headersdir)/threads.h $(headersdir)/tile.h $(headersdir)/txt.h        \
@@ -150,3 +149,20 @@ gnuastro.pc: Makefile $(srcdir)/gnuastro.pc.in
        '$(srcdir)/$@.in' >> $@.tmp
        chmod a-w $@.tmp
        mv $@.tmp $@
+
+
+
+
+
+# Remove the two local directories we needed during installation from the
+# library search paths of the installed `libgnuastro.la'.
+#
+# Note that this hook is executed after every installation command
+# (including `make uninstall'). So we should only do it if the library
+# actually exists.
+install-exec-hook:
+       if [ -f $(libdir)/libgnuastro.la ]; then                   \
+         $(SED) -e 's/ -L..\/lib//g' -e 's/ -L..\/..\/lib//g'     \
+                $(libdir)/libgnuastro.la > libgnuastro.la_tmp;    \
+         mv libgnuastro.la_tmp $(libdir)/libgnuastro.la;          \
+       fi
diff --git a/lib/box.c b/lib/box.c
index 3dd08dd..6c80d3c 100644
--- a/lib/box.c
+++ b/lib/box.c
@@ -64,22 +64,36 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
    and you will find the distance (about the center of the ellipse
    that encloses the whole ellipse. */
 void
-gal_box_bound_ellipse(double a, double b, double theta_deg, long *width)
+gal_box_bound_ellipse_extent(double a, double b, double theta_deg,
+                             double *extent)
 {
   double t_r=theta_deg*M_PI/180;
-  double max_x, max_y, ct=cos(t_r), st=sin(t_r);
+  double ct=cos(t_r), st=sin(t_r);
   double t_x=atan(b/a*tan(t_r)), t_y=atan(-1.0f*b/a/tan(t_r));
 
   /* Calculate the maxima along each direction. */
-  max_x = a*cos(t_x)*ct    + b*sin(t_x)*st;
-  max_y = -1*a*cos(t_y)*st + b*sin(t_y)*ct;
+  extent[0] = fabs( a*cos(t_x)*ct    + b*sin(t_x)*st );
+  extent[1] = fabs( -1*a*cos(t_y)*st + b*sin(t_y)*ct );
+}
+
+
+
+
+
+void
+gal_box_bound_ellipse(double a, double b, double theta_deg, long *width)
+{
+  double extent[2];
+
+  /* Find the extent of the ellipse. */
+  gal_box_bound_ellipse_extent(a, b, theta_deg, extent);
 
   /* max_x and max_y are calculated from the center of the ellipse. We
      want the final height and width of the box enclosing the
      ellipse. So we have to multiply them by two, then take one from
      them (for the center). */
-  width[0]=2*( (size_t)fabs(max_x)+1 ) + 1;
-  width[1]=2*( (size_t)fabs(max_y)+1 ) + 1;
+  width[0] = 2 * ( (size_t)extent[0] + 1 ) + 1;
+  width[1] = 2 * ( (size_t)extent[1] + 1 ) + 1;
 }
 
 
diff --git a/lib/checkset.c b/lib/checkset.c
index 6a9da0d..1d410b3 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -133,6 +133,28 @@ gal_checkset_allocate_copy_set(char *arg, char **copy, int 
*set)
 
 
 
+/* The dataset may be alone in a file (for example a table in a text file)
+   or it may an extension of a FITS file. In error messages in particular,
+   we need to differentiate between the two. This function will check the
+   filename and if it is FITS, it will return a string with the filename
+   and HDU in parenthesis. If it isn't a FITS file, it will only return the
+   filename. Note that the output needs to be freed, although when used in
+   an error message, you can leave it to the system to free the
+   space. There is no problem. */
+char *
+gal_checkset_dataset_name(char *filename, char *hdu)
+{
+  char *out;
+  if( gal_fits_name_is_fits(filename) )
+    asprintf(&out, "%s (hdu %s)", filename, hdu);
+  else
+    gal_checkset_allocate_copy(filename, &out);
+  return out;
+}
+
+
+
+
 
 
 
diff --git a/lib/data.c b/lib/data.c
index 17f09f4..b7c5c8a 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -282,6 +282,7 @@ gal_data_initialize(gal_data_t *data, void *array, uint8_t 
type,
                     char *unit, char *comment)
 {
   size_t i;
+  size_t data_size_limit = (size_t)(-1);
 
   /* Do the simple copying cases. For the display elements, set them all to
      impossible (negative) values so if not explicitly set by later steps,
@@ -321,11 +322,24 @@ gal_data_initialize(gal_data_t *data, void *array, 
uint8_t type,
       data->size=1;
       for(i=0;i<ndim;++i)
         {
-          /* Do a small sanity check. */
-          if(dsize[i]<=0)
-            error(EXIT_FAILURE, 0, "%s: the size of a dimension cannot be "
-                  "zero or negative. dsize[%zu], but has a value of %zu",
-                  __func__, i, dsize[i]);
+          /* Size along a dimension cannot be negative. */
+          if(dsize[i] == 0)
+            error(EXIT_FAILURE, 0, "%s: dsize[%zu]==0. The size of a "
+                  "dimension cannot be zero", __func__, i);
+
+          /* Check for possible overflow while multiplying. */
+          if (dsize[i] >= data_size_limit / data->size)
+            error(EXIT_FAILURE, 0, "%s: dimension %zu size is too "
+                    "large %zu. Total is out of bounds",
+                    __func__, i, dsize[i]);
+
+          /* Print a warning if the size in this dimension is too
+             large. May happen when the user (mistakenly) writes a negative
+             value in this dimension.. */
+          if (dsize[i] >= data_size_limit / 2)
+            fprintf(stderr, "%s: WARNING: dsize[%zu] value %zu is probably "
+                    "a mistake: it exceeds the limit %zu", __func__, i,
+                    dsize[i], data_size_limit / 2);
 
           /* Write this dimension's size, also correct the total number of
              elements. */
@@ -694,9 +708,9 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
   if(to->type!=GAL_TYPE_STRING)
     error(EXIT_FAILURE, 0, "%s: `to' must have a string type", __func__);
   if(from->block)
-    error(EXIT_FAILURE, 0, "%s: tile inputs not currently supported (`block' "
-          "element must be NULL). Please contact us at %s so we can implement "
-          "this feature", __func__, PACKAGE_BUGREPORT);
+    error(EXIT_FAILURE, 0, "%s: tile inputs not currently supported "
+          "(`block' element must be NULL). Please contact us at %s so we "
+          "can implement this feature", __func__, PACKAGE_BUGREPORT);
 
   /* Do the copying */
   switch(from->type)
@@ -918,9 +932,9 @@ gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t 
newtype)
 
 
 /* Copy a given dataset (`in') into an already allocated dataset `out' (the
-   actual dataset and its `array' element). The meta-data of `in' will be
-   fully copied into `out' also. `out->size' will be used to find the
-   available space in the allocated space.
+   actual dataset and its `array' element). The meta-data of `in' (except
+   for `block') will be fully copied into `out' also. `out->size' will be
+   used to find the available space in the allocated space.
 
    When `in->size != out->size' this function will behave as follows:
 
diff --git a/lib/fits.c b/lib/fits.c
index bd1cfed..0bb4672 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -986,7 +986,7 @@ gal_fits_key_read_from_ptr(fitsfile *fptr, gal_data_t 
*keysll,
         if(readcomment)
           {
             errno=0;
-            tmp->comment=malloc(FLEN_COMMENT * sizeof *tmp->comment);
+            tmp->comment=calloc(FLEN_COMMENT, sizeof *tmp->comment);
             if(tmp->comment==NULL)
               error(EXIT_FAILURE, errno, "%s: %zu bytes for tmp->comment",
                     __func__, FLEN_COMMENT * sizeof *tmp->comment);
@@ -1004,7 +1004,7 @@ gal_fits_key_read_from_ptr(fitsfile *fptr, gal_data_t 
*keysll,
           {
             /* Allocate space for the unit and read it in. */
             errno=0;
-            tmp->unit=malloc(FLEN_COMMENT * sizeof *tmp->unit);
+            tmp->unit=calloc(FLEN_COMMENT, sizeof *tmp->unit);
             if(tmp->unit==NULL)
               error(EXIT_FAILURE, errno, "%s: %zu bytes for tmp->unit",
                     __func__, FLEN_COMMENT * sizeof *tmp->unit);
@@ -1016,7 +1016,7 @@ gal_fits_key_read_from_ptr(fitsfile *fptr, gal_data_t 
*keysll,
         else
           tmp->unit=NULL;
 
-        /* Read the keyword and place its value in the poitner. */
+        /* Read the keyword and place its value in the pointer. */
         fits_read_key(fptr, gal_fits_type_to_datatype(tmp->type),
                       tmp->name, valueptr, tmp->comment, &tmp->status);
 
@@ -1491,9 +1491,9 @@ gal_fits_img_info(fitsfile *fptr, int *type, size_t 
*ndim, size_t **dsize,
     (*dsize)[i]=naxes[*ndim-1-i];
 
 
-  /* Clean up. */
+  /* Clean up. Note that bzero_str, gets freed by `gal_data_free' (which is
+     called by `gal_list_data_free'. */
   gal_list_data_free(keysll);
-  if(bzero_str) free(bzero_str);
 }
 
 
diff --git a/lib/gnuastro-internal/checkset.h b/lib/gnuastro-internal/checkset.h
index b9e6775..51050bb 100644
--- a/lib/gnuastro-internal/checkset.h
+++ b/lib/gnuastro-internal/checkset.h
@@ -79,6 +79,9 @@ gal_checkset_allocate_copy(const char *arg, char **copy);
 void
 gal_checkset_allocate_copy_set(char *arg, char **copy, int *set);
 
+char *
+gal_checkset_dataset_name(char *filename, char *hdu);
+
 
 
 
@@ -97,7 +100,7 @@ gal_checkset_check_file(char *filename);
 int
 gal_checkset_check_file_return(char *filename);
 
-void
+void    /* keep==0 && dontdelete==0: file will be deleted if exists.*/
 gal_checkset_writable_remove(char *filename, int keep, int dontdelete);
 
 int
diff --git a/lib/gnuastro-internal/options.h b/lib/gnuastro-internal/options.h
index b5a4eba..b14c739 100644
--- a/lib/gnuastro-internal/options.h
+++ b/lib/gnuastro-internal/options.h
@@ -279,6 +279,10 @@ gal_options_parse_sizes_reverse(struct argp_option 
*option, char *arg,
                                 char *filename, size_t lineno, void *params);
 
 void *
+gal_options_parse_csv_float64(struct argp_option *option, char *arg,
+                              char *filename, size_t lineno, void *junk);
+
+void *
 gal_options_read_sigma_clip(struct argp_option *option, char *arg,
                             char *filename, size_t lineno, void *junk);
 
diff --git a/lib/gnuastro/box.h b/lib/gnuastro/box.h
index 399d6a4..78d9710 100644
--- a/lib/gnuastro/box.h
+++ b/lib/gnuastro/box.h
@@ -52,6 +52,10 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 */
 
 void
+gal_box_bound_ellipse_extent(double a, double b, double theta_deg,
+                             double *extent);
+
+void
 gal_box_bound_ellipse(double a, double b, double theta_deg, long *width);
 
 void
diff --git a/lib/gnuastro/fits.h b/lib/gnuastro/fits.h
index 95dcb86..86d7343 100644
--- a/lib/gnuastro/fits.h
+++ b/lib/gnuastro/fits.h
@@ -44,6 +44,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <wcslib/wcshdr.h>
 #include <wcslib/wcsfix.h>
 
+#include <gnuastro/list.h>
 #include <gnuastro/data.h>
 #include <gnuastro/table.h>
 
diff --git a/lib/gnuastro/box.h b/lib/gnuastro/match.h
similarity index 62%
copy from lib/gnuastro/box.h
copy to lib/gnuastro/match.h
index 399d6a4..5e05baf 100644
--- a/lib/gnuastro/box.h
+++ b/lib/gnuastro/match.h
@@ -1,11 +1,11 @@
 /*********************************************************************
-Box -- Define bounding and overlapping boxes.
+match -- Functions to match catalogs and WCS.
 This is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
      Mohammad Akhlaghi <akhlaghi@gnu.org>
 Contributing author(s):
-Copyright (C) 2015, Free Software Foundation, Inc.
+Copyright (C) 2017, Free Software Foundation, Inc.
 
 Gnuastro is free software: you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -20,12 +20,12 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef __GAL_BOX_H__
-#define __GAL_BOX_H__
+#ifndef __GAL_MATCH_H__
+#define __GAL_MATCH_H__
 
 /* Include other headers if necessary here. Note that other header files
    must be included before the C++ preparations below */
-
+#include <gnuastro/data.h>
 
 
 /* C++ Preparations */
@@ -42,31 +42,17 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/* Actual header contants (the above were for the Pre-processor). */
-__BEGIN_C_DECLS  /* From C++ preparations */
-
-
-
-/*                        IMPORTANT NOTE:
-         All the axises are based on the FITS standard, NOT C.
-*/
 
-void
-gal_box_bound_ellipse(double a, double b, double theta_deg, long *width);
 
-void
-gal_box_bound_ellipsoid(double *semiaxes, double *euler_deg, long *width);
+gal_data_t *
+gal_match_coordinates(gal_data_t *coord1, gal_data_t *coord2,
+                      double *aperture, int sorted_by_first,
+                      int inplace, size_t minmapsize, size_t *nummatched);
 
-void
-gal_box_border_from_center(double *center, size_t ndim, long *width,
-                           long *fpixel, long *lpixel);
 
-int
-gal_box_overlap(long *naxes, long *fpixel_i, long *lpixel_i,
-                long *fpixel_o, long *lpixel_o, size_t ndim);
 
 
 
 __END_C_DECLS    /* From C++ preparations */
 
-#endif           /* __GAL_BOX_H__ */
+#endif           /* __GAL_TABLE_H__ */
diff --git a/lib/match.c b/lib/match.c
new file mode 100644
index 0000000..17de927
--- /dev/null
+++ b/lib/match.c
@@ -0,0 +1,798 @@
+/*********************************************************************
+match -- Functions to match catalogs and WCS.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <akhlaghi@gnu.org>
+Contributing author(s):
+Copyright (C) 2017, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+
+#include <gsl/gsl_sort.h>
+
+#include <gnuastro/box.h>
+#include <gnuastro/list.h>
+#include <gnuastro/permutation.h>
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/*****************   Coordinate match custom list   *******************/
+/**********************************************************************/
+struct match_coordinate_sfll
+{
+  float f;
+  size_t v;
+  struct match_coordinate_sfll *next;
+};
+
+
+
+
+
+static void
+match_coordinate_add_to_sfll(struct match_coordinate_sfll **list,
+                             size_t value, float fvalue)
+{
+  struct match_coordinate_sfll *newnode;
+
+  errno=0;
+  newnode=malloc(sizeof *newnode);
+  if(newnode==NULL)
+    error(EXIT_FAILURE, errno, "%s: new node couldn't be allocated",
+          __func__);
+
+  newnode->v=value;
+  newnode->f=fvalue;
+  newnode->next=*list;
+  *list=newnode;
+}
+
+
+
+
+
+static void
+match_coordinate_pop_from_sfll(struct match_coordinate_sfll **list,
+                               size_t *value, float *fvalue)
+{
+  struct match_coordinate_sfll *tmp;
+  tmp=*list;
+  *value=tmp->v;
+  *fvalue=tmp->f;
+  *list=tmp->next;
+  free(tmp);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/********************************************************************/
+/*************            Coordinate matching           *************/
+/*************      Sanity checks and preparations      *************/
+/********************************************************************/
+/* Since these checks are repetative, its easier to have a separate
+   function for both inputs. */
+static void
+match_coordinate_sanity_check_columns(gal_data_t *coord, char *info)
+{
+  gal_data_t *tmp;
+
+  for(tmp=coord; tmp!=NULL; tmp=tmp->next)
+    {
+      if(tmp->type!=GAL_TYPE_FLOAT64)
+        error(EXIT_FAILURE, 0, "%s: the input coordinates must have "
+              "`float64' type. At least one node of the %s list has type "
+              "of `%s'", __func__, info, gal_type_name(tmp->type, 1));
+
+      if(tmp->ndim!=1)
+        error(EXIT_FAILURE, 0, "%s: each input coordinate column must have "
+              "a single dimension (be a single column). Atleast one node of "
+              "the %s list has %zu dimensions", __func__, info, tmp->ndim);
+
+      if(tmp->size!=coord->size)
+        error(EXIT_FAILURE, 0, "%s: the nodes of each list of coordinates "
+              "must have the same number of elements. At least one node of "
+              "the %s list has %zu elements while the first has %zu "
+              "elements", __func__, info, tmp->size, coord->size);
+    }
+}
+
+
+
+
+
+/* To keep the main function clean, we'll do the sanity checks here. */
+static void
+match_coordinaes_sanity_check(gal_data_t *coord1, gal_data_t *coord2,
+                              double *aperture)
+{
+  size_t ncoord1=gal_list_data_number(coord1);
+
+  /* Make sure both lists have the same number of datasets. NOTE: they
+     don't need to have the same number of elements. */
+  if( ncoord1!=gal_list_data_number(coord2) )
+    error(EXIT_FAILURE, 0, "%s: the two inputs have different numbers of "
+          "datasets (%zu and %zu respectively)", __func__, ncoord1,
+          gal_list_data_number(coord2));
+
+
+  /* This function currently only works for 2 dimensions. */
+  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");
+  match_coordinate_sanity_check_columns(coord2, "second");
+
+  /* Check the aperture values. */
+  if(aperture[0]<=0)
+    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]);
+}
+
+
+
+
+
+/* To keep things clean, the sorting of each input array will be done in
+   this function. */
+static size_t *
+match_coordinates_prepare_sort(gal_data_t *coords, size_t minmapsize)
+{
+  gal_data_t *tmp;
+  size_t *permutation=gal_data_malloc_array(GAL_TYPE_SIZE_T, coords->size,
+                                            __func__, "permutation");
+
+  /* Get the permutation necessary to sort all the columns (based on the
+     first column). */
+  gsl_sort_index(permutation, coords->array, 1, coords->size);
+
+  /* Sort all the coordinates. */
+  for(tmp=coords; tmp!=NULL; tmp=tmp->next)
+    gal_permutation_apply(tmp, permutation);
+
+  /* Clean up. */
+  return permutation;
+}
+
+
+
+
+
+/* Do the preparations for matching of coordinates. */
+static void
+match_coordinates_prepare(gal_data_t *coord1, gal_data_t *coord2,
+                          int sorted_by_first, int inplace,
+                          gal_data_t **A_out, gal_data_t **B_out,
+                          size_t **A_perm, size_t **B_perm,
+                          size_t minmapsize)
+{
+  gal_data_t *c, *tmp, *A=NULL, *B=NULL;
+
+  /* Sort the datasets if they aren't sorted. If the dataset is already
+     sorted, then `inplace' is irrelevant. */
+  if(!sorted_by_first)
+    {
+      /* Allocating a new list is only necessary when  */
+      if(!inplace)
+        {
+          /* Copy the first list. */
+          for(tmp=coord1; tmp!=NULL; tmp=tmp->next)
+            {
+              c=gal_data_copy(tmp);
+              c->next=NULL;
+              gal_list_data_add(&A, c);
+            }
+
+          /* Copy the second list. */
+          for(tmp=coord2; tmp!=NULL; tmp=tmp->next)
+            {
+              c=gal_data_copy(tmp);
+              c->next=NULL;
+              gal_list_data_add(&B, c);
+            }
+
+          /* Reverse both lists: the copying process reversed the order. */
+          gal_list_data_reverse(&A);
+          gal_list_data_reverse(&B);
+
+          /* Set the output pointers. */
+          *A_out=A;
+          *B_out=B;
+        }
+      else
+        {
+          *A_out=coord1;
+          *B_out=coord2;
+        }
+
+      /* Sort each dataset by the first coordinate. */
+      *A_perm = match_coordinates_prepare_sort(*A_out, minmapsize);
+      *B_perm = match_coordinates_prepare_sort(*B_out, minmapsize);
+    }
+  else
+    {
+      *A_out=coord1;
+      *B_out=coord2;
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/********************************************************************/
+/*************            Coordinate matching           *************/
+/********************************************************************/
+static double
+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 );
+  return sqrt( Xr*Xr + Yr*Yr/ellipse[1]/ellipse[1] );
+}
+
+
+
+
+
+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
+   the first (a). */
+static void
+match_coordinates_second_in_first(gal_data_t *A, gal_data_t *B,
+                                  double *aperture,
+                                  struct match_coordinate_sfll **bina)
+{
+  /* To keep things easy to read, all variables related to catalog 1 start
+     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.*/
+  int iscircle=0;
+  double delta[2];
+  double r, c=NAN, s=NAN, dist[2];
+  size_t ai, bi, blow, prevblow=0;
+  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(ndim==1 || iscircle)
+    dist[0]=dist[1]=aperture[0];
+  else
+    {
+      /* Using the box that encloses the aperture, calculate the distance
+         along each axis. */
+      gal_box_bound_ellipse_extent(aperture[0], aperture[0]*aperture[1],
+                                   aperture[2], dist);
+
+      /* Calculate the sin and cos of the given ellipse if necessary for
+         ease of processing later. */
+      c = cos( aperture[2] * M_PI/180.0 );
+      s = sin( aperture[2] * M_PI/180.0 );
+    }
+
+
+  /* For each row/record of catalog `a', make a list of the nearest records
+     in catalog b within the maximum distance. Note that both catalogs are
+     sorted by their first axis coordinate.*/
+  for(ai=0;ai<ar;++ai)
+    {
+      /* Initialize `bina'. */
+      bina[ai]=NULL;
+
+      /* Find the first (lowest first axis value) row/record in catalog `b'
+        that is within the search radius for this record of catalog
+        `a'. `blow' is the index of the first element to start searching
+        in the catalog `b' for a match to `a[][ai]' (the record in catalog
+        a that is currently being searched). `blow' is only based on the
+        first coordinate, not the second.
+
+         Both catalogs are sorted by their first coordinate, so the `blow'
+        to search for the next record in catalog `a' will be larger or
+        equal to that of the previous catalog `a' record. To account for
+        possibly large distances between the records, we do a search here
+        to change `blow' if necessary before doing further searching.*/
+      for( blow=prevblow; blow<ar && b[0][blow] < a[0][ai]-dist[0]; ++blow)
+       {/* This can be blank, the `for' does all we need :-). */}
+
+
+      /* `blow' is now found for this `ai' and will be used unchanged to
+        the end of the loop. So keep its value to help the search for the
+        next entry in catalog `a'. */
+      prevblow=blow;
+
+
+      /* Go through catalog `b' (starting at `blow') with a first axis
+        value smaller than the maximum acceptable range for `si'. */
+      for( bi=blow; bi<br && b[0][bi] <= a[0][ai] + dist[0]; ++bi )
+       {
+         /* Only consider records with a second axis value in the
+            correct range, note that unlike the first axis, the
+            second axis is no longer sorted. so we have to do both
+            lower and higher limit checks for each item.
+
+            Positions can have an accuracy to a much higher order of
+            magnitude than the search radius. Therefore, it is
+            meaning-less to sort the second axis (after having sorted
+            the first). In other words, very rarely can two first
+            axis coordinates have EXACTLY the same floating point
+            value as each other to easily define an independent
+            sorting in the second axis. */
+         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
+                the following reasons:
+
+                1) Until now we have avoided calculations other than
+                   larger or smaller on double precision floating point
+                   variables for efficiency. So the `bi' is within a
+                   square of side `dist[0]*dist[1]' around `ai' (not
+                   within a fixed radius).
+
+                2) Other objects in the `b' catalog may be closer to `ai'
+                   than this `bi'.
+
+                3) The closest `bi' to `ai' might be closer to another
+                   catalog `a' record.
+
+                To address these problems, we will use a linked list to
+                keep the indexes of the `b's near `ai', along with their
+                distance. We only add the `bi's to this list that are
+                within the acceptable distance.
+
+                 Since we are dealing with much fewer objects at this
+                stage, it is justified to do complex mathematical
+                operations like square root and multiplication. This fixes
+                the first problem.
+
+                The next two problems will be solved with the list after
+                parsing of the whole catalog is complete.*/
+              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);
+           }
+       }
+
+
+      /* If there was no objects within the acceptable distance, then the
+        linked list pointer will be NULL, so go on to the next `ai'. */
+      if(bina[ai]==NULL)
+       continue;
+
+      /* For checking the status of affairs uncomment this block
+      {
+       struct match_coordinate_sfll *tmp;
+       printf("\n\nai: %lu:\n", ai);
+       printf("ax: %f (%f -- %f)\n", a[0][ai], a[0][ai]-dist[0],
+               a[0][ai]+dist[0]);
+       printf("ay: %f (%f -- %f)\n", a[1][ai], a[1][ai]-dist[1],
+               a[1][ai]+dist[1]);
+       for(tmp=bina[ai];tmp!=NULL;tmp=tmp->next)
+         printf("%lu: %f\n", tmp->v, tmp->f);
+      }
+      */
+    }
+}
+
+
+
+
+
+/* In `match_coordinates_second_in_first', we made an array of lists, here
+   we want to reverse that list to fix the second two issues that were
+   discussed there. */
+void
+match_coordinates_rearrange(gal_data_t *A, gal_data_t *B,
+                            struct match_coordinate_sfll **bina)
+{
+  size_t bi;
+  float *fp, *fpf, r, *ainb;
+  size_t ai, ar=A->size, br=B->size;
+
+  /* Allocate the space for `ainb' and initialize it to NaN (since zero is
+     meaningful) in this context (both for indexs and also for
+     floats). This is a two column array that will keep the distance and
+     index of the closest element in catalog `a' for each element in
+     catalog b. */
+  errno=0; ainb=calloc(2*br, sizeof *ainb);
+  if(ainb==NULL)
+    error(EXIT_FAILURE, errno, "%s: %zu bytes for `ainb'", __func__,
+          br*sizeof *ainb);
+  fpf=(fp=ainb)+2*br; do *fp++=NAN; while(fp<fpf);
+
+  /* Go over each object in catalog `a' and re-distribute the near objects,
+     to find which ones in catalog `a' are within the search radius of
+     catalog b in a sorted manner. Note that we only need the `ai' with the
+     minimum distance to `bi', the rest are junk.*/
+  for( ai=0; ai<ar; ++ai )
+    while( bina[ai] )  /* As long as its not NULL.            */
+      {
+       /* Pop out a `bi' and its distance to this `ai' from `bina'. */
+       match_coordinate_pop_from_sfll(&bina[ai], &bi, &r);
+
+       /* If nothing has been put here (the isnan condition below is
+          true), or something exists (the isnan is false, and so it
+          will check the second OR test) with a distance that is
+          larger than this distance then just put this value in. */
+       if( isnan(ainb[bi*2]) || r<ainb[bi*2+1] )
+         {
+           ainb[bi*2  ] = ai;
+           ainb[bi*2+1] = r;
+         }
+      }
+
+  /* For checking the status of affairs uncomment this block
+  {
+    printf("\n\nFilled ainb:\n");
+    for(bi=0;bi<br;++bi)
+      if( !isnan(ainb[bi*2]) )
+       printf("bi: %lu: %.0f, %f\n", bi, ainb[bi*2], ainb[bi*2+1]);
+  }
+  */
+
+  /* Re-fill the bina array, but this time only with the `bi' that is
+     closest to it. Note that bina was fully set to NULL after popping all
+     the elements in the loop above.*/
+  for( bi=0; bi<br; ++bi )
+    if( !isnan(ainb[bi*2]) )
+      {
+       /* Just to keep the same terminology as before and easier
+          reading.*/
+       r=ainb[bi*2+1];
+       ai=(size_t)(ainb[bi*2]);
+
+       /* Check if this is the first time we are associating a `bi' to
+          this `ai'. If so, then just allocate a single element
+          list. Otherwise, see if the distance is closer or not. If so,
+          replace the values in the single node. */
+       if( bina[ai] )
+         {
+           /* If the distance of this record is smaller than the existing
+              entry, then replace the values. */
+           if( r < bina[ai]->f )
+             {
+               bina[ai]->f=r;
+               bina[ai]->v=bi;
+             }
+         }
+       else
+          match_coordinate_add_to_sfll(&bina[ai], bi, r);
+      }
+
+  /* For checking the status of affairs uncomment this block
+  {
+    size_t bi, counter=0;
+    double *a[2]={A->array, A->next->array};
+    double *b[2]={B->array, B->next->array};
+    printf("Rearranged bina:\n");
+    for(ai=0;ai<ar;++ai)
+      if(bina[ai])
+        {
+          ++counter;
+          bi=bina[ai]->v;
+          printf("A_%lu (%.8f, %.8f) <--> B_%lu (%.8f, %.8f):\n\t%f\n",
+                 ai, a[0][ai], a[1][ai], bi, b[0][bi], b[1][bi],
+                 bina[ai]->f);
+        }
+    printf("\n-----------\nMatched: %zu\n", counter);
+  }
+  exit(0);
+  */
+
+  /* Clean up */
+  free(ainb);
+}
+
+
+
+
+
+/* The matching has been done, write the output. */
+static gal_data_t *
+gal_match_coordinates_output(gal_data_t *A, gal_data_t *B, size_t *A_perm,
+                             size_t *B_perm,
+                             struct match_coordinate_sfll **bina,
+                             size_t minmapsize)
+{
+  float r;
+  double *rval;
+  gal_data_t *out;
+  uint8_t *Bmatched;
+  size_t ai, bi, nummatched=0;
+  size_t *aind, *bind, match_i, nomatch_i;
+
+  /* Find how many matches there were in total */
+  for(ai=0;ai<A->size;++ai) if(bina[ai]) ++nummatched;
+
+
+  /* If there aren't any matches, return NULL. */
+  if(nummatched==0) return NULL;
+
+
+  /* Allocate the output list. */
+  out=gal_data_alloc(NULL, GAL_TYPE_SIZE_T, 1, &A->size, NULL, 0,
+                     minmapsize, "CAT1_ROW", "counter",
+                     "Row index in first catalog (counting from 0).");
+  out->next=gal_data_alloc(NULL, GAL_TYPE_SIZE_T, 1, &B->size, NULL, 0,
+                           minmapsize, "CAT2_ROW", "counter",
+                           "Row index in second catalog (counting "
+                           "from 0).");
+  out->next->next=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &nummatched,
+                                 NULL, 0, minmapsize, "MATCH_DIST", NULL,
+                                 "Distance between the match.");
+
+
+  /* Allocate the `Bmatched' array which is a flag for which rows of the
+     second catalog were matched. The columns that had a match will get a
+     value of one while we are parsing them below. */
+  Bmatched=gal_data_calloc_array(GAL_TYPE_UINT8, B->size, __func__,
+                                 "Bmatched");
+
+
+  /* Initialize the indexs. We want the first `nummatched' indexs in both
+     outputs to be the matching rows. The non-matched rows should start to
+     be indexed after the matched ones. So the first non-matched index is
+     at the index `nummatched'. */
+  match_i   = 0;
+  nomatch_i = nummatched;
+
+
+  /* Fill in the output arrays. */
+  aind = out->array;
+  bind = out->next->array;
+  rval = out->next->next->array;
+  for(ai=0;ai<A->size;++ai)
+    {
+      /* A match was found. */
+      if(bina[ai])
+        {
+          /* Note that the permutation keeps the original indexs. */
+          match_coordinate_pop_from_sfll(&bina[ai], &bi, &r);
+          rval[ match_i   ] = r;
+          aind[ match_i   ] = A_perm[ai];
+          bind[ match_i++ ] = B_perm[bi];
+
+          /* Set a `1' for this object in the second catalog. This will
+             later be used to find which rows didn't match to fill in the
+             output.. */
+          Bmatched[ B_perm[bi] ] = 1;
+        }
+      /* No match found. At this stage, we can only fill the indexs of the
+         first input. The second input needs to be matched afterwards.*/
+      else aind[ nomatch_i++ ] = A_perm[ai];
+    }
+
+
+  /* Complete the second input's permutation. */
+  nomatch_i=nummatched;
+  for(bi=0;bi<B->size;++bi)
+    if( Bmatched[bi] == 0 )
+      bind[ nomatch_i++ ] = bi;
+
+
+  /* For a check
+  printf("\nFirst input's permutation:\n");
+  for(ai=0;ai<A->size;++ai)
+    printf("%s%zu\n", ai<nummatched?"  ":"* ", aind[ai]+1);
+  printf("\nSecond input's permutation:\n");
+  for(bi=0;bi<B->size;++bi)
+    printf("%s%zu\n", bi<nummatched?"  ":"* ", bind[bi]+1);
+  exit(0);
+  */
+
+  /* Return the output. */
+  return out;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/********************************************************************/
+/*************            Coordinate matching           *************/
+/********************************************************************/
+/* Match two positions: the two inputs (`coord1' and `coord2') should be
+   lists of coordinates (each is a list of datasets). To speed up the
+   search, this function will sort the inputs by their first column. If
+   both are already sorted, give a non-zero value to
+   `sorted_by_first'. When sorting is necessary and `inplace' is non-zero,
+   the actual inputs will be sorted. Otherwise, an internal copy of the
+   inputs will be made which will be used (sorted) and later
+   freed. Therefore when `inplace==0', the input's won't be changed.
+
+   IMPORTANT NOTE: the output permutations will correspond to the initial
+   inputs. Therefore, even when `inplace' is non-zero (and this function
+   changes the inputs' order), the output permutation will correspond to
+   original inputs.
+
+   The output is a list of `gal_data_t' with the following columns:
+
+       Node 1: First catalog index (counting from zero).
+       Node 2: Second catalog index (counting from zero).
+       Node 3: Distance between the match.                    */
+gal_data_t *
+gal_match_coordinates(gal_data_t *coord1, gal_data_t *coord2,
+                      double *aperture, int sorted_by_first,
+                      int inplace, size_t minmapsize, size_t *nummatched)
+{
+  gal_data_t *A, *B, *out;
+  size_t *A_perm=NULL, *B_perm=NULL;
+  struct match_coordinate_sfll **bina;
+
+  /* Do a small sanity check and make the preparations. After this point,
+     we'll call the two arrays `a' and `b'.*/
+  match_coordinaes_sanity_check(coord1, coord2, aperture);
+  match_coordinates_prepare(coord1, coord2, sorted_by_first, inplace,
+                            &A, &B, &A_perm, &B_perm, minmapsize);
+
+
+  /* Allocate the `bina' array (an array of lists). Let's call the first
+     catalog `a' and the second `b'. This array has `a->size' elements
+     (pointers) and for each, it keeps a list of `b' elements that are
+     nearest to it. */
+  errno=0;
+  bina=calloc(A->size, sizeof *bina);
+  if(bina==NULL)
+    error(EXIT_FAILURE, errno, "%s: %zu bytes for `bina'", __func__,
+          A->size*sizeof *bina);
+
+
+  /* All records in `b' that match each `a' (possibly duplicate). */
+  match_coordinates_second_in_first(A, B, aperture, bina);
+
+
+  /* Two re-arrangings will fix the issue. */
+  match_coordinates_rearrange(A, B, bina);
+
+
+  /* The match is done, write the output. */
+  out=gal_match_coordinates_output(A, B, A_perm, B_perm, bina, minmapsize);
+
+
+  /* Clean up. */
+  free(bina);
+  free(A_perm);
+  free(B_perm);
+  if(A!=coord1)
+    {
+      gal_list_data_free(A);
+      gal_list_data_free(B);
+    }
+
+
+  /* Set `nummatched' and return output. */
+  *nummatched = out ?  out->next->next->size : 0;
+  return out;
+}
diff --git a/lib/options.c b/lib/options.c
index 29e1327..868d362 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.*/
@@ -763,6 +783,65 @@ gal_options_parse_sizes_reverse(struct argp_option 
*option, char *arg,
 
 
 
+/* Parse options with values of a list of numbers. */
+void *
+gal_options_parse_csv_float64(struct argp_option *option, char *arg,
+                              char *filename, size_t lineno, void *junk)
+{
+  size_t i, nc;
+  double *darray;
+  gal_data_t *values;
+  char *str, sstr[GAL_OPTIONS_STATIC_MEM_FOR_VALUES];
+
+  /* We want to print the stored values. */
+  if(lineno==-1)
+    {
+      /* Set the pointer to the values dataset. */
+      values = *(gal_data_t **)(option->value);
+      darray=values->array;
+
+      /* Write each string into the output string */
+      nc=0;
+      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 "
+                  "can address the problem. The number of necessary "
+                  "characters in the statically allocated string has become "
+                  "too close to %d", __func__, PACKAGE_BUGREPORT,
+                  GAL_OPTIONS_STATIC_MEM_FOR_VALUES);
+          nc += sprintf(sstr+nc, "%g,", darray[i]);
+        }
+      sstr[nc-1]='\0';
+
+      /* Copy the string into a dynamically allocated space, because it
+         will be freed later.*/
+      gal_checkset_allocate_copy(sstr, &str);
+      return str;
+    }
+
+  /* We want to read the user's string. */
+  else
+    {
+      /* If the option is already set, just return. */
+      if(option->set) return NULL;
+
+      /* Read the values. */
+      values=gal_options_parse_list_of_numbers(arg, filename, lineno);
+
+      /* Put the values into the option. */
+      *(gal_data_t **)(option->value) = values;
+
+      /* The return value is only for printing mode, so we can return
+         NULL after reading is complete. */
+      return NULL;
+    }
+}
+
+
+
+
+
 /* Two numbers must be provided as an argument. This function will read
    them as the sigma-clipping multiple and parameter and store the two in a
    2-element array. `option->value' must point to an already allocated
diff --git a/lib/permutation.c b/lib/permutation.c
index d5f86ef..1401928 100644
--- a/lib/permutation.c
+++ b/lib/permutation.c
@@ -136,6 +136,7 @@ gal_permutation_apply(gal_data_t *input, size_t 
*permutation)
 
 
 
+
 /* Apply the inverse of given permutation on the input dataset, see
    `gal_permutation_apply_inverse'. */
 void
diff --git a/lib/table.c b/lib/table.c
index 332d6d5..71112e5 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -223,144 +223,153 @@ make_list_of_indexs(gal_list_str_t *cols, gal_data_t 
*allcols,
   gal_list_sizet_t *indexll=NULL;
   char *str, *strcheck, *tailptr, *errorstring;
 
-  for(tmp=cols; tmp!=NULL; tmp=tmp->next)
-    {
-      /* Counter for number of columns matched, and length of name. */
-      nummatch=0;
-      len=strlen(tmp->v);
-
-      /* REGULAR EXPRESSION: When the first and last characters are `/'. */
-      if( tmp->v[0]=='/' && tmp->v[len-1]=='/' )
-        {
-          /* Remove the slashes, note that we don't want to change `tmp->v'
-             (because it should be freed later). So first we set the last
-             character to `\0', then define a new string from the first
-             element. */
-          tmp->v[len-1]='\0';
-          str = tmp->v + 1;
-
-          /* Allocate the regex_t structure: */
-          errno=0;
-          regex=malloc(sizeof *regex);
-          if(regex==NULL)
-            error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for regex",
-                  __func__, sizeof *regex);
-
-          /* First we have to "compile" the string into the regular
-             expression, see the "POSIX Regular Expression Compilation"
-             section of the GNU C Library.
-
-             About the case of the string: the FITS standard says: "It is
-             _strongly recommended_ that every field of the table be
-             assigned a unique, case insensitive name with this keyword..."
-             So the column names can be case-sensitive.
-
-             Here, we don't care about the details of a match, the only
-             important thing is a match, so we are using the REG_NOSUB
-             flag.*/
-          regreturn=0;
-          regreturn=regcomp(regex, str, ( ignorecase
-                                          ? RE_SYNTAX_AWK | REG_ICASE
-                                          : RE_SYNTAX_AWK ) );
-          if(regreturn)
-            table_regexerrorexit(regreturn, regex, str);
-
-
-          /* With the regex structure "compile"d you can go through all the
-             column names. Just note that column names are not mandatory in
-             the FITS standard, so some (or all) columns might not have
-             names, if so `p->tname[i]' will be NULL. */
-          for(i=0;i<numcols;++i)
-            {
-              strcheck=table_set_strcheck(&allcols[i], searchin);
-              if(strcheck && regexec(regex, strcheck, 0, 0, 0)==0)
-                {
-                  ++nummatch;
-                  gal_list_sizet_add(&indexll, i);
-                }
-            }
-
-          /* Free the regex_t structure: */
-          regfree(regex);
-
-          /* Put the `/' back into the input string. This is done because
-             after this function, the calling program might want to inform
-             the user of their exact input string. */
-          tmp->v[len-1]='/';
-        }
-
-
-      /* Not regular expression. */
-      else
-        {
-          tlong=strtol(tmp->v, &tailptr, 0);
-
-          /* INTEGER: If the string is an integer, then tailptr should
-             point to the null character. If it points to anything else, it
-             shows that we are not dealing with an integer (usable as a
-             column number). So floating point values are also not
-             acceptable. Since it is possible for the users to give zero
-             for the column number, we need to read the string as a number
-             first, then check it here. */
-          if(*tailptr=='\0')
-            {
-              /* Make sure the number is larger than zero! */
-              if(tlong<=0)
-                error(EXIT_FAILURE, 0, "%s: column numbers must be positive "
-                      "(not zero or negative). You have asked for column "
-                      "number %ld", __func__, tlong);
-
-              /* Check if the given value is not larger than the number of
-                 columns in the input catalog (note that the user is
-                 counting from 1, not 0!) */
-              if(tlong>numcols)
-                error(EXIT_FAILURE, 0, "%s: has %zu columns, but you "
-                      "have asked for column number %ld",
-                      gal_fits_name_save_as_string(filename, hdu),
-                      numcols, tlong);
-
-              /* Everything seems to be fine, put this column number in the
-                 output column numbers linked list. Note that internally,
-                 the column numbers start from 0, not 1.*/
-              gal_list_sizet_add(&indexll, tlong-1);
-              ++nummatch;
-            }
-
-
-
-          /* EXACT MATCH: */
-          else
-            {
-              /* Go through all the desired column information and add the
-                 column number when there is a match. */
-              for(i=0;i<numcols;++i)
-                {
-                  /* Check if this column actually has any
-                     information. Then do a case-sensitive or insensitive
-                     comparison of the strings. */
-                  strcheck=table_set_strcheck(&allcols[i], searchin);
-                  if(strcheck && ( ignorecase
-                                   ? !strcasecmp(tmp->v, strcheck)
-                                   : !strcmp(tmp->v, strcheck) ) )
-                    {
-                      ++nummatch;
-                      gal_list_sizet_add(&indexll, i);
-                    }
-                }
-            }
-        }
-
-
-      /* If there was no match, then report an error. This can only happen
-         for string matches, not column numbers, for numbers, the checks
-         are done (and program is aborted) before this step. */
-      if(nummatch==0)
-        {
-          asprintf(&errorstring, "`%s' didn't match any of the column %ss.",
-                   tmp->v, gal_tableintern_searchin_as_string(searchin));
-          gal_tableintern_error_col_selection(filename, hdu, errorstring);
-        }
-    }
+  /* Go over the given columns.  */
+  if(cols)
+    for(tmp=cols; tmp!=NULL; tmp=tmp->next)
+      {
+        /* Counter for number of columns matched, and length of name. */
+        nummatch=0;
+        len=strlen(tmp->v);
+
+        /* REGULAR EXPRESSION: the first and last characters are `/'. */
+        if( tmp->v[0]=='/' && tmp->v[len-1]=='/' )
+          {
+            /* Remove the slashes, note that we don't want to change
+               `tmp->v' (because it should be freed later). So first we set
+               the last character to `\0', then define a new string from
+               the first element. */
+            tmp->v[len-1]='\0';
+            str = tmp->v + 1;
+
+            /* Allocate the regex_t structure: */
+            errno=0;
+            regex=malloc(sizeof *regex);
+            if(regex==NULL)
+              error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for regex",
+                    __func__, sizeof *regex);
+
+            /* First we have to "compile" the string into the regular
+               expression, see the "POSIX Regular Expression Compilation"
+               section of the GNU C Library.
+
+               About the case of the string: the FITS standard says: "It is
+               _strongly recommended_ that every field of the table be
+               assigned a unique, case insensitive name with this
+               keyword..."  So the column names can be case-sensitive.
+
+               Here, we don't care about the details of a match, the only
+               important thing is a match, so we are using the REG_NOSUB
+               flag.*/
+            regreturn=0;
+            regreturn=regcomp(regex, str, ( ignorecase
+                                            ? RE_SYNTAX_AWK | REG_ICASE
+                                            : RE_SYNTAX_AWK ) );
+            if(regreturn)
+              table_regexerrorexit(regreturn, regex, str);
+
+
+            /* With the regex structure "compile"d you can go through all
+               the column names. Just note that column names are not
+               mandatory in the FITS standard, so some (or all) columns
+               might not have names, if so `p->tname[i]' will be NULL. */
+            for(i=0;i<numcols;++i)
+              {
+                strcheck=table_set_strcheck(&allcols[i], searchin);
+                if(strcheck && regexec(regex, strcheck, 0, 0, 0)==0)
+                  {
+                    ++nummatch;
+                    gal_list_sizet_add(&indexll, i);
+                  }
+              }
+
+            /* Free the regex_t structure: */
+            regfree(regex);
+
+            /* Put the `/' back into the input string. This is done because
+               after this function, the calling program might want to
+               inform the user of their exact input string. */
+            tmp->v[len-1]='/';
+          }
+
+
+        /* Not regular expression. */
+        else
+          {
+            tlong=strtol(tmp->v, &tailptr, 0);
+
+            /* INTEGER: If the string is an integer, then tailptr should
+               point to the null character. If it points to anything else,
+               it shows that we are not dealing with an integer (usable as
+               a column number). So floating point values are also not
+               acceptable. Since it is possible for the users to give zero
+               for the column number, we need to read the string as a
+               number first, then check it here. */
+            if(*tailptr=='\0')
+              {
+                /* Make sure the number is larger than zero! */
+                if(tlong<=0)
+                  error(EXIT_FAILURE, 0, "%s: column numbers must be "
+                        "positive (not zero or negative). You have asked "
+                        "for column number %ld", __func__, tlong);
+
+                /* Check if the given value is not larger than the number
+                   of columns in the input catalog (note that the user is
+                   counting from 1, not 0!) */
+                if(tlong>numcols)
+                  error(EXIT_FAILURE, 0, "%s: has %zu columns, but you "
+                        "have asked for column number %ld",
+                        gal_fits_name_save_as_string(filename, hdu),
+                        numcols, tlong);
+
+                /* Everything seems to be fine, put this column number in
+                   the output column numbers linked list. Note that
+                   internally, the column numbers start from 0, not 1.*/
+                gal_list_sizet_add(&indexll, tlong-1);
+                ++nummatch;
+              }
+
+
+
+            /* EXACT MATCH: */
+            else
+              {
+                /* Go through all the desired column information and add
+                   the column number when there is a match. */
+                for(i=0;i<numcols;++i)
+                  {
+                    /* Check if this column actually has any
+                       information. Then do a case-sensitive or insensitive
+                       comparison of the strings. */
+                    strcheck=table_set_strcheck(&allcols[i], searchin);
+                    if(strcheck && ( ignorecase
+                                     ? !strcasecmp(tmp->v, strcheck)
+                                     : !strcmp(tmp->v, strcheck) ) )
+                      {
+                        ++nummatch;
+                        gal_list_sizet_add(&indexll, i);
+                      }
+                  }
+              }
+          }
+
+
+        /* If there was no match, then report an error. This can only happen
+           for string matches, not column numbers, for numbers, the checks
+           are done (and program is aborted) before this step. */
+        if(nummatch==0)
+          {
+            asprintf(&errorstring, "`%s' didn't match any of the column %ss.",
+                     tmp->v, gal_tableintern_searchin_as_string(searchin));
+            gal_tableintern_error_col_selection(filename, hdu, errorstring);
+          }
+      }
+
+  /* cols==NULL */
+  else
+    for(i=0;i<numcols;++i)
+      gal_list_sizet_add(&indexll, i);
+
+
 
   /* Reverse the list. */
   gal_list_sizet_reverse(&indexll);
@@ -396,9 +405,6 @@ gal_table_read(char *filename, char *hdu, gal_list_str_t 
*cols,
   size_t i, numcols, numrows;
   gal_data_t *allcols, *out=NULL;
 
-  /* If the column string linked list is empty, no need to continue. */
-  if(cols==NULL) return NULL;
-
   /* First get the information of all the columns. */
   allcols=gal_table_info(filename, hdu, &numcols, &numrows, &tableformat);
 
diff --git a/lib/txt.c b/lib/txt.c
index 5fb6eab..5dd87a3 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -237,7 +237,7 @@ txt_info_from_comment(char *line, gal_data_t **datall, char 
*comm_start)
          are dealing with the string type, we have to pull out the number
          part first. If there is no number for a string type, then ignore
          the line. */
-      if(typestr)
+      if(typestr && *typestr!='\0')
         {
           typestr=txt_trim_space(typestr);
           if( !strncmp(typestr, "str", 3) )
@@ -1245,6 +1245,9 @@ gal_txt_write(gal_data_t *input, gal_list_str_t *comment, 
char *filename)
   size_t i, j, num=0, fmtlen;
   gal_data_t *data, *next2d=NULL;
 
+  /* Make sure input is valid. */
+  if(input==NULL) error(EXIT_FAILURE, 0, "%s: input is NULL", __func__);
+
 
   /* Currently only 1 and 2 dimension datasets are acceptable. */
   if( input->ndim!=1 && input->ndim!=2 )
diff --git a/lib/wcs.c b/lib/wcs.c
index 7c974f1..c3721bf 100644
--- a/lib/wcs.c
+++ b/lib/wcs.c
@@ -433,15 +433,14 @@ gal_wcs_angular_distance_deg(double r1, double d1, double 
r2, double d2)
 
 
 /* Return the pixel scale of the dataset in units of the WCS. */
-/* Return the pixel scale of the dataset in units of the WCS. */
 double *
 gal_wcs_pixel_scale(struct wcsprm *wcs)
 {
   gsl_vector S;
   gsl_matrix A, V;
-  size_t i, j, n=wcs->naxis;
-  double *a, *out, maxrow, minrow;
-  int permute_set, warning_printed;
+  int warning_printed;
+  size_t i, j, maxj, n=wcs->naxis;
+  double jvmax, *a, *out, maxrow, minrow;
   double *v=gal_data_malloc_array(GAL_TYPE_FLOAT64, n*n, __func__, "v");
   size_t *permutation=gal_data_malloc_array(GAL_TYPE_SIZE_T, n, __func__,
                                             "permutation");
@@ -525,30 +524,28 @@ gal_wcs_pixel_scale(struct wcsprm *wcs)
 
   /* The raw pixel scale array produced from the singular value
      decomposition above is ordered based on values, not the input. So when
-     the pixel scales in all the dimensions aren't the same (for example in
-     IFU datacubes), the order of the values in `pixelscale' will not
-     necessarily correspond to the input's dimensions.
+     the pixel scales in all the dimensions aren't the same (the units of
+     the dimensions differ), the order of the values in `pixelscale' will
+     not necessarily correspond to the input's dimensions.
 
      To correct the order, we can use the `V' matrix to find the original
      position of the pixel scale values and then use permutation to
-     re-order it correspondingly. This works when there is only one
-     non-zero element in each row of `V'. */
+     re-order it correspondingly. The column with the largest (absolute)
+     value will be taken as the one to be used for each row. */
   for(i=0;i<n;++i)
     {
-      permute_set=0;
+      /* Find the column with the maximum value. */
+      maxj=-1;
+      jvmax=-FLT_MAX;
       for(j=0;j<n;++j)
-        if(v[i*n+j])
+        if(fabs(v[i*n+j])>jvmax)
           {
-            /* Only works when each row only has one non-zero value. */
-            if(permute_set)
-              error(EXIT_FAILURE, 0, "%s: not able to find the proper "
-                    "permutation for given rotation matrix", __func__);
-            else
-              {
-                permutation[i]=j;
-                permute_set=1;
-              }
+            maxj=j;
+            jvmax=fabs(v[i*n+j]);
           }
+
+      /* Use the column with the maximum value for this dimension. */
+      permutation[i]=maxj;
     }
 
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index da998b1..21a0461 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -51,6 +51,11 @@ endif
 if COND_HASGNULIBTOOL
   MAYBE_HASGNULIBTOOL = "yes"
 endif
+if COND_NO_CPP_QUNUSED_ARGUMENTS_PROBLEM
+  MAYBE_VERSIONCPP    = versioncpp
+  MAYBE_VERSIONCPP_SH = lib/versioncpp.sh
+  versioncpp_SOURCES  = lib/versioncpp.cpp
+endif
 if COND_ARITHMETIC
   MAYBE_ARITHMETIC_TESTS = arithmetic/snimage.sh arithmetic/onlynumbers.sh \
   arithmetic/where.sh arithmetic/or.sh
@@ -117,6 +122,11 @@ if COND_FITS
   fits/delete.sh: fits/write.sh.log
   fits/copyhdu.sh: fits/write.sh.log mkprof/mosaic2.sh.log
 endif
+if COND_MATCH
+  MAYBE_MATCH_TESTS = match/positions.sh
+
+  match/positions.sh: prepconf.sh.log
+endif
 if COND_MKCATALOG
   MAYBE_MKCATALOG_TESTS = mkcatalog/simple.sh mkcatalog/simple-3d.sh \
   mkcatalog/aperturephot.sh
@@ -180,11 +190,9 @@ endif
 
 
 
-
-
-# `config.h' is built by `../lib/Makefile.am' and is only meant for
-# outside users (internally `config.h' has everything. Thus, we need to add
-# it to the include directories of the test programs in this directory.
+# `config.h' is built by `../lib/Makefile.am' and is only meant for outside
+# users (internally `config.h' has everything). Thus, we need to add it to
+# the include directories of the test programs in this directory.
 AM_CPPFLAGS = -I../lib
 
 
@@ -213,8 +221,7 @@ export hasghostscript=$(MAYBE_HASGHOSTSCRIPT);
 # `TESTS'. So they do not need to be specified as any dependency, they will
 # be present when the `.sh' based tests are run.
 LDADD = -lgnuastro
-check_PROGRAMS = versioncpp multithread
-versioncpp_SOURCES = lib/versioncpp.cpp
+check_PROGRAMS = multithread $(MAYBE_VERSIONCPP)
 multithread_SOURCES = lib/multithread.c
 lib/multithread.sh: mkprof/mosaic1.sh.log
 
@@ -223,23 +230,24 @@ lib/multithread.sh: mkprof/mosaic1.sh.log
 
 # Final Tests
 # ===========
-TESTS = prepconf.sh lib/versioncpp.sh lib/multithread.sh                   \
+TESTS = prepconf.sh lib/multithread.sh $(MAYBE_VERSIONCPP_SH)              \
   $(MAYBE_ARITHMETIC_TESTS) $(MAYBE_BUILDPROG_TESTS)                       \
   $(MAYBE_CONVERTT_TESTS) $(MAYBE_CONVOLVE_TESTS) $(MAYBE_COSMICCAL_TESTS) \
-  $(MAYBE_CROP_TESTS) $(MAYBE_FITS_TESTS) $(MAYBE_MKCATALOG_TESTS)         \
-  $(MAYBE_MKNOISE_TESTS) $(MAYBE_MKPROF_TESTS) $(MAYBE_NOISECHISEL_TESTS)  \
-  $(MAYBE_STATISTICS_TESTS) $(MAYBE_SUBTRACTSKY_TESTS)                     \
-  $(MAYBE_TABLE_TESTS) $(MAYBE_WARP_TESTS)
+  $(MAYBE_CROP_TESTS) $(MAYBE_FITS_TESTS) $(MAYBE_MATCH_TESTS)             \
+  $(MAYBE_MKCATALOG_TESTS) $(MAYBE_MKNOISE_TESTS) $(MAYBE_MKPROF_TESTS)    \
+  $(MAYBE_NOISECHISEL_TESTS) $(MAYBE_STATISTICS_TESTS)                     \
+  $(MAYBE_SUBTRACTSKY_TESTS) $(MAYBE_TABLE_TESTS) $(MAYBE_WARP_TESTS)
 
 
 
 
 
 # Files to distribute along with the tests.
-EXTRA_DIST = $(TESTS) during-dev.sh buildprog/simpleio.c crop/cat.txt   \
-  mkprof/3d-cat.txt mkprof/mkprofcat1.txt mkprof/ellipticalmasks.txt    \
-  mkprof/clearcanvas.txt mkprof/mkprofcat2.txt mkprof/mkprofcat3.txt    \
-  mkprof/mkprofcat4.txt mkprof/radeccat.txt table/table.txt
+EXTRA_DIST = $(TESTS) during-dev.sh buildprog/simpleio.c crop/cat.txt     \
+  mkprof/3d-cat.txt match/positions-1.txt match/positions-2.txt           \
+  mkprof/mkprofcat1.txt mkprof/ellipticalmasks.txt mkprof/clearcanvas.txt \
+  mkprof/mkprofcat2.txt mkprof/mkprofcat3.txt mkprof/mkprofcat4.txt       \
+  mkprof/radeccat.txt table/table.txt
 
 
 
diff --git a/tests/match/positions-1.txt b/tests/match/positions-1.txt
new file mode 100644
index 0000000..5964218
--- /dev/null
+++ b/tests/match/positions-1.txt
@@ -0,0 +1,9 @@
+1   1   1
+2   2   2
+3   3   3
+4   4   4
+5   5   5
+6   6   6
+7   7   7
+8   8   8
+9   9   9
diff --git a/tests/match/positions-2.txt b/tests/match/positions-2.txt
new file mode 100644
index 0000000..820dac8
--- /dev/null
+++ b/tests/match/positions-2.txt
@@ -0,0 +1,7 @@
+1   8.20    7.90
+2   20.1    2.80
+3   4.80    5.20
+4   5.01    4.99
+5   0.01    0.02
+6   6.10    6.05
+7   0.99    1.10
diff --git a/tests/match/positions.sh b/tests/match/positions.sh
new file mode 100755
index 0000000..4e69c1b
--- /dev/null
+++ b/tests/match/positions.sh
@@ -0,0 +1,52 @@
+# Match the two input catalogs
+#
+# See the Tests subsection of the manual for a complete explanation
+# (in the Installing gnuastro section).
+#
+# Original author:
+#     Mohammad Akhlaghi <akhlaghi@gnu.org>
+# Contributing author(s):
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.  This file is offered as-is,
+# without any warranty.
+
+
+
+
+
+# Preliminaries
+# =============
+#
+# Set the variables (The executable is in the build tree). Do the
+# basic checks to see if the executable is made or if the defaults
+# file exists (basicchecks.sh is in the source tree).
+prog=match
+execname=../bin/$prog/ast$prog
+cat1=$topsrc/tests/$prog/positions-1.txt
+cat2=$topsrc/tests/$prog/positions-2.txt
+
+
+
+
+
+# Skip?
+# =====
+#
+# If the dependencies of the test don't exist, then skip it. There are two
+# types of dependencies:
+#
+#   - The executable was not made (for example due to a configure option),
+#
+#   - The input data was not made (for example the test that created the
+#     data file failed).
+if [ ! -f $execname ]; then echo "$execname not created."; exit 77; fi
+
+
+
+
+
+# Actual test script
+# ==================
+$execname $cat1 $cat2 --aperture=0.5 --log --output=match-positions.fits
diff --git a/tests/prepconf.sh b/tests/prepconf.sh
index 664cc0f..984b96a 100755
--- a/tests/prepconf.sh
+++ b/tests/prepconf.sh
@@ -72,9 +72,9 @@ rm addedoptions.txt
 # file in each program's source. This is because some programs come with
 # some supplementary configuration files to help the users (like
 # MakeProfiles to operate in 3D).
-for prog in arithmetic convertt convolve cosmiccal crop fits      \
-            mkcatalog mknoise mkprof noisechisel statistics       \
-            table warp
+for prog in arithmetic buildprog convertt convolve cosmiccal crop fits  \
+            match mkcatalog mknoise mkprof noisechisel statistics table \
+            warp
 do
     cp $topsrc/bin/$prog/ast*.conf .gnuastro/
 done



reply via email to

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