gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master eaf19a3 115/125: NoiseChisel's initial detecti


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master eaf19a3 115/125: NoiseChisel's initial detection step implemented
Date: Sun, 23 Apr 2017 22:36:50 -0400 (EDT)

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

    NoiseChisel's initial detection step implemented
    
    Work on enabling NoiseChisel to benefit from the new `gal_data_t' has
    started. To make things easier, all its files have been removed and
    function by function, we are bringing them back in. By the next few commits
    it will be complete. So This commit has deleted a lot of files/lines from
    the code, but most of them will return. Until now, NoiseChisel's initial
    detection step has been implemented, along with several other changes that
    are listed below:
    
     - In the process of modifying the standard files of NoiseChisel, the
       `TEMPLATE' program was also corrected.
    
     - The comment above `AM_CPPFLAGS' of all the program's `Makefile.am' could
       be confusing, so it was corrected. The old comments were from the time
       that Gnulib was linked separately for each program (and separate from
       Gnuastro's own library). But now, Gnulib is statically linked with the
       Gnuastro library, so the programs just need the Gnulib headers.
    
     - The type related definitions and functions were moved to a new
       `lib/tile.c' source file (and an accompanying
       `lib/gnuastro/tile.h'). This allowed the names of all the types to be
       greatly shortened (a `_DATA' was removed from them). Also the function
       names have been similarly cleaned and are more readable. This was
       necessary because the `data.h' header was getting too crowded and the
       necessary names were too common and long.
    
     - To complete the initial detections, the binary-valued array functions
       (like erosion, dilation, or connected component labelling) are now
       implemented as libraries, usable by all the programs and library users.
---
 bin/TEMPLATE/Makefile.am                        |   17 +-
 bin/TEMPLATE/TEMPLATE.c                         |   24 +-
 bin/TEMPLATE/TEMPLATE.h                         |   14 +-
 bin/TEMPLATE/args.h                             |  212 +---
 bin/TEMPLATE/astTEMPLATE.conf                   |    8 +-
 bin/TEMPLATE/authors-cite.h                     |   16 +-
 bin/TEMPLATE/main.c                             |   32 +-
 bin/TEMPLATE/main.h                             |   52 +-
 bin/TEMPLATE/ui.c                               |  316 +++---
 bin/TEMPLATE/ui.h                               |   43 +-
 bin/arithmetic/Makefile.am                      |    7 +-
 bin/arithmetic/arithmetic.c                     |   22 +-
 bin/arithmetic/ui.c                             |    2 +-
 bin/convertt/Makefile.am                        |    7 +-
 bin/convertt/args.h                             |   14 +-
 bin/convertt/convertt.c                         |   12 +-
 bin/convertt/eps.c                              |    4 +-
 bin/convertt/jpeg.c                             |    2 +-
 bin/convertt/ui.c                               |    6 +-
 bin/convolve/Makefile.am                        |    7 +-
 bin/convolve/args.h                             |   10 +-
 bin/convolve/convolve.c                         |    8 +-
 bin/convolve/ui.c                               |    8 +-
 bin/cosmiccal/Makefile.am                       |    7 +-
 bin/cosmiccal/args.h                            |   10 +-
 bin/crop/Makefile.am                            |    7 +-
 bin/crop/args.h                                 |   40 +-
 bin/crop/onecrop.c                              |   30 +-
 bin/crop/ui.c                                   |   20 +-
 bin/crop/wcsmode.c                              |   10 +-
 bin/fits/Makefile.am                            |    7 +-
 bin/fits/args.h                                 |   20 +-
 bin/fits/fits.c                                 |   12 +-
 bin/fits/ui.c                                   |    6 +-
 bin/gnuastro.conf                               |   10 +-
 bin/mkcatalog/Makefile.am                       |    7 +-
 bin/mknoise/Makefile.am                         |    7 +-
 bin/mknoise/args.h                              |    6 +-
 bin/mknoise/mknoise.c                           |   10 +-
 bin/mknoise/ui.c                                |    2 +-
 bin/mkprof/Makefile.am                          |    7 +-
 bin/mkprof/args.h                               |   54 +-
 bin/mkprof/mkprof.c                             |    2 +-
 bin/mkprof/oneprofile.c                         |    2 +-
 bin/mkprof/ui.c                                 |   43 +-
 bin/noisechisel/Makefile.am                     |   16 +-
 bin/noisechisel/args.h                          |  968 ++++++-----------
 bin/noisechisel/astnoisechisel.conf             |   39 +-
 bin/noisechisel/authors-cite.h                  |    2 +-
 bin/noisechisel/binary.c                        |  669 ------------
 bin/noisechisel/binary.h                        |   89 --
 bin/noisechisel/clumps.c                        | 1011 ------------------
 bin/noisechisel/clumps.h                        |   86 --
 bin/noisechisel/detection.c                     |  737 +------------
 bin/noisechisel/detection.h                     |    7 +-
 bin/noisechisel/label.c                         |  421 --------
 bin/noisechisel/label.h                         |   64 --
 bin/noisechisel/main.c                          |   14 +-
 bin/noisechisel/main.h                          |  207 ++--
 bin/noisechisel/noisechisel.c                   |  276 +----
 bin/noisechisel/noisechisel.h                   |    2 +-
 bin/noisechisel/segmentation.c                  |  893 ----------------
 bin/noisechisel/sky.c                           |  273 -----
 bin/noisechisel/sky.h                           |   35 -
 bin/noisechisel/thresh.c                        |  393 -------
 bin/noisechisel/thresh.h                        |   36 -
 bin/noisechisel/threshold.c                     |  330 ++++++
 bin/noisechisel/{segmentation.h => threshold.h} |   11 +-
 bin/noisechisel/ui.c                            | 1299 ++++++++---------------
 bin/noisechisel/ui.h                            |   72 +-
 bin/statistics/Makefile.am                      |    6 +-
 bin/statistics/args.h                           |   38 +-
 bin/statistics/sky.c                            |   20 +-
 bin/statistics/statistics.c                     |   22 +-
 bin/statistics/ui.c                             |   22 +-
 bin/table/Makefile.am                           |    7 +-
 bin/table/args.h                                |    2 +-
 bin/warp/Makefile.am                            |    7 +-
 bin/warp/args.h                                 |   22 +-
 bin/warp/ui.c                                   |   12 +-
 bin/warp/warp.c                                 |    4 +-
 configure.ac                                    |   44 +-
 doc/gnuastro.texi                               |  148 +--
 lib/Makefile.am                                 |   25 +-
 lib/arithmetic-binary.c                         |   80 +-
 lib/arithmetic-onlyint.c                        |  111 +-
 lib/arithmetic.c                                |  362 +++----
 lib/binary.c                                    |  441 ++++++++
 lib/blank.c                                     |  196 ++--
 lib/commonopts.h                                |   34 +-
 lib/convolve.c                                  |   15 +-
 lib/data.c                                      |  703 +++---------
 lib/dimension.c                                 |    2 +-
 lib/fits.c                                      |  244 ++---
 lib/gnuastro/binary.h                           |  100 ++
 lib/gnuastro/data.h                             |   95 +-
 lib/gnuastro/dimension.h                        |    6 +-
 lib/gnuastro/tile.h                             |   70 +-
 lib/gnuastro/type.h                             |  134 +++
 lib/interpolate.c                               |   15 +-
 lib/options.c                                   |   81 +-
 lib/options.h                                   |    3 +-
 lib/permutation.c                               |    4 +-
 lib/statistics.c                                |  266 ++---
 lib/table.c                                     |   38 +-
 lib/tile.c                                      |   38 +-
 lib/timing.c                                    |   16 +-
 lib/timing.h                                    |    4 +-
 lib/txt.c                                       |  101 +-
 lib/type.c                                      |  297 ++++++
 lib/wcs.c                                       |   18 +-
 tmpfs-config-make                               |    7 +-
 112 files changed, 4004 insertions(+), 8968 deletions(-)

diff --git a/bin/TEMPLATE/Makefile.am b/bin/TEMPLATE/Makefile.am
index 54a99a5..d0c16ad 100644
--- a/bin/TEMPLATE/Makefile.am
+++ b/bin/TEMPLATE/Makefile.am
@@ -19,22 +19,23 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astTEMPLATE
+bin_PROGRAMS = astnoisechisel
+
+astnoisechisel_LDADD = -lgnuastro
 
-astTEMPLATE_LDADD = -lgnuastro
+astnoisechisel_SOURCES = main.c ui.c noisechisel.c
 
-astTEMPLATE_SOURCES = main.c ui.c TEMPLATE.c
+EXTRA_DIST = main.h authors-cite.h args.h ui.h noisechisel.h
 
-EXTRA_DIST = main.h authors-cite.h args.h ui.h TEMPLATE.h
 
 
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
-dist_sysconf_DATA = astTEMPLATE.conf
+dist_sysconf_DATA = astnoisechisel.conf
diff --git a/bin/TEMPLATE/TEMPLATE.c b/bin/TEMPLATE/TEMPLATE.c
index ba567e9..60d6340 100644
--- a/bin/TEMPLATE/TEMPLATE.c
+++ b/bin/TEMPLATE/TEMPLATE.c
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
@@ -32,18 +22,10 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
-#include <errno.h>
-#include <error.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
 
-#include <gnuastro/fits.h>
-#include <gnuastro/linkedlist.h>
-
-#include "main.h"
-
-
+#include <main.h>
 
 void
 TEMPLATE(struct TEMPLATEparams *p)
diff --git a/bin/TEMPLATE/TEMPLATE.h b/bin/TEMPLATE/TEMPLATE.h
index 823db66..8349e7a 100644
--- a/bin/TEMPLATE/TEMPLATE.h
+++ b/bin/TEMPLATE/TEMPLATE.h
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
diff --git a/bin/TEMPLATE/args.h b/bin/TEMPLATE/args.h
index 288aaf9..f48d983 100644
--- a/bin/TEMPLATE/args.h
+++ b/bin/TEMPLATE/args.h
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
@@ -33,84 +23,44 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef ARGS_H
 #define ARGS_H
 
-#include <argp.h>
-
-#include <gnuastro/commonargs.h>
-#include <gnuastro/linkedlist.h>
-#include <gnuastro/fixedstringmacros.h>
-
-
-
-
-
-
-
-
-
-
-/**************************************************************/
-/**************        argp.h definitions       ***************/
-/**************************************************************/
-
-
 
 
-/* Definition parameters for the argp: */
-const char *argp_program_version=SPACK_STRING"\n"GAL_STRINGS_COPYRIGHT
-  "\n\nWritten by Mohammad Akhlaghi";
-const char *argp_program_bug_address=PACKAGE_BUGREPORT;
-static char args_doc[] = "ASTRdata";
 
 
 
-
-
-const char doc[] =
-  /* Before the list of options: */
-  GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" description, add a description here. \n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Available letters for short options:
-
-   a b c d e f g i j k l m n p r s t u v w x y z
-   A B C E F G H I J L M O Q R T U W X Y Z
-
-   Number keys used: Nothing!
-
-   Options with keys (second structure element) larger than 500 do not
-   have a short version.
- */
-static struct argp_option options[] =
+/* Array of acceptable options. */
+struct argp_option program_options[] =
   {
     {
-      0, 0, 0, 0,
-      "Input:",
-      1
+      "multivalue",
+      ARGS_OPTION_KEY_MULTIVALUE,
+      "STR",
+      0,
+      "This option can take multiple values.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->multivalue,
+      GAL_TYPE_STRLL,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
 
-    {
-      0, 0, 0, 0,
-      "Output:",
-      2
-    },
-
-
 
     {
-      0, 0, 0, 0,
-      "Operating modes:",
-      -1
+      "onoff",
+      ARGS_OPTION_KEY_ONOFF,
+      0,
+      0,
+      "This option takes no value,.",
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &p->onoff,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -121,100 +71,24 @@ static struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  /* Save the arguments structure: */
-  struct TEMPLATEparams *p = state->input;
-
-  /* Set the pointer to the common parameters for all programs
-     here: */
-  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");
-
-  switch(key)
-    {
-
-
-    /* Input: */
-
-
-    /* Output: */
-
-
-    /* Operating modes: */
-
-
-    /* Read the non-option arguments: */
-    case ARGP_KEY_ARG:
-
-      /* See what type of input value it is and put it in. */
-      if( gal_fits_name_is_fits(arg) )
-        {
-          if(p->up.inputname)
-            argp_error(state, "only one input image should be given");
-          else
-            p->up.inputname=arg;
-        }
-      else
-        argp_error(state, "%s is not a valid file type", arg);
-      break;
-
-
-
-
-
-    /* The command line options and arguments are finished. */
-    case ARGP_KEY_END:
-      if(p->cp.setdirconf==0 && p->cp.setusrconf==0
-         && p->cp.printparams==0)
-        {
-          if(state->arg_num==0)
-            argp_error(state, "no argument given");
-          if(p->up.inputname==NULL)
-            argp_error(state, "no input FITS image(s) provided");
-        }
-      break;
-
+/* Define the child argp structure
+   -------------------------------
 
+   NOTE: these parts can be left untouched.*/
+struct argp
+gal_options_common_child = {gal_commonopts_options,
+                            gal_options_common_argp_parse,
+                            NULL, NULL, NULL, NULL, NULL};
 
+/* Use the child argp structure in list of children (only one for now). */
+struct argp_child
+children[]=
+{
+  {&gal_options_common_child, 0, NULL, 0},
+  {0, 0, 0, 0}
+};
 
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
-
-
-
-
-/* Specify the children parsers: */
-struct argp_child children[]=
-  {
-    {&commonargp, 0, NULL, 0},
-    {0, 0, 0, 0}
-  };
-
-
-
-
-
-/* Basic structure defining the whole argument reading process. */
-static struct argp thisargp = {options, parse_opt, args_doc,
-                               doc, children, NULL, NULL};
-
+/* Set all the necessary argp parameters. */
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
 #endif
diff --git a/bin/TEMPLATE/astTEMPLATE.conf b/bin/TEMPLATE/astTEMPLATE.conf
index c26309b..65e02f5 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.
+# Default parameters (System) for NoiseChisel.
+# Table is part of GNU Astronomy Utitlies.
 #
 # Use the long option name of each paramter followed by
 # a value. The name and value should be separated by
@@ -16,7 +16,3 @@
 # 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.
-
-# Input:
-
-# Output:
\ No newline at end of file
diff --git a/bin/TEMPLATE/authors-cite.h b/bin/TEMPLATE/authors-cite.h
index 33d40d3..5367ec5 100644
--- a/bin/TEMPLATE/authors-cite.h
+++ b/bin/TEMPLATE/authors-cite.h
@@ -1,21 +1,11 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Mohammad Akhlaghi <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
-Copyright (C) 2017, Free Software Foundation, Inc.
+Copyright (C) YYYY, 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
diff --git a/bin/TEMPLATE/main.c b/bin/TEMPLATE/main.c
index ec466f7..fbc6577 100644
--- a/bin/TEMPLATE/main.c
+++ b/bin/TEMPLATE/main.c
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files in this directory.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
@@ -35,29 +25,33 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <gnuastro/timing.h>    /* Includes time.h and sys/time.h */
+#include <timing.h>             /* Includes time.h and sys/time.h */
 
 #include "main.h"
 
-#include "ui.h"                 /* needs main.h.                  */
-#include "TEMPLATE.h"           /* needs main.h.                  */
+#include "ui.h"
+#include "TEMPLATE.h"
+
 
+/* Main function */
 int
 main (int argc, char *argv[])
 {
+  struct timeval t1;
   struct TEMPLATEparams p={{{0},0},0};
 
-  /* Set the starting time. */
+  /* Set they starting time. */
   time(&p.rawtime);
+  gettimeofday(&t1, NULL);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
-  /* Run the program */
+  /* Run MakeProfiles */
   TEMPLATE(&p);
 
   /* Free all non-freed allocations. */
-  freeandreport(&p);
+  ui_free_report(&p, &t1);
 
   /* Return successfully.*/
   return EXIT_SUCCESS;
diff --git a/bin/TEMPLATE/main.h b/bin/TEMPLATE/main.h
index ff49659..cad699e 100644
--- a/bin/TEMPLATE/main.h
+++ b/bin/TEMPLATE/main.h
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
@@ -33,39 +23,33 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef MAIN_H
 #define MAIN_H
 
-#include <gnuastro/fits.h>
-#include <gnuastro/commonparams.h>
+/* Include necessary headers */
+#include <gnuastro/data.h>
 
-/* Progarm name macros: */
-#define SPACK           "astTEMPLATE" /* Subpackage executable name. */
-#define SPACK_NAME      "TEMPLATE"    /* Subpackage full name.       */
-#define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
+#include <options.h>
 
+/* Progarm names.  */
+#define PROGRAM_NAME   "TEMPLATE"    /* Program full name.       */
+#define PROGRAM_EXEC   "astTEMPLATE" /* Program executable name. */
+#define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
 
 
 
-struct uiparams
-{
-  char             *inputname;  /* Name of input file.             */
-};
-
-
-
 
 
+/* Main program parameters structure */
 struct TEMPLATEparams
 {
-  /* Other structures: */
-  struct uiparams          up;  /* User interface parameters.         */
-  struct gal_commonparams  cp;  /* Common parameters.                 */
-
-  /* Input: */
-
-
-  /* Internal: */
-  time_t              rawtime;  /* Starting time of the program.      */
+  /* From command-line */
+  struct gal_options_common_params     cp; /* Common parameters.        */
+  struct gal_linkedlist_strll *multivalue; /* Pointer to multivalue.    */
+  char             *inputname;  /* Input filename.                      */
+  uint8_t              *onoff;  /* How to store on/off options.         */
+
+  /* Output: */
+  time_t              rawtime;  /* Starting time of the program.        */
 };
 
 #endif
diff --git a/bin/TEMPLATE/ui.c b/bin/TEMPLATE/ui.c
index 9f16a59..dc95510 100644
--- a/bin/TEMPLATE/ui.c
+++ b/bin/TEMPLATE/ui.c
@@ -1,19 +1,9 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
 Copyright (C) YYYY, Free Software Foundation, Inc.
 
@@ -32,153 +22,161 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
-#include <math.h>
-#include <stdio.h>
+#include <argp.h>
 #include <errno.h>
 #include <error.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fitsio.h>
-
-#include <nproc.h>               /* From Gnulib.                   */
+#include <stdio.h>
 
 #include <gnuastro/fits.h>
-#include <gnuastro/timing.h>     /* Includes time.h and sys/time.h */
-#include <gnuastro/checkset.h>
-#include <gnuastro/txtarray.h>
-#include <gnuastro/commonargs.h>
-#include <gnuastro/configfiles.h>
-
-#include "main.h"
-
-#include "ui.h"                  /* Needs main.h                   */
-#include "args.h"                /* Needs main.h, includes argp.h. */
+#include <gnuastro/linkedlist.h>
 
+#include <timing.h>
+#include <options.h>
+#include <checkset.h>
+#include <fixedstringmacros.h>
 
-/* Set the file names of the places where the default parameters are
-   put. */
-#define CONFIG_FILE SPACK CONF_POSTFIX
-#define SYSCONFIG_FILE SYSCONFIG_DIR "/" CONFIG_FILE
-#define USERCONFIG_FILEEND USERCONFIG_DIR CONFIG_FILE
-#define CURDIRCONFIG_FILE CURDIRCONFIG_DIR CONFIG_FILE
-
+#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";
 
-/**************************************************************/
-/**************       Options and parameters    ***************/
-/**************************************************************/
-void
-readconfig(char *filename, struct TEMPLATEparams *p)
-{
-  FILE *fp;
-  size_t lineno=0, len=200;
-  char *line, *name, *value;
-  /*struct uiparams *up=&p->up;*/
-  struct gal_commonparams *cp=&p->cp;
-  char key='a';        /* Not used, just a place holder. */
-
-  /* When the file doesn't exist or can't be opened, it is ignored. It
-     might be intentional, so there is no error. If a parameter is
-     missing, it will be reported after all defaults are read. */
-  fp=fopen(filename, "r");
-  if (fp==NULL) return;
-
-
-  /* Allocate some space for `line` with `len` elements so it can
-     easily be freed later on. The value of `len` is arbitarary at
-     this point, during the run, getline will change it along with the
-     pointer to line. */
-  errno=0;
-  line=malloc(len*sizeof *line);
-  if(line==NULL)
-    error(EXIT_FAILURE, errno, "ui.c: %zu bytes in readdefaults",
-          len * sizeof *line);
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" is just a place holder "
+  "used as a minimal set of files and functions necessary for a program in "
+  "Gnuastro. It can be used for learning or as a template to build new "
+  "programs.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
 
-  /* Read the tokens in the file:  */
-  while(getline(&line, &len, fp) != -1)
-    {
-      /* Prepare the "name" and "value" strings, also set lineno. */
-      GAL_CONFIGFILES_START_READING_LINE;
 
 
 
 
-      /* Inputs: */
-      if(strcmp(name, "hdu")==0)
-        gal_checkset_allocate_copy_set(value, &cp->hdu, &cp->hduset);
 
 
 
-      /* Outputs */
 
 
 
 
-      /* Operating modes: */
-      /* Read options common to all programs */
-      GAL_CONFIGFILES_READ_COMMONOPTIONS_FROM_CONF
 
 
-      else
-        error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                      "`%s` not recognized.\n", name);
-    }
 
-  free(line);
-  fclose(fp);
-}
 
 
 
 
 
-void
-printvalues(FILE *fp, struct TEMPLATEparams *p)
+/**************************************************************/
+/*********    Initialize & Parse command-line    **************/
+/**************************************************************/
+static void
+ui_initialize_options(struct TEMPLATEparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
 {
-  /*struct uiparams *up=&p->up;*/
-  struct gal_commonparams *cp=&p->cp;
+  size_t i;
+  struct gal_options_common_params *cp=&p->cp;
 
 
-  /* Print all the options that are set. Separate each group with a
-     commented line explaining the options in that group. */
-  fprintf(fp, "\n# Input image:\n");
-  if(cp->hduset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("hdu", cp->hdu);
+  /* 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;
 
 
-  /* For the operating mode, first put the macro to print the common
-     options, then the (possible options particular to this
-     program). */
-  fprintf(fp, "\n# Operating mode:\n");
-  GAL_CONFIGFILES_PRINT_COMMONOPTIONS;
+  /* 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_SEARCHIN:
+        case GAL_OPTIONS_KEY_MINMAPSIZE:
+        case GAL_OPTIONS_KEY_TABLEFORMAT:
+          cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+          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;
+        }
+    }
 }
 
 
 
 
 
-
-/* Note that numthreads will be used automatically based on the
-   configure time. */
-void
-checkifset(struct TEMPLATEparams *p)
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
 {
-  /*struct uiparams *up=&p->up;*/
-  struct gal_commonparams *cp=&p->cp;
+  struct TEMPLATEparams *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)
+    {
 
-  int intro=0;
-  if(cp->hduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("hdu");
+    /* Read the non-option tokens (arguments): */
+    case ARGP_KEY_ARG:
+      if(p->inputname)
+        argp_error(state, "only one argument (input file) should be given");
+      else
+        p->inputname=arg;
+      break;
 
 
-  GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
+
+  return 0;
 }
 
 
@@ -203,10 +201,34 @@ checkifset(struct TEMPLATEparams *p)
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
-void
-sanitycheck(struct TEMPLATEparams *p)
+/* 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 TEMPLATEparams *p)
+{
+
+}
+
+
+
+
+
+static void
+ui_check_options_and_arguments(struct TEMPLATEparams *p)
 {
+  /* Make sure an input file name was given and if it was a FITS file, that
+     a HDU is also given. */
+  if(p->inputname)
+    {
+      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+        error(EXIT_FAILURE, 0, "no HDU specified. 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");
 }
 
 
@@ -227,11 +249,12 @@ sanitycheck(struct TEMPLATEparams *p)
 
 
 
+
 /**************************************************************/
 /***************       Preparations         *******************/
 /**************************************************************/
 void
-preparearrays(struct TEMPLATEparams *p)
+ui_preparations(struct TEMPLATEparams *p)
 {
 
 }
@@ -257,38 +280,57 @@ preparearrays(struct TEMPLATEparams *p)
 /**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
+
 void
-setparams(int argc, char *argv[], struct TEMPLATEparams *p)
+ui_read_check_inputs_setup(int argc, char *argv[], struct TEMPLATEparams *p)
 {
-  struct gal_commonparams *cp=&p->cp;
+  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 <commonopts.h>
+#include "args.h"
+
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero value for all elements. */
-  cp->spack         = SPACK;
-  cp->verb          = 1;
-  cp->numthreads    = num_processors(NPROC_CURRENT);
-  cp->removedirinfo = 1;
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
-  /* Read the arguments. */
+
+  /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
-  /* Add the user default values and save them if asked. */
-  GAL_CONFIGFILES_CHECK_SET_CONFIG;
 
-  /* Check if all the required parameters are set. */
-  checkifset(p);
+  /* 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 values for each parameter. */
-  if(cp->printparams)
-    GAL_CONFIGFILES_REPORT_PARAMETERS_SET;
+  /* 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);
 
-  /* Do a sanity check. */
-  sanitycheck(p);
 
-  /* Make the array of input images. */
-  preparearrays(p);
+  /* 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);
 }
 
 
@@ -314,15 +356,13 @@ setparams(int argc, char *argv[], struct TEMPLATEparams 
*p)
 /************      Free allocated, report         *************/
 /**************************************************************/
 void
-freeandreport(struct TEMPLATEparams *p)
+ui_free_report(struct TEMPLATEparams *p, struct timeval *t1)
 {
   /* Free the allocated arrays: */
   free(p->cp.hdu);
   free(p->cp.output);
 
-  /* Close the FITS file:
-  if(fits_close_file(p->fptr, &status))
-    gal_fits_io_error(status, NULL);
-  */
-
+  /* Print the final message. */
+  if(!p->cp.quiet)
+    gal_timing_report(t1, PROGRAM_NAME" finished in: ", 0);
 }
diff --git a/bin/TEMPLATE/ui.h b/bin/TEMPLATE/ui.h
index 1e48777..e6dec00 100644
--- a/bin/TEMPLATE/ui.h
+++ b/bin/TEMPLATE/ui.h
@@ -1,21 +1,11 @@
 /*********************************************************************
-TEMPLATE - Source code for a blank utility for easy creation of new
-           utilities, just copy and paste all the files here replacing
-           TEMPLATE with the new utility name (in the source code and
-           file names).
-
-         - Add the utility name to `configure.ac' and `Makefile.am' in the
-           top Gnuastro source directory.
-
-         - Correct these top comments in all the files, don't forget the
-           `astTEMPLATE.conf' and `Makefile.am' files.
-
+TEMPLATE - A minimal set of files and functions to define a program.
 TEMPLATE is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
-     Your name <address@hidden>
+     Your Name <address@hidden>
 Contributing author(s):
-Copyright (C) 2016, Free Software Foundation, Inc.
+Copyright (C) YYYY, 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
@@ -33,10 +23,33 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef UI_H
 #define UI_H
 
+
+
+
+
+/* Available letters for short options:
+
+   a b c d e f g i j k l n p r s t u v w x y z
+   A B C E G H J L Q R W X Y
+*/
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_MULTIVALUE      = 'm',
+  ARGS_OPTION_KEY_ONOFF           = 'O',
+
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+};
+
+
+
+
+
 void
-setparams(int argc, char *argv[], struct TEMPLATEparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct TEMPLATEparams *p);
 
 void
-freeandreport(struct TEMPLATEparams *p);
+ui_free_report(struct TEMPLATEparams *p, struct timeval *t1);
 
 #endif
diff --git a/bin/arithmetic/Makefile.am b/bin/arithmetic/Makefile.am
index 9426846..bd1082d 100644
--- a/bin/arithmetic/Makefile.am
+++ b/bin/arithmetic/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astarithmetic
 
@@ -35,6 +35,7 @@ astarithmetic_SOURCES = main.c ui.c arithmetic.c operands.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h arithmetic.h operands.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astarithmetic.conf
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 5c1e123..182e039 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -75,18 +75,18 @@ set_number_of_operands(struct imgarithparams *p, gal_data_t 
*data,
     /* For the integer types, if they are unsigned, then just pass their
        value, if they are signed, you have to make sure they are zero or
        positive. */
-    case GAL_DATA_TYPE_UINT8:   SET_NUM_OP(uint8_t);     break;
-    case GAL_DATA_TYPE_INT8:    SET_NUM_OP(int8_t);      break;
-    case GAL_DATA_TYPE_UINT16:  SET_NUM_OP(uint16_t);    break;
-    case GAL_DATA_TYPE_INT16:   SET_NUM_OP(int16_t);     break;
-    case GAL_DATA_TYPE_UINT32:  SET_NUM_OP(uint32_t);    break;
-    case GAL_DATA_TYPE_INT32:   SET_NUM_OP(int32_t);     break;
-    case GAL_DATA_TYPE_UINT64:  SET_NUM_OP(uint64_t);    break;
-    case GAL_DATA_TYPE_INT64:   SET_NUM_OP(int64_t);     break;
+    case GAL_TYPE_UINT8:   SET_NUM_OP(uint8_t);     break;
+    case GAL_TYPE_INT8:    SET_NUM_OP(int8_t);      break;
+    case GAL_TYPE_UINT16:  SET_NUM_OP(uint16_t);    break;
+    case GAL_TYPE_INT16:   SET_NUM_OP(int16_t);     break;
+    case GAL_TYPE_UINT32:  SET_NUM_OP(uint32_t);    break;
+    case GAL_TYPE_INT32:   SET_NUM_OP(int32_t);     break;
+    case GAL_TYPE_UINT64:  SET_NUM_OP(uint64_t);    break;
+    case GAL_TYPE_INT64:   SET_NUM_OP(int64_t);     break;
 
     /* Floating point numbers are not acceptable in this context. */
-    case GAL_DATA_TYPE_FLOAT32:
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT64:
       error(EXIT_FAILURE, 0, "the first popped operand to the \"%s\" "
             "operator must be an integer type", token_string);
 
@@ -341,7 +341,7 @@ reversepolish(struct imgarithparams *p)
       /* To simplify the printing process, we will first change it to
          double, then use printf's `%g' to print it, so integers will be
          printed as an integer.  */
-      d2=gal_data_copy_to_new_type(d1, GAL_DATA_TYPE_FLOAT32);
+      d2=gal_data_copy_to_new_type(d1, GAL_TYPE_FLOAT32);
       printf("%g\n", *(double *)d2->array);
       gal_data_free(d2);
     }
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index f2f2b13..66711fa 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -129,7 +129,7 @@ ui_initialize_options(struct imgarithparams *p,
         {
         case GAL_OPTIONS_KEY_HDU:
           cp->coptions[i].value=&p->hdus;
-          cp->coptions[i].type=GAL_DATA_TYPE_STRLL;
+          cp->coptions[i].type=GAL_TYPE_STRLL;
           cp->coptions[i].doc="Nth call, used for HDU of Nth input FITS.";
           break;
 
diff --git a/bin/convertt/Makefile.am b/bin/convertt/Makefile.am
index 504f073..67312a1 100644
--- a/bin/convertt/Makefile.am
+++ b/bin/convertt/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astconvertt
 
@@ -35,6 +35,7 @@ astconvertt_SOURCES = main.c ui.c convertt.c eps.c jpeg.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h convertt.h eps.h jpeg.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astconvertt.conf
diff --git a/bin/convertt/args.h b/bin/convertt/args.h
index 9314fdb..16667fd 100644
--- a/bin/convertt/args.h
+++ b/bin/convertt/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Quality of output JPEG image (1 to 100).",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->quality,
-      GAL_DATA_TYPE_UINT8,
+      GAL_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Width in units of centimeters.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->widthincm,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "EPS/PDF border width in units of 1/72 inch.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->borderwidth,
-      GAL_DATA_TYPE_UINT32,
+      GAL_TYPE_UINT32,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -101,7 +101,7 @@ struct argp_option program_options[] =
       "Lower flux truncation value.",
       ARGS_GROUP_FLUX,
       &p->fluxlowstr,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -114,7 +114,7 @@ struct argp_option program_options[] =
       "Higher flux truncation value.",
       ARGS_GROUP_FLUX,
       &p->fluxhighstr,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -127,7 +127,7 @@ struct argp_option program_options[] =
       "Maximum byte value for all color channels.",
       ARGS_GROUP_FLUX,
       &p->maxbyte,
-      GAL_DATA_TYPE_UINT8,
+      GAL_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -166,7 +166,7 @@ struct argp_option program_options[] =
       "Change pixel values `from_1:to_1,from_2:to_2`.",
       ARGS_GROUP_FLUX,
       &p->changestr,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/convertt/convertt.c b/bin/convertt/convertt.c
index 93a755e..285fe4e 100644
--- a/bin/convertt/convertt.c
+++ b/bin/convertt/convertt.c
@@ -236,11 +236,10 @@ convertt_scale_to_uchar(struct converttparams *p)
       if(channel->status==0)
         {
           /* If the type isn't float, then convert it to float. */
-          if(channel->type!=GAL_DATA_TYPE_FLOAT32)
+          if(channel->type!=GAL_TYPE_FLOAT32)
             {
               /* Change the type to float. */
-              copied=gal_data_copy_to_new_type(channel,
-                                               GAL_DATA_TYPE_FLOAT32);
+              copied=gal_data_copy_to_new_type(channel, GAL_TYPE_FLOAT32);
 
               /* Correct the pointers. */
               copied->next=channel->next;
@@ -277,15 +276,14 @@ convertt_scale_to_uchar(struct converttparams *p)
       if(p->flminbyte)
         {
           /* Convert the fluxlow value to float and put it in min. */
-          copied=gal_data_copy_to_new_type(p->fluxlow, GAL_DATA_TYPE_FLOAT32);
+          copied=gal_data_copy_to_new_type(p->fluxlow, GAL_TYPE_FLOAT32);
           min = *((float *)(copied->array));
           gal_data_free(copied);
         }
       if(p->fhmaxbyte)
         {
           /* Convert the fluxhigh value to float and put it in min. */
-          copied=gal_data_copy_to_new_type(p->fluxhigh,
-                                           GAL_DATA_TYPE_FLOAT32);
+          copied=gal_data_copy_to_new_type(p->fluxhigh, GAL_TYPE_FLOAT32);
           max = *((float *)(copied->array));
           gal_data_free(copied);
         }
@@ -316,7 +314,7 @@ convertt_scale_to_uchar(struct converttparams *p)
             }
 
           /* Change the type to unsigned char. */
-          copied=gal_data_copy_to_new_type(channel, GAL_DATA_TYPE_UINT8);
+          copied=gal_data_copy_to_new_type(channel, GAL_TYPE_UINT8);
 
           /* Correct the pointers. */
           copied->next=channel->next;
diff --git a/bin/convertt/eps.c b/bin/convertt/eps.c
index a3155e8..a4b2f61 100644
--- a/bin/convertt/eps.c
+++ b/bin/convertt/eps.c
@@ -198,7 +198,7 @@ eps_convert_to_bitstream(struct converttparams *p)
   for(channel=p->chll; channel!=NULL; channel=channel->next)
     {
       /* Allocate the array. */
-      bits=gal_data_malloc_array(GAL_DATA_TYPE_UINT8, bytesinimg);
+      bits=gal_data_malloc_array(GAL_TYPE_UINT8, bytesinimg);
 
       /* Put the values in. */
       in=channel->array;
@@ -224,7 +224,7 @@ eps_convert_to_bitstream(struct converttparams *p)
         }
       free(channel->array);
       channel->array=bits;
-      channel->type=GAL_DATA_TYPE_BIT;
+      channel->type=GAL_TYPE_BIT;
     }
 
   /* Return the total number of bytes in the image. */
diff --git a/bin/convertt/jpeg.c b/bin/convertt/jpeg.c
index a79d8f4..e3c1252 100644
--- a/bin/convertt/jpeg.c
+++ b/bin/convertt/jpeg.c
@@ -259,7 +259,7 @@ jpeg_read_to_ll(char *filename, gal_data_t **list, size_t 
minmapsize)
       dsize[0]=s0;
       dsize[1]=s1;
       asprintf(&name, "JPEG_CH_%zu", i+1);
-      gal_data_add_to_ll(list, allcolors[i], GAL_DATA_TYPE_UINT8, ndim,
+      gal_data_add_to_ll(list, allcolors[i], GAL_TYPE_UINT8, ndim,
                          dsize, NULL, 0, minmapsize, name, NULL, NULL);
       free(name);
     }
diff --git a/bin/convertt/ui.c b/bin/convertt/ui.c
index dfff6d0..d6977aa 100644
--- a/bin/convertt/ui.c
+++ b/bin/convertt/ui.c
@@ -135,7 +135,7 @@ ui_initialize_options(struct converttparams *p,
         {
         case GAL_OPTIONS_KEY_HDU:
           cp->coptions[i].value=&p->hdus;
-          cp->coptions[i].type=GAL_DATA_TYPE_STRLL;
+          cp->coptions[i].type=GAL_TYPE_STRLL;
           cp->coptions[i].doc="FITS input HDU, multiple calls possible.";
           break;
 
@@ -460,7 +460,7 @@ ui_make_channels_ll(struct converttparams *p)
       /* Blank: */
       else if(strcmp(name->v, BLANK_CHANNEL_NAME)==0)
         {
-          gal_data_add_to_ll(&p->chll, NULL, GAL_DATA_TYPE_INVALID, 0,
+          gal_data_add_to_ll(&p->chll, NULL, GAL_TYPE_INVALID, 0,
                              &dsize, NULL, 0, p->cp.minmapsize, "blank",
                              NULL, NULL);
           ++p->numch;
@@ -571,7 +571,7 @@ ui_prepare_input_channels(struct converttparams *p)
       if(tmp->ndim==0)
         {
           /* Make the blank data structure. */
-          blank=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, ndim, dsize,
+          blank=gal_data_alloc(NULL, GAL_TYPE_UINT8, ndim, dsize,
                                wcs, 1, p->cp.minmapsize, "blank channel",
                                NULL, NULL);
 
diff --git a/bin/convolve/Makefile.am b/bin/convolve/Makefile.am
index a30872f..846d725 100644
--- a/bin/convolve/Makefile.am
+++ b/bin/convolve/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astconvolve
 
@@ -35,6 +35,7 @@ astconvolve_SOURCES = main.c ui.c convolve.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h convolve.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astconvolve.conf
diff --git a/bin/convolve/args.h b/bin/convolve/args.h
index 821eb06..795bb89 100644
--- a/bin/convolve/args.h
+++ b/bin/convolve/args.h
@@ -40,7 +40,7 @@ struct argp_option program_options[] =
       "File name of kernel for convolution.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->kernelname,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -53,7 +53,7 @@ struct argp_option program_options[] =
       "HDU containing the kernel.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->khdu,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -92,7 +92,7 @@ struct argp_option program_options[] =
       "Deconvolution: min spectrum of sharp img.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->minsharpspec,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -143,7 +143,7 @@ struct argp_option program_options[] =
       "Convolution domain: `spatial', `frequency'.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       &p->domainstr,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -156,7 +156,7 @@ struct argp_option program_options[] =
       "Make 2*INT kernel to create input image.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       &p->makekernel,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index 63333d3..7327598 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -59,7 +59,7 @@ complextoreal(double *c, size_t size, int action, double 
**output)
   double *out, *o, *of;
 
   /* Allocate the space for the real array. */
-  *output=out=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, size);
+  *output=out=gal_data_malloc_array(GAL_TYPE_FLOAT64, size);
 
   /* Fill the real array with the derived value from the complex array. */
   of=(o=out)+size;
@@ -208,7 +208,7 @@ frequency_make_padded_complex(struct convolveparams *p)
 
 
   /* Allocate the space for the padded input image and fill it. */
-  pimg=p->pimg=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*ps0*ps1);
+  pimg=p->pimg=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*ps0*ps1);
   for(i=0;i<ps0;++i)
     {
       op=(o=pimg+i*2*ps1)+2*ps1; /* pimg is complex.            */
@@ -222,7 +222,7 @@ frequency_make_padded_complex(struct convolveparams *p)
 
 
   /* Allocate the space for the padded Kernel and fill it. */
-  pker=p->pker=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*ps0*ps1);
+  pker=p->pker=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*ps0*ps1);
   for(i=0;i<ps0;++i)
     {
       op=(o=pker+i*2*ps1)+2*ps1; /* pker is complex.            */
@@ -640,7 +640,7 @@ convolve_frequency(struct convolveparams *p)
       /* Prepare the data structure for viewing the steps, note that we
          don't need the array that is initially made. */
       dsize[0]=p->ps0; dsize[1]=p->ps1;
-      data=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 2, dsize, NULL, 0,
+      data=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 2, dsize, NULL, 0,
                           p->cp.minmapsize, NULL, NULL, NULL);
       free(data->array);
 
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 866e2c9..052a0ee 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -297,7 +297,7 @@ ui_read_kernel(struct convolveparams *p)
 
   /* Read the image into file. */
   p->kernel = gal_fits_img_read_to_type(p->kernelname, p->khdu,
-                                        GAL_DATA_TYPE_FLOAT32,
+                                        GAL_TYPE_FLOAT32,
                                         p->cp.minmapsize);
 
   /* Convert all the NaN pixels to zero if the kernel contains blank
@@ -343,7 +343,7 @@ ui_preparations(struct convolveparams *p)
 
   /* Read the input image as a float64 array and its WCS info. */
   p->input=gal_fits_img_read_to_type(p->filename, cp->hdu,
-                                     GAL_DATA_TYPE_FLOAT32, cp->minmapsize);
+                                     GAL_TYPE_FLOAT32, cp->minmapsize);
   gal_wcs_read(p->filename, cp->hdu, 0, 0, &p->input->nwcs, &p->input->wcs);
 
 
@@ -391,11 +391,11 @@ ui_preparations(struct convolveparams *p)
          1 and their division (in the frequency domain) would be
          meaningful. */
       sum=gal_statistics_sum(p->input);
-      sum=gal_data_copy_to_new_type_free(sum, GAL_DATA_TYPE_FLOAT32);
+      sum=gal_data_copy_to_new_type_free(sum, GAL_TYPE_FLOAT32);
       p->input = gal_arithmetic(GAL_ARITHMETIC_OP_DIVIDE,
                                 GAL_ARITHMETIC_FLAGS_ALL, p->input, sum);
       sum=gal_statistics_sum(p->kernel);
-      sum=gal_data_copy_to_new_type_free(sum, GAL_DATA_TYPE_FLOAT32);
+      sum=gal_data_copy_to_new_type_free(sum, GAL_TYPE_FLOAT32);
       p->kernel = gal_arithmetic(GAL_ARITHMETIC_OP_DIVIDE,
                                 GAL_ARITHMETIC_FLAGS_ALL, p->kernel, sum);
     }
diff --git a/bin/cosmiccal/Makefile.am b/bin/cosmiccal/Makefile.am
index 97a6124..cbe90fd 100644
--- a/bin/cosmiccal/Makefile.am
+++ b/bin/cosmiccal/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astcosmiccal
 
@@ -35,6 +35,7 @@ astcosmiccal_SOURCES = main.c ui.c cosmiccal.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h cosmiccal.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astcosmiccal.conf
diff --git a/bin/cosmiccal/args.h b/bin/cosmiccal/args.h
index b9ab2b1..c99579f 100644
--- a/bin/cosmiccal/args.h
+++ b/bin/cosmiccal/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Redshift of interest.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->redshift,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Current expansion rate (Hubble constant).",
       GAL_OPTIONS_GROUP_INPUT,
       &p->H0,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "Current cosmological cst. dens. per crit. dens.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->olambda,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -78,7 +78,7 @@ struct argp_option program_options[] =
       "Current matter density per critical density.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->omatter,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -91,7 +91,7 @@ struct argp_option program_options[] =
       "Current radiation density per critical density.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->oradiation,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/crop/Makefile.am b/bin/crop/Makefile.am
index b430e3e..b2d1fac 100644
--- a/bin/crop/Makefile.am
+++ b/bin/crop/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astcrop
 
@@ -35,6 +35,7 @@ astcrop_SOURCES = main.c ui.c crop.c wcsmode.c onecrop.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h crop.h wcsmode.h onecrop.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.ma
 dist_sysconf_DATA = astcrop.conf
diff --git a/bin/crop/args.h b/bin/crop/args.h
index d21a557..24bda0e 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Header keyword number to start reading WCS.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->hstartwcs,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Header keyword number to stop reading WCS.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->hendwcs,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -96,7 +96,7 @@ struct argp_option program_options[] =
       "Suffix (postfix) of cropped images.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->suffix,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -119,7 +119,7 @@ struct argp_option program_options[] =
       "Width (in pixels) of box at center to check.",
       ARGS_GROUP_CENTER_GENERAL,
       &p->checkcenter,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_0_OR_ODD,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -132,7 +132,7 @@ struct argp_option program_options[] =
       "Width (pixels) when crop defined by X,Y.",
       ARGS_GROUP_CENTER_GENERAL,
       &p->iwidthin,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0_ODD,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -145,7 +145,7 @@ struct argp_option program_options[] =
       "Width (arcseconds) for crops defined by RA,Dec.",
       ARGS_GROUP_CENTER_GENERAL,
       &p->wwidth,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -168,7 +168,7 @@ struct argp_option program_options[] =
       "Right ascension of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->ra,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -181,7 +181,7 @@ struct argp_option program_options[] =
       "Declination of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->dec,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -194,7 +194,7 @@ struct argp_option program_options[] =
       "First axis position of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->xc,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -207,7 +207,7 @@ struct argp_option program_options[] =
       "Second axis position of one crop box center.",
       ARGS_GROUP_CENTER_SINGLE,
       &p->yc,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -232,7 +232,7 @@ struct argp_option program_options[] =
       "Input catalog filename.",
       ARGS_GROUP_CENTER_CATALOG,
       &p->catname,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -245,7 +245,7 @@ struct argp_option program_options[] =
       "HDU of catalog, if it is a FITS table.",
       ARGS_GROUP_CENTER_CATALOG,
       &p->cathdu,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -258,7 +258,7 @@ struct argp_option program_options[] =
       "Column no./info of crop filename (no suffix).",
       ARGS_GROUP_CENTER_CATALOG,
       &p->namecol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -271,7 +271,7 @@ struct argp_option program_options[] =
       "Column number/info of Right Ascension (RA).",
       ARGS_GROUP_CENTER_CATALOG,
       &p->racol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -284,7 +284,7 @@ struct argp_option program_options[] =
       "Column number/info of Declination.",
       ARGS_GROUP_CENTER_CATALOG,
       &p->deccol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -297,7 +297,7 @@ struct argp_option program_options[] =
       "Column number/info of X (first FITS axis).",
       ARGS_GROUP_CENTER_CATALOG,
       &p->xcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -310,7 +310,7 @@ struct argp_option program_options[] =
       "Column number/info of Y (second FITS axis).",
       ARGS_GROUP_CENTER_CATALOG,
       &p->ycol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -333,7 +333,7 @@ struct argp_option program_options[] =
       "Image section string specifying crop range.",
       ARGS_GROUP_REGION,
       &p->section,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -346,7 +346,7 @@ struct argp_option program_options[] =
       "Polygon vertices of region to crop, keep inside.",
       ARGS_GROUP_REGION,
       &p->polygon,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -379,7 +379,7 @@ struct argp_option program_options[] =
       "Coordinate mode `img' or `wcs'",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       &p->modestr,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index e5fbea2..a09b52e 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -357,15 +357,15 @@ polygonmask(struct onecropparams *crp, void *array, long 
*fpixel_i,
      polygon keep them if the user has asked for it.*/
   switch(type)
     {
-    case GAL_DATA_TYPE_UINT8:    POLYGON_MASK(uint8_t);  break;
-    case GAL_DATA_TYPE_INT8:     POLYGON_MASK(int8_t);   break;
-    case GAL_DATA_TYPE_UINT16:   POLYGON_MASK(uint16_t); break;
-    case GAL_DATA_TYPE_INT16:    POLYGON_MASK(int16_t);  break;
-    case GAL_DATA_TYPE_UINT32:   POLYGON_MASK(uint32_t); break;
-    case GAL_DATA_TYPE_INT32:    POLYGON_MASK(int32_t);  break;
-    case GAL_DATA_TYPE_INT64:    POLYGON_MASK(int64_t);  break;
-    case GAL_DATA_TYPE_FLOAT32:  POLYGON_MASK(float);    break;
-    case GAL_DATA_TYPE_FLOAT64:  POLYGON_MASK(double);   break;
+    case GAL_TYPE_UINT8:    POLYGON_MASK(uint8_t);  break;
+    case GAL_TYPE_INT8:     POLYGON_MASK(int8_t);   break;
+    case GAL_TYPE_UINT16:   POLYGON_MASK(uint16_t); break;
+    case GAL_TYPE_INT16:    POLYGON_MASK(int16_t);  break;
+    case GAL_TYPE_UINT32:   POLYGON_MASK(uint32_t); break;
+    case GAL_TYPE_INT32:    POLYGON_MASK(int32_t);  break;
+    case GAL_TYPE_INT64:    POLYGON_MASK(int64_t);  break;
+    case GAL_TYPE_FLOAT32:  POLYGON_MASK(float);    break;
+    case GAL_TYPE_FLOAT64:  POLYGON_MASK(double);   break;
     default:
       error(EXIT_FAILURE, 0, "a bug! Please contact us at %s, so we "
             "can fix the problem. For some reason, an unrecognized "
@@ -407,14 +407,14 @@ changezerotonan(void *array, size_t size, int type)
 
   switch(type)
     {
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       ffp=(fp=array)+size;
       do
         if(*fp==0.0f) *fp=NAN;
       while(++fp<ffp);
       break;
 
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       fdp=(dp=array)+size;
       do
         if(*dp==0.0f) *dp=NAN;
@@ -634,7 +634,7 @@ firstcropmakearray(struct onecropparams *crp, long 
*fpixel_i,
   status=0;
 
   /* Write the blank value if necessary. */
-  if( type!=GAL_DATA_TYPE_FLOAT32 && type!=GAL_DATA_TYPE_FLOAT64 )
+  if( type!=GAL_TYPE_FLOAT32 && type!=GAL_TYPE_FLOAT64 )
     if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
                       crp->p->bitnul, "pixels with no data", &status) )
       gal_fits_io_error(status, "adding Blank");
@@ -733,8 +733,8 @@ onecrop(struct onecropparams *crp)
          value should actually be a NaN. Unless the user specificly
          asks for it, make the conversion.*/
       if(p->zeroisnotblank==0
-         && (p->type==GAL_DATA_TYPE_FLOAT32
-             || p->type==GAL_DATA_TYPE_FLOAT64) )
+         && (p->type==GAL_TYPE_FLOAT32
+             || p->type==GAL_TYPE_FLOAT64) )
         changezerotonan(array, cropsize, p->type);
 
 
@@ -766,7 +766,7 @@ onecrop(struct onecropparams *crp)
       sprintf(regionkey, "%sPIX", basename);
       sprintf(region, "%ld:%ld,%ld:%ld", fpixel_i[0], lpixel_i[0],
               fpixel_i[1], lpixel_i[1]);
-      gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_STRING, regionkey,
+      gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_STRING, regionkey,
                                  0, region, 0,
                                  "Range of pixels used for this output.", 0,
                                  NULL);
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 18cb8b6..f988f7a 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -514,7 +514,7 @@ ui_read_cols(struct cropparams *p)
           colname="crop name prefix";
           if(p->namecol)
             {
-              if(tmp->type==GAL_DATA_TYPE_STRING)
+              if(tmp->type==GAL_TYPE_STRING)
                 {
                   p->name=tmp->array;
                   tmp->array=NULL;
@@ -523,7 +523,7 @@ ui_read_cols(struct cropparams *p)
               else
                 {
                   corrtype=gal_data_copy_to_new_type_free(tmp,
-                                            GAL_DATA_TYPE_STRING);
+                                            GAL_TYPE_STRING);
                   p->name=corrtype->array;
                 }
             }
@@ -533,13 +533,13 @@ ui_read_cols(struct cropparams *p)
 
         case 2:
           colname="first axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT64);
           p->c1=corrtype->array;
           break;
 
         case 1:
           colname="second axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT64);
           p->c2=corrtype->array;
           break;
 
@@ -595,18 +595,18 @@ ui_make_log(struct cropparams *p)
   /* If central pixels are filled. */
   asprintf(&comment, "Are the central pixels filled? (1: yes, 0: no, "
            "%u: not checked)", GAL_BLANK_UINT8);
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT8, 1, &p->numout,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_UINT8, 1, &p->numout,
                      NULL, 1, p->cp.minmapsize, "CENTER_FILLED", "bool",
                      comment);
   free(comment);
 
   /* Number of images used. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT16, 1, &p->numout,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_UINT16, 1, &p->numout,
                      NULL, 1, p->cp.minmapsize, "NUM_INPUTS", "count",
                      "Number of input images used to make this crop.");
 
   /* Row number in input catalog. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_STRING, 1, &p->numout,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_STRING, 1, &p->numout,
                      NULL, 1, p->cp.minmapsize, "CROP_NAME", "name",
                      "File name of crop.");
 }
@@ -712,9 +712,9 @@ ui_preparations(struct cropparams *p)
                   "information (press `SPACE' for going down and `q' to "
                   "return to the command-line):\n\n"
                   "    $ info Arithmetic\n",
-                  img->name, gal_data_type_as_string(p->type, 1),
-                  gal_data_type_as_string(firsttype, 1), img->name,
-                  gal_data_type_as_string(p->type, 1));
+                  img->name, gal_type_to_string(p->type, 1),
+                  gal_type_to_string(firsttype, 1), img->name,
+                  gal_type_to_string(p->type, 1));
         }
 
       /* In WCS mode, Check resolution and get the first pixel
diff --git a/bin/crop/wcsmode.c b/bin/crop/wcsmode.c
index 77f3684..ccc8c92 100644
--- a/bin/crop/wcsmode.c
+++ b/bin/crop/wcsmode.c
@@ -303,11 +303,11 @@ fillcrpipolygon(struct onecropparams *crp)
   struct cropparams *p=crp->p;
 
   /* Allocate the necessary arrays. */
-  x=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
-  y=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
-  ra=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
-  dec=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, p->nvertices);
-  crp->ipolygon=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*p->nvertices);
+  x=gal_data_calloc_array(GAL_TYPE_FLOAT64, p->nvertices);
+  y=gal_data_calloc_array(GAL_TYPE_FLOAT64, p->nvertices);
+  ra=gal_data_calloc_array(GAL_TYPE_FLOAT64, p->nvertices);
+  dec=gal_data_calloc_array(GAL_TYPE_FLOAT64, p->nvertices);
+  crp->ipolygon=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*p->nvertices);
 
   /* Fill in the RA and Dec columns. */
   for(i=0;i<p->nvertices;++i)
diff --git a/bin/fits/Makefile.am b/bin/fits/Makefile.am
index 5ef0f60..aab8b7f 100644
--- a/bin/fits/Makefile.am
+++ b/bin/fits/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astfits
 
@@ -35,6 +35,7 @@ astfits_SOURCES = main.c ui.c extension.c fits.c keywords.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h extension.c fits.c keywords.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astfits.conf
diff --git a/bin/fits/args.h b/bin/fits/args.h
index 3f1c3ad..2a57970 100644
--- a/bin/fits/args.h
+++ b/bin/fits/args.h
@@ -45,7 +45,7 @@ struct argp_option program_options[] =
       "Remove extension from input file.",
       ARGS_GROUP_EXTENSION,
       &p->remove,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -58,7 +58,7 @@ struct argp_option program_options[] =
       "Copy extension to output file.",
       ARGS_GROUP_EXTENSION,
       &p->copy,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -71,7 +71,7 @@ struct argp_option program_options[] =
       "Copy extension to output and remove from input.",
       ARGS_GROUP_EXTENSION,
       &p->cut,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -92,7 +92,7 @@ struct argp_option program_options[] =
       "Write the argument string as is into the header.",
       ARGS_GROUP_KEYWORD,
       &p->asis,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -105,7 +105,7 @@ struct argp_option program_options[] =
       "Delete a keyword from the header.",
       ARGS_GROUP_KEYWORD,
       &p->delete,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -118,7 +118,7 @@ struct argp_option program_options[] =
       "Rename keyword, keeping value and comments.",
       ARGS_GROUP_KEYWORD,
       &p->rename,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -131,7 +131,7 @@ struct argp_option program_options[] =
       "Update a keyword value or comments.",
       ARGS_GROUP_KEYWORD,
       &p->update,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -144,7 +144,7 @@ struct argp_option program_options[] =
       "Write a keyword (with value, comments and units).",
       ARGS_GROUP_KEYWORD,
       &p->write,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -157,7 +157,7 @@ struct argp_option program_options[] =
       "Add HISTORY keyword, any length is ok.",
       ARGS_GROUP_KEYWORD,
       &p->history,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -170,7 +170,7 @@ struct argp_option program_options[] =
       "Add COMMENT keyword, any length is ok.",
       ARGS_GROUP_KEYWORD,
       &p->comment,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/fits/fits.c b/bin/fits/fits.c
index 9f141c9..2a70ed6 100644
--- a/bin/fits/fits.c
+++ b/bin/fits/fits.c
@@ -106,16 +106,16 @@ fits_print_extension_info(struct fitsparams *p)
 
   /* Allocate all the columns (in reverse order, since this is a simple
      linked list). */
-  gal_data_add_to_ll(&cols, NULL, GAL_DATA_TYPE_STRING, 1, &numext, NULL, 1,
+  gal_data_add_to_ll(&cols, NULL, GAL_TYPE_STRING, 1, &numext, NULL, 1,
                      p->cp.minmapsize, "HDU_SIZE", "name",
                      "Size of image or table number of rows and columns.");
-  gal_data_add_to_ll(&cols, NULL, GAL_DATA_TYPE_STRING, 1, &numext, NULL, 1,
+  gal_data_add_to_ll(&cols, NULL, GAL_TYPE_STRING, 1, &numext, NULL, 1,
                      p->cp.minmapsize, "HDU_TYPE", "name",
                      "Image data type or `table' format (ASCII or binary).");
-  gal_data_add_to_ll(&cols, NULL, GAL_DATA_TYPE_STRING, 1, &numext, NULL, 1,
+  gal_data_add_to_ll(&cols, NULL, GAL_TYPE_STRING, 1, &numext, NULL, 1,
                      p->cp.minmapsize, "EXTNAME", "name",
                      "Extension name of this HDU (EXTNAME in FITS).");
-  gal_data_add_to_ll(&cols, NULL, GAL_DATA_TYPE_UINT16, 1, &numext, NULL, 1,
+  gal_data_add_to_ll(&cols, NULL, GAL_TYPE_UINT16, 1, &numext, NULL, 1,
                      p->cp.minmapsize, "HDU_INDEX", "count",
                      "Index (starting from zero) of each HDU (extension).");
 
@@ -138,14 +138,14 @@ fits_print_extension_info(struct fitsparams *p)
         {
         case IMAGE_HDU:
           gal_fits_img_info(fptr, &type, &ndim, &dsize);
-          tstr=gal_data_type_as_string(type , 1);
+          tstr=gal_type_to_string(type , 1);
           break;
 
         case ASCII_TBL:
         case BINARY_TBL:
           ndim=2;
           tstr = hdutype==ASCII_TBL ? "table_ascii" : "table_binary";
-          dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, 2);
+          dsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, 2);
           gal_fits_tab_size(fptr, dsize+1, dsize);
           break;
 
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index 65420d4..f83c8f9 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -389,7 +389,7 @@ ui_fill_fits_headerll(struct gal_linkedlist_stll *input,
       if(*tailptr=='\0' && errno==0)
         {
           vfree=1;
-          type=GAL_DATA_TYPE_INT64;
+          type=GAL_TYPE_INT64;
           errno=0;
           fvalue=lp=malloc(sizeof *lp);
           if(lp==NULL)
@@ -404,7 +404,7 @@ ui_fill_fits_headerll(struct gal_linkedlist_stll *input,
           if(*tailptr=='\0' && errno==0)
             {
               vfree=1;
-              type=GAL_DATA_TYPE_FLOAT64;
+              type=GAL_TYPE_FLOAT64;
               errno=0;
               fvalue=dp=malloc(sizeof *dp);
               if(dp==NULL)
@@ -413,7 +413,7 @@ ui_fill_fits_headerll(struct gal_linkedlist_stll *input,
               *dp=d;
             }
           else
-            { fvalue=value; type=GAL_DATA_TYPE_STRING; vfree=0; }
+            { fvalue=value; type=GAL_TYPE_STRING; vfree=0; }
         }
 
 
diff --git a/bin/gnuastro.conf b/bin/gnuastro.conf
index d64529f..472879f 100644
--- a/bin/gnuastro.conf
+++ b/bin/gnuastro.conf
@@ -18,9 +18,9 @@
 # without any warranty.
 
 # Input:
- hdu            1
- ignorecase     1
- searchin       name
+ hdu              1
+ ignorecase       1
+ searchin         name
 
 # Tessellation
  tilesize         50,50
@@ -31,7 +31,7 @@
  interponlyblank  0
 
 # Output:
- tableformat    fits-binary
+ tableformat      fits-binary
 
 # Operating mode
- minmapsize     1000000000
\ No newline at end of file
+ minmapsize       1000000000
\ No newline at end of file
diff --git a/bin/mkcatalog/Makefile.am b/bin/mkcatalog/Makefile.am
index f9b6f71..595f262 100644
--- a/bin/mkcatalog/Makefile.am
+++ b/bin/mkcatalog/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astmkcatalog
 
@@ -36,6 +36,7 @@ EXTRA_DIST = main.h authors-cite.h args.h ui.h mkcatalog.h 
columns.h    \
   upperlimit.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astmkcatalog.conf
diff --git a/bin/mknoise/Makefile.am b/bin/mknoise/Makefile.am
index 93ef35a..da95ebc 100644
--- a/bin/mknoise/Makefile.am
+++ b/bin/mknoise/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astmknoise
 
@@ -36,6 +36,7 @@ EXTRA_DIST = main.h authors-cite.h args.h ui.h mknoise.h
 
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astmknoise.conf
diff --git a/bin/mknoise/args.h b/bin/mknoise/args.h
index 65c0626..4eccecf 100644
--- a/bin/mknoise/args.h
+++ b/bin/mknoise/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Standard deviation addition constant.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->stdadd,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Fixed background magnitude for whole input.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->background_mag,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "Zeropoint magnitude of input.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->zeropoint,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/mknoise/mknoise.c b/bin/mknoise/mknoise.c
index 7de46f0..873cca6 100644
--- a/bin/mknoise/mknoise.c
+++ b/bin/mknoise/mknoise.c
@@ -63,25 +63,25 @@ convertsaveoutput(struct mknoiseparams *p)
   /* Add the proper information to the header of the output: */
   gal_fits_key_write_filename("INF", p->inputname, &headers);
   strcpy(keyname1, "BCKGRND");
-  gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_FLOAT64, keyname1, 0,
+  gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_FLOAT64, keyname1, 0,
                              &p->background_mag, 0, "Background "
                              "value (in magnitude) for noise.",
                              0, NULL);
   strcpy(keyname2, "BZRPNT");
-  gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_FLOAT64, keyname2, 0,
+  gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_FLOAT64, keyname2, 0,
                              &p->zeropoint, 0,
                              "Zeropoint magnitude of image.", 0, NULL);
   strcpy(keyname3, "STDADD");
-  gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_FLOAT64, keyname3, 0,
+  gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_FLOAT64, keyname3, 0,
                              &p->stdadd, 0,
                              "Instrumental noise in units of flux.", 0, NULL);
   strcpy(keyname4, "RNGTYPE");
-  gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_STRING, keyname4, 0,
+  gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_STRING, keyname4, 0,
                              p->rng_type, 0,
                              "Random number generator (by GSL) type.",
                              0, NULL);
   strcpy(keyname5, "RNGSEED");
-  gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_INT64, keyname5, 0,
+  gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_INT64, keyname5, 0,
                              &p->rng_seed,
                              0, "Random number generator (by GSL) seed.",
                              0, NULL);
diff --git a/bin/mknoise/ui.c b/bin/mknoise/ui.c
index dc6a99e..c9b283a 100644
--- a/bin/mknoise/ui.c
+++ b/bin/mknoise/ui.c
@@ -267,7 +267,7 @@ ui_preparations(struct mknoiseparams *p)
 {
   /* Read the input image as a double type */
   p->input=gal_fits_img_read_to_type(p->inputname, p->cp.hdu,
-                                     GAL_DATA_TYPE_FLOAT64, p->cp.minmapsize);
+                                     GAL_TYPE_FLOAT64, p->cp.minmapsize);
 
   /* Read the WSC structure. */
   gal_wcs_read(p->inputname, p->cp.hdu, 0, 0, &p->input->nwcs,
diff --git a/bin/mkprof/Makefile.am b/bin/mkprof/Makefile.am
index e78db15..81453aa 100644
--- a/bin/mkprof/Makefile.am
+++ b/bin/mkprof/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astmkprof
 
@@ -36,6 +36,7 @@ EXTRA_DIST = main.h authors-cite.h args.h ui.h mkprof.h 
oneprofile.h    \
   profiles.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astmkprof.conf
diff --git a/bin/mkprof/args.h b/bin/mkprof/args.h
index 25e9cc6..963762a 100644
--- a/bin/mkprof/args.h
+++ b/bin/mkprof/args.h
@@ -38,7 +38,7 @@ struct argp_option program_options[] =
       "A background image to make the profiles on.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->backname,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -51,7 +51,7 @@ struct argp_option program_options[] =
       "HDU of background image.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->backhdu,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -82,7 +82,7 @@ struct argp_option program_options[] =
       "Number of pixels along first FITS axis.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->naxes[0],
-      GAL_DATA_TYPE_UINT64,
+      GAL_TYPE_UINT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -95,7 +95,7 @@ struct argp_option program_options[] =
       "Number of pixels along second FITS axis.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->naxes[1],
-      GAL_DATA_TYPE_INT64,
+      GAL_TYPE_INT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -108,7 +108,7 @@ struct argp_option program_options[] =
       "Scale of oversampling (>0 and odd).",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->oversample,
-      GAL_DATA_TYPE_UINT8,
+      GAL_TYPE_UINT8,
       GAL_OPTIONS_RANGE_GT_0_ODD,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -170,7 +170,7 @@ struct argp_option program_options[] =
       "No. of random points in Monte Carlo integration.",
       ARGS_GROUP_PROFILES,
       &p->numrandom,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -183,7 +183,7 @@ struct argp_option program_options[] =
       "Tolerance to switch to less accurate method.",
       ARGS_GROUP_PROFILES,
       &p->tolerance,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -209,7 +209,7 @@ struct argp_option program_options[] =
       "Shift profile centers and enlarge image, X axis.",
       ARGS_GROUP_PROFILES,
       &p->shift[0],
-      GAL_DATA_TYPE_INT64,
+      GAL_TYPE_INT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -222,7 +222,7 @@ struct argp_option program_options[] =
       "Shift profile centers and enlarge image, Y axis.",
       ARGS_GROUP_PROFILES,
       &p->shift[1],
-      GAL_DATA_TYPE_INT64,
+      GAL_TYPE_INT64,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -248,7 +248,7 @@ struct argp_option program_options[] =
       "Magnitude zero point.",
       ARGS_GROUP_PROFILES,
       &p->zeropoint,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -261,7 +261,7 @@ struct argp_option program_options[] =
       "Width of circumference (inward) profiles",
       ARGS_GROUP_PROFILES,
       &p->circumwidth,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -323,7 +323,7 @@ struct argp_option program_options[] =
       "Center along first FITS axis (horizontal).",
       ARGS_GROUP_CATALOG,
       &p->xcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -336,7 +336,7 @@ struct argp_option program_options[] =
       "Center along second FITS axis (vertical).",
       ARGS_GROUP_CATALOG,
       &p->ycol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -349,7 +349,7 @@ struct argp_option program_options[] =
       "Center right ascension.",
       ARGS_GROUP_CATALOG,
       &p->racol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -362,7 +362,7 @@ struct argp_option program_options[] =
       "Center declination.",
       ARGS_GROUP_CATALOG,
       &p->deccol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -376,7 +376,7 @@ struct argp_option program_options[] =
       "flat (5), circumference (6).",
       ARGS_GROUP_CATALOG,
       &p->fcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -389,7 +389,7 @@ struct argp_option program_options[] =
       "Effective radius or FWHM in pixels.",
       ARGS_GROUP_CATALOG,
       &p->rcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -402,7 +402,7 @@ struct argp_option program_options[] =
       "Sersic index or Moffat beta.",
       ARGS_GROUP_CATALOG,
       &p->ncol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -415,7 +415,7 @@ struct argp_option program_options[] =
       "Position angle.",
       ARGS_GROUP_CATALOG,
       &p->pcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -428,7 +428,7 @@ struct argp_option program_options[] =
       "Axis ratio.",
       ARGS_GROUP_CATALOG,
       &p->qcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -441,7 +441,7 @@ struct argp_option program_options[] =
       "Magnitude.",
       ARGS_GROUP_CATALOG,
       &p->mcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -454,7 +454,7 @@ struct argp_option program_options[] =
       "Truncation in units of --rcol, unless --tunitinp.",
       ARGS_GROUP_CATALOG,
       &p->tcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -490,7 +490,7 @@ struct argp_option program_options[] =
       "Pixel coordinate of reference point (axis 1).",
       ARGS_GROUP_WCS,
       &p->crpix[0],
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -503,7 +503,7 @@ struct argp_option program_options[] =
       "Pixel coordinate of reference point (axis 2).",
       ARGS_GROUP_WCS,
       &p->crpix[1],
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -516,7 +516,7 @@ struct argp_option program_options[] =
       "Right ascension at reference point (degrees).",
       ARGS_GROUP_WCS,
       &p->crval[0],
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -529,7 +529,7 @@ struct argp_option program_options[] =
       "Declination at reference point (degrees).",
       ARGS_GROUP_WCS,
       &p->crval[1],
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -542,7 +542,7 @@ struct argp_option program_options[] =
       "Resolution of image (arcseconds/pixel).",
       ARGS_GROUP_WCS,
       &p->resolution,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index df0584d..fe4e961 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -133,7 +133,7 @@ saveindividual(struct mkonthread *mkp)
   gal_checkset_check_remove_file(filename, 0, p->cp.dontdelete);
 
   /* Put the array into a data structure */
-  data=gal_data_alloc(ibq->img, GAL_DATA_TYPE_FLOAT32, 2, dsize, NULL, 0,
+  data=gal_data_alloc(ibq->img, GAL_TYPE_FLOAT32, 2, dsize, NULL, 0,
                       p->cp.minmapsize, "MockImage", "Brightness", NULL);
 
   /* Write the array to file (a separately built PSF doesn't need WCS
diff --git a/bin/mkprof/oneprofile.c b/bin/mkprof/oneprofile.c
index e0e3fdd..aa2101c 100644
--- a/bin/mkprof/oneprofile.c
+++ b/bin/mkprof/oneprofile.c
@@ -255,7 +255,7 @@ makepixbypix(struct mkonthread *mkp)
     { img[p]=1; return; }
 
   /* Allocate the byt array to not repeat completed pixels. */
-  byt = gal_data_malloc_array(GAL_DATA_TYPE_UINT8, is0*is1);
+  byt = gal_data_malloc_array(GAL_TYPE_UINT8, is0*is1);
 
   /* Start the queue: */
   byt[p]=1;
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 376bbdb..57bc439 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -127,7 +127,7 @@ ui_initialize_options(struct mkprofparams *p,
   cp->coptions           = gal_commonopts_options;
 
   /* Default program parameters. */
-  p->type=GAL_DATA_TYPE_FLOAT32;
+  p->type=GAL_TYPE_FLOAT32;
 
 
   /* Modify the common options for this program. */
@@ -235,7 +235,7 @@ static void
 ui_read_check_only_options(struct mkprofparams *p)
 {
   /* When a no-merged image is to be created, type is necessary. */
-  if( p->type==GAL_DATA_TYPE_INVALID && p->nomerged==0)
+  if( p->type==GAL_TYPE_INVALID && p->nomerged==0)
     error(EXIT_FAILURE, 0, "an output type `--type' is necessary when a "
           "merged image is to be built.");
 
@@ -337,7 +337,7 @@ ui_read_profile_function(struct mkprofparams *p, char 
**strarr)
 {
   size_t i;
 
-  p->f=gal_data_malloc_array(GAL_DATA_TYPE_INT32, p->num);
+  p->f=gal_data_malloc_array(GAL_TYPE_INT32, p->num);
   for(i=0;i<p->num;++i)
     {
       if( !strcmp("sersic", strarr[i]) )
@@ -418,18 +418,18 @@ ui_read_cols(struct mkprofparams *p)
         {
         case 9:
           colname="first axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT64);
           p->x=corrtype->array;
           break;
 
         case 8:
           colname="second axis position";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT64);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT64);
           p->y=corrtype->array;
           break;
 
         case 7:
-          if(tmp->type==GAL_DATA_TYPE_STRING)
+          if(tmp->type==GAL_TYPE_STRING)
             {
               ui_read_profile_function(p, tmp->array);
               gal_data_free(tmp);
@@ -439,8 +439,7 @@ ui_read_cols(struct mkprofparams *p)
             {
               /* Read the user's profile codes. */
               colname="profile function code (`fcol')";
-              corrtype=gal_data_copy_to_new_type_free(tmp,
-                                                      GAL_DATA_TYPE_INT32);
+              corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_INT32);
               p->f=corrtype->array;
 
               /* Check if they are in the correct range. */
@@ -461,38 +460,38 @@ ui_read_cols(struct mkprofparams *p)
 
         case 6:
           colname="radius (`rcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->r=corrtype->array;
           break;
 
         case 5:
           colname="index (`ncol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->n=corrtype->array;
           break;
 
         case 4:
           colname="position angle (`pcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->p=corrtype->array;
           break;
 
         case 3:
           colname="axis ratio (`qcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->q=corrtype->array;
           break;
 
         case 2:
           colname="magnitude (`mcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->m=corrtype->array;
           checkblank=0;          /* Magnitude can be NaN: to mask regions. */
           break;
 
         case 1:
           colname="truncation (`tcol')";
-          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+          corrtype=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
           p->t=corrtype->array;
           break;
 
@@ -604,13 +603,13 @@ ui_prepare_canvas(struct mkprofparams *p)
          no merged image is desired, we just need the WCS information of
          the background image. */
       if(p->nomerged)
-        p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 0, dsize, NULL,
+        p->out=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 0, dsize, NULL,
                               1, p->cp.minmapsize, NULL, NULL, NULL);
       else
         {
           /* Read the image. */
           p->out=gal_fits_img_read_to_type(p->backname, p->backhdu,
-                                           GAL_DATA_TYPE_FLOAT32,
+                                           GAL_TYPE_FLOAT32,
                                            p->cp.minmapsize);
           p->naxes[0]=p->out->dsize[1];
           p->naxes[1]=p->out->dsize[0];
@@ -705,7 +704,7 @@ ui_prepare_canvas(struct mkprofparams *p)
         }
 
       /* Make the output structure. */
-      p->out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, ndim, dsize, NULL, 1,
+      p->out=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, ndim, dsize, NULL, 1,
                             p->cp.minmapsize, NULL, NULL, NULL);
     }
 
@@ -807,30 +806,30 @@ ui_make_log(struct mkprofparams *p)
   if(p->cp.log==0) return;
 
   /* Individual created. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT8, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_UINT8, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "INDIV_CREATED", "bool",
                      "If an individual image was made (1) or not (0).");
 
   /* Fraction of monte-carlo. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT32, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_FLOAT32, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "FRAC_MONTECARLO", "frac",
                      "Fraction of brightness in Monte-carlo integrated "
                      "pixels.");
 
   /* Number of monte-carlo. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT64, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_UINT64, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "NUM_MONTECARLO", "count",
                      "Number of Monte Carlo integrated pixels.");
 
   /* Magnitude of profile overlap. */
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_FLOAT32, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_FLOAT32, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "MAG_OVERLAP", "mag",
                      "Magnitude of profile's overlap with merged image.");
 
   /* Row number in input catalog. */
   name=gal_fits_name_save_as_string(p->catname, p->cp.hdu);
   asprintf(&comment, "Row number of profile in %s.", name);
-  gal_data_add_to_ll(&p->log, NULL, GAL_DATA_TYPE_UINT64, 1, &p->num, NULL,
+  gal_data_add_to_ll(&p->log, NULL, GAL_TYPE_UINT64, 1, &p->num, NULL,
                      1, p->cp.minmapsize, "INPUT_ROW_NO", "count", comment);
   free(comment);
   free(name);
diff --git a/bin/noisechisel/Makefile.am b/bin/noisechisel/Makefile.am
index 855c804..bb9793c 100644
--- a/bin/noisechisel/Makefile.am
+++ b/bin/noisechisel/Makefile.am
@@ -3,7 +3,7 @@
 ## Original author:
 ##     Mohammad Akhlaghi <address@hidden>
 ## Contributing author(s):
-## Copyright (C) 2015, Free Software Foundation, Inc.
+## Copyright (C) 2016, 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
@@ -19,22 +19,22 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astnoisechisel
 
 astnoisechisel_LDADD = -lgnuastro
 
-astnoisechisel_SOURCES = main.c ui.c noisechisel.c thresh.c binary.c    \
-  label.c detection.c sky.c segmentation.c clumps.c
+astnoisechisel_SOURCES = main.c ui.c detection.c noisechisel.c threshold.c
+
+EXTRA_DIST = main.h authors-cite.h args.h ui.h detection.h noisechisel.h \
+  threshold.h
 
-EXTRA_DIST = main.h authors-cite.h args.h ui.h noisechisel.h thresh.h   \
-  binary.h label.h detection.h sky.h segmentation.h clumps.h
 
 
 ## The configuration file (distribute and install).
diff --git a/bin/noisechisel/args.h b/bin/noisechisel/args.h
index fe59b0d..9d236b0 100644
--- a/bin/noisechisel/args.h
+++ b/bin/noisechisel/args.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -23,510 +23,497 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef ARGS_H
 #define ARGS_H
 
-#include <argp.h>
 
-#include <commonargs.h>
-#include <fixedstringmacros.h>
 
 
 
 
-
-
-
-
-
-
-/**************************************************************/
-/**************        argp.h definitions       ***************/
-/**************************************************************/
-
-
-
-
-/* Definition parameters for the argp: */
-const char *argp_program_version=SPACK_STRING"\n"GAL_STRINGS_COPYRIGHT
-  "\n\nWritten by Mohammad Akhlaghi";
-const char *argp_program_bug_address=PACKAGE_BUGREPORT;
-static char args_doc[] = "ASTRdata";
-
-
-
-
-
-const char doc[] =
-  /* Before the list of options: */
-  GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" Detects and segments signal that is deeply burried in noise. "
-  "It employs a noise-based detection and segmentation method enabling it "
-  "to be very resilient to the rich diversity of shapes in astronomical "
-  "targets.\n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Available letters for short options:
-
-   f j w x z
-   A J K W X Y Z
-
-   Used numbers: <=518 (except 515)
-
-   Options with keys (second structure element) larger than 500 do not
-   have a short version.
- */
-static struct argp_option options[] =
+/* Options in argp_option format. */
+struct argp_option program_options[] =
   {
-    {
-      0, 0, 0, 0,
-      "Input:",
-      1
-    },
-    {
-      "mask",
-      'M',
-      "STR",
-      0,
-      "Mask image file name.",
-      1
-    },
-    {
-      "mhdu",
-      'H',
-      "STR",
-      0,
-      "Mask image header name.",
-      1
-    },
+
+    /* Input options. */
     {
       "kernel",
-      'k',
+      ARGS_OPTION_KEY_KERNEL,
       "STR",
       0,
-      "Kernel image file name.",
-      1
+      "Filename of Kernel to convolve with input",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->kernelname,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "khdu",
-      'U',
+      ARGS_OPTION_KEY_KHDU,
       "STR",
       0,
-      "Kernel image header name.",
-      1
+      "HDU containing Kernel image.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->khdu,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "skysubtracted",
-      'E',
+      ARGS_OPTION_KEY_SKYSUBTRACTED,
       0,
       0,
-      "Input is already sky subtracted.",
-      1
+      "Input is Sky subtracted (for error estimation).",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->skysubtracted,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "minbfrac",
-      'B',
+      ARGS_OPTION_KEY_MINBFRAC,
       "FLT",
       0,
-      "Minimum fraction of undetected area in a mesh.",
-      1
+      "Min. fraction of undetected area in a tile.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->minbfrac,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "minnumfalse",
-      'F',
+      ARGS_OPTION_KEY_MINNUMFALSE,
       "INT",
       0,
-      "Min No. of false detection/segments for quantile.",
-      1
+      "Minimum number for S/N estimation.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->minnumfalse,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
+
+    /* Output options. */
     {
-      0, 0, 0, 0,
-      "Output:",
-      2
-    },
-    {
-      "detectonly",
-      517,
+      "onlydetect",
+      ARGS_OPTION_KEY_ONLYDETECT,
       0,
       0,
-      "Do not do any segmentation.",
-      2
+      "Don't do any segmentation.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->onlydetect,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "grownclumps",
-      'C',
+      ARGS_OPTION_KEY_GROWNCLUMPS,
       0,
       0,
-      "Save grownclumps instead of original clumps.",
-      2
+      "Save grown clumps instead of original.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->grownclumps,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
+
+    /* Detection. */
     {
       0, 0, 0, 0,
-      "Mesh grid:",
-      3
-    },
-    {
-      "smeshsize",
-      's',
-      "INT",
-      0,
-      "Size of each small mesh (tile) in the grid.",
-      3
-    },
-    {
-      "lmeshsize",
-      'l',
-      "INT",
-      0,
-      "Size of each large mesh (tile) in the grid.",
-      3
-    },
-    {
-      "nch1",
-      'a',
-      "INT",
-      0,
-      "Number of channels along first FITS axis.",
-      3
-    },
-    {
-      "nch2",
-      'b',
-      "INT",
-      0,
-      "Number of channels along second FITS axis.",
-      3
-    },
-    {
-      "lastmeshfrac",
-      'L',
-      "INT",
-      0,
-      "Fraction of last mesh area to add new.",
-      3
+      "Detection:",
+      ARGS_GROUP_DETECTION
     },
     {
       "mirrordist",
-      'd',
+      ARGS_OPTION_KEY_MIRRORDIST,
       "FLT",
       0,
-      "Distance beyond mirror point. Multiple of std.",
-      3
+      "Max. distance (error multip.) to find mode.",
+      ARGS_GROUP_DETECTION,
+      &p->mirrordist,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "minmodeq",
-      'Q',
+      "modmedqdiff",
+      ARGS_OPTION_KEY_MODMEDQDIFF,
       "FLT",
       0,
-      "Minimum acceptable quantile for the mode.",
-      3
-    },
-    {
-      "interponlyblank",
-      511,
-      0,
-      0,
-      "Only interpolate over the blank pixels.",
-      3
+      "Max. mode and median quant diff. per tile.",
+      ARGS_GROUP_DETECTION,
+      &p->modmedqdiff,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "numnearest",
-      'n',
-      "INT",
+      "qthresh",
+      ARGS_OPTION_KEY_QTHRESH,
+      "FLT",
       0,
-      "Number of nearest neighbors to interpolate.",
-      3
+      "Quantile threshold on convolved image.",
+      ARGS_GROUP_DETECTION,
+      &p->qthresh,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GE_0_LT_1,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "smoothwidth",
-      'T',
+      ARGS_OPTION_KEY_SMOOTHWIDTH,
       "INT",
       0,
-      "Width of smoothing kernel (odd number).",
-      3
-    },
-    {
-      "checkmesh",
-      500,
-      0,
-      0,
-      "Store mesh IDs in `_mesh.fits' file.",
-      3
-    },
-    {
-      "fullinterpolation",
-      501,
-      0,
-      0,
-      "Ignore channels in interpolation.",
-      3
-    },
-    {
-      "fullsmooth",
-      502,
-      0,
-      0,
-      "Ignore channels in smoothing.",
-      3
-    },
-    {
-      "fullconvolution",
-      504,
-      0,
-      0,
-      "Ignore channels in convolution.",
-      3
+      "Flat kernel width to smooth interpolated.",
+      ARGS_GROUP_DETECTION,
+      &p->smoothwidth,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_0_OR_ODD,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "meshbasedcheck",
-      516,
+      "checkqthresh",
+      ARGS_OPTION_KEY_CHECKQTHRESH,
       0,
       0,
-      "Each mesh in one pixel in mesh check images.",
-      3
-    },
-
-
-
-    {
-      0, 0, 0, 0,
-      "Detection:",
-      4
-    },
-    {
-      "qthresh",
-      't',
-      "FLT",
-      0,
-      "Quantile threshold on convolved image.",
-      4
+      "Save quantile threshold estimation in file.",
+      ARGS_GROUP_DETECTION,
+      &p->checkqthresh,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "erode",
-      'e',
+      ARGS_OPTION_KEY_ERODE,
       "INT",
       0,
-      "Num. erosions to apply after thresholding.",
-      4
+      "Number of erosions after thresholding.",
+      ARGS_GROUP_DETECTION,
+      &p->erode,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "erodengb",
-      506,
-      "4or8",
+      ARGS_OPTION_KEY_ERODENGB,
+      "INT",
       0,
-      "Use 4 or 8 connectivity in erosion.",
-      4
+      "4 or 8 connectivity in erosion.",
+      ARGS_GROUP_DETECTION,
+      &p->erodengb,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "noerodequant",
-      503,
+      ARGS_OPTION_KEY_NOERODEQUANT,
       "FLT",
       0,
       "Quantile for no erosion.",
-      4
+      ARGS_GROUP_DETECTION,
+      &p->noerodequant,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "opening",
-      'p',
+      ARGS_OPTION_KEY_OPENING,
       "INT",
       0,
-      "Depth of opening to apply after erosion.",
-      4
+      "Depth of opening after erosion.",
+      ARGS_GROUP_DETECTION,
+      &p->opening,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "openingngb",
-      507,
-      "4or8",
+      ARGS_OPTION_KEY_OPENINGNGB,
+      "INT",
       0,
-      "Use 4 or 8 connectivity in opening.",
-      4
+      "4 or 8 connectivity in opening.",
+      ARGS_GROUP_DETECTION,
+      &p->openingngb,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "sigclipmultip",
-      'u',
-      "FLT",
+      "sigmaclip",
+      ARGS_OPTION_KEY_SIGMACLIP,
+      "FLT,FLT",
       0,
-      "Multiple of standard deviation in sigma-clipping.",
-      4
+      "Multiple of sigma and, tolerance or number.",
+      ARGS_GROUP_DETECTION,
+      &p->sigmaclip,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+      gal_options_read_sigma_clip
     },
     {
-      "sigcliptolerance",
-      'r',
-      "FLT",
+      "checkdetsky",
+      ARGS_OPTION_KEY_CHECKDETSKY,
+      0,
       0,
-      "Difference in STD tolerance to halt iteration.",
-      4
+      "Save Sky value estimation for pseudo-dets.",
+      ARGS_GROUP_DETECTION,
+      &p->checkdetsky,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "dthresh",
-      'R',
+      ARGS_OPTION_KEY_DTHRESH,
       "FLT",
       0,
-      "Threshold (STD multiple) for false detections.",
-      4
+      "Sigma threshold for Pseudo-detections.",
+      ARGS_GROUP_DETECTION,
+      &p->dthresh,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "detsnminarea",
-      'i',
+      ARGS_OPTION_KEY_DETSNMINAREA,
       "INT",
       0,
-      "Minimum area to calculate S/N in detection.",
-      4
+      "Min. pseudo-detection area for S/N dist.",
+      ARGS_GROUP_DETECTION,
+      &p->detsnminarea,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "detsnhistnbins",
-      510,
-      "INT",
+      "checkdetsn",
+      ARGS_OPTION_KEY_CHECKDETSN,
       0,
-      "Det. S/N histogram bins, suffix `_detsn.txt'.",
-      4
+      0,
+      "Save pseudo-detection S/N values to a file.",
+      ARGS_GROUP_DETECTION,
+      &p->checkdetsn,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "detquant",
-      'c',
+      ARGS_OPTION_KEY_DETQUANT,
       "FLT",
       0,
-      "False detections S/N quantile to find the true.",
-      4
+      "Quantile in pseudo-det. to define true.",
+      ARGS_GROUP_DETECTION,
+      &p->checkdetsn,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GT_0_LT_1,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "dilate",
-      'I',
+      ARGS_OPTION_KEY_DILATE,
       "INT",
       0,
       "Number of times to dilate true detections.",
-      4
-    },
-
-    {
-      "checkthreshold",
-      505,
-      0,
-      0,
-      "Threshold value on each mesh `_thresh.fits'.",
-      4
+      ARGS_GROUP_DETECTION,
+      &p->dilate,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "checkdetection",
-      508,
+      ARGS_OPTION_KEY_CHECKDETECTION,
       0,
       0,
-      "False detection steps in file `_det.fits'.",
-      4
-    },
-    {
-      "checkdetectionsky",
-      509,
-      0,
-      0,
-      "Sky for false detections in file `_detsky.fits'.",
-      4
+      "Save all the detection steps to a file.",
+      ARGS_GROUP_DETECTION,
+      &p->checkdetection,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "checksky",
-      512,
-      0,
-      0,
-      "Final sky and its STD per pixel `_sky.fits'.",
-      4
-    },
-    {
-      "checkmaskdet",
-      518,
+      ARGS_OPTION_KEY_CHECKSKY,
       0,
       0,
-      "Mask detections and sky, `_maskdet.fits'.",
-      4
+      "Final sky and its STD steps in a file.",
+      ARGS_GROUP_DETECTION,
+      &p->checkdetection,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
+    /* Segmentation */
     {
       0, 0, 0, 0,
       "Segmentation:",
-      5
+      ARGS_GROUP_SEGMENTATION
     },
     {
       "segsnminarea",
-      'm',
+      ARGS_OPTION_KEY_SEGSNMINAREA,
       "INT",
       0,
-      "Minimum area to find clumps S/N.",
-      5
+      "Minimum area of clumps for S/N estimation.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->segsnminarea,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "segquant",
-      'g',
+      ARGS_OPTION_KEY_SEGQUANT,
       "FLT",
       0,
-      "Signal to noise ratio quantile for clumps.",
-      5
+      "Quantile of clumps in sky to find true S/N.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->segquant,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "clumpsnhistnbins",
-      514,
-      "INT",
+      "checkclumpsn",
+      ARGS_OPTION_KEY_CHECKCLUMPSN,
+      0,
       0,
-      "Clump S/N histogram bins, suffix `_clumpsn.txt'.",
-      5
+      "Save Sky clump S/N values into a file.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->checkclumpsn,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "keepmaxnearriver",
-      'v',
+      ARGS_OPTION_KEY_KEEPMAXNEARRIVER,
       0,
       0,
-      "Keep clumps with max touching river.",
-      5
+      "Keep clumps with peak touching a river.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->keepmaxnearriver,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "gthresh",
-      'G',
+      ARGS_OPTION_KEY_GTHRESH,
       "FLT",
       0,
-      "Threshold (STD multiple) to stop growing clumps.",
-      5
+      "Multiple of STD to stop growing clumps.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->gthresh,
+      GAL_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "minriverlength",
-      'y',
-      0,
+      ARGS_OPTION_KEY_MINRIVERLENGTH,
+      "INT",
       0,
-      "Minimum length of useful rivers in grown clumps.",
-      5
+      "Minimum len of useful grown clump rivers.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->minriverlength,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "objbordersn",
-      'O',
+      ARGS_OPTION_KEY_OBJBORDERSN,
       "FLT",
       0,
-      "Minimum S/N for grown clumps to be one object.",
-      5
+      "Min. S/N for grown clumps to be one object.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->objbordersn,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
-
     {
       "checksegmentation",
-      513,
+      ARGS_OPTION_KEY_CHECKSEGMENTATION,
       0,
       0,
-      "Store segmentation steps in file `_seg.fits'.",
-      5
+      "Store segmentation steps in a file.",
+      ARGS_GROUP_SEGMENTATION,
+      &p->checksegmentation,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
     {
-      0, 0, 0, 0,
-      "Operating modes:",
-      -1
+      "continueaftercheck",
+      ARGS_OPTION_KEY_CONTINUEAFTERCHECK,
+      0,
+      0,
+      "Continue processing after checks.",
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &p->continueaftercheck,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
@@ -538,324 +525,21 @@ static struct argp_option options[] =
 
 
 
-/* Parse a single option: */
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
-{
-  /* Save the arguments structure: */
-  struct noisechiselparams *p = state->input;
-
-  /* Set the pointer to the common parameters for all programs
-     here: */
-  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");
-
-  switch(key)
-    {
-
-
-    /* Input: */
-    case 'M':
-      gal_checkset_allocate_copy_set(arg, &p->up.maskname,
-                                     &p->up.masknameset);
-      break;
-    case 'H':
-      gal_checkset_allocate_copy_set(arg, &p->up.mhdu, &p->up.mhduset);
-      break;
-    case 'k':
-      gal_checkset_allocate_copy_set(arg, &p->up.kernelname,
-                                     &p->up.kernelnameset);
-      break;
-    case 'U':
-      gal_checkset_allocate_copy_set(arg, &p->up.khdu, &p->up.khduset);
-      break;
-    case 'E':
-      p->skysubtracted=1;
-      p->up.skysubtractedset=1;
-      break;
-    case 'B':
-      gal_checkset_float_l_0_s_1(arg, &p->minbfrac, "minbfrac", key,
-                                 SPACK, NULL, 0);
-      p->up.minbfracset=1;
-      break;
-    case 'F':
-      gal_checkset_sizet_l_zero(arg, &p->minnumfalse, "minnumfalse", key,
-                                SPACK, NULL, 0);
-      p->up.minnumfalseset=1;
-      break;
-
-    /* Output: */
-    case 517:
-      p->detectonly=1;
-      break;
-    case 'C':
-      p->grownclumps=1;
-      p->up.grownclumpsset=1;
-      break;
-
-    /* Mesh grid: */
-    case 's':
-      gal_checkset_sizet_l_zero(arg, &p->smp.meshsize, "smeshsize", key,
-                                SPACK, NULL, 0);
-      p->up.smeshsizeset=1;
-      break;
-    case 'l':
-      gal_checkset_sizet_l_zero(arg, &p->lmp.meshsize, "lmeshsize", key,
-                                SPACK, NULL, 0);
-      p->up.lmeshsizeset=1;
-      break;
-    case 'a':
-      gal_checkset_sizet_l_zero(arg, &p->smp.nch1, "nch1", key, SPACK,
-                                NULL, 0);
-      p->up.nch1set=1;
-      break;
-    case 'b':
-      gal_checkset_sizet_l_zero(arg, &p->smp.nch2, "nch2", key, SPACK,
-                                NULL, 0);
-      p->up.nch2set=1;
-      break;
-    case 'L':
-      gal_checkset_float_l_0_s_1(arg, &p->smp.lastmeshfrac, "lastmeshfrac",
-                                 key, SPACK, NULL, 0);
-      p->up.lastmeshfracset=1;
-      break;
-    case 'd':
-      gal_checkset_float_l_0(arg, &p->smp.mirrordist, "mirrordist", key,
-                             SPACK, NULL, 0);
-      p->up.mirrordistset=1;
-      break;
-    case 'Q':
-      gal_checkset_float_l_0_s_1(arg, &p->smp.minmodeq, "minmodeq", key,
-                                 SPACK, NULL, 0);
-      p->up.minmodeqset=1;
-      break;
-    case 511:
-      p->smp.interponlyblank=1;
-      break;
-    case 'n':
-      gal_checkset_sizet_l_zero(arg, &p->smp.numnearest, "numnearest", key,
-                                SPACK, NULL, 0);
-      p->up.numnearestset=1;
-      break;
-    case 'T':
-      gal_checkset_sizet_p_odd(arg, &p->smp.smoothwidth, "smoothwidth", key,
-                               SPACK, NULL, 0);
-      p->up.smoothwidthset=1;
-      break;
-    case 500:
-      p->meshname="a";  /* Just a placeholder! It will be corrected later */
-      break;
-    case 501:
-      p->smp.fullinterpolation=1;
-      p->up.fullinterpolationset=1;
-      break;
-    case 502:
-      p->smp.fullsmooth=1;
-      p->up.fullsmoothset=1;
-      break;
-    case 504:
-      p->smp.fullconvolution=1;
-      p->up.fullconvolutionset=1;
-      break;
-    case 516:
-      p->smp.meshbasedcheck=1;
-      break;
-
-
-    /* Detection */
-    case 't':
-      gal_checkset_float_l_0_s_1(arg, &p->qthresh, "qthresh", key, SPACK,
-                                 NULL, 0);
-      p->up.qthreshset=1;
-      break;
-    case 'e':
-      gal_checkset_sizet_el_zero(arg, &p->erode, "erode", key, SPACK,
-                                 NULL, 0);
-      p->up.erodeset=1;
-      break;
-    case 506:
-      gal_checkset_int_4_or_8(arg, &p->erodengb, "erodengb", key, SPACK,
-                              NULL, 0);
-      p->up.erodengbset=1;
-      break;
-    case 503:
-      gal_checkset_float_l_0_s_1(arg, &p->noerodequant, "noerodequant",
-                                 key, SPACK, NULL, 0);
-      p->up.noerodequantset=1;
-      break;
-    case 'p':
-      gal_checkset_sizet_el_zero(arg, &p->opening, "opening", key, SPACK,
-                                 NULL, 0);
-      p->up.openingset=1;
-      break;
-    case 507:
-      gal_checkset_int_4_or_8(arg, &p->openingngb, "openingngb", key, SPACK,
-                              NULL, 0);
-      p->up.openingngbset=1;
-      break;
-    case 'u':
-      gal_checkset_float_l_0(arg, &p->sigclipmultip, "sigclipmultip", key,
-                             SPACK, NULL, 0);
-      p->up.sigclipmultipset=1;
-      break;
-    case 'r':
-      gal_checkset_float_l_0_s_1(arg, &p->sigcliptolerance,
-                                 "sigcliptolerance", key, SPACK, NULL, 0);
-      p->up.sigcliptoleranceset=1;
-      break;
-    case 'R':
-      gal_checkset_any_float(arg, &p->dthresh, "dthresh", key, SPACK,
-                             NULL, 0);
-      p->up.dthreshset=1;
-      break;
-    case 'i':
-      gal_checkset_sizet_l_zero(arg, &p->detsnminarea, "detsnminarea", key,
-                                SPACK, NULL, 0);
-      p->up.detsnminareaset=1;
-      break;
-    case 510:
-      gal_checkset_sizet_el_zero(arg, &p->detsnhistnbins, "detsnhistnbins",
-                                 key, SPACK, NULL, 0);
-      p->up.detsnhistnbinsset=1;
-      break;
-    case 'c':
-      gal_checkset_float_l_0_s_1(arg, &p->detquant, "detquant", key, SPACK,
-                                 NULL, 0);
-      p->up.detquantset=1;
-      break;
-    case 'I':
-      gal_checkset_sizet_el_zero(arg, &p->dilate, "dilate", key, SPACK,
-                                 NULL, 0);
-      p->up.dilateset=1;
-      break;
-    case 505:
-      p->threshname="a";
-      break;
-    case 508:
-      p->detectionname="a";
-      break;
-    case 509:
-      p->detectionskyname="a";
-      break;
-    case 512:
-      p->skyname="a";
-      break;
-    case 518:
-      p->maskdetname="a";
-      break;
-
-
-    /* Segmentation: */
-    case 'm':
-      gal_checkset_sizet_l_zero(arg, &p->segsnminarea, "segsnminarea", key,
-                                SPACK, NULL, 0);
-      p->up.segsnminareaset=1;
-      break;
-    case 'g':
-      gal_checkset_float_l_0_s_1(arg, &p->segquant, "segquant", key, SPACK,
-                                 NULL, 0);
-      p->up.segquantset=1;
-      break;
-    case 'v':
-      p->keepmaxnearriver=1;
-      break;
-    case 'G':
-      gal_checkset_any_float(arg, &p->gthresh, "gthresh", key, SPACK, NULL, 0);
-      p->up.gthreshset=1;
-      break;
-    case 'y':
-      gal_checkset_sizet_l_zero(arg, &p->minriverlength, "minriverlength",
-                                key, SPACK, NULL, 0);
-      p->up.minriverlengthset=1;
-      break;
-    case 'O':
-      gal_checkset_float_l_0(arg, &p->objbordersn, "objbordersn", key, SPACK,
-                             NULL, 0);
-      p->up.objbordersnset=1;
-      break;
-
-    case 514:
-      gal_checkset_sizet_el_zero(arg, &p->clumpsnhistnbins,
-                                 "clumpsnhistnbins", key, SPACK, NULL, 0);
-      p->up.clumpsnhistnbinsset=1;
-      break;
-    case 513:
-      p->segmentationname="a";
-      break;
-
-
-    /* Operating modes: */
-
-
-    /* Read the non-option arguments: */
-    case ARGP_KEY_ARG:
-
-      /* See what type of input value it is and put it in. */
-      if( gal_fits_name_is_fits(arg) )
-        {
-          if(p->up.inputname)
-            argp_error(state, "only one input image should be given");
-          else
-            p->up.inputname=arg;
-        }
-      else
-        argp_error(state, "%s is not a valid file type", arg);
-      break;
-
-
-
-
-
-    /* The command line options and arguments are finished. */
-    case ARGP_KEY_END:
-      if(p->cp.setdirconf==0 && p->cp.setusrconf==0
-         && p->cp.printparams==0)
-        {
-          if(state->arg_num==0)
-            argp_error(state, "no argument given");
-          if(p->up.inputname==NULL)
-            argp_error(state, "no input FITS image(s) provided");
-        }
-      break;
-
-
-
-
-
-    default:
-      return ARGP_ERR_UNKNOWN;
-    }
-  return 0;
-}
-
-
-
-
-
-/* Specify the children parsers: */
-struct argp_child children[]=
-  {
-    {&commonargp, 0, NULL, 0},
-    {0, 0, 0, 0}
-  };
-
+/* Define the child argp structure. */
+struct argp
+gal_options_common_child = {gal_commonopts_options,
+                            gal_options_common_argp_parse,
+                            NULL, NULL, NULL, NULL, NULL};
 
+/* Use the child argp structure in list of children (only one for now). */
+struct argp_child
+children[]=
+{
+  {&gal_options_common_child, 0, NULL, 0},
+  {0, 0, 0, 0}
+};
 
-
-
-/* Basic structure defining the whole argument reading process. */
-static struct argp thisargp = {options, parse_opt, args_doc,
-                               doc, children, NULL, NULL};
-
+/* Set all the necessary argp parameters. */
+struct argp
+thisargp = {program_options, parse_opt, args_doc, doc, children, NULL, NULL};
 #endif
diff --git a/bin/noisechisel/astnoisechisel.conf 
b/bin/noisechisel/astnoisechisel.conf
index 7b952bc..90d9556 100644
--- a/bin/noisechisel/astnoisechisel.conf
+++ b/bin/noisechisel/astnoisechisel.conf
@@ -1,7 +1,7 @@
 # Default parameters (System) for NoiseChisel.
-# NoiseChisel is part of GNU Astronomy Utitlies.
+# Table is part of GNU Astronomy Utitlies.
 #
-# Use the long option name of each parameter followed by
+# Use the long option name of each paramter followed by
 # a value. The name and value should be separated by
 # atleast one of the following charaacters:
 # space, `,`, `=` or `:`
@@ -19,47 +19,32 @@
 
 # Input:
  khdu               1
- skysubtracted      0
  minbfrac         0.5
  minnumfalse      100
 
-# Output:
- grownclumps        0
-
-# Mesh grid:
- smeshsize         32
- lmeshsize        200
- nch1               1
- nch2               1
- lastmeshfrac    0.51
- numnearest        10
- smoothwidth        3
- fullconvolution    0
- fullinterpolation  0
- fullsmooth         0
-
 # Detection:
  mirrordist       1.5
- minmodeq        0.49
+ modmedqdiff     0.01
  qthresh          0.3
+ smoothwidth        3
  erode              2
  erodengb           4
  noerodequant  0.9331
  opening            1
  openingngb         8
- sigclipmultip      3
- sigcliptolerance 0.2
- dthresh         -0.1
- detsnminarea      15
- detsnhistnbins     0
+ sigmaclip      3,0.2
+ dthresh          0.0
+ detsnminarea      10
  detquant        0.95
  dilate             3
 
 # Segmentation
- segsnminarea      25
+ segsnminarea      15
  keepmaxnearriver   0
  segquant        0.95
- clumpsnhistnbins   0
  gthresh          0.5
  minriverlength    15
- objbordersn        1
\ No newline at end of file
+ objbordersn        1
+
+# Operating mode
+ continueaftercheck 0
\ No newline at end of file
diff --git a/bin/noisechisel/authors-cite.h b/bin/noisechisel/authors-cite.h
index 9589300..caaca75 100644
--- a/bin/noisechisel/authors-cite.h
+++ b/bin/noisechisel/authors-cite.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
diff --git a/bin/noisechisel/binary.c b/bin/noisechisel/binary.c
deleted file mode 100644
index c56b12c..0000000
--- a/bin/noisechisel/binary.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <math.h>
-#include <stdio.h>
-#include <errno.h>
-#include <error.h>
-#include <stdlib.h>
-
-#include <gnuastro/fits.h>
-
-#include "main.h"
-
-#include "label.h"
-#include "binary.h"
-
-
-
-
-
-/****************************************************************
- **************            Binary NAN           *****************
- ****************************************************************/
-/* When the float image has NaN pixels, set the respective byt value
-   to GAL_FITS_BYTE_BLANK. */
-void
-setbytblank(float *img, unsigned char *byt, size_t size)
-{
-  float *end=img+size;
-  do
-    {
-      if(isnan(*img++))
-        *byt=GAL_DATA_BLANK_UCHAR;
-      ++byt;
-    }
-  while(img<end);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/****************************************************************
- **************       Counting/indexing         *****************
- ****************************************************************/
-/* A region in a larger image is defined by its starting pixel
-   (`start`), its height (s0) and width (s1). This function will count
-   how many nonmasked (==0 in mask[]), foregound (==1 in byt[]) and
-   background (==0 in byt[]) pixels there are in a given region of
-   these two large arrays. mask[] and byt[] should have the same size
-   and their width is here called `is1`. */
-void
-count_f_b_onregion(unsigned char *byt, size_t startind, size_t s0,
-                   size_t s1, size_t is1, size_t *numf, size_t *numb,
-                   int *anyblank)
-{
-  unsigned char *b, *fb;
-  size_t nf=0, nb=0, row=0;
-
-  *anyblank=0;
-  do
-    {
-      fb = ( b = byt + startind + is1*row++ ) + s1;
-      do
-        *b ? (*b==GAL_DATA_BLANK_UCHAR ? *anyblank=1: ++nf) : ++nb;
-      while(++b<fb);
-    }
-  while(row<s0);
-
-  *numf=nf;
-  *numb=nb;
-}
-
-
-
-
-
-/* This function will put the indexs of the byt array that are equal
-   to b0f1 into the inds array. Note that the inds array has to have
-   been allocated outside this function. */
-void
-index_f_b_onregion(unsigned char *byt, size_t startind, size_t s0,
-                   size_t s1, size_t is1, size_t *inds,
-                   unsigned char b0f1)
-{
-  size_t row=0;
-  unsigned char *b, *fb;
-
-  do
-    {
-      fb = ( b = byt + startind + is1*row++ ) + s1;
-      do if(*b==b0f1) *inds++=b-byt; while(++b<fb);
-    }
-  while(row<s0);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/****************************************************************
- *****************      Dilate and Erode     ********************
- ****************************************************************/
-/* 4 connected dilation and erosion: b0_f1==0: Dilate the
-   foreground. b0_f1==1: Erode the foreground.  */
-void
-dilate0_erode1_4con(unsigned char *byt, size_t nr, size_t nc,
-                    unsigned char b0_f1)
-{
-  size_t i, j, ind;
-  unsigned char f, b, *pt, *fpt;
-
-  /* Do a sanity check: */
-  if(b0_f1!=1 && b0_f1!=0)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
-          "this problem. In dilate0_erode1_4con (binary.c), the value to "
-          "b0_f1 is %u while it should be 0 or 1", PACKAGE_BUGREPORT,
-          b0_f1);
-
-  /* Set the foreground and background values. */
-  if(b0_f1==0) {f=1; b=0;}
-  else         {f=0; b=1;}
-
-  /* Check the 4 corners: */
-  if(byt[0]==b && (byt[1]==f || byt[nc]==f) )
-    byt[0]=BINARYTMP;
-
-  if(byt[nc-1]==b && (byt[nc-2]==f || byt[2*nc-1]==f))
-    byt[nc-1]=BINARYTMP;
-
-  if(byt[(nr-1)*nc]==b
-     && (byt[(nr-2)*nc]==f || byt[(nr-1)*nc+1]==f) )
-    byt[(nr-1)*nc]=BINARYTMP;
-
-  if(byt[nr*nc-1]==b
-     && (byt[nr*nc-2]==f || byt[nr*nc-1-nc]==f) )
-    byt[nr*nc-1]=BINARYTMP;
-
-  /* Check the 4 sides: */
-  for(j=1;j<nc-1;++j)
-    if(byt[j]==b
-       && (byt[j+1]==f || byt[j-1]==f || byt[j+nc]==f) )
-      byt[j]=BINARYTMP;
-
-  for(j=1;j<nc-1;++j)
-    {
-      ind=(nr-1)*nc+j;
-      if(byt[ind]==b
-         && (byt[ind+1]==f || byt[ind-1]==f || byt[ind-nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  for(i=1;i<nr-1;++i)
-    {
-      ind=i*nc;
-      if(byt[ind]==b
-         && (byt[ind+1]==f || byt[ind+nc]==f || byt[ind-nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  for(i=1;i<nr-1;++i)
-    {
-      ind=(i+1)*nc-1;
-      if(byt[ind]==b
-         && (byt[ind-1]==f || byt[ind+nc]==f || byt[ind-nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  /* Check the body: */
-  for(i=1;i<nr-1;++i)
-    for(j=1;j<nc-1;++j)
-      {
-        ind=i*nc+j;
-        if(byt[ind]==b
-           && (byt[ind-1]==f     || byt[ind+1]==f
-               || byt[ind+nc]==f || byt[ind-nc]==f) )
-          byt[ind]=BINARYTMP;
-      }
-
-  /* Set all the changed pixels to the proper values: */
-  fpt=(pt=byt)+nr*nc;
-  do *pt = *pt==BINARYTMP ? f : *pt; while(++pt<fpt);
-}
-
-
-
-
-
-/* 8 connected dilation and erosion. b0_f1==0: Dilate the
-   foreground. b0_f1==1: Erode the foreground. */
-void
-dilate0_erode1_8con(unsigned char *byt, size_t nr, size_t nc,
-                    unsigned char b0_f1)
-{
-  size_t i, j, ind;
-  unsigned char f, b, *pt, *fpt;
-
-  /* Do a sanity check: */
-  if(b0_f1!=1 && b0_f1!=0)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
-          "this problem. In dilate0_erode1_4con (binary.c), the value to "
-          "b0_f1 is %u while it should be 0 or 1", PACKAGE_BUGREPORT,
-          b0_f1);
-
-  /* Set the foreground and background values: */
-  if(b0_f1==0) {f=1; b=0;}
-  else         {f=0; b=1;}
-
-  /* Check the 4 corners: */
-  if(byt[0]==b && (byt[1]==f
-                   || byt[nc]==f || byt[nc+1]==f) )
-    byt[0]=BINARYTMP;
-
-  if(byt[nc-1]==b && (byt[nc-2]==f
-                      || byt[2*nc-1]==f
-                      || byt[2*nc-2]==f) )
-    byt[nc-1]=BINARYTMP;
-
-  if(byt[(nr-1)*nc]==b
-     && ( byt[(nr-2)*nc]==f || byt[(nr-1)*nc+1]==f
-          || byt[(nr-2)*nc+1]==f) )
-    byt[(nr-1)*nc]=BINARYTMP;
-
-  if(byt[nr*nc-1]==b
-     && ( byt[nr*nc-2]==f || byt[nr*nc-1-nc]==f
-          || byt[nr*nc-2-nc]==f) )
-    byt[nr*nc-1]=BINARYTMP;
-
-  /* Check the 4 sides: */
-  for(j=1;j<nc-1;++j)
-    if(byt[j]==b
-       && ( byt[j+1]==f || byt[j-1]==f || byt[j+nc]==f
-            || byt[j-1+nc]==f || byt[j+1+nc]==f) )
-      byt[j]=BINARYTMP;
-
-  for(j=1;j<nc-1;++j)
-    {
-      ind=(nr-1)*nc+j;
-      if(byt[ind]==b
-         && ( byt[ind+1]==f || byt[ind-1]==f || byt[ind-nc]==f
-              || byt[ind-1-nc]==f || byt[ind+1-nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  for(i=1;i<nr-1;++i)
-    {
-      ind=i*nc;
-      if(byt[ind]==b
-         && ( byt[ind+1]==f || byt[ind+nc]==f || byt[ind-nc]==f
-              || byt[ind+1-nc]==f || byt[ind+1+nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  for(i=1;i<nr-1;++i)
-    {
-      ind=(i+1)*nc-1;
-      if(byt[ind]==b
-         && (byt[ind-1]==f || byt[ind+nc]==f || byt[ind-nc]==f
-             || byt[ind-1-nc]==f || byt[ind-1+nc]==f) )
-        byt[ind]=BINARYTMP;
-    }
-
-  /* Check the body: */
-  for(i=1;i<nr-1;++i)
-    for(j=1;j<nc-1;++j)
-      {
-        ind=i*nc+j;
-        if(byt[ind]==b
-           && (byt[ind-1]==f        || byt[ind+1]==f
-               || byt[ind+nc]==f    || byt[ind-nc]==f
-               || byt[ind-1-nc]==f  || byt[ind+1+nc]==f
-               || byt[ind-1+nc]==f  || byt[ind+1-nc]==f) )
-          byt[ind]=BINARYTMP;
-      }
-
-  /* Set all the changed pixels to the proper values: */
-  fpt=(pt=byt)+nr*nc;
-  do *pt = *pt==BINARYTMP ? f : *pt; while(++pt<fpt);
-}
-
-
-
-
-
-
-/* Opening: erode n times then dilate n times. */
-void
-opening(unsigned char *byt, size_t s0, size_t s1,
-        size_t depth, int con_type)
-{
-  size_t i;
-  void (*func)(unsigned char *, size_t, size_t, unsigned char);
-
-  /* Sanity check: */
-  if(con_type!=4 && con_type!=8)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
-          "this problem. For some reason, the value to con_type in opening "
-          "(binary.c) is %d while it should be 4 or 8", PACKAGE_BUGREPORT,
-          con_type);
-
-  /* Do the opening: */
-  if(con_type==4)
-    func=dilate0_erode1_4con;
-  else func=dilate0_erode1_8con;
-
-  for(i=0;i<depth;++i)
-    func(byt, s0, s1, 1);
-
-  for(i=0;i<depth;++i)
-    func(byt, s0, s1, 0);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/****************************************************************
- *****************          Fill holes       ********************
- ****************************************************************/
-void
-fillleftside(unsigned char *inv, size_t idx, size_t idy,
-             size_t maxfill)
-{
-  size_t i, j, min_o, end, index;
-
-  min_o=1;
-  end=idx-2;
-  for(i=2;i<end;++i)
-    {
-      index=i*idy+2;
-      if(inv[index]==1 && inv[index+idy]==0)
-        {
-          if(i+1-min_o<maxfill)
-            for(j=min_o;j<=i+1;++j)
-              inv[j*idy+1]=BINARYTMP;
-          min_o=i+1;
-        }
-      else if(inv[index]==0 && inv[index+idy]==1)
-        min_o=i;
-    }
-  if(min_o!=1 && end-min_o<maxfill)
-    for(j=min_o;j<=end;++j)
-      inv[j*idy+1]=BINARYTMP;
-}
-
-
-
-
-
-void
-fillbottomside(unsigned char *inv, size_t idy,
-               size_t maxfill)
-{
-  size_t i, j, min_o, end, index;
-
-  min_o=1;
-  end=idy-2;
-  for(i=2;i<end;++i)
-    {
-      index=2*idy+i;
-      if(inv[index]==1 && inv[index+1]==0)
-        {
-          if(i+1-min_o<maxfill)
-            for(j=min_o;j<=i+1;++j)
-              inv[idy+j]=BINARYTMP;
-          min_o=i+1;
-        }
-      else if(inv[index]==0 && inv[index+1]==1)
-        min_o=i;
-    }
-  if(min_o!=1 && end-min_o<maxfill)
-    for(j=min_o;j<=end;++j)
-      inv[idy+j]=BINARYTMP;
-}
-
-
-
-
-
-void
-fillrightside(unsigned char *inv, size_t idx, size_t idy,
-              size_t maxfill)
-{
-  size_t i, j, min_o, end, index;
-
-  min_o=1;
-  end=idx-2;
-  for(i=2;i<end;++i)
-    {
-      index=i*idy+idy-3;
-      if(inv[index]==1 && inv[index+idy]==0)
-        {
-          if(i+1-min_o<maxfill)
-            for(j=min_o;j<=i+1;++j)
-              inv[j*idy+idy-2]=BINARYTMP;
-          min_o=i+1;
-        }
-      else if(inv[index]==0 && inv[index+idy]==1)
-        min_o=i;
-    }
-  if(min_o!=1 && end-min_o<maxfill)
-    for(j=min_o;j<=end;++j)
-      inv[j*idy+idy-2]=BINARYTMP;
-}
-
-
-
-
-
-void
-filltopside(unsigned char *inv, size_t idx, size_t idy,
-            size_t maxfill)
-{
-  size_t i, j, min_o, end, index;
-
-  min_o=1;
-  end=idy-2;
-  for(i=2;i<end;++i)
-    {
-      index=(idx-3)*idy+i;
-      if(inv[index]==1 && inv[index+1]==0)
-        {
-          if(i+1-min_o<maxfill)
-            for(j=min_o;j<=i+1;++j)
-              inv[(idx-2)*idy+j]=BINARYTMP;
-          min_o=i+1;
-        }
-      else if(inv[index]==0 && inv[index+1]==1)
-        min_o=i;
-    }
-  if(min_o!=1 && end-min_o<maxfill)
-    for(j=min_o;j<=end;++j)
-      inv[(idx-2)*idy+j]=BINARYTMP;
-}
-
-
-
-
-
-/* Make the array that is the inverse of the input byt of fill
-   holes. The inverse array will also be 4 pixels larger in both
-   dimensions. This is because we might also want to fill those holes
-   that are touching the side of the image. One pixel for a pixel that
-   is one pixel away from the image border. Another pixel for those
-   objects that are touching the image border. */
-void
-fh_makeinv(unsigned char *byt, size_t s0, size_t s1,
-           unsigned char **inv, size_t *oidx, size_t *oidy,
-           size_t l, size_t b, size_t r, size_t t, int anyblank)
-{
-  unsigned char *tinv, *bp, *bf, *tp, *sp;
-  size_t i, row, start, idx, idy, size, tdiff=2;
-
-  idx=s0+2*tdiff;
-  idy=s1+2*tdiff;
-  size=idx*idy;
-
-  /* Allocate the temporary inverse array: */
-  errno=0; tinv=malloc(size*sizeof *tinv);
-  if(tinv==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for tinv (binary.c)",
-          size*sizeof *tinv);
-
-  /* Fill in the central regions of the inverse array: */
-  row=0;
-  start=tdiff*idy+tdiff;
-  do
-    {
-      tp=tinv+start+row*idy;
-      bf = ( bp = byt + row++ * s1 ) + s1;
-      if(anyblank)
-        do *tp++ = *bp==GAL_DATA_BLANK_UCHAR
-             ? GAL_DATA_BLANK_UCHAR : !*bp; while(++bp<bf);
-      else
-        do *tp++ = !*bp; while(++bp<bf);
-    }
-  while(row<s0);
-
-  /* Fill in the edges: */
-  row=0;
-  do
-    {
-      bf = ( bp = tinv + row * idy ) + idy;
-      if(row<tdiff || row>=idx-2)   /* Fill the full row if it is one of  */
-        do *bp++=1; while(bp<bf);   /* the first or last rows.            */
-      else
-        {                       /* Fill the start and end of the row. */
-          sp=bp; do *bp++=1; while(bp-sp<tdiff);
-          bp=sp+s1+tdiff; do *bp++=1; while(bp<bf);
-        }
-    }
-  while(++row<idx);
-
-  /* Fill the four sides if such holes are to be filled. */
-  if(l!=0) fillleftside(tinv, idx, idy, l);
-  if(b!=0) fillbottomside(tinv, idy, b);
-  if(r!=0) fillrightside(tinv, idx, idy, r);
-  if(t!=0) filltopside(tinv, idx, idy, t);
-
-  if(l!=0 || b!=0 || r!=0 || t!=0)
-    for(i=0;i<size;++i)
-      if(tinv[i]==BINARYTMP) tinv[i]=0;
-
-  *inv=tinv;
-  *oidx=idx;
-  *oidy=idy;
-}
-
-
-
-
-
-/* Fill all the holes in an input unsigned char array that are bounded
-   within a 4-connected region.
-
-   The basic method is this:
-
-   1. An inverse image is created:
-
-        * For every pixel in the input that is 1, the inverse is 0.
-
-        * The inverse image has two extra pixels on each edge to
-          ensure that all the inv[i]==1 pixels around the image are
-          touching each other and a diagonal object passing through
-          the image does not cause the inv[i]==1 pixels on the edges
-          of the image to get a different label.
-
-   2. The 8 connected regions in this inverse image are found.
-
-   3. Since we had a 2 pixel padding on the edges of the image, we
-      know for sure that all labeled regions with a label of 1 are
-      actually connected `holes' in the input image.
-
-      Any pixel with a label larger than 1, is therefore a bounded
-      hole that is not 8-connected to the rest of the holes.
-
-*/
-void
-fillboundedholes(unsigned char *in, size_t s0, size_t s1, int anyblank)
-{
-  long *h, *hlab;
-  unsigned char *inv, *n, *nf;
-  size_t row, idx, idy, diff, start;
-
-
-  /* Make the inverse array: */
-  fh_makeinv(in, s0, s1, &inv, &idx, &idy, 0, 0, 0, 0, anyblank);
-  diff=(idx-s0)/2;
-
-
-  /* Allocate the array to keep the hole indexs */
-  errno=0; hlab=malloc(idx*idy*sizeof *hlab);
-  if(hlab==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for hlab in filllabeledholes "
-          "(binary.c)", idx*idy*sizeof *hlab);
-
-
-  /* Find the hole labels */
-  BF_concmp(inv, hlab, idx, idy, anyblank, 8);
-
-
-  /* For a check
-  gal_fits_array_to_file("fbh.fits", "INPUT", BYTE_IMG, in,
-                         s0, s1, anyblank, NULL, NULL, "tmp");
-  gal_fits_array_to_file("fbh.fits", "INV", BYTE_IMG, inv,
-                         idx, idy, anyblank, NULL, NULL, "tmp");
-  gal_fits_array_to_file("fbh.fits", "HLAB", LONG_IMG, hlab,
-                         idx, idy, anyblank, NULL, NULL, "tmp");
-  */
-
-  /* Correct the labels: */
-  row=0;
-  start=diff*idy+diff;
-  do                            /* Note that holes will always  */
-    {                           /* be in the inner diff pixels. */
-      h = hlab + start + row*idy;
-      nf = ( n = in + row++ * s1) + s1;
-      do *n = *h++>1 ? 1 : *n; while(++n<nf);
-    }
-  while(row<s0);
-
-
-  /* For a check:
-  gal_fits_array_to_file("fbh.fits", "INPUT", BYTE_IMG, in,
-                         s0, s1, anyblank, NULL, NULL, "tmp");
-  exit(0);
-  */
-
-  free(inv);
-  free(hlab);
-}
-
-
-
-
-
-void
-maskbackorforeground(float *in, size_t size, unsigned char *byt,
-                     unsigned char b0f1)
-{
-  float *endin=in+size;
-  do if(*byt++==b0f1) *in=NAN; while(++in<endin);
-}
diff --git a/bin/noisechisel/binary.h b/bin/noisechisel/binary.h
deleted file mode 100644
index 21db117..0000000
--- a/bin/noisechisel/binary.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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/>.
-**********************************************************************/
-#ifndef BINARY_H
-#define BINARY_H
-
-
-
-
-
-/* For the GAL_FITSARRAY_BYTE_BLANK value: */
-#include <gnuastro/fits.h>
-
-
-
-
-
-/* Special values:
-
-     BINARYNOOP:   Value that no binary operation should be preformed on.
-     BINARYTMP:    Temporary value to use within one function.
-
-   Note that through the `setbytblank' function, practically we are using
-   the value `GAL_FITS_BYTE_BLANK' (from `gnuastro/fits.h') for blank
-   binary values. Recall that due to the nature of the CPU (which operates
-   on 8-bits), in practice it is much more efficient to work on a byte (or
-   8-bits) rather than each bit. So in practice we can use 256 values for
-   meta-data analyais (like blank values, or temporary values at etc),
-   eventhough the main values we are working with are 0 and 1.
-*/
-#define BINARYNOOP  2
-#define BINARYTMP   3
-
-
-
-
-
-void
-setbytblank(float *img, unsigned char *byt, size_t size);
-
-void
-count_f_b_onregion(unsigned char *byt, size_t startind, size_t s0,
-                   size_t s1, size_t is1, size_t *numf, size_t *numb,
-                   int *anyblank);
-
-void
-index_f_b_onregion(unsigned char *byt, size_t startind, size_t s0,
-                   size_t s1, size_t is1, size_t *inds,
-                   unsigned char b0f1);
-
-void
-dilate0_erode1_4con(unsigned char *byt, size_t nr, size_t nc,
-                    unsigned char b0_f1);
-
-void
-dilate0_erode1_8con(unsigned char *byt, size_t nr, size_t nc,
-                    unsigned char b0_f1);
-
-void
-opening(unsigned char *byt, size_t s0, size_t s1,
-        size_t depth, int con_type);
-
-void
-fillboundedholes(unsigned char *in, size_t s0, size_t s1, int anyblank);
-
-void
-maskbackorforeground(float *in, size_t size, unsigned char *byt,
-                     unsigned char b0f1);
-
-#endif
diff --git a/bin/noisechisel/clumps.c b/bin/noisechisel/clumps.c
deleted file mode 100644
index f18a898..0000000
--- a/bin/noisechisel/clumps.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <float.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <gnuastro/fits.h>
-#include <gnuastro/array.h>
-#include <gnuastro/qsort.h>
-#include <gnuastro/linkedlist.h>
-#include <gnuastro/statistics.h>
-
-#include <timing.h>
-#include <checkset.h>
-#include <neighbors.h>
-
-#include "main.h"
-
-#include "clumps.h"
-#include "binary.h"
-#include "thresh.h"
-
-
-
-
-
-
-
-
-
-/****************************************************************
- *****************   Over segmentation       ********************
- ****************************************************************/
-/* This is very similar to the immersion method of Vincent &
-   Soille(1991), but I will not separate the image into layers, and
-   work based on the ordered flux values. If a certain pixel (at a
-   certain level) has no neighbors it is a local maximum and will be
-   assigned a new label. If it has a labeled neighbor, it will take
-   that label and if there is more than one neighboring labeled region
-   that pixel will be a `river` pixel.
-
-   x0, y0, x1 and y1:
-
-     - For the noise (mesh boxs), they specify the region in the image
-       where this over-segmentation is taking place.
-
-     - For the detections, they should be set to 0, 0, is0 and is1,
-       where is0 and is1 are the height and width of the input image.
-*/
-void
-oversegment(struct clumpsthreadparams *ctp)
-{
-  struct noisechiselparams *p=ctp->p;
-
-  /* pix is not actually used its self, however, the pointer to it will be
-     extensively used (ind) for the macro GAL_NEIGHBORS_FILL_8_REGION.
-     This macro works on the pointer to the index, not the index its
-     self. `pix` is filled with different index values, so the pointer to
-     it doesn't change. */
-  size_t pix;
-
-  float *arr=p->conv;
-  struct gal_linkedlist_sll *Q=NULL, *cleanup=NULL;
-  long n1, rlab, nlab, curlab=1, *clab=p->clab;
-  size_t x0=ctp->x0, y0=ctp->y0, x1=ctp->x1, y1=ctp->y1;
-  size_t *n, *nf, *indf, *pind, *ind=&pix, is1=p->lmp.s1;
-  size_t ng, *rn, *rnf, numngb, ngb[8], *relngb=p->relngb;
-
-  /* Sort the indexs based on the flux within them. */
-  qsort(ctp->inds, ctp->area, sizeof(size_t),
-        gal_qsort_index_float_decreasing);
-
-  /* Initialize the region you want to over-segment. */
-  indf=(pind=ctp->inds)+ctp->area;
-  do clab[*pind]=SEGMENTINIT; while(++pind<indf);
-
-  /* In the case where a connected region with the same flux or masked
-     regions exists, some later indices might already be labeled. Note
-     that in the convolved image that is being used here, the masked
-     pixels have the smallest possible float value.  */
-  indf=(pind=ctp->inds)+ctp->area;
-  do
-    /* When regions of a constant flux or masked regions exist, some
-       later indexs (although they have same flux) will be filled
-       before hand. If they are done, there is no need to do them
-       again. */
-    if(clab[*pind]==SEGMENTINIT)
-      {
-        /* View the over-segmentation pixel by pixel. Make sure that
-           `--viewsegtf` is off, or else several copies will be made.
-
-        if(p->data0_noise1==0 && p->mid==81 && pind!=p->indexs)
-          {
-            long *tmp;
-            float *ftmp;
-            static size_t counter=0;
-            size_t tmpx0=495, tmpy0=499, tmpx1=510, tmpy1=508;
-
-            if(counter==0)
-              {
-                floatshrinkarraytonew(arr, np->lmesh.s0, np->lmesh.s1,
-                                      tmpx0, tmpy0, tmpx1, tmpy1, &ftmp);
-                array_to_fits("overseg.fits", NULL, "1", FLOAT_IMG,
-                              ftmp, tmpx1-tmpx0, tmpy1-tmpy0, NULL);
-                free(ftmp);
-                counter++;
-              }
-
-            if( *(pind-1)/is1>=tmpx0 && *(pind-1)/is1<tmpx1
-                && *(pind-1)%is1>=tmpy0 && *(pind-1)%is1<tmpy1
-                && counter<=(tmpx1-tmpx0)*(tmpy1-tmpy0) )
-              {
-                longshrinkarraytonew(clab, np->lmesh.s0, np->lmesh.s1,
-                                     tmpx0, tmpy0, tmpx1, tmpy1, &tmp);
-                array_to_fits("overseg.fits", NULL, "1", LONG_IMG,
-                              tmp, tmpx1-tmpx0, tmpy1-tmpy0, NULL);
-                free(tmp);
-                counter++;
-              }
-          }
-        */
-        /* Some cases might happen where one or multiple regions of
-           the pixels under study have the same flux. In particular
-           note that masked pixels were all given a value of
-           FLT_MAX. We have sorted the pixels by flux. So two equal
-           valued pixels of two separate (but equal flux) regions
-           might fall immediately after each other (For example two
-           nearby stars whose centers are masked and are initially
-           detected as one object because their wings touch above the
-           noise).
-
-           Therefore, if we see that the next pixel in the index list
-           has the same flux as this one, it does not guarantee that
-           it should be given the same label. Similar to the breadth
-           first search algorithm for finding connected components, we
-           will search all the neighbours and the neighbours of those
-           neighbours that have the same flux of this pixel to see if
-           they touch any label or not and to finally give them all
-           the same label. */
-        if( pind+1<indf && arr[*pind]==arr[*(pind+1)] )
-          {
-            n1=0;
-            if(Q!=NULL || cleanup!=NULL)
-              error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we "
-                    "can fix this problem. In oversegment (clumps.c) Q and "
-                    "cleanup should be NULL but while checking the equal "
-                    "flux regions they aren't", PACKAGE_BUGREPORT);
-            gal_linkedlist_add_to_sll(&Q, *pind);
-            gal_linkedlist_add_to_sll(&cleanup, *pind);
-            clab[*pind]=SEGMENTTMPCHECK;
-
-            /* Find all the pixels that have the same flux and are
-               connected. */
-            while(Q!=NULL)
-              {
-                /* Pop an element from the queue. */
-                gal_linkedlist_pop_from_sll(&Q, ind);
-
-                /* Check the vicinity of this pixel that was just
-                   popped to see if it can find any already labeled
-                   neighbour or not. */
-                GAL_NEIGHBORS_FILL_8_REGION;
-
-                /* If the pixel is on the side of the region, set it
-                   as a river, no more need to look around it. */
-                if(numngb<8)
-                  clab[*ind]=SEGMENTRIVER;
-                else
-                  {
-                    /* Begin looking into the neighbours of this pixel. */
-                    nf=(n=ngb)+numngb;
-                    do
-                      {
-                        /* If this neighbour has not been labeled yet
-                           and has an equal flux, add it to the queue
-                           to expand the studied region.*/
-                        nlab=clab[*n];
-                        if( nlab == SEGMENTINIT && arr[*n] == arr[*pind] )
-                          {
-                            clab[*n]=SEGMENTTMPCHECK;
-                            gal_linkedlist_add_to_sll(&cleanup, *n);
-                            gal_linkedlist_add_to_sll(&Q, *n);
-                          }
-                        /* If this neighbour has a positive nlab, it
-                           means that it belongs to another object, so
-                           if n1 has not been set for the whole region
-                           put this label equal to n1. If n1 has been
-                           set and is different from `nlab' then this
-                           whole equal flux region should be a wide
-                           river because it is connecting two
-                           connected regions.*/
-                        else if (nlab>0)
-                          {
-                            if(n1==0)
-                              n1=nlab;
-                            else if(nlab!=n1)
-                              n1=SEGMENTRIVER;
-                          }
-                        /* If this neigbour has a label of zero, then
-                           we are on the edge of the region. When
-                           over-segmenting the noise and the
-                           detections, clab is zero for the parts of
-                           the image that we are not interested in
-                           (detections and noise respectively). */
-                        else if(nlab==0)
-                          clab[*ind]=SEGMENTRIVER;
-                      }
-                    while(++n<nf);
-                  }
-              }
-
-            /* Set the label that is to be given to this equal flux
-               region. If n1 was set to any value, then that label
-               should be used for the whole region. Otherwise, this is
-               a new label, see the case for a non-flat region. */
-            if(n1)
-              rlab = n1;
-            else
-              {
-                rlab = curlab++;
-                if( ctp->topinds)
-                  ctp->topinds[rlab]=*pind;
-              }
-
-            /* Give the same label to the whole connected equal flux
-               region, except those that might have been on the side
-               of the image and were a river pixel. */
-            while(cleanup!=NULL)
-              {
-                gal_linkedlist_pop_from_sll(&cleanup, &pix);
-                /* If it was on the sides of the image, it has been
-                   changed to a river pixel. */
-                if(clab[pix]==SEGMENTTMPCHECK)
-                  clab[pix]=rlab;
-              }
-          }
-        /* The flux of this pixel is not the same as the next sorted
-           flux, so simply find the label for this object. */
-        else
-          {
-            /* Check if the pixel is on the side of the image (for
-               detections) or mesh box (for noise).*/
-            if(*pind/is1==x0 || *pind%is1==y0
-               || *pind/is1==x1-1 || *pind%is1==y1-1)
-              n1=SEGMENTRIVER;
-            else
-              {
-                /* Set the first neighbour's label to zero. */
-                n1=0;
-                if(Q!=NULL || cleanup!=NULL)
-                  error(EXIT_FAILURE, 0, "a bug! Please contact us at %s "
-                        "so we can fix this problem. In oversegment "
-                        "(clumps.c) Q and cleanup should be NULL but while "
-                        "checking the equal flux regions they aren't",
-                        PACKAGE_BUGREPORT);
-
-                /* Go over all the 8 neighbors of this pixel and see
-                   if all the neighbors that have a non-negative value
-                   belong to one label or not. If the pixel is
-                   neighboured by more than one label, set it as a
-                   river pixel. Also if it is touching a zero valued
-                   pixel (which does not belong to this object), set
-                   it as a river pixel.
-
-                   relngb was defined in ui.c: it keeps the relative
-                   indexs of the neighbors of a pixel.*/
-                rnf=(rn=relngb)+8;
-                do
-                  {
-                    ng=*pind+*rn;
-                    nlab=clab[ng];
-                    if(nlab>0)
-                      {
-                        if(n1==0) n1=nlab;
-                        else if(nlab!=n1)
-                          {
-                            n1=SEGMENTRIVER;
-                            break;
-                          }
-                      }
-                    else if(nlab==0)
-                      {
-                        n1=SEGMENTRIVER;
-                        break;
-                      }
-                  }
-                while(++rn<rnf);
-              }
-
-            /* Either assign a new label to this pixel, or give it the
-               one of its neighbors. If n1 equals zero, then it is a
-               new peak, and a new label should be created.  But if
-               n1!=0, it is either a river pixel (has more than one
-               labeled neighbor and has been set to SEGMENTRIVER) or
-               all its neighbors have the same label. In both such
-               cases, rlab should be set to n1.*/
-            if(n1)
-              rlab = n1;
-            else
-              {
-                rlab = curlab++;
-                if( ctp->topinds )
-                  ctp->topinds[rlab]=*pind;
-              }
-
-            /* Put the found label in the pixel. */
-            clab[ *pind ] = rlab;
-          }
-      }
-  while(++pind<indf);
-
-  ctp->numclumps=curlab;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*************            Grow clumps            ******************/
-/******************************************************************/
-/* Grow the true clumps in a detection. Note that unlike before, were
-   river pixels would get a separate label for them selves, here, they
-   don't, they just get set back to SEGMENTINIT. This is because the
-   some of the pixels that lie immediately between two labeled regions
-   might not be in the blankinds array (they were below the
-   threshold). So we have to find river pixels later on after the
-   growth is done independently. */
-void
-growclumps(struct clumpsthreadparams *ctp, int withrivers)
-{
-  struct noisechiselparams *p=ctp->p;
-
-  long n1, *olab=p->olab;
-  size_t *ind, *indf, thisround, numngb;
-  size_t *n, *nf, numblanks=ctp->numblanks;
-  size_t ngb[8], is0=p->lmp.s0, is1=p->lmp.s1;
-
-  /* It might happen that the growth threshold is larger than any of
-     the non-clump pixels. So, if the number of blanks is zero, just
-     leave this function. */
-  if(numblanks==0) return;
-
-
-  /* The basic idea is this: after growing, not all the blank pixels
-     are necessarily filled, for example the pixels might belong to
-     two regions above the growth threshold. So the pixels in between
-     them (which are below the threshold will not ever be able to get
-     a label). Therefore, the safest way we can terminate the loop of
-     growing the objects is to stop it when the number of pixels left
-     to fill in this round (thisround) equals the number of blanks.
-
-     To start the loop, we set thisround=numblanks+1. Note that
-     immediately after the loop has started, thisround is set to
-     numblanks, so we will not be reading an un-initialized element.
-  */
-  thisround=numblanks+1;
-  while(thisround>numblanks)
-    {
-      /* "thisround" will keep the number of pixels to be inspected in
-         this round. "numblanks" will count the number of pixels left
-         without an index by the end of this round. Since numblack
-         comes from the previous loop (or outside for the first loop)
-         it has to be saved in "thisround" to begin counting a
-         fresh. */
-      thisround=numblanks;
-      numblanks=0;
-
-      /* Go over all the available indexs to fill: */
-      indf = ( ind=ctp->blankinds ) + thisround;
-      do
-        {
-          /* We begin by assuming the neighbor label is zero (meaning
-             that no neighbor actually exists!) */
-          n1=0;
-
-          /* Check the 4 connected neighbors of the pixel: */
-          GAL_NEIGHBORS_FILL_4_ALLIMG;
-          nf=(n=ngb)+numngb;
-          do
-            if( olab[*n]>0 )                 /* This neighbor is labeled. */
-            {
-              if(n1)           /* A previous neighboring label was found. */
-                {
-                  if(n1!=olab[*n])      /* This neighbor has a new label. */
-                    {              /* So it should be set to SEGMENTINIT. */
-                      n1=SEGMENTINIT;     /* IMPORTANT: not SEGMENTRIVER. */
-                      break;                   /* See explanations above. */
-                    }
-                }
-              else              /* This is the first labeled     */
-                {               /* neighbor that is found.       */
-                  n1=olab[*n];
-                  if(!withrivers) break;
-                }
-            }
-          while(++n<nf);
-
-          /* The loop above finishes with three possibilities:
-               n1==0            --> No labeled neighbor was found.
-               n1==SEGMENTINIT  --> It is connecting two labeled regions.
-               n1>0             --> It only has one neighbouring label.*/
-          if(n1==0)                   /* First condition above. */
-            ctp->blankinds[numblanks++]=*ind;
-          else                        /* Last two conditions above. */
-            olab[*ind]=n1;
-        }
-      while(++ind<indf);
-    }
-
-  ctp->numblanks=numblanks;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*************             Clump S/N             ******************/
-/******************************************************************/
-/* In this function we want to find the general information for each
-   clump in an over-segmented labeled array. The signal in each clump
-   is the average signal inside it subtracted by the average signal in
-   the river pixels around it. So this function will go over all the
-   pixels in the object (already found in deblendclumps()) and add
-   them appropriately.
-
-   The output is an array of size numseg*INFOTABCOLS. INFOTABCOLS=4. The
-   columns are:
-   0: Average signal (flux) in clump.
-   1: Number of pixels in clump.
-   2: Average signal (flux) around clump.
-   3: Number of pixels around clump.
-   4: Standard deviation on flux weighted center of clump.
-*/
-void
-getclumpinfo(struct clumpsthreadparams *ctp, double **outclumpinfo)
-{
-  struct noisechiselparams *p=ctp->p;
-  struct gal_mesh_params *smp=&p->smp;
-
-  double *xys, *clumpinfo;
-  float *img=p->img, *smpstd=smp->garray2;
-  size_t lab, is0=p->lmp.s0, is1=p->lmp.s1;
-  long *clab=p->clab, wngb[WNGBSIZE], ngblab;
-  size_t x0=ctp->x0, y0=ctp->y0, x1=ctp->x1, y1=ctp->y1;
-  size_t i=0, ii=0, row, *n, *nf, ngb[8], *ind, *indf, numngb;
-
-  /* Just make sure that the box size is not only around one pixel! */
-  if(x1-x0<=1 || y1-y0<=1)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can find "
-          "and fix the problem in clumpinfo (clumps.c). For some reason, "
-          "the specified input region is %zu by %zu wide",
-          PACKAGE_BUGREPORT, y1-y0, x1-x0);
-
-  /* Allocate the clump information array. */
-  errno=0;
-  clumpinfo=calloc(ctp->numclumps*INFOTABCOLS, sizeof *clumpinfo);
-  if(clumpinfo==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for clumpinfo in getclumpinfo "
-          "(clumps.c)", ctp->numclumps*INFOTABCOLS*sizeof *clumpinfo);
-  *outclumpinfo=clumpinfo;
-
-  /* If the image is sky subtracted, we will need the light weighted
-     center of each clump for finding the error in measuring the sky
-     (through the smp->garray2).
-
-     Since we are also segmenting the undetected regions, negative
-     pixel values are common and they will mess up the flux weighted
-     center (since all the weights have to be positive). So the xys
-     array has three columns: the first is the total flux calculated
-     from the positive pixels. The second is the x axis center and the
-     third is the y axis center.
-  */
-  if(p->skysubtracted)
-    {
-      errno=0; xys=calloc(3*ctp->numclumps, sizeof *xys);
-      if(xys==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for xys (clumps.c)",
-              3*ctp->numclumps*sizeof *xys);
-    }
-  else xys=NULL; /* To check if it is needed below. */
-
-  /* Go over all the pixels in this set of pixels and fill in the
-     proper information for each clump. */
-  indf = (ind=ctp->inds) + ctp->area;
-  do
-    if(!isnan(img[*ind]))
-      {
-        if(clab[*ind]==SEGMENTRIVER) /* We are on a river. */
-          {
-            /* Fill in the neighbours arrary for this pixel. If we are
-               working on the mesh grid (the noise), then we only want
-               the neighbors within a region. Otherwise (when working
-               on the detections) we want the neighbors on the full
-               image.*/
-            if(p->b0f1) {GAL_NEIGHBORS_FILL_8_ALLIMG}
-            else        {GAL_NEIGHBORS_FILL_8_REGION}
-
-
-            /* We are on a river pixel. So its value has to be added
-               to the borders of any object it touches. But since it
-               might touch a labeled region more than once, we use
-               wngb to keep track of which label we have already added
-               its value to. `ii` is the number of different labels
-               this river pixel has already been added to. wngb will
-               keep the labels. */
-            ii=0;
-            memset(wngb, 0, sizeof(wngb));
-
-            /* Look into the 8-connected neighbors: */
-            nf=(n=ngb)+numngb;
-            do
-              if( (ngblab=clab[ *n ]) >0)
-                {
-                  /* Go over wngb to see if this river pixel's value
-                     has been added to a segment or not. */
-                  for(i=0;i<ii;++i)
-                    if(wngb[i]==ngblab)
-                      /* It is already present. break out. */
-                      break;
-
-                  if(i==ii) /* This label was not added yet. */
-                    {
-                      clumpinfo[ ngblab*INFOTABCOLS+2 ]+=img[*ind];
-                      ++clumpinfo[ ngblab*INFOTABCOLS+3 ];
-                      wngb[ii]=ngblab;
-                      ++ii;
-                    }
-                }
-            while(++n<nf);
-          }
-        else                    /* We are on a clump. */
-          {
-            lab=clab[*ind];
-            ++clumpinfo[ lab * INFOTABCOLS + 1 ];
-            clumpinfo[ lab * INFOTABCOLS ] += img[*ind];
-            if(p->skysubtracted && img[*ind]>0.0f)
-              {
-                xys[ 3 * lab     ] += img[*ind];
-                xys[ 3 * lab + 1 ] += (*ind/is1) * img[*ind];
-                xys[ 3 * lab + 2 ] += (*ind%is1) * img[*ind];
-              }
-
-          }
-      }
-  while(++ind<indf);
-
-  /* Do the final preparations. All the calculations are only
-     necessary for the clumps that satisfy the minimum area. So there
-     is no need to waste time on the smaller ones. */
-  for(lab=1;lab<ctp->numclumps;++lab)
-    {
-      row=lab*INFOTABCOLS;
-      if(clumpinfo[row+1]>p->segsnminarea)
-        {
-          /* Find the index of the flux weighted center and use it to
-             find the standard deviation for this clump. Note that
-             this is only needed if the input image was already sky
-             subtracted. If it wasn't, then we are not subtracting the
-             sky to worry about its error! The error in a pixel flux
-             measurement is simply its square root. */
-          if(p->skysubtracted)
-            {
-              /* Especially for noise, it might happen that no pixel
-                 within the clump was positive! If so, then the center
-                 cannot be calculated and the clump must not be
-                 used, so just set its area to zero. */
-              if(xys[3*lab]==0.0f)
-                {
-                  clumpinfo[row+1]=0;
-                  continue;
-                }
-              else
-                {
-                  xys[3*lab+1] /= xys[3*lab];
-                  xys[3*lab+2] /= xys[3*lab];
-                  if(p->skysubtracted)
-                      clumpinfo[row+4]=
-                        smpstd[gal_mesh_img_xy_to_mesh_id(smp,xys[3*lab+1],
-                                                          xys[3*lab+2])];
-
-                  /* For a check:
-                  printf("%zu: (%zu, %zu) --> %f\n", lab,
-                         (size_t)(xys[3*lab+2] / clumpinfo[row]) +1,
-                         (size_t)(xys[3*lab+1] / clumpinfo[row]) +1,
-                         clumpinfo[row+4]);
-                  */
-                }
-            }
-
-          /* Convert sum to average. We are doing this after so if a
-             clump should be ignored, control doesn't get to this
-             point. */
-          clumpinfo[row  ] /= clumpinfo[row+1];
-          clumpinfo[row+2] /= clumpinfo[row+3];
-        }
-    }
-
-  /* To check a specific detection (p->b0f1==1) or a noise mesh grid
-     (p->b0f1==0). set ctp->thislabel to the desired label.
-  if(p->b0f1==1 && ctp->thislabel==1)
-    for(i=1;i<ctp->numclumps;++i)
-      printf("%zu: %-10.3f %-5.0f %-10.3f %-5.0f %-10.3f\n", i,
-             clumpinfo[i*INFOTABCOLS], clumpinfo[i*INFOTABCOLS+1],
-             clumpinfo[i*INFOTABCOLS+2], clumpinfo[i*INFOTABCOLS+3],
-             clumpinfo[i*INFOTABCOLS+4]);
-  */
-
-  /* If we are on the noise clumps, then xys is not needed any more.
-     So if it was allocated, fre the space. */
-  if(p->skysubtracted) free(xys);
-}
-
-
-
-
-
-void
-clumpsntable(struct clumpsthreadparams *ctp, float **sntable)
-{
-  struct noisechiselparams *p=ctp->p;
-
-  float *sntab;
-  double *clumpinfo, err;
-  size_t i, ind, row, counter=0;
-  double I, O, Ni, cpscorr=p->cpscorr;
-
-
-  /* Get the information for all the segments. */
-  getclumpinfo(ctp, &clumpinfo);
-
-
-  /* Allocate the signal to noise table. */
-  errno=0;
-  sntab = *sntable = malloc( ctp->numclumps * sizeof *sntab );
-  if(sntab==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for sntab (clumps.c)",
-          ctp->numclumps*sizeof *sntab);
-
-
-  /* Start calculating the Signal to noise ratios. */
-  sntab[0]=0;
-  for(i=1;i<ctp->numclumps;++i)
-    {
-      /* These variables used for easy readability. */
-      row=i*INFOTABCOLS;
-      I  = clumpinfo[ row     ];
-      Ni = clumpinfo[ row + 1 ];
-      O  = clumpinfo[ row + 2 ];
-
-      /* If the inner flux is smaller than the outer flux (happens
-         only in noise cases) or the area is smaller than the minimum
-         area to calculate signal-to-noise, then set the S/N of this
-         segment to zero. */
-      if( Ni>p->segsnminarea && I>O )   /* This is O, not 0 (zero). */
-        {
-          /* If the sky was subtracted then put in the second power of
-             the standard deviation multiplied by two (because we are
-             measuring two fluxs). */
-          err  = ( p->skysubtracted
-                   ? ( 2.0f * clumpinfo[row+4] * clumpinfo[row+4] )
-                   : 0.0f );
-
-          /* Calculate the Signal to noise ratio, if we are on the
-             noise regions, we don't care about the IDs of the clumps
-             anymore, so store the Signal to noise ratios contiguously
-             (for easy sorting and etc). Note that counter will always
-             be smaller and equal to i. */
-          ind = p->b0f1 ? i : counter++;
-          sntab[ind]=( sqrt((float)(Ni)/cpscorr)*(I-O)
-                       / sqrt( (I>0?I:-1*I) + (O>0?O:-1*O) + err ) );
-        }
-      else
-        sntab[i]=0;
-    }
-
-
-  /* If we are dealing with noise, replace the number of clumps with
-     the number of those with a sufficient area and inner flux. */
-  if(p->b0f1==0)
-    ctp->numclumps=counter;
-
-
-  /* To check a specific detection (p->b0f1==1) or a noise mesh grid
-     (p->b0f1==0):
-  if(p->b0f1==1 && ctp->thislabel==151)
-    {
-      for(i=1;i<ctp->numclumps;++i)
-        printf("%zu: %-10.3g %-5.0f %-10.3g(%-5.0f) --> %-10.3g\n", i,
-               clumpinfo[i*INFOTABCOLS], clumpinfo[i*INFOTABCOLS+1],
-               clumpinfo[i*INFOTABCOLS+2], clumpinfo[i*INFOTABCOLS+3],
-               sntab[i]);
-    }
-  */
-  /* Clean up */
-  free(clumpinfo);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*************           S/N threshold           ******************/
-/******************************************************************/
-void *
-clumpsntableonmesh(void *inparams)
-{
-  struct clumpsthreadparams ctp;
-  struct gal_mesh_thread_params *mtp=(struct gal_mesh_thread_params *)inparams;
-  struct gal_mesh_params *mp=mtp->mp;
-  struct noisechiselparams *p=(struct noisechiselparams *)mp->params;
-
-  size_t *mponeforall=mp->oneforall;
-
-  int anyblank;
-  float *sntable;
-  size_t s0, s1, nf, ind, startind, is1=mp->s1;
-  size_t i, *indexs=&mp->indexs[mtp->id*mp->thrdcols];
-
-  /* Set the necessary pointers for the clumpsthreadparams
-     structure. */
-  ctp.p=p;
-  ctp.topinds=NULL;             /* For noise, we don't want topinds. */
-  ctp.inds=&mponeforall[mtp->id*mp->maxs0*mp->maxs1];
-
-  /* Go over all the meshs that are assigned to this thread. */
-  for(i=0;indexs[i]!=GAL_THREADS_NON_THRD_INDEX;++i)
-    {
-      /* Set index of this mesh: */
-      ind=ctp.thislabel=indexs[i];
-
-      /* Find the necessary parameters */
-      startind=mp->start[ind];
-      s0=mp->ts0[mp->types[ind]];
-      s1=mp->ts1[mp->types[ind]];
-      ctp.x1 = (ctp.x0=startind/is1) + s0;
-      ctp.y1 = (ctp.y0=startind%is1) + s1;
-
-
-      /* Check to see if we have enough blank area for getting the
-         background noise statistics. */
-      count_f_b_onregion(p->byt, startind, s0, s1, is1, &nf, &ctp.area,
-                         &anyblank);
-      if( (float)ctp.area < (float)(s0*s1)*p->minbfrac )
-        {
-          p->numclumpsarr[ind]=0;
-          p->sntablearr[ind]=NULL;
-          continue;
-        }
-
-
-      /* We want to find the clumps on the noise, not the signal, the
-         number of noise pixels in this mesh were calculated above
-         (area). Here we want to pull out the indexs of those pixels
-         which is necessary for the over-segmentation. */
-      index_f_b_onregion(p->byt, startind, s0, s1, is1, ctp.inds, 0);
-
-
-      /* Do the over-segmentation and put the number of clumps in
-         ctp.numclumps */
-      oversegment(&ctp);
-
-
-      /* Find the signal to noise of all the clumps. */
-      clumpsntable(&ctp, &sntable);
-
-
-      /* Keep the relevant information for this mesh: */
-      p->sntablearr[ind]=sntable;
-      p->numclumpsarr[ind]=ctp.numclumps;
-    }
-
-  /* Free any allocated space and if multiple threads were used, wait
-     until all other threads finish. */
-  if(mp->numthreads>1)
-    pthread_barrier_wait(&mp->b);
-  return NULL;
-}
-
-
-
-
-
-/* The job of this function is to find the best signal to noise value
-   to use as a threshold to detect real clumps.
-
-   Each thread will find the useful signal to noise values for the
-   meshs that have been assigned to it. It will then store the pointer
-   to the S/N table into the sntablearr array (with the size of the
-   number of meshs). If no clumps could be found in a mesh, then
-   sntablearr[i]=NULL. Otherwise, it points to an array of the useful
-   S/N values in that clump. Note that we don't care about the order
-   of S/N values any more! There is also an accompanying array to keep
-   the number of elements in the final S/N array of each mesh:
-   numclumpsarr.
-
-   Using these two arrays, after all the threads are finished, we can
-   concatenate all the S/N values into one array and send it to the
-   main findsnthresh function in thresh.c.
-*/
-void
-findclumpsn(struct noisechiselparams *p)
-{
-  float *sntable;
-  struct gal_mesh_params *lmp=&p->lmp;
-  size_t i, j, numclumps=0, nmeshi=lmp->nmeshi;
-
-
-  /* Set the convolved image as the basis for sorting the indexs and
-     finding clumps. */
-  gal_qsort_index_arr=p->conv;
-
-
-  /* Allocate the two arrays to keep the number and values of the S/Ns
-     in each mesh. */
-  errno=0; p->numclumpsarr=malloc(nmeshi*sizeof*p->numclumpsarr);
-  if(p->numclumpsarr==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->numclumpsarr in "
-          "findclumpsn (clumps.c)", nmeshi*sizeof*p->numclumpsarr);
-  errno=0; p->sntablearr=malloc(nmeshi*sizeof*p->sntablearr);
-  if(p->sntablearr==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->sntablearr in "
-          "findclumpsn (clumps.c)", nmeshi*sizeof*p->sntablearr);
-
-
-  /* Find the clump Signal to noise ratio on successful meshs then on
-     all the meshs. findsnthreshongrid is in detection.c. */
-  gal_mesh_operate_on_mesh(lmp, clumpsntableonmesh, sizeof(size_t), 0, 0);
-
-
-  /* Find the total number of useful clumps and allocate sntable.  */
-  for(i=0;i<nmeshi;++i) numclumps+=p->numclumpsarr[i];
-  errno=0; sntable=malloc(numclumps*sizeof*sntable);
-  if(sntable==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for sntable in "
-          "findclumpsn (clumps.c)", numclumps*sizeof*sntable);
-
-
-  /* Fill in the sntable array: */
-  numclumps=0;
-  for(i=0;i<nmeshi;++i)
-    for(j=0;j<p->numclumpsarr[i];++j)
-      sntable[numclumps++]=p->sntablearr[i][j];
-
-
-  /* Set the clump signal to noise value: */
-  snthresh(p, sntable, numclumps, 1);
-
-
-  /* Clean up. In clumpsntableonmesh we put an allocated array in each
-     member of p->sntablearr[i]. */
-  for(i=0;i<nmeshi;++i)
-    free(p->sntablearr[i]);
-  free(p->numclumpsarr);
-  free(p->sntablearr);
-  free(sntable);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*************        Remove false clumps        ******************/
-/******************************************************************/
-/* Given the signal to noise of each segment (in sntable), and a
-   threshold for an acceptable S/N (in `p`), remove those segments
-   that don't satisfy the criteria and correct the number of clumps. */
-void
-removefalseclumps(struct clumpsthreadparams *ctp, float *sntable)
-{
-  struct gal_mesh_params *lmp=&ctp->p->lmp;
-
-  long *newlabs, *clab=ctp->p->clab;
-  size_t *n, *nf, is0=lmp->s0, is1=lmp->s1;
-  size_t i, curlab=1, *ind, *indf, ngb[8], numngb;
-
-  /* Allocate space for the new labels array. */
-  errno=0; newlabs=malloc(ctp->numclumps*sizeof *newlabs);
-  if(newlabs==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newlabs in "
-          "removefalsedetections (clumps.c)",
-          ctp->numclumps*sizeof *newlabs);
-
-  /* We want the removed regions to become SEGMENTINIT. */
-  gal_array_long_init(newlabs, ctp->numclumps, SEGMENTINIT);
-
-  /* Set the new labels: */
-  if(ctp->p->keepmaxnearriver)
-    {       /* `{' because We don't want to confuse the `else' below. */
-      for(i=1;i<ctp->numclumps;++i)
-        if( sntable[i] > ctp->p->clumpsn )
-          newlabs[i]=curlab++;
-    }
-  else
-    for(i=1;i<ctp->numclumps;++i)
-      if(ctp->topinds[i]!=NOTOPIND)
-        {
-          /* Check to see if the brightest pixel in this clump is
-             touching a river or not. */
-          ind=&ctp->topinds[i];
-          GAL_NEIGHBORS_FILL_8_ALLIMG;
-          nf=(n=ngb)+numngb;
-          do if(clab[*n++]==SEGMENTRIVER) break; while(n<nf);
-
-          /* If the brightest pixel of this clump was not touching a
-             river and its Signal to noise ratio is larger than the
-             threshold, then give it a new label.*/
-          if( n==nf  &&  sntable[i] > ctp->p->clumpsn )
-            newlabs[i]=curlab++;
-        }
-  ctp->numclumps=curlab;
-
-  /* Change the values of the false clumps. Note that the labels are
-     either SEGMENTRIVER or a label. */
-  indf = (ind=ctp->inds) + ctp->area;
-  do
-    {
-      if(clab[*ind]>0)
-        clab[*ind] = newlabs[ clab[*ind] ];
-      else
-        clab[*ind] = SEGMENTINIT;
-    }
-  while(++ind<indf);
-
-  /* Cleanup. */
-  free(newlabs);
-}
diff --git a/bin/noisechisel/clumps.h b/bin/noisechisel/clumps.h
deleted file mode 100644
index 4306122..0000000
--- a/bin/noisechisel/clumps.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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/>.
-**********************************************************************/
-#ifndef CLUMPS_H
-#define CLUMPS_H
-
-
-struct clumpsthreadparams
-{
-  /* Main NoiseChisel parameters: */
-  struct noisechiselparams *p;  /* Main NoiseChisel structure. */
-
-  /* Threads (only for detections, the noise uses the mesh threads.) */
-  size_t       thislabel; /* The initial label of this detection.        */
-  size_t              id; /* ID of this thread.                          */
-  size_t       *allareas; /* Array keeping the areas of all detections.  */
-  size_t    **alllabinds; /* Array of pointers to the indexs of all dets.*/
-  size_t         *indexs; /* 2D array of initial indexs for each thread. */
-  pthread_barrier_t   *b; /* pthreads barrier for running threads.       */
-  pthread_mutex_t *totalnummtx; /* Mutex to change the total numbers.    */
-
-  /* Box coordinates for this thread: */
-  size_t              x0; /* Bottom left corner on x axis.               */
-  size_t              y0; /* Bottom left corner on y axis.               */
-  size_t              x1; /* Top right corner on x axis.                 */
-  size_t              y1; /* Top right corner on y axis.                 */
-
-  /* Other basic parameters: */
-  float              std; /* Standard deviation on this detection.       */
-  size_t        *topinds; /* Indexs of the top flux in each clump.       */
-  size_t       numclumps; /* Number of clumps in this set of pixels.     */
-  size_t      numobjects; /* Number of objects in this detected region.  */
-  size_t            area; /* Area of the current region for this thread. */
-  size_t           *inds; /* Indexs of the current region for this thrd. */
-  size_t      *blankinds; /* Array of pixels which should be grown.      */
-  size_t       numblanks; /* Number of blank pixels.                     */
-  long     *segtoobjlabs; /* Convert from grown segments to object label.*/
-  long firstavailablelab; /* First free label over the full image.       */
-};
-
-
-/* Important sizes and values (do not change). */
-#define SEGMENTNOOBJ     0
-#define SEGMENTMASKED   -4
-#define SEGMENTTMPCHECK -3
-#define SEGMENTINIT     -2
-#define SEGMENTRIVER    -1
-#define INFOTABCOLS      5
-#define WNGBSIZE        20
-#define NOTOPIND        (size_t)(-1)
-
-void
-oversegment(struct clumpsthreadparams *ctp);
-
-void
-growclumps(struct clumpsthreadparams *ctp, int withrivers);
-
-void
-clumpsntable(struct clumpsthreadparams *ctp, float **sntable);
-
-void
-findclumpsn(struct noisechiselparams *p);
-
-void
-removefalseclumps(struct clumpsthreadparams *ctp, float *sntable);
-
-#endif
diff --git a/bin/noisechisel/detection.c b/bin/noisechisel/detection.c
index 4ade95a..404cd3b 100644
--- a/bin/noisechisel/detection.c
+++ b/bin/noisechisel/detection.c
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -23,39 +23,17 @@ 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 <gnuastro/data.h>
 #include <gnuastro/fits.h>
-#include <gnuastro/mesh.h>
-#include <gnuastro/array.h>
-#include <gnuastro/qsort.h>
-#include <gnuastro/threads.h>
-#include <gnuastro/statistics.h>
+#include <gnuastro/binary.h>
 
 #include <timing.h>
-#include <checkset.h>
 
 #include "main.h"
 
-#include "sky.h"
-#include "label.h"
-#include "thresh.h"
-#include "binary.h"
-#include "detection.h"
-
-
-
-
-
-
-
-
-
-
-
+#include "ui.h"
+#include "threshold.h"
 
 
 
@@ -65,703 +43,98 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
  ************           Initial detection            ************
  ****************************************************************/
 void
-initialdetection(struct noisechiselparams *p)
-{
-  int verb=p->cp.verb;
-  size_t i, s0=p->smp.s0, s1=p->smp.s1;
-  char *detectionname=p->detectionname;
-  char report[GAL_TIMING_VERB_MSG_LENGTHS_2_V];
-
-  /* Find the threshold and apply it, if there are blank pixels in the
-     image, set those pixels to the binary blank value too: */
-  findapplyqthreshold(p);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "Thresholded", BYTE_IMG,
-                           p->byt, s0, s1, p->anyblank, p->wcs, NULL,
-                           SPACK_STRING);
-  if(verb)
-    {
-      sprintf(report, "%.2f quantile threshold found and applied.",
-              p->qthresh);
-      gal_timing_report(NULL, report, 2);
-    }
-
-
-
-
-  /* Erode the thresholded image, then convert the pixels that should not
-     have been eroded back to 1 so the next step (opening) can be
-     completely ignorant of them. */
-  if(p->erodengb==4)
-    for(i=0;i<p->erode;++i)
-      dilate0_erode1_4con(p->byt, s0, s1, 1);
-  else
-    for(i=0;i<p->erode;++i)
-      dilate0_erode1_8con(p->byt, s0, s1, 1);
-  gal_array_uchar_replace(p->byt, s0*s1, BINARYNOOP, 1);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "Eroded", BYTE_IMG, p->byt,
-                           s0, s1, p->anyblank, p->wcs, NULL,
-                           SPACK_STRING);
-  if(verb)
-    {
-      sprintf(report, "Eroded %zu times (%s connectivity).",
-              p->erode, p->erodengb==4 ? "4" : "8");
-      gal_timing_report(NULL, report, 2);
-    }
-
-
-
-
-  /* Do the opening: */
-  opening(p->byt, s0, s1, p->opening, p->openingngb);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "Opened", BYTE_IMG, p->byt,
-                           s0, s1, p->anyblank, p->wcs, NULL,
-                           SPACK_STRING);
-  if(verb)
-    {
-      sprintf(report, "Opened (depth: %zu, %s connectivity).",
-              p->opening, p->openingngb==4 ? "4" : "8");
-      gal_timing_report(NULL, report, 2);
-    }
-
-
-
-
-  /* Label the connected regions. Note that p->olab was allocated in
-     ui.c and will be freed there. */
-  p->numobjects=BF_concmp(p->byt, p->olab, s0, s1, p->anyblank, 4);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "Labeled", LONG_IMG, p->olab,
-                           s0, s1, p->anyblank, p->wcs, NULL,
-                           SPACK_STRING);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/****************************************************************
- *********    Signal to noise ratio calculation      ************
- ****************************************************************/
-/* Calculate the Signal to noise ratio for all the labels in p->clab
-   which is keeping all the pseudo detections' labels.  However, the
-   array keeping the labels of each object is only over the mesh under
-   consideration. */
-void
-detlabelsn(struct noisechiselparams *p, size_t *numlabs, float **outsntable)
+detection_initial(struct noisechiselparams *p)
 {
-  float *imgss=p->imgss;
-  struct gal_mesh_params *smp=&p->smp;
-  double *brightnesses, err, *xys;
-  float *f, *ff, ave, *sntable, cpscorr=p->cpscorr;
-  size_t i, ind, xyscol=3, is1=p->smp.s1, counter=0;
-  unsigned char *coversdet=NULL, b0f1=p->b0f1, *b=p->byt;
-  long *areas, *lab=p->clab, *lf, detsnminarea=p->detsnminarea;
-
-
-  /* Allocate the necessary arrays to keep the label information: */
-  errno=0; sntable=*outsntable=calloc(*numlabs, sizeof *sntable);
-  if(sntable==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for sntable in detlabelsn "
-          "(detection.c)", *numlabs*sizeof *sntable);
-  errno=0; brightnesses=calloc(*numlabs, sizeof *brightnesses);
-  if(brightnesses==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for brightnesses in detlabelsn "
-          "(detection.c)", *numlabs*sizeof *brightnesses);
-  errno=0; xys=calloc(*numlabs*xyscol, sizeof *xys);
-  if(xys==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for xys in detlabelsn "
-          "(detection.c)", *numlabs*sizeof *xys);
-  errno=0; areas=calloc(*numlabs, sizeof *areas);
-  if(areas==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for areas in detlabelsn "
-          "(detection.c)", *numlabs*sizeof *areas);
-  if(b0f1==0)
-    {
-      errno=0; coversdet=calloc(*numlabs, sizeof *coversdet);
-      if(coversdet==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for coversdet in detlabelsn "
-              "(detection.c)", *numlabs*sizeof *coversdet);
-    }
-
-
-  /* Go over the area and fill in the necessary information for
-     calculating the Signal to noise ratio. */
-  ff = (f=imgss) + p->smp.s0*p->smp.s1;
-  do
-    {
-      /* See label.h for this macro. It checks speciie*/
-      if(ISINDEXABLELABEL)
-        {
-          /* This test is done first so if the sky region
-             pseudo-detection lies over a detected object it doesn't
-             waste our time for the next calculations. */
-          if(b0f1==0)
-            {
-              if(coversdet[*lab]) {++lab; ++b; continue;}
-              else if(*b==1)
-                {coversdet[*lab]=1; areas[*lab]=0; ++lab; ++b; continue;}
-            }
-
-          if(isnan(*f))
-            error(EXIT_FAILURE, 0, "*f was nan");
-
-          ++areas[*lab];
-          brightnesses[*lab]     += *f;
-          if(f-imgss>0)
-            {
-              xys[*lab*xyscol+2] += f-imgss;
-              xys[*lab*xyscol  ] += (double)((f-imgss)/is1) * *f;
-              xys[*lab*xyscol+1] += (double)((f-imgss)%is1) * *f;
-            }
-        }
-      ++lab;
-      if(b0f1==0) ++b;
-    }
-  while(++f<ff);
-
-
-  /* If the user wants to see the steps (on the background), remove
-     all the pseudo-detections that will not be used in the histogram
-     calcluation. */
-  if(p->detectionname && b0f1==0)
-    {
-      b=p->dbyt;
-      lf=(lab=p->clab)+p->smp.s0*p->smp.s1;
-      do
-        {
-          if( ISINDEXABLELABEL
-              && (areas[*lab]<detsnminarea || brightnesses[*lab]<0) )
-              *b=0;
-          ++b;
-        }
-      while(++lab<lf);
-      gal_fits_array_to_file(p->detectionname, "For S/N", BYTE_IMG,
-                             p->dbyt, p->smp.s0, p->smp.s1,
-                             p->anyblank, p->wcs, NULL, SPACK_STRING);
-    }
-
-
-
-  /* calculate the signal to noise for successful detections: */
-  for(i=1;i<*numlabs;++i)
-    {
-      ave=brightnesses[i]/areas[i];
-      if(areas[i]>detsnminarea && ave>0.0f && xys[i*xyscol+2]>0.0f)
-        {
-          /* Find the flux weighted center of this object in each
-             dimension to find the mesh it belongs to and get the
-             standard deviation at this point. Note that the standard
-             deviation on the grid was stored in smp->garray2. The error
-             should then be taken to the power of two and if the sky is
-             subtracted, a 2 should be multiplied to it.*/
-          err = smp->garray2[
-                 gal_mesh_img_xy_to_mesh_id(smp,
-                                    xys[i*xyscol]/xys[i*xyscol+2],
-                                    xys[i*xyscol+1]/xys[i*xyscol+2]) ];
-          err *= p->skysubtracted ? err : 2.0f*err;
-
-          /* Set the index in the sntable to store the Signal to noise
-             ratio. When we are dealing with the noise, we only want the
-             non-zero signal to noise values, so we will just use a
-             counter. But for initial detections, it is very important
-             that their Signal to noise ratio be placed in the same
-             index as their label. */
-          ind = p->b0f1 ? i : counter++;
-          sntable[ind] = ( sqrt( (float)(areas[i])/cpscorr )
-                           * ave / sqrt(ave+err) );
-        }
-    }
-
+  char *msg;
+  uint8_t *b, *bf;
+  struct timeval t0, t1;
 
-  /* In background mode, set the number of labels to the number of
-     acceptable S/N values measured. */
-  if(p->b0f1==0) *numlabs=counter;
 
 
-  /* For a check. IMPORTANT NOTE: in background mode, the sntable is
-     not ordered like the areas, brightnesses and coversdet
-     arrays. Since indexes are irrelevant for this mode, they are just
-     put contigusly in memory for the next step.
-  if(b0f1)
+  /* Get the starting time. */
+  if(!p->cp.quiet)
     {
-      for(i=0;i<*numlabs;++i)
-        printf("%zu: %-10ld %-10.3f %-10.3f\n",
-               i, areas[i], brightnesses[i], sntable[i]);
+      gal_timing_report(NULL, "Starting to find initial detections.", 1);
+      gettimeofday(&t0, NULL);
     }
-  */
-
-  /* Clean up */
-  free(xys);
-  free(areas);
-  free(brightnesses);
-  if(b0f1==0) free(coversdet);
-}
-
-
-
-
-
-/* Apply the S/N threshold on the pseudo-detections. */
-void
-applydetsn(struct noisechiselparams *p, float *sntable, size_t numpseudo)
-{
-  size_t i, curlab=1;
-  unsigned char *b=p->dbyt;
-  long *newlabs, *lab, *lf, *clab=p->clab;
-
 
-  errno=0; newlabs=calloc(numpseudo, sizeof *newlabs);
-  if(newlabs==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for numlabs in "
-          "removefalsedetections (detections.c)",
-          numpseudo*sizeof *newlabs);
-
-
-  for(i=1;i<numpseudo;++i)
-    if(sntable[i] > p->detsn)
-      newlabs[i]=curlab++;
-
-
-  lf= (lab=clab) + p->smp.s0*p->smp.s1;
-  do
-    {
-      if(*lab!=GAL_DATA_BLANK_LONG)
-        *b = newlabs[*lab] > 0;
-      ++b;
-    }
-  while(++lab<lf);
 
 
+  /* Find and apply the threshold on the input. */
+  threshold_quantile_find_apply(p);
   if(p->detectionname)
-    gal_fits_array_to_file(p->detectionname, "True pseudo-detections",
-                           BYTE_IMG, p->dbyt, p->smp.s0, p->smp.s1,
-                           p->anyblank, p->wcs, NULL, SPACK_STRING);
-
-  free(newlabs);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/****************************************************************
- ************        Remove false detections         ************
- ****************************************************************/
-/* The p->byt points to the array keeping the positions of initial
-   detections. p->dbyt points to the array keeping the thresholded
-   values for removal of false detections. We want to copy the above
-   threshold (with value 1) parts of p->dbyt to `out' which are either
-   foreground or background in p->byt (depending on if the process is
-   done over the detections or over the noise). */
-void
-bytpartfromlarge(struct noisechiselparams *p, unsigned char *out,
-                 size_t start, size_t s0, size_t s1)
-{
-  size_t r=0, is1=p->smp.s1;
-  unsigned char *b, *d, *bf, b0f1=p->b0f1;
-
-  do
     {
-      d = p->dbyt + start + r*is1;
-      bf = ( b = p->byt + start + r++ * is1 ) + s1;
-      do
-        {
-          *out++ = *b==b0f1 ? *d : (*b==GAL_DATA_BLANK_UCHAR
-                                    ? GAL_DATA_BLANK_UCHAR : 0);
-          ++d;
-        }
-      while(++b<bf);
+      p->binary->name="THRESHOLDED";
+      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_STRING);
+      p->binary->name=NULL;
     }
-  while(r<s0);
-}
-
 
 
 
-
-/* Copy a region of a smaller array into a larger array. *in is the
-   smaller array and *out is the larger array. */
-void
-bytparttolarge(struct noisechiselparams *p, unsigned char *in,
-               size_t start, size_t s0, size_t s1)
-{
-  unsigned char *d, *df;
-  size_t r=0, is1=p->smp.s1;
-
-  do
+  /* Erode the image. */
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
+  gal_binary_erode(p->binary, p->erode, p->erodengb, 1);
+  if(!p->cp.quiet)
     {
-      df = ( d = p->dbyt + start + r++ * is1 ) + s1;
-      do *d=*in++; while(++d<df);
+      asprintf(&msg, "Eroded %zu time%s (%zu-connectivity).", p->erode,
+               p->erode>1?"s":"", p->erodengb);
+      gal_timing_report(&t1, msg, 2);
     }
-  while(r<s0);
-}
-
-
-
-
-
-
-void*
-detectpseudos(void *inparams)
-{
-  struct gal_mesh_thread_params *mtp=(struct gal_mesh_thread_params *)inparams;
-  struct gal_mesh_params *mp=mtp->mp;
-  struct noisechiselparams *p=(struct noisechiselparams *)mp->params;
-
-  unsigned char *mponeforall=mp->oneforall;
-  unsigned char *thisbyt=&mponeforall[mtp->id*mp->maxs0*mp->maxs1];
-
-  int anyblank;
-  size_t i, s0, s1;
-  unsigned char *b, *bf;
-  size_t ind, startind;
-  char *detectionname=p->detectionname;
-  size_t *indexs=&mp->indexs[mtp->id*mp->thrdcols];
-
-
-  /* Do the job for each mesh: */
-  for(i=0;indexs[i]!=GAL_THREADS_NON_THRD_INDEX;++i)
+  if(p->detectionname)
     {
-      /* Set the necesary parameters: */
-      ind=indexs[i];
-      s0=mp->ts0[mp->types[ind]];
-      s1=mp->ts1[mp->types[ind]];
-      startind=mp->start[ind];
-      anyblank=0;
-
-      /* Copy this mesh into a separate array. In the meantime, only
-         bring in the desired pixels. If the user wanted to see the
-         steps, then save the result to the p->dbyt and come leave the
-         work for this mesh if this is the first step. */
-      bytpartfromlarge(p, thisbyt, startind, s0, s1);
-      if(detectionname && p->stepnum==1)
-        { bytparttolarge(p, thisbyt, startind, s0, s1); continue; }
-
-
-      /* If there were NaN pixels in the image, make sure if this
-         mesh has any or not. */
-      if(p->anyblank)
-        {
-          bf=(b=thisbyt)+s0*s1;
-          do if(*b++==GAL_DATA_BLANK_UCHAR) { anyblank=1; break; }
-          while(b<bf);
-        }
-
-
-      /* Fill the bounded holes. */
-      fillboundedholes(thisbyt, s0, s1, anyblank);
-      if(detectionname && p->stepnum==2)
-        { bytparttolarge(p, thisbyt, startind, s0, s1); continue; }
-
-      /* Open the image once: */
-      opening(thisbyt, s0, s1, 1, 4);
-
-
-      /* Put this region back into p->dbyte. */
-      bytparttolarge(p, thisbyt, startind, s0, s1);
+      p->binary->name="ERODED";
+      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_STRING);
+      p->binary->name=NULL;
     }
 
 
-  /* If multiple threads were used, wait until all other threads
-     finish. */
-  if(mp->numthreads>1)
-    pthread_barrier_wait(&mp->b);
 
+  /* Correct the no-erode values. */
+  bf=(b=p->binary->array)+p->binary->size; do *b = *b>0; while(++b<bf);
 
-  return NULL;
-}
 
 
-
-
-
-/* Doing object detection is done separately on each mesh both for the
-   first part of finding the SN limit and the second part of applying
-   it and removing false detections. Therefore, if the user asks to
-   view the steps, the mesh process has to be stopped at differnt
-   times for all the meshs and re-done for each step. This function
-   does that job.
-
-   Here we temporarily (clab will be cleaned when it is needed)
-   operate on the p->clab array which is finally used to keep the
-   clump labels.
-*/
-void
-detsnthresh(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *lmp=&p->lmp;
-
-  float *sntable;
-  static int b0f1;
-  char *extname=NULL;
-  unsigned char *tmp, *originaldbyt;
-  size_t numpseudo, s0=lmp->s0, s1=lmp->s1;
-
-  /* General preparations: */
-  p->b0f1 = b0f1++;
-
-  /* All the operations below happen on p->dbyt, but we need it two
-     times (once for the sky region and once for the detected
-     region). So the first time we operate on it,  */
-  if(p->b0f1==0)
-    gal_array_uchar_copy(p->dbyt, s0*s1, &originaldbyt);
-
-  /* Find the psudo-detections: */
-  if(p->detectionname)
+  /* Do the opening. */
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
+  gal_binary_open(p->binary, p->opening, p->openingngb, 1);
+  if(!p->cp.quiet)
     {
-      p->stepnum=1;
-      /* Backup of p->dbyt in tmp */
-      gal_array_uchar_copy(p->dbyt, s0*s1, &tmp);
-      while(p->stepnum<4)
-        {
-          free(p->dbyt);    /* Free the old, p->dbyt, put the original */
-          gal_array_uchar_copy(tmp, s0*s1, &p->dbyt);
-          gal_mesh_operate_on_mesh(lmp, detectpseudos,
-                                   sizeof(unsigned char), 0, 0);
-          switch(p->stepnum)
-            {
-            case 1:
-              extname = p->b0f1 ? "ThresholdDetections" : "ThresholdNoise";
-              break;
-            case 2:
-              extname="HolesFilled"; break;
-            case 3:
-              extname="Opened"; break;
-            default:
-              error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we "
-                    "can find the solution. For some reason, the value to "
-                    "p->stepnum (%d) is not recognized in detsnthresh "
-                    "(detection.c)", PACKAGE_BUGREPORT, p->stepnum);
-            }
-          gal_fits_array_to_file(p->detectionname, extname, BYTE_IMG,
-                                 p->dbyt, s0, s1, p->anyblank, p->wcs,
-                                 NULL, SPACK_STRING);
-          ++p->stepnum;
-        }
-      free(tmp);
+      asprintf(&msg, "Opened (depth: %zu, %s connectivity).",
+              p->opening, p->openingngb==4 ? "4" : "8");
+      gal_timing_report(&t1, msg, 2);
     }
-  else
-    gal_mesh_operate_on_mesh(lmp, detectpseudos,
-                             sizeof(unsigned char), 0, 0);
-
-
-  /* Find the connected components and the signal to noise ratio of
-     all the detections. Note that when dealing with the background
-     pixels in p->byt, the order of sntable is no longer valid, since
-     we don't care any more, we just want their sorted values for the
-     quantile. */
-  numpseudo=BF_concmp(p->dbyt, p->clab, s0, s1, p->anyblank, 4);
   if(p->detectionname)
-    gal_fits_array_to_file(p->detectionname, "Labeled", LONG_IMG,
-                           p->clab, s0, s1, p->anyblank, p->wcs,
-                           NULL, SPACK_STRING);
-  detlabelsn(p, &numpseudo, &sntable);
-
-
-
-  /* Find or apply the threshold depending on if we are dealing with
-     the background or foreground. */
-  if(p->b0f1)
-    applydetsn(p, sntable, numpseudo);
-  else
     {
-      snthresh(p, sntable, numpseudo, 0);
-      free(p->dbyt);
-      p->dbyt=originaldbyt;
+      p->binary->name="OPENED";
+      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_STRING);
+      p->binary->name=NULL;
     }
 
-  /* Clean up: */
-  free(sntable);
-}
-
-
 
 
-
-void
-dbytolaboverlap(struct noisechiselparams *p)
-{
-  unsigned char *byt;
-  long *lf, *tokeep, *lab;
-  size_t numobjects=p->numobjects;
-  size_t i, size=p->smp.s0*p->smp.s1, curlab=1;
-
-
-  /* Allocate array to keep the overlapping labels. */
-  errno=0; tokeep=calloc(numobjects, sizeof*tokeep);
-  if(tokeep==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for tokeep in dbytolaboverlap "
-          "(detection.c)", numobjects*sizeof*tokeep);
-
-
-  /* Note that the zeroth element of tokeep can also be non zero, this
-     is because the holes of the labeled regions might be filled
-     during filling the holes, but have not been filled in the
-     original labeled array. They are not important so you can just
-     ignore them.
-
-     The basic idea is that after the first pixel of a label overlaps
-     with dbyt[i], we don't need to check the rest of that object's
-     pixels. At this point, tokeep is only binary: 0 or 1.
-  */
-  byt=p->dbyt; lf=(lab=p->olab)+size;
-  do
+  /* Label the connected components. */
+  p->numobjects=gal_binary_connected_components(p->binary, &p->olabel, 1);
+  if(p->detectionname)
     {
-      if(ISINDEXABLELABEL)
-        {
-          tokeep[ *lab ] =
-            tokeep[ *lab ]    /* Check if this label is to be kept.    */
-            ? 1               /* It has, its all we need!              */
-            : *byt;           /* It hasn't, check if it should be kept.*/
-        }
-      ++byt;
+      p->olabel->name="LABELED";
+      gal_fits_img_write(p->olabel, p->detectionname, NULL, PROGRAM_STRING);
+      p->olabel->name=NULL;
     }
-  while(++lab<lf);
-  tokeep[0]=0;
-
-
-  /* Set the new labels: */
-  for(i=1;i<numobjects;++i)
-    if(tokeep[i])
-      tokeep[i]=curlab++;
-
-
-  /* Replace the byt and olab values with their proper values. If the
-     user doesn't want to dilate, then change the labels in `lab'
-     too. Otherwise, you don't have to worry about the label
-     array. After dilation a new labeling will be done and the whole
-     labeled array will be re-filled.*/
-  byt=p->byt; lf=(lab=p->olab)+size;
-  if(p->dilate)
-    do
-      {
-        if(*lab!=GAL_DATA_BLANK_LONG)
-          *byt=tokeep[*lab]>0;
-        ++byt;
-      }
-    while(++lab<lf);
-  else
-    do
-      {
-        if(*lab!=GAL_DATA_BLANK_LONG)
-          *byt = ( *lab = tokeep[*lab] ) > 0;
-        ++byt;
-      }
-    while(++lab<lf);
-
-
-  /* Note that until here, numdetected is the number of labels
-     assigned. But since later we will want the labels to be
-     indexes in an array, numdetected has to be added with one. */
-  p->numobjects=curlab;
-
-  free(tokeep);
-}
-
-
-
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*********************************************************************/
-/**************       Main detection function      *******************/
-/*********************************************************************/
-void
-onlytruedetections(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *lmp=&p->lmp;
-
-  int verb=p->cp.verb;
-  char report[GAL_TIMING_VERB_MSG_LENGTHS_2_V];
-  char *detectionname=p->detectionname;
-  size_t s0=lmp->s0, s1=lmp->s1, numobjects=p->numobjects;
-
-
-  /* Find the average and STD of the undetected pixels for each
-     mesh for the initial detection threshold: */
-  findavestdongrid(p, p->detectionskyname);
-
-
-  /* Apply the false detection removal threshold to the image. */
-  applydetectionthresholdskysub(p);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "InitalSkySubtracted",
-                           FLOAT_IMG, p->imgss, s0, s1, p->anyblank,
-                           p->wcs, NULL, SPACK_STRING);
-  if(verb)
+  /* Report the ending of initial detection. */
+  if(!p->cp.quiet)
     {
-      sprintf(report, "Initial sky threshold (%.3f sigma) applied.",
-              p->dthresh);
-      gal_timing_report(NULL, report, 2);
+      asprintf(&msg, "%zu initial detections found.", p->numobjects);
+      gal_timing_report(&t0, msg, 1);
+      free(msg);
     }
 
 
-  /* Find the Signal to noise ratio threshold on the grid and keep it
-     in one array. */
-  detsnthresh(p);
-
-  /* Apply the SN threshold to all the detections. */
-  detsnthresh(p);
-
-  /* Select the true detections: */
-  dbytolaboverlap(p);
-  if(detectionname)
-    gal_fits_array_to_file(detectionname, "TrueDetections",
-                           BYTE_IMG, p->byt, s0, s1, p->anyblank,
-                           p->wcs, NULL, SPACK_STRING);
-  if(verb)
-    {            /* p->numobjects changed in dbytlaboverlap. */
-      sprintf(report, "%zu false detections removed.",
-              numobjects-p->numobjects);
-      gal_timing_report(NULL, report, 2);
-    }
-
 
-  /* Clean up: */
-  free(p->dbyt);
+  /* If the user wanted to check the threshold and hasn't called
+     `continueaftercheck', then stop NoiseChisel. */
+  if(p->detectionname && !p->continueaftercheck)
+    ui_abort_after_check(p, p->detectionname, "showing all detection steps");
 }
diff --git a/bin/noisechisel/detection.h b/bin/noisechisel/detection.h
index 40db697..1923622 100644
--- a/bin/noisechisel/detection.h
+++ b/bin/noisechisel/detection.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -24,9 +24,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define DETECTION_H
 
 void
-initialdetection(struct noisechiselparams *p);
-
-void
-onlytruedetections(struct noisechiselparams *p);
+detection_initial(struct noisechiselparams *p);
 
 #endif
diff --git a/bin/noisechisel/label.c b/bin/noisechisel/label.c
deleted file mode 100644
index 05f2d3d..0000000
--- a/bin/noisechisel/label.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <string.h>
-#include <stdlib.h>
-
-#include <gnuastro/data.h>
-#include <gnuastro/fits.h>
-#include <gnuastro/linkedlist.h>
-
-#include <neighbors.h>
-
-#include "main.h"
-
-#include "label.h"
-#include "binary.h"
-
-
-
-
-
-
-
-
-
-
-/**********************************************************************/
-/**************     Connected component labeling    *******************/
-/**********************************************************************/
-/* Find the connected components in an image based on the breadth
-   first algorithm. The output curlab is one more than the actual
-   number of objects in the array. The input image is a unsigned char
-   binary, either background (==0) or foreground (==1), image. This
-   function will find and label the different components of all
-   pixels labeled b0_f1.*/
-size_t
-BF_concmp(unsigned char *byt, long *lab, size_t s0, size_t s1,
-          int anyblank, const size_t connectivity)
-{
-  struct gal_linkedlist_sll *Q=NULL;
-  long *l=lab, curlab=1; /* Current label */
-  size_t i, p, size=s0*s1, s0t1=s0-1, s1t1=s1-1;
-  unsigned char *b=byt, *bf=byt+s0*s1, counter, bl, br, tl, tr;
-
-
-  /* A simple sanity check. */
-  if(connectivity!=4 && connectivity!=8)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
-          "the problem. For some reason, the value to connectivity in "
-          "BF_concmp (label.c) is %zu which is not recognized",
-          PACKAGE_BUGREPORT, connectivity);
-
-
-  /* Initialize the labels array. If we have blank pixels in the byt
-     array, then give them the blank labeled array. Note that since
-     their value will not be 0, they will also not be labeled. */
-  if(anyblank)
-    do *l++ = *b==GAL_DATA_BLANK_UCHAR ? GAL_DATA_BLANK_LONG
-         : 0; while(++b<bf);
-  else
-    memset(lab, 0, size*sizeof *lab);
-
-  /* Go over all the pixels: */
-  if(connectivity==4)
-    {
-      for(i=0;i<size;++i)
-        /* Check if it is not needed or already done: */
-        if(byt[i] && !lab[i])
-          {
-            lab[i]=curlab;
-            gal_linkedlist_add_to_sll(&Q, i);
-            while(Q!=NULL)
-              {
-                /* Pop from the queue */
-                gal_linkedlist_pop_from_sll(&Q, &p);
-
-                /* Check the four connected neighbors: */
-                if(p/s1>0    && byt[p-s1] && !lab[p-s1])
-                  {gal_linkedlist_add_to_sll(&Q, p-s1); lab[p-s1]=curlab;}
-                if(p/s1<s0t1 && byt[p+s1] && !lab[p+s1])
-                  {gal_linkedlist_add_to_sll(&Q, p+s1); lab[p+s1]=curlab;}
-                if(p%s1>0    && byt[p-1]  && !lab[p-1])
-                  {gal_linkedlist_add_to_sll(&Q, p-1); lab[p-1]=curlab;}
-                if(p%s1<s1t1 && byt[p+1]  && !lab[p+1])
-                  {gal_linkedlist_add_to_sll(&Q, p+1); lab[p+1]=curlab;}
-              }
-            ++curlab;
-          }
-    }
-  else
-    {
-      for(i=0;i<size;++i)
-        /* Check if it is not needed or already done: */
-        if(byt[i] && !lab[i])
-          {
-            lab[i]=curlab;
-            gal_linkedlist_add_to_sll(&Q, i);
-
-            while(Q!=NULL)
-              {
-
-                gal_linkedlist_pop_from_sll(&Q, &p);
-
-                /* Set the counters for the corners in 8-connectivity */
-                counter=bl=br=tl=tr=0;
-
-                /* Check the four connected neighbors: */
-                if(p/s1>0)
-                  {
-                    ++counter; ++bl; ++br;
-                    if(byt[p-s1] && !lab[p-s1])
-                      {gal_linkedlist_add_to_sll(&Q, p-s1); lab[p-s1]=curlab;}
-                  }
-                if(p/s1<s0t1)
-                  {
-                    ++counter; ++tl; ++tr;
-                    if(byt[p+s1] && !lab[p+s1])
-                      {gal_linkedlist_add_to_sll(&Q, p+s1); lab[p+s1]=curlab;}
-                  }
-                if(p%s1>0)
-                  {
-                    ++counter; ++bl; ++tl;
-                    if(byt[p-1]  && !lab[p-1])
-                      {gal_linkedlist_add_to_sll(&Q, p-1); lab[p-1]=curlab;}
-                  }
-                if(p%s1<s1t1)
-                  {
-                    ++counter; ++tr; ++br;
-                    if(byt[p+1]  && !lab[p+1])
-                      {gal_linkedlist_add_to_sll(&Q, p+1); lab[p+1]=curlab;}
-                  }
-
-                if(counter==4)  /* All four corners are in the image. */
-                  {
-                    if(byt[p-s1-1] && !lab[p-s1-1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p-s1-1);
-                        lab[p-s1-1]=curlab;
-                      }
-                    if(byt[p-s1+1] && !lab[p-s1+1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p-s1+1);
-                        lab[p-s1+1]=curlab;
-                      }
-                    if(byt[p+s1-1] && !lab[p+s1-1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p+s1-1);
-                        lab[p+s1-1]=curlab;
-                      }
-                    if(byt[p+s1+1] && !lab[p+s1+1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p+s1+1);
-                        lab[p+s1+1]=curlab;
-                      }
-                  }
-                else            /* At least one corner isn't in the image. */
-                  {
-                    if(bl==2 && byt[p-s1-1] && !lab[p-s1-1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p-s1-1);
-                        lab[p-s1-1]=curlab;
-                      }
-                    if(br==2 && byt[p-s1+1] && !lab[p-s1+1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p-s1+1);
-                        lab[p-s1+1]=curlab;
-                      }
-                    if(tl==2 && byt[p+s1-1] && !lab[p+s1-1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p+s1-1);
-                        lab[p+s1-1]=curlab;}
-                    if(tr==2 && byt[p+s1+1] && !lab[p+s1+1])
-                      {
-                        gal_linkedlist_add_to_sll(&Q, p+s1+1);
-                        lab[p+s1+1]=curlab;}
-                  }
-              }
-            ++curlab;
-          }
-    }
-
-  return curlab;
-}
-
-
-
-
-
-/* This function applied the same principles of the above function but
-   on an adjacency matrix. Its output is an array the size of one side
-   of the adjacency matrix that will have the label each object should
-   have.
-
-   The adjacency matrix should be zero (for no connection) and
-   non-zero for connection (note that it should be symmetric).
-*/
-size_t
-BF_concomp_AdjMatrix(int *adj, size_t numside, long **outnewlabs)
-{
-  size_t i, j, p;
-  struct gal_linkedlist_sll *Q=NULL;
-  long *newlabs, curlab=1;
-
-  errno=0;
-  newlabs=calloc(numside, sizeof *newlabs);
-  if(newlabs==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newlabs in "
-          "BF_concomp_AdjMatrix (label.c)", numside*sizeof *newlabs);
-
-  for(i=1;i<numside;++i)
-    if(newlabs[i]==0)
-      {
-        gal_linkedlist_add_to_sll(&Q, i);
-        while(Q!=NULL)
-          {
-            gal_linkedlist_pop_from_sll(&Q, &p);
-            if(newlabs[p]!=curlab)
-              {
-                newlabs[p]=curlab;
-                for(j=1;j<numside;++j)
-                  if( adj[p*numside+j] && newlabs[j]==0 )
-                    gal_linkedlist_add_to_sll(&Q, j);
-              }
-          }
-        ++curlab;
-      }
-
-  /* For a check:
-  for(i=1;i<numside;++i)
-    printf("%zu: %ld\n", i, newlabs[i]);
-  */
-
-  *outnewlabs=newlabs;
-  return curlab;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**********************************************************************/
-/**************            Work on labels           *******************/
-/**********************************************************************/
-/* Find the areas of labeled regions in an array. `numlabs`, which is
-   the number of labels in the array has to be one larger than the
-   largest label in the array. */
-void
-labareas(long *lab, size_t size, size_t numlabs, size_t **outareas)
-{
-  size_t *areas;
-  long *last=lab+size;
-
-  /* Allocate the areas array: */
-  errno=0;
-  areas=*outareas=calloc(numlabs, sizeof *areas);
-  if(areas==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for areas in labareas (label.c)",
-          numlabs*sizeof *areas);
-
-  /* Find the area of each label. */
-  do if(ISINDEXABLELABEL) ++areas[*lab]; while(++lab<last);
-
-  /* For a check:
-  for(i=0;i<numlabs;++i)
-    printf("%zu: %ld\n", i, a[i]);
-  printf("\n\n\n\n\n");
-  */
-}
-
-
-
-
-
-void
-removesmallarea_relabel(long *in, unsigned char *byt, size_t size,
-                        size_t *numlabs, size_t minarea)
-{
-  size_t i, *areas;
-  long *newlabs, curlab=1;
-
-  /* Allocate the space to keep the new labels. */
-  errno=0; newlabs=calloc(*numlabs, sizeof *newlabs);
-  if(newlabs==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newlabs in "
-          "removesmallarea_relabel (label.c)", *numlabs*sizeof *newlabs);
-
-  /* Find the areas: */
-  labareas(in, size, *numlabs, &areas);
-  areas[0]=0;
-
-  /* Set the new labels: */
-  for(i=1;i<*numlabs;++i)
-    if(areas[i]>minarea)
-      newlabs[i]=curlab++;
-
-  if(byt)
-    {
-      for(i=0;i<size;++i)
-        if(in[i]!=GAL_DATA_BLANK_LONG)
-          byt[i] = (in[i]=newlabs[in[i]]) > 0;
-    }
-  else
-    {
-      for(i=0;i<size;++i)
-        if(in[i]!=GAL_DATA_BLANK_LONG)
-          in[i]=newlabs[in[i]];
-    }
-
-  *numlabs=curlab;
-
-  free(areas);
-  free(newlabs);
-}
-
-
-
-
-
-/* Make an array of pointers to arrays that keep the indexes of
-   different labeled regions in the image. Note that the label zero
-   is not going to be considered. */
-void
-labindexs(long *inlab, size_t size, size_t numlabs, size_t **outareas,
-          size_t ***outlabinds)
-{
-  long *lab, *lp;
-  size_t i, *areas, *counters, **labinds;
-
-  /* Allocate the pointers to the objects index array and set the
-     pointer to label zero to NULL. */
-  errno=0;
-  labinds=*outlabinds=malloc(numlabs*sizeof *labinds);
-  if(labinds==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for labinds in labindexs "
-          "(label.c)", numlabs*sizeof *labinds);
-  labinds[0]=NULL;
-
-  /* Find the area of each label: */
-  labareas(inlab, size, numlabs, outareas);
-  areas=*outareas;
-  areas[0]=0;
-
-  /* For each label, counter will keep the position of the last filled
-     element. */
-  errno=0;
-  counters=calloc(numlabs, sizeof *counters);
-  if(counters==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for counters in labindexs "
-          "(label.c)", numlabs*sizeof *counters);
-
-  /* Allocate space for each label's indexs: */
-  for(i=1;i<numlabs;++i)
-    {
-      errno=0;
-      labinds[i]=malloc(areas[i]*sizeof **labinds);
-      if(labinds[i]==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for labinds[%zu] in "
-              "labindexs (label.c)", areas[i]*sizeof **labinds, i);
-    }
-
-  /* Fill in the indexs array. */
-  lp=(lab=inlab)+size;
-  do
-    if(ISINDEXABLELABEL)
-      labinds[*lab][counters[*lab]++]=lab-inlab;
-  while(++lab<lp);
-  labinds[0]=NULL;
-
-  /* For a check:
-  {
-    size_t j;
-    for(i=1;i<numlabs;++i)
-      {
-        printf("Lab: %zu\n", i);
-        for(j=0;j<areas[i];++j)
-          printf("  %zu\n", labinds[i][j]);
-      }
-    exit(0);
-  }
-  */
-  free(counters);
-}
diff --git a/bin/noisechisel/label.h b/bin/noisechisel/label.h
deleted file mode 100644
index 74dc2ec..0000000
--- a/bin/noisechisel/label.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-This is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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/>.
-**********************************************************************/
-#ifndef LABEL_H
-#define LABEL_H
-
-
-
-
-
-/* For the GAL_FITS_LONG_BLANK and GAL_FITS_BYTE_BLANK macros: */
-#include <gnuastro/fits.h>
-
-
-/* In case the blank value for the long type is negative, the only
-   necessary check to see if we are on a label or not is to see if its
-   value is positive. But since we don't want to impose this condition on
-   the fits.h macro (which is used by all Gnuastro programs) we allow for
-   it to be positive through this C preprocessor check. The compiler has no
-   idea of our convention to label things with positive indices, so we
-   can't rely on the compiler to optimize this. */
-#if GAL_FITS_LONG_BLANK<0
-#define ISINDEXABLELABEL (*lab>0)
-#else
-#define ISINDEXABLELABEL (*lab && *lab!=GAL_DATA_BLANK_LONG)
-#endif
-
-
-
-size_t
-BF_concmp(unsigned char *byt, long *lab, size_t s0, size_t s1,
-          int anyblank, const size_t connectivity);
-
-size_t
-BF_concomp_AdjMatrix(int *adj, size_t numside, long **outnewlabs);
-
-void
-removesmallarea_relabel(long *in, unsigned char *byt, size_t size,
-                        size_t *numlabs, size_t minarea);
-
-void
-labindexs(long *lab, size_t size, size_t numlabs, size_t **outareas,
-          size_t ***outlabinds);
-
-#endif
diff --git a/bin/noisechisel/main.c b/bin/noisechisel/main.c
index d385593..d7eb2d5 100644
--- a/bin/noisechisel/main.c
+++ b/bin/noisechisel/main.c
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -29,27 +29,29 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #include "main.h"
 
-#include "ui.h"                 /* needs main.h.                  */
-#include "noisechisel.h"        /* needs main.h.                  */
+#include "ui.h"
+#include "noisechisel.h"
 
+
+/* Main function */
 int
 main (int argc, char *argv[])
 {
   struct timeval t1;
   struct noisechiselparams p={{{0},0},0};
 
-  /* Set the starting time. */
+  /* Set they starting time. */
   time(&p.rawtime);
   gettimeofday(&t1, NULL);
 
   /* Read the input parameters. */
-  setparams(argc, argv, &p);
+  ui_read_check_inputs_setup(argc, argv, &p);
 
   /* Run MakeProfiles */
   noisechisel(&p);
 
   /* Free all non-freed allocations. */
-  freeandreport(&p, &t1);
+  ui_free_report(&p, &t1);
 
   /* Return successfully.*/
   return EXIT_SUCCESS;
diff --git a/bin/noisechisel/main.h b/bin/noisechisel/main.h
index 134b33f..aa9c388 100644
--- a/bin/noisechisel/main.h
+++ b/bin/noisechisel/main.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -23,154 +23,85 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef MAIN_H
 #define MAIN_H
 
-#include <gnuastro/mesh.h>
-#include <gnuastro/fits.h>
+/* Include necessary headers */
+#include <gnuastro/data.h>
 
-#include <commonparams.h>
+#include <options.h>
 
-/* Progarm name macros: */
-#define SPACK           "astnoisechisel" /* Subpackage executable name. */
-#define SPACK_NAME      "NoiseChisel"    /* Subpackage full name.       */
-#define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
+/* Progarm names.  */
+#define PROGRAM_NAME   "NoiseChisel"    /* Program full name.       */
+#define PROGRAM_EXEC   "astnoisechisel" /* Program executable name. */
+#define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
 
 
-struct uiparams
-{
-  char          *inputname;  /* Name of input file.                 */
-  char           *maskname;  /* Name of mask image file.            */
-  char               *mhdu;  /* Name of mask image header name.     */
-  char         *kernelname;  /* Name of kernel image file.          */
-  char               *khdu;  /* Name of kernel header name.         */
-
-  int   fullconvolutionset;
-  int fullinterpolationset;
-  int        fullsmoothset;
-  int          masknameset;
-  int              mhduset;
-  int        kernelnameset;
-  int              khduset;
-  int     skysubtractedset;
-  int       grownclumpsset;
-
-  int         smeshsizeset;
-  int         lmeshsizeset;
-  int              nch1set;
-  int              nch2set;
-  int      lastmeshfracset;
-  int        numnearestset;
-  int       smoothwidthset;
-  int        mirrordistset;
-  int          minmodeqset;
-
-  int           qthreshset;
-  int             erodeset;
-  int          erodengbset;
-  int      noerodequantset;
-  int           openingset;
-  int        openingngbset;
-  int          minbfracset;
-  int     sigclipmultipset;
-  int  sigcliptoleranceset;
-  int           dthreshset;
-  int      detsnminareaset;
-  int       minnumfalseset;
-  int          detquantset;
-  int    detsnhistnbinsset;
-  int            dilateset;
-
-  int      segsnminareaset;
-  int  keepmaxnearriverset;
-  int          segquantset;
-  int  clumpsnhistnbinsset;
-  int           gthreshset;
-  int    minriverlengthset;
-  int       objbordersnset;
-};
-
-
 
 
 
+/* Main program parameters structure */
 struct noisechiselparams
 {
-  /* Other structures: */
-  struct uiparams         up; /* User interface parameters.                */
-  struct gal_commonparams cp; /* Common parameters.                        */
-  struct gal_mesh_params smp; /* Smaller mesh grid of input image.         */
-  struct gal_mesh_params lmp; /* Larger mesh grid of input image.          */
-
-  /* Input: */
-  int                 nwcs; /* Number of WCS structures.                   */
-  struct wcsprm       *wcs; /* Pointer to WCS structures.                  */
-  int               bitpix; /* Input image bitpix value.                   */
-  int             anyblank; /* ==1 There are blank pixels in input image.  */
-  int        skysubtracted; /* ==1: the input image is already sky subted. */
-
-  /* output: */
-  char           *meshname; /* Name of --checkmesh output.                 */
-  char         *threshname; /* !=NULL: Name of threshold steps.            */
-  char      *detectionname; /* !=NULL: Name of detection steps.            */
-  char   *detectionskyname; /* !=NULL: Name of detection sky steps.        */
-  char    *detectionsnhist; /* !=NULL: Name of detection S/N histogram.    */
-  char            *skyname; /* !=NULL: Name of image showing sky and STD.  */
-  char   *segmentationname; /* !=NULL: Name of segmentation steps.         */
-  char        *clumpsnhist; /* !=NULL: Name of clump S/N histogram.        */
-  int           detectonly; /* ==1: Only do detection, no segmentation.    */
-  char        *maskdetname; /* !=NULL: Save masked detections and sky.     */
-  int          grownclumps; /* ==1: Save the grown clumps in output.       */
-
-  /* Detection: */
-  float              *conv; /* Convolved image.                            */
-  float            qthresh; /* Quantile threshold on convolved img.        */
-  float       noerodequant; /* Quantile for no erosion.                    */
-  size_t             erode; /* Number of times to erode thresholded image. */
-  int             erodengb; /* Use 4 or 8 connectivity in erosion.         */
-  size_t           opening; /* Depth of opening to apply to eroded image.  */
-  int           openingngb; /* Use 4 or 8 connectivity in opening.         */
-  float           minbfrac; /* Minimum fraction of undetected pixels.      */
-  float      sigclipmultip; /* Multiple of standard deviation, sigma clip. */
-  float   sigcliptolerance; /* Tolerance in sigma clip.                    */
-  float            dthresh; /* Threshold to remove false detections.       */
-  size_t      detsnminarea; /* Minimum area to calculate S/N for detection.*/
-  size_t       minnumfalse; /* Min No. false detections/segments for quant.*/
-  float           detquant; /* False detection S/N quantile to find true.  */
-  size_t    detsnhistnbins; /* ==1: Save false detection S/Ns histogram.   */
-  size_t            dilate; /* Number of times to dilate true detections.  */
-
-  /* Segmentation: */
-  size_t      segsnminarea; /* Minimum area to find the S/N of a clump.    */
-  float           segquant; /* S/N quantile for true clump.                */
-  size_t  clumpsnhistnbins; /* ==1: Save false clumps S/Ns histogram.      */
-  int     keepmaxnearriver; /* ==1: Keep clumps with max touching river.   */
-  float            gthresh; /* Threshold to stop growing objects.          */
-  size_t    minriverlength; /* Minimum length of river between grown clmps.*/
-  float        objbordersn; /* S/N of rivers to define objects.            */
-
-  /* Operating mode: */
-
-  /* Internal: */
-  double             detsn; /* Signal to noise threshold for detections.   */
-  double           clumpsn; /* Signal to noise threshold for clumps.       */
-  float               *img; /* Input image.                                */
-  float             *imgss; /* Sky subtracted image.                       */
-  time_t           rawtime; /* Starting time of the program.               */
-  long               *olab; /* Object labels.                              */
-  long               *clab; /* Clump labels.                               */
-  unsigned char       *byt; /* Array of single bytes for binary operations.*/
-  unsigned char      *dbyt; /* False detection removal thresholded array.  */
-  float             minstd; /* For correction to counts per second data.   */
-  float             maxstd; /* To store in output header.                  */
-  float             medstd; /* Median Standard deviation over image.       */
-  float            cpscorr; /* correction to counts per second data.       */
-  unsigned char       b0f1; /* ==1: we are now working on data, not noise. */
-  int              stepnum; /* Number of step if user wants to see steps.  */
-  size_t        numobjects; /* Total number of objects (detections).       */
-  size_t         numclumps; /* Total number of clumps.                     */
-  size_t         relngb[8]; /* Indexs of relative neighbors.               */
-  size_t     *numclumpsarr; /* The number of clumps in each mesh.          */
-  float       **sntablearr; /* Array of pointers to sntable of each mesh.  */
+  /* From command-line */
+  struct gal_options_common_params cp; /* Common parameters.              */
+  char             *inputname;  /* Input filename.                        */
+  char            *kernelname;  /* Input kernel filename.                 */
+  char                  *khdu;  /* Kernel HDU.                            */
+  uint8_t       skysubtracted;  /* Input has been Sky subtracted before.  */
+  float              minbfrac;  /* Undetected area min. frac. in tile.    */
+  size_t          minnumfalse;  /* Min No. of det/seg for true quantile.  */
+
+  uint8_t          onlydetect;  /* Do not do any segmentation.            */
+  uint8_t         grownclumps;  /* Save grown clumps instead of original. */
+  uint8_t  continueaftercheck;  /* Don't abort after the check steps.     */
+
+  float            mirrordist;  /* Maximum distance to check mode sym.    */
+  float           modmedqdiff;  /* Difference between mode and median.    */
+  float               qthresh;  /* Quantile threshold on convolved image. */
+  size_t          smoothwidth;  /* Width of flat kernel to smooth.        */
+  uint8_t        checkqthresh;  /* Save the quantile threhsold steps.     */
+  size_t                erode;  /* Number of erosions after thresholding. */
+  size_t             erodengb;  /* Connectivity for erosion.              */
+  float          noerodequant;  /* Quantile for no erosion.               */
+  size_t              opening;  /* Depth of opening after erosion.        */
+  size_t           openingngb;  /* Connectivity to use for opening.       */
+  double         sigmaclip[2];  /* Sigma-clipping parameters.             */
+  uint8_t         checkdetsky;  /* Check pseudo-detection sky value.      */
+  float               dthresh;  /* Sigma threshold for Pseudo-detections. */
+  size_t         detsnminarea;  /* Minimum pseudo-detection area for S/N. */
+  uint8_t          checkdetsn;  /* Save pseudo-detection S/N values.      */
+  float              detquant;  /* True detection quantile.               */
+  size_t               dilate;  /* Number of times to dilate true dets.   */
+  uint8_t      checkdetection;  /* Save all detection steps to a file.    */
+  uint8_t            checksky;  /* Check the Sky value estimation.        */
+
+  size_t         segsnminarea;  /* Minimum area for segmentation.         */
+  float              segquant;  /* Quantile of clumps in sky for true S/N.*/
+  uint8_t        checkclumpsn;  /* Save the clump S/N values to a file.   */
+  uint8_t    keepmaxnearriver;  /* Keep clumps with a peak near a river.  */
+  float               gthresh;  /* Multiple of STD to stop growing clumps.*/
+  size_t       minriverlength;  /* Min, len of good grown clump rivers.   */
+  float           objbordersn;  /* Minimum S/N for grown clumps to be one.*/
+  uint8_t   checksegmentation;  /* Save the segmentation steps in file.   */
+
+  /* Internal. */
+  char           *qthreshname;  /* Name of Quantile threshold check image.*/
+  char            *detskyname;  /* Name of Initial det sky check image.   */
+  char             *detsnname;  /* Name of pseudo-detections S/N values.  */
+  char         *detectionname;  /* Name of detection steps file.          */
+  char               *skyname;  /* Name of Sky estimation steps file.     */
+  char           *clumpsnname;  /* Name of Clump S/N values file.         */
+  char      *segmentationname;  /* Name of segmentation steps file.       */
+  gal_data_t           *input;  /* Input image.                           */
+  gal_data_t          *kernel;  /* Input image.                           */
+  gal_data_t            *conv;  /* Convolved input.                       */
+  gal_data_t          *binary;  /* For binary operations.                 */
+  gal_data_t          *olabel;  /* Labels of objects in the detection.    */
+  time_t              rawtime;  /* Starting time of the program.          */
+
+  size_t           numobjects;  /* Number of objects detected.            */
+  size_t           maxtcontig;  /* Maximum contiguous space for a tile.   */
+  size_t            *maxtsize;  /* Maximum size of a single tile.         */
 };
 
 #endif
diff --git a/bin/noisechisel/noisechisel.c b/bin/noisechisel/noisechisel.c
index a835465..d25fab8 100644
--- a/bin/noisechisel/noisechisel.c
+++ b/bin/noisechisel/noisechisel.c
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -23,113 +23,36 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <config.h>
 
 #include <stdio.h>
-#include <errno.h>
-#include <error.h>
-#include <string.h>
 #include <stdlib.h>
 
 #include <gnuastro/fits.h>
-#include <gnuastro/array.h>
+#include <gnuastro/convolve.h>
 
 #include <timing.h>
 
 #include "main.h"
 
-#include "sky.h"
-#include "label.h"
-#include "binary.h"
-#include "thresh.h"
 #include "detection.h"
-#include "noisechisel.h"
-#include "segmentation.h"
 
 
 
 
-
-
-
-
-
-
-/*********************************************************************/
-/******************         NoiseChisel        ***********************/
-/*********************************************************************/
-void
-makeoutput(struct noisechiselparams *p)
+static void
+noisechisel_convolve(struct noisechiselparams *p)
 {
-  float *fpt;
-  double *dpt;
-  long num[0];
-  float *sky=NULL, *std=NULL;
-  struct gal_fits_key_ll *keys=NULL;
-  size_t s0=p->smp.s0, s1=p->smp.s1;
-
-
-  /* First put a copy of the input image. */
-  gal_fits_array_to_file(p->cp.output, "Input", FLOAT_IMG, p->img,
-                         s0, s1, 0, p->wcs, NULL, SPACK_STRING);
-
-
-  /* Add the necessary FITS keywords for MakeCatalog when reading the
-     objects image. */
-  gal_fits_add_to_key_ll(&keys, TSTRING, "WCLUMPS", 0, "yes", 0,
-                         "Is there a clumps image companion?", 0, NULL);
-  num[0]=p->numobjects-1;
-  gal_fits_add_to_key_ll(&keys, TLONG, "NOBJS", 0, num, 0,
-                         "Number of objects in the image.", 0, NULL);
-  dpt=&p->detsn;
-  gal_fits_add_to_key_ll(&keys, TDOUBLE, "DETSN", 0, dpt, 0,
-                         "Signal to noise of true pseudo-detections.", 0, 
NULL);
-  gal_fits_array_to_file(p->cp.output, "Objects", LONG_IMG, p->olab,
-                         s0, s1, p->anyblank, p->wcs, keys,
-                         SPACK_STRING);
-  keys=NULL;     /* keys was freed after writing. */
-
-
-  /* The clump labels, mentioning the total number of clumps. Note
-     that even if no segmentation is to be done, we need this
-     extension filled so the sky and its standard deviation can remain
-     on the 3rd and 4th extensions. */
-  num[0] = p->detectonly ? 0 : p->numclumps-1;
-  gal_fits_add_to_key_ll(&keys, TLONG, "NCLUMPS", 0, num, 0,
-                         "Number of clumps in the image.", 0, NULL);
-  dpt=&p->clumpsn;
-  gal_fits_add_to_key_ll(&keys, TDOUBLE, "CLUMPSN", 0, dpt, 0,
-                         "Signal to noise of true clumps.", 0, NULL);
-  gal_fits_array_to_file(p->cp.output, "Clumps", LONG_IMG, p->clab, s0,
-                         s1, p->anyblank, p->wcs, keys, SPACK_STRING);
-  keys=NULL;
-
-  /* The sky image: */
-  gal_mesh_check_garray(&p->smp, &sky, &std);
-  gal_fits_array_to_file(p->cp.output, "Sky", FLOAT_IMG, sky,
-                         s0, s1, 0, p->wcs, NULL, SPACK_STRING);
-
-
-  /* The sky standard deviation image. Note that since this is a
-     linked list, the median will be written to the FITS header
-     first. Also note that these values were found before
-     interpolating or smoothing the image, so we have put a "raw" in
-     the comments of each variable.*/
-  fpt=&p->maxstd;
-  gal_fits_add_to_key_ll(&keys, TFLOAT, "MAXSTD", 0, fpt, 0,
-                         "Maximum raw mesh sky standard deviation.", 0, NULL);
-  fpt=&p->minstd;
-  gal_fits_add_to_key_ll(&keys, TFLOAT, "MINSTD", 0, fpt, 0,
-                         "Minimum raw mesh sky standard deviation.", 0, NULL);
-  fpt=&p->medstd;
-  gal_fits_add_to_key_ll(&keys, TFLOAT, "MEDSTD", 0, fpt, 0,
-                         "Median raw mesh standard deviation.", 0, NULL);
-  gal_fits_array_to_file(p->cp.output, "Standard deviation",
-                         FLOAT_IMG, std, s0, s1, 0, p->wcs,
-                         keys, SPACK_STRING);
-  keys=NULL;
+  struct timeval t1;
+  struct gal_tile_two_layer_params *tl=&p->cp.tl;
 
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
+  p->conv=gal_convolve_spatial(tl->tiles, p->kernel, p->cp.numthreads,
+                               1, tl->workoverch);
 
-  /* Clean up: */
-  free(sky);
-  free(std);
+  if(!p->cp.quiet) gal_timing_report(&t1, "Convolved with kernel.", 1);
+  if(p->detectionname)
+    {
+      gal_fits_img_write(p->input, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->conv, p->detectionname, NULL, PROGRAM_STRING);
+    }
 }
 
 
@@ -139,172 +62,9 @@ makeoutput(struct noisechiselparams *p)
 void
 noisechisel(struct noisechiselparams *p)
 {
-  struct gal_mesh_params *smp=&p->smp, *lmp=&p->lmp;
-
-  float *imgcopy;
-  struct timeval t1;
-  int verb=p->cp.verb;
-  size_t i, s0=smp->s0, s1=smp->s1;
-  char report[GAL_TIMING_VERB_MSG_LENGTH_V], *oreport;
-
-
-  /* Convolve the image: */
-  if(verb) gettimeofday(&t1, NULL);
-  gal_mesh_spatial_convolve_on_mesh(smp, &p->conv);
-  if(p->detectionname)
-    {
-      gal_fits_array_to_file(p->detectionname, "Input", FLOAT_IMG,
-                             smp->img, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-      gal_fits_array_to_file(p->detectionname, "Convolved", FLOAT_IMG,
-                             p->conv, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-    }
-  if(verb) gal_timing_report(&t1, "Convolved with kernel.", 1);
-
-
+  /* Convolve the image. */
+  noisechisel_convolve(p);
 
   /* Do the initial detection: */
-  if(verb)
-    {
-      gal_timing_report(NULL, "Starting to find initial detections.", 1);
-      gettimeofday(&t1, NULL);
-    }
-  initialdetection(p);
-  if(verb)
-    {
-      sprintf(report, "%zu initial detections found.", p->numobjects-1);
-      gal_timing_report(&t1, report, 1);
-    }
-
-
-
-  /* Remove the false detections */
-  if(verb)
-    {
-      gal_timing_report(NULL, "Starting to find and remove false detections.",
-                        1);
-      gettimeofday(&t1, NULL);
-    }
-  onlytruedetections(p);
-  if(verb)
-    {
-      sprintf(report, "%zu true detections identified.", p->numobjects-1);
-      gal_timing_report(&t1, report, 1);
-    }
-
-
-
-  /* Dilate the byt array and find the new number of detections. Note
-     that the connectivity has to be 8 connected. This is because we
-     check the eight neighbors of every river pixel within each
-     detection during the segmentation. Therefore if 4 connectivity is
-     used here, two detection might be four connected and so their
-     labels will be mixed during the checking of neighbors in the
-     segmentation. */
-  if(verb) gettimeofday(&t1, NULL);
-  if(p->dilate)
-    {
-      for(i=0;i<p->dilate;++i)
-        dilate0_erode1_8con(p->byt, s0, s1, 0);
-      p->numobjects=BF_concmp(p->byt, p->olab, s0, s1, p->anyblank, 8);
-      if(verb)
-        {
-          sprintf(report, "%zu detections after %zu dilation%s",
-                  p->numobjects-1, p->dilate, p->dilate>1 ? "s." : ".");
-          gal_timing_report(&t1, report, 1);
-        }
-    }
-  if(p->detectionname)
-    gal_fits_array_to_file(p->detectionname, "Dilated", LONG_IMG,
-                           p->olab, s0, s1, p->anyblank, p->wcs,
-                           NULL, SPACK_STRING);
-  if(p->maskdetname)
-    {
-      gal_fits_array_to_file(p->maskdetname, "Input", FLOAT_IMG,
-                             p->img, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-      gal_array_float_copy(p->img, s0*s1, &imgcopy);
-      maskbackorforeground(imgcopy, s0*s1, p->byt, 0);
-      gal_fits_array_to_file(p->maskdetname, "Undetected masked",
-                             FLOAT_IMG, imgcopy, s0, s1, p->anyblank,
-                             p->wcs, NULL, SPACK_STRING);
-      free(imgcopy);
-      gal_array_float_copy(p->img, s0*s1, &imgcopy);
-      maskbackorforeground(imgcopy, s0*s1, p->byt, 1);
-      gal_fits_array_to_file(p->maskdetname, "Detected masked",
-                             FLOAT_IMG, imgcopy, s0, s1, p->anyblank,
-                             p->wcs, NULL, SPACK_STRING);
-      free(imgcopy);
-    }
-
-  /* Correct convolution if it was done on edges independently: */
-  if(smp->nch>1 && smp->fullconvolution==0 && p->detectonly==0)
-    {
-      if(verb) gettimeofday(&t1, NULL);
-      gal_mesh_change_to_full_convolution(smp, p->conv);
-      if(verb)
-        gal_timing_report(&t1, "Convolved image internals corrected.", 1);
-    }
-
-  /* Find and subtract the final sky value for the input and convolved
-     images.
-
-     VERY IMPORTANT:
-     ###############
-
-     The sky value for the input image should be found after the
-     convolved image. This is because findavestdongrid, will also set
-     the p->cpscorr value and we want that from the input image, not
-     the convolved image.  */
-  if(verb) gettimeofday(&t1, NULL);
-  if(p->detectonly==0) findsubtractskyconv(p);
-  findavestdongrid(p, p->skyname);
-  if(p->detectonly==0) subtractskyimg(p);
-  if(verb)
-    gal_timing_report(&t1, "Final sky and its STD found and subtracted.", 1);
-
-
-
-
-  /* Segment the detections if segmentation is to be done. */
-  if(p->detectonly)
-    clabwithnoseg(p->olab, p->clab, s0*s1, p->anyblank);
-  else
-    {
-      if(verb)
-        {
-          gal_timing_report(NULL, "Starting to find clumps and objects.", 1);
-          gettimeofday(&t1, NULL);
-        }
-      segmentation(p);
-      if(verb)
-        {
-          sprintf(report, "%zu object%s""containing %zu clump%sfound.",
-                  p->numobjects-1, p->numobjects==2 ? " " : "s ",
-                  p->numclumps-1,  p->numclumps ==2 ? " " : "s ");
-          gal_timing_report(&t1, report, 1);
-        }
-    }
-
-
-
-  /* Make the output: */
-  if(verb) gettimeofday(&t1, NULL);
-  makeoutput(p);
-  if(verb)
-    {
-      errno=0; oreport=malloc(strlen(p->cp.output)+100*sizeof *oreport);
-      if(oreport==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for oreport in noisechisel "
-              "(noisechisel.c)", strlen(p->cp.output)+100*sizeof *oreport);
-      sprintf(oreport, "Output written to %s.", p->cp.output);
-      gal_timing_report(&t1, oreport, 1);
-      free(oreport);
-    }
-
-  /* Clean up: */
-  free(p->conv);           /* Allocated in gal_mesh_spatial_convolve_on_mesh. 
*/
-  gal_mesh_free_mesh(smp); /* Allocated here.                                 
*/
-  gal_mesh_free_mesh(lmp); /* Allocated here.                                 
*/
+  detection_initial(p);
 }
diff --git a/bin/noisechisel/noisechisel.h b/bin/noisechisel/noisechisel.h
index 5acc841..b1a41d1 100644
--- a/bin/noisechisel/noisechisel.h
+++ b/bin/noisechisel/noisechisel.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
diff --git a/bin/noisechisel/segmentation.c b/bin/noisechisel/segmentation.c
deleted file mode 100644
index 902d839..0000000
--- a/bin/noisechisel/segmentation.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <string.h>
-#include <stdlib.h>
-
-#include <gnuastro/fits.h>
-#include <gnuastro/qsort.h>
-
-#include <neighbors.h>
-
-#include "main.h"
-
-#include "label.h"
-#include "clumps.h"
-#include "segmentation.h"
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*****************     Growing preparations     *******************/
-/******************************************************************/
-/* Set the growth threshold. We need one standard deviation for the
-   full detection so we take the light weighted center of the full
-   detected region and use that to find a standard deviation. Note
-   that we are using the sky subtracted input image so gradients don't
-   harm our results and that we only use pixels above the sky
-   value. */
-void
-prepfirstgrowth(struct clumpsthreadparams *ctp)
-{
-  struct gal_mesh_params *smp=&ctp->p->smp;
-
-  size_t *ind, *indf, is1=smp->s1;
-  float growlimit, *imgss=ctp->p->imgss;
-  double x=0.0f, y=0.0f, brightness=0.0f;
-  long *olab=ctp->p->olab, *clab=ctp->p->clab;
-
-  /* Try to find the flux weighted center (only on the pixels with
-     positive flux) */
-  indf=(ind=ctp->inds)+ctp->area;
-  do
-    if(imgss[*ind]>0.0f)
-      {
-        brightness+=imgss[*ind];
-        x+=(*ind/is1)*imgss[*ind];
-        y+=(*ind%is1)*imgss[*ind];
-      }
-  while(++ind<indf);
-
-  /* Calculate the center, if no pixels were positive, use the
-     geometric center (irrespective of flux). */
-  if(brightness==0.0f)
-    {
-      ind=ctp->inds;
-      do { x+=*ind/is1; y+=*ind%is1; } while(++ind<indf);
-      x/=ctp->area;
-      y/=ctp->area;
-    }
-  else
-    {
-      x/=brightness;
-      y/=brightness;
-    }
-
-  /* First find the standard deviation on this detection, then use
-     it to calculate the growth threshold. */
-  ctp->std=smp->garray2[gal_mesh_img_xy_to_mesh_id(smp, x, y)];
-  growlimit=ctp->p->gthresh * ctp->std;
-
-  /* Allocate and fill the array for the blank pixels and reset the
-     olab pixels while you are at it. Note that after removing false
-     clumps, usually most of the objects become blank, so we can just
-     allocate an area the size of the detection: */
-  errno=0;
-  ctp->blankinds=malloc(ctp->area*sizeof *ctp->blankinds);
-  if(ctp->blankinds==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for ctp->blankpixels in "
-          "prepfirstgrowth (clumps.c)", ctp->area*sizeof *ctp->blankinds);
-  ctp->numblanks=0;
-  indf=(ind=ctp->inds)+ctp->area;
-  do
-    {
-      olab[*ind]=clab[*ind];
-      if(olab[*ind]==SEGMENTINIT && imgss[*ind]>growlimit)
-        ctp->blankinds[ctp->numblanks++]=*ind;
-    }
-  while(++ind<indf);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*****************            Objects           *******************/
-/******************************************************************/
-void
-thisdetectionisoneobject(struct clumpsthreadparams *ctp)
-{
-  size_t *ind, *indf;
-  long *olab=ctp->p->olab;
-
-  indf=(ind=ctp->inds)+ctp->area;
-  do olab[*ind]=1; while(++ind<indf);
-}
-
-
-
-
-
-/* Find the adjacency matrixs (number, sum and signal to noise) for
-   the rivers between potentially separate objects in a detection
-   region. They have to be allocated prior to entering this funciton.
-
-   The way to find connected objects is through an adjacency
-   matrix. It is a square array with a side equal to numobjs. So to
-   see if regions `a` and `b` are connected. All I have to do is to
-   look at element a*numobjs+b or b*numobjs+a and get my answer. Since
-   the number of objects in a given region will not be too high, this
-   is efficient. */
-void
-adjacencymatrixs(struct clumpsthreadparams *ctp,
-                 double *sns, double *sums, int *nums)
-{
-  int rpnum;
-  float *imgss=ctp->p->imgss;
-  size_t numclumps=ctp->numclumps;
-  long wngb[WNGBSIZE], *olab=ctp->p->olab;
-  size_t i, j, ii, *n, *nf, ngb[8], numngb;
-  double ave, rpave, c=sqrt(1/ctp->p->cpscorr);
-  size_t *ind, *indf, is0=ctp->p->lmp.s0, is1=ctp->p->lmp.s1;
-  double err=ctp->std*ctp->std*(ctp->p->skysubtracted?1.0f:2.0f);
-
-  /* Go over all the still-unlabeled pixels and see which labels they
-     touch. */
-  indf = (ind=ctp->inds) + ctp->area;
-  do
-    if( olab[*ind]==SEGMENTINIT && !isnan(imgss[*ind]) )
-      {
-        /* Initialize the values to be used: */
-        ii=0;
-        rpnum=1;
-        rpave=imgss[*ind];
-        memset(wngb, 0, sizeof(wngb));
-
-        /* Find which grown clumps this river pixel touches.      */
-        GAL_NEIGHBORS_FILL_8_ALLIMG;
-        nf=(n=ngb)+numngb;
-        do
-          if( olab[*n]>0 )
-            {
-              if(!isnan(imgss[*n])) /* Add the flux of this neighbor */
-                {                   /* pixel for finding the average */
-                  ++rpnum;          /* of this river pixel later.    */
-                  rpave+=imgss[*n];
-                }
-              for(i=0;i<ii;++i)
-                if(wngb[i]==olab[*n])
-                  break;
-              if(i==ii)             /* label not yet added to wngb.  */
-                {
-                  wngb[ii]=olab[*n];
-                  ++ii;
-                }
-            }
-        while(++n<nf);
-
-        /* If more than one neighboring label was found, fill in the
-           'sums' and 'nums' adjacency matrixs with the values for
-           this pixel. Recall that ii is the number of neighboring
-           labels to this river pixel. */
-        if(ii>1)
-          {
-            rpave/=rpnum;
-            for(i=0;i<ii;++i)
-              for(j=0;j<ii;++j)
-                if(i!=j)
-                  {
-                    nums[ wngb[i] * numclumps + wngb[j] ]++;
-                    sums[ wngb[i] * numclumps + wngb[j] ]+=rpave;
-                  }
-          }
-      }
-  while(++ind<indf);
-
-
-  /* Calculate the Signal to noise ratio of the rivers. Here, ii is
-     the index in the adjacency matrix. */
-  for(i=0;i<numclumps;++i)
-    for(j=0;j<i;++j)
-      if( nums [ ii=i*numclumps+j ] ) /* There is a connection! */
-        {
-          ave = sums[ii]/nums[ii];
-          /* In case the average is nagive (only possible if sums is
-             negative), forget it. Note that even an area of 1 is
-             acceptable, and we put no area criteria here, because the
-             fact that a river exists between two clumps is
-             important. */
-          if( ave<0 )
-            {
-              nums[ii]=nums[j*numclumps+i]=0;
-              sums[ii]=sums[j*numclumps+i]=0;
-            }
-          /* Everything is ready, calculate the SN for this river:  */
-          else
-            /* Calculate the SN for this river and put it in both
-               sections of the SN adjacency matrix. Note that here we
-               want the average SN of the river, not the total. This
-               is why we haven't included the number of pixels. */
-            sns[ii] = sns[j*numclumps+i] = c * ave / sqrt(ave+err);
-        }
-
-  /* To check the matrix specific detected region:
-  if(ctp->thislabel==104)
-    for(i=1;i<numclumps;++i)
-      {
-        printf("%zu: \n", i);
-        for(j=1;j<numclumps;++j)
-          if(nums[ i * numclumps + j])
-            printf("   %zu: %-4d %-10.2f %-10.3f\n", j,
-                   nums[i*numclumps+j],
-                   sums[i*numclumps+j]/nums[i*numclumps+j],
-                   sns[i*numclumps+j]);
-        printf("\n");
-      }
-  */
-}
-
-
-
-
-
-/* The true clumps were expanded. Here the job is to create two
-   adjacency matrixs, which will keep the brightness (sum of pixel
-   values) on the rivers between two neighbouring objects. Note that
-   since growth was not extended to cover the whole image, some
-   objects might be totally isolated from others with no rivers
-   existing between them. To find the unique neighbours of each river
-   pixel, I will be using the same `wngb[]` and `ii` introduced in
-   segmentinfo() of clumps.c.
-*/
-void
-grownclumpstoobjects(struct clumpsthreadparams *ctp)
-{
-  int *nums;
-  double *sums, *sns;
-  long *olab=ctp->p->olab;
-  size_t i, j, ii, *ind, *indf;
-  size_t numclumps=ctp->numclumps;
-
-
-  /* Allocate the necessary arrays: */
-  errno=0; nums=calloc(numclumps*numclumps, sizeof *nums);
-  if(nums==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for nums in grownclumpstoobjects "
-          "(segmentation.c)", numclumps*numclumps*sizeof *nums);
-  errno=0; sums=calloc(numclumps*numclumps, sizeof *sums);
-  if(sums==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for sums in grownclumpstoobjects "
-          "(segmentation.c)", numclumps*numclumps*sizeof *sums);
-  errno=0; sns=calloc(numclumps*numclumps, sizeof *sns);
-  if(sns==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for sns in grownclumpstoobjects "
-          "(segmentation.c)", numclumps*numclumps*sizeof *sns);
-
-
-  /* Find the signal to noise adjacency matrix for these grown
-     clumps. */
-  adjacencymatrixs(ctp, sns, sums, nums);
-
-
-  /* Remove the connections that are smaller than the required
-     threshold. Note that we don't need to worry about the number of
-     pixels, because each river pixels's value was the average of its
-     self and its 8 neighbors. Note that these river pixels are also
-     in systematically low valued regions, which is exactly what we
-     want, so they aren't completely random and any area is
-     important. Connections will be based on the `nums' array. So if a
-     connection is severed, its place in nums will be set to zero. */
-  for(i=1;i<numclumps;++i)
-    for(j=1;j<i;++j)
-      if( nums[ ii=i*numclumps+j ] < ctp->p->minriverlength
-          || sns[ii] < ctp->p->objbordersn )
-        nums[ ii ] = nums[ j*numclumps+i ]=0;
-
-
-  /* Find the connected regions and assign new labels (starting
-     from one) to the grown clumps regions. */
-  ctp->numobjects=BF_concomp_AdjMatrix(nums, numclumps, &ctp->segtoobjlabs);
-
-
-  /* Correct all the pixels in olab: */
-  indf = (ind=ctp->inds) + ctp->area;
-  do
-    if(olab[*ind]>0)
-      olab[*ind]=ctp->segtoobjlabs[ olab[*ind] ];
-  while(++ind<indf);
-
-
-  /* Clean up */
-  free(sns);
-  free(nums);
-  free(sums);
-}
-
-
-
-
-
-/* When there is more than one object over a detection and there is
-   more than one clump over the detected region, the clumps have to be
-   re-labeled. The clumps have to be re-labeled based on which object
-   they overlap with.*/
-void
-newclumplabels(struct clumpsthreadparams *ctp)
-{
-  long *clab=ctp->p->clab;
-  size_t i, *ind, *indf, *numclumpsinobj;
-  long *newclumplabs, *segtoobjlabs=ctp->segtoobjlabs;
-
-  /* A simple sanity check. */
-  if(ctp->numclumps<=2 || ctp->numobjects<=2)
-    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
-          "it. For some reason, the newclumplabels function (in "
-          "segmentation.c) was called for the %zu detected region, even "
-          "though this region has ctp->numclumps=%zu and "
-          "ctp->numobjects=%zu! This function should only be used when "
-          "there is more than one object and clump over a detected region",
-          PACKAGE_BUGREPORT, ctp->thislabel, ctp->numclumps,
-          ctp->numobjects);
-
-  /* 'numclumpsinobj' will keep the number of clumps in each object.
-     Unlike the numbers of objects and clumps, this is the actual
-     number of clumps in an object, NOT ADDED WITH ONE. */
-  errno=0;
-  numclumpsinobj=calloc(ctp->numobjects, sizeof *numclumpsinobj);
-  if(numclumpsinobj==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for numclumpsinobj in "
-          "newclumplabels (segmentation.c)",
-          ctp->numobjects*sizeof *numclumpsinobj);
-
-
-  /* Allocate the array to keep the new clump labels.  */
-  errno=0;
-  newclumplabs=calloc(ctp->numclumps, sizeof *newclumplabs);
-  if(newclumplabs==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for newclumplabs in "
-          "newclumplabels (segmentation.c)",
-          ctp->numclumps*sizeof *newclumplabs);
-
-
-  /* Fill the newclumplabs and numclumpsinobj arrays: */
-  for(i=1;i<ctp->numclumps;++i)
-    newclumplabs[i]=++numclumpsinobj[ segtoobjlabs[i] ];
-
-
-  /* Reset the clump labels over the detected region */
-  indf=(ind=ctp->inds)+ctp->area;
-  do
-    if(clab[*ind]>0)
-      clab[*ind]=newclumplabs[ clab[*ind] ];
-  while(++ind<indf);
-
-
-  /* Clean up: */
-  free(newclumplabs);
-  free(numclumpsinobj);
-}
-
-
-
-
-
-/* We are potentially dealing with multiple threads which will get to
-   this point at various (asynchronous) times. However, the total
-   object and clump counters in noisechiselparams should only be
-   accessed by one thread at a time. Therefore we have defined the
-   totalnummtx mutex to make threads wait at this point and not allow
-   multiple threads to change these two variables simultaneously. */
-void
-nextavailablelabel(struct clumpsthreadparams *ctp)
-{
-  size_t numclumps = ( (ctp->p->grownclumps && ctp->numclumps<3) ?
-                       1 : ctp->numclumps-1 );
-
-  /* If we are using multiple threads, lock the mutex, so only this
-     thread can change the p->numobjects and p->numclumps values. */
-  if(ctp->p->cp.numthreads>1)
-    pthread_mutex_lock(ctp->totalnummtx);
-
-  ctp->firstavailablelab  = ctp->p->numobjects;
-  ctp->p->numobjects     += ctp->numobjects-1;
-  ctp->p->numclumps      += numclumps;
-
-  /* This thread is finished with the mutex, unlock it for the
-     other threads: */
-  if(ctp->p->cp.numthreads>1)
-    pthread_mutex_unlock(ctp->totalnummtx);
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*****************         Segmentation         *******************/
-/******************************************************************/
-void *
-segmentonthread(void *inparam)
-{
-  struct clumpsthreadparams *ctp=(struct clumpsthreadparams *)inparam;
-  struct noisechiselparams *p=ctp->p;
-
-  float *sntable;
-  char *segmentationname=p->segmentationname;
-  size_t i, *ind, *indf, s0=p->lmp.s0, s1=p->lmp.s1;
-
-  /* For the detections, there is no box, only the sides of the image. */
-  ctp->x1=s0;
-  ctp->y1=s1;
-  ctp->x0=ctp->y0=0;
-
-  /* Go over all the initial detections that were assigned to this
-     thread. */
-  for(i=0;ctp->indexs[i]!=GAL_THREADS_NON_THRD_INDEX;++i)
-    if(ctp->indexs[i])   /* sp->indexs[i]==0 for the background. */
-      {
-        /* Keep the initial label of this detection. The initial label
-           is mainly stored for possible debugging and checking. */
-        ctp->thislabel=ctp->indexs[i];
-        ctp->area=ctp->allareas[ctp->thislabel];
-        ctp->inds=ctp->alllabinds[ctp->thislabel];
-
-
-        /* Allocate the space for the indexs of the brightest pixels
-           in each clump of this detection. We don't know how many
-           clumps there are before hand, so to be safe just allocate a
-           space equal to the number of pixels*/
-        errno=0; ctp->topinds=malloc(ctp->area*sizeof *ctp->topinds);
-        if(ctp->topinds==NULL)
-          error(EXIT_FAILURE, errno, "%zu bytes for ctp->topinds in "
-                "segmentonthread (segmentation.c)",
-                ctp->area*sizeof *ctp->topinds);
-
-
-        /* Oversegment this detection. */
-        oversegment(ctp);
-        if(segmentationname && p->stepnum==1)
-          {free(ctp->topinds); continue;}
-
-
-        /* Get the Signal to noise ratio of all the clumps within this
-           detection. */
-        clumpsntable(ctp, &sntable);
-
-        /* Remove clumps with smaller signal to noise ratios and free
-           all the nolonger necessary arrays: */
-        removefalseclumps(ctp, sntable);
-        free(ctp->topinds);
-        free(sntable);
-        if(segmentationname && p->stepnum==2) continue;
-
-
-        /* Segmenting objects can only be defined when there is more
-           than one segment. Since ctp->numclumps is the number of
-           clumps+1, if an object has more than one clump,
-           p->numclumps will be larger than two. When there is only
-           one segment (p->numseg==2) or none (p->numseg==1), then
-           just set the required preliminaries to make the next steps
-           be generic for all cases. */
-        if(ctp->numclumps<=2)
-          {
-            ctp->numobjects=2;
-            thisdetectionisoneobject(ctp);
-            if(segmentationname && ( p->stepnum>=3 && p->stepnum<=6) )
-              continue;
-
-            /* If the grown clumps are desired in the output, then
-               replace all these grown clumps with those in
-               p->clab. */
-            if(p->grownclumps)
-              {
-                indf=(ind=ctp->inds)+ctp->area;
-                do p->clab[*ind]=p->olab[*ind]; while(++ind<indf);
-              }
-          }
-        else
-          {
-            /* Grow the true clumps until the growth limit. */
-            prepfirstgrowth(ctp);
-            growclumps(ctp, 1);
-            if(segmentationname && p->stepnum==3)
-              { free(ctp->blankinds); continue; }
-
-            /* If the grown clumps are desired in the output, then
-               replace all these grown clumps with those in
-               p->clab. */
-            if(p->grownclumps)
-              {
-                indf=(ind=ctp->inds)+ctp->area;
-                do p->clab[*ind]=p->olab[*ind]; while(++ind<indf);
-              }
-
-            /* Identify the objects within the grown clumps and set
-               ctp->numobjects. This function allocates
-               ctp->segtoobjlabs. */
-            grownclumpstoobjects(ctp);
-            if(segmentationname && p->stepnum==4)
-              { free(ctp->blankinds); free(ctp->segtoobjlabs); continue; }
-
-            /* Fill in the full detected area. */
-            if(ctp->numclumps<=2)
-              /* There is only one object in this whole detection. So
-                 automatically, the whole region should get a label of
-                 1. Do that with this function. */
-              thisdetectionisoneobject(ctp);
-            else
-              {
-                /* Grow the clumps unconditionally to fill the
-                   remaining blank pixels. */
-                ctp->numblanks=0; indf=(ind=ctp->inds)+ctp->area;
-                do
-                  if(p->olab[*ind]<0) ctp->blankinds[ctp->numblanks++]=*ind;
-                while(++ind<indf);
-                growclumps(ctp, 0);
-              }
-            if(segmentationname && p->stepnum==5)
-              { free(ctp->blankinds); free(ctp->segtoobjlabs); continue; }
-
-            /* Set the final clump labels. Note that this is only
-               necessary when there is more than object over the
-               detection. When there is only one object over the full
-               detection or if there is only one clump, the existing
-               clump labels are fine. Note that both these counters
-               are one more than the total number of objects or clumps
-               (they are the labels of the next object). */
-            if(ctp->numobjects>2)
-              newclumplabels(ctp);
-            if(segmentationname && p->stepnum==6)
-              { free(ctp->blankinds); free(ctp->segtoobjlabs); continue; }
-
-            /* Clean up */
-            free(ctp->blankinds);
-            free(ctp->segtoobjlabs);
-          }
-
-
-        /* Get the next available unique label for the final image. */
-        nextavailablelabel(ctp);
-
-
-        /* Fix all the labels in the olab array */
-        indf=(ind=ctp->inds)+ctp->area;
-        do p->olab[*ind] += ctp->firstavailablelab-1; while(++ind<indf);
-      }
-
-  /* Wait until all the threads finish: */
-  if(p->cp.numthreads>1)
-    pthread_barrier_wait(ctp->b);
-  return NULL;
-}
-
-
-
-
-
-void
-segmentdetections(struct noisechiselparams *p, size_t numobjsinit,
-                  size_t *allareas, size_t **alllabinds)
-{
-  int err;
-  pthread_t t; /* We don't use the thread id, so all are saved here. */
-  pthread_attr_t attr;
-  pthread_barrier_t b;
-  pthread_mutex_t totalnummtx;
-  struct clumpsthreadparams *ctp;
-  size_t i, nb, *indexs, thrdcols;
-  size_t numthreads=p->cp.numthreads;
-
-
-  /* Allocate the arrays to keep the thread and parameters for each
-     thread. */
-  errno=0; ctp=malloc(numthreads*sizeof *ctp);
-  if(ctp==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes in segmentdetections "
-          "(segmentation.c) for ctp", numthreads*sizeof *ctp);
-
-
-  /* Distribute the initial labels between all the threads.  */
-  gal_threads_dist_in_threads(numobjsinit, numthreads, &indexs, &thrdcols);
-
-  /* Spin off the threads to work on each object if more than one
-     thread will be used. If not, simply start working on all the
-     detections. */
-  if(numthreads==1)
-    {
-      ctp[0].p=p;
-      ctp[0].id=0;
-      ctp[0].indexs=indexs;
-      ctp[0].allareas=allareas;
-      ctp[0].alllabinds=alllabinds;
-      segmentonthread(&ctp[0]);
-    }
-  else
-    {
-      /* Initialize the attributes. Note that this running thread
-         (that spinns off the nt threads) is also a thread, so the
-         number the barrier should be one more than the number of
-         threads spinned off. */
-      if(numobjsinit<numthreads) nb=numobjsinit+1;
-      else                       nb=numthreads+1;
-      gal_threads_attr_barrier_init(&attr, &b, nb);
-
-      /* Initialize the mutex for the number of objects. */
-      pthread_mutex_init(&totalnummtx, NULL);
-
-      /* Spin off the threads: */
-      for(i=0;i<numthreads;++i)
-        if(indexs[i*thrdcols]!=GAL_THREADS_NON_THRD_INDEX)
-          {
-            ctp[i].p=p;
-            ctp[i].id=i;
-            ctp[i].b=&b;
-            ctp[i].allareas=allareas;
-            ctp[i].alllabinds=alllabinds;
-            ctp[i].totalnummtx=&totalnummtx;
-            ctp[i].indexs=&indexs[i*thrdcols];
-            err=pthread_create(&t, &attr, segmentonthread, &ctp[i]);
-            if(err) error(EXIT_FAILURE, 0, "can't create thread %zu", i);
-          }
-
-      /* Wait for all threads to finish and free the spaces. */
-      pthread_barrier_wait(&b);
-      pthread_attr_destroy(&attr);
-      pthread_barrier_destroy(&b);
-      pthread_mutex_destroy(&totalnummtx);
-    }
-
-  free(ctp);
-  free(indexs);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/******************************************************************/
-/*****************         Main function        *******************/
-/******************************************************************/
-/* This function is intended for cases when the user doesn't want
-   segmentation. In such cases, a suitable clumps array is necessary
-   for consistency with cases when they do want clumps. So this array
-   will just initialize all the elements in clab that lie over an
-   object with SEGMENTINIT and it will set all the non-masked pixels
-   in it to zero.*/
-void
-clabwithnoseg(long *olab, long *clab, size_t size, int anyblank)
-{
-  long *end=olab+size;
-
-  if(anyblank)
-    do
-      *clab++ = ( *olab==GAL_DATA_BLANK_LONG ? GAL_DATA_BLANK_LONG
-                  : ( *olab>0 ? SEGMENTINIT : 0 ) );
-    while(++olab<end);
-  else
-    do
-      *clab++ =  *olab>0 ? SEGMENTINIT : 0 ;
-    while(++olab<end);
-}
-
-
-
-
-
-void
-segmentation(struct noisechiselparams *p)
-{
-  unsigned char *b;
-  char *extname=NULL;
-  long *l, *lf, *forfits=NULL;
-  size_t i, s0=p->smp.s0, s1=p->smp.s1;
-  char *segmentationname=p->segmentationname;
-  size_t *labareas, **labinds, numobjsinit=p->numobjects;
-
-
-  /* Start off the counter for the number of objects and clumps. The
-     value to these variables will be the label that is given to the
-     next clump or object found. Note that we stored a copy of the
-     initial number of objects in the numobjsinit variable above.*/
-  p->numclumps=1;
-  p->numobjects=1;
-
-
-
-  /* Start the steps image: */
-  if(segmentationname)
-    {
-      gal_fits_array_to_file(segmentationname, "Input", FLOAT_IMG,
-                             p->img, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-      gal_fits_array_to_file(segmentationname,
-                             "Convolved-SkySubtracted", FLOAT_IMG,
-                             p->conv, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-      gal_fits_array_to_file(segmentationname, "InitialLabels",
-                             LONG_IMG, p->olab, s0, s1, p->anyblank,
-                             p->wcs, NULL, SPACK_STRING);
-    }
-
-
-
-  /* p->clab was used once during detection, we have to reset it to
-     zero. Note that olab will be initialized for each object later
-     on. Since we don't want to care about how clab was set an used,
-     here we simply re-set all the blank pixels too. If there aren't
-     any blank pixels, then just do a memset with no conditionals.*/
-  if(p->anyblank)
-    {
-      b=p->byt;lf=(l=p->clab)+s0*s1;
-      do *l = *b++==GAL_DATA_BLANK_UCHAR ? GAL_DATA_BLANK_LONG
-           : 0; while(++l<lf);
-    }
-  else
-    memset(p->clab, 0, s0*s1*sizeof *p->clab);
-
-
-
-  /* Find the true clump S/N threshold over the image. */
-  p->b0f1=0;
-  findclumpsn(p);
-  if(p->segmentationname)
-    {
-      gal_fits_array_to_file(p->segmentationname,
-                             "Noise Oversegmentaion", LONG_IMG,
-                             p->clab, p->smp.s0, p->smp.s1,
-                             p->anyblank, p->wcs, NULL, SPACK_STRING);
-    }
-
-
-
-  /* Initialize p->clab for the clumps within objects. */
-  if(p->anyblank)
-    {
-      lf=(l=p->clab)+s0*s1;
-      do *l = *l==GAL_DATA_BLANK_LONG ? GAL_DATA_BLANK_LONG
-           : 0; while(++l<lf);
-    }
-  else memset(p->clab, 0, s0*s1*sizeof *p->clab);
-
-
-
-  /* Save the indexs of all the detected labels. We will be working on
-     each label independently: */
-  labindexs(p->olab, s0*s1, numobjsinit, &labareas, &labinds);
-
-
-
-  /* Segment the detections. When the viewer wants to check the steps,
-     the operations have to be repeated multiple times to output each
-     step. */
-  p->b0f1=1;
-  if(p->segmentationname)
-    {
-      p->stepnum=1;
-      while(p->stepnum<8)
-        {
-
-          if(p->anyblank)
-            {
-              lf=(l=p->clab)+s0*s1;
-              do *l = *l==GAL_DATA_BLANK_LONG ? GAL_DATA_BLANK_LONG
-                   : 0; while(++l<lf);
-            }
-          else memset(p->clab, 0, s0*s1*sizeof *p->clab);
-
-          segmentdetections(p, numobjsinit, labareas, labinds);
-
-          switch(p->stepnum)
-            {
-            case 1:
-              extname="Over-segmentation"; forfits=p->clab; break;
-            case 2:
-              extname="Successful clumps"; forfits=p->clab; break;
-            case 3:
-              extname="Clumps grown"; forfits=p->olab; break;
-            case 4:
-              extname="Objects found"; forfits=p->olab; break;
-            case 5:
-              extname="Objects grown"; forfits=p->olab; break;
-            case 6:
-              extname="New clump labels"; forfits=p->clab; break;
-            case 7:
-              extname="Final object labels"; forfits=p->olab; break;
-            default:
-              error(EXIT_FAILURE, 0, "a bug! Please contact us at %s to "
-                    "fix the problem. For some reason, the variable "
-                    "p->stepnum in segmenation (segmentation.c) has the "
-                    "unrecognized value of %d", PACKAGE_BUGREPORT,
-                    p->stepnum);
-            }
-          gal_fits_array_to_file(p->segmentationname, extname,
-                                 LONG_IMG, forfits, s0, s1,
-                                 p->anyblank, p->wcs, NULL,
-                                 SPACK_STRING);
-          ++p->stepnum;
-        }
-    }
-  else
-    segmentdetections(p, numobjsinit, labareas, labinds);
-
-
-  /* Clean up */
-  for(i=0;i<numobjsinit;++i) free(labinds[i]);
-  free(labareas);
-  free(labinds);
-}
diff --git a/bin/noisechisel/sky.c b/bin/noisechisel/sky.c
deleted file mode 100644
index d27d19f..0000000
--- a/bin/noisechisel/sky.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <gnuastro/mesh.h>
-#include <gnuastro/qsort.h>
-#include <gnuastro/statistics.h>
-
-#include "main.h"
-
-#include "sky.h"
-
-void *
-avestdonthread(void *inparam)
-{
-  struct gal_mesh_thread_params *mtp=(struct gal_mesh_thread_params *)inparam;
-  struct gal_mesh_params *mp=mtp->mp;
-  struct noisechiselparams *p=(struct noisechiselparams *)mp->params;
-
-  float *mponeforall=mp->oneforall;
-  float *oneforall=&mponeforall[mtp->id*mp->maxs0*mp->maxs1];
-
-  unsigned char *byt, *inbyt=p->byt;
-  size_t s0, s1, ind, start, is1=mp->s1;
-  float *f, *img, *imgend, *inimg=p->img;
-  float ave, med, std, minbfrac=p->minbfrac;
-  size_t i, num, row, *indexs=&mp->indexs[mtp->id*mp->thrdcols];
-
-  /* Start this thread's work: */
-  for(i=0;indexs[i]!=GAL_THREADS_NON_THRD_INDEX;++i)
-    {
-      /* Prepare the values: */
-      num=row=0;
-      f=oneforall;
-      ind=indexs[i];
-      start=mp->start[ind];
-      s0=mp->ts0[mp->types[ind]];
-      s1=mp->ts1[mp->types[ind]];
-
-      /* Copy all the non-NaN pixels images pixels of this mesh into
-         the mesh array. Note that currently, the spatial positioning
-         of the pixels is irrelevant, so we only keep those that are
-         non-NaN. Recall that both the convolved an unconvolved image
-         have the same NaN pixels.*/
-      do
-        {
-          byt = inbyt + start + row*is1;
-          imgend=(img = inimg + start + row++ * is1 ) + s1;
-          do
-            /* Only input pixels that have byt==0 (note that NaN
-               pixels have a non-zero byt value.) */
-            if(*byt++==0)
-              {
-                ++num;
-                *f++ = *img;
-              }
-          while(++img<imgend);
-        }
-      while(row<s0);
-
-      /* Do the desired operation on the mesh, all the meshs were
-         initialized to NaN, so if they don't fit the criteria, they
-         can just be ignored. */
-      if( (float)num/(float)(s0*s1)>minbfrac )
-        {
-          /* Sort the array of values: */
-          qsort(oneforall, num, sizeof *oneforall, gal_qsort_float_increasing);
-
-          /* Do sigma-clipping and save the result if it is
-             accurate. */
-          if(gal_statistics_sigma_clip_converge(oneforall, 1, num,
-                                                p->sigclipmultip,
-                                                p->sigcliptolerance, &ave,
-                                                &med, &std, 0))
-            {
-              mp->garray1[ind]=ave;
-              mp->garray2[ind]=std;
-            }
-        }
-    }
-
-  /* Free any allocated space and if multiple threads were used, wait
-     until all other threads finish. */
-  if(mp->numthreads>1)
-    pthread_barrier_wait(&mp->b);
-  return NULL;
-}
-
-
-
-
-
-/* Using the smaller mesh and the p->byt array, find the average and
-   standard deviation of the undetected pixels and put them in the
-   smp->garray1 and smp->garray2 arrays. This function will be used
-   multiple times, the outputs for each should be different. So it
-   takes the second argument as the name.*/
-void
-findavestdongrid(struct noisechiselparams *p, char *outname)
-{
-  struct gal_mesh_params *smp=&p->smp;
-  size_t s0=smp->s0, s1=smp->s1;
-
-
-
-  /* Find the average and standard deviation */
-  gal_mesh_operate_on_mesh(smp, avestdonthread, sizeof(float), 1, 1);
-  if(outname)
-    {
-      if(smp->meshbasedcheck==0)
-        gal_fits_array_to_file(outname, "Detected", BYTE_IMG, p->byt, s0,
-                               s1, p->anyblank, p->wcs, NULL, SPACK_STRING);
-      gal_mesh_value_file(smp, outname, "Calculated Sky", "Calculated Sky STD",
-                          p->wcs, SPACK_STRING);
-    }
-
-
-
-  /* In case the image is in electrons or counts per second, the
-     standard deviation of the noise will become smaller than
-     unity. You have to find the minimum STD value (which is always
-     positive) for later corrections. The maximum STD is only
-     calculated here to include in the output headers so MakeCatalog
-     can read it and not have to go through the whole STD array (which
-     is the size of the full image for it). */
-  p->medstd=gal_statistics_median(smp->garray2, smp->nmeshi);
-  gal_statistics_f_min_max(smp->garray2, smp->nmeshi, &p->minstd, &p->maxstd);
-  p->cpscorr = p->minstd>1 ? 1.0f : p->minstd;
-
-
-
-  /* Interpolate over the meshs to fill all the blank ones in both the
-     sky and the standard deviation arrays: */
-  gal_mesh_interpolate(smp,
-                       "Interpolating sky value and its standard deviation");
-  if(outname)
-    gal_mesh_value_file(smp, outname, "Interpolated Sky",
-                        "Interpolated Sky STD", p->wcs, SPACK_STRING);
-
-
-
-  /* Smooth the interpolated array:  */
-  if(smp->smoothwidth>1)
-    {
-      gal_mesh_smooth(smp);
-      if(outname)
-        gal_mesh_value_file(smp, outname, "Smoothed Sky", "Smoothed Sky STD",
-                            p->wcs, SPACK_STRING);
-    }
-}
-
-
-
-
-
-/* Using the p->byt array find the sky value on the input and
-   convolved images. Then subtract the sky value from both and save
-   the standard deviation for every pixel in p->std. */
-void
-findsubtractskyconv(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *smp=&p->smp;
-
-  float *f, *fp, *tmpg1, *tmpg2, *tmpimg;
-  size_t gid, s0, s1, row, start, chbasedid, is1=smp->s1;
-  float csky, *tmpcg1, *tmpcg2, *tmpfg1, *tmpfg2, *convsky;
-
-
-  /* Replace the necessary arrays to find the sky value on the
-     convolved image. */
-  tmpimg=p->img;          /* Keep backup pointers to the main arrays.  */
-  tmpg1=smp->garray1;           tmpg2=smp->garray2;
-  tmpcg1=smp->cgarray1;         tmpcg2=smp->cgarray2;
-  tmpfg1=smp->fgarray1;         tmpfg2=smp->fgarray2;
-
-  p->img=smp->img=p->conv;  /* Prepare for working on convolved image. */
-  smp->cgarray1=smp->cgarray2=NULL;
-  smp->fgarray1=smp->fgarray2=NULL;
-  findavestdongrid(p, NULL);
-
-  convsky=smp->garray1;                /* Keep garray1, free the rest. */
-  if(smp->garray1==smp->cgarray1)  free(smp->fgarray1);
-  else                             free(smp->cgarray1);
-  free(smp->cgarray2);             free(smp->fgarray2);
-
-  p->img=smp->img=tmpimg;          /* Set back to their previous state */
-  smp->garray1=tmpg1;           smp->garray2=tmpg2;
-  smp->cgarray1=tmpcg1;         smp->cgarray2=tmpcg2;
-  smp->fgarray1=tmpfg1;         smp->fgarray2=tmpfg2;
-
-
-  /* Subtract the sky */
-  for(gid=0;gid<smp->nmeshi;++gid)
-    {
-      /* Get the meshid from i: */
-      chbasedid=gal_mesh_ch_based_id_from_gid(smp, gid);
-
-      /* Subtract the sky for each pixel. */
-      row=0;
-      csky = convsky[gid];
-      start=smp->start[chbasedid];
-      s0=smp->ts0[smp->types[chbasedid]];
-      s1=smp->ts1[smp->types[chbasedid]];
-      do
-        {
-          fp= ( f = p->conv + start + row++ * is1 ) + s1;
-          do *f++ -= csky; while(f<fp);
-        }
-      while(row<s0);
-    }
-
-  /* Clean up: */
-  free(convsky);
-}
-
-
-
-
-
-void
-subtractskyimg(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *smp=&p->smp;
-
-  float *f, *fp, *in, sky;
-  size_t gid, s0, s1, row, start, chbasedid, is1=smp->s1;
-
-  /* Apply the threshold */
-  for(gid=0;gid<smp->nmeshi;++gid)
-    {
-      /* Get the meshid from i: */
-      chbasedid=gal_mesh_ch_based_id_from_gid(smp, gid);
-
-      /* Subtract the sky for each pixel. */
-      row=0;
-      sky = smp->garray1[gid];
-      start=smp->start[chbasedid];
-      s0=smp->ts0[smp->types[chbasedid]];
-      s1=smp->ts1[smp->types[chbasedid]];
-      do
-        {
-          in = p->img + start + row * is1;
-          fp= ( f = p->imgss + start + row++ * is1 ) + s1;
-          do *f = *in++ - sky; while(++f<fp);
-        }
-      while(row<s0);
-    }
-}
diff --git a/bin/noisechisel/sky.h b/bin/noisechisel/sky.h
deleted file mode 100644
index cc9f393..0000000
--- a/bin/noisechisel/sky.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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/>.
-**********************************************************************/
-#ifndef SKY_H
-#define SKY_H
-
-void
-findavestdongrid(struct noisechiselparams *p, char *outname);
-
-void
-findsubtractskyconv(struct noisechiselparams *p);
-
-void
-subtractskyimg(struct noisechiselparams *p);
-
-#endif
diff --git a/bin/noisechisel/thresh.c b/bin/noisechisel/thresh.c
deleted file mode 100644
index b9b1f28..0000000
--- a/bin/noisechisel/thresh.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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 <gnuastro/qsort.h>
-#include <gnuastro/statistics.h>
-#include <gnuastro/spatialconvolve.h>
-
-#include <timing.h>
-#include <checkset.h>
-
-#include "main.h"
-#include "binary.h"
-#include "noisechisel.h"
-
-
-
-
-
-
-
-
-
-
-/*********************************************************************/
-/***************        Quantile threshold       *********************/
-/*********************************************************************/
-void *
-qthreshonmesh(void *inparam)
-{
-  struct gal_mesh_thread_params *mtp=(struct gal_mesh_thread_params *)inparam;
-  struct gal_mesh_params *mp=mtp->mp;
-  struct noisechiselparams *p=(struct noisechiselparams *)mp->params;
-
-  float *mponeforall=mp->oneforall;
-  float *oneforall=&mponeforall[mtp->id*mp->maxs0*mp->maxs1];
-
-  size_t modeindex=(size_t)(-1);
-  size_t s0, s1, ind, row, num, start, is1=mp->s1;
-  size_t i, *indexs=&mp->indexs[mtp->id*mp->thrdcols];
-  float *f, *img, *imgend, *inimg=p->conv, modesym=0.0f;
-  float mirrordist=mp->mirrordist, minmodeq=mp->minmodeq;
-
-  /* Start this thread's work: */
-  for(i=0;indexs[i]!=GAL_THREADS_NON_THRD_INDEX;++i)
-    {
-      /* Prepare the values: */
-      num=row=0;
-      f=oneforall;
-      ind=indexs[i];
-      start=mp->start[ind];
-      s0=mp->ts0[mp->types[ind]];
-      s1=mp->ts1[mp->types[ind]];
-
-      /* Copy all the non-NaN pixels images pixels of this mesh into
-         the mesh array. Note that currently, the spatial positioning
-         of the pixels is irrelevant, so we only keep those that are
-         non-NaN.*/
-      do
-        {
-          imgend=(img = inimg + start + row++ * is1 ) + s1;
-          do
-            if(!isnan(*img))
-            {
-              ++num;
-              *f++ = *img;
-            }
-          while(++img<imgend);
-        }
-      while(row<s0);
-
-      /* Do the desired operation on the mesh: */
-      if(num)
-        {
-          qsort(oneforall, num, sizeof *oneforall,
-                gal_qsort_float_increasing);
-          gal_statistics_mode_index_in_sorted(oneforall, num, mirrordist,
-                                              &modeindex, &modesym);
-          if( modesym>GAL_STATISTICS_MODE_SYM_GOOD
-              && (float)modeindex/(float)num>minmodeq)
-            {
-              mp->garray1[ind] = oneforall[
-                 gal_statistics_index_from_quantile(num, p->qthresh) ];
-              mp->garray2[ind] = oneforall[
-                 gal_statistics_index_from_quantile(num, p->noerodequant) ];
-            }
-        }
-    }
-
-  /* Free alltype and if multiple threads were used, wait until all
-     other threads finish. */
-  if(mp->numthreads>1)
-    pthread_barrier_wait(&mp->b);
-  return NULL;
-}
-
-
-
-
-
-/* The threshold values are stored in the garray1 array of the
-   gal_mesh_params structure. This function is basically identical to the
-   gal_mesh_check_garray function in mesh.c, only in the middle, it does
-   something else.
-
-   See the comments there to better understand the process.
-*/
-void
-applythreshold(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *mp=&p->smp; /* `mp' instead of `smp' so you     */
-                                      /* can try with p->lmp if you like. */
-  float qthreshv, nethreshv;
-  unsigned char *b, *byt=p->byt;
-  size_t gs0=mp->gs0, gs1=mp->gs1, nch1=mp->nch1;
-  size_t s0, s1, fs1=mp->gs1*mp->nch1, chid, inchid;
-  float *f, *fp, *garray1=mp->garray1, *array=p->conv;
-  size_t *types=mp->types, *ts0=mp->ts0, *ts1=mp->ts1;
-  size_t i, f0, f1, nmeshi=mp->nmeshi, nmeshc=mp->nmeshc;
-  size_t row, startind, *start=mp->start, meshid, is1=mp->s1;
-
-  /* Fill the array: */
-  for(i=0;i<nmeshi;++i)
-    {
-      /* Set the proper meshid. */
-      if(garray1==mp->fgarray1)
-        {
-          f0=i/fs1;
-          f1=i%fs1;
-          inchid = (f0%gs0) * gs1  + f1%gs1;
-          chid   = (f0/gs0) * nch1 + f1/gs1;
-          meshid = chid * nmeshc + inchid;
-        }
-      else meshid=i;
-
-      /* Fill the output array with the value in this mesh: */
-      row=0;
-      qthreshv=garray1[i];
-      s0=ts0[types[meshid]];
-      s1=ts1[types[meshid]];
-      startind=start[meshid];
-      nethreshv=mp->garray2[i];
-      do
-        {
-          b  = byt + startind + row * is1;
-          fp = ( f = array + startind + row * is1 ) + s1;
-          do
-            /* The image might have NaN pixels too, in which case any
-               comparison will fail and the value in `b' will be 0, This is
-               no problem, after this loop, all NaN pixels will be set to a
-               fixed blank value. */
-            *b++ = ( *f>qthreshv
-                     ? ( *f>nethreshv ? BINARYNOOP : 1 )
-                     : 0 );
-          while(++f<fp);
-          ++row;
-        }
-      while(row<s0);
-    }
-
-  /* If there are any NaN pixels (in the float image), set them to the
-     blank value for the unsigned character type. */
-  if(p->anyblank) setbytblank(p->img, p->byt, p->smp.s0*p->smp.s1);
-}
-
-
-
-
-
-void
-findapplyqthreshold(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *mp=&p->smp;
-
-  /* Find the threshold on each mesh that has the proper conditions. */
-  gal_mesh_operate_on_mesh(mp, qthreshonmesh, sizeof(float), 1, 1);
-  if(p->threshname)
-    gal_mesh_value_file(mp, p->threshname, "Quantile threshold value",
-                        "No erode threshold value", p->wcs, SPACK_STRING);
-
-  /* Interpolate to have a value for each mesh. */
-  gal_mesh_interpolate(mp, "Interpolating quantile threshold");
-  if(p->threshname)
-    gal_mesh_value_file(mp, p->threshname, "qthreshv interpolated",
-                        "nethreshv interpolated", p->wcs, SPACK_STRING);
-
-  /* Smooth the interpolation  */
-  gal_mesh_smooth(mp);
-  if(p->threshname)
-    gal_mesh_value_file(mp, p->threshname, "qthreshv smoothed",
-                        "nethreshv smoothed", p->wcs, SPACK_STRING);
-
-  /* Apply the threshold on all the pixels: */
-  applythreshold(p);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*********************************************************************/
-/**************      Average and STD threshold     *******************/
-/*********************************************************************/
-/* This is very similar to the gal_mesh_check_garray function. The sky and its
-   Standard deviation are stored in the garray1 and garray2 arrays of
-   smp gal_mesh_params structure. */
-void
-applydetectionthresholdskysub(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *smp=&p->smp;
-
-  size_t is0=smp->s0;
-  float *f, *in, sky, std;
-  float dthresh=p->dthresh;
-  unsigned char *b, *bf, *dbyt;
-  size_t gid, row, start, chbasedid, *types=smp->types;
-  size_t s0, s1, is1=smp->s1, *ts0=smp->ts0, *ts1=smp->ts1;
-
-  /* Allocate the array to keep the threshold value: */
-  errno=0; dbyt=p->dbyt=malloc(is0*is1*sizeof *p->dbyt);
-  if(dbyt==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for dbyt in "
-          "applydetectionthreshold (detection.c)", is0*is1*sizeof *dbyt);
-
-
-  /* Apply the threshold */
-  for(gid=0;gid<smp->nmeshi;++gid)
-    {
-      /* Get the meshid from i: */
-      chbasedid=gal_mesh_ch_based_id_from_gid(smp, gid);
-
-      /* Fill the output array with the value in this mesh: */
-      row=0;
-      sky = smp->garray1[gid];
-      std = smp->garray2[gid];
-      s0=ts0[types[chbasedid]];
-      s1=ts1[types[chbasedid]];
-      start=smp->start[chbasedid];
-      do
-        {
-          in = p->img + start + row*is1;
-          f = p->imgss + start + row*is1;
-          bf= ( b = dbyt + start + row++ * is1) + s1;
-          do
-            {
-              /* The threshold is always very low. So for the majority
-                 of non-NaN pixels in the image, the condition above
-                 will be true. If we come over a NaN pixel, then by
-                 definition of NaN, all conditionals will fail.
-
-                 The benefit of this method of testing is that if an
-                 image doesn't have any NaN pixels, only the pixels
-                 below the threshold have to be checked for a NaN
-                 which are by definition a very small fraction of the
-                 total pixels. And if there are NaN pixels in the
-                 image, they will be checked. */
-              *b = ( (*f++=*in-sky) > dthresh*std
-                     ? 1
-                     : isnan(*in) ? GAL_DATA_BLANK_UCHAR : 0 );
-              ++in;
-            }
-          while(++b<bf);
-        }
-      while(row<s0);
-    }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*********************************************************************/
-/***************      S/N Quantile threshold     *********************/
-/*********************************************************************/
-void
-snthresh(struct noisechiselparams *p, float *sntable, size_t size,
-         int det0seg1)
-{
-  double sn;
-  char report[200], cline[1000];
-  char *job = det0seg1 ? "Clump" : "Detection";
-  float quant = det0seg1 ? p->segquant : p->detquant;
-  char *name = det0seg1 ? "clumps" : "pseudo-detections";
-  char *histname= det0seg1 ? p->clumpsnhist : p->detectionsnhist;
-  size_t snhistnbins= det0seg1 ? p->clumpsnhistnbins : p->detsnhistnbins;
-
-
-  /* Check if the number is acceptable to the user. */
-  if(size<p->minnumfalse)
-    error(EXIT_FAILURE, 0, "there are only %zu %s in the sky region of "
-          "the image. This is smaller than the minimum number you "
-          "specified: %zu. You can decrease this minimum with the "
-          "`--minnumfalse' (`-F') option or you can decrease the other "
-          "parameters that determine the %s. See the GNU Astronomy "
-          "Utilities manual (section on NoiseChisel) or Akhlaghi and "
-          "Ichikawa (2015) for more information", size, name,
-          p->minnumfalse, name);
-
-
-  /* Sort the signal to noise ratios and remove their outliers */
-  qsort(sntable, size, sizeof *sntable, gal_qsort_float_increasing);
-
-
-  /* Store the SN value. */
-  sn=sntable[gal_statistics_index_from_quantile(size, quant)];
-  if(p->cp.verb)
-    {
-      sprintf(report, "%s S/N: %.3f (%.3f quantile of %zu %s).",
-              job, sn, quant, size, name);
-      gal_timing_report(NULL, report, 2);
-    }
-
-  /* Put the S/N value in its proper place. */
-  if(det0seg1) p->clumpsn = sn;
-  else         p->detsn   = sn;
-
-
-  /* If the user has asked for it, make the histogram of the S/N
-     distribution. */
-  if(snhistnbins)
-    {
-      /* For a check:
-         if(ind!=0) continue;
-         ff=(f=sntable)+numlabs; do printf("%f\n", *f++); while(f<ff);
-      */
-
-      /* histname has to be set to NULL so gal_checkset_automatic_output can
-         safey free it. */
-      sprintf(cline, "# %s\n# %s started on %s"
-              "# Input: %s (hdu: %s)\n"
-              "# S/N distribution histogram of %zu sky %s.\n"
-              "# The %.3f quantile has an S/N of %.4f.",
-              SPACK_STRING, SPACK_NAME, ctime(&p->rawtime),
-              p->up.inputname, p->cp.hdu, size, name, quant, sn);
-      gal_statistics_save_hist(sntable, size, snhistnbins, histname, cline);
-      free(histname);
-    }
-}
diff --git a/bin/noisechisel/thresh.h b/bin/noisechisel/thresh.h
deleted file mode 100644
index 7ca16fd..0000000
--- a/bin/noisechisel/thresh.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
-NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
-
-Original author:
-     Mohammad Akhlaghi <address@hidden>
-Contributing author(s):
-Copyright (C) 2015, 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/>.
-**********************************************************************/
-#ifndef THRESH_H
-#define THRESH_H
-
-void
-findapplyqthreshold(struct noisechiselparams *p);
-
-void
-applydetectionthresholdskysub(struct noisechiselparams *p);
-
-void
-snthresh(struct noisechiselparams *p, float *sntable, size_t size,
-         int det0seg1);
-
-#endif
diff --git a/bin/noisechisel/threshold.c b/bin/noisechisel/threshold.c
new file mode 100644
index 0000000..2a58e08
--- /dev/null
+++ b/bin/noisechisel/threshold.c
@@ -0,0 +1,330 @@
+/*********************************************************************
+NoiseChisel - Detect and segment signal in a noisy dataset.
+NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+Copyright (C) 2015, 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 <string.h>
+#include <stdlib.h>
+
+#include <gnuastro/fits.h>
+#include <gnuastro/blank.h>
+#include <gnuastro/threads.h>
+#include <gnuastro/statistics.h>
+#include <gnuastro/interpolate.h>
+
+#include <timing.h>
+
+#include "main.h"
+
+#include "ui.h"
+#include "threshold.h"
+
+
+
+
+/****************************************************************
+ ************           Quantile threshold           ************
+ ****************************************************************/
+struct qthreshparams
+{
+  gal_data_t        *erode_th;
+  gal_data_t      *noerode_th;
+  void                 *usage;
+  struct noisechiselparams *p;
+};
+
+
+
+
+
+static void *
+qthresh_on_tile(void *in_prm)
+{
+  struct gal_threads_params *tprm=(struct gal_threads_params *)in_prm;
+  struct qthreshparams *qprm=(struct qthreshparams *)tprm->params;
+  struct noisechiselparams *p=qprm->p;
+
+  double *darr;
+  void *tarray=NULL;
+  int type=qprm->erode_th->type;
+  gal_data_t *tile, *mode, *qvalue, *usage, *tblock=NULL;
+  size_t i, tind, twidth=gal_type_sizeof(type), ndim=p->input->ndim;
+
+  /* Put the temporary usage space for this thread into a data set for easy
+     processing. */
+  usage=gal_data_alloc(gal_data_ptr_increment(qprm->usage,
+                                              tprm->id*p->maxtcontig, type),
+                       type, ndim, p->maxtsize, NULL, 0, p->cp.minmapsize,
+                       NULL, NULL, NULL);
+
+  /* Go over all the tiles given to this thread. */
+  for(i=0; tprm->indexs[i] != GAL_THREADS_NON_THRD_INDEX; ++i)
+    {
+      /* Re-initialize the usage array's space (will be changed in
+         `gal_data_copy_to_allocated' for each tile). */
+      usage->ndim=ndim;
+      usage->size=p->maxtcontig;
+      memcpy(usage->dsize, p->maxtsize, ndim*sizeof *p->maxtsize);
+
+
+      /* Copy the tile's contents into the pre-allocated space. Note that
+         we have to initialize the `dsize' and `size' elements of
+         `contents', since they can be changed and the size is
+         important. Recall that this is a 1D array. */
+      tind = tprm->indexs[i];
+      tile = &p->cp.tl.tiles[tind];
+
+
+      /* If we have a convolved image, temporarily change the tile's
+         pointers so we can do the work on the convolved image. */
+      if(p->conv)
+        {
+          tarray=tile->array; tblock=tile->block;
+          tile->array=gal_tile_block_relative_to_other(tile, p->conv);
+          tile->block=p->conv;
+        }
+      gal_data_copy_to_allocated(tile, usage);
+      if(p->conv) { tile->array=tarray; tile->block=tblock; }
+
+
+      /* Find the mode on this dataset, note that we have set the `inplace'
+         flag to `1'. So as a byproduct of finding the mode, `usage' is not
+         going to have any blank elements and will be sorted (thus ready to
+         be used by the quantile functions). */
+      mode=gal_statistics_mode(usage, p->mirrordist, 1);
+
+
+      /* Check the mode value. Note that if the mode is not accurate, then
+         the contents of `darr' will be NaN and all conditions will
+         fail. In such cases, the tile will be ignored. */
+      darr=mode->array;
+      if( fabs(darr[1]-0.5f) < p->modmedqdiff )
+        {
+          /* Get the erosion quantile for this tile and save it. Note that
+             the type of `qvalue' is the same as the input dataset. */
+          qvalue=gal_statistics_quantile(usage, p->qthresh, 1);
+          memcpy(gal_data_ptr_increment(qprm->erode_th->array, tind, type),
+                 qvalue->array, twidth);
+          gal_data_free(qvalue);
+
+          /* Do the same for the no-erode quantile. */
+          qvalue=gal_statistics_quantile(tile, p->noerodequant, 1);
+          memcpy(gal_data_ptr_increment(qprm->noerode_th->array, tind, type),
+                 qvalue->array, twidth);
+          gal_data_free(qvalue);
+        }
+      else
+        {
+          gal_blank_write(gal_data_ptr_increment(qprm->erode_th->array,
+                                                 tind, type), type);
+          gal_blank_write(gal_data_ptr_increment(qprm->noerode_th->array,
+                                                 tind, type), type);
+        }
+
+      /* Clean up and fix the tile's pointers. */
+      gal_data_free(mode);
+    }
+
+  /* Clean up and wait for the other threads to finish, then return. */
+  usage->array=NULL;  /* Not allocated here. */
+  gal_data_free(usage);
+  if(tprm->b) pthread_barrier_wait(tprm->b);
+  return NULL;
+}
+
+
+
+
+
+static void
+apply_quantile_threshold(struct qthreshparams *qprm)
+{
+  size_t tid;
+  void *tarray=NULL;
+  gal_data_t *tile, *tblock=NULL;
+  struct noisechiselparams *p=qprm->p;
+  float *erode_th=qprm->erode_th->array, *noerode_th=qprm->noerode_th->array;
+
+  /* A small sanity check. */
+  if(qprm->erode_th->type!=GAL_TYPE_FLOAT32)
+    error(EXIT_FAILURE, 0, "`apply_quantile_threshold' currently only "
+          "supports float arrays.");
+
+  /* Clear the binary array (this is mainly because the input may contain
+     blank values and we won't be doing the thresholding no those
+     pixels. */
+  memset(p->binary->array, 0, p->binary->size);
+
+  /* Go over all the tiles. */
+  for(tid=0; tid<p->cp.tl.tottiles;++tid)
+    {
+      /* For easy reading. */
+      tile=&p->cp.tl.tiles[tid];
+
+      /* Correct the tile's pointers to apply the threshold on the
+         convolved image. */
+      if(p->conv)
+        {
+          tarray=tile->array; tblock=tile->block;
+          tile->array=gal_tile_block_relative_to_other(tile, p->conv);
+          tile->block=p->conv;
+        }
+
+      /* Apply the threshold. */
+      GAL_TILE_PARSE_OPERATE({
+          *o = ( *i > erode_th[tid]
+                 ? ( *i > noerode_th[tid] ? THRESHOLD_NO_ERODE_VALUE : 1 )
+                 : 0 );
+        }, tile, p->binary, 1, 1);
+
+      /* Revert the tile's pointers back to what they were. */
+      if(p->conv) { tile->array=tarray; tile->block=tblock; }
+    }
+}
+
+
+
+
+
+void
+threshold_quantile_find_apply(struct noisechiselparams *p)
+{
+  char *msg;
+  gal_data_t *tmp;
+  struct timeval t1;
+  struct qthreshparams qprm;
+  struct gal_options_common_params *cp=&p->cp;
+  struct gal_tile_two_layer_params *tl=&cp->tl;
+
+
+  /* Get the starting time if necessary. */
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
+
+
+  /* Add image to check image if requested. If the user has asked for
+     `oneelempertile', then the size of values is not going to be the same
+     as the input, making it hard to inspect visually. So we'll only put
+     the full input when `oneelempertile' isn't requested. */
+  if(p->qthreshname && !tl->oneelempertile)
+    gal_fits_img_write(p->conv ? p->conv : p->input, p->qthreshname, NULL,
+                       PROGRAM_STRING);
+
+
+  /* Allocate space for the quantile threshold values. */
+  qprm.erode_th=gal_data_alloc(NULL, p->input->type, p->input->ndim,
+                               tl->numtiles, NULL, 0, cp->minmapsize,
+                               "QTHRESH-ERODE", p->input->unit, NULL);
+  qprm.noerode_th=gal_data_alloc(NULL, p->input->type, p->input->ndim,
+                                 tl->numtiles, NULL, 0, cp->minmapsize,
+                                 "QTHRESH-NOERODE", p->input->unit, NULL);
+
+
+  /* Allocate temporary space for processing in each tile. */
+  qprm.usage=gal_data_malloc_array(p->input->type,
+                                   cp->numthreads * p->maxtcontig);
+
+  /* Find the threshold on each tile, then clean up the temporary space. */
+  qprm.p=p;
+  gal_threads_spin_off(qthresh_on_tile, &qprm, tl->tottiles, cp->numthreads);
+  if(p->qthreshname)
+    {
+      gal_tile_full_values_write(qprm.erode_th, tl, p->qthreshname,
+                                 PROGRAM_STRING);
+      gal_tile_full_values_write(qprm.noerode_th, tl, p->qthreshname,
+                                 PROGRAM_STRING);
+    }
+  free(qprm.usage);
+
+
+  /* Interpolate over the blank tiles. */
+  qprm.erode_th->next = qprm.noerode_th;
+  tmp=gal_interpolate_close_neighbors(qprm.erode_th, tl, cp->interpnumngb,
+                                      cp->numthreads, cp->interponlyblank, 1);
+  gal_data_free(qprm.erode_th);
+  gal_data_free(qprm.noerode_th);
+  qprm.erode_th=tmp;
+  qprm.noerode_th=tmp->next;
+  qprm.erode_th->next=qprm.noerode_th->next=NULL;
+  if(p->qthreshname)
+    {
+      gal_tile_full_values_write(qprm.erode_th, tl, p->qthreshname,
+                                 PROGRAM_STRING);
+      gal_tile_full_values_write(qprm.noerode_th, tl, p->qthreshname,
+                                 PROGRAM_STRING);
+    }
+
+
+  /* Smooth the threshold if requested. */
+  if(p->smoothwidth>1)
+    {
+      /* Do the smoothing on the erosion quantile. */
+      if(!cp->quiet) gettimeofday(&t1, NULL);
+      tmp=gal_tile_full_values_smooth(qprm.erode_th, tl, p->smoothwidth,
+                                      p->cp.numthreads);
+      gal_data_free(qprm.erode_th);
+      qprm.erode_th=tmp;
+
+      /* Same for the no-erosion quantile. */
+      tmp=gal_tile_full_values_smooth(qprm.noerode_th, tl, p->smoothwidth,
+                                      p->cp.numthreads);
+      gal_data_free(qprm.noerode_th);
+      qprm.noerode_th=tmp;
+
+      /* Add them to the check image. */
+      if(p->qthreshname)
+        {
+          gal_tile_full_values_write(qprm.erode_th, tl, p->qthreshname,
+                                     PROGRAM_STRING);
+          gal_tile_full_values_write(qprm.noerode_th, tl, p->qthreshname,
+                                     PROGRAM_STRING);
+        }
+    }
+
+
+  /* The quantile threshold is found, now apply it. */
+  apply_quantile_threshold(&qprm);
+
+
+  /* Write the binary image if check is requested. */
+  if(p->qthreshname && !tl->oneelempertile)
+    gal_fits_img_write(p->binary, p->qthreshname, NULL, PROGRAM_STRING);
+
+
+  /* Clean up and report duration if necessary. */
+  gal_data_free(qprm.erode_th);
+  gal_data_free(qprm.noerode_th);
+  if(!p->cp.quiet)
+    {
+      asprintf(&msg, "%.2f quantile threshold found and applied.",
+               p->qthresh);
+      gal_timing_report(&t1, msg, 2);
+    }
+
+
+  /* If the user wanted to check the threshold and hasn't called
+     `continueaftercheck', then stop NoiseChisel. */
+  if(p->qthreshname && !p->continueaftercheck)
+    ui_abort_after_check(p, p->qthreshname, "quantile threshold check");
+}
diff --git a/bin/noisechisel/segmentation.h b/bin/noisechisel/threshold.h
similarity index 82%
rename from bin/noisechisel/segmentation.h
rename to bin/noisechisel/threshold.h
index 3a46f33..2ffaceb 100644
--- a/bin/noisechisel/segmentation.h
+++ b/bin/noisechisel/threshold.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -20,13 +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 SEGMENTATION_H
-#define SEGMENTATION_H
+#ifndef THRESHOLD_H
+#define THRESHOLD_H
 
-void
-clabwithnoseg(long *olab, long *clab, size_t size, int anyblank);
+#define THRESHOLD_NO_ERODE_VALUE 2
 
 void
-segmentation(struct noisechiselparams *p);
+threshold_quantile_find_apply(struct noisechiselparams *p);
 
 #endif
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index b9603db..9f59689 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -22,608 +22,169 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
-#include <math.h>
-#include <stdio.h>
+#include <argp.h>
 #include <errno.h>
 #include <error.h>
-#include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
-#include <fitsio.h>
 
+#include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
-#include <gnuastro/array.h>
-#include <gnuastro/txtarray.h>
-#include <gnuastro/statistics.h>
+#include <gnuastro/threads.h>
+#include <gnuastro/dimension.h>
 
-#include <nproc.h>              /* From Gnulib.                   */
-#include <timing.h>             /* includes time.h and sys/time.h */
+#include <timing.h>
+#include <options.h>
 #include <checkset.h>
-#include <commonargs.h>
-#include <configfiles.h>
+#include <fixedstringmacros.h>
 
 #include "main.h"
 
-#include "ui.h"                  /* Needs main.h                   */
-#include "args.h"                /* Needs main.h, includes argp.h. */
-
-
-/* Set the file names of the places where the default parameters are
-   put. */
-#define CONFIG_FILE SPACK CONF_POSTFIX
-#define SYSCONFIG_FILE SYSCONFIG_DIR "/" CONFIG_FILE
-#define USERCONFIG_FILEEND USERCONFIG_DIR CONFIG_FILE
-#define CURDIRCONFIG_FILE CURDIRCONFIG_DIR CONFIG_FILE
-
-
-
-
-
+#include "ui.h"
+#include "authors-cite.h"
 
 
 
 
 
 /**************************************************************/
-/**************       Options and parameters    ***************/
+/*********      Argp necessary global entities     ************/
 /**************************************************************/
-void
-readconfig(char *filename, struct noisechiselparams *p)
+/* 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" Detects and segments signal "
+  "that is deeply burried in noise. It employs a noise-based detection and "
+  "segmentation method enabling it to be very resilient to the rich diversity "
+  "of shapes in astronomical targets.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
+
+
+/* Option groups particular to this program. */
+enum program_args_groups
 {
-  FILE *fp;
-  size_t lineno=0, len=200;
-  char *line, *name, *value;
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-  char key='a';        /* Not used, just a place holder. */
-
-  /* When the file doesn't exist or can't be opened, it is ignored. It
-     might be intentional, so there is no error. If a parameter is
-     missing, it will be reported after all defaults are read. */
-  fp=fopen(filename, "r");
-  if (fp==NULL) return;
-
-
-  /* Allocate some space for `line` with `len` elements so it can
-     easily be freed later on. The value of `len` is arbitarary at
-     this point, during the run, getline will change it along with the
-     pointer to line. */
-  errno=0;
-  line=malloc(len*sizeof *line);
-  if(line==NULL)
-    error(EXIT_FAILURE, errno, "ui.c: %zu bytes in readdefaults",
-          len * sizeof *line);
+  ARGS_GROUP_DETECTION = GAL_OPTIONS_GROUP_AFTER_COMMON,
+  ARGS_GROUP_SEGMENTATION,
+};
 
-  /* Read the tokens in the file:  */
-  while(getline(&line, &len, fp) != -1)
-    {
-      /* Prepare the "name" and "value" strings, also set lineno. */
-      GAL_CONFIGFILES_START_READING_LINE;
 
 
-      /* Inputs: */
-      if(strcmp(name, "hdu")==0)
-        gal_checkset_allocate_copy_set(value, &cp->hdu, &cp->hduset);
 
-      else if(strcmp(name, "mask")==0)
-        gal_checkset_allocate_copy_set(value, &up->maskname,
-                                       &up->masknameset);
 
-      else if(strcmp(name, "mhdu")==0)
-        gal_checkset_allocate_copy_set(value, &up->mhdu, &up->mhduset);
 
-      else if(strcmp(name, "kernel")==0)
-        gal_checkset_allocate_copy_set(value, &up->kernelname,
-                                       &up->kernelnameset);
 
-      else if(strcmp(name, "khdu")==0)
-        gal_checkset_allocate_copy_set(value, &up->khdu, &up->khduset);
 
-      else if(strcmp(name, "skysubtracted")==0)
-        {
-          if(up->skysubtractedset) continue;
-          gal_checkset_int_zero_or_one(value, &p->skysubtracted, name,
-                                       key, SPACK, filename, lineno);
-          up->skysubtractedset=1;
-        }
-      else if(strcmp(name, "minbfrac")==0)
-        {
-          if(up->minbfracset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->minbfrac, name,
-                                     key, SPACK, filename, lineno);
-          up->minbfracset=1;
-        }
-      else if(strcmp(name, "minnumfalse")==0)
-        {
-          if(up->minnumfalseset) continue;
-          gal_checkset_sizet_l_zero(value, &p->minnumfalse, name,
-                                    key, SPACK, filename, lineno);
-          up->minnumfalseset=1;
-        }
 
 
 
-      /* Outputs */
-      else if(strcmp(name, "output")==0)
-        gal_checkset_allocate_copy_set(value, &cp->output, &cp->outputset);
 
-      else if(strcmp(name, "grownclumps")==0)
-        {
-          if(up->grownclumpsset) continue;
-          gal_checkset_int_zero_or_one(value, &p->grownclumps, name,
-                                       key, SPACK, filename, lineno);
-          up->grownclumpsset=1;
-        }
 
 
-      /* Mesh grid: */
-      else if(strcmp(name, "smeshsize")==0)
-        {
-          if(up->smeshsizeset) continue;
-          gal_checkset_sizet_l_zero(value, &p->smp.meshsize, name,
-                                    key, SPACK, filename, lineno);
-          up->smeshsizeset=1;
-        }
-      else if(strcmp(name, "lmeshsize")==0)
-        {
-          if(up->lmeshsizeset) continue;
-          gal_checkset_sizet_l_zero(value, &p->lmp.meshsize, name,
-                                    key, SPACK, filename, lineno);
-          up->lmeshsizeset=1;
-        }
-      else if(strcmp(name, "nch1")==0)
-        {
-          if(up->nch1set) continue;
-          gal_checkset_sizet_l_zero(value, &p->smp.nch1, name, key,
-                                    SPACK, filename, lineno);
-          up->nch1set=1;
-        }
-      else if(strcmp(name, "nch2")==0)
-        {
-          if(up->nch2set) continue;
-          gal_checkset_sizet_l_zero(value, &p->smp.nch2, name, key,
-                                    SPACK, filename, lineno);
-          up->nch2set=1;
-        }
-      else if(strcmp(name, "lastmeshfrac")==0)
-        {
-          if(up->lastmeshfracset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->smp.lastmeshfrac, name,
-                                     key, SPACK, filename, lineno);
-          up->lastmeshfracset=1;
-        }
-      else if(strcmp(name, "mirrordist")==0)
-        {
-          if(up->mirrordistset) continue;
-          gal_checkset_float_l_0(value, &p->smp.mirrordist, name,
-                                 key, SPACK, filename, lineno);
-          up->mirrordistset=1;
-        }
-      else if(strcmp(name, "minmodeq")==0)
-        {
-          if(up->minmodeqset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->smp.minmodeq, name,
-                                     key, SPACK, filename, lineno);
-          up->minmodeqset=1;
-        }
-      else if(strcmp(name, "numnearest")==0)
-        {
-          if(up->numnearestset) continue;
-          gal_checkset_sizet_l_zero(value, &p->smp.numnearest, name,
-                                    key, SPACK, filename, lineno);
-          up->numnearestset=1;
-        }
-      else if(strcmp(name, "smoothwidth")==0)
-        {
-          if(up->smoothwidthset) continue;
-          gal_checkset_sizet_p_odd(value, &p->smp.smoothwidth, name,
-                                   key, SPACK, filename, lineno);
-          up->smoothwidthset=1;
-        }
-      else if(strcmp(name, "fullconvolution")==0)
-        {
-          if(up->fullconvolutionset) continue;
-          gal_checkset_int_zero_or_one(value, &p->smp.fullconvolution,
-                                       name, key, SPACK, filename, lineno);
-          up->fullconvolutionset=1;
-        }
-      else if(strcmp(name, "fullinterpolation")==0)
-        {
-          if(up->fullinterpolationset) continue;
-          gal_checkset_int_zero_or_one(value, &p->smp.fullinterpolation,
-                                       name, key, SPACK, filename, lineno);
-          up->fullinterpolationset=1;
-        }
-      else if(strcmp(name, "fullsmooth")==0)
-        {
-          if(up->fullsmoothset) continue;
-          gal_checkset_int_zero_or_one(value, &p->smp.fullsmooth, name, key,
-                                       SPACK, filename, lineno);
-          up->fullsmoothset=1;
-        }
 
 
-      /* Detection: */
-      else if(strcmp(name, "qthresh")==0)
-        {
-          if(up->qthreshset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->qthresh, name, key,
-                                     SPACK, filename, lineno);
-          up->qthreshset=1;
-        }
-      else if(strcmp(name, "erode")==0)
-        {
-          if(up->erodeset) continue;
-          gal_checkset_sizet_el_zero(value, &p->erode, name, key,
-                                     SPACK, filename, lineno);
-          up->erodeset=1;
-        }
-      else if(strcmp(name, "erodengb")==0)
-        {
-          if(up->erodengbset) continue;
-          gal_checkset_int_4_or_8(value, &p->erodengb, name, key,
-                                  SPACK, filename, lineno);
-          up->erodengbset=1;
-        }
-      else if(strcmp(name, "noerodequant")==0)
-        {
-          if(up->noerodequantset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->noerodequant, name, key,
-                                     SPACK, filename, lineno);
-          up->noerodequantset=1;
-        }
-      else if(strcmp(name, "opening")==0)
-        {
-          if(up->openingset) continue;
-          gal_checkset_sizet_el_zero(value, &p->opening, name, key,
-                                     SPACK, filename, lineno);
-          up->openingset=1;
-        }
-      else if(strcmp(name, "openingngb")==0)
-        {
-          if(up->openingngbset) continue;
-          gal_checkset_int_4_or_8(value, &p->openingngb, name,
-                                  key, SPACK, filename, lineno);
-          up->openingngbset=1;
-        }
-      else if(strcmp(name, "sigclipmultip")==0)
-        {
-          if(up->sigclipmultipset) continue;
-          gal_checkset_float_l_0(value, &p->sigclipmultip, name,
-                                 key, SPACK, filename, lineno);
-          up->sigclipmultipset=1;
-        }
-      else if(strcmp(name, "sigcliptolerance")==0)
-        {
-          if(up->sigcliptoleranceset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->sigcliptolerance, name,
-                                     key, SPACK, filename, lineno);
-          up->sigcliptoleranceset=1;
-        }
-      else if(strcmp(name, "dthresh")==0)
-        {
-          if(up->dthreshset) continue;
-          gal_checkset_any_float(value, &p->dthresh, name, key,
-                                 SPACK, filename, lineno);
-          up->dthreshset=1;
-        }
-      else if(strcmp(name, "detsnminarea")==0)
-        {
-          if(up->detsnminareaset) continue;
-          gal_checkset_sizet_l_zero(value, &p->detsnminarea, name,
-                                    key, SPACK, filename, lineno);
-          up->detsnminareaset=1;
-        }
-      else if(strcmp(name, "detsnhistnbins")==0)
-        {
-          if(up->detsnhistnbinsset) continue;
-          gal_checkset_sizet_el_zero(value, &p->detsnhistnbins, name,
-                                     key, SPACK, filename, lineno);
-          up->detsnhistnbinsset=1;
-        }
-      else if(strcmp(name, "detquant")==0)
-        {
-          if(up->detquantset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->detquant, name, key,
-                                     SPACK, filename, lineno);
-          up->detquantset=1;
-        }
-      else if(strcmp(name, "dilate")==0)
-        {
-          if(up->dilateset) continue;
-          gal_checkset_sizet_el_zero(value, &p->dilate, name, key,
-                                     SPACK, filename, lineno);
-          up->dilateset=1;
-        }
 
 
-      /* Segmentation: */
-      else if(strcmp(name, "segsnminarea")==0)
-        {
-          if(up->segsnminareaset) continue;
-          gal_checkset_sizet_l_zero(value, &p->segsnminarea, name,
-                                    key, SPACK, filename, lineno);
-          up->segsnminareaset=1;
-        }
-      else if(strcmp(name, "keepmaxnearriver")==0)
-        {
-          if(up->keepmaxnearriverset) continue;
-          gal_checkset_int_zero_or_one(value, &p->keepmaxnearriver, name,
-                                       key, SPACK, filename, lineno);
-          up->keepmaxnearriverset=1;
-        }
-      else if(strcmp(name, "segquant")==0)
-        {
-          if(up->segquantset) continue;
-          gal_checkset_float_l_0_s_1(value, &p->segquant, name, key,
-                                     SPACK, filename, lineno);
-          up->segquantset=1;
-        }
-      else if(strcmp(name, "clumpsnhistnbins")==0)
-        {
-          if(up->clumpsnhistnbinsset) continue;
-          gal_checkset_sizet_el_zero(value, &p->clumpsnhistnbins, name,
-                                     key, SPACK,filename, lineno);
-          up->clumpsnhistnbinsset=1;
-        }
-      else if(strcmp(name, "gthresh")==0)
-        {
-          if(up->gthreshset) continue;
-          gal_checkset_any_float(value, &p->gthresh, name, key, SPACK,
-                                 filename, lineno);
-          up->gthreshset=1;
-        }
-      else if(strcmp(name, "minriverlength")==0)
-        {
-          if(up->minriverlengthset) continue;
-          gal_checkset_sizet_l_zero(value, &p->minriverlength, name,
-                                    key, SPACK, filename, lineno);
-          up->minriverlengthset=1;
-        }
-      else if(strcmp(name, "objbordersn")==0)
-        {
-          if(up->objbordersnset) continue;
-          gal_checkset_float_l_0(value, &p->objbordersn, name, key,
-                                 SPACK, filename, lineno);
-          up->objbordersnset=1;
-        }
+/**************************************************************/
+/*********    Initialize & Parse command-line    **************/
+/**************************************************************/
+static void
+ui_initialize_options(struct noisechiselparams *p,
+                      struct argp_option *program_options,
+                      struct argp_option *gal_commonopts_options)
+{
+  size_t i;
+  struct gal_options_common_params *cp=&p->cp;
 
 
-      /* Operating modes: */
-      /* Read options common to all programs */
-      GAL_CONFIGFILES_READ_COMMONOPTIONS_FROM_CONF
+  /* 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->numthreads         = gal_threads_number();
+  cp->coptions           = gal_commonopts_options;
 
 
-      else
-        error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                      "`%s` not recognized.\n", name);
+  /* 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_SEARCHIN:
+        case GAL_OPTIONS_KEY_IGNORECASE:
+        case GAL_OPTIONS_KEY_TABLEFORMAT:
+          cp->coptions[i].flags=OPTION_HIDDEN;
+          break;
+
+        case GAL_OPTIONS_KEY_TILESIZE:
+        case GAL_OPTIONS_KEY_MINMAPSIZE:
+        case GAL_OPTIONS_KEY_NUMCHANNELS:
+        case GAL_OPTIONS_KEY_INTERPNUMNGB:
+        case GAL_OPTIONS_KEY_REMAINDERFRAC:
+          cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+        }
     }
-
-  free(line);
-  fclose(fp);
 }
 
 
 
 
 
-void
-printvalues(FILE *fp, struct noisechiselparams *p)
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
 {
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-  struct gal_mesh_params *smp=&p->smp, *lmp=&p->lmp;
-
-  /* Print all the options that are set. Separate each group with a
-     commented line explaining the options in that group. */
-  fprintf(fp, "\n# Input:\n");
-  if(cp->hduset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("hdu", cp->hdu);
-  if(up->masknameset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("mask", up->maskname);
-  if(up->mhdu)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("mhdu", up->mhdu);
-  if(up->kernelnameset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("kernel", up->kernelname);
-  if(up->khdu)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("khdu", up->khdu);
-  if(up->skysubtractedset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "skysubtracted", p->skysubtracted);
-  if(up->minbfracset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "minbfrac", p->minbfrac);
-  if(up->minnumfalseset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "minnumfalse", p->minnumfalse);
-
-
-  fprintf(fp, "\n# Output:\n");
-  if(cp->outputset)
-    fprintf(fp, CONF_SHOWFMT"%s\n", "output", cp->output);
-  if(up->grownclumpsset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "grownclumps", p->grownclumps);
-
-
-  fprintf(fp, "\n# Mesh grid:\n");
-  if(up->smeshsizeset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "smeshsize", smp->meshsize);
-  if(up->lmeshsizeset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "lmeshsize", lmp->meshsize);
-  if(up->nch1set)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "nch1", smp->nch1);
-  if(up->nch2set)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "nch2", smp->nch2);
-  if(up->lastmeshfracset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "lastmeshfrac", smp->lastmeshfrac);
-  if(up->mirrordistset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "mirrordist", smp->mirrordist);
-  if(up->minmodeqset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "minmodeq", smp->minmodeq);
-  if(up->numnearestset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "numnearest", smp->numnearest);
-  if(up->smoothwidthset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "smoothwidth", smp->smoothwidth);
-  if(up->fullconvolutionset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "fullconvolution",
-            smp->fullconvolution);
-  if(up->fullinterpolationset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "fullinterpolation",
-            smp->fullinterpolation);
-  if(up->fullsmoothset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "fullsmooth", smp->fullsmooth);
-
-
-  fprintf(fp, "\n# Detection:\n");
-  if(up->qthreshset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "qthresh", p->qthresh);
-  if(up->erodeset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "erode", p->erode);
-  if(up->erodengbset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "erodengb", p->erodengb);
-  if(up->noerodequantset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "noerodequant", p->noerodequant);
-  if(up->openingset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "opening", p->opening);
-  if(up->openingngbset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "openingngb", p->openingngb);
-  if(up->sigclipmultipset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "sigclipmultip", p->sigclipmultip);
-  if(up->sigcliptoleranceset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "sigcliptolerance",
-            p->sigcliptolerance);
-  if(up->dthreshset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "dthresh", p->dthresh);
-  if(up->detsnminareaset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "detsnminarea", p->detsnminarea);
-  if(up->detsnhistnbinsset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "detsnhistnbins", p->detsnhistnbins);
-  if(up->detquantset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "detquant", p->detquant);
-  if(up->dilateset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "dilate", p->dilate);
-
-
-  fprintf(fp, "\n# Segmentation:\n");
-  if(up->segsnminareaset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "segsnminarea", p->segsnminarea);
-  if(up->keepmaxnearriverset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "keepmaxnearriver", p->keepmaxnearriver);
-  if(up->segquantset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "segquant", p->segquant);
-  if(up->clumpsnhistnbinsset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "clumpsnhistnbins", p->clumpsnhistnbins);
-  if(up->gthreshset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "gthresh", p->gthresh);
-  if(up->minriverlengthset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "minriverlength", p->minriverlength);
-  if(up->objbordersnset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "objbordersn", p->objbordersn);
-
-
-  /* For the operating mode, first put the macro to print the common
-     options, then the (possible options particular to this
-     program). */
-  fprintf(fp, "\n# Operating mode:\n");
-  GAL_CONFIGFILES_PRINT_COMMONOPTIONS;
-}
-
-
+  struct noisechiselparams *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->inputname)
+        argp_error(state, "only one argument (input file) should be given");
+      else
+        p->inputname=arg;
+      break;
 
 
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
 
-/* Note that numthreads will be used automatically based on the
-   configure time. */
-void
-checkifset(struct noisechiselparams *p)
-{
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-
-  int intro=0;
-  if(cp->hduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("hdu");
-  if(up->khduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("khdu");
-  if(up->skysubtractedset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("skysubtracted");
-  if(up->minbfracset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("minbfrac");
-  if(up->minnumfalseset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("minnumfalse");
-
-  /* Output */
-  if(up->grownclumpsset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("grownclumps");
-
-  /* Mesh grid: */
-  if(up->smeshsizeset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("smeshsize");
-  if(up->lmeshsizeset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("lmeshsize");
-  if(up->nch1set==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("nch1");
-  if(up->nch2set==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("nch2");
-  if(up->lastmeshfracset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("lastmeshfrac");
-  if(up->mirrordistset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("mirrordist");
-  if(up->minmodeqset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("minmodeq");
-  if(up->numnearestset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("numnearest");
-  if(up->smoothwidthset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("smoothwidth");
-  if(up->fullconvolutionset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("fullconvolution");
-  if(up->fullinterpolationset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("fullinterpolation");
-  if(up->fullsmoothset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("fullsmooth");
-
-  /* Detection: */
-  if(up->qthreshset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("qthresh");
-  if(up->erodeset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("erode");
-  if(up->erodengbset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("erodengb");
-  if(up->noerodequantset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("noerodequant");
-  if(up->openingset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("opening");
-  if(up->openingngbset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("openingngb");
-  if(up->sigclipmultipset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("sigclipmultip");
-  if(up->sigcliptoleranceset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("sigcliptolerance");
-  if(up->dthreshset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("dthresh");
-  if(up->detsnminareaset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("detsnminarea");
-  if(up->detsnhistnbinsset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("detsnhistnbins");
-  if(up->detquantset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("detquant");
-  if(up->dilateset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("dilate");
-
-  /* Segmentation: */
-  if(up->segsnminareaset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("segsnminarea");
-  if(up->keepmaxnearriverset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("keepmaxnearriver");
-  if(up->segquantset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("segquant");
-  if(up->clumpsnhistnbinsset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("clumpsnhistnbins");
-  if(up->gthreshset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("gthresh");
-  if(up->minriverlengthset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("minriverlength");
-  if(up->objbordersnset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("objbordersn");
-
-  GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
+  return 0;
 }
 
 
@@ -648,112 +209,66 @@ checkifset(struct noisechiselparams *p)
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
-void
-sanitycheck(struct noisechiselparams *p)
+/* 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 noisechiselparams *p)
 {
-  struct gal_mesh_params *smp=&p->smp;
-
-  /* Make sure the input file exists. */
-  gal_checkset_check_file(p->up.inputname);
-
-  /* Make sure that the noerode quantile is larger than qthresh. */
+  /* Make sure the connectivity is defined. */
+  if(p->erodengb!=4 && p->erodengb!=8)
+    error(EXIT_FAILURE, 0, "%zu not acceptable for `--erodengb'. It must "
+          "be 4 or 8 (specifying the type of connectivity)", p->erodengb);
+  if(p->openingngb!=4 && p->openingngb!=8)
+    error(EXIT_FAILURE, 0, "%zu not acceptable for `--openingngb'. It must "
+          "be 4 or 8 (specifying the type of connectivity)", p->openingngb);
+
+  /* Make sure that the no-erode-quantile is not smaller or equal to
+     qthresh. */
   if( p->noerodequant <= p->qthresh)
-    error(EXIT_FAILURE, 0, "The quantile for no erosion (`--noerodequant') "
+    error(EXIT_FAILURE, 0, "the quantile for no erosion (`--noerodequant') "
           "must be larger than the base quantile threshold (`--qthresh', "
           "or `-t'). You have provided %.4f and %.4f for the former and "
-          "latter, respectively.", p->noerodequant, p->qthresh);
+          "latter, respectively", p->noerodequant, p->qthresh);
+}
 
-  /* Set the maskname and mask hdu accordingly: */
-  gal_fits_file_or_ext_name(p->up.inputname, p->cp.hdu, p->up.masknameset,
-                                 &p->up.maskname, p->up.mhdu, p->up.mhduset,
-                                 "mask");
 
-  /* Set the output name: */
-  if(p->cp.output)
-    {
-      gal_checkset_check_remove_file(p->cp.output, p->cp.dontdelete);
 
-      /* When the output name is given (possibly with directory
-         information), the user certainly wants the directory
-         information, if they have bothered to include it. */
-      p->cp.removedirinfo=0;
 
-    }
-  else
-    gal_checkset_automatic_output(p->up.inputname, "_labeled.fits",
-                                  p->cp.removedirinfo, p->cp.dontdelete,
-                                  &p->cp.output);
 
-  /* Set the check image names: */
-  if(p->meshname)
-    {
-      p->meshname=NULL;         /* Was not allocated before!  */
-      gal_checkset_automatic_output(p->cp.output, "_meshs.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->meshname);
-    }
-  if(p->threshname)
-    {
-      p->threshname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_thresh.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->threshname);
-    }
-  if(p->detectionname)
-    {
-      p->detectionname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_det.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->detectionname);
-    }
-  if(p->detectionskyname)
-    {
-      p->detectionskyname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_detsky.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->detectionskyname);
-    }
-  if(p->detsnhistnbins)
-    {
-      p->detectionsnhist=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_detsn.txt",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->detectionsnhist);
-    }
-  if(p->skyname)
-    {
-      p->skyname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_sky.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->skyname);
-    }
-  if(p->segmentationname)
-    {
-      p->segmentationname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_seg.fits",
-                                    p->cp.removedirinfo,
-                                    p->cp.dontdelete, &p->segmentationname);
-    }
-  if(p->clumpsnhistnbins)
+static void
+ui_check_options_and_arguments(struct noisechiselparams *p)
+{
+  /* Basic input file checks. */
+  if(p->inputname)
     {
-      p->clumpsnhist=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_clumpsn.txt",
-                                    p->cp.removedirinfo,
-                                    p->cp.dontdelete, &p->clumpsnhist);
+      /* Check if it exists. */
+      gal_checkset_check_file(p->inputname);
+
+      /* If its FITS, see if a HDU has been provided. */
+      if( gal_fits_name_is_fits(p->inputname) && p->cp.hdu==NULL )
+        error(EXIT_FAILURE, 0, "no HDU specified for 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");
     }
-  if(p->maskdetname)
+  else
+    error(EXIT_FAILURE, 0, "no input file is specified");
+
+  /* Basic Kernel file checks. */
+  if(p->kernelname)
     {
-      p->maskdetname=NULL;
-      gal_checkset_automatic_output(p->cp.output, "_maskdet.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->maskdetname);
+      /* Check if it exists. */
+      gal_checkset_check_file(p->kernelname);
+
+      /* If its FITS, see if a HDU has been provided. */
+      if( gal_fits_name_is_fits(p->kernelname) && p->khdu==NULL )
+        error(EXIT_FAILURE, 0, "no HDU specified for kernel. When the "
+              "kernel is a FITS file, a HDU must also be specified, you "
+              "can use the `--khdu' option and give it the HDU number "
+              "(starting from zero), extension name, or anything "
+              "acceptable by CFITSIO");
     }
-
-  /* Other checks: */
-  if(smp->numnearest<GAL_MESH_MIN_ACCEPTABLE_NEAREST)
-    error(EXIT_FAILURE, 0, "the smallest possible number for `--numnearest' "
-          "(`-n') is %d. You have asked for: %zu",
-          GAL_MESH_MIN_ACCEPTABLE_NEAREST, smp->numnearest);
 }
 
 
@@ -774,200 +289,203 @@ sanitycheck(struct noisechiselparams *p)
 
 
 
+
 /**************************************************************/
 /***************       Preparations         *******************/
 /**************************************************************/
-/* The default PSF. It was created by saving the following commands in
-   a script and running it. The crop is because the first and last
-   rows of all PSFs made by MakeProfiles is blank (zero). You can keep
-   the spaces when copying and pasting ;-). Just make it executable
-   and run it.
+static void
+ui_set_output_names(struct noisechiselparams *p)
+{
+  char *output=p->cp.output;
+  char *basename = output ? output : p->inputname;
 
-   set -o errexit           # Stop if a program returns false.
-   echo "0    0.0    0.0   2   2   0   0   1   1   5" > tmp.txt
-   export GSL_RNG_TYPE=ranlxs2
-   export GSL_RNG_SEED=1
-   astmkprof tmp.txt --oversample=1 --envseed --numrandom=10000 \
-             --tolerance=0.01
-   astcrop 0.fits --section=2:*,2:* --zeroisnotblank --output=fwhm2.fits
-   astconvertt fwhm2.fits --output=fwhm2.txt
-   rm 0.fits tmp.fits *.log tmp.txt
-*/
-size_t defaultkernel_s0=11;
-size_t defaultkernel_s1=11;
-float defaultkernel[121]=
-  {
-    0, 0, 0, 0, 0, 2.58073e-08, 0, 0, 0, 0, 0,
+  /* Main program output. */
+  if(output)
+    {
+      /* Delete the file if it already exists. */
+      gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
 
-    0, 0, 2.90237e-08, 6.79851e-07, 4.4435e-06, 8.31499e-06,
-    4.50166e-06, 6.97185e-07, 3.00904e-08, 0, 0,
+      /* When the output name is given (possibly with directory
+         information), the check images will also be put in that same
+         directory.. */
+      p->cp.keepinputdir=1;
+    }
+  else
+    p->cp.output=gal_checkset_automatic_output(&p->cp, p->inputname,
+                                               "_labeled.fits");
+
+  /* Quantile threshold. */
+  if(p->checkqthresh)
+    p->qthreshname=gal_checkset_automatic_output(&p->cp, basename,
+                                                 "_qthresh.fits");
+
+  /* Initial detection Sky values. */
+  if(p->checkdetsky)
+    p->detskyname=gal_checkset_automatic_output(&p->cp, basename,
+                                                "_detsky.fits");
+
+  /* Pseudo-detection S/N values. */
+  if(p->checkdetsn)
+    p->detsnname=gal_checkset_automatic_output(&p->cp, basename,
+                                               "_detsn.txt");
+
+  /* Detection steps. */
+  if(p->checkdetection)
+    p->detectionname=gal_checkset_automatic_output(&p->cp, basename,
+                                               "_det.fits");
+
+  /* Detection steps. */
+  if(p->checksky)
+    p->skyname=gal_checkset_automatic_output(&p->cp, basename, "_sky.fits");
+
+  /* Clump S/N values. */
+  if(p->checkclumpsn)
+    p->clumpsnname=gal_checkset_automatic_output(&p->cp, basename,
+                                                 "_clumpsn.txt");
+
+  /* Segmentation steps. */
+  if(p->checksegmentation)
+    p->segmentationname=gal_checkset_automatic_output(&p->cp, basename,
+                                                      "_seg.txt");
 
-    0, 2.87873e-08, 2.48435e-06, 5.81339e-05, 0.000379508, 0.000709334,
-    0.000383714, 5.94125e-05, 2.56498e-06, 3.00032e-08, 0,
+}
 
-    0, 6.70501e-07, 5.77826e-05, 0.00134992, 0.00879665, 0.0164126,
-    0.00886609, 0.00137174, 5.92134e-05, 6.92853e-07, 0,
 
-    0, 4.3798e-06, 0.000376616, 0.00877689, 0.0570404, 0.106142, 0.0572108,
-    0.00883846, 0.000381257, 4.46059e-06, 0,
 
-    2.54661e-08, 8.24845e-06, 0.00070725, 0.0164287, 0.10639, 0.19727,
-    0.106003, 0.0163402, 0.000703951, 8.23152e-06, 2.55057e-08,
 
-    0, 4.5229e-06, 0.000386632, 0.00894947, 0.0577282, 0.106614, 0.0570877,
-    0.00877699, 0.000377496, 4.41036e-06, 0,
 
-    0, 7.1169e-07, 6.0678e-05, 0.00140013, 0.00899917, 0.0165582, 0.00883658,
-    0.00135509, 5.81823e-05, 6.79067e-07, 0,
+static void
+ui_prepare_kernel(struct noisechiselparams *p)
+{
+  /* The default kernel. It was created by saving the following commands in a
+     script and running it. It will create a plain text array along with a
+     FITS image. The crop is because the first and last rows and columns of
+     all PSFs made by MakeProfiles are blank (zero) when you run with
+     oversample=1. You can keep the spaces when copying and pasting ;-). Just
+     make it executable and run it.
+
+     set -o errexit           # Stop if a program returns false.
+     echo "0 0.0 0.0 3 2 0 0 1 1 5" > tmp.txt
+     export GSL_RNG_TYPE=ranlxs2
+     export GSL_RNG_SEED=1
+     astmkprof tmp.txt --oversample=1 --envseed --numrandom=10000 \
+     --tolerance=0.01 --nomerged
+     astcrop 0_tmp.fits --section=2:*-1,2:*-1 --zeroisnotblank    \
+     --output=fwhm2.fits
+     astconvertt fwhm2.fits --output=fwhm2.txt
+     rm 0_tmp.fits tmp.txt
+  */
+  size_t kernel_2d_dsize[2]={11,11};
+  float *f, *ff, *k, kernel_2d[121]=
+    {
+      0, 0, 0, 0, 0, 6.57699e-09, 0, 0, 0, 0, 0,
 
-    0, 3.12002e-08, 2.65502e-06, 6.11192e-05, 0.000391739, 0.000718637,
-    0.000382453, 5.85194e-05, 2.50864e-06, 2.9249e-08, 0,
+      0, 0, 6.57699e-09, 2.10464e-07, 1.68371e-06, 3.36742e-06, 1.68371e-06,
+      2.10464e-07, 6.57699e-09, 0, 0,
 
-    0, 0, 3.14197e-08, 7.22146e-07, 4.61954e-06, 8.45613e-06, 4.49082e-06,
-    6.85919e-07, 2.9364e-08, 0, 0,
+      0, 6.57699e-09, 8.41855e-07, 2.69394e-05, 0.000383569, 0.000717224,
+      0.000379782, 2.69394e-05, 8.41855e-07, 6.57699e-09, 0,
 
-    0, 0, 0, 0, 0, 2.63305e-08, 0, 0, 0, 0, 0
-  };
+      0, 2.10464e-07, 2.69394e-05, 0.00140714, 0.00888549, 0.016448,
+      0.00867408, 0.00138203, 2.69394e-05, 2.10464e-07, 0,
 
+      0, 1.68371e-06, 0.000381138, 0.00875434, 0.0573377, 0.106308, 0.0570693,
+      0.00891745, 0.000378914, 1.68371e-06, 0,
 
+      6.57699e-09, 3.36742e-06, 0.00071364, 0.0164971, 0.106865, 0.197316,
+      0.106787, 0.0166434, 0.000713827, 3.36742e-06, 6.57699e-09,
 
+      0, 1.68371e-06, 0.000215515, 0.00894112, 0.0573699, 0.106239, 0.0567907,
+      0.00901191, 0.000215515, 1.68371e-06, 0,
 
+      0, 2.10464e-07, 2.69394e-05, 0.00135085, 0.0089288, 0.0164171,
+      0.00879334, 0.0013622, 2.69394e-05, 2.10464e-07, 0,
 
-void
-preparearrays(struct noisechiselparams *p)
-{
-  struct gal_mesh_params *smp=&p->smp, *lmp=&p->lmp;
-
-  long *meshindexs;
-  float *f, *ff, *fp;
-  size_t *relngb=p->relngb, s0, s1;
-
-  /* Read the input image in. Note that the pointer to the image is
-     also kept in p->img. Since some of the mesh operations should be
-     done on the convolved image and some on the actual image, we will
-     need to change the mesh's img value some times and the p->img
-     will be used to keep its actual value. */
-  gal_fits_file_to_float(p->up.inputname, p->up.maskname, p->cp.hdu,
-                              p->up.mhdu, (float **)&smp->img, &p->bitpix,
-                              &p->anyblank, &smp->s0, &smp->s1);
-  gal_fits_read_wcs(p->up.inputname, p->cp.hdu, 0, 0, &p->nwcs, &p->wcs);
-  s0=smp->s0; s1=smp->s1;
-
-  /* make sure the channel sizes fit the channel sizes. */
-  if( s0%smp->nch2 || s1%smp->nch1 )
-    error(EXIT_FAILURE, 0, "the input image size (%zu x %zu) is not an "
-          "exact multiple of the number of the given channels (%zu, %zu) "
-          "in the respective axis", s1, s0, smp->nch1, smp->nch2);
-
-  /* p->imgss (image-sky-subtracted) is the sky subtracted input
-     image. For both the removal of false detections and also the
-     segmentation, it is important to use the sky subtracted image,
-     not the actual input image for some operations. In both cases the
-     input image is used for Signal to noise ratio measurements (where
-     subtracting the sky will add noise).
-
-       False detection removal: The sky subtracted image will be used
-           for thresholding over the detected and undetected regions.
-
-       Segmentation: The sky subtracted image will also be used for
-           generating the catalog.
-
-     Since both operations involve the sky subtracted input image
-     (with different sky values) one array playing the role can really
-     help in following the code. It will also help in the memory usage
-     of the program. This array is allocated in the beginning and
-     freed in the end and used throughout. A huge chunk of memory
-     doesn't have to be allocated and de-allocated on every step.  */
-  errno=0; p->imgss=malloc(s0*s1*sizeof *p->imgss);
-  if(p->imgss==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->imgss in preparearrays "
-          "(ui.c)", s0*s1*sizeof *p->imgss);
-
-  /* Read the kernel: */
-  if(p->up.kernelnameset)
-    gal_fits_prep_float_kernel(p->up.kernelname, p->up.khdu, &smp->kernel,
-                                    &smp->ks0, &smp->ks1);
+      0, 6.57699e-09, 8.41855e-07, 2.69394e-05, 0.000215515, 0.000724137,
+      0.000215515, 2.69394e-05, 8.41855e-07, 6.57699e-09, 0,
+
+      0, 0, 6.57699e-09, 2.10464e-07, 1.68371e-06, 3.36742e-06, 1.68371e-06,
+      2.10464e-07, 6.57699e-09, 0, 0,
+
+      0, 0, 0, 0, 0, 6.57699e-09, 0, 0, 0, 0, 0
+    };
+
+  /* If a kernel file is given, then use it. Otherwise, use the default
+     kernel. */
+  if(p->kernelname)
+    p->kernel=gal_fits_img_read_kernel(p->kernelname, p->khdu,
+                                       p->cp.minmapsize);
   else
     {
-      errno=0;
-      smp->ks0=defaultkernel_s0;
-      smp->ks1=defaultkernel_s1;
-      smp->kernel=malloc(smp->ks0*smp->ks1*sizeof *smp->kernel);
-      if(smp->kernel==NULL)
-        error(EXIT_FAILURE, errno, "%zu bytes for default kernel",
-              smp->ks0*smp->ks1);
-      ff=defaultkernel;
-      fp=(f=smp->kernel)+smp->ks0*smp->ks1;
-      do *f=*ff++; while(++f<fp);
+      /* Allocate space for the kernel (we don't want to use the statically
+         allocated array. */
+      p->kernel=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 2,
+                               kernel_2d_dsize, NULL, 0, p->cp.minmapsize,
+                               NULL, NULL, NULL);
+
+      /* Now copy the staticly allocated array into it. */
+      k=p->kernel->array;
+      ff=(f=kernel_2d)+gal_dimension_total_size(2, p->kernel->dsize);
+      do *k++=*f; while(++f<ff);
     }
+}
 
-  /* Allocate the other necessary arrays: */
-  errno=0; p->byt=malloc(s0*s1*sizeof *p->byt);
-  if(p->byt==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->byt (ui.c)",
-          s0*s1*sizeof *p->byt);
-  errno=0; p->olab=malloc(s0*s1*sizeof *p->olab);
-  if(p->olab==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->olab (ui.c)",
-          s0*s1*sizeof *p->olab);
-  errno=0; p->clab=malloc(s0*s1*sizeof *p->clab);
-  if(p->clab==NULL)
-    error(EXIT_FAILURE, errno, "%zu bytes for p->clab (ui.c)",
-          s0*s1*sizeof *p->clab);
-
-  /* This ngb array is used to keep the relative indexs of the
-     neighbors of a pixel. It is used in the over-segmentation step
-     (clumps.c). The labelings are such that the first four elements
-     are the four-connected ones and the second four are
-     8-connected. There is no problem with the negative values that
-     are stored as size_t (which is an unsigned type): they will be
-     added with positive values during the processing to give correct
-     values. */
-  relngb[4]=    s1-1;    relngb[0]=    s1;    relngb[5]=    s1+1;
-  relngb[1]=      -1;                         relngb[2]=       1;
-  relngb[6]= -1*s1-1;    relngb[3]= -1*s1;    relngb[7]= -1*s1+1;
-
-  /* Set the parameters for both mesh grids. */
-  lmp->s0=smp->s0;
-  lmp->s1=smp->s1;
-  lmp->ks0=smp->ks0;
-  lmp->ks1=smp->ks1;
-  lmp->nch1=smp->nch1;
-  lmp->nch2=smp->nch2;
-  lmp->kernel=smp->kernel;
-  lmp->img=p->img=smp->img;
-  lmp->params=smp->params=p;
-  lmp->minmodeq=smp->minmodeq;
-  lmp->mirrordist=smp->mirrordist;
-  lmp->fullsmooth=smp->fullsmooth;
-  lmp->numnearest=smp->numnearest;
-  lmp->smoothwidth=smp->smoothwidth;
-  lmp->lastmeshfrac=smp->lastmeshfrac;
-  lmp->meshbasedcheck=smp->meshbasedcheck;
-  lmp->interponlyblank=smp->interponlyblank;
-  lmp->fullinterpolation=smp->fullinterpolation;
-  lmp->numthreads=smp->numthreads=p->cp.numthreads;
-
-
-  /* Prepare the mesh structures. */
-  gal_mesh_make_mesh(smp);
-  gal_mesh_make_mesh(lmp);
-  if(p->meshname)
+
+
+
+
+void
+ui_preparations(struct noisechiselparams *p)
+{
+  gal_data_t *check;
+  struct gal_tile_two_layer_params *tl=&p->cp.tl;
+
+  /* Prepare the names of the outputs. */
+  ui_set_output_names(p);
+
+  /* Read the input as a single precision floating point dataset. */
+  p->input = gal_fits_img_read_to_type(p->inputname, p->cp.hdu,
+                                       GAL_TYPE_FLOAT32,
+                                       p->cp.minmapsize);
+  gal_wcs_read(p->inputname, p->cp.hdu, 0, 0, &p->input->nwcs,
+               &p->input->wcs);
+  if(p->input->name==NULL)
+    gal_checkset_allocate_copy("INPUT", &p->input->name);
+
+  /* Read in the kernel for convolution. */
+  ui_prepare_kernel(p);
+
+  /* Check the tile parameters and make the tile structure. We will also
+     need the dimensions of the tile with the maximum required memory.  */
+  p->maxtsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, p->input->ndim);
+  gal_tile_full_sanity_check(p->inputname, p->cp.hdu, p->input, tl);
+  gal_tile_full_two_layers(p->input, tl);
+  gal_tile_full_permutation(tl);
+  for(check=tl->tiles; check!=NULL; check=check->next)
+    if( check->size > p->maxtcontig )/* p->maxtcontig was initialized to 0. */
+      {
+        p->maxtcontig=check->size;
+        memcpy(p->maxtsize, check->dsize, tl->ndim*sizeof *p->maxtsize);
+      }
+
+  /* Make the tile check image if requested. */
+  if(tl->checktiles)
     {
-      gal_fits_array_to_file(p->meshname, "Input", FLOAT_IMG,
-                             smp->img, s0, s1, p->anyblank, p->wcs,
-                             NULL, SPACK_STRING);
-      gal_mesh_check_mesh_id(smp, &meshindexs);
-      gal_fits_array_to_file(p->meshname, "SmallMeshIndexs",
-                             LONG_IMG, meshindexs, s0, s1, 0, p->wcs,
-                             NULL, SPACK_STRING);
-      free(meshindexs);
-      gal_mesh_check_mesh_id(lmp, &meshindexs);
-      gal_fits_array_to_file(p->meshname, "LargeMeshIndexs", LONG_IMG,
-                             meshindexs, s0, s1, 0, p->wcs,
-                             NULL, SPACK_STRING);
-      free(meshindexs);
+      tl->tilecheckname=gal_checkset_automatic_output(&p->cp, p->inputname,
+                                                      "_tiled.fits");
+      check=gal_tile_block_check_tiles(tl->tiles);
+      gal_fits_img_write(check, tl->tilecheckname, NULL, PROGRAM_NAME);
+      gal_data_free(check);
+      free(tl->tilecheckname);
     }
+
+  /* Allocate space for the over-all necessary arrays. */
+  p->binary=gal_data_alloc(NULL, GAL_TYPE_UINT8, p->input->ndim,
+                           p->input->dsize, p->input->wcs, 0,
+                           p->cp.minmapsize, NULL, "binary", NULL);
+  p->olabel=gal_data_alloc(NULL, GAL_TYPE_UINT32, p->input->ndim,
+                           p->input->dsize, p->input->wcs, 0,
+                           p->cp.minmapsize, NULL, "labels", NULL);
 }
 
 
@@ -991,54 +509,68 @@ preparearrays(struct noisechiselparams *p)
 /**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
+
 void
-setparams(int argc, char *argv[], struct noisechiselparams *p)
+ui_read_check_inputs_setup(int argc, char *argv[], struct noisechiselparams *p)
 {
-  struct gal_commonparams *cp=&p->cp;
+  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 <commonopts.h>
+#include "args.h"
 
-  /* Set the non-zero initial values, the structure was initialized to
-     have a zero value for all elements. */
-  cp->spack         = SPACK;
-  cp->verb          = 1;
-  cp->numthreads    = num_processors(NPROC_CURRENT);
-  cp->removedirinfo = 1;
 
-  /* NoiseChisel parameter initializations. */
-  p->detsnhistnbins=p->clumpsnhistnbins=0;
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
 
-  /* Read the arguments. */
+
+  /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
-  /* Add the user default values and save them if asked. */
-  GAL_CONFIGFILES_CHECK_SET_CONFIG;
 
-  /* Check if all the required parameters are set. */
-  checkifset(p);
+  /* 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);
 
-  /* Print the values for each parameter. */
-  if(cp->printparams)
-    GAL_CONFIGFILES_REPORT_PARAMETERS_SET;
 
-  /* Do a sanity check. */
-  sanitycheck(p);
+  /* 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);
 
-  /* Make the array of input images. */
-  preparearrays(p);
 
-  /* Everything is ready, notify the user of the program starting. */
-  if(cp->verb)
+  /* Read/allocate all the necessary starting arrays. */
+  ui_preparations(p);
+
+
+  /* Let the user know that processing has started. */
+  if(!p->cp.quiet)
     {
-      printf(SPACK_NAME" started on %s", ctime(&p->rawtime));
+      printf(PROGRAM_NAME" started on %s", ctime(&p->rawtime));
       printf("  - Using %zu CPU thread%s\n", p->cp.numthreads,
              p->cp.numthreads==1 ? "." : "s.");
-      printf("  - Input: %s (hdu: %s)\n", p->up.inputname, p->cp.hdu);
-      if(p->up.maskname)
-        printf("  - Mask: %s (hdu: %s)\n", p->up.maskname, p->up.mhdu);
-      if(p->up.kernelnameset)
-        printf("  - Kernel: %s (hdu: %s)\n", p->up.kernelname,
-               p->up.khdu);
+      printf("  - Input: %s (hdu: %s)\n", p->inputname, p->cp.hdu);
+      if(p->kernelname)
+        printf("  - Kernel: %s (hdu: %s)\n", p->kernelname, p->khdu);
       else
         printf("  - Kernel: FWHM=2 pixel Gaussian.\n");
     }
@@ -1064,43 +596,58 @@ setparams(int argc, char *argv[], struct 
noisechiselparams *p)
 
 
 /**************************************************************/
-/************      Free allocated, report         *************/
+/************     Pre-finish/abort operations     *************/
 /**************************************************************/
 void
-freeandreport(struct noisechiselparams *p, struct timeval *t1)
+ui_abort_after_check(struct noisechiselparams *p, char *filename,
+                     char *description)
+{
+  /* Let the user know that NoiseChisel is aborting. */
+  fprintf(stderr,
+          "------------------------------------------------\n"
+          "%s aborted for a check\n"
+          "------------------------------------------------\n"
+          "`%s' (%s) has been created.\n\n"
+          "If you want %s to continue its processing AND save any "
+          "requested check(s), please run it again with "
+          "`--continueaftercheck'.\n"
+          "------------------------------------------------\n",
+          PROGRAM_NAME, filename, description, PROGRAM_NAME);
+
+  /* Clean up. */
+  ui_free_report(p, NULL);
+
+  /* Abort. */
+  exit(EXIT_SUCCESS);
+}
+
+
+
+
+
+void
+ui_free_report(struct noisechiselparams *p, struct timeval *t1)
 {
-  /* Free the allocated arrays: */
-  free(p->img);
-  free(p->byt);
-  free(p->olab);
-  free(p->clab);
-  free(p->imgss);
+  /* Free the simply allocated spaces. */
   free(p->cp.hdu);
-  free(p->up.mhdu);
-  free(p->up.khdu);
+  free(p->maxtsize);
   free(p->cp.output);
-  free(p->smp.kernel);
-  free(p->up.kernelname);
-
-  /* Free the mask image name. Note that p->up.inputname was not
-     allocated, but given to the program by the operating system. */
-  if(p->up.maskname && p->up.maskname!=p->up.inputname)
-    free(p->up.maskname);
-
-  /* Free all the allocated names. Note that detsnhist */
-  free(p->skyname);
-  free(p->meshname);
-  free(p->threshname);
-  free(p->maskdetname);
-  free(p->detectionname);
-  free(p->segmentationname);
-  free(p->detectionskyname);
-
-  /* Free the WCS structure: */
-  if(p->wcs)
-    wcsvfree(&p->nwcs, &p->wcs);
+  if(p->skyname)          free(p->skyname);
+  if(p->detsnname)        free(p->detsnname);
+  if(p->detskyname)       free(p->detskyname);
+  if(p->clumpsnname)      free(p->clumpsnname);
+  if(p->qthreshname)      free(p->qthreshname);
+  if(p->detectionname)    free(p->detectionname);
+  if(p->segmentationname) free(p->segmentationname);
+
+  /* Free the allocated datasets. */
+  gal_data_free(p->conv);
+  gal_data_free(p->input);
+  gal_data_free(p->kernel);
+  gal_data_free(p->binary);
+  gal_data_free(p->olabel);
 
   /* Print the final message. */
-  if(p->cp.verb)
-    gal_timing_report(t1, SPACK_NAME" finished in", 0);
+  if(!p->cp.quiet && t1)
+    gal_timing_report(t1, PROGRAM_NAME" finished in: ", 0);
 }
diff --git a/bin/noisechisel/ui.h b/bin/noisechisel/ui.h
index 0992b24..6eea6c4 100644
--- a/bin/noisechisel/ui.h
+++ b/bin/noisechisel/ui.h
@@ -1,5 +1,5 @@
 /*********************************************************************
-NoiseChisel - Detect and segment signal in noise.
+NoiseChisel - Detect and segment signal in a noisy dataset.
 NoiseChisel is part of GNU Astronomy Utilities (Gnuastro) package.
 
 Original author:
@@ -20,13 +20,75 @@ 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 IMCROPUI_H
-#define IMCROPUI_H
+#ifndef UI_H
+#define UI_H
+
+
+
+
+
+/* Available letters for short options:
+
+   a b f j l n u w x z
+   A H J L W X Y
+*/
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_KERNEL             = 'k',
+  ARGS_OPTION_KEY_SKYSUBTRACTED      = 'E',
+  ARGS_OPTION_KEY_MINBFRAC           = 'B',
+  ARGS_OPTION_KEY_MIRRORDIST         = 'r',
+  ARGS_OPTION_KEY_MODMEDQDIFF        = 'Q',
+  ARGS_OPTION_KEY_QTHRESH            = 't',
+  ARGS_OPTION_KEY_ERODE              = 'e',
+  ARGS_OPTION_KEY_OPENING            = 'p',
+  ARGS_OPTION_KEY_SIGMACLIP          = 's',
+  ARGS_OPTION_KEY_DTHRESH            = 'R',
+  ARGS_OPTION_KEY_DETSNMINAREA       = 'i',
+  ARGS_OPTION_KEY_DETQUANT           = 'c',
+  ARGS_OPTION_KEY_DILATE             = 'd',
+  ARGS_OPTION_KEY_SEGSNMINAREA       = 'm',
+  ARGS_OPTION_KEY_SEGQUANT           = 'g',
+  ARGS_OPTION_KEY_KEEPMAXNEARRIVER   = 'v',
+  ARGS_OPTION_KEY_GTHRESH            = 'G',
+  ARGS_OPTION_KEY_MINRIVERLENGTH     = 'y',
+  ARGS_OPTION_KEY_OBJBORDERSN        = 'O',
+  ARGS_OPTION_KEY_CONTINUEAFTERCHECK = 'C',
+
+
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+  ARGS_OPTION_KEY_KHDU              = 1000,
+  ARGS_OPTION_KEY_MINNUMFALSE,
+  ARGS_OPTION_KEY_ONLYDETECT,
+  ARGS_OPTION_KEY_GROWNCLUMPS,
+  ARGS_OPTION_KEY_SMOOTHWIDTH,
+  ARGS_OPTION_KEY_CHECKQTHRESH,
+  ARGS_OPTION_KEY_ERODENGB,
+  ARGS_OPTION_KEY_NOERODEQUANT,
+  ARGS_OPTION_KEY_OPENINGNGB,
+  ARGS_OPTION_KEY_CHECKDETSKY,
+  ARGS_OPTION_KEY_CHECKDETSN,
+  ARGS_OPTION_KEY_CHECKDETECTION,
+  ARGS_OPTION_KEY_CHECKSKY,
+  ARGS_OPTION_KEY_CHECKCLUMPSN,
+  ARGS_OPTION_KEY_CHECKSEGMENTATION,
+};
+
+
+
+
+
+void
+ui_read_check_inputs_setup(int argc, char *argv[],
+                           struct noisechiselparams *p);
 
 void
-setparams(int argc, char *argv[], struct noisechiselparams *p);
+ui_abort_after_check(struct noisechiselparams *p, char *filename,
+                     char *description);
 
 void
-freeandreport(struct noisechiselparams *p, struct timeval *t1);
+ui_free_report(struct noisechiselparams *p, struct timeval *t1);
 
 #endif
diff --git a/bin/statistics/Makefile.am b/bin/statistics/Makefile.am
index 6454a24..36eb9cc 100644
--- a/bin/statistics/Makefile.am
+++ b/bin/statistics/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = aststatistics
 
diff --git a/bin/statistics/args.h b/bin/statistics/args.h
index 9617ddc..04ae3c5 100644
--- a/bin/statistics/args.h
+++ b/bin/statistics/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Column name or number if input is a table.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->column,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -52,7 +52,7 @@ struct argp_option program_options[] =
       "Reference column name or number.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->refcol,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -65,7 +65,7 @@ struct argp_option program_options[] =
       "Only use values greater-equal than this.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->greaterequal,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -78,7 +78,7 @@ struct argp_option program_options[] =
       "Only use values less than this.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->lessthan,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -91,7 +91,7 @@ struct argp_option program_options[] =
       "Quantile range: one (from Q to 1-Q) or two.",
       GAL_OPTIONS_GROUP_INPUT,
       NULL,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -229,7 +229,7 @@ struct argp_option program_options[] =
       "Quantile (multiple values acceptable).",
       ARGS_GROUP_SINGLE_VALUE,
       &p->singlevalue,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -243,7 +243,7 @@ struct argp_option program_options[] =
       "Quantile function (multiple values acceptable).",
       ARGS_GROUP_SINGLE_VALUE,
       &p->singlevalue,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -374,7 +374,7 @@ struct argp_option program_options[] =
       "Save the histogram and CFP of the mirror dist.",
       ARGS_GROUP_PARTICULAR_STAT,
       &p->mirror,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -436,7 +436,7 @@ struct argp_option program_options[] =
       "File name of kernel to convolve input.",
       ARGS_GROUP_SKY,
       &p->kernelname,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -449,7 +449,7 @@ struct argp_option program_options[] =
       "HDU/extension name or number of kernel.",
       ARGS_GROUP_SKY,
       &p->khdu,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -462,7 +462,7 @@ struct argp_option program_options[] =
       "Max. distance (error multip.) to find mode.",
       ARGS_GROUP_SKY,
       &p->mirrordist,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -475,7 +475,7 @@ struct argp_option program_options[] =
       "Max. mode and median quantile diff. per tile.",
       ARGS_GROUP_SKY,
       &p->modmedqdiff,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -485,10 +485,10 @@ struct argp_option program_options[] =
       ARGS_OPTION_KEY_SCLIPPARAMS,
       "FLT,FLT",
       0,
-      "Multiple of sigma and tolerance/number.",
+      "Sigma clip: Multiple, and tolerance/number.",
       ARGS_GROUP_SKY,
       p->sclipparams,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -502,7 +502,7 @@ struct argp_option program_options[] =
       "Sky: flat kernel width to smooth interpolated.",
       ARGS_GROUP_SKY,
       &p->smoothwidth,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_0_OR_ODD,
       GAL_OPTIONS_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -537,7 +537,7 @@ struct argp_option program_options[] =
       "No. of bins in histogram or CFP tables.",
       ARGS_GROUP_HIST_CFP,
       &p->numbins,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -550,7 +550,7 @@ struct argp_option program_options[] =
       "No. of bins in ASCII histogram or CFP plots.",
       ARGS_GROUP_HIST_CFP,
       &p->numasciibins,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -563,7 +563,7 @@ struct argp_option program_options[] =
       "Height of ASCII histogram or CFP plots.",
       ARGS_GROUP_HIST_CFP,
       &p->asciiheight,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -602,7 +602,7 @@ struct argp_option program_options[] =
       "Shift bins so one bin starts on this value.",
       ARGS_GROUP_HIST_CFP,
       &p->onebinstart,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/statistics/sky.c b/bin/statistics/sky.c
index 79c56b0..0eb54c8 100644
--- a/bin/statistics/sky.c
+++ b/bin/statistics/sky.c
@@ -51,12 +51,12 @@ sky_on_thread(void *in_prm)
 {
   struct gal_threads_params *tprm=(struct gal_threads_params *)in_prm;
   struct statisticsparams *p=(struct statisticsparams *)tprm->params;
-  int type=p->input->type, stype=GAL_DATA_TYPE_FLOAT32;
 
   double *darr;
+  int stype=p->sky_t->type;
   void *tblock=NULL, *tarray=NULL;
   gal_data_t *tile, *mode, *sigmaclip;
-  size_t i, tind, twidth=gal_data_sizeof(stype);
+  size_t i, tind, twidth=gal_type_sizeof(stype);
 
 
   /* Find the Sky and its standard deviation on the tiles given to this
@@ -106,10 +106,10 @@ sky_on_thread(void *in_prm)
         }
       else
         {
-          gal_blank_write(gal_data_ptr_increment(p->sky_t->array, tind, type),
-                          type);
-          gal_blank_write(gal_data_ptr_increment(p->std_t->array, tind, type),
-                          type);
+          gal_blank_write(gal_data_ptr_increment(p->sky_t->array, tind,
+                                                 stype), stype);
+          gal_blank_write(gal_data_ptr_increment(p->std_t->array, tind,
+                                                 stype), stype);
         }
 
       /* Clean up. */
@@ -170,10 +170,10 @@ sky(struct statisticsparams *p)
 
 
   /* Make the arrays keeping the Sky and Sky standard deviation values. */
-  p->sky_t=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, p->input->ndim,
-                          tl->numtiles, NULL, 0, p->input->minmapsize, "SKY",
-                          p->input->unit, NULL);
-  p->std_t=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, p->input->ndim,
+  p->sky_t=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->input->ndim,
+                          tl->numtiles, NULL, 0, p->input->minmapsize,
+                          "SKY", p->input->unit, NULL);
+  p->std_t=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, p->input->ndim,
                           tl->numtiles, NULL, 0, p->input->minmapsize,
                           "SKY STD", p->input->unit, NULL);
 
diff --git a/bin/statistics/statistics.c b/bin/statistics/statistics.c
index d9d141d..f1d0d48 100644
--- a/bin/statistics/statistics.c
+++ b/bin/statistics/statistics.c
@@ -180,7 +180,7 @@ statistics_print_one_row(struct statisticsparams *p)
 
         case ARGS_OPTION_KEY_QUANTFUNC:
           arg = statistics_read_check_args(p);
-          tmpv = gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+          tmpv = gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                 NULL, 1, -1, NULL, NULL, NULL);
           *((double *)(tmpv->array)) = arg;
           tmpv = gal_data_copy_to_new_type_free(tmpv, p->input->type);
@@ -267,7 +267,7 @@ statistics_on_tile(struct statisticsparams *p)
   double arg=0;
   gal_data_t *tile, *values;
   size_t tind, dsize=1, mind=-1;
-  uint8_t type=GAL_DATA_TYPE_INVALID;
+  uint8_t type=GAL_TYPE_INVALID;
   struct gal_linkedlist_ill *operation;
   gal_data_t *tmp=NULL, *tmpv=NULL, *ttmp;
   struct gal_options_common_params *cp=&p->cp;
@@ -284,7 +284,7 @@ statistics_on_tile(struct statisticsparams *p)
       switch(operation->v)
         {
         case ARGS_OPTION_KEY_NUMBER:
-          type=GAL_DATA_TYPE_INT32; break;
+          type=GAL_TYPE_INT32; break;
 
         case ARGS_OPTION_KEY_MINIMUM:
         case ARGS_OPTION_KEY_MAXIMUM:
@@ -300,7 +300,7 @@ statistics_on_tile(struct statisticsparams *p)
         case ARGS_OPTION_KEY_MODEQUANT:
         case ARGS_OPTION_KEY_MODESYM:
         case ARGS_OPTION_KEY_MODESYMVALUE:
-          type=GAL_DATA_TYPE_FLOAT64; break;
+          type=GAL_TYPE_FLOAT64; break;
 
         default:
           error(EXIT_FAILURE, 0, "a bug! %d is not a recognized operation "
@@ -320,7 +320,7 @@ statistics_on_tile(struct statisticsparams *p)
           break;
         case ARGS_OPTION_KEY_QUANTFUNC:
           arg = statistics_read_check_args(p);
-          tmpv = gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+          tmpv = gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                 NULL, 1, -1, NULL, NULL, NULL);
           *((double *)(tmpv->array)) = arg;
           tmpv = gal_data_copy_to_new_type_free(tmpv, p->input->type);
@@ -387,7 +387,7 @@ statistics_on_tile(struct statisticsparams *p)
           /* Put the output value into the `values' array and clean up. */
           tmp=gal_data_copy_to_new_type_free(tmp, type);
           memcpy(gal_data_ptr_increment(values->array, tind++, values->type),
-                 tmp->array, gal_data_sizeof(type));
+                 tmp->array, gal_type_sizeof(type));
           gal_data_free(tmp);
         }
 
@@ -613,10 +613,10 @@ save_hist_and_or_cfp(struct statisticsparams *p)
 
   /* FITS tables don't accept `uint64_t', so to be consistent, we'll conver
      the histogram and CFP to `uint32_t'.*/
-  if(hist->type==GAL_DATA_TYPE_UINT64)
-    hist=gal_data_copy_to_new_type_free(hist, GAL_DATA_TYPE_UINT32);
-  if(cfp && cfp->type==GAL_DATA_TYPE_UINT64)
-    cfp=gal_data_copy_to_new_type_free(cfp, GAL_DATA_TYPE_UINT32);
+  if(hist->type==GAL_TYPE_UINT64)
+    hist=gal_data_copy_to_new_type_free(hist, GAL_TYPE_UINT32);
+  if(cfp && cfp->type==GAL_TYPE_UINT64)
+    cfp=gal_data_copy_to_new_type_free(cfp, GAL_TYPE_UINT32);
 
 
   /* Finalize the next pointers. */
@@ -647,7 +647,7 @@ print_mirror_hist_cfp(struct statisticsparams *p)
   size_t dsize=1;
   gal_data_t *table;
   double mirror_val;
-  gal_data_t *mirror=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *mirror=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                     NULL, 1, -1, NULL, NULL, NULL);
 
   /* Convert the given mirror value into the type of the input dataset. */
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index b06b026..7813f23 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -601,12 +601,12 @@ ui_out_of_range_to_blank(struct statisticsparams *p)
 
       /* Set the greater-equal value. */
       tmp=gal_statistics_quantile(ref, p->quantmin, 1);
-      tmp=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+      tmp=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
       p->greaterequal=*((float *)(tmp->array));
 
       /* Set the lower-than value. */
       tmp=gal_statistics_quantile(ref, p->quantmax, 1);
-      tmp=gal_data_copy_to_new_type_free(tmp, GAL_DATA_TYPE_FLOAT32);
+      tmp=gal_data_copy_to_new_type_free(tmp, GAL_TYPE_FLOAT32);
       p->lessthan=*((float *)(tmp->array));
     }
 
@@ -616,7 +616,7 @@ ui_out_of_range_to_blank(struct statisticsparams *p)
      less-than  */
   if(!isnan(p->greaterequal))
     {
-      tmp=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 1, &one, NULL, 0, -1,
+      tmp=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 1, &one, NULL, 0, -1,
                         NULL, NULL, NULL);
       *((float *)(tmp->array)) = p->greaterequal;
       cond_g=gal_arithmetic(GAL_ARITHMETIC_OP_LT, flags, ref, tmp);
@@ -627,7 +627,7 @@ ui_out_of_range_to_blank(struct statisticsparams *p)
   /* Same reasoning as above for `p->greaterthan'. */
   if(!isnan(p->lessthan))
     {
-      tmp=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 1, &one, NULL, 0, -1,
+      tmp=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 1, &one, NULL, 0, -1,
                         NULL, NULL, NULL);
       *((float *)(tmp->array)) = p->lessthan;
       cond_l=gal_arithmetic(GAL_ARITHMETIC_OP_GE, flags, ref, tmp);
@@ -651,7 +651,7 @@ ui_out_of_range_to_blank(struct statisticsparams *p)
 
   /* Allocate a blank value to mask all pixels that don't satisfy the
      condition. */
-  blank=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 1, &one, NULL,
+  blank=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 1, &one, NULL,
                      0, -1, NULL, NULL, NULL);
   *((float *)(blank->array)) = NAN;
 
@@ -743,14 +743,14 @@ ui_read_columns(struct statisticsparams *p)
       /* Make sure it is a usable datatype. */
       switch(tmp->type)
         {
-        case GAL_DATA_TYPE_BIT:
-        case GAL_DATA_TYPE_STRLL:
-        case GAL_DATA_TYPE_STRING:
-        case GAL_DATA_TYPE_COMPLEX32:
-        case GAL_DATA_TYPE_COMPLEX64:
+        case GAL_TYPE_BIT:
+        case GAL_TYPE_STRLL:
+        case GAL_TYPE_STRING:
+        case GAL_TYPE_COMPLEX32:
+        case GAL_TYPE_COMPLEX64:
           error(EXIT_FAILURE, 0, " read column number %zu has a %s type, "
                 "which is not currently supported by %s", counter,
-                gal_data_type_as_string(tmp->type, 1), PROGRAM_NAME);
+                gal_type_to_string(tmp->type, 1), PROGRAM_NAME);
         }
 
       /* Put the column into the proper pointer. */
diff --git a/bin/table/Makefile.am b/bin/table/Makefile.am
index d5d00da..75eea69 100644
--- a/bin/table/Makefile.am
+++ b/bin/table/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = asttable
 
@@ -35,6 +35,7 @@ asttable_SOURCES = main.c ui.c table.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h table.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = asttable.conf
diff --git a/bin/table/args.h b/bin/table/args.h
index a98750a..42fff9a 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -39,7 +39,7 @@ struct argp_option program_options[] =
       "Column number (counting from 1) or search string.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->columns,
-      GAL_DATA_TYPE_STRLL,
+      GAL_TYPE_STRLL,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
diff --git a/bin/warp/Makefile.am b/bin/warp/Makefile.am
index 9cddfaa..416e959 100644
--- a/bin/warp/Makefile.am
+++ b/bin/warp/Makefile.am
@@ -19,12 +19,12 @@
 ## along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 
 
-## Necessary flags. NOTE: $(top_srcdir)/bootstrapped/lib is only necessary
-## for internally compiled utilities and libraries. It must not be included
-## during the tests since the bootstrapped libraries are not installed.
+## 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 = astwarp
 
@@ -35,6 +35,7 @@ astwarp_SOURCES = main.c ui.c warp.c
 EXTRA_DIST = main.h authors-cite.h args.h ui.h warp.h
 
 
+
 ## The configuration file (distribute and install).
 ## NOTE: the man page is created in doc/Makefile.am
 dist_sysconf_DATA = astwarp.conf
diff --git a/bin/warp/args.h b/bin/warp/args.h
index 56b5fd8..b082090 100644
--- a/bin/warp/args.h
+++ b/bin/warp/args.h
@@ -41,7 +41,7 @@ struct argp_option program_options[] =
       "Header keyword number to start reading WCS.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->hstartwcs,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -54,7 +54,7 @@ struct argp_option program_options[] =
       "Header keyword number to end reading WCS.",
       GAL_OPTIONS_GROUP_INPUT,
       &p->hendwcs,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -84,7 +84,7 @@ struct argp_option program_options[] =
       "Acceptable fraction of output pixel covered.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &p->coveredfrac,
-      GAL_DATA_TYPE_FLOAT64,
+      GAL_TYPE_FLOAT64,
       GAL_OPTIONS_RANGE_GE_0_LE_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -104,7 +104,7 @@ struct argp_option program_options[] =
       "Align the image and celestial axes.",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -118,7 +118,7 @@ struct argp_option program_options[] =
       "Rotate by the given angle in degrees.",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -132,7 +132,7 @@ struct argp_option program_options[] =
       "Scale along the given axis(es).",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -146,7 +146,7 @@ struct argp_option program_options[] =
       "Flip along the given axis(es).",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -160,7 +160,7 @@ struct argp_option program_options[] =
       "Shear along the given axis(es).",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -174,7 +174,7 @@ struct argp_option program_options[] =
       "Translate along the given axis(es).",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -188,7 +188,7 @@ struct argp_option program_options[] =
       "Project along the given axis(es).",
       ARGS_GROUP_WARPS,
       0,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -202,7 +202,7 @@ struct argp_option program_options[] =
       "Raw transformation matrix, highest priority.",
       ARGS_GROUP_WARPS,
       &p->matrix,
-      GAL_DATA_TYPE_INVALID,
+      GAL_TYPE_INVALID,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
diff --git a/bin/warp/ui.c b/bin/warp/ui.c
index b958a0d..eadef37 100644
--- a/bin/warp/ui.c
+++ b/bin/warp/ui.c
@@ -245,7 +245,7 @@ ui_add_to_modular_warps_ll(struct argp_option *option, char 
*arg,
       if(arg && *arg=='0') return NULL;
 
       /* Allocate the data structure. */
-      new=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 0, NULL, NULL, 0,
+      new=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 0, NULL, NULL, 0,
                          -1, NULL, NULL, NULL);
     }
   else new=gal_options_parse_list_of_numbers(arg, filename, lineno);
@@ -344,7 +344,7 @@ ui_check_options_and_arguments(struct warpparams *p)
 
       /* Read the input image as double type and its WCS structure. */
       p->input=gal_fits_img_read_to_type(p->inputname, p->cp.hdu,
-                                         GAL_DATA_TYPE_FLOAT64,
+                                         GAL_TYPE_FLOAT64,
                                          p->cp.minmapsize);
       gal_wcs_read(p->inputname, p->cp.hdu, p->hstartwcs,
                    p->hendwcs, &p->input->nwcs, &p->input->wcs);
@@ -413,7 +413,7 @@ ui_matrix_prepare_raw(struct warpparams *p)
   if(p->matrix->size==4)
     {
       /* Allocate the final matrix. */
-      final=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 9);
+      final=gal_data_malloc_array(GAL_TYPE_FLOAT64, 9);
 
       /* Fill in the final 3x3 matrix from the 2x2 matrix. */
       final[0]=in[0];    final[1]=in[1];   final[2]=0.0f;
@@ -429,7 +429,7 @@ ui_matrix_prepare_raw(struct warpparams *p)
   /* Correct the dimensional information, because the matrix was read as a
      single dimensional list of numbers. */
   free(p->matrix->dsize);
-  dsize=p->matrix->dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, 2);
+  dsize=p->matrix->dsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, 2);
   dsize[0]=dsize[1]=3;
   p->matrix->ndim=2;
 }
@@ -587,7 +587,7 @@ ui_matrix_from_modular(struct warpparams *p)
   gal_data_reverse_ll(&p->modularll);
 
   /* Allocate space for the final matrix. */
-  p->matrix=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 2, dsize, NULL, 0,
+  p->matrix=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 2, dsize, NULL, 0,
                            p->cp.minmapsize, NULL, NULL, NULL);
   final=p->matrix->array;
 
@@ -760,7 +760,7 @@ ui_matrix_finalize(struct warpparams *p)
      yet implemented. */
 
    /* Make the inverse matrix: */
-  inv=p->inverse=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 9);
+  inv=p->inverse=gal_data_malloc_array(GAL_TYPE_FLOAT64, 9);
   inv[0] = d[4]*d[8] - d[5]*d[7];
   inv[1] = d[2]*d[7] - d[1]*d[8];
   inv[2] = d[1]*d[5] - d[2]*d[4];
diff --git a/bin/warp/warp.c b/bin/warp/warp.c
index a639189..887505c 100644
--- a/bin/warp/warp.c
+++ b/bin/warp/warp.c
@@ -343,7 +343,7 @@ warppreparations(struct warpparams *p)
   /* We now know the size of the output and the starting and ending
      coordinates in the output image (bottom left corners of pixels)
      for the transformation. */
-  p->output=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 2, dsize,
+  p->output=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 2, dsize,
                            p->input->wcs, 0, p->cp.minmapsize, "Warped",
                            p->input->unit, NULL);
 
@@ -444,7 +444,7 @@ correct_wcs_save_output(struct warpparams *p)
   for(i=0;i<9;++i)
     {
       sprintf(&keyword[i*FLEN_KEYWORD], "WMTX%zu_%zu", i/3+1, i%3+1);
-      gal_fits_key_add_to_ll_end(&headers, GAL_DATA_TYPE_FLOAT64,
+      gal_fits_key_add_to_ll_end(&headers, GAL_TYPE_FLOAT64,
                                  &keyword[i*FLEN_KEYWORD], 0,
                                  &m[i], 0, "Warp matrix element value", 0,
                                  NULL);
diff --git a/configure.ac b/configure.ac
index d642ba8..6afc7de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,20 +283,38 @@ AC_DEFINE_UNQUOTED([CONF_SHOWFMT], [" %-20s"],
 
 
 # The native types for binary arithmetic operations, see the manual for a
-# detailed discussion. The initial list of values given here specify the
-# default list of types. If they have a value of 1, they will be
-# compiled. unless the user configures with `--disable-bin-op-TYPENAME', or
+# detailed discussion. The initial list of which types to compile can be
+# determined with the `--enable-bin-op-alltypes' option. If they have a
+# value of 1, they will be compiled. It is possible to disable a previously
+# compiled type with with `--disable-bin-op-TYPENAME', or
 # `--enable-bin-op-TYPENAME=no'.
-binop_uint8=1
-binop_int8=0
-binop_uint16=0
-binop_int16=0
-binop_uint32=0
-binop_int32=0
-binop_uint64=1
-binop_int64=1
-binop_float32=1
-binop_float64=1
+binop_alltypes=0
+AC_ARG_ENABLE([bin-op-alltypes],
+              [AS_HELP_STRING([--enable-bin-op-alltypes],
+                    [Allow native binary operations for all types.])],
+             [AS_IF([test "x$enable_bin_op_alltypes" != xno],
+                     [binop_alltypes=1], [binop_alltypes=0])], [])
+AS_IF([test "x$binop_alltypes" != x0],
+      [binop_uint8=1
+       binop_int8=1
+       binop_uint16=1
+       binop_int16=1
+       binop_uint32=1
+       binop_int32=1
+       binop_uint64=1
+       binop_int64=1
+       binop_float32=1
+       binop_float64=1],
+      [binop_uint8=1
+       binop_int8=0
+       binop_uint16=0
+       binop_int16=0
+       binop_uint32=0
+       binop_int32=0
+       binop_uint64=1
+       binop_int64=1
+       binop_float32=1
+       binop_float64=1] )
 
 AC_MSG_CHECKING(compilation of 8-bit unsigned int binary operators)
 AC_ARG_ENABLE([bin-op-uint8],
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 2c68e90..3851962 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -3209,8 +3209,16 @@ GNU/Linux distribution package managers who compile 
once, for a large
 audience of users who just download the compiled programs and executables,
 are recommended to enable all types to help their users.
 
-
-
address@hidden --enable-bin-op-alltypes
+Enable native binary arithmetic operation on all types, see the description
+above for the various types for a full discussion. As discussed there,
+enabling all types can greatly speed up arithmetic operations on any
+arbitrary dataset, but will also slow down the building time of
+Gnuastro. Recall that in practice this only affects the @ref{Arithmetic}
+program and the @code{gal_arithmetic} library binary operators, nothing
+else. This option is strongly recommended when you are building Gnuastro to
+be included in a package manager of a GNU/Linux distribution (or other
+operating system).
 
 @item --enable-gnulibcheck
 @cindex GNU C library
@@ -11853,14 +11861,14 @@ The maximum acceptable distance between the mode and 
median, see
 @ref{Quantifying signal in a tile}.
 
 @item --sclipparams=FLT,FLT
-The @mymath{\sigma}-clipping parameters. This option takes two values which
-are separated by a comma (@key{,}). Each value can either be written as a
-single number or as a fraction of two numbers (for example
address@hidden,1/10}). The first value to this option is the multiple of
address@hidden that will be clipped (@mymath{\alpha} in that section). The
-second value is the exit criteria. If it is less than 1, then it is
-interpretted as tolerance and if it is larger than one it is a specific
-number. Hence, in the latter case the value must be an integer.
+The @mymath{\sigma}-clipping parameters, see @ref{Sigma clipping}. This
+option takes two values which are separated by a comma (@key{,}). Each
+value can either be written as a single number or as a fraction of two
+numbers (for example @code{3,1/10}). The first value to this option is the
+multiple of @mymath{\sigma} that will be clipped (@mymath{\alpha} in that
+section). The second value is the exit criteria. If it is less than 1, then
+it is interpretted as tolerance and if it is larger than one it is a
+specific number. Hence, in the latter case the value must be an integer.
 
 @item --smoothwidth=INT
 Width of a flat kernel to convolve the interpolated tile values. Tile
@@ -12058,8 +12066,7 @@ the undetected regions. Therefore, to get an accurate 
measurement of
 the above parameters over the full mesh grid, meshs that harbor too
 many detected regions should be excluded.
 
address@hidden -F INT
address@hidden --minnumfalse=INT
address@hidden --minnumfalse=INT
 The minimum number of `psudo-detections' (in identifying false detections)
 or clumps (in identifying false clumps) in each large mesh grid. If their
 number is less than this value, this mesh will be left blank and filled
@@ -12082,6 +12089,32 @@ two groups: 1) Signal and 2) Noise. Through the 
parameters below, you
 can customize the detection process in NoiseChisel.
 @table @option
 
address@hidden --continueaftercheck
+Continue NoiseChisel after any of the options starting with
address@hidden NoiseChisel involves many steps and as a result, there
+are many checks, allowing to inspect the status of the processing. The
+results of each step affect the next steps of processing, so, when you are
+want to check the status of the processing at one step, the time spent to
+complete NoiseChisel is just wasted time. As a result, by default, when you
+use any of the NoiseChisel options that start with @option{--check},
+NoiseChisel will abort once all the desired extensions (steps of the
+processign) to the file have been written into it. With this option, you
+can disable this behavior and ask NoiseChisel to continue with the rest of
+the processing.
+
address@hidden -r FLT
address@hidden --mirrordist=FLT
+Maximum distance (as a multiple of error) to estimate the difference
+between the input and mirror distributions in finding the mode, see
+Appendix C of @url{https://arxiv.org/abs/1505.01664, Akhlaghi and Ichikawa
+2015}, also see @ref{Quantifying signal in a tile}.
+
address@hidden -Q FLT
address@hidden --modmedqdiff=FLT
+The maximum acceptable distance between the mode and median, see
address@hidden signal in a tile}. The quantile threshold will be found on
+tiles that satisfy this mode and median difference.
+
 @item -t FLT
 @itemx --qthresh=FLT
 The quantile threshold to apply to the convolved image. The detection
@@ -12105,9 +12138,12 @@ pixels (have a value of 1) while those which lie below 
the threshold
 are known as background (have a value of 0).
 
 @cindex NaN
address@hidden --checkthreshold
address@hidden --checkqthresh
 Check the quantile threshold values on the mesh grid. A file suffixed with
address@hidden will be created, see @ref{Tessellation}.
address@hidden will be created, see @ref{Tessellation}. With this
+option, NoiseChisel will abort as soon as quantile estimation has been
+completed, allowing you to inspect the status. This behavior can be
+disabled with @option{--continueaftercheck}.
 
 @item -e INT
 @itemx --erode=INT
@@ -12171,39 +12207,25 @@ them. Once opening is complete, we have 
@emph{initial} detections.
 The structuring element used for opening, see @option{--erodengb} for more
 information about a structuring element.
 
address@hidden -u FLT
address@hidden --sigclumpmultip=FLT
-The multiple of the standard deviation during
address@hidden NoiseChisel uses @mymath{\sigma}-clipping to
-remove the effect of cosmic rays when calculating the average and standard
-deviation of the undetected regions.
-
-Since cosmic rays have sharp boundaries and are usually small, the
-erosion and opening might put them within the undetected
-pixels. Although they might cover a very small number of pixels, they
-usually have very large flux values which can easily bias the average
-and standard deviation measured on a mesh. Their effect can easily be
-removed by @mymath{\sigma}-clipping, see @ref{Sigma
-clipping}. NoiseChisel uses the convergence of the value of the
-standard deviation as the criteria to stop the
address@hidden iteration.
-
address@hidden -r FLT
address@hidden --sigcliptolerance=FLT
-The tolerance level to stop @mymath{\sigma}-clipping. The iteration is
-stopped when @mymath{(\sigma_{old}-\sigma_{new})/\sigma_{new}} becomes
-smaller than the value given to this option. Note that
address@hidden will always be larger than
address@hidden Only statistical scatter (error) can cause it to be
-smaller, in which case they can be considered to be approximately equal.
-
address@hidden --checkdetectionsky
address@hidden -s FLT,FLT
address@hidden --sigmaclip=FLT,FLT
+The @mymath{\sigma}-clipping parameters, see @ref{Sigma clipping}. This
+option takes two values which are separated by a comma (@key{,}). Each
+value can either be written as a single number or as a fraction of two
+numbers (for example @code{3,1/10}). The first value to this option is the
+multiple of @mymath{\sigma} that will be clipped (@mymath{\alpha} in that
+section). The second value is the exit criteria. If it is less than 1, then
+it is interpretted as tolerance and if it is larger than one it is assumed
+to be the fixed number of iterations. Hence, in the latter case the value
+must be an integer.
+
address@hidden --checkdetsky
 Check the initial approximation of the sky value and its standard deviation
 in a FITS file ending with @file{_detsky.fits}. See @ref{Tessellation} for
-more information. If @option{--meshbasedcheck} is not called, then the
-first extension will be the the binary image with initial detections
-labeled one and background labeled zero. The mesh values will be in the
-subsequent extensions.
+more information. If @option{--oneelempertile} is not called (see
address@hidden options}), then the first extension will be the the binary
+image with initial detections labeled one and background labeled zero. The
+mesh values will be in the subsequent extensions.
 
 @item -R FLT
 @itemx --dthresh=FLT
@@ -12227,22 +12249,22 @@ be heavily skewed to the positive. So it is best to 
ignore any
 psudo-detection that is smaller than this area. Use
 @option{--detsnhistnbins} to check if this value is reasonable or not.
 
address@hidden --detsnhistnbins=INT
-If not equal to zero, a histogram of the Signal to noise ratios of the
-psudo-detections will be stored in a text file ending with
address@hidden The number of bins in this histogram is specified by the
-value given to this option. This is good for inspecting the best possible
-value to @option{--detsnminarea}.
-
-An empirical way to estimate the best @option{--detsnminarea} value
-for your data set is that the histogram have a sharp drop towards the
-higher S/Ns. In other words, when there is a prominent peak in the
-histogram and the last few bins have less than 10 (an arbitrary
-number, meaning very few!) pseudo-detections. When the minimum area is
-too large or too small, the slope of the histogram in the higher S/N
-bins will not be to sharp with the very high S/N bins having a large
-number of objects and the peak being less significant. A good minimum
-area will result in the last bins having very few pseudo-detections.
address@hidden --checkdetsn
+Save the S/N values of the pseudo-detections into a file ending with
address@hidden You can use these to inspect the values/distribution,
+you can use the histogram creating feature of @ref{Statistics} to make a
+histogram of the distribution (ready for plotting in a text file, or a
+crude ASCII-art demonstration on the command-line).
+
+You can use this for an empirical way to estimate the best
address@hidden value for your dataset. A good minimum area results
+in the histogram having a sharp drop towards the higher S/Ns. In other
+words, when there is a prominent peak in the histogram and the last few
+bins have less than 10 (an arbitrary number, meaning very few!)
+pseudo-detections. When the minimum area is too large or too small, the
+slope of the histogram in the higher S/N bins will not be too sharp with
+the very high S/N bins having a large number of objects and the peak being
+less significant.
 
 @item -c FLT
 @itemx --detquant=FLT
@@ -12252,7 +12274,7 @@ that this is only calculated for the large mesh grids 
that satisfy the
 minimum fraction of undetected pixels (value of @option{--minbfrac}) and
 minimum number of psudo-detections (value of @option{--minnumfalse}).
 
address@hidden -I INT
address@hidden -d INT
 @itemx --dilate=INT
 Number of times to dilate the final true detections. See the explanations
 in @option{--opening} for more information on dilation. The structuring
@@ -12318,7 +12340,7 @@ object.
 
 @table @option
 
address@hidden --detectonly
address@hidden --onlydetect
 If this option is called, no segmentation will be done. The object
 labels extension in the output will simply be the detection (connected
 components) labels and the clumps image will be blank (see
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 7fd8ef9..222d6c6 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -51,10 +51,10 @@ 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 blank.c box.c checkset.c convolve.c data.c fits.c   \
-  git.c interpolate.c linkedlist.c options.c permutation.c polygon.c       \
-  qsort.c dimension.c statistics.c table.c threads.c tile.c timing.c txt.c \
-  wcs.c
+  arithmetic-onlyint.c binary.c blank.c box.c checkset.c convolve.c data.c \
+  fits.c git.c interpolate.c linkedlist.c options.c permutation.c          \
+  polygon.c qsort.c dimension.c statistics.c table.c threads.c tile.c      \
+  timing.c txt.c type.c wcs.c
 
 
 
@@ -66,14 +66,15 @@ libgnuastro_la_SOURCES = arithmetic.c arithmetic-binary.c   
               \
 # in the $(headersdir) directory. Some of the header files don't need to be
 # installed.
 headersdir=$(top_srcdir)/lib/gnuastro
-pkginclude_HEADERS = gnuastro/config.h $(headersdir)/arithmetic.h          \
-  $(headersdir)/blank.h $(headersdir)/box.h $(headersdir)/convolve.h       \
-  $(headersdir)/data.h $(headersdir)/fits.h $(headersdir)/git.h            \
-  $(headersdir)/interpolate.h $(headersdir)/linkedlist.h                   \
-  $(headersdir)/dimension.h $(headersdir)/permutation.h                    \
-  $(headersdir)/polygon.h $(headersdir)/qsort.h $(headersdir)/statistics.h \
-  $(headersdir)/table.h $(headersdir)/threads.h $(headersdir)/tile.h       \
-  $(headersdir)/wcs.h $(headersdir)/txt.h
+pkginclude_HEADERS = gnuastro/config.h $(headersdir)/arithmetic.h        \
+  $(headersdir)/binary.h $(headersdir)/blank.h $(headersdir)/box.h       \
+  $(headersdir)/convolve.h $(headersdir)/data.h $(headersdir)/fits.h     \
+  $(headersdir)/git.h $(headersdir)/interpolate.h                        \
+  $(headersdir)/linkedlist.h $(headersdir)/dimension.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       \
+  $(headersdir)/type.h $(headersdir)/wcs.h
 
 
 
diff --git a/lib/arithmetic-binary.c b/lib/arithmetic-binary.c
index a4b6b79..2ed3f46 100644
--- a/lib/arithmetic-binary.c
+++ b/lib/arithmetic-binary.c
@@ -39,13 +39,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /************************************************************************/
 #if GAL_CONFIG_BIN_OP_UINT8 == 1
 #define BINARY_LT_IS_UINT8                                         \
-  case GAL_DATA_TYPE_UINT8:                                        \
-    BINARY_LT_SET(uint8_t);                                        \
-    break;
+  case GAL_TYPE_UINT8: BINARY_LT_SET(uint8_t);          break;
 #define BINARY_LT_SET_RT_IS_UINT8(LT)                              \
-  case GAL_DATA_TYPE_UINT8:                                        \
-    BINARY_RT_LT_SET(uint8_t, LT);                                 \
-    break;
+  case GAL_TYPE_UINT8: BINARY_RT_LT_SET(uint8_t, LT);   break;
 #else
 #define BINARY_LT_IS_UINT8
 #define BINARY_LT_SET_RT_IS_UINT8(LT)
@@ -57,13 +53,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT8 == 1
 #define BINARY_LT_IS_INT8                                          \
-  case GAL_DATA_TYPE_INT8:                                         \
-    BINARY_LT_SET(int8_t);                                         \
-    break;
+  case GAL_TYPE_INT8: BINARY_LT_SET(int8_t);            break;
 #define BINARY_LT_SET_RT_IS_INT8(LT)                               \
-  case GAL_DATA_TYPE_INT8:                                         \
-    BINARY_RT_LT_SET(int8_t, LT);                                  \
-    break;
+  case GAL_TYPE_INT8: BINARY_RT_LT_SET(int8_t, LT);     break;
 #else
 #define BINARY_LT_IS_INT8
 #define BINARY_LT_SET_RT_IS_INT8(LT)
@@ -75,13 +67,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT16 == 1
 #define BINARY_LT_IS_UINT16                                        \
-  case GAL_DATA_TYPE_UINT16:                                       \
-    BINARY_LT_SET(uint16_t);                                       \
-    break;
+  case GAL_TYPE_UINT16: BINARY_LT_SET(uint16_t);        break;
 #define BINARY_LT_SET_RT_IS_UINT16(LT)                             \
-  case GAL_DATA_TYPE_UINT16:                                       \
-    BINARY_RT_LT_SET(uint16_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT16: BINARY_RT_LT_SET(uint16_t, LT); break;
 #else
 #define BINARY_LT_IS_UINT16
 #define BINARY_LT_SET_RT_IS_UINT16(LT)
@@ -93,13 +81,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT16 == 1
 #define BINARY_LT_IS_INT16                                         \
-  case GAL_DATA_TYPE_INT16:                                        \
-    BINARY_LT_SET(int16_t);                                        \
-    break;
+  case GAL_TYPE_INT16: BINARY_LT_SET(int16_t);          break;
 #define BINARY_LT_SET_RT_IS_INT16(LT)                              \
-  case GAL_DATA_TYPE_INT16:                                        \
-    BINARY_RT_LT_SET(int16_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT16: BINARY_RT_LT_SET(int16_t, LT);   break;
 #else
 #define BINARY_LT_IS_INT16
 #define BINARY_LT_SET_RT_IS_INT16(LT)
@@ -111,13 +95,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT32 == 1
 #define BINARY_LT_IS_UINT32                                        \
-  case GAL_DATA_TYPE_UINT32:                                       \
-    BINARY_LT_SET(uint32_t);                                       \
-    break;
+  case GAL_TYPE_UINT32: BINARY_LT_SET(uint32_t);        break;
 #define BINARY_LT_SET_RT_IS_UINT32(LT)                             \
-  case GAL_DATA_TYPE_UINT32:                                       \
-    BINARY_RT_LT_SET(uint32_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT32: BINARY_RT_LT_SET(uint32_t, LT); break;
 #else
 #define BINARY_LT_IS_UINT32
 #define BINARY_LT_SET_RT_IS_UINT32(LT)
@@ -129,13 +109,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT32 == 1
 #define BINARY_LT_IS_INT32                                         \
-  case GAL_DATA_TYPE_INT32:                                        \
-    BINARY_LT_SET(int32_t);                                        \
-    break;
+  case GAL_TYPE_INT32: BINARY_LT_SET(int32_t);          break;
 #define BINARY_LT_SET_RT_IS_INT32(LT)                              \
-  case GAL_DATA_TYPE_INT32:                                        \
-    BINARY_RT_LT_SET(int32_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT32: BINARY_RT_LT_SET(int32_t, LT);   break;
 #else
 #define BINARY_LT_IS_INT32
 #define BINARY_LT_SET_RT_IS_INT32(LT)
@@ -147,13 +123,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT64 == 1
 #define BINARY_LT_IS_UINT64                                        \
-  case GAL_DATA_TYPE_UINT64:                                       \
-    BINARY_LT_SET(uint64_t);                                       \
-    break;
+  case GAL_TYPE_UINT64: BINARY_LT_SET(uint64_t);        break;
 #define BINARY_LT_SET_RT_IS_UINT64(LT)                             \
-  case GAL_DATA_TYPE_UINT64:                                       \
-    BINARY_RT_LT_SET(uint64_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT64: BINARY_RT_LT_SET(uint64_t, LT); break;
 #else
 #define BINARY_LT_IS_UINT64
 #define BINARY_LT_SET_RT_IS_UINT64(LT)
@@ -165,13 +137,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT64 == 1
 #define BINARY_LT_IS_INT64                                         \
-  case GAL_DATA_TYPE_INT64:                                        \
-    BINARY_LT_SET(int64_t);                                        \
-    break;
+  case GAL_TYPE_INT64: BINARY_LT_SET(int64_t);          break;
 #define BINARY_LT_SET_RT_IS_INT64(LT)                              \
-  case GAL_DATA_TYPE_INT64:                                        \
-    BINARY_RT_LT_SET(int64_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT64: BINARY_RT_LT_SET(int64_t, LT);   break;
 #else
 #define BINARY_LT_IS_INT64
 #define BINARY_LT_SET_RT_IS_INT64(LT)
@@ -183,13 +151,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_FLOAT32 == 1
 #define BINARY_LT_IS_FLOAT32                                       \
-  case GAL_DATA_TYPE_FLOAT32:                                      \
-    BINARY_LT_SET(float);                                          \
-    break;
+  case GAL_TYPE_FLOAT32: BINARY_LT_SET(float);          break;
 #define BINARY_LT_SET_RT_IS_FLOAT32(LT)                            \
-  case GAL_DATA_TYPE_FLOAT32:                                      \
-    BINARY_RT_LT_SET(float, LT);                                   \
-    break;
+  case GAL_TYPE_FLOAT32: BINARY_RT_LT_SET(float, LT);   break;
 #else
 #define BINARY_LT_IS_FLOAT32
 #define BINARY_LT_SET_RT_IS_FLOAT32(LT)
@@ -201,13 +165,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_FLOAT64 == 1
 #define BINARY_LT_IS_FLOAT64                                       \
-  case GAL_DATA_TYPE_FLOAT64:                                      \
-    BINARY_LT_SET(double);                                         \
-    break;
+  case GAL_TYPE_FLOAT64: BINARY_LT_SET(double);         break;
 #define BINARY_LT_SET_RT_IS_FLOAT64(LT)                            \
-  case GAL_DATA_TYPE_FLOAT64:                                      \
-    BINARY_RT_LT_SET(double, LT);                                  \
-    break;
+  case GAL_TYPE_FLOAT64: BINARY_RT_LT_SET(double, LT);  break;
 #else
 #define BINARY_LT_IS_FLOAT64
 #define BINARY_LT_SET_RT_IS_FLOAT64(LT)
diff --git a/lib/arithmetic-onlyint.c b/lib/arithmetic-onlyint.c
index 6073c32..0437866 100644
--- a/lib/arithmetic-onlyint.c
+++ b/lib/arithmetic-onlyint.c
@@ -40,13 +40,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /************************************************************************/
 #if GAL_CONFIG_BIN_OP_UINT8 == 1
 #define BINOIN_LT_IS_UINT8                                         \
-  case GAL_DATA_TYPE_UINT8:                                        \
-    BINOIN_LT_SET(uint8_t);                                        \
-    break;
+  case GAL_TYPE_UINT8: BINOIN_LT_SET(uint8_t);          break;
 #define BINOIN_LT_SET_RT_IS_UINT8(LT)                              \
-  case GAL_DATA_TYPE_UINT8:                                        \
-    BINOIN_RT_LT_SET(uint8_t, LT);                                 \
-    break;
+  case GAL_TYPE_UINT8: BINOIN_RT_LT_SET(uint8_t, LT);   break;
 #else
 #define BINOIN_LT_IS_UINT8
 #define BINOIN_LT_SET_RT_IS_UINT8(LT)
@@ -58,13 +54,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT8 == 1
 #define BINOIN_LT_IS_INT8                                          \
-  case GAL_DATA_TYPE_INT8:                                         \
-    BINOIN_LT_SET(int8_t);                                         \
-    break;
+  case GAL_TYPE_INT8: BINOIN_LT_SET(int8_t);            break;
 #define BINOIN_LT_SET_RT_IS_INT8(LT)                               \
-  case GAL_DATA_TYPE_INT8:                                         \
-    BINOIN_RT_LT_SET(int8_t, LT);                                  \
-    break;
+  case GAL_TYPE_INT8: BINOIN_RT_LT_SET(int8_t, LT);     break;
 #else
 #define BINOIN_LT_IS_INT8
 #define BINOIN_LT_SET_RT_IS_INT8(LT)
@@ -76,13 +68,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT16 == 1
 #define BINOIN_LT_IS_UINT16                                        \
-  case GAL_DATA_TYPE_UINT16:                                       \
-    BINOIN_LT_SET(uint16_t);                                       \
-    break;
+  case GAL_TYPE_UINT16: BINOIN_LT_SET(uint16_t);        break;
 #define BINOIN_LT_SET_RT_IS_UINT16(LT)                             \
-  case GAL_DATA_TYPE_UINT16:                                       \
-    BINOIN_RT_LT_SET(uint16_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT16: BINOIN_RT_LT_SET(uint16_t, LT); break;
 #else
 #define BINOIN_LT_IS_UINT16
 #define BINOIN_LT_SET_RT_IS_UINT16(LT)
@@ -94,13 +82,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT16 == 1
 #define BINOIN_LT_IS_INT16                                         \
-  case GAL_DATA_TYPE_INT16:                                        \
-    BINOIN_LT_SET(int16_t);                                        \
-    break;
+  case GAL_TYPE_INT16: BINOIN_LT_SET(int16_t);          break;
 #define BINOIN_LT_SET_RT_IS_INT16(LT)                              \
-  case GAL_DATA_TYPE_INT16:                                        \
-    BINOIN_RT_LT_SET(int16_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT16: BINOIN_RT_LT_SET(int16_t, LT);   break;
 #else
 #define BINOIN_LT_IS_INT16
 #define BINOIN_LT_SET_RT_IS_INT16(LT)
@@ -112,13 +96,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT32 == 1
 #define BINOIN_LT_IS_UINT32                                        \
-  case GAL_DATA_TYPE_UINT32:                                       \
-    BINOIN_LT_SET(uint32_t);                                       \
-    break;
+  case GAL_TYPE_UINT32: BINOIN_LT_SET(uint32_t);        break;
 #define BINOIN_LT_SET_RT_IS_UINT32(LT)                             \
-  case GAL_DATA_TYPE_UINT32:                                       \
-    BINOIN_RT_LT_SET(uint32_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT32: BINOIN_RT_LT_SET(uint32_t, LT); break;
 #else
 #define BINOIN_LT_IS_UINT32
 #define BINOIN_LT_SET_RT_IS_UINT32(LT)
@@ -130,13 +110,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT32 == 1
 #define BINOIN_LT_IS_INT32                                         \
-  case GAL_DATA_TYPE_INT32:                                        \
-    BINOIN_LT_SET(int32_t);                                        \
-    break;
+  case GAL_TYPE_INT32: BINOIN_LT_SET(int32_t);          break;
 #define BINOIN_LT_SET_RT_IS_INT32(LT)                              \
-  case GAL_DATA_TYPE_INT32:                                        \
-    BINOIN_RT_LT_SET(int32_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT32: BINOIN_RT_LT_SET(int32_t, LT);   break;
 #else
 #define BINOIN_LT_IS_INT32
 #define BINOIN_LT_SET_RT_IS_INT32(LT)
@@ -148,13 +124,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_UINT64 == 1
 #define BINOIN_LT_IS_UINT64                                        \
-  case GAL_DATA_TYPE_UINT64:                                       \
-    BINOIN_LT_SET(uint64_t);                                       \
-    break;
+  case GAL_TYPE_UINT64: BINOIN_LT_SET(uint64_t);        break;
 #define BINOIN_LT_SET_RT_IS_UINT64(LT)                             \
-  case GAL_DATA_TYPE_UINT64:                                       \
-    BINOIN_RT_LT_SET(uint64_t, LT);                                \
-    break;
+  case GAL_TYPE_UINT64: BINOIN_RT_LT_SET(uint64_t, LT); break;
 #else
 #define BINOIN_LT_IS_UINT64
 #define BINOIN_LT_SET_RT_IS_UINT64(LT)
@@ -166,13 +138,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 #if GAL_CONFIG_BIN_OP_INT64 == 1
 #define BINOIN_LT_IS_INT64                                         \
-  case GAL_DATA_TYPE_INT64:                                        \
-    BINOIN_LT_SET(int64_t);                                        \
-    break;
+  case GAL_TYPE_INT64: BINOIN_LT_SET(int64_t);          break;
 #define BINOIN_LT_SET_RT_IS_INT64(LT)                              \
-  case GAL_DATA_TYPE_INT64:                                        \
-    BINOIN_RT_LT_SET(int64_t, LT);                                 \
-    break;
+  case GAL_TYPE_INT64: BINOIN_RT_LT_SET(int64_t, LT);   break;
 #else
 #define BINOIN_LT_IS_INT64
 #define BINOIN_LT_SET_RT_IS_INT64(LT)
@@ -314,8 +282,8 @@ arithmetic_onlyint_binary(int operator, unsigned char flags,
     error(EXIT_FAILURE, 0, "the non-number inputs to %s don't have the "
           "same dimension/size", opstring);
 
-  if( lo->type==GAL_DATA_TYPE_FLOAT32 || lo->type==GAL_DATA_TYPE_FLOAT64
-      || ro->type==GAL_DATA_TYPE_FLOAT32 || ro->type==GAL_DATA_TYPE_FLOAT64 )
+  if( lo->type==GAL_TYPE_FLOAT32 || lo->type==GAL_TYPE_FLOAT64
+      || ro->type==GAL_TYPE_FLOAT32 || ro->type==GAL_TYPE_FLOAT64 )
       error(EXIT_FAILURE, 0, "the %s operator can only work on integer "
             "type operands", opstring);
 
@@ -336,7 +304,7 @@ arithmetic_onlyint_binary(int operator, unsigned char flags,
 
 
   /* Sanity check: see if the compiled type is actually an integer. */
-  if( l->type>=GAL_DATA_TYPE_FLOAT32 || r->type>=GAL_DATA_TYPE_FLOAT32 )
+  if( l->type>=GAL_TYPE_FLOAT32 || r->type>=GAL_TYPE_FLOAT32 )
     error(EXIT_FAILURE, 0, "no larger integer compiled type. The `%s' "
           "operator can only work on integer types. The left and right "
           "operands had types `%s' and `%s'.\n\nYou can use the "
@@ -347,11 +315,10 @@ arithmetic_onlyint_binary(int operator, unsigned char 
flags,
           "and `q' to return to the command-line):\n\n"
           "    $ info gnuastro \"Gnuastro configure options\"\n",
           gal_arithmetic_operator_string(operator),
-          gal_data_type_as_string(lo->type, 1),
-          gal_data_type_as_string(ro->type, 1));
+          gal_type_to_string(lo->type, 1), gal_type_to_string(ro->type, 1));
 
   /* Set the output type. */
-  otype=gal_data_out_type(l, r);
+  otype=gal_type_out(l->type, r->type);
 
 
   /* Set the output sizes. */
@@ -456,8 +423,8 @@ arithmetic_onlyint_bitwise_not(unsigned char flags, 
gal_data_t *in)
   /* Check the type */
   switch(in->type)
     {
-    case GAL_DATA_TYPE_FLOAT32:
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT64:
       error(EXIT_FAILURE, 0, "the bitwise not (one's complement) "
             "operator can only work on integer types");
     }
@@ -473,29 +440,29 @@ arithmetic_onlyint_bitwise_not(unsigned char flags, 
gal_data_t *in)
   /* Start setting the types. */
   switch(in->type)
     {
-    case GAL_DATA_TYPE_UINT8:
-      ou8=o->array;   do  *ou8++ = ~(*iu8++);    while(iu8<iu8f);
+    case GAL_TYPE_UINT8:
+      ou8=o->array;   do  *ou8++ = ~(*iu8++);    while(iu8<iu8f);     break;
 
-    case GAL_DATA_TYPE_INT8:
-      oi8=o->array;   do  *oi8++ = ~(*ii8++);    while(ii8<ii8f);
+    case GAL_TYPE_INT8:
+      oi8=o->array;   do  *oi8++ = ~(*ii8++);    while(ii8<ii8f);     break;
 
-    case GAL_DATA_TYPE_UINT16:
-      ou16=o->array;  do *ou16++ = ~(*iu16++);   while(iu16<iu16f);
+    case GAL_TYPE_UINT16:
+      ou16=o->array;  do *ou16++ = ~(*iu16++);   while(iu16<iu16f);   break;
 
-    case GAL_DATA_TYPE_INT16:
-      oi16=o->array;  do *oi16++ = ~(*ii16++);   while(ii16<ii16f);
+    case GAL_TYPE_INT16:
+      oi16=o->array;  do *oi16++ = ~(*ii16++);   while(ii16<ii16f);   break;
 
-    case GAL_DATA_TYPE_UINT32:
-      ou32=o->array;  do *ou32++ = ~(*iu32++);   while(iu32<iu32f);
+    case GAL_TYPE_UINT32:
+      ou32=o->array;  do *ou32++ = ~(*iu32++);   while(iu32<iu32f);   break;
 
-    case GAL_DATA_TYPE_INT32:
-      oi32=o->array;  do *oi32++ = ~(*ii32++);   while(ii32<ii32f);
+    case GAL_TYPE_INT32:
+      oi32=o->array;  do *oi32++ = ~(*ii32++);   while(ii32<ii32f);   break;
 
-    case GAL_DATA_TYPE_UINT64:
-      ou64=o->array;  do *ou64++ = ~(*iu64++);   while(iu64<iu64f);
+    case GAL_TYPE_UINT64:
+      ou64=o->array;  do *ou64++ = ~(*iu64++);   while(iu64<iu64f);   break;
 
-    case GAL_DATA_TYPE_INT64:
-      oi64=o->array;  do *oi64++ = ~(*ii64++);   while(ii64<ii64f);
+    case GAL_TYPE_INT64:
+      oi64=o->array;  do *oi64++ = ~(*ii64++);   while(ii64<ii64f);   break;
 
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 68d301e..112076b 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -54,16 +54,16 @@ arithmetic_change_type(gal_data_t *data, int operator, 
unsigned char flags)
   /* Set the output type. */
   switch(operator)
     {
-    case GAL_ARITHMETIC_OP_TO_UINT8:    type=GAL_DATA_TYPE_UINT8;    break;
-    case GAL_ARITHMETIC_OP_TO_INT8:     type=GAL_DATA_TYPE_INT8;     break;
-    case GAL_ARITHMETIC_OP_TO_UINT16:   type=GAL_DATA_TYPE_UINT16;   break;
-    case GAL_ARITHMETIC_OP_TO_INT16:    type=GAL_DATA_TYPE_INT16;    break;
-    case GAL_ARITHMETIC_OP_TO_UINT32:   type=GAL_DATA_TYPE_UINT32;   break;
-    case GAL_ARITHMETIC_OP_TO_INT32:    type=GAL_DATA_TYPE_INT32;    break;
-    case GAL_ARITHMETIC_OP_TO_UINT64:   type=GAL_DATA_TYPE_UINT64;   break;
-    case GAL_ARITHMETIC_OP_TO_INT64:    type=GAL_DATA_TYPE_INT64;    break;
-    case GAL_ARITHMETIC_OP_TO_FLOAT32:  type=GAL_DATA_TYPE_FLOAT32;  break;
-    case GAL_ARITHMETIC_OP_TO_FLOAT64:  type=GAL_DATA_TYPE_FLOAT64;  break;
+    case GAL_ARITHMETIC_OP_TO_UINT8:    type=GAL_TYPE_UINT8;    break;
+    case GAL_ARITHMETIC_OP_TO_INT8:     type=GAL_TYPE_INT8;     break;
+    case GAL_ARITHMETIC_OP_TO_UINT16:   type=GAL_TYPE_UINT16;   break;
+    case GAL_ARITHMETIC_OP_TO_INT16:    type=GAL_TYPE_INT16;    break;
+    case GAL_ARITHMETIC_OP_TO_UINT32:   type=GAL_TYPE_UINT32;   break;
+    case GAL_ARITHMETIC_OP_TO_INT32:    type=GAL_TYPE_INT32;    break;
+    case GAL_ARITHMETIC_OP_TO_UINT64:   type=GAL_TYPE_UINT64;   break;
+    case GAL_ARITHMETIC_OP_TO_INT64:    type=GAL_TYPE_INT64;    break;
+    case GAL_ARITHMETIC_OP_TO_FLOAT32:  type=GAL_TYPE_FLOAT32;  break;
+    case GAL_ARITHMETIC_OP_TO_FLOAT64:  type=GAL_TYPE_FLOAT64;  break;
     default:
       error(EXIT_FAILURE, 0, "operator value of %d not recognized in "
             "`arithmetic_change_type'", operator);
@@ -98,7 +98,7 @@ arithmetic_not(gal_data_t *data, unsigned char flags)
   gal_data_t *out;
 
   /* Allocate the output array. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, data->ndim, data->dsize,
+  out=gal_data_alloc(NULL, GAL_TYPE_UINT8, data->ndim, data->dsize,
                      data->wcs, 0, data->minmapsize, data->name, data->unit,
                      data->comment);
   o=out->array;
@@ -107,18 +107,18 @@ arithmetic_not(gal_data_t *data, unsigned char flags)
   /* Go over the pixels and set the output values. */
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:   TYPE_CASE_FOR_NOT(uint8_t);   break;
-    case GAL_DATA_TYPE_INT8:    TYPE_CASE_FOR_NOT(int8_t);    break;
-    case GAL_DATA_TYPE_UINT16:  TYPE_CASE_FOR_NOT(uint16_t);  break;
-    case GAL_DATA_TYPE_INT16:   TYPE_CASE_FOR_NOT(int16_t);   break;
-    case GAL_DATA_TYPE_UINT32:  TYPE_CASE_FOR_NOT(uint32_t);  break;
-    case GAL_DATA_TYPE_INT32:   TYPE_CASE_FOR_NOT(int32_t);   break;
-    case GAL_DATA_TYPE_UINT64:  TYPE_CASE_FOR_NOT(uint64_t);  break;
-    case GAL_DATA_TYPE_INT64:   TYPE_CASE_FOR_NOT(int64_t);   break;
-    case GAL_DATA_TYPE_FLOAT32: TYPE_CASE_FOR_NOT(float);     break;
-    case GAL_DATA_TYPE_FLOAT64: TYPE_CASE_FOR_NOT(double);    break;
-
-    case GAL_DATA_TYPE_BIT:
+    case GAL_TYPE_UINT8:   TYPE_CASE_FOR_NOT(uint8_t);   break;
+    case GAL_TYPE_INT8:    TYPE_CASE_FOR_NOT(int8_t);    break;
+    case GAL_TYPE_UINT16:  TYPE_CASE_FOR_NOT(uint16_t);  break;
+    case GAL_TYPE_INT16:   TYPE_CASE_FOR_NOT(int16_t);   break;
+    case GAL_TYPE_UINT32:  TYPE_CASE_FOR_NOT(uint32_t);  break;
+    case GAL_TYPE_INT32:   TYPE_CASE_FOR_NOT(int32_t);   break;
+    case GAL_TYPE_UINT64:  TYPE_CASE_FOR_NOT(uint64_t);  break;
+    case GAL_TYPE_INT64:   TYPE_CASE_FOR_NOT(int64_t);   break;
+    case GAL_TYPE_FLOAT32: TYPE_CASE_FOR_NOT(float);     break;
+    case GAL_TYPE_FLOAT64: TYPE_CASE_FOR_NOT(double);    break;
+
+    case GAL_TYPE_BIT:
       error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
             "datatype, please get in touch with us to implement it.");
 
@@ -168,16 +168,16 @@ arithmetic_abs(unsigned char flags, gal_data_t *in)
      output must be a separate array), just copy the values.*/
   switch(in->type)
     {
-    case GAL_DATA_TYPE_UINT8:   ARITHMETIC_ABS_SGN(uint8_t, 0);   break;
-    case GAL_DATA_TYPE_INT8:    ARITHMETIC_ABS_SGN(int8_t, 1);    break;
-    case GAL_DATA_TYPE_UINT16:  ARITHMETIC_ABS_SGN(uint16_t, 0);  break;
-    case GAL_DATA_TYPE_INT16:   ARITHMETIC_ABS_SGN(int16_t, 1);   break;
-    case GAL_DATA_TYPE_UINT32:  ARITHMETIC_ABS_SGN(uint32_t, 0);  break;
-    case GAL_DATA_TYPE_INT32:   ARITHMETIC_ABS_SGN(int32_t, 1);   break;
-    case GAL_DATA_TYPE_UINT64:  ARITHMETIC_ABS_SGN(uint64_t, 0);  break;
-    case GAL_DATA_TYPE_INT64:   ARITHMETIC_ABS_SGN(int64_t, 1);   break;
-    case GAL_DATA_TYPE_FLOAT32: ARITHMETIC_ABS_SGN(float, 1);     break;
-    case GAL_DATA_TYPE_FLOAT64: ARITHMETIC_ABS_SGN(double, 1);    break;
+    case GAL_TYPE_UINT8:   ARITHMETIC_ABS_SGN(uint8_t, 0);   break;
+    case GAL_TYPE_INT8:    ARITHMETIC_ABS_SGN(int8_t, 1);    break;
+    case GAL_TYPE_UINT16:  ARITHMETIC_ABS_SGN(uint16_t, 0);  break;
+    case GAL_TYPE_INT16:   ARITHMETIC_ABS_SGN(int16_t, 1);   break;
+    case GAL_TYPE_UINT32:  ARITHMETIC_ABS_SGN(uint32_t, 0);  break;
+    case GAL_TYPE_INT32:   ARITHMETIC_ABS_SGN(int32_t, 1);   break;
+    case GAL_TYPE_UINT64:  ARITHMETIC_ABS_SGN(uint64_t, 0);  break;
+    case GAL_TYPE_INT64:   ARITHMETIC_ABS_SGN(int64_t, 1);   break;
+    case GAL_TYPE_FLOAT32: ARITHMETIC_ABS_SGN(float, 1);     break;
+    case GAL_TYPE_FLOAT64: ARITHMETIC_ABS_SGN(double, 1);    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`arithmetic_abs'", in->type);
@@ -220,8 +220,8 @@ arithmetic_check_float_input(gal_data_t *in, int operator, 
char *numstr)
 {
   switch(in->type)
     {
-    case GAL_DATA_TYPE_FLOAT32:
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT64:
       break;
     default:
       error(EXIT_FAILURE, 0, "the %s operator can only accept single or "
@@ -233,7 +233,7 @@ arithmetic_check_float_input(gal_data_t *in, int operator, 
char *numstr)
             "after it so it is directly read into the proper precision "
             "floating point number (based on the number of non-zero "
             "decimals it has)", gal_arithmetic_operator_string(operator),
-            numstr, gal_data_type_as_string(in->type, 1));
+            numstr, gal_type_to_string(in->type, 1));
     }
 }
 
@@ -272,34 +272,34 @@ arithmetic_check_float_input(gal_data_t *in, int 
operator, char *numstr)
 #define UNIARY_FUNCTION_ON_ELEMENT(OP)                                  \
   switch(in->type)                                                      \
     {                                                                   \
-    case GAL_DATA_TYPE_UINT8:                                           \
+    case GAL_TYPE_UINT8:                                                \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint8_t, OP)                      \
-      break;                                                            \
-    case GAL_DATA_TYPE_INT8:                                            \
+        break;                                                          \
+    case GAL_TYPE_INT8:                                                 \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int8_t, OP)                       \
-      break;                                                            \
-    case GAL_DATA_TYPE_UINT16:                                          \
+        break;                                                          \
+    case GAL_TYPE_UINT16:                                               \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint16_t, OP)                     \
-      break;                                                            \
-    case GAL_DATA_TYPE_INT16:                                           \
+        break;                                                          \
+    case GAL_TYPE_INT16:                                                \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int16_t, OP)                      \
-      break;                                                            \
-    case GAL_DATA_TYPE_UINT32:                                          \
+        break;                                                          \
+    case GAL_TYPE_UINT32:                                               \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint32_t, OP)                     \
-      break;                                                            \
-    case GAL_DATA_TYPE_INT32:                                           \
+        break;                                                          \
+    case GAL_TYPE_INT32:                                                \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int32_t, OP)                      \
-      break;                                                            \
-    case GAL_DATA_TYPE_UINT64:                                          \
+        break;                                                          \
+    case GAL_TYPE_UINT64:                                               \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(uint64_t, OP)                     \
-      break;                                                            \
-    case GAL_DATA_TYPE_INT64:                                           \
+        break;                                                          \
+    case GAL_TYPE_INT64:                                                \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(int64_t, OP)                      \
-      break;                                                            \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
+        break;                                                          \
+    case GAL_TYPE_FLOAT32:                                              \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(float, OP)                        \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
+    case GAL_TYPE_FLOAT64:                                              \
       UNIFUNC_RUN_FUNCTION_ON_ELEMENT(double, OP)                       \
       break;                                                            \
     default:                                                            \
@@ -400,10 +400,10 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(RT, LT, OP)                   \
   switch(o->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
+    case GAL_TYPE_FLOAT32:                                              \
       BINFUNC_RUN_FUNCTION(float, RT, LT, OP);                          \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
+    case GAL_TYPE_FLOAT64:                                              \
       BINFUNC_RUN_FUNCTION(double, RT, LT, OP);                         \
       break;                                                            \
     default:                                                            \
@@ -419,15 +419,15 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_LEFT_SET(LT, OP)                             \
   switch(r->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
+    case GAL_TYPE_FLOAT32:                                              \
       BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(float, LT, OP);                 \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
+    case GAL_TYPE_FLOAT64:                                              \
       BINFUNC_F_OPERATOR_LEFT_RIGHT_SET(double, LT, OP);                \
       break;                                                            \
     default:                                                            \
       error(EXIT_FAILURE, 0, "type %d not recognized in "               \
-            "for r->type in BINFUNC_F_OPERATOR_LEFT_SET", r->type);    \
+            "for r->type in BINFUNC_F_OPERATOR_LEFT_SET", r->type);     \
     }
 
 
@@ -437,10 +437,10 @@ arithmetic_unary_function(int operator, unsigned char 
flags, gal_data_t *in)
 #define BINFUNC_F_OPERATOR_SET(OP)                                      \
   switch(l->type)                                                       \
     {                                                                   \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
+    case GAL_TYPE_FLOAT32:                                              \
       BINFUNC_F_OPERATOR_LEFT_SET(float, OP);                           \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
+    case GAL_TYPE_FLOAT64:                                              \
       BINFUNC_F_OPERATOR_LEFT_SET(double, OP);                          \
       break;                                                            \
     default:                                                            \
@@ -472,7 +472,7 @@ arithmetic_binary_function_flt(int operator, unsigned char 
flags,
   arithmetic_check_float_input(r, operator, "second");
 
   /* Set the output type. */
-  final_otype = gal_data_out_type(l, r);
+  final_otype = gal_type_out(l->type, r->type);
 
   /* Set the output sizes. */
   minmapsize = ( l->minmapsize < r->minmapsize
@@ -579,42 +579,22 @@ arithmetic_binary_function_flt(int operator, unsigned 
char flags,
 
 
 
-#define WHERE_OUT_SET(OT)                                            \
-  switch(iftrue->type)                                               \
-    {                                                                \
-    case GAL_DATA_TYPE_UINT8:                                        \
-      DO_WHERE_OPERATION(uint8_t, OT);                               \
-      break;                                                         \
-    case GAL_DATA_TYPE_INT8:                                         \
-      DO_WHERE_OPERATION(int8_t, OT);                                \
-      break;                                                         \
-    case GAL_DATA_TYPE_UINT16:                                       \
-      DO_WHERE_OPERATION(uint16_t, OT);                              \
-      break;                                                         \
-    case GAL_DATA_TYPE_INT16:                                        \
-      DO_WHERE_OPERATION(int16_t, OT);                               \
-      break;                                                         \
-    case GAL_DATA_TYPE_UINT32:                                       \
-      DO_WHERE_OPERATION(uint32_t, OT);                              \
-      break;                                                         \
-    case GAL_DATA_TYPE_INT32:                                        \
-      DO_WHERE_OPERATION(int32_t, OT);                               \
-      break;                                                         \
-    case GAL_DATA_TYPE_UINT64:                                       \
-      DO_WHERE_OPERATION(uint64_t, OT);                              \
-      break;                                                         \
-    case GAL_DATA_TYPE_INT64:                                        \
-      DO_WHERE_OPERATION(int64_t, OT);                               \
-      break;                                                         \
-    case GAL_DATA_TYPE_FLOAT32:                                      \
-      DO_WHERE_OPERATION(float, OT);                                 \
-      break;                                                         \
-    case GAL_DATA_TYPE_FLOAT64:                                      \
-      DO_WHERE_OPERATION(double, OT);                                \
-      break;                                                         \
-    default:                                                         \
-      error(EXIT_FAILURE, 0, "type code %d not recognized for the "  \
-            "`iftrue' dataset of `WHERE_OUT_SET'", iftrue->type);    \
+#define WHERE_OUT_SET(OT)                                               \
+  switch(iftrue->type)                                                  \
+    {                                                                   \
+    case GAL_TYPE_UINT8:    DO_WHERE_OPERATION( uint8_t,  OT);  break;  \
+    case GAL_TYPE_INT8:     DO_WHERE_OPERATION( int8_t,   OT);  break;  \
+    case GAL_TYPE_UINT16:   DO_WHERE_OPERATION( uint16_t, OT);  break;  \
+    case GAL_TYPE_INT16:    DO_WHERE_OPERATION( int16_t,  OT);  break;  \
+    case GAL_TYPE_UINT32:   DO_WHERE_OPERATION( uint32_t, OT);  break;  \
+    case GAL_TYPE_INT32:    DO_WHERE_OPERATION( int32_t,  OT);  break;  \
+    case GAL_TYPE_UINT64:   DO_WHERE_OPERATION( uint64_t, OT);  break;  \
+    case GAL_TYPE_INT64:    DO_WHERE_OPERATION( int64_t,  OT);  break;  \
+    case GAL_TYPE_FLOAT32:  DO_WHERE_OPERATION( float,    OT);  break;  \
+    case GAL_TYPE_FLOAT64:  DO_WHERE_OPERATION( double,   OT);  break;  \
+    default:                                                            \
+      error(EXIT_FAILURE, 0, "type code %d not recognized for the "     \
+            "`iftrue' dataset of `WHERE_OUT_SET'", iftrue->type);       \
     }
 
 
@@ -628,10 +608,10 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
   unsigned char *c=cond->array;
 
   /* The condition operator has to be unsigned char. */
-  if(cond->type!=GAL_DATA_TYPE_UINT8)
+  if(cond->type!=GAL_TYPE_UINT8)
     error(EXIT_FAILURE, 0, "the condition operand to `arithmetic_where' "
           "must be an `unsigned char' type, but the given condition "
-          "operator has a `%s' type", gal_data_type_as_string(cond->type, 1));
+          "operator has a `%s' type", gal_type_to_string(cond->type, 1));
 
   /* The dimension and sizes of the out and condition data sets must be the
      same. */
@@ -642,36 +622,16 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
   /* Do the operation. */
   switch(out->type)
     {
-    case GAL_DATA_TYPE_UINT8:
-      WHERE_OUT_SET(uint8_t);
-      break;
-    case GAL_DATA_TYPE_INT8:
-      WHERE_OUT_SET(uint8_t);
-      break;
-    case GAL_DATA_TYPE_UINT16:
-      WHERE_OUT_SET(uint16_t);
-      break;
-    case GAL_DATA_TYPE_INT16:
-      WHERE_OUT_SET(int16_t);
-      break;
-    case GAL_DATA_TYPE_UINT32:
-      WHERE_OUT_SET(uint32_t);
-      break;
-    case GAL_DATA_TYPE_INT32:
-      WHERE_OUT_SET(int32_t);
-      break;
-    case GAL_DATA_TYPE_UINT64:
-      WHERE_OUT_SET(uint64_t);
-      break;
-    case GAL_DATA_TYPE_INT64:
-      WHERE_OUT_SET(int64_t);
-      break;
-    case GAL_DATA_TYPE_FLOAT32:
-      WHERE_OUT_SET(float);
-      break;
-    case GAL_DATA_TYPE_FLOAT64:
-      WHERE_OUT_SET(double);
-      break;
+    case GAL_TYPE_UINT8:         WHERE_OUT_SET( uint8_t  );      break;
+    case GAL_TYPE_INT8:          WHERE_OUT_SET( int8_t   );      break;
+    case GAL_TYPE_UINT16:        WHERE_OUT_SET( uint16_t );      break;
+    case GAL_TYPE_INT16:         WHERE_OUT_SET( int16_t  );      break;
+    case GAL_TYPE_UINT32:        WHERE_OUT_SET( uint32_t );      break;
+    case GAL_TYPE_INT32:         WHERE_OUT_SET( int32_t  );      break;
+    case GAL_TYPE_UINT64:        WHERE_OUT_SET( uint64_t );      break;
+    case GAL_TYPE_INT64:         WHERE_OUT_SET( int64_t  );      break;
+    case GAL_TYPE_FLOAT32:       WHERE_OUT_SET( float    );      break;
+    case GAL_TYPE_FLOAT64:       WHERE_OUT_SET( double   );      break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized for the `out' "
             "dataset of `arithmetic_where'", out->type);
@@ -709,7 +669,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
 /***********************************************************************/
 #define MULTIOPERAND_MIN(TYPE) {                                        \
     TYPE p, max;                                                        \
-    gal_data_type_max(list->type, &max);                                \
+    gal_type_max(list->type, &max);                                     \
     do    /* Loop over each pixel */                                    \
       {                                                                 \
         p=max;                                                          \
@@ -731,7 +691,7 @@ arithmetic_where(unsigned char flags, gal_data_t *out, 
gal_data_t *cond,
 
 #define MULTIOPERAND_MAX(TYPE) {                                        \
     TYPE p, min;                                                        \
-    gal_data_type_min(list->type, &min);                                \
+    gal_type_min(list->type, &min);                                     \
     do    /* Loop over each pixel */                                    \
       {                                                                 \
         p=min;                                                          \
@@ -1017,7 +977,7 @@ arithmetic_multioperand(int operator, unsigned char flags, 
gal_data_t *list)
 
   /* hasblank is used to see if a blank value should be checked for each
      list element or not. */
-  hasblank=gal_data_malloc_array(GAL_DATA_TYPE_UINT8, dnum);
+  hasblank=gal_data_malloc_array(GAL_TYPE_UINT8, dnum);
   for(tmp=list;tmp!=NULL;tmp=tmp->next)
     hasblank[i++]=gal_blank_present(tmp);
 
@@ -1025,34 +985,34 @@ arithmetic_multioperand(int operator, unsigned char 
flags, gal_data_t *list)
   /* Start the operation. */
   switch(list->type)
     {
-    case GAL_DATA_TYPE_UINT8:
+    case GAL_TYPE_UINT8:
       MULTIOPERAND_TYPE_SET(uint8_t,   gal_qsort_uint8_increasing);
       break;
-    case GAL_DATA_TYPE_INT8:
+    case GAL_TYPE_INT8:
       MULTIOPERAND_TYPE_SET(int8_t,    gal_qsort_int8_increasing);
       break;
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       MULTIOPERAND_TYPE_SET(uint16_t,  gal_qsort_uint16_increasing);
       break;
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       MULTIOPERAND_TYPE_SET(int16_t,   gal_qsort_int16_increasing);
       break;
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       MULTIOPERAND_TYPE_SET(uint32_t,  gal_qsort_uint32_increasing);
       break;
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       MULTIOPERAND_TYPE_SET(int32_t,   gal_qsort_int32_increasing);
       break;
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       MULTIOPERAND_TYPE_SET(uint64_t,  gal_qsort_uint64_increasing);
       break;
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       MULTIOPERAND_TYPE_SET(int64_t,   gal_qsort_int64_increasing);
       break;
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       MULTIOPERAND_TYPE_SET(float,     gal_qsort_float32_increasing);
       break;
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       MULTIOPERAND_TYPE_SET(double,    gal_qsort_float64_increasing);
       break;
     default:
@@ -1109,10 +1069,10 @@ gal_arithmetic_binary_out_type(int operator, gal_data_t 
*l, gal_data_t *r)
     case GAL_ARITHMETIC_OP_MINUS:
     case GAL_ARITHMETIC_OP_MULTIPLY:
     case GAL_ARITHMETIC_OP_DIVIDE:
-      return gal_data_out_type(l, r);
+      return gal_type_out(l->type, r->type);
 
     default:
-      return GAL_DATA_TYPE_UINT8;
+      return GAL_TYPE_UINT8;
     }
   return -1;
 }
@@ -1126,106 +1086,106 @@ arithmetic_nearest_compiled_type(int intype)
 {
   switch(intype)
     {
-    case GAL_DATA_TYPE_UINT8:
-      if(GAL_CONFIG_BIN_OP_UINT8) return GAL_DATA_TYPE_UINT8;
+    case GAL_TYPE_UINT8:
+      if(GAL_CONFIG_BIN_OP_UINT8) return GAL_TYPE_UINT8;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_UINT16)   return GAL_DATA_TYPE_UINT16;
-          else if(GAL_CONFIG_BIN_OP_INT16)    return GAL_DATA_TYPE_INT16;
-          else if(GAL_CONFIG_BIN_OP_UINT32)   return GAL_DATA_TYPE_UINT32;
-          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
-          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
-          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_UINT16)   return GAL_TYPE_UINT16;
+          else if(GAL_CONFIG_BIN_OP_INT16)    return GAL_TYPE_INT16;
+          else if(GAL_CONFIG_BIN_OP_UINT32)   return GAL_TYPE_UINT32;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_INT8:
-      if(GAL_CONFIG_BIN_OP_INT8) return GAL_DATA_TYPE_INT8;
+    case GAL_TYPE_INT8:
+      if(GAL_CONFIG_BIN_OP_INT8) return GAL_TYPE_INT8;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_INT16)    return GAL_DATA_TYPE_INT16;
-          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
-          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_INT16)    return GAL_TYPE_INT16;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_UINT16:
-      if(GAL_CONFIG_BIN_OP_UINT16) return GAL_DATA_TYPE_UINT16;
+    case GAL_TYPE_UINT16:
+      if(GAL_CONFIG_BIN_OP_UINT16) return GAL_TYPE_UINT16;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_UINT32)   return GAL_DATA_TYPE_UINT32;
-          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
-          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
-          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_UINT32)   return GAL_TYPE_UINT32;
+          else if(GAL_CONFIG_BIN_OP_INT32)    return GAL_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_UINT64)   return GAL_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_INT16:
-      if(GAL_CONFIG_BIN_OP_INT16) return GAL_DATA_TYPE_INT16;
+    case GAL_TYPE_INT16:
+      if(GAL_CONFIG_BIN_OP_INT16) return GAL_TYPE_INT16;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_INT32)    return GAL_DATA_TYPE_INT32;
-          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_INT32)    return GAL_TYPE_INT32;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_UINT32:
-      if(GAL_CONFIG_BIN_OP_UINT32) return GAL_DATA_TYPE_UINT32;
+    case GAL_TYPE_UINT32:
+      if(GAL_CONFIG_BIN_OP_UINT32) return GAL_TYPE_UINT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_UINT64)   return GAL_DATA_TYPE_UINT64;
-          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_UINT64)   return GAL_TYPE_UINT64;
+          else if(GAL_CONFIG_BIN_OP_INT64)    return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)  return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)  return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_INT32:
-      if(GAL_CONFIG_BIN_OP_INT32) return GAL_DATA_TYPE_INT32;
+    case GAL_TYPE_INT32:
+      if(GAL_CONFIG_BIN_OP_INT32) return GAL_TYPE_INT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_INT64)     return GAL_DATA_TYPE_INT64;
-          else if(GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_INT64)     return GAL_TYPE_INT64;
+          else if(GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_UINT64:
-      if(GAL_CONFIG_BIN_OP_UINT64) return GAL_DATA_TYPE_UINT64;
+    case GAL_TYPE_UINT64:
+      if(GAL_CONFIG_BIN_OP_UINT64) return GAL_TYPE_UINT64;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_INT64:
-      if(GAL_CONFIG_BIN_OP_INT64) return GAL_DATA_TYPE_INT64;
+    case GAL_TYPE_INT64:
+      if(GAL_CONFIG_BIN_OP_INT64) return GAL_TYPE_INT64;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_DATA_TYPE_FLOAT32;
-          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_FLOAT32)   return GAL_TYPE_FLOAT32;
+          else if(GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_FLOAT32:
-      if(GAL_CONFIG_BIN_OP_FLOAT32) return GAL_DATA_TYPE_FLOAT32;
+    case GAL_TYPE_FLOAT32:
+      if(GAL_CONFIG_BIN_OP_FLOAT32) return GAL_TYPE_FLOAT32;
       else
         {
-          if     (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
+          if     (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_TYPE_FLOAT64;
         }
       break;
 
-    case GAL_DATA_TYPE_FLOAT64:
-      if         (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_DATA_TYPE_FLOAT64;
+    case GAL_TYPE_FLOAT64:
+      if         (GAL_CONFIG_BIN_OP_FLOAT64)   return GAL_TYPE_FLOAT64;
       break;
 
     default:
@@ -1362,7 +1322,7 @@ gal_arithmetic_convert_to_compiled_type(gal_data_t *in, 
unsigned char flags)
         }
       else
         {
-          typestring=gal_data_type_as_string(in->type, 1);
+          typestring=gal_type_to_string(in->type, 1);
           error(EXIT_FAILURE, 0, "The given %s type data given to "
                 "binary operators is not compiled for native operation "
                 "and no larger types are compiled either.\n\nThe "
diff --git a/lib/binary.c b/lib/binary.c
new file mode 100644
index 0000000..263e2ec
--- /dev/null
+++ b/lib/binary.c
@@ -0,0 +1,441 @@
+/*********************************************************************
+binary -- Work on binary (0 and 1 valued) datasets.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+Copyright (C) 2016, 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/tile.h>
+#include <gnuastro/binary.h>
+#include <gnuastro/dimension.h>
+#include <gnuastro/linkedlist.h>
+
+
+
+
+
+
+
+
+
+/*********************************************************************/
+/*****************      Erosion and dilation      ********************/
+/*********************************************************************/
+static void
+binary_erode_dilate_2d_4con(gal_data_t *input, int dilate0_erode1)
+{
+  uint8_t f, b, *pt, *fpt, *byt=input->array;
+  size_t i, j, ind, nr=input->dsize[0], nc=input->dsize[1];
+
+  /* Do a sanity check: */
+  if(dilate0_erode1!=1 && dilate0_erode1!=0)
+    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
+          "this problem. In binary_2d_4con, the value to `dilate0_erode1' "
+          "is %u while it should be 0 or 1", PACKAGE_BUGREPORT,
+          dilate0_erode1);
+
+  /* Set the foreground and background values. */
+  if(dilate0_erode1==0) {f=1; b=0;}
+  else                  {f=0; b=1;}
+
+  /* Check the 4 corners: */
+  if(byt[0]==b && (byt[1]==f || byt[nc]==f) )
+    byt[0]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[nc-1]==b && (byt[nc-2]==f || byt[2*nc-1]==f))
+    byt[nc-1]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[(nr-1)*nc]==b
+     && (byt[(nr-2)*nc]==f || byt[(nr-1)*nc+1]==f) )
+    byt[(nr-1)*nc]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[nr*nc-1]==b
+     && (byt[nr*nc-2]==f || byt[nr*nc-1-nc]==f) )
+    byt[nr*nc-1]=GAL_BINARY_TMP_VALUE;
+
+  /* Check the 4 sides: */
+  for(j=1;j<nc-1;++j)
+    if(byt[j]==b
+       && (byt[j+1]==f || byt[j-1]==f || byt[j+nc]==f) )
+      byt[j]=GAL_BINARY_TMP_VALUE;
+
+  for(j=1;j<nc-1;++j)
+    {
+      ind=(nr-1)*nc+j;
+      if(byt[ind]==b
+         && (byt[ind+1]==f || byt[ind-1]==f || byt[ind-nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  for(i=1;i<nr-1;++i)
+    {
+      ind=i*nc;
+      if(byt[ind]==b
+         && (byt[ind+1]==f || byt[ind+nc]==f || byt[ind-nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  for(i=1;i<nr-1;++i)
+    {
+      ind=(i+1)*nc-1;
+      if(byt[ind]==b
+         && (byt[ind-1]==f || byt[ind+nc]==f || byt[ind-nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  /* Check the body: */
+  for(i=1;i<nr-1;++i)
+    for(j=1;j<nc-1;++j)
+      {
+        ind=i*nc+j;
+        if(byt[ind]==b
+           && (byt[ind-1]==f     || byt[ind+1]==f
+               || byt[ind+nc]==f || byt[ind-nc]==f) )
+          byt[ind]=GAL_BINARY_TMP_VALUE;
+      }
+
+  /* Set all the changed pixels to the proper values: */
+  fpt=(pt=byt)+nr*nc;
+  do *pt = *pt==GAL_BINARY_TMP_VALUE ? f : *pt; while(++pt<fpt);
+}
+
+
+
+
+
+/* 8 connected dilation and erosion. b0_f1==0: Dilate the
+   foreground. b0_f1==1: Erode the foreground. */
+static void
+binary_erode_dilate_2d_8con(gal_data_t *input, unsigned char dilate0_erode1)
+{
+  uint8_t f, b, *pt, *fpt, *byt=input->array;
+  size_t i, j, ind, nr=input->dsize[0], nc=input->dsize[1];
+
+  /* Do a sanity check: */
+  if(dilate0_erode1!=1 && dilate0_erode1!=0)
+    error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix "
+          "this problem. In dilate0_erode1_4con (binary.c), the value to "
+          "dilate0_erode1 is %u while it should be 0 or 1", PACKAGE_BUGREPORT,
+          dilate0_erode1);
+
+  /* Set the foreground and background values: */
+  if(dilate0_erode1==0) {f=1; b=0;}
+  else         {f=0; b=1;}
+
+  /* Check the 4 corners: */
+  if(byt[0]==b && (byt[1]==f
+                   || byt[nc]==f || byt[nc+1]==f) )
+    byt[0]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[nc-1]==b && (byt[nc-2]==f
+                      || byt[2*nc-1]==f
+                      || byt[2*nc-2]==f) )
+    byt[nc-1]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[(nr-1)*nc]==b
+     && ( byt[(nr-2)*nc]==f || byt[(nr-1)*nc+1]==f
+          || byt[(nr-2)*nc+1]==f) )
+    byt[(nr-1)*nc]=GAL_BINARY_TMP_VALUE;
+
+  if(byt[nr*nc-1]==b
+     && ( byt[nr*nc-2]==f || byt[nr*nc-1-nc]==f
+          || byt[nr*nc-2-nc]==f) )
+    byt[nr*nc-1]=GAL_BINARY_TMP_VALUE;
+
+  /* Check the 4 sides: */
+  for(j=1;j<nc-1;++j)
+    if(byt[j]==b
+       && ( byt[j+1]==f || byt[j-1]==f || byt[j+nc]==f
+            || byt[j-1+nc]==f || byt[j+1+nc]==f) )
+      byt[j]=GAL_BINARY_TMP_VALUE;
+
+  for(j=1;j<nc-1;++j)
+    {
+      ind=(nr-1)*nc+j;
+      if(byt[ind]==b
+         && ( byt[ind+1]==f || byt[ind-1]==f || byt[ind-nc]==f
+              || byt[ind-1-nc]==f || byt[ind+1-nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  for(i=1;i<nr-1;++i)
+    {
+      ind=i*nc;
+      if(byt[ind]==b
+         && ( byt[ind+1]==f || byt[ind+nc]==f || byt[ind-nc]==f
+              || byt[ind+1-nc]==f || byt[ind+1+nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  for(i=1;i<nr-1;++i)
+    {
+      ind=(i+1)*nc-1;
+      if(byt[ind]==b
+         && (byt[ind-1]==f || byt[ind+nc]==f || byt[ind-nc]==f
+             || byt[ind-1-nc]==f || byt[ind-1+nc]==f) )
+        byt[ind]=GAL_BINARY_TMP_VALUE;
+    }
+
+  /* Check the body: */
+  for(i=1;i<nr-1;++i)
+    for(j=1;j<nc-1;++j)
+      {
+        ind=i*nc+j;
+        if(byt[ind]==b
+           && (byt[ind-1]==f        || byt[ind+1]==f
+               || byt[ind+nc]==f    || byt[ind-nc]==f
+               || byt[ind-1-nc]==f  || byt[ind+1+nc]==f
+               || byt[ind-1+nc]==f  || byt[ind+1-nc]==f) )
+          byt[ind]=GAL_BINARY_TMP_VALUE;
+      }
+
+  /* Set all the changed pixels to the proper values: */
+  fpt=(pt=byt)+nr*nc;
+  do *pt = *pt==GAL_BINARY_TMP_VALUE ? f : *pt; while(++pt<fpt);
+}
+
+
+
+
+
+/* Erode a binary dataset any number of times. If `inplace' is given a
+   value of `1', then do the erosion within the already allocated space,
+   otherwise, allocate a new array and save the result into that.
+
+   This function will only work on the elements with a value of 1 or 0. It
+   will leave all the rest unchanged. Also note that it only works on
+   `uint8_t' type datasets. So if the input doesn't have that type, it is
+   going to copy it this type and return the newlyallocated dataset. So
+   when the input's type isn't `uint8_t', `inplace' is irrelevant. */
+static gal_data_t *
+binary_erode_dilate(gal_data_t *input, size_t num, int connectivity,
+                    int inplace, int d0e1)
+{
+  size_t counter;
+  gal_data_t *binary;
+  size_t *dinc=gal_dimension_increment(input->ndim, input->dsize);
+
+  /* Currently this only works on blocks. */
+  if(input->block)
+    error(EXIT_FAILURE, 0, "`gal_binary_erode' currently only works on a "
+          "fully allocated block of memory");
+
+  /* Set the dataset to work on. */
+  binary = ( (inplace && input->type==GAL_TYPE_UINT8)
+             ? input :
+             gal_data_copy_to_new_type(input, GAL_TYPE_UINT8) );
+
+  /* Go over every element and do the erosion. */
+  switch(binary->ndim)
+    {
+    case 2:
+      for(counter=0;counter<num;++counter)
+        switch(connectivity)
+          {
+          case 4: binary_erode_dilate_2d_4con(binary, d0e1); break;
+          case 8: binary_erode_dilate_2d_8con(binary, d0e1); break;
+          default:
+            error(EXIT_FAILURE, 0, "%d not acceptable for connectivity in "
+                  "a 2D dataset", connectivity);
+          }
+      break;
+
+    default:
+      error(EXIT_FAILURE, 0, "`gal_binary_erode' currently doesn't work on "
+            "%zu dimensional datasets", binary->ndim);
+    }
+
+  /* Clean up and return. */
+  free(dinc);
+  return binary;
+}
+
+
+
+
+
+gal_data_t *
+gal_binary_erode(gal_data_t *input, size_t num, int connectivity,
+                 int inplace)
+{
+  return binary_erode_dilate(input, num, connectivity, inplace, 1);
+}
+
+
+
+
+
+gal_data_t *
+gal_binary_dilate(gal_data_t *input, size_t num, int connectivity,
+                  int inplace)
+{
+  return binary_erode_dilate(input, num, connectivity, inplace, 0);
+}
+
+
+
+
+
+gal_data_t *
+gal_binary_open(gal_data_t *input, size_t num, int connectivity,
+                int inplace)
+{
+  gal_data_t *out;
+
+  /* First do the necessary number of erosions. */
+  out=gal_binary_erode(input, num, connectivity, inplace);
+
+  /* If `inplace' was called, then `out' is the same as `input', if it
+     wasn't, then `out' is a newly allocated array. In any case, we should
+     dilate in the same allocated space. */
+  gal_binary_dilate(input, num, connectivity, 1);
+
+  /* Return the output dataset. */
+  return out;
+}
+
+
+
+
+
+
+
+
+
+
+/*********************************************************************/
+/*****************      Connected components      ********************/
+/*********************************************************************/
+/* Find the connected components in the input binary dataset `binary'
+   through the breadth first search algorithm. `binary' has to have an
+   `uint8' datatype and only zero and non-zero values in it will be
+   distinguished. The output dataset (which will contain a label on each
+   pixel) maybe already allocated (with type `uint32'). If `*out!=NULL',
+   the labels will be reset to zero before the start and the labels will be
+   written into it. If `*out==NULL', the necessary dataset will be
+   allocated here and put into it. */
+size_t
+gal_binary_connected_components(gal_data_t *binary, gal_data_t **out,
+                                int connectivity)
+{
+  uint32_t *l;
+  uint8_t *b, *bf;
+  gal_data_t *lab;
+  size_t p, i, curlab=1;
+  struct gal_linkedlist_sll *Q=NULL;
+  size_t *dinc=gal_dimension_increment(binary->ndim, binary->dsize);
+
+  /* Two small sanity checks. */
+  if(binary->type!=GAL_TYPE_UINT8)
+    error(EXIT_FAILURE, 0, "the input data structure to "
+          "`gal_binary_connected_components' must be `uint8' type");
+  if(binary->block)
+    error(EXIT_FAILURE, 0, "currently, the input data structure to "
+          "`gal_binary_connected_components' must not be a tile");
+
+
+  /* Prepare the dataset for the labels. */
+  if(*out)
+    {
+      /* Use the given dataset.  */
+      lab=*out;
+
+      /* Make sure the given dataset has the same size as the input. */
+      if( gal_data_dsize_is_different(binary, lab) )
+        error(EXIT_FAILURE, 0, "the `binary' and `out' datasets must have "
+              "the same size in `gal_binary_connected_components'");
+
+      /* Make sure it has a `uint32' type. */
+      if( lab->type!=GAL_TYPE_UINT32 )
+        error(EXIT_FAILURE, 0, "the `out' dataset in "
+              "`gal_binary_connected_components' must have `uint32' type"
+              "but the array you have given is `%s' type",
+              gal_type_to_string(lab->type, 1));
+
+      /* Reset all its values to zero. */
+      memset(lab->array, 0, lab->size * gal_type_sizeof(lab->type));
+    }
+  else
+    lab=*out=gal_data_alloc(NULL, GAL_TYPE_UINT32, binary->ndim,
+                            binary->dsize, binary->wcs, 1,
+                            binary->minmapsize, NULL, "labels", NULL);
+
+
+  /* Initialize the labels array. If we have blank pixels in the byt
+     array, then give them the blank labeled array. Note that since
+     their value will not be 0, they will also not be labeled. */
+  l=lab->array;
+  bf=(b=binary->array)+binary->size;
+  if( gal_blank_present(binary) )
+    do *l++ = *b==GAL_BLANK_UINT8 ? GAL_BLANK_UINT32 : 0; while(++b<bf);
+
+
+  /* Go over all the pixels and do a breadth-first: any pixel that is not
+     labeled is used to label the full object by checking neighbors before
+     going onto the next pixels. */
+  l=lab->array;
+  b=binary->array;
+  for(i=0;i<binary->size;++i)
+    /* Check if this pixel is already labeled. */
+    if( b[i] && !l[i] )
+      {
+        /* This is the first pixel of this connected region that we have
+           got to. */
+        l[i]=curlab;
+
+        /* Add this pixel to the queue of pixels to work with. */
+        gal_linkedlist_add_to_sll(&Q, i);
+
+        /* While a pixel remains in the queue, continue labelling and
+           searching for neighbors. */
+        while(Q!=NULL)
+          {
+            /* Pop an element from the queue. */
+            gal_linkedlist_pop_from_sll(&Q, &p);
+
+            /* Go over all its neighbors and add them to the list if they
+               haven't already been labeled. */
+            GAL_DIMENSION_NEIGHBOR_OP(p, binary->ndim, binary->dsize,
+                                      connectivity, dinc,
+              {
+                if( b[ nind ] && !l[ nind ] )
+                  {
+                    l[ nind ] = curlab;
+                    gal_linkedlist_add_to_sll(&Q, nind);
+                  }
+              } );
+          }
+
+        /* This object has been fully labeled, so increment the current
+           label. */
+        ++curlab;
+      }
+
+
+  /* Clean up and return the total number. */
+  free(dinc);
+  return curlab-1;
+}
diff --git a/lib/blank.c b/lib/blank.c
index 776027b..b675ac9 100644
--- a/lib/blank.c
+++ b/lib/blank.c
@@ -45,25 +45,25 @@ gal_blank_write(void *ptr, uint8_t type)
   switch(type)
     {
     /* Numeric types */
-    case GAL_DATA_TYPE_UINT8:   *(uint8_t  *)ptr = GAL_BLANK_UINT8;    break;
-    case GAL_DATA_TYPE_INT8:    *(int8_t   *)ptr = GAL_BLANK_INT8;     break;
-    case GAL_DATA_TYPE_UINT16:  *(uint16_t *)ptr = GAL_BLANK_UINT16;   break;
-    case GAL_DATA_TYPE_INT16:   *(int16_t  *)ptr = GAL_BLANK_INT16;    break;
-    case GAL_DATA_TYPE_UINT32:  *(uint32_t *)ptr = GAL_BLANK_UINT32;   break;
-    case GAL_DATA_TYPE_INT32:   *(int32_t  *)ptr = GAL_BLANK_INT32;    break;
-    case GAL_DATA_TYPE_UINT64:  *(uint64_t *)ptr = GAL_BLANK_UINT64;   break;
-    case GAL_DATA_TYPE_INT64:   *(int64_t  *)ptr = GAL_BLANK_INT64;    break;
-    case GAL_DATA_TYPE_FLOAT32: *(float    *)ptr = GAL_BLANK_FLOAT32;  break;
-    case GAL_DATA_TYPE_FLOAT64: *(double   *)ptr = GAL_BLANK_FLOAT64;  break;
+    case GAL_TYPE_UINT8:   *(uint8_t  *)ptr = GAL_BLANK_UINT8;    break;
+    case GAL_TYPE_INT8:    *(int8_t   *)ptr = GAL_BLANK_INT8;     break;
+    case GAL_TYPE_UINT16:  *(uint16_t *)ptr = GAL_BLANK_UINT16;   break;
+    case GAL_TYPE_INT16:   *(int16_t  *)ptr = GAL_BLANK_INT16;    break;
+    case GAL_TYPE_UINT32:  *(uint32_t *)ptr = GAL_BLANK_UINT32;   break;
+    case GAL_TYPE_INT32:   *(int32_t  *)ptr = GAL_BLANK_INT32;    break;
+    case GAL_TYPE_UINT64:  *(uint64_t *)ptr = GAL_BLANK_UINT64;   break;
+    case GAL_TYPE_INT64:   *(int64_t  *)ptr = GAL_BLANK_INT64;    break;
+    case GAL_TYPE_FLOAT32: *(float    *)ptr = GAL_BLANK_FLOAT32;  break;
+    case GAL_TYPE_FLOAT64: *(double   *)ptr = GAL_BLANK_FLOAT64;  break;
 
     /* String type. */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       gal_checkset_allocate_copy(GAL_BLANK_STRING, ptr);
       break;
 
     /* Complex types */
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "complex types are not yet supported in "
             "`gal_blank_write'");
 
@@ -149,19 +149,19 @@ gal_blank_present(gal_data_t *input)
   switch(block->type)
     {
     /* Numeric types */
-    case GAL_DATA_TYPE_UINT8:     HAS_BLANK( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:      HAS_BLANK( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:    HAS_BLANK( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:     HAS_BLANK( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:    HAS_BLANK( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:     HAS_BLANK( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:    HAS_BLANK( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:     HAS_BLANK( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:   HAS_BLANK( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:   HAS_BLANK( double   );    break;
+    case GAL_TYPE_UINT8:     HAS_BLANK( uint8_t  );    break;
+    case GAL_TYPE_INT8:      HAS_BLANK( int8_t   );    break;
+    case GAL_TYPE_UINT16:    HAS_BLANK( uint16_t );    break;
+    case GAL_TYPE_INT16:     HAS_BLANK( int16_t  );    break;
+    case GAL_TYPE_UINT32:    HAS_BLANK( uint32_t );    break;
+    case GAL_TYPE_INT32:     HAS_BLANK( int32_t  );    break;
+    case GAL_TYPE_UINT64:    HAS_BLANK( uint64_t );    break;
+    case GAL_TYPE_INT64:     HAS_BLANK( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:   HAS_BLANK( float    );    break;
+    case GAL_TYPE_FLOAT64:   HAS_BLANK( double   );    break;
 
     /* String. */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       if(input!=block)
         error(EXIT_FAILURE, 0, "tile mode is currently not supported for "
               "strings");
@@ -170,13 +170,13 @@ gal_blank_present(gal_data_t *input)
       break;
 
     /* Complex types */
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "complex types are not yet supported in "
             "`gal_blank_write'");
 
     /* Bit */
-    case GAL_DATA_TYPE_BIT:
+    case GAL_TYPE_BIT:
       error(EXIT_FAILURE, 0, "bit type datasets are not yet supported in "
             "`gal_blank_present'");
 
@@ -216,7 +216,7 @@ gal_blank_flag(gal_data_t *data)
   char **str=data->array, **strf=str+data->size;
 
   /* Allocate the output array. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, data->ndim, data->dsize,
+  out=gal_data_alloc(NULL, GAL_TYPE_UINT8, data->ndim, data->dsize,
                      data->wcs, 0, data->minmapsize, data->name, data->unit,
                      data->comment);
 
@@ -227,28 +227,28 @@ gal_blank_flag(gal_data_t *data)
   switch(data->type)
     {
     /* Numeric types */
-    case GAL_DATA_TYPE_UINT8:     FLAG_BLANK( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:      FLAG_BLANK( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:    FLAG_BLANK( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:     FLAG_BLANK( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:    FLAG_BLANK( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:     FLAG_BLANK( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:    FLAG_BLANK( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:     FLAG_BLANK( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:   FLAG_BLANK( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:   FLAG_BLANK( double   );    break;
+    case GAL_TYPE_UINT8:     FLAG_BLANK( uint8_t  );    break;
+    case GAL_TYPE_INT8:      FLAG_BLANK( int8_t   );    break;
+    case GAL_TYPE_UINT16:    FLAG_BLANK( uint16_t );    break;
+    case GAL_TYPE_INT16:     FLAG_BLANK( int16_t  );    break;
+    case GAL_TYPE_UINT32:    FLAG_BLANK( uint32_t );    break;
+    case GAL_TYPE_INT32:     FLAG_BLANK( int32_t  );    break;
+    case GAL_TYPE_UINT64:    FLAG_BLANK( uint64_t );    break;
+    case GAL_TYPE_INT64:     FLAG_BLANK( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:   FLAG_BLANK( float    );    break;
+    case GAL_TYPE_FLOAT64:   FLAG_BLANK( double   );    break;
 
     /* String. */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       do *o++ = !strcmp(*str,GAL_BLANK_STRING); while(++str<strf);
       break;
 
     /* Currently unsupported types. */
-    case GAL_DATA_TYPE_BIT:
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_BIT:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "%s type not yet supported in `gal_blank_flag'",
-            gal_data_type_as_string(data->type, 1));
+            gal_type_to_string(data->type, 1));
 
     /* Bad input. */
     default:
@@ -288,16 +288,16 @@ gal_blank_remove(gal_data_t *data)
   /* Shift all non-blank elements to the start of the array. */
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:    BLANK_REMOVE( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:     BLANK_REMOVE( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:   BLANK_REMOVE( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:    BLANK_REMOVE( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:   BLANK_REMOVE( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:    BLANK_REMOVE( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:   BLANK_REMOVE( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:    BLANK_REMOVE( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:  BLANK_REMOVE( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:  BLANK_REMOVE( double   );    break;
+    case GAL_TYPE_UINT8:    BLANK_REMOVE( uint8_t  );    break;
+    case GAL_TYPE_INT8:     BLANK_REMOVE( int8_t   );    break;
+    case GAL_TYPE_UINT16:   BLANK_REMOVE( uint16_t );    break;
+    case GAL_TYPE_INT16:    BLANK_REMOVE( int16_t  );    break;
+    case GAL_TYPE_UINT32:   BLANK_REMOVE( uint32_t );    break;
+    case GAL_TYPE_INT32:    BLANK_REMOVE( int32_t  );    break;
+    case GAL_TYPE_UINT64:   BLANK_REMOVE( uint64_t );    break;
+    case GAL_TYPE_INT64:    BLANK_REMOVE( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:  BLANK_REMOVE( float    );    break;
+    case GAL_TYPE_FLOAT64:  BLANK_REMOVE( double   );    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_blank_remove'", data->type);
@@ -319,86 +319,64 @@ gal_blank_as_string(uint8_t type, int width)
   char *blank;
   switch(type)
     {
-    case GAL_DATA_TYPE_BIT:
+    case GAL_TYPE_BIT:
       error(EXIT_FAILURE, 0, "bit types are not implemented in "
             "`gal_data_blank_as_string' yet.");
       break;
 
-    case GAL_DATA_TYPE_STRING:
-      if(width)
-        asprintf(&blank, "%*s", width, GAL_BLANK_STRING);
-      else
-        asprintf(&blank, "%s", GAL_BLANK_STRING);
+    case GAL_TYPE_STRING:
+      if(width) asprintf(&blank, "%*s", width,  GAL_BLANK_STRING);
+      else      asprintf(&blank, "%s",          GAL_BLANK_STRING);
       break;
 
-    case GAL_DATA_TYPE_UINT8:
-      if(width)
-        asprintf(&blank, "%*u", width, (uint8_t)GAL_BLANK_UINT8);
-      else
-        asprintf(&blank, "%u",         (uint8_t)GAL_BLANK_UINT8);
+    case GAL_TYPE_UINT8:
+      if(width) asprintf(&blank, "%*u", width,  (uint8_t)GAL_BLANK_UINT8);
+      else      asprintf(&blank, "%u",          (uint8_t)GAL_BLANK_UINT8);
       break;
 
-    case GAL_DATA_TYPE_INT8:
-      if(width)
-        asprintf(&blank, "%*d", width, (int8_t)GAL_BLANK_INT8);
-      else
-        asprintf(&blank, "%d",         (int8_t)GAL_BLANK_INT8);
+    case GAL_TYPE_INT8:
+      if(width) asprintf(&blank, "%*d", width,  (int8_t)GAL_BLANK_INT8);
+      else      asprintf(&blank, "%d",          (int8_t)GAL_BLANK_INT8);
       break;
 
-    case GAL_DATA_TYPE_UINT16:
-      if(width)
-        asprintf(&blank, "%*u", width, (uint16_t)GAL_BLANK_UINT16);
-      else
-        asprintf(&blank, "%u",         (uint16_t)GAL_BLANK_UINT16);
+    case GAL_TYPE_UINT16:
+      if(width) asprintf(&blank, "%*u", width,  (uint16_t)GAL_BLANK_UINT16);
+      else      asprintf(&blank, "%u",          (uint16_t)GAL_BLANK_UINT16);
       break;
 
-    case GAL_DATA_TYPE_INT16:
-      if(width)
-        asprintf(&blank, "%*d", width, (int16_t)GAL_BLANK_INT16);
-      else
-        asprintf(&blank, "%d",         (int16_t)GAL_BLANK_INT16);
+    case GAL_TYPE_INT16:
+      if(width) asprintf(&blank, "%*d", width,  (int16_t)GAL_BLANK_INT16);
+      else      asprintf(&blank, "%d",          (int16_t)GAL_BLANK_INT16);
       break;
 
-    case GAL_DATA_TYPE_UINT32:
-      if(width)
-        asprintf(&blank, "%*u", width, (uint32_t)GAL_BLANK_UINT32);
-      else
-        asprintf(&blank, "%u",         (uint32_t)GAL_BLANK_UINT32);
+    case GAL_TYPE_UINT32:
+      if(width) asprintf(&blank, "%*u", width,  (uint32_t)GAL_BLANK_UINT32);
+      else      asprintf(&blank, "%u",          (uint32_t)GAL_BLANK_UINT32);
       break;
 
-    case GAL_DATA_TYPE_INT32:
-      if(width)
-        asprintf(&blank, "%*d", width, (int32_t)GAL_BLANK_INT32);
-      else
-        asprintf(&blank, "%d",         (int32_t)GAL_BLANK_INT32);
+    case GAL_TYPE_INT32:
+      if(width) asprintf(&blank, "%*d", width,  (int32_t)GAL_BLANK_INT32);
+      else      asprintf(&blank, "%d",          (int32_t)GAL_BLANK_INT32);
       break;
 
-    case GAL_DATA_TYPE_UINT64:
-      if(width)
-        asprintf(&blank, "%*lu", width, (uint64_t)GAL_BLANK_UINT64);
-      else
-        asprintf(&blank, "%lu",         (uint64_t)GAL_BLANK_UINT64);
+    case GAL_TYPE_UINT64:
+      if(width) asprintf(&blank, "%*lu", width, (uint64_t)GAL_BLANK_UINT64);
+      else      asprintf(&blank, "%lu",         (uint64_t)GAL_BLANK_UINT64);
       break;
 
-    case GAL_DATA_TYPE_INT64:
-      if(width)
-        asprintf(&blank, "%*ld", width, (int64_t)GAL_BLANK_INT64);
-      else
-        asprintf(&blank, "%ld",         (int64_t)GAL_BLANK_INT64);
+    case GAL_TYPE_INT64:
+      if(width) asprintf(&blank, "%*ld", width, (int64_t)GAL_BLANK_INT64);
+      else      asprintf(&blank, "%ld",         (int64_t)GAL_BLANK_INT64);
       break;
 
-    case GAL_DATA_TYPE_FLOAT32:
-      if(width)
-        asprintf(&blank, "%*f", width, (float)GAL_BLANK_FLOAT32);
-      else
-        asprintf(&blank, "%f",         (float)GAL_BLANK_FLOAT32);
+    case GAL_TYPE_FLOAT32:
+      if(width) asprintf(&blank, "%*f", width,  (float)GAL_BLANK_FLOAT32);
+      else      asprintf(&blank, "%f",          (float)GAL_BLANK_FLOAT32);
       break;
 
-    case GAL_DATA_TYPE_FLOAT64:
-      if(width)
-        asprintf(&blank, "%*f", width, (double)GAL_BLANK_FLOAT64);
-      else
-        asprintf(&blank, "%f",         (double)GAL_BLANK_FLOAT64);
+    case GAL_TYPE_FLOAT64:
+      if(width) asprintf(&blank, "%*f", width,  (double)GAL_BLANK_FLOAT64);
+      else      asprintf(&blank, "%f",          (double)GAL_BLANK_FLOAT64);
       break;
 
     default:
diff --git a/lib/commonopts.h b/lib/commonopts.h
index 4edaca9..e4ac0ad 100644
--- a/lib/commonopts.h
+++ b/lib/commonopts.h
@@ -50,7 +50,7 @@ struct argp_option gal_commonopts_options[] =
       "Extension name or number of input data.",
       GAL_OPTIONS_GROUP_INPUT,
       &cp->hdu,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -63,7 +63,7 @@ struct argp_option gal_commonopts_options[] =
       "Select column(s) in: `name', `unit', `comment'.",
       GAL_OPTIONS_GROUP_INPUT,
       &cp->searchin,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -74,7 +74,7 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_KEY_IGNORECASE,
       0,
       0,
-      "Ignore case when matching/searching col. info.",
+      "Ignore case in matching/searching columns.",
       GAL_OPTIONS_GROUP_INPUT,
       &cp->ignorecase,
       GAL_OPTIONS_NO_ARG_TYPE,
@@ -97,10 +97,10 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_KEY_TILESIZE,
       "INT[,INT]",
       0,
-      "Regular tile size on each dim. (FITS order).",
+      "Regular tile size on dim.s (FITS order).",
       GAL_OPTIONS_GROUP_TESSELLATION,
       &cp->tl.tilesize,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -111,10 +111,10 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_KEY_NUMCHANNELS,
       "INT[,..]",
       0,
-      "No. of channels along each dim. (FITS order).",
+      "No. of channels in dim.s (FITS order).",
       GAL_OPTIONS_GROUP_TESSELLATION,
       &cp->tl.numchannels,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -128,7 +128,7 @@ struct argp_option gal_commonopts_options[] =
       "Fraction of remainder to split last tile.",
       GAL_OPTIONS_GROUP_TESSELLATION,
       &cp->tl.remainderfrac,
-      GAL_DATA_TYPE_FLOAT32,
+      GAL_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0_LT_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -190,10 +190,10 @@ struct argp_option gal_commonopts_options[] =
       GAL_OPTIONS_KEY_INTERPNUMNGB,
       "INT",
       0,
-      "Number of neighbors to use for interpolation.",
+      "No. of neighbors to use for interpolation.",
       GAL_OPTIONS_GROUP_TESSELLATION,
       &cp->interpnumngb,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -215,7 +215,7 @@ struct argp_option gal_commonopts_options[] =
       "Output name.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &cp->output,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -228,7 +228,7 @@ struct argp_option gal_commonopts_options[] =
       "Type of output: e.g., int16, float32, etc...",
       GAL_OPTIONS_GROUP_OUTPUT,
       &cp->type,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -242,7 +242,7 @@ struct argp_option gal_commonopts_options[] =
       "Table format: `fits-ascii', `fits-binary'.",
       GAL_OPTIONS_GROUP_OUTPUT,
       &cp->tableformat,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -305,7 +305,7 @@ struct argp_option gal_commonopts_options[] =
       "Number of CPU threads to use.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       &cp->numthreads,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -318,7 +318,7 @@ struct argp_option gal_commonopts_options[] =
       "Minimum no. bytes to map arrays to hdd/ssd.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       &cp->minmapsize,
-      GAL_DATA_TYPE_SIZE_T,
+      GAL_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GE_0,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
@@ -375,7 +375,7 @@ struct argp_option gal_commonopts_options[] =
       "Read configuration file STR immediately.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       NULL,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
@@ -428,7 +428,7 @@ struct argp_option gal_commonopts_options[] =
       "Only run if the program version is STR.",
       GAL_OPTIONS_GROUP_OPERATING_MODE,
       NULL,
-      GAL_DATA_TYPE_STRING,
+      GAL_TYPE_STRING,
       GAL_OPTIONS_RANGE_0_OR_1,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
diff --git a/lib/convolve.c b/lib/convolve.c
index 3b59e16..8d53fc0 100644
--- a/lib/convolve.c
+++ b/lib/convolve.c
@@ -102,7 +102,7 @@ struct spatial_params
    the necessary input image parameters are stored in `overlap' (its
    `array' and `dsize' elements). The pointer to the kernel array that the
    overlap starts will be returned. */
-int
+static int
 convolve_spatial_overlap(int on_edge, size_t *parse_coords, size_t *hsize,
                          gal_data_t *block, gal_data_t *kernel,
                          gal_data_t *overlap, size_t *k_start_inc,
@@ -393,13 +393,12 @@ convolve_spatial_on_thread(void *inparam)
 
   size_t i;
   gal_data_t overlap, *block=gal_tile_block(cprm->tiles);
-  size_t *parse_coords=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T,
-                                             6*block->ndim);
+  size_t *parse_coords=gal_data_malloc_array(GAL_TYPE_SIZE_T, 6*block->ndim);
 
   /* Initialize the necessary overlap parameters. */
   overlap.block=block;
   overlap.ndim=block->ndim;
-  overlap.dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, block->ndim);
+  overlap.dsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, block->ndim);
 
 
   /* Go over all the tiles given to this thread. */
@@ -436,15 +435,15 @@ gal_convolve_spatial(gal_data_t *tiles, gal_data_t 
*kernel,
   if(tiles->ndim!=kernel->ndim)
     error(EXIT_FAILURE, 0, "The number of dimensions between the kernel and "
           "input should be the same in `gal_convolve_spatial'");
-  if( block->type!=GAL_DATA_TYPE_FLOAT32
-      || kernel->type!=GAL_DATA_TYPE_FLOAT32 )
+  if( block->type!=GAL_TYPE_FLOAT32
+      || kernel->type!=GAL_TYPE_FLOAT32 )
     error(EXIT_FAILURE, 0, "`gal_convolve_spatial' currently only works on "
           "`float32' type input and kernel");
 
   /* Allocate the output convolved dataset. */
   name = ( block->name
            ? gal_checkset_malloc_cat("CONVL_", block->name) : NULL );
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, block->ndim, block->dsize,
+  out=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, block->ndim, block->dsize,
                      block->wcs, 0, block->minmapsize, name,
                      block->unit, NULL);
 
@@ -460,6 +459,6 @@ gal_convolve_spatial(gal_data_t *tiles, gal_data_t *kernel,
                        gal_data_num_in_ll(tiles), numthreads);
 
   /* Clean up and return the output array. */
-  free(name);
+  if(name) free(name);
   return out;
 }
diff --git a/lib/data.c b/lib/data.c
index 28ab527..4553f9a 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -51,222 +51,6 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-/*************************************************************
- **************            Type info           ***************
- *************************************************************/
-
-char *
-gal_data_type_as_string(uint8_t type, int long_name)
-{
-  switch(type)
-    {
-    case GAL_DATA_TYPE_BIT:
-      if(long_name) return "bit";                 else return "b";
-
-    case GAL_DATA_TYPE_UINT8:
-      if(long_name) return "uint8";               else return "u8";
-
-    case GAL_DATA_TYPE_INT8:
-      if(long_name) return "int8";                else return "i8";
-
-    case GAL_DATA_TYPE_UINT16:
-      if(long_name) return "uint16";              else return "u16";
-
-    case GAL_DATA_TYPE_INT16:
-      if(long_name) return "int16";               else return "i16";
-
-    case GAL_DATA_TYPE_UINT32:
-      if(long_name) return "uint32";              else return "u32";
-
-    case GAL_DATA_TYPE_INT32:
-      if(long_name) return "int32";               else return "i32";
-
-    case GAL_DATA_TYPE_UINT64:
-      if(long_name) return "uint64";              else return "u64";
-
-    case GAL_DATA_TYPE_INT64:
-      if(long_name) return "int64";               else return "i64";
-
-    case GAL_DATA_TYPE_FLOAT32:
-      if(long_name) return "float32";             else return "f32";
-
-    case GAL_DATA_TYPE_FLOAT64:
-      if(long_name) return "float64";             else return "f64";
-
-    case GAL_DATA_TYPE_COMPLEX32:
-      if(long_name) return "complex32";           else return "c32";
-
-    case GAL_DATA_TYPE_COMPLEX64:
-      if(long_name) return "complex64";           else return "c64";
-
-    case GAL_DATA_TYPE_STRING:
-      if(long_name) return "string";              else return "str";
-
-    case GAL_DATA_TYPE_STRLL:
-      if(long_name) return "string linked list";  else return "strll";
-
-    default:
-      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-            "`gal_data_type_as_string'", type);
-    }
-
-  /* Any of the cases above should return this function, so if control
-     reaches here, there is a bug. */
-  error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can address "
-        "the problem. For some reason control has reached the end of "
-        "the `gal_data_type_as_string' function. This must not happen",
-        PACKAGE_BUGREPORT);
-  return NULL;
-}
-
-
-
-
-
-uint8_t
-gal_data_string_as_type(char *str)
-{
-  if(      !strcmp(str, "b")     || !strcmp(str, "bit") )
-    return GAL_DATA_TYPE_BIT;
-
-  else if( !strcmp(str, "u8")    || !strcmp(str, "uint8") )
-    return GAL_DATA_TYPE_UINT8;
-
-  else if( !strcmp(str, "i8")    || !strcmp(str, "int8") )
-    return GAL_DATA_TYPE_INT8;
-
-  else if( !strcmp(str, "u16")   || !strcmp(str, "uint16") )
-    return GAL_DATA_TYPE_UINT16;
-
-  else if( !strcmp(str, "i16")   || !strcmp(str, "int16") )
-    return GAL_DATA_TYPE_INT16;
-
-  else if( !strcmp(str, "u32")   || !strcmp(str, "uint32") )
-    return GAL_DATA_TYPE_UINT32;
-
-  else if( !strcmp(str, "i32")   || !strcmp(str, "int32") )
-    return GAL_DATA_TYPE_INT32;
-
-  else if( !strcmp(str, "u64")   || !strcmp(str, "uint64") )
-    return GAL_DATA_TYPE_UINT64;
-
-  else if( !strcmp(str, "i64")   || !strcmp(str, "int64") )
-    return GAL_DATA_TYPE_INT64;
-
-  else if( !strcmp(str, "f32")   || !strcmp(str, "float32") )
-    return GAL_DATA_TYPE_FLOAT32;
-
-  else if( !strcmp(str, "f64")   || !strcmp(str, "float64") )
-    return GAL_DATA_TYPE_FLOAT64;
-
-  else if( !strcmp(str, "c32")   || !strcmp(str, "complex32") )
-    return GAL_DATA_TYPE_COMPLEX32;
-
-  else if( !strcmp(str, "c64")   || !strcmp(str, "complex64") )
-    return GAL_DATA_TYPE_COMPLEX64;
-
-  else if( !strcmp(str, "str")   || !strcmp(str, "string") )
-    return GAL_DATA_TYPE_STRING;
-
-  else
-    return GAL_DATA_TYPE_INVALID;
-
-  /* Any of the cases above should return this function, so if control
-     reaches here, there is a bug. */
-  error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can address "
-        "the problem. For some reason control has reached the end of "
-        "the `gal_data_string_as_type' function. This must not happen",
-        PACKAGE_BUGREPORT);
-  return 0;
-}
-
-
-
-
-
-/* Put the minimum (or maximum for the `gal_data_type_max') value for the
-   type in the space (that must already be allocated before the call to
-   this function) pointed to by in.  */
-void
-gal_data_type_min(uint8_t type, void *in)
-{
-  switch(type)
-    {
-    case GAL_DATA_TYPE_UINT8:    *(uint8_t *)  in = 0;            break;
-    case GAL_DATA_TYPE_INT8:     *(int8_t *)   in = INT8_MIN;     break;
-    case GAL_DATA_TYPE_UINT16:   *(uint16_t *) in = 0;            break;
-    case GAL_DATA_TYPE_INT16:    *(int16_t *)  in = INT16_MIN;    break;
-    case GAL_DATA_TYPE_UINT32:   *(uint32_t *) in = 0;            break;
-    case GAL_DATA_TYPE_INT32:    *(int32_t *)  in = INT32_MIN;    break;
-    case GAL_DATA_TYPE_UINT64:   *(uint64_t *) in = 0;            break;
-    case GAL_DATA_TYPE_INT64:    *(int64_t *)  in = INT64_MIN;    break;
-    case GAL_DATA_TYPE_FLOAT32:  *(float *)    in = -FLT_MAX;     break;
-    case GAL_DATA_TYPE_FLOAT64:  *(double *)   in = -DBL_MAX;     break;
-    default:
-      error(EXIT_FAILURE, 0, "type code %d not recognized in "
-            "`gal_data_type_min'", type);
-    }
-}
-
-
-
-
-
-void
-gal_data_type_max(uint8_t type, void *in)
-{
-  switch(type)
-    {
-    case GAL_DATA_TYPE_UINT8:    *(uint8_t *)  in = UINT8_MAX;    break;
-    case GAL_DATA_TYPE_INT8:     *(int8_t *)   in = INT8_MAX;     break;
-    case GAL_DATA_TYPE_UINT16:   *(uint16_t *) in = UINT16_MAX;   break;
-    case GAL_DATA_TYPE_INT16:    *(int16_t *)  in = INT16_MAX;    break;
-    case GAL_DATA_TYPE_UINT32:   *(uint32_t *) in = UINT32_MAX;   break;
-    case GAL_DATA_TYPE_INT32:    *(int32_t *)  in = INT32_MAX;    break;
-    case GAL_DATA_TYPE_UINT64:   *(uint64_t *) in = UINT64_MAX;   break;
-    case GAL_DATA_TYPE_INT64:    *(int64_t *)  in = INT64_MAX;    break;
-    case GAL_DATA_TYPE_FLOAT32:  *(float *)    in = FLT_MAX;      break;
-    case GAL_DATA_TYPE_FLOAT64:  *(double *)   in = DBL_MAX;      break;
-    default:
-      error(EXIT_FAILURE, 0, "type code %d not recognized in "
-            "`gal_data_type_min'", type);
-    }
-}
-
-
-
-
-
-/* Since linked lists need a different process than arrays, for functions
-   that work on both, it is convenient to simiplify the check with this
-   function. */
-int
-gal_data_is_linked_list(uint8_t type)
-{
-  return type==GAL_DATA_TYPE_STRLL;
-}
-
-
-
-
-
-int
-gal_data_out_type(gal_data_t *first, gal_data_t *second)
-{
-  int ftype=gal_tile_block(first)->type;
-  int stype=gal_tile_block(second)->type;
-  return ftype > stype ? ftype : stype;
-}
-
-
-
-
-
-
-
-
-
-
 
 
 
@@ -323,82 +107,6 @@ gal_data_dsize_is_different(gal_data_t *first, gal_data_t 
*second)
 
 
 
-size_t
-gal_data_sizeof(uint8_t type)
-{
-  /* Allocate space for the array to keep the image. */
-  switch(type)
-    {
-    case GAL_DATA_TYPE_BIT:
-      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
-            "types, please get in touch with us to implement it.");
-
-      /* The parenthesis after sizeof is not a function, it is actually a
-         type cast, so we have put a space between size of and the
-         parenthesis to highlight this. In C, `sizeof' is an operator, not
-         a function.*/
-    case GAL_DATA_TYPE_UINT8:
-      return sizeof (uint8_t);
-
-    case GAL_DATA_TYPE_INT8:
-      return sizeof (int8_t);
-
-    case GAL_DATA_TYPE_UINT16:
-      return sizeof (uint16_t);
-
-    case GAL_DATA_TYPE_INT16:
-      return sizeof (int16_t);
-
-    case GAL_DATA_TYPE_UINT32:
-      return sizeof (uint32_t);
-
-    case GAL_DATA_TYPE_INT32:
-      return sizeof (int32_t);
-
-    case GAL_DATA_TYPE_UINT64:
-      return sizeof (uint64_t);
-
-    case GAL_DATA_TYPE_INT64:
-      return sizeof (int64_t);
-
-    case GAL_DATA_TYPE_FLOAT32:
-      if( sizeof (float) != 4 )
-        error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
-      return sizeof (float);
-
-    case GAL_DATA_TYPE_FLOAT64:
-      if( sizeof (double) != 8 )
-        error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
-      return sizeof (double);
-
-    case GAL_DATA_TYPE_COMPLEX32:
-      if( sizeof (float) != 4 )
-        error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
-      return sizeof (gsl_complex_float);
-
-    case GAL_DATA_TYPE_COMPLEX64:
-      if( sizeof (double) != 8 )
-        error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
-      return sizeof (gsl_complex);
-
-    case GAL_DATA_TYPE_STRING:
-      return sizeof (char *);
-
-    default:
-      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
-            "gal_data_sizeof", type);
-    }
-
-  error(EXIT_FAILURE, 0, "Control has reached the end of `gal_data_sizeof' "
-        "This is a bug! Please contact us at %s so we can find the cause "
-        "of the problem.", PACKAGE_BUGREPORT);
-  return -1;
-}
-
-
-
-
-
 /* Increment a give pointer depending on the given type.
 
    When working with the `array' elements of `gal_data_t', we are actually
@@ -415,7 +123,7 @@ void *
 gal_data_ptr_increment(void *pointer, size_t increment, uint8_t type)
 {
   char *p=(char *)pointer;
-  return p + increment * gal_data_sizeof(type);
+  return p + increment * gal_type_sizeof(type);
 }
 
 
@@ -428,7 +136,7 @@ size_t
 gal_data_ptr_dist(void *earlier, void *later, uint8_t type)
 {
   char *e=(char *)earlier, *l=(char *)later;
-  return (l-e)/gal_data_sizeof(type);
+  return (l-e)/gal_type_sizeof(type);
 }
 
 
@@ -445,10 +153,10 @@ gal_data_malloc_array(uint8_t type, size_t size)
   void *array;
 
   errno=0;
-  array=malloc( size * gal_data_sizeof(type) );
+  array=malloc( size * gal_type_sizeof(type) );
   if(array==NULL)
     error(EXIT_FAILURE, errno, "array of %zu bytes in gal_data_malloc_array",
-          size * gal_data_sizeof(type));
+          size * gal_type_sizeof(type));
 
   return array;
 }
@@ -463,10 +171,10 @@ gal_data_calloc_array(uint8_t type, size_t size)
   void *array;
 
   errno=0;
-  array=calloc( size,  gal_data_sizeof(type) );
+  array=calloc( size,  gal_type_sizeof(type) );
   if(array==NULL)
     error(EXIT_FAILURE, errno, "array of %zu bytes in gal_data_calloc_array",
-          size * gal_data_sizeof(type));
+          size * gal_type_sizeof(type));
 
   return array;
 }
@@ -480,71 +188,42 @@ gal_data_calloc_array(uint8_t type, size_t size)
 void *
 gal_data_alloc_number(uint8_t type, void *number)
 {
-  void *allocated;
+  void *allocd;
 
   /* Allocate the space for the blank value: */
-  allocated=gal_data_malloc_array(type, 1);
+  allocd=gal_data_malloc_array(type, 1);
 
   /* Put the blank value into it. */
   errno=0;
   switch(type)
     {
-    case GAL_DATA_TYPE_BIT:
+    case GAL_TYPE_BIT:
       error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support blank "
-            "values for `GAL_DATA_TYPE_BIT', please get in touch with "
+            "values for `GAL_TYPE_BIT', please get in touch with "
             "us to see how we can implement it.");
 
-    case GAL_DATA_TYPE_UINT8:
-      *(uint8_t *)allocated=*(uint8_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_INT8:
-      *(int8_t *)allocated=*(int8_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_UINT16:
-      *(uint16_t *)allocated=*(uint16_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_INT16:
-      *(int16_t *)allocated=*(int16_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_UINT32:
-      *(uint32_t *)allocated=*(uint32_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_INT32:
-      *(int32_t *)allocated=*(int32_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_UINT64:
-      *(uint64_t *)allocated=*(uint64_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_INT64:
-      *(int64_t *)allocated=*(int64_t *)number;
-      break;
-
-    case GAL_DATA_TYPE_FLOAT32:
-      *(float *)allocated=*(float *)number;
-      break;
-
-    case GAL_DATA_TYPE_FLOAT64:
-      *(double *)allocated=*(double *)number;
-      break;
-
-    case GAL_DATA_TYPE_COMPLEX32:
-      GSL_COMPLEX_P_REAL(((gsl_complex_float *)allocated)) =
+    case GAL_TYPE_UINT8:   *(uint8_t *)allocd  = *(uint8_t *)  number; break;
+    case GAL_TYPE_INT8:    *(int8_t *)allocd   = *(int8_t *)   number; break;
+    case GAL_TYPE_UINT16:  *(uint16_t *)allocd = *(uint16_t *) number; break;
+    case GAL_TYPE_INT16:   *(int16_t *)allocd  = *(int16_t *)  number; break;
+    case GAL_TYPE_UINT32:  *(uint32_t *)allocd = *(uint32_t *) number; break;
+    case GAL_TYPE_INT32:   *(int32_t *)allocd  = *(int32_t *)  number; break;
+    case GAL_TYPE_UINT64:  *(uint64_t *)allocd = *(uint64_t *) number; break;
+    case GAL_TYPE_INT64:   *(int64_t *)allocd  = *(int64_t *)  number; break;
+    case GAL_TYPE_FLOAT32: *(float *)allocd    = *(float *)    number; break;
+    case GAL_TYPE_FLOAT64: *(double *)allocd   = *(double *)   number; break;
+
+    case GAL_TYPE_COMPLEX32:
+      GSL_COMPLEX_P_REAL(((gsl_complex_float *)allocd)) =
         GSL_COMPLEX_P_REAL(((gsl_complex_float *)number));
-      GSL_COMPLEX_P_IMAG(((gsl_complex_float *)allocated)) =
+      GSL_COMPLEX_P_IMAG(((gsl_complex_float *)allocd)) =
         GSL_COMPLEX_P_IMAG(((gsl_complex_float *)number));
       break;
 
-    case GAL_DATA_TYPE_COMPLEX64:
-      GSL_COMPLEX_P_REAL(((gsl_complex *)allocated)) =
+    case GAL_TYPE_COMPLEX64:
+      GSL_COMPLEX_P_REAL(((gsl_complex *)allocd)) =
         GSL_COMPLEX_P_REAL(((gsl_complex *)number));
-      GSL_COMPLEX_P_IMAG(((gsl_complex *)allocated)) =
+      GSL_COMPLEX_P_IMAG(((gsl_complex *)allocd)) =
         GSL_COMPLEX_P_IMAG(((gsl_complex *)number));
       break;
 
@@ -553,7 +232,7 @@ gal_data_alloc_number(uint8_t type, void *number)
             "`gal_data_alloc_number'", type);
     }
 
-  return allocated;
+  return allocd;
 }
 
 
@@ -566,7 +245,7 @@ gal_data_mmap(gal_data_t *data, int clear)
   int filedes;
   char *filename;
   unsigned char uc=0;
-  size_t bsize=data->size*gal_data_sizeof(data->type);
+  size_t bsize=data->size*gal_type_sizeof(data->type);
 
   /* Check if the .gnuastro folder exists, write the file there. If it
      doesn't exist, then make the .gnuastro directory.*/
@@ -694,7 +373,7 @@ gal_data_initialize(gal_data_t *data, void *array, uint8_t 
type,
         data->array=array;
       else
         {
-          if( gal_data_sizeof(type)*data->size  > minmapsize )
+          if( gal_type_sizeof(type)*data->size  > minmapsize )
             gal_data_mmap(data, clear);
           else
             {
@@ -761,7 +440,7 @@ gal_data_string_fixed_alloc_size(gal_data_t *data)
   char *tmp, **strarr=data->array;
 
   /* Return 0 if the dataset is not a string. */
-  if(data->type!=GAL_DATA_TYPE_STRING)
+  if(data->type!=GAL_TYPE_STRING)
     return -1;
 
   /* Get the maximum length. */
@@ -828,7 +507,7 @@ gal_data_free_contents(gal_data_t *data)
   /* If the data type is string, then each element in the array is actually
      a pointer to the array of characters, so free them before freeing the
      actual array. */
-  if(data->type==GAL_DATA_TYPE_STRING && data->array)
+  if(data->type==GAL_TYPE_STRING && data->array)
     {
       size_t i;
       char **strarr=data->array;
@@ -908,7 +587,7 @@ gal_data_array_calloc(size_t size)
   for(i=0;i<size;++i)
     {
       out[i].array      = NULL;
-      out[i].type       = GAL_DATA_TYPE_INVALID;
+      out[i].type       = GAL_TYPE_INVALID;
       out[i].ndim       = 0;
       out[i].dsize      = NULL;
       out[i].nwcs       = 0;
@@ -1174,7 +853,7 @@ data_copy_to_string_not_parsed(char *string, void *to, 
uint8_t type)
     gal_blank_write(to, type);
   else
     error(EXIT_FAILURE, 0, "`%s' couldn't be parsed as `%s' type",
-          string, gal_data_type_as_string(type, 1));
+          string, gal_type_to_string(type, 1));
 }
 
 
@@ -1192,7 +871,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
   char **strarr=from->array, **outstrarr=to->array;
 
   /* Sanity check. */
-  if(from->type!=GAL_DATA_TYPE_STRING)
+  if(from->type!=GAL_TYPE_STRING)
     error(EXIT_FAILURE, 0, "`from' in `data_copy_from_string' must have "
           "a string type.");
   if(from->block)
@@ -1206,34 +885,23 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
       /* Set the pointer. */
       switch(to->type)
         {
-        case GAL_DATA_TYPE_UINT8:    ptr = (uint8_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_INT8:     ptr = (int8_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_UINT16:   ptr = (uint16_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_INT16:    ptr = (int16_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_UINT32:   ptr = (uint32_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_INT32:    ptr = (int32_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_UINT64:   ptr = (uint64_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_INT64:    ptr = (int64_t *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_FLOAT32:  ptr = (float *)(to->array) + i;
-          break;
-        case GAL_DATA_TYPE_FLOAT64:  ptr = (double *)(to->array) + i;
-          break;
-
-        case GAL_DATA_TYPE_BIT:
-        case GAL_DATA_TYPE_STRLL:
-        case GAL_DATA_TYPE_COMPLEX32:
-        case GAL_DATA_TYPE_COMPLEX64:
+        case GAL_TYPE_UINT8:    ptr = (uint8_t *)(to->array)  + i;   break;
+        case GAL_TYPE_INT8:     ptr = (int8_t *)(to->array)   + i;   break;
+        case GAL_TYPE_UINT16:   ptr = (uint16_t *)(to->array) + i;   break;
+        case GAL_TYPE_INT16:    ptr = (int16_t *)(to->array)  + i;   break;
+        case GAL_TYPE_UINT32:   ptr = (uint32_t *)(to->array) + i;   break;
+        case GAL_TYPE_INT32:    ptr = (int32_t *)(to->array)  + i;   break;
+        case GAL_TYPE_UINT64:   ptr = (uint64_t *)(to->array) + i;   break;
+        case GAL_TYPE_INT64:    ptr = (int64_t *)(to->array)  + i;   break;
+        case GAL_TYPE_FLOAT32:  ptr = (float *)(to->array)    + i;   break;
+        case GAL_TYPE_FLOAT64:  ptr = (double *)(to->array)   + i;   break;
+        case GAL_TYPE_BIT:
+        case GAL_TYPE_STRLL:
+        case GAL_TYPE_COMPLEX32:
+        case GAL_TYPE_COMPLEX64:
           error(EXIT_FAILURE, 0, "`data_copy_from_string' currently doesn't "
                 "support copying to %s type",
-                gal_data_type_as_string(to->type, 1));
+                gal_type_to_string(to->type, 1));
           break;
 
         default:
@@ -1242,7 +910,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
         }
 
       /* Read/put the input into the output. */
-      if(to->type==GAL_DATA_TYPE_STRING)
+      if(to->type==GAL_TYPE_STRING)
         gal_checkset_allocate_copy(strarr[i], &outstrarr[i]);
       else
         {
@@ -1263,7 +931,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
       {                                                                 \
         if(a[i]!=BLANK) asprintf(&strarr[i], FMT, a[i]);                \
         else                                                            \
-          gal_checkset_allocate_copy(GAL_BLANK_STRING, &strarr[i]); \
+          gal_checkset_allocate_copy(GAL_BLANK_STRING, &strarr[i]);     \
       }                                                                 \
   }
 
@@ -1274,7 +942,7 @@ data_copy_from_string(gal_data_t *from, gal_data_t *to)
         if(isnan(BLANK)) isblank = isnan(a[i]) ? 1 : 0;                 \
         else             isblank = a[i]==BLANK ? 1 : 0;                 \
         if(isblank==0) asprintf(&strarr[i], "%f", a[i]);                \
-        else gal_checkset_allocate_copy(GAL_BLANK_STRING, &strarr[i]); \
+        else gal_checkset_allocate_copy(GAL_BLANK_STRING, &strarr[i]);  \
       }                                                                 \
   }
 
@@ -1288,7 +956,7 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
   char **strarr=to->array, **instrarr=from->array;
 
   /* Sanity check */
-  if(to->type!=GAL_DATA_TYPE_STRING)
+  if(to->type!=GAL_TYPE_STRING)
     error(EXIT_FAILURE, 0, "`to' in `data_copy_to_string' must have a "
           "string type");
   if(from->block)
@@ -1299,48 +967,48 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
   /* Do the copying */
   switch(from->type)
     {
-    case GAL_DATA_TYPE_UINT8:
+    case GAL_TYPE_UINT8:
       COPY_TO_STR_INT(uint8_t,  GAL_BLANK_UINT8, "%u");    break;
 
-    case GAL_DATA_TYPE_INT8:
+    case GAL_TYPE_INT8:
       COPY_TO_STR_INT(int8_t,   GAL_BLANK_INT8, "%d");     break;
 
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       COPY_TO_STR_INT(uint16_t, GAL_BLANK_UINT16, "%u");   break;
 
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       COPY_TO_STR_INT(int16_t,  GAL_BLANK_INT16, "%d");    break;
 
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       COPY_TO_STR_INT(uint32_t, GAL_BLANK_UINT32, "%u");   break;
 
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       COPY_TO_STR_INT(int32_t,  GAL_BLANK_INT32, "%d");    break;
 
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       COPY_TO_STR_INT(uint64_t, GAL_BLANK_UINT64, "%lu");  break;
 
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       COPY_TO_STR_INT(int64_t,  GAL_BLANK_INT64, "%ld");   break;
 
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       COPY_TO_STR_FLT(float, GAL_BLANK_FLOAT32);           break;
 
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       COPY_TO_STR_FLT(double, GAL_BLANK_FLOAT32);          break;
 
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       for(i=0;i<from->size;++i)
         gal_checkset_allocate_copy(instrarr[i], &strarr[i]);
       break;
 
-    case GAL_DATA_TYPE_BIT:
-    case GAL_DATA_TYPE_STRLL:
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_BIT:
+    case GAL_TYPE_STRLL:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "`data_copy_to_string' currently doesn't "
             "support copying to %s type",
-            gal_data_type_as_string(from->type, 1));
+            gal_type_to_string(from->type, 1));
       break;
 
     default:
@@ -1354,10 +1022,10 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
 
 
 #define COPY_OT_IT_SET(OT, IT) {                                        \
-    OT ob, *o=out->array;                                               \
+    OT ob, *restrict o=out->array;                                      \
     size_t increment=0, num_increment=1;                                \
-    IT ib, *ist, *i=in->array, *f=i+in->size;                           \
     size_t mclen=0, contig_len=in->dsize[in->ndim-1];                   \
+    IT ib, *ist, *restrict i=in->array, *f=i+in->size;                  \
     size_t s_e_ind[2]={0,iblock->size-1}; /* -1: this is INCLUSIVE */   \
                                                                         \
     /* If we are on a tile, the default values need to change. */       \
@@ -1385,7 +1053,7 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
         /* conversion). */                                              \
         if(iblock->type==out->type)                                     \
           {                                                             \
-            memcpy(o, i, mclen*gal_data_sizeof(iblock->type));          \
+            memcpy(o, i, mclen*gal_type_sizeof(iblock->type));          \
             o += mclen;                                                 \
           }                                                             \
         else                                                            \
@@ -1415,57 +1083,24 @@ data_copy_to_string(gal_data_t *from, gal_data_t *to)
 #define COPY_OT_SET(OT)                                                 \
   switch(iblock->type)                                                  \
     {                                                                   \
-    case GAL_DATA_TYPE_UINT8:                                           \
-      COPY_OT_IT_SET(OT, uint8_t);                                      \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_INT8:                                            \
-      COPY_OT_IT_SET(OT, int8_t);                                       \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_UINT16:                                          \
-      COPY_OT_IT_SET(OT, uint16_t);                                     \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_INT16:                                           \
-      COPY_OT_IT_SET(OT, int16_t);                                      \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_UINT32:                                          \
-      COPY_OT_IT_SET(OT, uint32_t);                                     \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_INT32:                                           \
-      COPY_OT_IT_SET(OT, int32_t);                                      \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_UINT64:                                          \
-      COPY_OT_IT_SET(OT, uint64_t);                                     \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_INT64:                                           \
-      COPY_OT_IT_SET(OT, int64_t);                                      \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
-      COPY_OT_IT_SET(OT, float);                                        \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
-      COPY_OT_IT_SET(OT, double);                                       \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_STRING:                                          \
-      data_copy_from_string(in, out);                                   \
-      break;                                                            \
-                                                                        \
-    case GAL_DATA_TYPE_BIT:                                             \
-    case GAL_DATA_TYPE_STRLL:                                           \
-    case GAL_DATA_TYPE_COMPLEX32:                                       \
-    case GAL_DATA_TYPE_COMPLEX64:                                       \
+    case GAL_TYPE_UINT8:      COPY_OT_IT_SET(OT, uint8_t  );    break;  \
+    case GAL_TYPE_INT8:       COPY_OT_IT_SET(OT, int8_t   );    break;  \
+    case GAL_TYPE_UINT16:     COPY_OT_IT_SET(OT, uint16_t );    break;  \
+    case GAL_TYPE_INT16:      COPY_OT_IT_SET(OT, int16_t  );    break;  \
+    case GAL_TYPE_UINT32:     COPY_OT_IT_SET(OT, uint32_t );    break;  \
+    case GAL_TYPE_INT32:      COPY_OT_IT_SET(OT, int32_t  );    break;  \
+    case GAL_TYPE_UINT64:     COPY_OT_IT_SET(OT, uint64_t );    break;  \
+    case GAL_TYPE_INT64:      COPY_OT_IT_SET(OT, int64_t  );    break;  \
+    case GAL_TYPE_FLOAT32:    COPY_OT_IT_SET(OT, float    );    break;  \
+    case GAL_TYPE_FLOAT64:    COPY_OT_IT_SET(OT, double   );    break;  \
+    case GAL_TYPE_STRING:     data_copy_from_string(in, out);   break;  \
+    case GAL_TYPE_BIT:                                                  \
+    case GAL_TYPE_STRLL:                                                \
+    case GAL_TYPE_COMPLEX32:                                            \
+    case GAL_TYPE_COMPLEX64:                                            \
       error(EXIT_FAILURE, 0, "`gal_data_copy_to_new_type' currently "   \
             "doesn't support copying from %s type to a numeric (real) " \
-            "type", gal_data_type_as_string(in->type, 1));              \
+            "type", gal_type_to_string(in->type, 1));                   \
       break;                                                            \
                                                                         \
     default:                                                            \
@@ -1513,53 +1148,67 @@ gal_data_copy_to_new_type(gal_data_t *in, uint8_t 
newtype)
 
 
 
-/* Copy an array into the already allocated space in `out'. */
+/* Copy an array into the already allocated space of `out'. Note this
+   function won't re-allocate the space if the required size is larger. It
+   will abort with an error. If the output's size parameters are larger
+   than the input, then this function will update them to be the same as
+   the input. */
 void
 gal_data_copy_to_new_type_to_allocated(gal_data_t *in, gal_data_t *out,
                                        uint8_t newtype)
 {
   gal_data_t *iblock=gal_tile_block(in);
 
-  /* Two small sanity checks to avoid segmentation faults. */
-  if(out->size<in->size)
+  /* Make sure the number of allocated elements (of whatever type) in the
+     output is not smaller than the input. Note that the type is irrelevant
+     because we will be doing type conversion if they differ.*/
+  if( out->size < in->size  )
     error(EXIT_FAILURE, 0, "the output dataset must be equal or larger than "
           "the input in `gal_data_copy_to_new_type_allocated', the sizes "
           "are %zu and %zu respectively", out->size, in->size);
-  if(out->type!=newtype)
-    error(EXIT_FAILURE, 0, "the output dataset must have the same type as "
-          "the requested type in `gal_data_copy_to_new_type_allocated', "
-          "the types are %s and %s respectively",
-          gal_data_type_as_string(out->type, 1),
-          gal_data_type_as_string(newtype, 1));
+  if( out->ndim != in->ndim )
+    error(EXIT_FAILURE, 0, "the output dataset must have the same number of "
+          "dimensions in `gal_data_copy_to_new_type_allocated', the "
+          "dimensions "
+          "are %zu and %zu respectively", out->ndim, in->ndim);
+
 
   /* Do the copying. */
   switch(out->type)
     {
-    case GAL_DATA_TYPE_UINT8:   COPY_OT_SET( uint8_t  );      break;
-    case GAL_DATA_TYPE_INT8:    COPY_OT_SET( int8_t   );      break;
-    case GAL_DATA_TYPE_UINT16:  COPY_OT_SET( uint16_t );      break;
-    case GAL_DATA_TYPE_INT16:   COPY_OT_SET( int16_t  );      break;
-    case GAL_DATA_TYPE_UINT32:  COPY_OT_SET( uint32_t );      break;
-    case GAL_DATA_TYPE_INT32:   COPY_OT_SET( int32_t  );      break;
-    case GAL_DATA_TYPE_UINT64:  COPY_OT_SET( uint64_t );      break;
-    case GAL_DATA_TYPE_INT64:   COPY_OT_SET( int64_t  );      break;
-    case GAL_DATA_TYPE_FLOAT32: COPY_OT_SET( float    );      break;
-    case GAL_DATA_TYPE_FLOAT64: COPY_OT_SET( double   );      break;
-    case GAL_DATA_TYPE_STRING:  data_copy_to_string(in, out); break;
-
-    case GAL_DATA_TYPE_BIT:
-    case GAL_DATA_TYPE_STRLL:
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_UINT8:   COPY_OT_SET( uint8_t  );      break;
+    case GAL_TYPE_INT8:    COPY_OT_SET( int8_t   );      break;
+    case GAL_TYPE_UINT16:  COPY_OT_SET( uint16_t );      break;
+    case GAL_TYPE_INT16:   COPY_OT_SET( int16_t  );      break;
+    case GAL_TYPE_UINT32:  COPY_OT_SET( uint32_t );      break;
+    case GAL_TYPE_INT32:   COPY_OT_SET( int32_t  );      break;
+    case GAL_TYPE_UINT64:  COPY_OT_SET( uint64_t );      break;
+    case GAL_TYPE_INT64:   COPY_OT_SET( int64_t  );      break;
+    case GAL_TYPE_FLOAT32: COPY_OT_SET( float    );      break;
+    case GAL_TYPE_FLOAT64: COPY_OT_SET( double   );      break;
+    case GAL_TYPE_STRING:  data_copy_to_string(in, out); break;
+
+    case GAL_TYPE_BIT:
+    case GAL_TYPE_STRLL:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "`gal_data_copy_to_new_type' currently doesn't "
             "support copying to %s type",
-            gal_data_type_as_string(out->type, 1));
+            gal_type_to_string(out->type, 1));
       break;
 
     default:
       error(EXIT_FAILURE, 0, "type %d not recognized for "
             "for `out->type' in gal_data_copy_to_new_type", out->type);
     }
+
+
+  /* Correct the sizes of the output to be the same as the input. If it is
+     equal, there is no problem, if not, the size information will be
+     changed, so if you want to use this allocated space again, be sure to
+     re-set the size parameters. */
+  out->size=in->size;
+  memcpy(out->dsize, in->dsize, in->ndim * sizeof *(in->dsize) );
 }
 
 
@@ -1601,23 +1250,25 @@ gal_data_copy_to_new_type_free(gal_data_t *in, uint8_t 
type)
 
 /* Copy/read the element at `index' of the array in `data' into the space
    pointed to by `ptr'. */
-#define COPY_ELEM(IT) { IT *o=ptr, *a=input->array; *o = a[index]; }
+#define COPY_ELEM(IT) {                                                 \
+    IT *restrict o=ptr, *restrict a=input->array; *o = a[index];        \
+}
 void
 gal_data_copy_element_same_type(gal_data_t *input, size_t index, void *ptr)
 {
   /* Set the value. */
   switch(input->type)
     {
-    case GAL_DATA_TYPE_UINT8:     COPY_ELEM( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:      COPY_ELEM( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:    COPY_ELEM( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:     COPY_ELEM( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:    COPY_ELEM( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:     COPY_ELEM( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:    COPY_ELEM( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:     COPY_ELEM( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:   COPY_ELEM( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:   COPY_ELEM( double   );    break;
+    case GAL_TYPE_UINT8:     COPY_ELEM( uint8_t  );    break;
+    case GAL_TYPE_INT8:      COPY_ELEM( int8_t   );    break;
+    case GAL_TYPE_UINT16:    COPY_ELEM( uint16_t );    break;
+    case GAL_TYPE_INT16:     COPY_ELEM( int16_t  );    break;
+    case GAL_TYPE_UINT32:    COPY_ELEM( uint32_t );    break;
+    case GAL_TYPE_INT32:     COPY_ELEM( int32_t  );    break;
+    case GAL_TYPE_UINT64:    COPY_ELEM( uint64_t );    break;
+    case GAL_TYPE_INT64:     COPY_ELEM( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:   COPY_ELEM( float    );    break;
+    case GAL_TYPE_FLOAT64:   COPY_ELEM( double   );    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_data_copy_elem'", input->type);
@@ -1656,7 +1307,7 @@ gal_data_write_to_string(void *ptr, uint8_t type, int 
quote_if_str_has_space)
     /* For a string we might need to make sure it has no white space
        characters, if it does, it can be printed it within quotation
        signs. */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       if(quote_if_str_has_space)
         {
           c=*(char **)ptr; while(*c!='\0') if(isspace(*c++)) break;
@@ -1667,16 +1318,16 @@ gal_data_write_to_string(void *ptr, uint8_t type, int 
quote_if_str_has_space)
         asprintf(&str, "%s", *(char **)ptr);
       break;
 
-    case GAL_DATA_TYPE_UINT8:   WRITE_TO_STRING(uint8_t,   "%u");  break;
-    case GAL_DATA_TYPE_INT8:    WRITE_TO_STRING(int8_t,    "%d");  break;
-    case GAL_DATA_TYPE_UINT16:  WRITE_TO_STRING(uint16_t,  "%u");  break;
-    case GAL_DATA_TYPE_INT16:   WRITE_TO_STRING(int16_t,   "%d");  break;
-    case GAL_DATA_TYPE_UINT32:  WRITE_TO_STRING(uint32_t,  "%u");  break;
-    case GAL_DATA_TYPE_INT32:   WRITE_TO_STRING(int32_t,   "%d");  break;
-    case GAL_DATA_TYPE_UINT64:  WRITE_TO_STRING(uint64_t, "%lu");  break;
-    case GAL_DATA_TYPE_INT64:   WRITE_TO_STRING(int64_t,  "%ld");  break;
-    case GAL_DATA_TYPE_FLOAT32: WRITE_TO_STRING(float,   "%.6g");  break;
-    case GAL_DATA_TYPE_FLOAT64: WRITE_TO_STRING(double, "%.10g");  break;
+    case GAL_TYPE_UINT8:   WRITE_TO_STRING( uint8_t,   "%u");  break;
+    case GAL_TYPE_INT8:    WRITE_TO_STRING( int8_t,    "%d");  break;
+    case GAL_TYPE_UINT16:  WRITE_TO_STRING( uint16_t,  "%u");  break;
+    case GAL_TYPE_INT16:   WRITE_TO_STRING( int16_t,   "%d");  break;
+    case GAL_TYPE_UINT32:  WRITE_TO_STRING( uint32_t,  "%u");  break;
+    case GAL_TYPE_INT32:   WRITE_TO_STRING( int32_t,   "%d");  break;
+    case GAL_TYPE_UINT64:  WRITE_TO_STRING( uint64_t, "%lu");  break;
+    case GAL_TYPE_INT64:   WRITE_TO_STRING( int64_t,  "%ld");  break;
+    case GAL_TYPE_FLOAT32: WRITE_TO_STRING( float,   "%.6g");  break;
+    case GAL_TYPE_FLOAT64: WRITE_TO_STRING( double, "%.10g");  break;
 
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
@@ -1736,17 +1387,17 @@ gal_data_string_to_number(char *string)
          types. */
       if( d < 0 )
         {
-          if     (d>INT8_MIN)    {i8=d;  ptr=&i8;  type=GAL_DATA_TYPE_INT8;}
-          else if(d>INT16_MIN)   {i16=d; ptr=&i16; type=GAL_DATA_TYPE_INT16;}
-          else if(d>INT32_MIN)   {i32=d; ptr=&i32; type=GAL_DATA_TYPE_INT32;}
-          else                   {i64=d; ptr=&i64; type=GAL_DATA_TYPE_INT64;}
+          if     (d>INT8_MIN)    {i8=d;  ptr=&i8;  type=GAL_TYPE_INT8;}
+          else if(d>INT16_MIN)   {i16=d; ptr=&i16; type=GAL_TYPE_INT16;}
+          else if(d>INT32_MIN)   {i32=d; ptr=&i32; type=GAL_TYPE_INT32;}
+          else                   {i64=d; ptr=&i64; type=GAL_TYPE_INT64;}
         }
       else
         {
-          if     (d<=UINT8_MAX)  {u8=d;  ptr=&u8;  type=GAL_DATA_TYPE_UINT8;}
-          else if(d<=UINT16_MAX) {u16=d; ptr=&u16; type=GAL_DATA_TYPE_UINT16;}
-          else if(d<=UINT32_MAX) {u32=d; ptr=&u32; type=GAL_DATA_TYPE_UINT32;}
-          else                   {u64=d; ptr=&u64; type=GAL_DATA_TYPE_UINT64;}
+          if     (d<=UINT8_MAX)  {u8=d;  ptr=&u8;  type=GAL_TYPE_UINT8;}
+          else if(d<=UINT16_MAX) {u16=d; ptr=&u16; type=GAL_TYPE_UINT16;}
+          else if(d<=UINT32_MAX) {u32=d; ptr=&u32; type=GAL_TYPE_UINT32;}
+          else                   {u64=d; ptr=&u64; type=GAL_TYPE_UINT64;}
         }
     }
   else
@@ -1780,9 +1431,9 @@ gal_data_string_to_number(char *string)
       /* Calculate the number of decimal digits and decide if it the number
          should be a float or a double. */
       if( lnz-fnz < FLT_DIG || ( d<FLT_MAX && d>FLT_MIN ) )
-        { f=d; ptr=&f; type=GAL_DATA_TYPE_FLOAT32; }
+        { f=d; ptr=&f; type=GAL_TYPE_FLOAT32; }
       else
-        {      ptr=&d; type=GAL_DATA_TYPE_FLOAT64; }
+        {      ptr=&d; type=GAL_TYPE_FLOAT64; }
     }
 
   /* Return the pointer to the data structure. */
@@ -1824,7 +1475,7 @@ gal_data_string_to_type(void **out, char *string, uint8_t 
type)
   /* If the output is NULL, then allocate the necessary space if we are not
      dealing with a linked list. In a linked list, a NULL value is
      meaningful (it is the end of the list). */
-  if( *out==NULL && !gal_data_is_linked_list(type) )
+  if( *out==NULL && !gal_type_is_linked_list(type) )
     {
       allocated=1;
       *out=gal_data_malloc_array(type, 1);
@@ -1836,28 +1487,28 @@ gal_data_string_to_type(void **out, char *string, 
uint8_t type)
     {
 
     /* Linked lists, currently only string linked lists. */
-    case GAL_DATA_TYPE_STRLL:
+    case GAL_TYPE_STRLL:
       gal_linkedlist_add_to_stll( (struct gal_linkedlist_stll **)out,
                                   string, 1);
       break;
 
     /* String, just allocate and copy the string and keep its pointer in
        the place `*out' points to (for strings, `*out' is `char **'). */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       gal_checkset_allocate_copy(string, value);
       break;
 
     /* Floating point: Read it as a double or long, then put it in the
        array. When the conversion can't be done (the string isn't a number
        for example), then just assume no blank value was given. */
-    case GAL_DATA_TYPE_FLOAT32:
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT64:
       d=strtod(string, &tailptr);
       if(*tailptr!='\0')
         status=1;
       else
         {
-          if(type==GAL_DATA_TYPE_FLOAT32) *(float *) value=d;
+          if(type==GAL_TYPE_FLOAT32) *(float *) value=d;
           else                            *(double *) value=d;
         }
       break;
@@ -1871,10 +1522,10 @@ gal_data_string_to_type(void **out, char *string, 
uint8_t type)
         switch(type)
           {
           /* The signed values can easily be put in. */
-          case GAL_DATA_TYPE_INT8:         *(int8_t *)    value = l; break;
-          case GAL_DATA_TYPE_INT16:        *(int16_t *)   value = l; break;
-          case GAL_DATA_TYPE_INT32:        *(int32_t *)   value = l; break;
-          case GAL_DATA_TYPE_INT64:        *(int64_t *)   value = l; break;
+          case GAL_TYPE_INT8:         *(int8_t *)    value = l; break;
+          case GAL_TYPE_INT16:        *(int16_t *)   value = l; break;
+          case GAL_TYPE_INT32:        *(int32_t *)   value = l; break;
+          case GAL_TYPE_INT64:        *(int64_t *)   value = l; break;
 
           /* For the unsigned types, the value has to be positive, so if
              the input was negative, then just return a status of one and
@@ -1885,10 +1536,10 @@ gal_data_string_to_type(void **out, char *string, 
uint8_t type)
             else
               switch(type)
                 {
-                case GAL_DATA_TYPE_UINT8:  *(uint8_t *)   value=l; break;
-                case GAL_DATA_TYPE_UINT16: *(uint16_t *)  value=l; break;
-                case GAL_DATA_TYPE_UINT32: *(uint32_t *)  value=l; break;
-                case GAL_DATA_TYPE_UINT64: *(uint64_t *)  value=l; break;
+                case GAL_TYPE_UINT8:  *(uint8_t *)   value=l;   break;
+                case GAL_TYPE_UINT16: *(uint16_t *)  value=l;   break;
+                case GAL_TYPE_UINT32: *(uint32_t *)  value=l;   break;
+                case GAL_TYPE_UINT64: *(uint64_t *)  value=l;   break;
                 default:
                   error(EXIT_FAILURE, 0, "type code %d not recognized in "
                         "`gal_data_string_to_type'", type);
diff --git a/lib/dimension.c b/lib/dimension.c
index cced659..5bc4987 100644
--- a/lib/dimension.c
+++ b/lib/dimension.c
@@ -55,7 +55,7 @@ size_t *
 gal_dimension_increment(size_t ndim, size_t *dsize)
 {
   int i;
-  size_t *out=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  size_t *out=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
 
   /* Along the fastest dimension, it is 1. */
   out[ndim-1]=1;
diff --git a/lib/fits.c b/lib/fits.c
index 71469c3..3869a5b 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -175,15 +175,15 @@ gal_fits_bitpix_to_type(int bitpix)
 {
   switch(bitpix)
     {
-    case BYTE_IMG:                  return GAL_DATA_TYPE_UINT8;
-    case SBYTE_IMG:                 return GAL_DATA_TYPE_INT8;
-    case USHORT_IMG:                return GAL_DATA_TYPE_UINT16;
-    case SHORT_IMG:                 return GAL_DATA_TYPE_INT16;
-    case ULONG_IMG:                 return GAL_DATA_TYPE_UINT32;
-    case LONG_IMG:                  return GAL_DATA_TYPE_INT32;
-    case LONGLONG_IMG:              return GAL_DATA_TYPE_INT64;
-    case FLOAT_IMG:                 return GAL_DATA_TYPE_FLOAT32;
-    case DOUBLE_IMG:                return GAL_DATA_TYPE_FLOAT64;
+    case BYTE_IMG:                  return GAL_TYPE_UINT8;
+    case SBYTE_IMG:                 return GAL_TYPE_INT8;
+    case USHORT_IMG:                return GAL_TYPE_UINT16;
+    case SHORT_IMG:                 return GAL_TYPE_INT16;
+    case ULONG_IMG:                 return GAL_TYPE_UINT32;
+    case LONG_IMG:                  return GAL_TYPE_INT32;
+    case LONGLONG_IMG:              return GAL_TYPE_INT64;
+    case FLOAT_IMG:                 return GAL_TYPE_FLOAT32;
+    case DOUBLE_IMG:                return GAL_TYPE_FLOAT64;
     default:
       error(EXIT_FAILURE, 0, "bitpix value of %d not recognized in "
             "gal_fits_bitpix_to_type", bitpix);
@@ -200,24 +200,24 @@ gal_fits_type_to_bitpix(uint8_t type)
 {
   switch(type)
     {
-    case GAL_DATA_TYPE_UINT8:       return BYTE_IMG;
-    case GAL_DATA_TYPE_INT8:        return SBYTE_IMG;
-    case GAL_DATA_TYPE_UINT16:      return USHORT_IMG;
-    case GAL_DATA_TYPE_INT16:       return SHORT_IMG;
-    case GAL_DATA_TYPE_UINT32:      return ULONG_IMG;
-    case GAL_DATA_TYPE_INT32:       return LONG_IMG;
-    case GAL_DATA_TYPE_INT64:       return LONGLONG_IMG;
-    case GAL_DATA_TYPE_FLOAT32:     return FLOAT_IMG;
-    case GAL_DATA_TYPE_FLOAT64:     return DOUBLE_IMG;
-
-    case GAL_DATA_TYPE_BIT:
-    case GAL_DATA_TYPE_STRLL:
-    case GAL_DATA_TYPE_STRING:
-    case GAL_DATA_TYPE_UINT64:
-    case GAL_DATA_TYPE_COMPLEX32:
-    case GAL_DATA_TYPE_COMPLEX64:
+    case GAL_TYPE_UINT8:       return BYTE_IMG;
+    case GAL_TYPE_INT8:        return SBYTE_IMG;
+    case GAL_TYPE_UINT16:      return USHORT_IMG;
+    case GAL_TYPE_INT16:       return SHORT_IMG;
+    case GAL_TYPE_UINT32:      return ULONG_IMG;
+    case GAL_TYPE_INT32:       return LONG_IMG;
+    case GAL_TYPE_INT64:       return LONGLONG_IMG;
+    case GAL_TYPE_FLOAT32:     return FLOAT_IMG;
+    case GAL_TYPE_FLOAT64:     return DOUBLE_IMG;
+
+    case GAL_TYPE_BIT:
+    case GAL_TYPE_STRLL:
+    case GAL_TYPE_STRING:
+    case GAL_TYPE_UINT64:
+    case GAL_TYPE_COMPLEX32:
+    case GAL_TYPE_COMPLEX64:
       error(EXIT_FAILURE, 0, "type %s not recognized for FITS image BITPIX",
-            gal_data_type_as_string(type, 1));
+            gal_type_to_string(type, 1));
 
     default:
       error(EXIT_FAILURE, 0, "type value of %d not recognized in "
@@ -240,24 +240,24 @@ gal_fits_type_to_bin_tform(uint8_t type)
   switch(type)
     {
     /* Recognized by CFITSIO. */
-    case GAL_DATA_TYPE_STRING:      return 'A';
-    case GAL_DATA_TYPE_BIT:         return 'X';
-    case GAL_DATA_TYPE_UINT8:       return 'B';
-    case GAL_DATA_TYPE_INT8:        return 'S';
-    case GAL_DATA_TYPE_UINT16:      return 'U';
-    case GAL_DATA_TYPE_INT16:       return 'I';
-    case GAL_DATA_TYPE_UINT32:      return 'V';
-    case GAL_DATA_TYPE_INT32:       return 'J';
-    case GAL_DATA_TYPE_INT64:       return 'K';
-    case GAL_DATA_TYPE_FLOAT32:     return 'E';
-    case GAL_DATA_TYPE_FLOAT64:     return 'D';
-    case GAL_DATA_TYPE_COMPLEX32:   return 'C';
-    case GAL_DATA_TYPE_COMPLEX64:   return 'M';
+    case GAL_TYPE_STRING:      return 'A';
+    case GAL_TYPE_BIT:         return 'X';
+    case GAL_TYPE_UINT8:       return 'B';
+    case GAL_TYPE_INT8:        return 'S';
+    case GAL_TYPE_UINT16:      return 'U';
+    case GAL_TYPE_INT16:       return 'I';
+    case GAL_TYPE_UINT32:      return 'V';
+    case GAL_TYPE_INT32:       return 'J';
+    case GAL_TYPE_INT64:       return 'K';
+    case GAL_TYPE_FLOAT32:     return 'E';
+    case GAL_TYPE_FLOAT64:     return 'D';
+    case GAL_TYPE_COMPLEX32:   return 'C';
+    case GAL_TYPE_COMPLEX64:   return 'M';
 
     /* Not recognized by CFITSIO. */
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       error(EXIT_FAILURE, 0, "type %s not recognized for FITS binary "
-            "table TFORM", gal_data_type_as_string(type, 1));
+            "table TFORM", gal_type_to_string(type, 1));
       break;
 
     /* Wrong type code. */
@@ -284,50 +284,50 @@ gal_fits_type_to_datatype(uint8_t type)
   switch(type)
     {
     /* Recognized CFITSIO types. */
-    case GAL_DATA_TYPE_BIT:              return TBIT;
-    case GAL_DATA_TYPE_UINT8:            return TBYTE;
-    case GAL_DATA_TYPE_INT8:             return TSBYTE;
-    case GAL_DATA_TYPE_FLOAT32:          return TFLOAT;
-    case GAL_DATA_TYPE_FLOAT64:          return TDOUBLE;
-    case GAL_DATA_TYPE_COMPLEX32:        return TCOMPLEX;
-    case GAL_DATA_TYPE_COMPLEX64:        return TDBLCOMPLEX;
-    case GAL_DATA_TYPE_STRING:           return TSTRING;
+    case GAL_TYPE_BIT:              return TBIT;
+    case GAL_TYPE_UINT8:            return TBYTE;
+    case GAL_TYPE_INT8:             return TSBYTE;
+    case GAL_TYPE_FLOAT32:          return TFLOAT;
+    case GAL_TYPE_FLOAT64:          return TDOUBLE;
+    case GAL_TYPE_COMPLEX32:        return TCOMPLEX;
+    case GAL_TYPE_COMPLEX64:        return TDBLCOMPLEX;
+    case GAL_TYPE_STRING:           return TSTRING;
 
     /* Types that depend on the host system. The C standard says that the
        `short', `int' and `long' types are ATLEAST 2, 2, 4 bytes, so be
        safe, we will checking all of them for the 32-bit types.*/
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       w=2;
       if     ( sizeof(short)    == w )   return TUSHORT;
       else if( sizeof(int)      == w )   return TUINT;
       break;
 
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       w=2;
       if     ( sizeof(short)    == w )   return TSHORT;
       else if( sizeof(int)      == w )   return TINT;
       break;
 
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       w=4;
       if     ( sizeof(int)      == w )   return TUINT;
       else if( sizeof(long)     == w )   return TULONG;
       else if( sizeof(short)    == w )   return TUSHORT;
       break;
 
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       w=4;
       if     ( sizeof(int)      == w )   return TINT;
       else if( sizeof(long)     == w )   return TLONG;
       else if( sizeof(short)    == w )   return TSHORT;
       break;
 
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       w=8;
       if     ( sizeof(long)     == w )   return TULONG;
       break;
 
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       w=8;
       if     ( sizeof(long)     == w )   return TLONG;
       else if( sizeof(LONGLONG) == w )   return TLONGLONG;
@@ -343,12 +343,12 @@ gal_fits_type_to_datatype(uint8_t type)
   if(w)
     error(EXIT_FAILURE, 0, "this system doesn't have a %d byte integer "
           "type, so type `%s' cannot be written to FITS", w,
-          gal_data_type_as_string(type, 1));
+          gal_type_to_string(type, 1));
   else
     error(EXIT_FAILURE, 0, "a bug! please contact us at %s so we can "
           "fix theh problem. Control must not have reached the end of "
           "`gal_fits_type_to_datatype', for the given type `%s'",
-          PACKAGE_BUGREPORT, gal_data_type_as_string(type, 1));
+          PACKAGE_BUGREPORT, gal_type_to_string(type, 1));
   return -1;
 }
 
@@ -363,72 +363,72 @@ gal_fits_datatype_to_type(int datatype, int 
is_table_column)
 
   switch(datatype)
     {
-    case TBIT:            return GAL_DATA_TYPE_BIT;
-    case TBYTE:           return GAL_DATA_TYPE_UINT8;
-    case TSBYTE:          return GAL_DATA_TYPE_INT8;
-    case TFLOAT:          return GAL_DATA_TYPE_FLOAT32;
-    case TDOUBLE:         return GAL_DATA_TYPE_FLOAT64;
-    case TCOMPLEX:        return GAL_DATA_TYPE_COMPLEX32;
-    case TDBLCOMPLEX:     return GAL_DATA_TYPE_COMPLEX64;
-    case TSTRING:         return GAL_DATA_TYPE_STRING;
+    case TBIT:            return GAL_TYPE_BIT;
+    case TBYTE:           return GAL_TYPE_UINT8;
+    case TSBYTE:          return GAL_TYPE_INT8;
+    case TFLOAT:          return GAL_TYPE_FLOAT32;
+    case TDOUBLE:         return GAL_TYPE_FLOAT64;
+    case TCOMPLEX:        return GAL_TYPE_COMPLEX32;
+    case TDBLCOMPLEX:     return GAL_TYPE_COMPLEX64;
+    case TSTRING:         return GAL_TYPE_STRING;
 
     /* Sizes that depend on the host system. */
     case TUSHORT:
       switch( sizeof(short) )
         {
-        case 2:           return GAL_DATA_TYPE_UINT16; break;
-        case 4:           return GAL_DATA_TYPE_UINT32; break;
-        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        case 2:           return GAL_TYPE_UINT16; break;
+        case 4:           return GAL_TYPE_UINT32; break;
+        case 8:           return GAL_TYPE_UINT64; break;
         }
       break;
 
     case TSHORT:
       switch( sizeof(short) )
         {
-        case 2:           return GAL_DATA_TYPE_INT16;  break;
-        case 4:           return GAL_DATA_TYPE_INT32;  break;
-        case 8:           return GAL_DATA_TYPE_INT64;  break;
+        case 2:           return GAL_TYPE_INT16;  break;
+        case 4:           return GAL_TYPE_INT32;  break;
+        case 8:           return GAL_TYPE_INT64;  break;
         }
       break;
 
     case TUINT:
       switch( sizeof(int) )
         {
-        case 2:           return GAL_DATA_TYPE_UINT16; break;
-        case 4:           return GAL_DATA_TYPE_UINT32; break;
-        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        case 2:           return GAL_TYPE_UINT16; break;
+        case 4:           return GAL_TYPE_UINT32; break;
+        case 8:           return GAL_TYPE_UINT64; break;
         }
       break;
 
     case TINT:
       switch( sizeof(int) )
         {
-        case 2:           return GAL_DATA_TYPE_INT16;  break;
-        case 4:           return GAL_DATA_TYPE_INT32;  break;
-        case 8:           return GAL_DATA_TYPE_INT64;  break;
+        case 2:           return GAL_TYPE_INT16;  break;
+        case 4:           return GAL_TYPE_INT32;  break;
+        case 8:           return GAL_TYPE_INT64;  break;
         }
       break;
 
     case TULONG:
       switch( sizeof(long) )
         {
-        case 4:           return GAL_DATA_TYPE_UINT32; break;
-        case 8:           return GAL_DATA_TYPE_UINT64; break;
+        case 4:           return GAL_TYPE_UINT32; break;
+        case 8:           return GAL_TYPE_UINT64; break;
         }
       break;
 
     case TLONG: /* ==TINT32BIT when in a table column. */
-      if(is_table_column) return GAL_DATA_TYPE_INT32;
+      if(is_table_column) return GAL_TYPE_INT32;
       else
         switch( sizeof(long) )
           {
-          case 4:         return GAL_DATA_TYPE_INT32;  break;
-          case 8:         return GAL_DATA_TYPE_INT64;  break;
+          case 4:         return GAL_TYPE_INT32;  break;
+          case 8:         return GAL_TYPE_INT64;  break;
           }
       break;
 
     case TLONGLONG:
-      return GAL_DATA_TYPE_INT64;
+      return GAL_TYPE_INT64;
       break;
 
     /* The TLOGICAL depends on the context: for keywords, it is int32, for
@@ -436,11 +436,11 @@ gal_fits_datatype_to_type(int datatype, int 
is_table_column)
     case TLOGICAL:
       switch( sizeof(int) )
         {
-        case 2: inttype=GAL_DATA_TYPE_INT16;  break;
-        case 4: inttype=GAL_DATA_TYPE_INT32;  break;
-        case 8: inttype=GAL_DATA_TYPE_INT64;  break;
+        case 2: inttype=GAL_TYPE_INT16;  break;
+        case 4: inttype=GAL_TYPE_INT32;  break;
+        case 8: inttype=GAL_TYPE_INT64;  break;
         }
-      return is_table_column ? GAL_DATA_TYPE_INT8 : inttype;
+      return is_table_column ? GAL_TYPE_INT8 : inttype;
       break;
 
     /* A bug! */
@@ -716,7 +716,7 @@ gal_fits_key_read_from_ptr(fitsfile *fptr, gal_data_t 
*keysll,
            allocated space above is enough to keep the value.*/
         switch(tmp->type)
           {
-          case GAL_DATA_TYPE_STRING:
+          case GAL_TYPE_STRING:
             errno=0;
             strarray=tmp->array;
             valueptr=strarray[0]=malloc(FLEN_VALUE * sizeof *strarray[0]);
@@ -965,7 +965,7 @@ gal_fits_key_write_filename(char *keynamebase, char 
*filename,
          length was copied. */
       if(value[maxlength-1]=='\0')
         {
-          gal_fits_key_add_to_ll_end(list, GAL_DATA_TYPE_STRING, keyname, 1,
+          gal_fits_key_add_to_ll_end(list, GAL_TYPE_STRING, keyname, 1,
                                      value, 1, NULL, 0, NULL);
           break;
         }
@@ -1212,7 +1212,7 @@ gal_fits_img_info(fitsfile *fptr, int *type, size_t 
*ndim, size_t **dsize)
 
   /* Allocate the array to keep the dimension size and fill it in, note
      that its order is the opposite of naxes. */
-  *dsize=gal_data_malloc_array(GAL_DATA_TYPE_INT64, *ndim);
+  *dsize=gal_data_malloc_array(GAL_TYPE_INT64, *ndim);
   for(i=0; i<*ndim; ++i)
     (*dsize)[i]=naxes[*ndim-1-i];
 }
@@ -1256,7 +1256,7 @@ gal_fits_img_read(char *filename, char *hdu, size_t 
minmapsize)
 
 
   /* Set the fpixel array (first pixel in all dimensions): */
-  fpixel=gal_data_malloc_array(GAL_DATA_TYPE_INT64, ndim);
+  fpixel=gal_data_malloc_array(GAL_TYPE_INT64, ndim);
   for(i=0;i<ndim;++i) fpixel[i]=1;
 
 
@@ -1265,9 +1265,9 @@ gal_fits_img_read(char *filename, char *hdu, size_t 
minmapsize)
      the linked list of keys to keep the `name' and `unit' pointers. We can
      free the linked list after `gal_data_alloc' has read/copied the
      values.*/
-  gal_data_add_to_ll(&keysll, NULL, GAL_DATA_TYPE_STRING, 1, &dsize_key,
+  gal_data_add_to_ll(&keysll, NULL, GAL_TYPE_STRING, 1, &dsize_key,
                      NULL, 0, -1, "EXTNAME", NULL, NULL);
-  gal_data_add_to_ll(&keysll, NULL, GAL_DATA_TYPE_STRING, 1, &dsize_key,
+  gal_data_add_to_ll(&keysll, NULL, GAL_TYPE_STRING, 1, &dsize_key,
                      NULL, 0, -1, "BUNIT", NULL, NULL);
   gal_fits_key_read_from_ptr(fptr, keysll, 0, 0);
   if(keysll->status==0)       {str=keysll->array;       unit=*str; }
@@ -1341,7 +1341,7 @@ gal_fits_img_read_kernel(char *filename, char *hdu, 
size_t minmapsize)
   float *f, *fp, tmp;
 
   /* Read the image as a float */
-  kernel=gal_fits_img_read_to_type(filename, hdu, GAL_DATA_TYPE_FLOAT32,
+  kernel=gal_fits_img_read_to_type(filename, hdu, GAL_TYPE_FLOAT32,
                                    minmapsize);
 
   /* Check if the size along each dimension of the kernel is an odd
@@ -1404,8 +1404,8 @@ gal_fits_img_write_to_ptr(gal_data_t *input, char 
*filename)
 
   /* Allocate the naxis area. */
   naxes=gal_data_malloc_array( ( sizeof(long)==8
-                                 ? GAL_DATA_TYPE_INT64
-                                 : GAL_DATA_TYPE_INT32 ), ndim);
+                                 ? GAL_TYPE_INT64
+                                 : GAL_TYPE_INT32 ), ndim);
 
   /* Open the file for writing */
   fptr=gal_fits_open_to_write(filename);
@@ -1435,8 +1435,8 @@ gal_fits_img_write_to_ptr(gal_data_t *input, char 
*filename)
   if(gal_blank_present(towrite))
     switch(towrite->type)
       {
-      case GAL_DATA_TYPE_FLOAT32:
-      case GAL_DATA_TYPE_FLOAT64:
+      case GAL_TYPE_FLOAT32:
+      case GAL_TYPE_FLOAT64:
         /* Do nothing! Since there are much fewer floating point types
            (that don't need any BLANK keyword), we are checking them.*/
         break;
@@ -1777,16 +1777,16 @@ fits_correct_bin_table_int_types(gal_data_t *allcols, 
int tfields,
       /* Correct the type based on the initial read type and the value to
          tzero. If tzero is any other value, then again, its not a type
          conversion, so just ignore it. */
-      if(allcols[i].type==GAL_DATA_TYPE_UINT8 && tzero[i]==INT8_MIN)
-        allcols[i].type = GAL_DATA_TYPE_INT8;
+      if(allcols[i].type==GAL_TYPE_UINT8 && tzero[i]==INT8_MIN)
+        allcols[i].type = GAL_TYPE_INT8;
 
-      else if ( allcols[i].type==GAL_DATA_TYPE_INT16
+      else if ( allcols[i].type==GAL_TYPE_INT16
                 && tzero[i] == -(long long)INT16_MIN )
-        allcols[i].type = GAL_DATA_TYPE_UINT16;
+        allcols[i].type = GAL_TYPE_UINT16;
 
-      else if (allcols[i].type==GAL_DATA_TYPE_INT32
+      else if (allcols[i].type==GAL_TYPE_INT32
                && tzero[i] ==  -(long long)INT32_MIN)
-        allcols[i].type = GAL_DATA_TYPE_UINT32;
+        allcols[i].type = GAL_TYPE_UINT32;
 
       /* For a check
       printf("Column %zu corrected type: %s\n", i+1,
@@ -1886,7 +1886,7 @@ gal_fits_tab_info(char *filename, char *hdu, size_t 
*numcols,
 
               /* If we are dealing with a string type, we need to know the
                  number of bytes in both cases for printing later. */
-              if( allcols[index].type==GAL_DATA_TYPE_STRING )
+              if( allcols[index].type==GAL_TYPE_STRING )
                 {
                   if(*tabletype==GAL_TABLE_FORMAT_AFITS)
                     {
@@ -2039,7 +2039,7 @@ gal_fits_tab_read(char *filename, char *hdu, size_t 
numrows,
          even in binary values. This value should be stored in the
          disp_width element of the data structure, which is done
          automatically in `gal_fits_table_info'. */
-      if(out->type==GAL_DATA_TYPE_STRING)
+      if(out->type==GAL_TYPE_STRING)
         for(i=0;i<numrows;++i)
           {
             strarr=out->array;
@@ -2136,20 +2136,20 @@ fits_table_prepare_arrays(gal_data_t *cols, size_t 
numcols, int tabletype,
             /* Print the value to be used as TFORMn:  */
             switch(col->type)
               {
-              case GAL_DATA_TYPE_STRING:
-              case GAL_DATA_TYPE_UINT8:
-              case GAL_DATA_TYPE_INT8:
-              case GAL_DATA_TYPE_UINT16:
-              case GAL_DATA_TYPE_INT16:
-              case GAL_DATA_TYPE_UINT32:
-              case GAL_DATA_TYPE_INT32:
-              case GAL_DATA_TYPE_UINT64:
-              case GAL_DATA_TYPE_INT64:
+              case GAL_TYPE_STRING:
+              case GAL_TYPE_UINT8:
+              case GAL_TYPE_INT8:
+              case GAL_TYPE_UINT16:
+              case GAL_TYPE_INT16:
+              case GAL_TYPE_UINT32:
+              case GAL_TYPE_INT32:
+              case GAL_TYPE_UINT64:
+              case GAL_TYPE_INT64:
                 asprintf(&tform[i], "%c%d", fmt[0], col->disp_width);
                 break;
 
-              case GAL_DATA_TYPE_FLOAT32:
-              case GAL_DATA_TYPE_FLOAT64:
+              case GAL_TYPE_FLOAT32:
+              case GAL_TYPE_FLOAT64:
                 asprintf(&tform[i], "%c%d.%d", fmt[0], col->disp_width,
                          col->disp_precision);
                 break;
@@ -2168,7 +2168,7 @@ fits_table_prepare_arrays(gal_data_t *cols, size_t 
numcols, int tabletype,
              then write the value of tform depending on the type. */
           col->disp_width=gal_data_string_fixed_alloc_size(col);
           fmt[0]=gal_fits_type_to_bin_tform(col->type);
-          if( col->type==GAL_DATA_TYPE_STRING )
+          if( col->type==GAL_TYPE_STRING )
             asprintf(&tform[i], "%d%c", col->disp_width, fmt[0]);
           else
             asprintf(&tform[i], "%c", fmt[0]);
@@ -2230,9 +2230,9 @@ fits_write_tnull_tcomm(fitsfile *fptr, gal_data_t *col, 
int tabletype,
       /* FITS binary tables don't accept NULL values for floating point or
          string columns. For floating point is must be NaN and for strings
          it is a blank string. */
-      if( col->type!=GAL_DATA_TYPE_FLOAT32
-          && col->type!=GAL_DATA_TYPE_FLOAT64
-          && col->type!=GAL_DATA_TYPE_STRING )
+      if( col->type!=GAL_TYPE_FLOAT32
+          && col->type!=GAL_TYPE_FLOAT64
+          && col->type!=GAL_TYPE_STRING )
         {
           blank=gal_blank_alloc_write(col->type);
           asprintf(&keyname, "TNULL%zu", colnum);
@@ -2329,7 +2329,7 @@ gal_fits_tab_write(gal_data_t *cols, struct 
gal_linkedlist_stll *comments,
          need a blank pointer in a FITS ASCII table.*/
       blank = ( gal_blank_present(col)
                 ? gal_blank_alloc_write(col->type) : NULL );
-      if(tabletype==GAL_TABLE_FORMAT_AFITS && col->type==GAL_DATA_TYPE_STRING)
+      if(tabletype==GAL_TABLE_FORMAT_AFITS && col->type==GAL_TYPE_STRING)
         { if(blank) free(blank); blank=NULL; }
 
       /* Write the full column into the table. */
diff --git a/lib/gnuastro/binary.h b/lib/gnuastro/binary.h
new file mode 100644
index 0000000..f5e24d8
--- /dev/null
+++ b/lib/gnuastro/binary.h
@@ -0,0 +1,100 @@
+/*********************************************************************
+binary -- Work on binary (0 and 1 valued) datasets.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+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/>.
+**********************************************************************/
+#ifndef __GAL_BINARY_H__
+#define __GAL_BINARY_H__
+
+/* Include other headers if necessary here. Note that other header files
+   must be included before the C++ preparations below */
+#include <gnuastro/data.h>
+#include <gnuastro/blank.h>
+
+/* C++ Preparations */
+#undef __BEGIN_C_DECLS
+#undef __END_C_DECLS
+#ifdef __cplusplus
+# define __BEGIN_C_DECLS extern "C" {
+# define __END_C_DECLS }
+#else
+# define __BEGIN_C_DECLS                /* empty */
+# define __END_C_DECLS                  /* empty */
+#endif
+/* End of C++ preparations */
+
+
+
+/* Actual header contants (the above were for the Pre-processor). */
+__BEGIN_C_DECLS  /* From C++ preparations */
+
+
+
+/* The binary functions will be working on a `uint8_t' type dataset with
+   values of 1 or 0 (no other pixel will be touched). However, in some
+   cases, it is necessary to put temporary values in each element during
+   the processing of the functions. So if your input datasets have values
+   other than 0 and 1 that you don't want these functions to work on, be
+   sure they are not equal to this value. It is chosen as the immediate
+   value before the maximum value for this type (which is the blank value
+   for this type), so blank values will also not be touched by this
+   function. */
+#define GAL_BINARY_TMP_VALUE GAL_BLANK_UINT8-1
+
+
+
+
+
+
+/*********************************************************************/
+/*****************      Erosion and dilation      ********************/
+/*********************************************************************/
+gal_data_t *
+gal_binary_erode(gal_data_t *input, size_t num, int connectivity,
+                 int inplace);
+
+gal_data_t *
+gal_binary_dilate(gal_data_t *input, size_t num, int connectivity,
+                  int inplace);
+
+gal_data_t *
+gal_binary_open(gal_data_t *input, size_t num, int connectivity,
+                int inplace);
+
+
+
+
+
+/*********************************************************************/
+/*****************      Connected components      ********************/
+/*********************************************************************/
+size_t
+gal_binary_connected_components(gal_data_t *binary, gal_data_t **out,
+                                int connectivity);
+
+
+
+
+
+
+
+__END_C_DECLS    /* From C++ preparations */
+
+#endif           /* __GAL_DATA_H__ */
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index 4381d74..741f4ef 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -26,25 +26,13 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Include other headers if necessary here. Note that other header files
    must be included before the C++ preparations below */
 #include <math.h>
-#include <limits.h>
-#include <stdint.h>
 
 #include <wcslib/wcs.h>
-#include <gsl/gsl_complex.h>
 
+#include <gnuastro/type.h>
 #include <gnuastro/linkedlist.h>
 
-/* When we are within Gnuastro's building process, `IN_GNUASTRO_BUILD' is
-   defined. In the build process, installation information (in particular
-   `GAL_CONFIG_SIZEOF_SIZE_T' that we need below) is kept in
-   `config.h'. When building a user's programs, this information is kept in
-   `gnuastro/config.h'. Note that all `.c' files in Gnuastro's source must
-   start with the inclusion of `config.h' and that `gnuastro/config.h' is
-   only created at installation time (not present during the building of
-   Gnuastro).*/
-#ifndef IN_GNUASTRO_BUILD
-#include <gnuastro/config.h>
-#endif
+
 
 /* C++ Preparations */
 #undef __BEGIN_C_DECLS
@@ -67,42 +55,6 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
-/* Macros to identify the type of data. */
-enum gal_data_types
-{
-  GAL_DATA_TYPE_INVALID,     /* Invalid (=0 by C standard).             */
-
-  GAL_DATA_TYPE_BIT,         /* 1 bit                                   */
-  GAL_DATA_TYPE_UINT8,       /* 8-bit  unsigned integer.                */
-  GAL_DATA_TYPE_INT8,        /* 8-bit  signed   integer.                */
-  GAL_DATA_TYPE_UINT16,      /* 16-bit unsigned integer.                */
-  GAL_DATA_TYPE_INT16,       /* 16-bit signed   integer.                */
-  GAL_DATA_TYPE_UINT32,      /* 32-bit unsigned integer.                */
-  GAL_DATA_TYPE_INT32,       /* 32-bit signed   integer.                */
-  GAL_DATA_TYPE_UINT64,      /* 64-bit unsigned integer.                */
-  GAL_DATA_TYPE_INT64,       /* 64-bit signed   integer.                */
-  GAL_DATA_TYPE_FLOAT32,     /* 32-bit single precision floating point. */
-  GAL_DATA_TYPE_FLOAT64,     /* 64-bit double precision floating point. */
-  GAL_DATA_TYPE_COMPLEX32,   /* Complex 32-bit floating point.          */
-  GAL_DATA_TYPE_COMPLEX64,   /* Complex 64-bit floating point.          */
-  GAL_DATA_TYPE_STRING,      /* String of characters.                   */
-  GAL_DATA_TYPE_STRLL,       /* Linked list of strings.                 */
-};
-
-/* `size_t' is 4 and 8 bytes on 32 and 64 bit systems respectively. In both
-   cases, the standard defines `size_t' to be unsigned. During
-   `./configure' the sizeof size_t was found and is stored in
-   `GAL_CONFIG_SIZEOF_SIZE_T'. */
-#if GAL_CONFIG_SIZEOF_SIZE_T == 4
-#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_UINT32
-#else
-#define GAL_DATA_TYPE_SIZE_T GAL_DATA_TYPE_UINT64
-#endif
-
-
-
-
-
 /* Main data structure.
 
    mmap (keep data outside of RAM)
@@ -199,7 +151,7 @@ enum gal_data_types
 typedef struct gal_data_t
 {
   /* Basic information on array of data. */
-  void              *array;  /* Array keeping data elements.               */
+  void     *restrict array;  /* Array keeping data elements.               */
   uint8_t             type;  /* Type of data (from `gal_data_alltypes').   */
   size_t              ndim;  /* Number of dimensions in the array.         */
   size_t            *dsize;  /* Size of array along each dimension.        */
@@ -230,41 +182,16 @@ typedef struct gal_data_t
 
 
 
-/*************************************************************
- **************        Type information        ***************
- *************************************************************/
-void
-gal_data_bit_print_stream(void *in, size_t size);
-
-char *
-gal_data_type_as_string(uint8_t type, int long_name);
-
-uint8_t
-gal_data_string_as_type(char *str);
-
-void
-gal_data_type_min(uint8_t type, void *in);
-
-void
-gal_data_type_max(uint8_t type, void *in);
-
-int
-gal_data_is_linked_list(uint8_t type);
-
-int
-gal_data_out_type(gal_data_t *first, gal_data_t *second);
-
-
 
 /*********************************************************************/
 /*************         Size and allocation         *******************/
 /*********************************************************************/
+void
+gal_data_bit_print_stream(void *in, size_t size);
+
 int
 gal_data_dsize_is_different(gal_data_t *first, gal_data_t *second);
 
-size_t
-gal_data_sizeof(uint8_t type);
-
 void *
 gal_data_ptr_increment(void *pointer, size_t increment, uint8_t type);
 
@@ -301,6 +228,8 @@ gal_data_free(gal_data_t *data);
 
 
 
+
+
 /*********************************************************************/
 /*************        Array of data structures      ******************/
 /*********************************************************************/
@@ -312,6 +241,8 @@ gal_data_array_free(gal_data_t *data, size_t num, int 
free_array);
 
 
 
+
+
 /*********************************************************************/
 /*************    Data structure as a linked list   ******************/
 /*********************************************************************/
@@ -340,6 +271,8 @@ gal_data_free_ll(gal_data_t *list);
 
 
 
+
+
 /*************************************************************
  **************            Copying             ***************
  *************************************************************/
@@ -364,6 +297,8 @@ gal_data_copy_element_same_type(gal_data_t *input, size_t 
index, void *ptr);
 
 
 
+
+
 /*************************************************************
  **************              Write             ***************
  *************************************************************/
@@ -372,6 +307,8 @@ gal_data_write_to_string(void *ptr, uint8_t type, int 
quote_if_str_has_space);
 
 
 
+
+
 /*************************************************************
  **************              Read              ***************
  *************************************************************/
diff --git a/lib/gnuastro/dimension.h b/lib/gnuastro/dimension.h
index 95e6908..6bd4b8c 100644
--- a/lib/gnuastro/dimension.h
+++ b/lib/gnuastro/dimension.h
@@ -96,7 +96,7 @@ gal_dimension_dist_manhattan(size_t *a, size_t *b, size_t 
ndim);
    -------
 
    This macro will allow you to do a fixed operation on the neighbors of an
-   eleemnt. The identifier for the element is its dimension-agnostic index
+   element. The identifier for the element is its dimension-agnostic index
    (distance from start of array). It is defined as a macro (and not a
    function) it is often necessary to loop over a very large number of
    pixels/indexs and the number of neighbors differs (in different
@@ -160,7 +160,9 @@ gal_dimension_dist_manhattan(size_t *a, size_t *b, size_t 
ndim);
                 that is defined by this macro and will have the index of
                 each neighbor. You can use this `nind' for any processing
                 that you like on the neighbor. Note that `op' will be
-                repeated the number of times there is a neighbor.
+                repeated the number of times there is a neighbor. If you
+                want to stop parsing the neighbors, set the `stop' variable
+                to 1.
 
 
    Implementation
diff --git a/lib/gnuastro/tile.h b/lib/gnuastro/tile.h
index 505fb6a..1db7e26 100644
--- a/lib/gnuastro/tile.h
+++ b/lib/gnuastro/tile.h
@@ -218,39 +218,42 @@ gal_tile_full_free_contents(struct 
gal_tile_two_layer_params *tl);
 #define GAL_TILE_PO_OSET(OT, OP, IN, OUT, PARSE_OUT, CHECK_BLANK) {     \
   switch(iblock->type)                                                  \
     {                                                                   \
-    case GAL_DATA_TYPE_UINT8:                                           \
+    case GAL_TYPE_UINT8:                                                \
       GAL_TILE_PO_OISET(uint8_t,  OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_INT8:                                            \
+    case GAL_TYPE_INT8:                                                 \
       GAL_TILE_PO_OISET(int8_t,   OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_UINT16:                                          \
+    case GAL_TYPE_UINT16:                                               \
       GAL_TILE_PO_OISET(uint16_t, OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_INT16:                                           \
+    case GAL_TYPE_INT16:                                                \
       GAL_TILE_PO_OISET(int16_t,  OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_UINT32:                                          \
+    case GAL_TYPE_UINT32:                                               \
       GAL_TILE_PO_OISET(uint32_t, OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_INT32:                                           \
+    case GAL_TYPE_INT32:                                                \
       GAL_TILE_PO_OISET(int32_t,  OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_UINT64:                                          \
+    case GAL_TYPE_UINT64:                                               \
       GAL_TILE_PO_OISET(uint64_t, OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_INT64:                                           \
+    case GAL_TYPE_INT64:                                                \
       GAL_TILE_PO_OISET(int64_t,  OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT32:                                         \
+    case GAL_TYPE_FLOAT32:                                              \
       GAL_TILE_PO_OISET(float,    OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
-    case GAL_DATA_TYPE_FLOAT64:                                         \
+    case GAL_TYPE_FLOAT64:                                              \
       GAL_TILE_PO_OISET(double,   OT,OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
       break;                                                            \
     default:                                                            \
-      error(EXIT_FAILURE, 0, "type code %d not recognized in "          \
-            "`GAL_TILE_PO_OSET'", iblock->type);                        \
+      {                                                                 \
+        fprintf(stderr, "type code %d not recognized in "               \
+              "`GAL_TILE_PO_OSET'", iblock->type);                      \
+        exit(EXIT_FAILURE);                                             \
+      }                                                                 \
     }                                                                   \
   }
 
@@ -278,7 +281,7 @@ gal_tile_full_free_contents(struct 
gal_tile_two_layer_params *tl);
              memory.
 
        `OUT': Output `gal_data_t'. It can be NULL. In that case, `o' will
-             be NULL and should not be used.
+             be NULL and should not be used. If given,
 
        `PARSE_OUT': Parse the output along with the input. When this is
              non-zero, then the `o' pointer (described in `OP') will be
@@ -308,49 +311,56 @@ gal_tile_full_free_contents(struct 
gal_tile_two_layer_params *tl);
                                                                         \
     /* A small sanity check. */                                         \
     if( parse_out && gal_data_dsize_is_different(iblock, oblock) )      \
-      error(EXIT_FAILURE, 0, "when `PARSE_OUT' is non-zero, the "       \
-            "allocated block size of the input and output of "          \
-            "`GAL_TILE_PARSE_OPERATE' must be equal, but they are "     \
-            "not: %zu and %zu elements respectively)", iblock->size,    \
-            oblock->size);                                              \
+      {                                                                 \
+        /* The `error' function, is a GNU extension. */                 \
+        fprintf(stderr, "when `PARSE_OUT' is non-zero, the "            \
+                "allocated block size of the input and output of "      \
+                "`GAL_TILE_PARSE_OPERATE' must be equal, but they are " \
+                "not: %zu and %zu elements respectively)",              \
+                iblock->size, oblock->size);                            \
+        exit(EXIT_FAILURE);                                             \
+      }                                                                 \
                                                                         \
     /* First set the OUTPUT type. */                                    \
     if(OUT)                                                             \
       switch(oblock->type)                                              \
         {                                                               \
-        case GAL_DATA_TYPE_UINT8:                                       \
+        case GAL_TYPE_UINT8:                                            \
           GAL_TILE_PO_OSET(uint8_t,  OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_INT8:                                        \
+        case GAL_TYPE_INT8:                                             \
           GAL_TILE_PO_OSET(int8_t,   OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_UINT16:                                      \
+        case GAL_TYPE_UINT16:                                           \
           GAL_TILE_PO_OSET(uint16_t, OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_INT16:                                       \
+        case GAL_TYPE_INT16:                                            \
           GAL_TILE_PO_OSET(int16_t,  OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_UINT32:                                      \
+        case GAL_TYPE_UINT32:                                           \
           GAL_TILE_PO_OSET(uint32_t, OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_INT32:                                       \
+        case GAL_TYPE_INT32:                                            \
           GAL_TILE_PO_OSET(int32_t,  OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_UINT64:                                      \
+        case GAL_TYPE_UINT64:                                           \
           GAL_TILE_PO_OSET(uint64_t, OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_INT64:                                       \
+        case GAL_TYPE_INT64:                                            \
           GAL_TILE_PO_OSET(int64_t,  OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_FLOAT32:                                     \
+        case GAL_TYPE_FLOAT32:                                          \
           GAL_TILE_PO_OSET(float,    OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
-        case GAL_DATA_TYPE_FLOAT64:                                     \
+        case GAL_TYPE_FLOAT64:                                          \
           GAL_TILE_PO_OSET(double,   OP,IN,OUT,PARSE_OUT,CHECK_BLANK);  \
           break;                                                        \
         default:                                                        \
-          error(EXIT_FAILURE, 0, "type code %d not recognized in "      \
-                "`GAL_TILE_PARSE_OPERATE'", oblock->type);              \
+          {                                                             \
+            fprintf(stderr, "type code %d not recognized in "           \
+                    "`GAL_TILE_PARSE_OPERATE'", oblock->type);          \
+            exit(EXIT_FAILURE);                                         \
+          }                                                             \
         }                                                               \
     else                                                                \
       /* When `OUT==NULL', its type is irrelevant, we'll just use */    \
diff --git a/lib/gnuastro/type.h b/lib/gnuastro/type.h
new file mode 100644
index 0000000..f3b6fa2
--- /dev/null
+++ b/lib/gnuastro/type.h
@@ -0,0 +1,134 @@
+/*********************************************************************
+Type -- Type information and basic operations.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+Copyright (C) 2015, 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/>.
+**********************************************************************/
+#ifndef __GAL_TYPE_H__
+#define __GAL_TYPE_H__
+
+#include <limits.h>
+#include <stdint.h>
+
+#include <gsl/gsl_complex.h>
+
+/* When we are within Gnuastro's building process, `IN_GNUASTRO_BUILD' is
+   defined. In the build process, installation information (in particular
+   `GAL_CONFIG_SIZEOF_SIZE_T' that we need below) is kept in
+   `config.h'. When building a user's programs, this information is kept in
+   `gnuastro/config.h'. Note that all `.c' files in Gnuastro's source must
+   start with the inclusion of `config.h' and that `gnuastro/config.h' is
+   only created at installation time (not present during the building of
+   Gnuastro).*/
+#ifndef IN_GNUASTRO_BUILD
+#include <gnuastro/config.h>
+#endif
+
+
+
+/* C++ Preparations */
+#undef __BEGIN_C_DECLS
+#undef __END_C_DECLS
+#ifdef __cplusplus
+# define __BEGIN_C_DECLS extern "C" {
+# define __END_C_DECLS }
+#else
+# define __BEGIN_C_DECLS                /* empty */
+# define __END_C_DECLS                  /* empty */
+#endif
+/* End of C++ preparations */
+
+
+
+/* Actual header contants (the above were for the Pre-processor). */
+__BEGIN_C_DECLS  /* From C++ preparations */
+
+
+
+
+
+/*************************************************************
+ **************           Constants            ***************
+ *************************************************************/
+/* Macros to identify the type of data. */
+enum gal_types
+{
+  GAL_TYPE_INVALID,         /* Invalid (=0 by C standard).             */
+
+  GAL_TYPE_BIT,             /* 1 bit                                   */
+  GAL_TYPE_UINT8,           /* 8-bit  unsigned integer.                */
+  GAL_TYPE_INT8,            /* 8-bit  signed   integer.                */
+  GAL_TYPE_UINT16,          /* 16-bit unsigned integer.                */
+  GAL_TYPE_INT16,           /* 16-bit signed   integer.                */
+  GAL_TYPE_UINT32,          /* 32-bit unsigned integer.                */
+  GAL_TYPE_INT32,           /* 32-bit signed   integer.                */
+  GAL_TYPE_UINT64,          /* 64-bit unsigned integer.                */
+  GAL_TYPE_INT64,           /* 64-bit signed   integer.                */
+  GAL_TYPE_FLOAT32,         /* 32-bit single precision floating point. */
+  GAL_TYPE_FLOAT64,         /* 64-bit double precision floating point. */
+  GAL_TYPE_COMPLEX32,       /* Complex 32-bit floating point.          */
+  GAL_TYPE_COMPLEX64,       /* Complex 64-bit floating point.          */
+  GAL_TYPE_STRING,          /* String of characters.                   */
+  GAL_TYPE_STRLL,           /* Linked list of strings.                 */
+};
+
+/* `size_t' is 4 and 8 bytes on 32 and 64 bit systems respectively. In both
+   cases, the standard defines `size_t' to be unsigned. During
+   `./configure' the sizeof size_t was found and is stored in
+   `GAL_CONFIG_SIZEOF_SIZE_T'. */
+#if GAL_CONFIG_SIZEOF_SIZE_T == 4
+#define GAL_TYPE_SIZE_T GAL_TYPE_UINT32
+#else
+#define GAL_TYPE_SIZE_T GAL_TYPE_UINT64
+#endif
+
+
+
+
+
+/*************************************************************
+ **************           Functions            ***************
+ *************************************************************/
+size_t
+gal_type_sizeof(uint8_t type);
+
+char *
+gal_type_to_string(uint8_t type, int long_name);
+
+uint8_t
+gal_type_from_string(char *str);
+
+void
+gal_type_min(uint8_t type, void *in);
+
+void
+gal_type_max(uint8_t type, void *in);
+
+int
+gal_type_is_linked_list(uint8_t type);
+
+int
+gal_type_out(int first_type, int second_type);
+
+
+
+
+__END_C_DECLS    /* From C++ preparations */
+
+#endif           /* __GAL_TYPE_H__ */
diff --git a/lib/interpolate.c b/lib/interpolate.c
index b963173..8323ff9 100644
--- a/lib/interpolate.c
+++ b/lib/interpolate.c
@@ -92,9 +92,9 @@ interpolate_close_neighbors_on_thread(void *in_prm)
   size_t ngb_counter, dist, pind, *dinc;
   size_t i, index, fullind, chstart=0, ndim=input->ndim;
   gal_data_t *median, *tin, *tout, *tnear, *nearest=NULL;
+  size_t *icoord=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
+  size_t *ncoord=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
   size_t size = (correct_index ? tl->tottilesinch : input->size);
-  size_t *icoord=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
-  size_t *ncoord=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
   size_t *dsize = (correct_index ? tl->numtilesinch : input->dsize);
   uint8_t *fullflag=&prm->thread_flags[tprm->id*input->size], *flag=fullflag;
 
@@ -138,7 +138,7 @@ interpolate_close_neighbors_on_thread(void *in_prm)
             {
               memcpy(gal_data_ptr_increment(tout->array, fullind, tin->type),
                      gal_data_ptr_increment(tin->array,  fullind, tin->type),
-                     gal_data_sizeof(tin->type));
+                     gal_type_sizeof(tin->type));
               tin=tin->next;
             }
           continue;
@@ -161,8 +161,7 @@ interpolate_close_neighbors_on_thread(void *in_prm)
           chstart = (fullind / tl->tottilesinch) * tl->tottilesinch;
 
           /* Set the channel's starting pointer for the flags. */
-          flag = gal_data_ptr_increment(fullflag, chstart,
-                                        GAL_DATA_TYPE_UINT8);
+          flag = gal_data_ptr_increment(fullflag, chstart, GAL_TYPE_UINT8);
         }
       else
         {
@@ -203,7 +202,7 @@ interpolate_close_neighbors_on_thread(void *in_prm)
                                                 tin->type),
                          gal_data_ptr_increment(tin->array, chstart+pind,
                                                 tin->type),
-                         gal_data_sizeof(tin->type));
+                         gal_type_sizeof(tin->type));
                   tin=tin->next;
                 }
 
@@ -252,7 +251,7 @@ interpolate_close_neighbors_on_thread(void *in_prm)
           /* Find the median and copy it. */
           median=gal_statistics_median(tnear, 1);
           memcpy(gal_data_ptr_increment(tout->array, fullind, tout->type),
-                 median->array, gal_data_sizeof(tout->type));
+                 median->array, gal_type_sizeof(tout->type));
 
           /* Clean up and go to next array. */
           gal_data_free(median);
@@ -366,7 +365,7 @@ gal_interpolate_close_neighbors(gal_data_t *input,
 
   /* Allocate space for all the flag values of all the threads here (memory
      in each thread is limited) and this is cleaner. */
-  prm.thread_flags=gal_data_malloc_array(GAL_DATA_TYPE_UINT8,
+  prm.thread_flags=gal_data_malloc_array(GAL_TYPE_UINT8,
                                          numthreads*input->size);
 
 
diff --git a/lib/options.c b/lib/options.c
index 4ceab43..8e634ec 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -248,7 +248,7 @@ gal_options_parse_list_of_numbers(char *string, char 
*filename, size_t lineno)
 
   /* Allocate the output data structure and fill it up. */
   i=num;
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &num, NULL, 0,
+  out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &num, NULL, 0,
                      minmapsize, NULL, NULL, NULL);
   for(tdll=list;tdll!=NULL;tdll=tdll->next)
     ((double *)(out->array))[--i]=tdll->v;
@@ -403,7 +403,7 @@ gal_options_read_type(struct argp_option *option, char *arg,
       /* Note that `gal_data_type_as_string' returns a static string. But
          the output must be an allocated string so we can free it. */
       gal_checkset_allocate_copy(
-           gal_data_type_as_string( *(uint8_t *)(option->value), 1), &str);
+           gal_type_to_string( *(uint8_t *)(option->value), 1), &str);
       return str;
     }
   else
@@ -412,8 +412,8 @@ gal_options_read_type(struct argp_option *option, char *arg,
       if(option->set) return NULL;
 
       /* Read the value. */
-      if ( (*(uint8_t *)(option->value) = gal_data_string_as_type(arg) )
-           == GAL_DATA_TYPE_INVALID )
+      if ( (*(uint8_t *)(option->value) = gal_type_from_string(arg) )
+           == GAL_TYPE_INVALID )
         error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to "
                       "`%s' option) couldn't be recognized as a known "
                       "type.\n\nFor the full list of known types, please "
@@ -579,7 +579,7 @@ gal_options_parse_sizes_reverse(struct argp_option *option, 
char *arg,
       /* Write the values into an allocated size_t array and finish it with
          a `-1' so the total number can be found later.*/
       num=values->size;
-      array=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, num+1);
+      array=gal_data_malloc_array(GAL_TYPE_SIZE_T, num+1);
       for(i=0;i<num;++i) array[num-1-i]=v[i];
       array[num] = (size_t)(-1);
 
@@ -710,8 +710,8 @@ options_sanity_check(struct argp_option *option, char *arg,
   /* Currently, this function is only for numeric types, so if the value is
      string type, or its `range' field is `GAL_OPTIONS_RANGE_ANY', then
      just return without any checks. */
-  if( option->type==GAL_DATA_TYPE_STRING
-      || option->type==GAL_DATA_TYPE_STRLL
+  if( option->type==GAL_TYPE_STRING
+      || option->type==GAL_TYPE_STRLL
       || option->range==GAL_OPTIONS_RANGE_ANY )
     return;
 
@@ -725,7 +725,7 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GT_0:
       message="greater than zero";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       operator1=GAL_ARITHMETIC_OP_GT;
@@ -735,7 +735,7 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GE_0:
       message="greater or equal to zero";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       operator1=GAL_ARITHMETIC_OP_GE;
@@ -745,9 +745,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_0_OR_1:
       message="either 0 or 1";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=1;
@@ -760,9 +760,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GE_0_LE_1:
       message="between zero and one (inclusive)";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=1;
@@ -773,11 +773,26 @@ options_sanity_check(struct argp_option *option, char 
*arg,
       break;
 
 
+    case GAL_OPTIONS_RANGE_GE_0_LT_1:
+      message="between zero (inclusive) and one (exclusive)";
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
+                          0, -1, NULL, NULL, NULL);
+      *(unsigned char *)(ref1->array)=0;
+      *(unsigned char *)(ref2->array)=1;
+
+      operator1=GAL_ARITHMETIC_OP_GE;
+      operator2=GAL_ARITHMETIC_OP_LT;
+      multicheckop=GAL_ARITHMETIC_OP_AND;
+      break;
+
+
     case GAL_OPTIONS_RANGE_GT_0_LT_1:
       message="between zero and one (not inclusive)";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=1;
@@ -790,9 +805,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_GT_0_ODD:
       message="greater than zero and odd";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=2;
@@ -804,9 +819,9 @@ options_sanity_check(struct argp_option *option, char *arg,
 
     case GAL_OPTIONS_RANGE_0_OR_ODD:
       message="greater than, or equal to, zero and odd";
-      ref1=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref1=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
-      ref2=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT8, 1, &dsize, NULL,
+      ref2=gal_data_alloc(NULL, GAL_TYPE_UINT8, 1, &dsize, NULL,
                           0, -1, NULL, NULL, NULL);
       *(unsigned char *)(ref1->array)=0;
       *(unsigned char *)(ref2->array)=2;
@@ -893,7 +908,7 @@ gal_options_read_check(struct argp_option *option, char 
*arg, char *filename,
      command-line can have a NULL arg value). */
   if(arg)
     {
-      if(option->type==GAL_DATA_TYPE_STRLL)
+      if(option->type==GAL_TYPE_STRLL)
         gal_linkedlist_add_to_stll(option->value, arg, 1);
       else
         {
@@ -938,8 +953,8 @@ gal_options_read_check(struct argp_option *option, char 
*arg, char *filename,
               "type `%s' to be read in `gal_options_read_from_key'. "
               "However, the `%s' option has type %s",
               PACKAGE_BUGREPORT,
-              gal_data_type_as_string(GAL_OPTIONS_NO_ARG_TYPE, 1),
-              option->name, gal_data_type_as_string(option->type, 1));
+              gal_type_to_string(GAL_OPTIONS_NO_ARG_TYPE, 1),
+              option->name, gal_type_to_string(option->type, 1));
     }
 
 
@@ -996,7 +1011,7 @@ gal_options_set_from_key(int key, char *arg, struct 
argp_option *options,
              As a result, only when searching for options on the
              command-line, a second value to the same option will replace
              the first one. This will not happen in configuration files. */
-          if(options[i].set && gal_data_is_linked_list(options[i].type)==0)
+          if(options[i].set && gal_type_is_linked_list(options[i].type)==0)
             options[i].set=GAL_OPTIONS_NOT_SET;
 
           /* Parse the value. */
@@ -1174,7 +1189,7 @@ options_set_from_name(char *name, char *arg,  struct 
argp_option *options,
                  list. */
           if( options[i].flags==OPTION_HIDDEN
               || ( options[i].set
-                   && !gal_data_is_linked_list(options[i].type ) ) )
+                   && !gal_type_is_linked_list(options[i].type ) ) )
             return 0;
 
           /* Read the value into the option and do a sanity check. */
@@ -1334,7 +1349,7 @@ gal_options_parse_config_files(struct 
gal_options_common_params *cp)
 
   /* A small sanity check because in multiple places, we have assumed the
      on/off options have a type of `unsigned char'. */
-  if(GAL_OPTIONS_NO_ARG_TYPE != GAL_DATA_TYPE_UINT8)
+  if(GAL_OPTIONS_NO_ARG_TYPE != GAL_TYPE_UINT8)
     error(EXIT_FAILURE, 0, "A bug! Please contact us at %s so we can fix the "
           "problem. The `GAL_OPTIONS_NO_ARG_TYPE' must have the "
           "`unsigned char' type. But",
@@ -1390,7 +1405,7 @@ options_reverse_lists_check_mandatory(struct 
gal_options_common_params *cp,
       if(options[i].set)
         switch(options[i].type)
           {
-          case GAL_DATA_TYPE_STRLL:
+          case GAL_TYPE_STRLL:
             gal_linkedlist_reverse_stll(
                   (struct gal_linkedlist_stll **)(options[i].value) );
             break;
@@ -1457,7 +1472,7 @@ option_is_printable(struct argp_option *option)
        - Options with an INVALID type are not to be printed (they are
          probably processed to a higher level value with functions). */
   if( (option->flags & OPTION_HIDDEN)
-      || option->type==GAL_DATA_TYPE_INVALID )
+      || option->type==GAL_TYPE_INVALID )
     return 0;
 
   /* Then check if it is a pre-program option. */
@@ -1522,14 +1537,14 @@ options_correct_max_lengths(struct argp_option *option, 
int *max_nlen,
 
   /* Invalid types are set for functions that don't save the raw user
      input, but do higher-level analysis on them for storing. */
-  if(option->type==GAL_DATA_TYPE_INVALID) return;
+  if(option->type==GAL_TYPE_INVALID) return;
 
   /* Get the length of the value and save its length length if its
      larger than the widest value. */
-  if(gal_data_is_linked_list(option->type))
+  if(gal_type_is_linked_list(option->type))
     {
       /* A small sanity check. */
-      if(option->type!=GAL_DATA_TYPE_STRLL)
+      if(option->type!=GAL_TYPE_STRLL)
         error(EXIT_FAILURE, 0, "currently only string linked lists "
               "are acceptable for printing");
 
@@ -1538,7 +1553,7 @@ options_correct_max_lengths(struct argp_option *option, 
int *max_nlen,
           tmp!=NULL; tmp=tmp->next)
         {
           /* Get the length of this node: */
-          vlen=options_print_any_type(option, &tmp->v, GAL_DATA_TYPE_STRING,
+          vlen=options_print_any_type(option, &tmp->v, GAL_TYPE_STRING,
                                       0, NULL, cp);
 
           /* If its larger than the maximum length, then put it in. */
@@ -1656,13 +1671,13 @@ options_print_all_in_group(struct argp_option *options, 
int groupint,
         && option_is_printable(&options[i]) )  /* Is relevant for printing.*/
       {
         /* Linked lists */
-        if(gal_data_is_linked_list(options[i].type))
+        if(gal_type_is_linked_list(options[i].type))
           for(tmp=*(struct gal_linkedlist_stll **)(options[i].value);
               tmp!=NULL; tmp=tmp->next)
             {
               fprintf(fp, " %-*s ", namewidth, options[i].name);
               options_print_any_type(&options[i], &tmp->v,
-                                     GAL_DATA_TYPE_STRING, valuewidth,
+                                     GAL_TYPE_STRING, valuewidth,
                                      fp, cp);
               options_print_doc(fp, options[i].doc, namewidth+valuewidth);
             }
diff --git a/lib/options.h b/lib/options.h
index c6cf69f..b915c4f 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -38,7 +38,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Type for options that don't accept an argument/value. This macro is
    defined to help make the definition and processing of these options
    easier and less buggy. Please use this macro for such options. */
-#define GAL_OPTIONS_NO_ARG_TYPE GAL_DATA_TYPE_UINT8
+#define GAL_OPTIONS_NO_ARG_TYPE GAL_TYPE_UINT8
 
 
 
@@ -123,6 +123,7 @@ enum gal_options_range_values
   GAL_OPTIONS_RANGE_GE_0,
   GAL_OPTIONS_RANGE_0_OR_1,
   GAL_OPTIONS_RANGE_GE_0_LE_1,
+  GAL_OPTIONS_RANGE_GE_0_LT_1,
   GAL_OPTIONS_RANGE_GT_0_LT_1,
 
   GAL_OPTIONS_RANGE_GT_0_ODD,
diff --git a/lib/permutation.c b/lib/permutation.c
index 2675cb3..d3e532d 100644
--- a/lib/permutation.c
+++ b/lib/permutation.c
@@ -99,7 +99,7 @@ gal_permutation_apply(gal_data_t *input, size_t *permutation)
   if(permutation)
     {
       /* Necessary initializations. */
-      width=gal_data_sizeof(input->type);
+      width=gal_type_sizeof(input->type);
       tmp=gal_data_malloc_array(input->type, 1);
 
       /* Do the permutation. */
@@ -148,7 +148,7 @@ gal_permutation_apply_inverse(gal_data_t *input, size_t 
*permutation)
   if(permutation)
     {
       /* Initializations */
-      width=gal_data_sizeof(input->type);
+      width=gal_type_sizeof(input->type);
       tmp=gal_data_malloc_array(input->type, 1);
       ttmp=gal_data_malloc_array(input->type, 1);
 
diff --git a/lib/statistics.c b/lib/statistics.c
index 9a236f5..a7f1acf 100644
--- a/lib/statistics.c
+++ b/lib/statistics.c
@@ -58,7 +58,7 @@ gal_data_t *
 gal_statistics_number(gal_data_t *input)
 {
   size_t dsize=1;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_UINT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_UINT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
   /* If there is no blank values in the input, then the total number is
@@ -87,7 +87,7 @@ gal_statistics_minimum(gal_data_t *input)
                                  &dsize, NULL, 1, -1, NULL, NULL, NULL);
 
   /* Initialize the output with the maximum possible value. */
-  gal_data_type_max(out->type, out->array);
+  gal_type_max(out->type, out->array);
 
   /* Parse the full input. */
   GAL_TILE_PARSE_OPERATE({*o = *i < *o ? *i : *o; ++n;}, input, out, 0, 0);
@@ -112,7 +112,7 @@ gal_statistics_maximum(gal_data_t *input)
                                  &dsize, NULL, 1, -1, NULL, NULL, NULL);
 
   /* Initialize the output with the minimum possible value. */
-  gal_data_type_min(out->type, out->array);
+  gal_type_min(out->type, out->array);
 
   /* Parse the full input. */
   GAL_TILE_PARSE_OPERATE({*o = *i > *o ? *i : *o; ++n;}, input, out, 0, 0);
@@ -133,7 +133,7 @@ gal_data_t *
 gal_statistics_sum(gal_data_t *input)
 {
   size_t dsize=1, n=0;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
   /* Parse the dataset. Note that in `gal_data_alloc' we set the `clear'
@@ -156,7 +156,7 @@ gal_data_t *
 gal_statistics_mean(gal_data_t *input)
 {
   size_t dsize=1, n=0;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
   /* Parse the dataset. Note that in `gal_data_alloc' we set the `clear'
@@ -182,7 +182,7 @@ gal_statistics_std(gal_data_t *input)
 {
   size_t dsize=1, n=0;
   double s=0.0f, s2=0.0f;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
   /* Parse the input. */
@@ -205,7 +205,7 @@ gal_statistics_mean_std(gal_data_t *input)
 {
   size_t dsize=2, n=0;
   double s=0.0f, s2=0.0f;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
   /* Parse the input. */
@@ -235,16 +235,16 @@ statistics_median_in_sorted_no_blank(gal_data_t *sorted, 
void *median)
 
   switch(sorted->type)
     {
-    case GAL_DATA_TYPE_UINT8:     MED_IN_SORTED( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:      MED_IN_SORTED( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:    MED_IN_SORTED( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:     MED_IN_SORTED( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:    MED_IN_SORTED( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:     MED_IN_SORTED( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:    MED_IN_SORTED( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:     MED_IN_SORTED( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:   MED_IN_SORTED( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:   MED_IN_SORTED( double   );    break;
+    case GAL_TYPE_UINT8:     MED_IN_SORTED( uint8_t  );    break;
+    case GAL_TYPE_INT8:      MED_IN_SORTED( int8_t   );    break;
+    case GAL_TYPE_UINT16:    MED_IN_SORTED( uint16_t );    break;
+    case GAL_TYPE_INT16:     MED_IN_SORTED( int16_t  );    break;
+    case GAL_TYPE_UINT32:    MED_IN_SORTED( uint32_t );    break;
+    case GAL_TYPE_INT32:     MED_IN_SORTED( int32_t  );    break;
+    case GAL_TYPE_UINT64:    MED_IN_SORTED( uint64_t );    break;
+    case GAL_TYPE_INT64:     MED_IN_SORTED( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:   MED_IN_SORTED( float    );    break;
+    case GAL_TYPE_FLOAT64:   MED_IN_SORTED( double   );    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_statistics_median_in_sorted_no_blank'", sorted->type);
@@ -368,16 +368,16 @@ gal_statistics_quantile_function_index(gal_data_t *input, 
gal_data_t *value,
   /* Find the result: */
   switch(nbs->type)
     {
-    case GAL_DATA_TYPE_UINT8:     STATS_QFUNC( uint8_t  );     break;
-    case GAL_DATA_TYPE_INT8:      STATS_QFUNC( int8_t   );     break;
-    case GAL_DATA_TYPE_UINT16:    STATS_QFUNC( uint16_t );     break;
-    case GAL_DATA_TYPE_INT16:     STATS_QFUNC( int16_t  );     break;
-    case GAL_DATA_TYPE_UINT32:    STATS_QFUNC( uint32_t );     break;
-    case GAL_DATA_TYPE_INT32:     STATS_QFUNC( int32_t  );     break;
-    case GAL_DATA_TYPE_UINT64:    STATS_QFUNC( uint64_t );     break;
-    case GAL_DATA_TYPE_INT64:     STATS_QFUNC( int64_t  );     break;
-    case GAL_DATA_TYPE_FLOAT32:   STATS_QFUNC( float    );     break;
-    case GAL_DATA_TYPE_FLOAT64:   STATS_QFUNC( double   );     break;
+    case GAL_TYPE_UINT8:     STATS_QFUNC( uint8_t  );     break;
+    case GAL_TYPE_INT8:      STATS_QFUNC( int8_t   );     break;
+    case GAL_TYPE_UINT16:    STATS_QFUNC( uint16_t );     break;
+    case GAL_TYPE_INT16:     STATS_QFUNC( int16_t  );     break;
+    case GAL_TYPE_UINT32:    STATS_QFUNC( uint32_t );     break;
+    case GAL_TYPE_INT32:     STATS_QFUNC( int32_t  );     break;
+    case GAL_TYPE_UINT64:    STATS_QFUNC( uint64_t );     break;
+    case GAL_TYPE_INT64:     STATS_QFUNC( int64_t  );     break;
+    case GAL_TYPE_FLOAT32:   STATS_QFUNC( float    );     break;
+    case GAL_TYPE_FLOAT64:   STATS_QFUNC( double   );     break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_statistics_quantile_function'", nbs->type);
@@ -399,7 +399,7 @@ gal_statistics_quantile_function(gal_data_t *input, 
gal_data_t *value,
 {
   double *d;
   size_t dsize=1;
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
   size_t ind=gal_statistics_quantile_function_index(input, value, inplace);
 
@@ -452,7 +452,7 @@ struct statistics_mode_params
 
 /* Macros for the mode finding algorithm. */
 #define MODE_MIN_Q        0.01f  /* Mode search lower interval quantile.  */
-#define MODE_MAX_Q        0.90f  /* Mode search higher interval quantile. */
+#define MODE_MAX_Q        0.55f  /* Mode search higher interval quantile. */
 #define MODE_GOOD_LQ      0.02f  /* Least acceptable mode quantile.       */
 #define MODE_SYM_LOW_Q    0.01f  /* Lower quantile to get symmetricity.   */
 #define MODE_GOLDEN_RATIO 1.618034f /* Golden ratio: (1+sqrt(5))/2.       */
@@ -535,16 +535,16 @@ mode_mirror_max_index_diff(struct statistics_mode_params 
*p, size_t m)
          distribution. */
       switch(p->data->type)
         {
-        case GAL_DATA_TYPE_UINT8:     MIRR_MAX_DIFF( uint8_t  );   break;
-        case GAL_DATA_TYPE_INT8:      MIRR_MAX_DIFF( int8_t   );   break;
-        case GAL_DATA_TYPE_UINT16:    MIRR_MAX_DIFF( uint16_t );   break;
-        case GAL_DATA_TYPE_INT16:     MIRR_MAX_DIFF( int16_t  );   break;
-        case GAL_DATA_TYPE_UINT32:    MIRR_MAX_DIFF( uint32_t );   break;
-        case GAL_DATA_TYPE_INT32:     MIRR_MAX_DIFF( int32_t  );   break;
-        case GAL_DATA_TYPE_UINT64:    MIRR_MAX_DIFF( uint64_t );   break;
-        case GAL_DATA_TYPE_INT64:     MIRR_MAX_DIFF( int64_t  );   break;
-        case GAL_DATA_TYPE_FLOAT32:   MIRR_MAX_DIFF( float    );   break;
-        case GAL_DATA_TYPE_FLOAT64:   MIRR_MAX_DIFF( double   );   break;
+        case GAL_TYPE_UINT8:     MIRR_MAX_DIFF( uint8_t  );   break;
+        case GAL_TYPE_INT8:      MIRR_MAX_DIFF( int8_t   );   break;
+        case GAL_TYPE_UINT16:    MIRR_MAX_DIFF( uint16_t );   break;
+        case GAL_TYPE_INT16:     MIRR_MAX_DIFF( int16_t  );   break;
+        case GAL_TYPE_UINT32:    MIRR_MAX_DIFF( uint32_t );   break;
+        case GAL_TYPE_INT32:     MIRR_MAX_DIFF( int32_t  );   break;
+        case GAL_TYPE_UINT64:    MIRR_MAX_DIFF( uint64_t );   break;
+        case GAL_TYPE_INT64:     MIRR_MAX_DIFF( int64_t  );   break;
+        case GAL_TYPE_FLOAT32:   MIRR_MAX_DIFF( float    );   break;
+        case GAL_TYPE_FLOAT64:   MIRR_MAX_DIFF( double   );   break;
         default:
           error(EXIT_FAILURE, 0, "type code %d not recognized in "
                 "`mode_mirror_max_diff'", p->data->type);
@@ -773,16 +773,16 @@ mode_symmetricity(struct statistics_mode_params *p, 
size_t m, void *b_val)
   /* Do the process. */
   switch(p->data->type)
     {
-    case GAL_DATA_TYPE_UINT8:      MODE_SYM( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:       MODE_SYM( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:     MODE_SYM( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:      MODE_SYM( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:     MODE_SYM( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:      MODE_SYM( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:     MODE_SYM( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:      MODE_SYM( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:    MODE_SYM( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:    MODE_SYM( double   );    break;
+    case GAL_TYPE_UINT8:      MODE_SYM( uint8_t  );    break;
+    case GAL_TYPE_INT8:       MODE_SYM( int8_t   );    break;
+    case GAL_TYPE_UINT16:     MODE_SYM( uint16_t );    break;
+    case GAL_TYPE_INT16:      MODE_SYM( int16_t  );    break;
+    case GAL_TYPE_UINT32:     MODE_SYM( uint32_t );    break;
+    case GAL_TYPE_INT32:      MODE_SYM( int32_t  );    break;
+    case GAL_TYPE_UINT64:     MODE_SYM( uint64_t );    break;
+    case GAL_TYPE_INT64:      MODE_SYM( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:    MODE_SYM( float    );    break;
+    case GAL_TYPE_FLOAT64:    MODE_SYM( double   );    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`mode_symmetricity'", p->data->type);
@@ -832,7 +832,7 @@ gal_statistics_mode(gal_data_t *input, float mirrordist, 
int inplace)
                                   NULL, NULL, NULL);
   gal_data_t *b_val=gal_data_alloc(NULL, type, 1, &mdsize, NULL, 1, -1,
                                    NULL, NULL, NULL);
-  gal_data_t *out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &dsize,
+  gal_data_t *out=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &dsize,
                                  NULL, 1, -1, NULL, NULL, NULL);
 
 
@@ -878,7 +878,7 @@ gal_statistics_mode(gal_data_t *input, float mirrordist, 
int inplace)
   oa=out->array;
   modeindex = mode_golden_section(&p);
   gal_data_copy_element_same_type(p.data, modeindex, mode->array);
-  mode=gal_data_copy_to_new_type_free(mode, GAL_DATA_TYPE_FLOAT64);
+  mode=gal_data_copy_to_new_type_free(mode, GAL_TYPE_FLOAT64);
   gal_data_copy_element_same_type(mode, 0, &oa[0]);
 
 
@@ -891,7 +891,7 @@ gal_statistics_mode(gal_data_t *input, float mirrordist, 
int inplace)
      output values to NaN. */
   if(oa[2]>GAL_STATISTICS_MODE_GOOD_SYM)
     {
-      b_val=gal_data_copy_to_new_type_free(mode, GAL_DATA_TYPE_FLOAT64);
+      b_val=gal_data_copy_to_new_type_free(mode, GAL_TYPE_FLOAT64);
       gal_data_copy_element_same_type(b_val, 0, &oa[3]);
     }
   else oa[0]=oa[1]=oa[2]=oa[3]=NAN;
@@ -939,16 +939,16 @@ statistics_make_mirror(gal_data_t *noblank_sorted, size_t 
index,
   /* Fill in the mirror array. */
   switch(noblank_sorted->type)
     {
-    case GAL_DATA_TYPE_UINT8:     STATS_MKMIRROR( uint8_t  );     break;
-    case GAL_DATA_TYPE_INT8:      STATS_MKMIRROR( int8_t   );     break;
-    case GAL_DATA_TYPE_UINT16:    STATS_MKMIRROR( uint16_t );     break;
-    case GAL_DATA_TYPE_INT16:     STATS_MKMIRROR( int16_t  );     break;
-    case GAL_DATA_TYPE_UINT32:    STATS_MKMIRROR( uint32_t );     break;
-    case GAL_DATA_TYPE_INT32:     STATS_MKMIRROR( int32_t  );     break;
-    case GAL_DATA_TYPE_UINT64:    STATS_MKMIRROR( uint64_t );     break;
-    case GAL_DATA_TYPE_INT64:     STATS_MKMIRROR( int64_t  );     break;
-    case GAL_DATA_TYPE_FLOAT32:   STATS_MKMIRROR( float    );     break;
-    case GAL_DATA_TYPE_FLOAT64:   STATS_MKMIRROR( double   );     break;
+    case GAL_TYPE_UINT8:     STATS_MKMIRROR( uint8_t  );     break;
+    case GAL_TYPE_INT8:      STATS_MKMIRROR( int8_t   );     break;
+    case GAL_TYPE_UINT16:    STATS_MKMIRROR( uint16_t );     break;
+    case GAL_TYPE_INT16:     STATS_MKMIRROR( int16_t  );     break;
+    case GAL_TYPE_UINT32:    STATS_MKMIRROR( uint32_t );     break;
+    case GAL_TYPE_INT32:     STATS_MKMIRROR( int32_t  );     break;
+    case GAL_TYPE_UINT64:    STATS_MKMIRROR( uint64_t );     break;
+    case GAL_TYPE_INT64:     STATS_MKMIRROR( int64_t  );     break;
+    case GAL_TYPE_FLOAT32:   STATS_MKMIRROR( float    );     break;
+    case GAL_TYPE_FLOAT64:   STATS_MKMIRROR( double   );     break;
     }
 
   /* Return the mirrored distribution. */
@@ -1053,16 +1053,16 @@ gal_statistics_is_sorted(gal_data_t *data)
   /* Do the check. */
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:     IS_SORTED( uint8_t  );    break;
-    case GAL_DATA_TYPE_INT8:      IS_SORTED( int8_t   );    break;
-    case GAL_DATA_TYPE_UINT16:    IS_SORTED( uint16_t );    break;
-    case GAL_DATA_TYPE_INT16:     IS_SORTED( int16_t  );    break;
-    case GAL_DATA_TYPE_UINT32:    IS_SORTED( uint32_t );    break;
-    case GAL_DATA_TYPE_INT32:     IS_SORTED( int32_t  );    break;
-    case GAL_DATA_TYPE_UINT64:    IS_SORTED( uint64_t );    break;
-    case GAL_DATA_TYPE_INT64:     IS_SORTED( int64_t  );    break;
-    case GAL_DATA_TYPE_FLOAT32:   IS_SORTED( float    );    break;
-    case GAL_DATA_TYPE_FLOAT64:   IS_SORTED( double   );    break;
+    case GAL_TYPE_UINT8:     IS_SORTED( uint8_t  );    break;
+    case GAL_TYPE_INT8:      IS_SORTED( int8_t   );    break;
+    case GAL_TYPE_UINT16:    IS_SORTED( uint16_t );    break;
+    case GAL_TYPE_INT16:     IS_SORTED( int16_t  );    break;
+    case GAL_TYPE_UINT32:    IS_SORTED( uint32_t );    break;
+    case GAL_TYPE_INT32:     IS_SORTED( int32_t  );    break;
+    case GAL_TYPE_UINT64:    IS_SORTED( uint64_t );    break;
+    case GAL_TYPE_INT64:     IS_SORTED( int64_t  );    break;
+    case GAL_TYPE_FLOAT32:   IS_SORTED( float    );    break;
+    case GAL_TYPE_FLOAT64:   IS_SORTED( double   );    break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_statistics_is_sorted'", data->type);
@@ -1082,32 +1082,32 @@ gal_statistics_is_sorted(gal_data_t *data)
 /* This function is ignorant to blank values, if you want to make sure
    there is no blank values, you can call `gal_blank_remove' first. */
 #define STATISTICS_SORT(QSORT_F) {                                        \
-    qsort(data->array, data->size, gal_data_sizeof(data->type), QSORT_F); \
+    qsort(data->array, data->size, gal_type_sizeof(data->type), QSORT_F); \
   }
 void
 gal_statistics_sort_increasing(gal_data_t *data)
 {
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:
+    case GAL_TYPE_UINT8:
       STATISTICS_SORT(gal_qsort_uint8_increasing);    break;
-    case GAL_DATA_TYPE_INT8:
+    case GAL_TYPE_INT8:
       STATISTICS_SORT(gal_qsort_int8_increasing);     break;
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       STATISTICS_SORT(gal_qsort_uint16_increasing);   break;
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       STATISTICS_SORT(gal_qsort_int16_increasing);    break;
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       STATISTICS_SORT(gal_qsort_uint32_increasing);   break;
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       STATISTICS_SORT(gal_qsort_int32_increasing);    break;
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       STATISTICS_SORT(gal_qsort_uint64_increasing);   break;
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       STATISTICS_SORT(gal_qsort_int64_increasing);    break;
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       STATISTICS_SORT(gal_qsort_float32_increasing);  break;
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       STATISTICS_SORT(gal_qsort_float64_increasing);  break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
@@ -1125,25 +1125,25 @@ gal_statistics_sort_decreasing(gal_data_t *data)
 {
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:
+    case GAL_TYPE_UINT8:
       STATISTICS_SORT(gal_qsort_uint8_decreasing);    break;
-    case GAL_DATA_TYPE_INT8:
+    case GAL_TYPE_INT8:
       STATISTICS_SORT(gal_qsort_int8_decreasing);     break;
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       STATISTICS_SORT(gal_qsort_uint16_decreasing);   break;
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       STATISTICS_SORT(gal_qsort_int16_decreasing);    break;
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       STATISTICS_SORT(gal_qsort_uint32_decreasing);   break;
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       STATISTICS_SORT(gal_qsort_int32_decreasing);    break;
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       STATISTICS_SORT(gal_qsort_uint64_decreasing);   break;
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       STATISTICS_SORT(gal_qsort_int64_decreasing);    break;
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       STATISTICS_SORT(gal_qsort_float32_decreasing);  break;
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       STATISTICS_SORT(gal_qsort_float64_decreasing);  break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
@@ -1310,10 +1310,10 @@ gal_statistics_regular_bins(gal_data_t *data, 
gal_data_t *inrange,
   if(inrange && inrange->size)
     {
       /* Make sure we are dealing with a double type range. */
-      if(inrange->type==GAL_DATA_TYPE_FLOAT64)
+      if(inrange->type==GAL_TYPE_FLOAT64)
         range=inrange;
       else
-        range=gal_data_copy_to_new_type(inrange, GAL_DATA_TYPE_FLOAT64);
+        range=gal_data_copy_to_new_type(inrange, GAL_TYPE_FLOAT64);
 
       /* Set the minimum and maximum of the bins. */
       ra=range->array;
@@ -1326,7 +1326,7 @@ gal_statistics_regular_bins(gal_data_t *data, gal_data_t 
*inrange,
           if( isnan(ra[0]) )
             {
               tmp=gal_data_copy_to_new_type_free(gal_statistics_minimum(data),
-                                                 GAL_DATA_TYPE_FLOAT64);
+                                                 GAL_TYPE_FLOAT64);
               min=*((double *)(tmp->array));
               gal_data_free(tmp);
             }
@@ -1337,7 +1337,7 @@ gal_statistics_regular_bins(gal_data_t *data, gal_data_t 
*inrange,
           if( isnan(ra[1]) )
             {
               tmp=gal_data_copy_to_new_type_free(gal_statistics_maximum(data),
-                                                 GAL_DATA_TYPE_FLOAT64);
+                                                 GAL_TYPE_FLOAT64);
               max=*((double *)(tmp->array))+1e-6;
               gal_data_free(tmp);
             }
@@ -1351,18 +1351,18 @@ gal_statistics_regular_bins(gal_data_t *data, 
gal_data_t *inrange,
   else
     {
       tmp=gal_data_copy_to_new_type_free(gal_statistics_minimum(data),
-                                         GAL_DATA_TYPE_FLOAT64);
+                                         GAL_TYPE_FLOAT64);
       min=*((double *)(tmp->array));
       gal_data_free(tmp);
       tmp=gal_data_copy_to_new_type_free(gal_statistics_maximum(data),
-                                         GAL_DATA_TYPE_FLOAT64);
+                                         GAL_TYPE_FLOAT64);
       max=*((double *)(tmp->array)) + 1e-6;
       gal_data_free(tmp);
     }
 
 
   /* Allocate the space for the bins. */
-  bins=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT64, 1, &numbins, NULL,
+  bins=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &numbins, NULL,
                       0, data->minmapsize, "bin_center", data->unit,
                       "Center value of each bin.");
 
@@ -1447,7 +1447,7 @@ gal_statistics_histogram(gal_data_t *data, gal_data_t 
*bins, int normalize,
 
   /* Allocate the histogram (note that we are clearning it so all values
      are zero. */
-  hist=gal_data_alloc(NULL, GAL_DATA_TYPE_SIZE_T, bins->ndim, bins->dsize,
+  hist=gal_data_alloc(NULL, GAL_TYPE_SIZE_T, bins->ndim, bins->dsize,
                       NULL, 1, data->minmapsize, "hist_number", "counts",
                       "Number of data points within each bin.");
 
@@ -1463,16 +1463,16 @@ gal_statistics_histogram(gal_data_t *data, gal_data_t 
*bins, int normalize,
   h=hist->array;
   switch(data->type)
     {
-    case GAL_DATA_TYPE_UINT8:     HISTOGRAM_TYPESET(uint8_t);     break;
-    case GAL_DATA_TYPE_INT8:      HISTOGRAM_TYPESET(int8_t);      break;
-    case GAL_DATA_TYPE_UINT16:    HISTOGRAM_TYPESET(uint16_t);    break;
-    case GAL_DATA_TYPE_INT16:     HISTOGRAM_TYPESET(int16_t);     break;
-    case GAL_DATA_TYPE_UINT32:    HISTOGRAM_TYPESET(uint32_t);    break;
-    case GAL_DATA_TYPE_INT32:     HISTOGRAM_TYPESET(int32_t);     break;
-    case GAL_DATA_TYPE_UINT64:    HISTOGRAM_TYPESET(uint64_t);    break;
-    case GAL_DATA_TYPE_INT64:     HISTOGRAM_TYPESET(int64_t);     break;
-    case GAL_DATA_TYPE_FLOAT32:   HISTOGRAM_TYPESET(float);       break;
-    case GAL_DATA_TYPE_FLOAT64:   HISTOGRAM_TYPESET(double);      break;
+    case GAL_TYPE_UINT8:     HISTOGRAM_TYPESET(uint8_t);     break;
+    case GAL_TYPE_INT8:      HISTOGRAM_TYPESET(int8_t);      break;
+    case GAL_TYPE_UINT16:    HISTOGRAM_TYPESET(uint16_t);    break;
+    case GAL_TYPE_INT16:     HISTOGRAM_TYPESET(int16_t);     break;
+    case GAL_TYPE_UINT32:    HISTOGRAM_TYPESET(uint32_t);    break;
+    case GAL_TYPE_INT32:     HISTOGRAM_TYPESET(int32_t);     break;
+    case GAL_TYPE_UINT64:    HISTOGRAM_TYPESET(uint64_t);    break;
+    case GAL_TYPE_INT64:     HISTOGRAM_TYPESET(int64_t);     break;
+    case GAL_TYPE_FLOAT32:   HISTOGRAM_TYPESET(float);       break;
+    case GAL_TYPE_FLOAT64:   HISTOGRAM_TYPESET(double);      break;
     default:
       error(EXIT_FAILURE, 0, "type code %d not recognized in "
             "`gal_statistics_histogram'", data->type);
@@ -1492,7 +1492,7 @@ gal_statistics_histogram(gal_data_t *data, gal_data_t 
*bins, int normalize,
     {
       /* Set the reference. */
       ref=0.0f;
-      hist=gal_data_copy_to_new_type_free(hist, GAL_DATA_TYPE_FLOAT32);
+      hist=gal_data_copy_to_new_type_free(hist, GAL_TYPE_FLOAT32);
       ff=(f=hist->array)+hist->size; do ref += *f++;   while(f<ff);
 
       /* Correct the name, units and comments. */
@@ -1506,7 +1506,7 @@ gal_statistics_histogram(gal_data_t *data, gal_data_t 
*bins, int normalize,
     {
       /* Calculate the reference. */
       ref=-FLT_MAX;
-      hist=gal_data_copy_to_new_type_free(hist, GAL_DATA_TYPE_FLOAT32);
+      hist=gal_data_copy_to_new_type_free(hist, GAL_TYPE_FLOAT32);
       ff=(f=hist->array)+hist->size;
       do ref = *f>ref ? *f : ref; while(++f<ff);
 
@@ -1577,7 +1577,7 @@ gal_statistics_cfp(gal_data_t *data, gal_data_t *bins, 
int normalize)
      either normalized or its maximum was set to 1. We can only use it if
      it was normalized. If it isn't normalized, then we must ignore it and
      build the histogram here.*/
-  if(hist->type==GAL_DATA_TYPE_FLOAT32)
+  if(hist->type==GAL_TYPE_FLOAT32)
     {
       sum=0.0f;
       ff=(f=hist->array)+hist->size; do sum += *f++;   while(f<ff);
@@ -1589,11 +1589,11 @@ gal_statistics_cfp(gal_data_t *data, gal_data_t *bins, 
int normalize)
   /* Allocate the cumulative frequency plot's necessary space. */
   cfp=gal_data_alloc( NULL, hist->type, bins->ndim, bins->dsize,
                       NULL, 1, data->minmapsize,
-                      ( hist->type==GAL_DATA_TYPE_FLOAT32
+                      ( hist->type==GAL_TYPE_FLOAT32
                         ? "cfp_normalized" : "cfp_number" ),
-                      ( hist->type==GAL_DATA_TYPE_FLOAT32
+                      ( hist->type==GAL_TYPE_FLOAT32
                         ? "frac" : "count" ),
-                      ( hist->type==GAL_DATA_TYPE_FLOAT32
+                      ( hist->type==GAL_TYPE_FLOAT32
                         ? "Fraction of data elements from the start to this "
                         "bin (inclusive)."
                         : "Number of data elements from the start to this "
@@ -1603,12 +1603,12 @@ gal_statistics_cfp(gal_data_t *data, gal_data_t *bins, 
int normalize)
   /* Fill in the cumulative frequency plot. */
   switch(hist->type)
     {
-    case GAL_DATA_TYPE_SIZE_T:
+    case GAL_TYPE_SIZE_T:
       sums=0; hs=hist->array; sf=(s=cfp->array)+cfp->size;
       do sums = (*s += *hs++ + sums); while(++s<sf);
       break;
 
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       sum=0.0f; hf=hist->array; ff=(f=cfp->array)+cfp->size;
       do sum = (*f += *hf++ + sum);  while(++f<ff);
       break;
@@ -1621,12 +1621,12 @@ gal_statistics_cfp(gal_data_t *data, gal_data_t *bins, 
int normalize)
 
   /* Normalize the CFP if the user asked for it and it wasn't normalized
      until now. */
-  if(normalize && cfp->type==GAL_DATA_TYPE_SIZE_T)
+  if(normalize && cfp->type==GAL_TYPE_SIZE_T)
     {
       /* Find the sum, then divide the plot by it. Note that the sum must
          come from the histogram, not the CFP!*/
       sums=0;
-      cfp=gal_data_copy_to_new_type_free(cfp, GAL_DATA_TYPE_FLOAT32);
+      cfp=gal_data_copy_to_new_type_free(cfp, GAL_TYPE_FLOAT32);
       sf=(s=hist->array)+hist->size; do sums += *s++;   while(s<sf);
       ff=(f=cfp->array)+cfp->size;   do *f++ /= sums;   while(f<ff);
 
@@ -1741,7 +1741,7 @@ gal_statistics_sigma_clip(gal_data_t *input, float 
multip, float param,
 
 
   /* Allocate the necessary spaces. */
-  out=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, 1, &four, NULL, 0,
+  out=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, 1, &four, NULL, 0,
                      input->minmapsize, NULL, NULL, NULL);
   median_i=gal_data_alloc(NULL, type, 1, &one, NULL, 0, input->minmapsize,
                           NULL, NULL, NULL);
@@ -1762,7 +1762,7 @@ gal_statistics_sigma_clip(gal_data_t *input, float 
multip, float param,
     {
       /* Find the median. */
       statistics_median_in_sorted_no_blank(nbs, median_i->array);
-      median_d=gal_data_copy_to_new_type(median_i, GAL_DATA_TYPE_FLOAT64);
+      median_d=gal_data_copy_to_new_type(median_i, GAL_TYPE_FLOAT64);
 
       /* Find the average and Standard deviation, note that both `start'
          and `size' will be different in the next round. */
@@ -1793,16 +1793,16 @@ gal_statistics_sigma_clip(gal_data_t *input, float 
multip, float param,
          and size of the array. */
       switch(type)
         {
-        case GAL_DATA_TYPE_UINT8:     SIGCLIP( uint8_t  );   break;
-        case GAL_DATA_TYPE_INT8:      SIGCLIP( int8_t   );   break;
-        case GAL_DATA_TYPE_UINT16:    SIGCLIP( uint16_t );   break;
-        case GAL_DATA_TYPE_INT16:     SIGCLIP( int16_t  );   break;
-        case GAL_DATA_TYPE_UINT32:    SIGCLIP( uint32_t );   break;
-        case GAL_DATA_TYPE_INT32:     SIGCLIP( int32_t  );   break;
-        case GAL_DATA_TYPE_UINT64:    SIGCLIP( uint64_t );   break;
-        case GAL_DATA_TYPE_INT64:     SIGCLIP( int64_t  );   break;
-        case GAL_DATA_TYPE_FLOAT32:   SIGCLIP( float    );   break;
-        case GAL_DATA_TYPE_FLOAT64:   SIGCLIP( double   );   break;
+        case GAL_TYPE_UINT8:     SIGCLIP( uint8_t  );   break;
+        case GAL_TYPE_INT8:      SIGCLIP( int8_t   );   break;
+        case GAL_TYPE_UINT16:    SIGCLIP( uint16_t );   break;
+        case GAL_TYPE_INT16:     SIGCLIP( int16_t  );   break;
+        case GAL_TYPE_UINT32:    SIGCLIP( uint32_t );   break;
+        case GAL_TYPE_INT32:     SIGCLIP( int32_t  );   break;
+        case GAL_TYPE_UINT64:    SIGCLIP( uint64_t );   break;
+        case GAL_TYPE_INT64:     SIGCLIP( int64_t  );   break;
+        case GAL_TYPE_FLOAT32:   SIGCLIP( float    );   break;
+        case GAL_TYPE_FLOAT64:   SIGCLIP( double   );   break;
         default:
           error(EXIT_FAILURE, 0, "type code %d not recognized in "
                 "`gal_statistics_sigma_clip'", type);
diff --git a/lib/table.c b/lib/table.c
index eb8569f..6ca7f29 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -238,8 +238,8 @@ gal_table_print_info(gal_data_t *allcols, size_t numcols, 
size_t numrows)
       if(allcols[i].unit && strlen(allcols[i].unit)>uw)
         uw=strlen(allcols[i].unit);
       if(allcols[i].type
-         && strlen(gal_data_type_as_string(allcols[i].type, 1))>tw)
-        tw=strlen(gal_data_type_as_string(allcols[i].type, 1));
+         && strlen(gal_type_to_string(allcols[i].type, 1))>tw)
+        tw=strlen(gal_type_to_string(allcols[i].type, 1));
     }
 
   /* We want one column space between the columns for readability, not the
@@ -263,7 +263,7 @@ gal_table_print_info(gal_data_t *allcols, size_t numcols, 
size_t numrows)
       printf("%-*zu%-*s%-*s%-*s%s\n", Nw, i+1,
              nw, name ? name : GAL_BLANK_STRING ,
              uw, unit ? unit : GAL_BLANK_STRING ,
-             tw, gal_data_type_as_string(allcols[i].type, 1),
+             tw, gal_type_to_string(allcols[i].type, 1),
              comment ? comment : GAL_BLANK_STRING);
     }
 
@@ -313,7 +313,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
   fmt[0]=fmt[1]=lng[0]=lng[1]=lng[2]='\0';
   switch(col->type)
     {
-    case GAL_DATA_TYPE_BIT:
+    case GAL_TYPE_BIT:
       error(EXIT_FAILURE, 0, "printing of bit types is currently "
             "not supported");
       break;
@@ -321,7 +321,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
 
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
 
       /* Set the basic information. */
       fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 's' : 'A';
@@ -341,10 +341,10 @@ gal_table_col_print_info(gal_data_t *col, int 
tableformat, char *fmt,
 
 
 
-    case GAL_DATA_TYPE_UINT8:
-    case GAL_DATA_TYPE_UINT16:
-    case GAL_DATA_TYPE_UINT32:
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT8:
+    case GAL_TYPE_UINT16:
+    case GAL_TYPE_UINT32:
+    case GAL_TYPE_UINT64:
 
       /* For the FITS ASCII table, there is only one format for all
          integers.  */
@@ -360,7 +360,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
           }
 
       /* If we have a long type, then make changes. */
-      if(col->type==GAL_DATA_TYPE_UINT64)
+      if(col->type==GAL_TYPE_UINT64)
         {
           lng[0]='l';
           width=( col->disp_width<=0 ? GAL_TABLE_DEF_LINT_WIDTH
@@ -375,9 +375,9 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
 
-    case GAL_DATA_TYPE_INT8:
-    case GAL_DATA_TYPE_INT16:
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT8:
+    case GAL_TYPE_INT16:
+    case GAL_TYPE_INT32:
       fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'd' : 'I';
       width = ( col->disp_width<=0 ? GAL_TABLE_DEF_INT_WIDTH
                 : col->disp_width );
@@ -388,7 +388,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
 
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       lng[0] = 'l';
       fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'd' : 'I';
       width=( col->disp_width<=0 ? GAL_TABLE_DEF_LINT_WIDTH
@@ -400,8 +400,8 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 
 
     /* We need a default value (because in most cases, it won't be set. */
-    case GAL_DATA_TYPE_FLOAT32:
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT64:
       switch(col->disp_fmt)
         {
         case GAL_TABLE_DISPLAY_FMT_FLOAT:
@@ -414,7 +414,7 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
           fmt[0] = tableformat==GAL_TABLE_FORMAT_TXT ? 'g' : 'E'; break;
         }
       width = ( col->disp_width<=0
-                ? ( col->type==GAL_DATA_TYPE_FLOAT32
+                ? ( col->type==GAL_TYPE_FLOAT32
                     ? GAL_TABLE_DEF_FLT_WIDTH
                     : GAL_TABLE_DEF_DBL_WIDTH )
                 : col->disp_width );
@@ -445,6 +445,8 @@ gal_table_col_print_info(gal_data_t *col, int tableformat, 
char *fmt,
 void
 gal_table_read_blank(gal_data_t *col, char *blank)
 {
+  void *colarr=col->array;
+
   /* If there is nothing to use as blank, then don't continue, note that
      the column data structure was initialized to mean that there is no
      blank value. */
@@ -460,7 +462,7 @@ gal_table_read_blank(gal_data_t *col, char *blank)
      `gal_data_string_to_type' will return 0. In that case, we need to
      initialize the necessary paramters to read this data structure
      correctly. */
-  if( !gal_data_string_to_type(&(col->array), blank, col->type) )
+  if( !gal_data_string_to_type(&colarr, blank, col->type) )
     {
       errno=0;
       col->dsize=malloc(sizeof *col->dsize);
diff --git a/lib/tile.c b/lib/tile.c
index 3a6dd7c..d4671a9 100644
--- a/lib/tile.c
+++ b/lib/tile.c
@@ -61,7 +61,7 @@ gal_tile_start_coord(gal_data_t *tile, size_t *start_coord)
   /* If the input tile is actually the same as the block, then the start is
      at 0 (in all dimensions). */
   if(block==tile)
-    memset(start_coord, 0, ndim*gal_data_sizeof(GAL_DATA_TYPE_SIZE_T));
+    memset(start_coord, 0, ndim*gal_type_sizeof(GAL_TYPE_SIZE_T));
   else
     {
       /* Calculate the coordinates of the first pixel of the tile. */
@@ -136,8 +136,8 @@ gal_tile_start_end_ind_inclusive(gal_data_t *tile, 
gal_data_t *work,
 {
   gal_data_t *block=gal_tile_block(tile);
   size_t ndim=tile->ndim, *s, *e, *l, *sf;
-  size_t *start_coord = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
-  size_t *end_coord   = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  size_t *start_coord = gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
+  size_t *end_coord   = gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
 
 
   /* The starting index can be found from the distance of the `tile->array'
@@ -368,7 +368,7 @@ gal_tile_block_write_const_value(gal_data_t *tilevalues, 
gal_data_t *tilesll,
     {
       /* Set the pointer to use as input. */
       in=gal_data_ptr_increment(tilevalues->array, tile_ind++, type);;
-      GAL_TILE_PARSE_OPERATE({memcpy(o, in, gal_data_sizeof(type));},
+      GAL_TILE_PARSE_OPERATE({memcpy(o, in, gal_type_sizeof(type));},
                              tile, tofill, 1, 0);
     }
 
@@ -393,7 +393,7 @@ gal_tile_block_check_tiles(gal_data_t *tilesll)
   gal_data_t *ids, *out, *block=gal_tile_block(tilesll);
 
   /* Allocate the array to keep the IDs of each tile. */
-  ids=gal_data_alloc(NULL, GAL_DATA_TYPE_INT32, 1, &dsize,
+  ids=gal_data_alloc(NULL, GAL_TYPE_INT32, 1, &dsize,
                      NULL, 0, block->minmapsize, NULL, NULL, NULL);
 
   /* Put the IDs into the array. */
@@ -578,11 +578,11 @@ gal_tile_full(gal_data_t *input, size_t *regular,
 {
   size_t i, d, tind, numtiles, *start=NULL;
   gal_data_t *tiles, *block=gal_tile_block(input);
-  size_t *last   = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-  size_t *first  = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-  size_t *coord  = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-  size_t *tcoord = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-  size_t *tsize  = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim+1);
+  size_t *last   = gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim);
+  size_t *first  = gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim);
+  size_t *coord  = gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim);
+  size_t *tcoord = gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim);
+  size_t *tsize  = gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim+1);
 
 
   /* Set the first tile size and total number of tiles along each
@@ -602,7 +602,7 @@ gal_tile_full(gal_data_t *input, size_t *regular,
      the block's dimensions when calculating the position of this block. */
   if(input->block)
     {
-      start=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
+      start=gal_data_malloc_array(GAL_TYPE_SIZE_T, input->ndim);
       gal_tile_start_coord(input, start);
     }
 
@@ -646,7 +646,7 @@ gal_tile_full(gal_data_t *input, size_t *regular,
       tiles[i].size=1;
       tiles[i].ndim=input->ndim;
       tiles[i].minmapsize=input->minmapsize;
-      tiles[i].dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T,input->ndim);
+      tiles[i].dsize=gal_data_malloc_array(GAL_TYPE_SIZE_T,input->ndim);
       for(d=0;d<input->ndim;++d)
         {
           /* The size of the first and last tiles can be different from the
@@ -741,7 +741,7 @@ gal_tile_full_sanity_check(char *filename, char *hdu, 
gal_data_t *input,
 
 
   /* Allocate space for the channel sizes. */
-  tl->channelsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  tl->channelsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
 
 
   /* Check if the channels are exactly divisible by the input's size along
@@ -837,7 +837,7 @@ gal_tile_full_two_layers(gal_data_t *input,
   /* Multiply the number of tiles along each dimension OF ONE CHANNEL by
      the number of channels in each dimension to get the dimensionality of
      the full tile structure. */
-  tl->numtiles = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  tl->numtiles = gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
   for(i=0;i<ndim;++i)
     tl->numtiles[i] = tl->numtilesinch[i] * tl->numchannels[i];
   tl->tottiles = gal_dimension_total_size(ndim, tl->numtiles);
@@ -915,9 +915,9 @@ gal_tile_full_permutation(struct gal_tile_two_layer_params 
*tl)
   if( ndim==1 || tl->totchannels==1) return;
 
   /* Allocate the space for the permutation and coordinates. */
-  ch_coord=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
-  tinch_coord=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
-  tl->permutation=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, tl->tottiles);
+  ch_coord=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
+  tinch_coord=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
+  tl->permutation=gal_data_malloc_array(GAL_TYPE_SIZE_T, tl->tottiles);
 
   /* Fill in the permutation, we use the fact that the tiles are filled
      from the first channel to the last. */
@@ -1016,12 +1016,12 @@ gal_tile_full_values_smooth(gal_data_t *tilevalues,
 
 
   /* Prepare the kernel size along every dimension. */
-  kdsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, tl->ndim);
+  kdsize=gal_data_malloc_array(GAL_TYPE_SIZE_T, tl->ndim);
   for(i=0;i<tl->ndim;++i) kdsize[i]=width;
 
 
   /* Make the kernel. */
-  kernel=gal_data_alloc(NULL, GAL_DATA_TYPE_FLOAT32, tilevalues->ndim,
+  kernel=gal_data_alloc(NULL, GAL_TYPE_FLOAT32, tilevalues->ndim,
                         kdsize, NULL, 0, -1, NULL, NULL, NULL);
   knum=gal_dimension_total_size(tl->ndim, kernel->dsize);
   for(i=0;i<knum;++i) ((float *)(kernel->array))[i]=1/((double)knum);
diff --git a/lib/timing.c b/lib/timing.c
index 3517be0..970461e 100644
--- a/lib/timing.c
+++ b/lib/timing.c
@@ -51,7 +51,7 @@ gal_timing_report(struct timeval *t1, char *jobname, size_t 
level)
   double dt=1e30;
   struct timeval t2;
 
-  if(level<2 && t1)
+  if(t1)
     {
       gettimeofday(&t2, NULL);
 
@@ -64,11 +64,15 @@ gal_timing_report(struct timeval *t1, char *jobname, size_t 
level)
   else if(level==1)
     {
       if(t1)
-        printf("  - %-"GAL_TIMING_VERB_MSG_LENGTH_T"s %f seconds\n",
-               jobname, dt);
-      else
-        printf("  - %-"GAL_TIMING_VERB_MSG_LENGTH_T"s\n", jobname);
+        printf("  - %-*s %f seconds\n",
+               GAL_TIMING_VERB_MSG_LENGTH_V, jobname, dt);
+      else printf("  - %s\n", jobname);
     }
   else if(level==2)
-    printf("  ---- %s\n", jobname);
+    {
+      if(t1)
+        printf("  ---- %-*s %f seconds\n",
+               GAL_TIMING_VERB_MSG_LENGTH_V-3, jobname, dt);
+      else printf("  ---- %s\n", jobname);
+    }
 }
diff --git a/lib/timing.h b/lib/timing.h
index b37b18f..6ea3714 100644
--- a/lib/timing.h
+++ b/lib/timing.h
@@ -49,10 +49,8 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
-#define GAL_TIMING_VERB_MSG_LENGTH_V     45
-#define GAL_TIMING_VERB_MSG_LENGTH_T    "45"
+#define GAL_TIMING_VERB_MSG_LENGTH_V     50
 #define GAL_TIMING_VERB_MSG_LENGTHS_2_V  65
-#define GAL_TIMING_VERB_MSG_LENGTHS_2_T "65"
 
 int64_t
 gal_timing_time_based_rng_seed();
diff --git a/lib/txt.c b/lib/txt.c
index 9c83afd..3d50116 100644
--- a/lib/txt.c
+++ b/lib/txt.c
@@ -157,7 +157,7 @@ txt_info_from_comment(char *line, gal_data_t **datall, char 
*comm_start)
   gal_data_t *tmp;
   int index, strw=0;
   size_t len=strlen(comm_start);
-  int type=GAL_DATA_TYPE_FLOAT64;                     /* Default type. */
+  int type=GAL_TYPE_FLOAT64;                     /* Default type. */
   char *number=NULL, *name=NULL, *comment=NULL;
   char *inbrackets=NULL, *unit=NULL, *typestr=NULL, *blank=NULL;
 
@@ -238,14 +238,14 @@ txt_info_from_comment(char *line, gal_data_t **datall, 
char *comm_start)
           typestr=txt_trim_space(typestr);
           if( !strncmp(typestr, "str", 3) )
             {
-              type=GAL_DATA_TYPE_STRING;
+              type=GAL_TYPE_STRING;
               strw=strtol(typestr+3, &tailptr, 0);
               if(*tailptr!='\0' || strw<0) return;
             }
           else
             {
-              type=gal_data_string_as_type(typestr);
-              if(type==GAL_DATA_TYPE_INVALID) return;
+              type=gal_type_from_string(typestr);
+              if(type==GAL_TYPE_INVALID) return;
             }
         }
 
@@ -262,7 +262,7 @@ txt_info_from_comment(char *line, gal_data_t **datall, char 
*comm_start)
          structure. If the type is string, then also copy the width into
          the structure. */
       (*datall)->status=index;
-      (*datall)->disp_width = type==GAL_DATA_TYPE_STRING ? strw : 0;
+      (*datall)->disp_width = type==GAL_TYPE_STRING ? strw : 0;
 
       /* Write the blank value into the array. Note that this is not the
          final column, we are just collecting information now. */
@@ -320,7 +320,7 @@ txt_info_from_first_row(char *line, gal_data_t **datall, 
int format)
          space set for the strings. */
       if(col)
         {
-          if( col->type==GAL_DATA_TYPE_STRING )
+          if( col->type==GAL_TYPE_STRING )
             {
               /* Remove all delimiters before the string starts. */
               while(isspace(*line) || *line==',') ++line;
@@ -363,7 +363,7 @@ txt_info_from_first_row(char *line, gal_data_t **datall, 
int format)
              information). */
           if( *datall==NULL || format==TXT_FORMAT_TABLE )
             {
-              gal_data_add_to_ll(datall, NULL, GAL_DATA_TYPE_FLOAT64, 0,
+              gal_data_add_to_ll(datall, NULL, GAL_TYPE_FLOAT64, 0,
                                  NULL, NULL, 0, -1, NULL, NULL, NULL);
               (*datall)->status=n;
             }
@@ -661,7 +661,7 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
   /* Read the proper token into the column. */
   switch(data->type)
     {
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       gal_checkset_allocate_copy(txt_trim_space(token), &str[i]);
       if( (strb=info->array) && !strcmp( *strb, str[i] ) )
         {
@@ -670,49 +670,49 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
         }
       break;
 
-    case GAL_DATA_TYPE_UINT8:
+    case GAL_TYPE_UINT8:
       uc[i]=strtol(token, &tailptr, 0);
       if( (ucb=info->array) && *ucb==uc[i] )
         uc[i]=GAL_BLANK_UINT8;
       break;
 
-    case GAL_DATA_TYPE_INT8:
+    case GAL_TYPE_INT8:
       c[i]=strtol(token, &tailptr, 0);
       if( (cb=info->array) && *cb==c[i] )
         c[i]=GAL_BLANK_INT8;
       break;
 
-    case GAL_DATA_TYPE_UINT16:
+    case GAL_TYPE_UINT16:
       us[i]=strtol(token, &tailptr, 0);
       if( (usb=info->array) && *usb==us[i] )
         us[i]=GAL_BLANK_UINT16;
       break;
 
-    case GAL_DATA_TYPE_INT16:
+    case GAL_TYPE_INT16:
       s[i]=strtol(token, &tailptr, 0);
       if( (sb=info->array) && *sb==s[i] )
         s[i]=GAL_BLANK_INT16;
       break;
 
-    case GAL_DATA_TYPE_UINT32:
+    case GAL_TYPE_UINT32:
       ui[i]=strtol(token, &tailptr, 0);
       if( (uib=info->array) && *uib==ui[i] )
         ui[i]=GAL_BLANK_UINT32;
       break;
 
-    case GAL_DATA_TYPE_INT32:
+    case GAL_TYPE_INT32:
       ii[i]=strtol(token, &tailptr, 0);
       if( (ib=info->array) && *ib==ii[i] )
         ii[i]=GAL_BLANK_INT32;
       break;
 
-    case GAL_DATA_TYPE_UINT64:
+    case GAL_TYPE_UINT64:
       ul[i]=strtoul(token, &tailptr, 0);
       if( (ulb=info->array) && *ulb==ul[i] )
         ul[i]=GAL_BLANK_UINT64;
       break;
 
-    case GAL_DATA_TYPE_INT64:
+    case GAL_TYPE_INT64:
       l[i]=strtol(token, &tailptr, 0);
       if( (lb=info->array) && *lb==l[i] )
         l[i]=GAL_BLANK_INT64;
@@ -722,14 +722,14 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
          sure it isn't a NaN, because a NaN value will fail on any
          condition check (even `=='). If it isn't NaN, then we can
          compare the values. */
-    case GAL_DATA_TYPE_FLOAT32:
+    case GAL_TYPE_FLOAT32:
       f[i]=strtod(token, &tailptr);
       if( (fb=info->array)
           && ( (isnan(*fb) && isnan(f[i])) || *fb==f[i] ) )
         f[i]=GAL_BLANK_FLOAT64;
       break;
 
-    case GAL_DATA_TYPE_FLOAT64:
+    case GAL_TYPE_FLOAT64:
       d[i]=strtod(token, &tailptr);
       if( (db=info->array)
           && ( (isnan(*db) && isnan(d[i])) || *db==d[i] ) )
@@ -742,10 +742,10 @@ txt_read_token(gal_data_t *data, gal_data_t *info, char 
*token,
     }
 
   /* If a number couldn't be read properly, then report an error. */
-  if(data->type!=GAL_DATA_TYPE_STRING && *tailptr!='\0')
+  if(data->type!=GAL_TYPE_STRING && *tailptr!='\0')
     error_at_line(EXIT_FAILURE, 0, filename, lineno, "column %zu "
                   "(`%s') couldn't be read as a `%s' number",
-                  colnum, token, gal_data_type_as_string(data->type, 1) );
+                  colnum, token, gal_type_to_string(data->type, 1) );
 }
 
 
@@ -775,7 +775,7 @@ txt_fill(char *line, char **tokens, size_t maxcolnum, 
gal_data_t *info,
 
       /* Set the pointer to the start of this token/column. See
          explanations in `txt_info_from_row'. */
-      if( info[n-1].type == GAL_DATA_TYPE_STRING )
+      if( info[n-1].type == GAL_TYPE_STRING )
         {
           /* Remove any delimiters and stop at the first non-delimiter. If
              we have reached the end of the line then its an error, because
@@ -1045,7 +1045,7 @@ make_fmts_for_printf(gal_data_t *datall, int leftadjust, 
size_t *len)
       else
         {
           /* Set the blank value. */
-          if(data->type==GAL_DATA_TYPE_STRING)
+          if(data->type==GAL_TYPE_STRING)
             gal_checkset_allocate_copy(GAL_BLANK_STRING,
                                        &fmts[i*FMTS_COLS+2]);
           else
@@ -1080,11 +1080,11 @@ make_fmts_for_printf(gal_data_t *datall, int 
leftadjust, size_t *len)
 
       /* Set the string for the Gnuastro type. For strings, we also need to
          write the maximum number of characters.*/
-      if(data->type==GAL_DATA_TYPE_STRING)
+      if(data->type==GAL_TYPE_STRING)
         sprintf(fmts[i*FMTS_COLS+1], "%s%d",
-                gal_data_type_as_string(data->type, 0), data->disp_width);
+                gal_type_to_string(data->type, 0), data->disp_width);
       else
-        strcpy(fmts[i*FMTS_COLS+1], gal_data_type_as_string(data->type, 0));
+        strcpy(fmts[i*FMTS_COLS+1], gal_type_to_string(data->type, 0));
 
 
       /* Increment the column counter. */
@@ -1105,48 +1105,19 @@ txt_print_value(FILE *fp, void *array, int type, size_t 
ind, char *fmt)
   switch(type)
     {
       /* Numerical types. */
-    case GAL_DATA_TYPE_UINT8:
-      fprintf(fp, fmt, ((uint8_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_INT8:
-      fprintf(fp, fmt, ((int8_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_UINT16:
-      fprintf(fp, fmt, ((uint16_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_INT16:
-      fprintf(fp, fmt, ((int16_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_UINT32:
-      fprintf(fp, fmt, ((uint32_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_INT32:
-      fprintf(fp, fmt, ((int32_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_UINT64:
-      fprintf(fp, fmt, ((uint64_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_INT64:
-      fprintf(fp, fmt, ((int64_t *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT32:
-      fprintf(fp, fmt, ((float *)array)[ind]);
-      break;
-
-    case GAL_DATA_TYPE_FLOAT64:
-      fprintf(fp, fmt, ((double *)array)[ind]);
-      break;
+    case GAL_TYPE_UINT8:   fprintf(fp, fmt, ((uint8_t *) array)[ind]); break;
+    case GAL_TYPE_INT8:    fprintf(fp, fmt, ((int8_t *)  array)[ind]); break;
+    case GAL_TYPE_UINT16:  fprintf(fp, fmt, ((uint16_t *)array)[ind]); break;
+    case GAL_TYPE_INT16:   fprintf(fp, fmt, ((int16_t *) array)[ind]); break;
+    case GAL_TYPE_UINT32:  fprintf(fp, fmt, ((uint32_t *)array)[ind]); break;
+    case GAL_TYPE_INT32:   fprintf(fp, fmt, ((int32_t *) array)[ind]); break;
+    case GAL_TYPE_UINT64:  fprintf(fp, fmt, ((uint64_t *)array)[ind]); break;
+    case GAL_TYPE_INT64:   fprintf(fp, fmt, ((int64_t *) array)[ind]); break;
+    case GAL_TYPE_FLOAT32: fprintf(fp, fmt, ((float *)   array)[ind]); break;
+    case GAL_TYPE_FLOAT64: fprintf(fp, fmt, ((double *)  array)[ind]); break;
 
       /* Special consideration for strings. */
-    case GAL_DATA_TYPE_STRING:
+    case GAL_TYPE_STRING:
       if( !strcmp( ((char **)array)[ind], GAL_BLANK_STRING ) )
         fprintf(fp, fmt, GAL_BLANK_STRING);
       else
diff --git a/lib/type.c b/lib/type.c
new file mode 100644
index 0000000..11c39a3
--- /dev/null
+++ b/lib/type.c
@@ -0,0 +1,297 @@
+/*********************************************************************
+Type -- Type information and basic operations.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+     Mohammad Akhlaghi <address@hidden>
+Contributing author(s):
+Copyright (C) 2016, 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 <float.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gnuastro/type.h>
+
+
+
+
+size_t
+gal_type_sizeof(uint8_t type)
+{
+  /* Allocate space for the array to keep the image. */
+  switch(type)
+    {
+    case GAL_TYPE_BIT:
+      error(EXIT_FAILURE, 0, "Currently Gnuastro doesn't support bit "
+            "types, please get in touch with us to implement it.");
+
+      /* The parenthesis after sizeof is not a function, it is actually a
+         type cast, so we have put a space between size of and the
+         parenthesis to highlight this. In C, `sizeof' is an operator, not
+         a function.*/
+    case GAL_TYPE_UINT8:     return sizeof (uint8_t);
+    case GAL_TYPE_INT8:      return sizeof (int8_t);
+    case GAL_TYPE_UINT16:    return sizeof (uint16_t);
+    case GAL_TYPE_INT16:     return sizeof (int16_t);
+    case GAL_TYPE_UINT32:    return sizeof (uint32_t);
+    case GAL_TYPE_INT32:     return sizeof (int32_t);
+    case GAL_TYPE_UINT64:    return sizeof (uint64_t);
+    case GAL_TYPE_INT64:     return sizeof (int64_t);
+
+    case GAL_TYPE_FLOAT32:
+      if( sizeof (float) != 4 )
+        error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
+      return sizeof (float);
+
+    case GAL_TYPE_FLOAT64:
+      if( sizeof (double) != 8 )
+        error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
+      return sizeof (double);
+
+    case GAL_TYPE_COMPLEX32:
+      if( sizeof (float) != 4 )
+        error(EXIT_FAILURE, 0, "`float` is not 32 bits on this machine");
+      return sizeof (gsl_complex_float);
+
+    case GAL_TYPE_COMPLEX64:
+      if( sizeof (double) != 8 )
+        error(EXIT_FAILURE, 0, "`double` is not 64 bits on this machine");
+      return sizeof (gsl_complex);
+
+    case GAL_TYPE_STRING:
+      return sizeof (char *);
+
+    default:
+      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
+            "gal_data_sizeof", type);
+    }
+
+  error(EXIT_FAILURE, 0, "Control has reached the end of `gal_data_sizeof' "
+        "This is a bug! Please contact us at %s so we can find the cause "
+        "of the problem.", PACKAGE_BUGREPORT);
+  return -1;
+}
+
+
+
+
+
+char *
+gal_type_to_string(uint8_t type, int long_name)
+{
+  switch(type)
+    {
+    case GAL_TYPE_BIT:
+      if(long_name) return "bit";                 else return "b";
+
+    case GAL_TYPE_UINT8:
+      if(long_name) return "uint8";               else return "u8";
+
+    case GAL_TYPE_INT8:
+      if(long_name) return "int8";                else return "i8";
+
+    case GAL_TYPE_UINT16:
+      if(long_name) return "uint16";              else return "u16";
+
+    case GAL_TYPE_INT16:
+      if(long_name) return "int16";               else return "i16";
+
+    case GAL_TYPE_UINT32:
+      if(long_name) return "uint32";              else return "u32";
+
+    case GAL_TYPE_INT32:
+      if(long_name) return "int32";               else return "i32";
+
+    case GAL_TYPE_UINT64:
+      if(long_name) return "uint64";              else return "u64";
+
+    case GAL_TYPE_INT64:
+      if(long_name) return "int64";               else return "i64";
+
+    case GAL_TYPE_FLOAT32:
+      if(long_name) return "float32";             else return "f32";
+
+    case GAL_TYPE_FLOAT64:
+      if(long_name) return "float64";             else return "f64";
+
+    case GAL_TYPE_COMPLEX32:
+      if(long_name) return "complex32";           else return "c32";
+
+    case GAL_TYPE_COMPLEX64:
+      if(long_name) return "complex64";           else return "c64";
+
+    case GAL_TYPE_STRING:
+      if(long_name) return "string";              else return "str";
+
+    case GAL_TYPE_STRLL:
+      if(long_name) return "string linked list";  else return "strll";
+
+    default:
+      error(EXIT_FAILURE, 0, "type value of %d not recognized in "
+            "`gal_data_type_as_string'", type);
+    }
+
+  /* Any of the cases above should return this function, so if control
+     reaches here, there is a bug. */
+  error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can address "
+        "the problem. For some reason control has reached the end of "
+        "the `gal_data_type_as_string' function. This must not happen",
+        PACKAGE_BUGREPORT);
+  return NULL;
+}
+
+
+
+
+
+uint8_t
+gal_type_from_string(char *str)
+{
+  if(      !strcmp(str, "b")     || !strcmp(str, "bit") )
+    return GAL_TYPE_BIT;
+
+  else if( !strcmp(str, "u8")    || !strcmp(str, "uint8") )
+    return GAL_TYPE_UINT8;
+
+  else if( !strcmp(str, "i8")    || !strcmp(str, "int8") )
+    return GAL_TYPE_INT8;
+
+  else if( !strcmp(str, "u16")   || !strcmp(str, "uint16") )
+    return GAL_TYPE_UINT16;
+
+  else if( !strcmp(str, "i16")   || !strcmp(str, "int16") )
+    return GAL_TYPE_INT16;
+
+  else if( !strcmp(str, "u32")   || !strcmp(str, "uint32") )
+    return GAL_TYPE_UINT32;
+
+  else if( !strcmp(str, "i32")   || !strcmp(str, "int32") )
+    return GAL_TYPE_INT32;
+
+  else if( !strcmp(str, "u64")   || !strcmp(str, "uint64") )
+    return GAL_TYPE_UINT64;
+
+  else if( !strcmp(str, "i64")   || !strcmp(str, "int64") )
+    return GAL_TYPE_INT64;
+
+  else if( !strcmp(str, "f32")   || !strcmp(str, "float32") )
+    return GAL_TYPE_FLOAT32;
+
+  else if( !strcmp(str, "f64")   || !strcmp(str, "float64") )
+    return GAL_TYPE_FLOAT64;
+
+  else if( !strcmp(str, "c32")   || !strcmp(str, "complex32") )
+    return GAL_TYPE_COMPLEX32;
+
+  else if( !strcmp(str, "c64")   || !strcmp(str, "complex64") )
+    return GAL_TYPE_COMPLEX64;
+
+  else if( !strcmp(str, "str")   || !strcmp(str, "string") )
+    return GAL_TYPE_STRING;
+
+  else
+    return GAL_TYPE_INVALID;
+
+  /* Any of the cases above should return this function, so if control
+     reaches here, there is a bug. */
+  error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can address "
+        "the problem. For some reason control has reached the end of "
+        "the `gal_data_string_as_type' function. This must not happen",
+        PACKAGE_BUGREPORT);
+  return 0;
+}
+
+
+
+
+
+/* Put the minimum (or maximum for the `gal_data_type_max') value for the
+   type in the space (that must already be allocated before the call to
+   this function) pointed to by in.  */
+void
+gal_type_min(uint8_t type, void *in)
+{
+  switch(type)
+    {
+    case GAL_TYPE_UINT8:        *(uint8_t *)  in = 0;            break;
+    case GAL_TYPE_INT8:         *(int8_t *)   in = INT8_MIN;     break;
+    case GAL_TYPE_UINT16:       *(uint16_t *) in = 0;            break;
+    case GAL_TYPE_INT16:        *(int16_t *)  in = INT16_MIN;    break;
+    case GAL_TYPE_UINT32:       *(uint32_t *) in = 0;            break;
+    case GAL_TYPE_INT32:        *(int32_t *)  in = INT32_MIN;    break;
+    case GAL_TYPE_UINT64:       *(uint64_t *) in = 0;            break;
+    case GAL_TYPE_INT64:        *(int64_t *)  in = INT64_MIN;    break;
+    case GAL_TYPE_FLOAT32:      *(float *)    in = -FLT_MAX;     break;
+    case GAL_TYPE_FLOAT64:      *(double *)   in = -DBL_MAX;     break;
+    default:
+      error(EXIT_FAILURE, 0, "type code %d not recognized in "
+            "`gal_data_type_min'", type);
+    }
+}
+
+
+
+
+
+void
+gal_type_max(uint8_t type, void *in)
+{
+  switch(type)
+    {
+    case GAL_TYPE_UINT8:        *(uint8_t *)  in = UINT8_MAX;    break;
+    case GAL_TYPE_INT8:         *(int8_t *)   in = INT8_MAX;     break;
+    case GAL_TYPE_UINT16:       *(uint16_t *) in = UINT16_MAX;   break;
+    case GAL_TYPE_INT16:        *(int16_t *)  in = INT16_MAX;    break;
+    case GAL_TYPE_UINT32:       *(uint32_t *) in = UINT32_MAX;   break;
+    case GAL_TYPE_INT32:        *(int32_t *)  in = INT32_MAX;    break;
+    case GAL_TYPE_UINT64:       *(uint64_t *) in = UINT64_MAX;   break;
+    case GAL_TYPE_INT64:        *(int64_t *)  in = INT64_MAX;    break;
+    case GAL_TYPE_FLOAT32:      *(float *)    in = FLT_MAX;      break;
+    case GAL_TYPE_FLOAT64:      *(double *)   in = DBL_MAX;      break;
+    default:
+      error(EXIT_FAILURE, 0, "type code %d not recognized in "
+            "`gal_data_type_min'", type);
+    }
+}
+
+
+
+
+
+/* Since linked lists need a different process than arrays, for functions
+   that work on both, it is convenient to simiplify the check with this
+   function. */
+int
+gal_type_is_linked_list(uint8_t type)
+{
+  return type==GAL_TYPE_STRLL;
+}
+
+
+
+
+
+int
+gal_type_out(int first_type, int second_type)
+{
+  return first_type > second_type ? first_type : second_type;
+}
diff --git a/lib/wcs.c b/lib/wcs.c
index b4c7e64..55d2643 100644
--- a/lib/wcs.c
+++ b/lib/wcs.c
@@ -234,7 +234,7 @@ gal_wcs_on_tile(gal_data_t *tile)
 {
   size_t i, start_ind, ndim=tile->ndim;
   gal_data_t *block=gal_tile_block(tile);
-  size_t *coord=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  size_t *coord=gal_data_malloc_array(GAL_TYPE_SIZE_T, ndim);
 
   /* If the tile already has a WCS structure, don't do anything. */
   if(tile->wcs) return;
@@ -549,12 +549,12 @@ gal_wcs_world_to_img(struct wcsprm *wcs, double *ra, 
double *dec,
   double *phi, *theta, *world, *pixcrd, *imgcrd;
 
   /* Allocate all the necessary arrays. */
-  stat=gal_data_calloc_array(GAL_DATA_TYPE_INT32, size);
-  phi=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, size);
-  theta=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, size);
-  world=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
-  imgcrd=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
-  pixcrd=gal_data_malloc_array(GAL_DATA_TYPE_FLOAT64, 2*size);
+  stat=gal_data_calloc_array(GAL_TYPE_INT32, size);
+  phi=gal_data_malloc_array(GAL_TYPE_FLOAT64, size);
+  theta=gal_data_malloc_array(GAL_TYPE_FLOAT64, size);
+  world=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*size);
+  imgcrd=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*size);
+  pixcrd=gal_data_malloc_array(GAL_TYPE_FLOAT64, 2*size);
 
   /* Put in the values. */
   for(i=0;i<size;++i) { world[i*2]=ra[i]; world[i*2+1]=dec[i]; }
@@ -573,8 +573,8 @@ gal_wcs_world_to_img(struct wcsprm *wcs, double *ra, double 
*dec,
   */
 
   /* Allocate the output arrays if they were not already allocated. */
-  if(*x==NULL) *x=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, size);
-  if(*y==NULL) *y=gal_data_calloc_array(GAL_DATA_TYPE_FLOAT64, size);
+  if(*x==NULL) *x=gal_data_calloc_array(GAL_TYPE_FLOAT64, size);
+  if(*y==NULL) *y=gal_data_calloc_array(GAL_TYPE_FLOAT64, size);
 
   /* Put the values into the output arrays. */
   for(i=0;i<size;++i)
diff --git a/tmpfs-config-make b/tmpfs-config-make
index 1be490f..09ab2df 100755
--- a/tmpfs-config-make
+++ b/tmpfs-config-make
@@ -133,14 +133,11 @@ if [ ! -f Makefile ]; then
     $srcdir/configure --srcdir=$srcdir                                        \
                  --enable-arithmetic --enable-convertt   --enable-convolve    \
                  --enable-cosmiccal  --enable-crop       --enable-fits        \
-                 --enable-mknoise    --enable-statistics --enable-mkprof      \
-                 --enable-table      --enable-warp                            \
-                 --disable-shared CFLAGS="-g -O0"
+                 --enable-mknoise    --enable-mkprof     --enable-noisechisel \
+                 --enable-statistics --enable-table      --enable-warp
 fi
 
 
 
-
-
 # Build Gnuastro in that directory with the specified number of threads
 make -kj$NUM_THREADS



reply via email to

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