gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 8f390d4 079/125: Convolve works with gal_data_


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 8f390d4 079/125: Convolve works with gal_data_t features
Date: Sun, 23 Apr 2017 22:36:42 -0400 (EDT)

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

    Convolve works with gal_data_t features
    
    The Convolve program is now also using the new features of `gal_data_t'
    which greatly helped in simplifying `ui.c'. A summary of the changes are:
    
     - The old `--frequency' and `--spatial' options were removed to have just
       one: `--domain'. It can get values of `frequency' and `spatial' (as a
       string).
    
     - The old `--viewfreqsteps' was changed to `--checkfreqsteps' to fit with
       the general style of such check images.
    
     - In ImageCrop (from the previous commit), the description of the column
       options was not updated, so they were updated.
    
     - `gal_fits_write_img_fitsptr' deletes the two comment lines that CFITSIO
       puts in the header for clarity and a clean header. The version of
       CFITSIO is included in the header, clearly showing which version of
       CFITSIO was used to make the file. This more directly relevant to how
       the file was written (and should be read) than the raw standard (after
       all, CFITSIO complies with the standard, but also has additional
       features, like file types). So having a citation to the paper was
       irrelevant in Gnuastro (which writes the version of CFITSIO).
    
     - `gal_fits_write_keys_version' now also writes the version of GSL used.
---
 bin/convolve/args.h           | 444 +++++++++-----------------
 bin/convolve/astconvolve.conf |  10 +-
 bin/convolve/convolve.c       | 155 +++++----
 bin/convolve/main.c           |   6 +-
 bin/convolve/main.h           | 125 ++++----
 bin/convolve/ui.c             | 724 +++++++++++++++++++-----------------------
 bin/convolve/ui.h             |   4 +-
 doc/gnuastro.texi             |  80 +++--
 lib/data.c                    |   9 +
 lib/fits.c                    |  16 +-
 lib/gnuastro/mesh.h           |   2 +-
 tests/convolve/frequency.sh   |   2 +-
 tests/convolve/spatial.sh     |   2 +-
 tmpfs-config-make             |   7 +-
 14 files changed, 699 insertions(+), 887 deletions(-)

diff --git a/bin/convolve/args.h b/bin/convolve/args.h
index 53317b5..f662d63 100644
--- a/bin/convolve/args.h
+++ b/bin/convolve/args.h
@@ -23,214 +23,231 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef ARGS_H
 #define ARGS_H
 
-#include <commonargs.h>
-#include <fixedstringmacros.h>
 
-#include "ui.h"
 
-/* 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[] = "InputFile";
 
 
 
-
-
-const char doc[] =
-  /* Before the list of options: */
-  GAL_STRINGS_TOP_HELP_INFO
-  SPACK_NAME" will convolve an input image with a given spatial kernel "
-  "(image) in the spatial domain (no edge effects) or frequency domain. "
-  "The latter suffers from edge effects, but can be much faster.\n"
-  GAL_STRINGS_MORE_HELP_INFO
-  /* After the list of options: */
-  "\v"
-  PACKAGE_NAME" home page: "PACKAGE_URL;
-
-
-
-
-
-/* Free letters for options:
-
-   d e g i j l n r t u w x y z
-   A B C E F G H I J O Q R T W X Y Z
-
-   Free numbers: >=504
-*/
-static struct argp_option options[] =
+/* Array of acceptable options. */
+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
-    },
+    /* Inputs */
     {
       "kernel",
-      'k',
+      ARGS_OPTION_KEY_KERNEL,
       "STR",
       0,
-      "Name of kernel for convolution.",
-      1
+      "File name of kernel for convolution.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->kernelname,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "khdu",
-      'U',
+      ARGS_OPTION_KEY_KHDU,
       "STR",
       0,
-      "HDU of kernel file.",
-      1
+      "HDU containing the kernel.",
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->khdu,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "nokernelflip",
-      500,
+      ARGS_OPTION_KEY_NOKERNELFLIP,
       0,
       0,
       "Do not flip the kernel image.",
-      1
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->nokernelflip,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "nokernelnorm",
-      501,
+      ARGS_OPTION_KEY_NOKERNELNORM,
       0,
       0,
       "Do not normalize the kernel image.",
-      1
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->nokernelnorm,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "minsharpspec",
-      'c',
+      ARGS_OPTION_KEY_MINSHARPSPEC,
       "FLT",
       0,
       "Deconvolution: min spectrum of sharp img.",
-      1
+      GAL_OPTIONS_GROUP_INPUT,
+      &p->minsharpspec,
+      GAL_DATA_TYPE_DOUBLE,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
-
-
-    {
-      0, 0, 0, 0,
-      "Output:",
-      2
-    },
+    /* Outputs */
     {
-      "viewfreqsteps",
-      'v',
+      "checkfreqsteps",
+      ARGS_OPTION_KEY_CHECKFREQSTEPS,
       0,
       0,
       "View the steps in the frequency domain.",
-      2
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->checkfreqsteps,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
 
 
+
+
+    /* Mesh grid options. */
     {
       0, 0, 0, 0,
       "Mesh grid (only for spatial domain):",
-      3
+      ARGS_GROUP_MESH_GRID
     },
     {
       "meshsize",
-      's',
+      ARGS_OPTION_KEY_MESHSIZE,
       "INT",
       0,
       "Size of each mesh (tile) in the grid.",
-      3
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.meshsize,
+      GAL_DATA_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "nch1",
-      'a',
+      ARGS_OPTION_KEY_NCH1,
       "INT",
       0,
       "Number of channels along first FITS axis.",
-      3
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.nch1,
+      GAL_DATA_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "nch2",
-      'b',
+      ARGS_OPTION_KEY_NCH2,
       "INT",
       0,
       "Number of channels along second FITS axis.",
-      3
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.nch2,
+      GAL_DATA_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GT_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "lastmeshfrac",
-      'L',
-      "INT",
+      ARGS_OPTION_KEY_LASTMESHFRAC,
+      "FLT",
       0,
       "Fraction of last mesh area to add new.",
-      3
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.lastmeshfrac,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "checkmesh",
-      503,
-      0,
+      "lastmeshfrac",
+      ARGS_OPTION_KEY_LASTMESHFRAC,
+      "FLT",
       0,
-      "Store mesh IDs in `_mesh.fits' file.",
-      3
+      "Fraction of last mesh area to add new.",
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.lastmeshfrac,
+      GAL_DATA_TYPE_FLOAT,
+      GAL_OPTIONS_RANGE_GE_0_LE_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "fullconvolution",
-      502,
+      ARGS_OPTION_KEY_FULLCONVOLUTION,
       0,
       0,
-      "Ignore channels in imageconvolution.",
-      3
-    },
-
-
-
-
-    {
-      0, 0, 0, 0,
-      "Operating modes:",
-      -1
+      "Ignore channels in spatial convolution.",
+      ARGS_GROUP_MESH_GRID,
+      &p->mp.fullconvolution,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
-      "spatial",
-      'p',
+      "checkmesh",
+      ARGS_OPTION_KEY_CHECKMESH,
       0,
       0,
-      "Spatial domain convolution.",
-      -1
+      "File created to view mesh structure",
+      ARGS_GROUP_MESH_GRID,
+      &p->checkmesh,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
+
+
+
+    /* Operating mode. */
     {
-      "frequency",
-      'f',
-      0,
+      "domain",
+      ARGS_OPTION_KEY_DOMAIN,
+      "STR",
       0,
-      "Frequency domain convolution.",
-      -1
+      "Convolution domain: `spatial', `frequency'.",
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &p->domainstr,
+      GAL_DATA_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
     {
       "makekernel",
-      'm',
-      "INT",
+      ARGS_OPTION_KEY_MAKEKERNEL,
+      0,
       0,
       "Make 2*INT kernel to create input image.",
-      -1
+      GAL_OPTIONS_GROUP_OPERATING_MODE,
+      &p->makekernel,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
     },
 
+
     {0}
   };
 
@@ -238,190 +255,21 @@ static struct argp_option options[] =
 
 
 
+/* Define the child argp structure. */
+struct argp
+gal_options_common_child = {gal_commonopts_options,
+                            gal_options_common_argp_parse,
+                            NULL, NULL, NULL, NULL, NULL};
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* Parse a single option: */
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
+/* 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}
+};
 
-  /* Save the arguments structure: */
-  struct convolveparams *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)
-    {
-
-    /* Inputs: */
-    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 500:
-      p->kernelflip=0;
-      break;
-    case 501:
-      p->kernelnorm=0;
-      break;
-    case 'c':
-      gal_checkset_double_l_0_s_1(arg, &p->minsharpspec, "minsharpspec",
-                                 key, SPACK, NULL, 0);
-      p->up.minsharpspecset=1;
-      break;
-
-
-    /* Output: */
-
-
-   /* Mesh grid: */
-    case 's':
-      gal_checkset_sizet_l_zero(arg, &p->mp.meshsize, "meshsize", key,
-                                SPACK, NULL, 0);
-      p->up.meshsizeset=1;
-      break;
-    case 'a':
-      gal_checkset_sizet_l_zero(arg, &p->mp.nch1, "nch1", key, SPACK,
-                                NULL, 0);
-      p->up.nch1set=1;
-      break;
-    case 'b':
-      gal_checkset_sizet_l_zero(arg, &p->mp.nch2, "nch2", key, SPACK,
-                                NULL, 0);
-      p->up.nch2set=1;
-      break;
-    case 'L':
-      gal_checkset_float_l_0_s_1(arg, &p->mp.lastmeshfrac, "lastmeshfrac",
-                                 key, SPACK, NULL, 0);
-      p->up.lastmeshfracset=1;
-      break;
-    case 503:
-      p->meshname="a";
-      break;
-    case 502:
-      p->mp.fullconvolution=1;
-      p->up.fullconvolutionset=1;
-      break;
-
-
-   /* Operating mode: */
-    case 'p':
-      if(p->up.frequencyset)
-        argp_error(state, "only one of spatial or frequency domain "
-                   "convolution modes may be chosen");
-      p->spatial=1;
-      p->frequency=0;
-      p->up.spatialset=p->up.frequencyset=1;
-      break;
-    case 'f':
-      if(p->up.spatialset)
-        argp_error(state, "only one of spatial or frequency domain "
-                   "convolution modes may be chosen");
-      p->spatial=0;
-      p->frequency=1;
-      p->up.spatialset=p->up.frequencyset=1;
-      break;
-    case 'v':
-      p->viewfreqsteps=1;
-      break;
-    case 'm':
-      gal_checkset_int_el_zero(arg, &p->makekernel, "makekernel", key,
-                               SPACK, NULL, 0);
-      p->up.makekernelset=1;
-      break;
-
-
-
-
-    /* Read the non-option arguments: */
-    case ARGP_KEY_ARG:
-      if(p->up.inputname)
-        argp_error(state, "only one input file (argument) is required");
-      p->up.inputname=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 files 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}
-  };
-
-
-
-
-
-/* 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/convolve/astconvolve.conf b/bin/convolve/astconvolve.conf
index fb06348..8354f88 100644
--- a/bin/convolve/astconvolve.conf
+++ b/bin/convolve/astconvolve.conf
@@ -18,8 +18,7 @@
 # without any warranty.
 
 # Operating mode:
- spatial            0
- frequency          1
+ domain             frequency
  makekernel         0
  minsharpspec       0.005
 
@@ -31,8 +30,9 @@
 # Output:
 
 # Mesh grid:
- meshsize          32
+ meshsize           32
  nch1               1
  nch2               1
- lastmeshfrac     0.6
- fullconvolution    0
\ No newline at end of file
+ lastmeshfrac       0.6
+ fullconvolution    0
+ minmapsize         500000000
\ No newline at end of file
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index 45284ec..a918932 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -64,13 +64,13 @@ complextoreal(double *c, size_t size, int action, double 
**output)
   of=(o=out)+size;
   switch(action)
     {
-    case COMPLEXTOREALSPEC:
+    case COMPLEX_TO_REAL_SPEC:
       do { *o++ = sqrt( *c**c + *(c+1)**(c+1) ); c+=2; } while(o<of);
       break;
-    case COMPLEXTOREALPHASE:
+    case COMPLEX_TO_REAL_PHASE:
       do { *o++ = atan2( *(c+1), *c );           c+=2; } while(o<of);
       break;
-    case COMPLEXTOREALREAL:
+    case COMPLEX_TO_REAL_REAL:
       do { *o++ = *c;                            c+=2; } while(o<of);
       break;
     default:
@@ -370,7 +370,7 @@ correctdeconvolve(struct convolveparams *p, double 
**spatial)
           "even number", PACKAGE_BUGREPORT);
 
   /* First convert the complex image to a real image: */
-  complextoreal(p->pimg, ps0*ps1, COMPLEXTOREALSPEC, &s);
+  complextoreal(p->pimg, ps0*ps1, COMPLEX_TO_REAL_SPEC, &s);
 
   /* Allocate the array to keep the new values */
   errno=0;
@@ -628,28 +628,37 @@ void
 frequencyconvolve(struct convolveparams *p)
 {
   double *tmp;
+  size_t dsize[2];
   struct timeval t1;
-  int verb=p->cp.verb;
+  gal_data_t *data=NULL;
   struct fftonthreadparams *fp;
-  char *operation = p->makekernel ? "Divided" : "Multiplied";
 
 
   /* Make the padded arrays. */
-  if(verb) gettimeofday(&t1, NULL);
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
   makepaddedcomplex(p);
-  if(verb) gal_timing_report(&t1, "Input and Kernel images padded.", 1);
-  if(p->viewfreqsteps)
+  if(!p->cp.quiet)
+    gal_timing_report(&t1, "Input and Kernel images padded.", 1);
+  if(p->checkfreqsteps)
     {
-      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEXTOREALREAL, &tmp);
-      gal_fits_array_to_file(p->up.freqstepsname, "Input padded",
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
-      complextoreal(p->pker, p->ps0*p->ps1, COMPLEXTOREALREAL, &tmp);
-      gal_fits_array_to_file(p->up.freqstepsname, "Kernel padded",
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
+      /* 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_DOUBLE, 2, dsize, NULL, 0,
+                          p->cp.minmapsize, NULL, NULL, NULL);
+      free(data->array);
+
+      /* Save the padded input image. */
+      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_REAL, &tmp);
+      data->array=tmp; data->name="input padded";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      free(tmp); data->name=NULL;
+
+      /* Save the padded kernel image. */
+      complextoreal(p->pker, p->ps0*p->ps1, COMPLEX_TO_REAL_REAL, &tmp);
+      data->array=tmp; data->name="kernel padded";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      free(tmp); data->name=NULL;
     }
 
 
@@ -658,73 +667,73 @@ frequencyconvolve(struct convolveparams *p)
 
 
   /* Forward 2D FFT on each image. */
-  if(verb) gettimeofday(&t1, NULL);
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
   twodimensionfft(p, fp, 1);
-  if(verb)
+  if(!p->cp.quiet)
     gal_timing_report(&t1, "Images converted to frequency domain.", 1);
-  if(p->viewfreqsteps)
+  if(p->checkfreqsteps)
     {
-      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEXTOREALSPEC, &tmp);
-      gal_fits_array_to_file(p->up.freqstepsname, "Input transform",
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
-      complextoreal(p->pker, p->ps0*p->ps1, COMPLEXTOREALSPEC, &tmp);
-      gal_fits_array_to_file(p->up.freqstepsname, "Kernel transform",
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
+      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
+      data->array=tmp; data->name="input transformed";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      free(tmp); data->name=NULL;
+
+      complextoreal(p->pker, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
+      data->array=tmp; data->name="kernel transformed";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      free(tmp); data->name=NULL;
     }
 
   /* Multiply or divide the two arrays and save them in the output.*/
-  if(verb) gettimeofday(&t1, NULL);
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
   if(p->makekernel)
     {
       complexarraydivide(p->pimg, p->pker, p->ps0*p->ps1, p->minsharpspec);
-      if(verb)
+      if(!p->cp.quiet)
         gal_timing_report(&t1, "Divided in the frequency domain.", 1);
     }
   else
     {
       complexarraymultiply(p->pimg, p->pker, p->ps0*p->ps1);
-      if(verb)
+      if(!p->cp.quiet)
         gal_timing_report(&t1, "Multiplied in the frequency domain.", 1);
     }
-  if(p->viewfreqsteps)
+  if(p->checkfreqsteps)
     {
-      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEXTOREALSPEC, &tmp);
-      gal_fits_array_to_file(p->up.freqstepsname, operation,
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
+      complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
+      data->array=tmp; data->name=p->makekernel ? "Divided" : "Multiplied";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      free(tmp); data->name=NULL;
     }
 
   /* Forward (in practice inverse) 2D FFT on each image. */
-  if(verb) gettimeofday(&t1, NULL);
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
   twodimensionfft(p, fp, -1);
-  if(p->makekernel) correctdeconvolve(p, &tmp);
-  else complextoreal(p->pimg, p->ps0*p->ps1, COMPLEXTOREALREAL, &tmp);
-  if(verb)
+  if(p->makekernel)
+    correctdeconvolve(p, &tmp);
+  else
+    complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_REAL, &tmp);
+  if(!p->cp.quiet)
     gal_timing_report(&t1, "Converted back to the spatial domain.", 1);
-  if(p->viewfreqsteps)
+  if(p->checkfreqsteps)
     {
-      gal_fits_array_to_file(p->up.freqstepsname, "Spatial",
-                             DOUBLE_IMG, tmp, p->ps0, p->ps1, 0,
-                             NULL, NULL, SPACK_STRING);
-      free(tmp);
+      data->array=tmp; data->name="padded output";
+      gal_fits_write_img(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      data->name=NULL;
     }
 
   /* Free the padded arrays (they are no longer needed) and put the
      converted array (that is real, not complex) in p->pimg. */
+  gal_data_free(data);
   free(p->pimg);
   free(p->pker);
   p->pimg=tmp;
 
   /* Crop out the center, numbers smaller than 10^{-17} are errors,
      remove them. */
-  if(verb) gettimeofday(&t1, NULL);
+  if(!p->cp.quiet) gettimeofday(&t1, NULL);
   removepaddingcorrectroundoff(p);
-  if(verb) gal_timing_report(&t1, "Padded parts removed.", 1);
+  if(!p->cp.quiet) gal_timing_report(&t1, "Padded parts removed.", 1);
 
 
   /* Free all the allocated space. */
@@ -757,10 +766,12 @@ convolve(struct convolveparams *p)
 {
   float *convolved;
   long *meshindexs;
+  gal_data_t *data;
   struct gal_mesh_params *mp=&p->mp;
+  size_t ndim=2, dsize[]={p->is0, p->is1};
 
   /* Do the convolution. */
-  if(p->spatial)
+  if(p->domain==CONVOLVE_DOMAIN_SPATIAL)
     {
       /* Prepare the mesh structure: */
       mp->img=p->input;      mp->s0=p->is0;      mp->s1=p->is1;
@@ -769,15 +780,23 @@ convolve(struct convolveparams *p)
       gal_mesh_make_mesh(mp);
       if(p->meshname)
         {
+          /* Allocate the `gal_data_t' with the input imag. */
           gal_mesh_check_mesh_id(mp, &meshindexs);
-          gal_fits_array_to_file(p->meshname, "Input", FLOAT_IMG,
-                                 p->mp.img, mp->s0, mp->s1,
-                                 p->anyblank, p->wcs, NULL,
-                                          SPACK_STRING);
-          gal_fits_array_to_file(p->meshname, "MeshIndexs", LONG_IMG,
-                                 meshindexs, mp->s0, mp->s1, 0, p->wcs,
-                                 NULL, SPACK_STRING);
+          data=gal_data_alloc(p->mp.img, GAL_DATA_TYPE_FLOAT, ndim, dsize,
+                              p->wcs, 0, p->cp.minmapsize, NULL, NULL, NULL);
+          data->name="Input";
+          gal_fits_write_img(data, p->meshname, NULL, PROGRAM_STRING);
+
+          /* Change the array, type, and name. */
+          data->array=meshindexs;
+          data->type=GAL_DATA_TYPE_LONG;
+          data->name="Mesh indexs";
+          gal_fits_write_img(data, p->meshname, NULL, PROGRAM_STRING);
+
+          /* Clean up. */
+          data->name=NULL;
           free(meshindexs);
+          gal_data_free(data);
         }
 
       /* Do the spatial convolution on the mesh: */
@@ -790,9 +809,15 @@ convolve(struct convolveparams *p)
   else
     frequencyconvolve(p);
 
-  /* Save the output (which is in p->input) array. Note that p->input
-     will be freed in ui.c. */
-  gal_fits_array_to_file(p->cp.output, "Convolved", FLOAT_IMG,
-                         p->input, p->is0, p->is1, p->anyblank, p->wcs,
-                         NULL, SPACK_STRING);
+  /* Save the output (which is in p->input) array and clean up. Note that
+     we will rely on `gal_data_free' to free some of the things that we
+     don't need any more. */
+  data=gal_data_alloc(p->input, GAL_DATA_TYPE_FLOAT, ndim, dsize,
+                      NULL, 0, p->cp.minmapsize, NULL, NULL, NULL);
+  data->wcs=p->wcs;
+  data->unit=p->unit;
+  data->name="Convolved";
+  gal_fits_write_img(data, p->cp.output, NULL, PROGRAM_STRING);
+  data->name=NULL;
+  gal_data_free(data);
 }
diff --git a/bin/convolve/main.c b/bin/convolve/main.c
index 2316a0e..0a927bd 100644
--- a/bin/convolve/main.c
+++ b/bin/convolve/main.c
@@ -36,20 +36,20 @@ int
 main(int argc, char *argv[])
 {
   struct timeval t1;
-  struct convolveparams p={{0}, {0}, {0}, 0};
+  struct convolveparams p={{0}, {0}, 0};
 
   /* Set the 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 Image Crop */
   convolve(&p);
 
   /* Free all non-freed allocations. */
-  freeandreport(&p, &t1);
+  ui_free_report(&p, &t1);
 
   /* Return successfully. */
   return EXIT_SUCCESS;
diff --git a/bin/convolve/main.h b/bin/convolve/main.h
index d5158e5..10fa237 100644
--- a/bin/convolve/main.h
+++ b/bin/convolve/main.h
@@ -23,93 +23,86 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #ifndef MAIN_H
 #define MAIN_H
 
-
-
+/* Include necessary headers */
+#include <gnuastro/data.h>
 #include <gnuastro/mesh.h>
-#include <gnuastro/threads.h>
 
-#include <commonparams.h>
+#include <options.h>
 
+/* Program names.  */
+#define PROGRAM_NAME "Convolve"      /* Program full name.       */
+#define PROGRAM_EXEC "astconvolve"   /* Program executable name. */
+#define PROGRAM_STRING PROGRAM_NAME" (" PACKAGE_NAME ") " PACKAGE_VERSION
 
 
-/* Progarm name macros: */
-#define SPACK           "astconvolve" /* Subpackage executable name. */
-#define SPACK_NAME      "Convolve" /* Subpackage full name.       */
-#define SPACK_STRING    SPACK_NAME" ("PACKAGE_NAME") "PACKAGE_VERSION
 
 
 
+/* Macros */
 #define CONVFLOATINGPOINTERR 1e-10
-#define COMPLEXTOREALSPEC    1  /* Spectrum of complex number.  */
-#define COMPLEXTOREALPHASE   2  /* Phase of the complex number. */
-#define COMPLEXTOREALREAL    3  /* Only show the real part.     */
 
 
 
-/* User interface parameters structure */
-struct uiparams
+
+
+/* Enumerators */
+enum complex_to_real
 {
-  char        *inputname;   /* Name of input file.           */
-  char         *maskname;   /* Mask file name.               */
-  char             *mhdu;   /* HDU of mask image.            */
-  char       *kernelname;   /* Name of kernel file.          */
-  char             *khdu;   /* HDU of input Kernel.          */
-  char    *freqstepsname;   /* Name of frequency steps file. */
-
-  int         spatialset;
-  int       frequencyset;
-  int        masknameset;
-  int            mhduset;
-  int      kernelnameset;
-  int            khduset;
-  int    minsharpspecset;
-  int        meshsizeset;
-  int            nch1set;
-  int            nch2set;
-  int    lastmeshfracset;
-  int fullconvolutionset;
-  int      makekernelset;
+  COMPLEX_TO_REAL_INVALID,           /* ==0 by C standard. */
+
+  COMPLEX_TO_REAL_SPEC,
+  COMPLEX_TO_REAL_PHASE,
+  COMPLEX_TO_REAL_REAL,
 };
 
 
+enum domain_codes
+{
+  CONVOLVE_DOMAIN_INVALID,           /* ==0 by C standard. */
+
+  CONVOLVE_DOMAIN_SPATIAL,
+  CONVOLVE_DOMAIN_FREQUENCY,
+};
+
+
+
 
 
 /* Processing parameters structure */
 struct convolveparams
 {
-  struct uiparams     up;   /* user interface structure.                */
-  struct gal_commonparams cp; /* gal_commonparams structure.            */
-  struct gal_mesh_params mp; /* gal_mesh_params structure.              */
-
-  /* Inputs: */
-  int         makekernel;   /* ==1: Make a kernel to create input.      */
-  float           *input;   /* Input image array.                       */
-  float          *kernel;   /* Input Kernel array.                      */
-  int           anyblank;   /* If there are blank pixels in input.      */
-  size_t             is0;   /* Input image size along C's first axis.   */
-  size_t             is1;   /* Input image size along C's second axis.  */
-  size_t             ks0;   /* Kernel size along C's first axis.        */
-  size_t             ks1;   /* Kernel size along C's second axis.       */
-  double    minsharpspec;   /* Deconvolution: min spectrum of sharp img.*/
-  int         kernelflip;   /* ==1: Flip the kernel.                    */
-  int         kernelnorm;   /* ==1: Normalize the kernel.               */
-  int               nwcs;   /* Number of WCS headers.                   */
-  struct wcsprm     *wcs;   /* WCS structure.                           */
-
-  /* Outputs: */
-  char         *meshname;   /* Name of mesh structure output.           */
-
-  /* Operating modes: */
-  int            spatial;   /* Convolve using spatial domain.           */
-  int          frequency;   /* Convolve using frequency domain.         */
-  int      viewfreqsteps;   /* View the frequency domain steps.         */
-
-  /* internal: */
-  time_t         rawtime;   /* Starting time of the program.            */
-  double           *pimg;   /* Padded image array.                      */
-  double           *pker;   /* Padded kernel array.                     */
-  size_t             ps0;   /* Padded size along first C axis.          */
-  size_t             ps1;   /* Padded size along second C axis.         */
+  /* From command-line */
+  struct gal_options_common_params cp; /* Common parameters.             */
+  struct gal_mesh_params  mp;  /* gal_mesh_params structure.             */
+  char             *filename;  /* Name of input file.                    */
+  char           *kernelname;  /* File name of kernel.                   */
+  char                 *khdu;  /* HDU of kernel.                         */
+  unsigned char nokernelflip;  /* Do not flip the kernel.                */
+  unsigned char nokernelnorm;  /* Do not normalize the kernel.           */
+  double        minsharpspec;  /* Deconvolution: min spect. of sharp img.*/
+  unsigned char checkfreqsteps; /* View the frequency domain steps.      */
+  unsigned char    checkmesh;  /* View the mesh structure.               */
+  char            *domainstr;  /* String value specifying domain.        */
+  unsigned char   makekernel;  /* ==1: Make a kernel to create input.    */
+
+  /* Internal */
+  int                 domain;  /* Frequency or spatial domain conv.      */
+  float               *input;  /* Input image array.                     */
+  float              *kernel;  /* Input Kernel array.                    */
+  time_t             rawtime;  /* Starting time of the program.          */
+  double               *pimg;  /* Padded image array.                    */
+  double               *pker;  /* Padded kernel array.                   */
+  size_t                 ps0;  /* Padded size along first C axis.        */
+  size_t                 ps1;  /* Padded size along second C axis.       */
+  size_t                 is0;  /* Input image size along C's first axis. */
+  size_t                 is1;  /* Input image size along C's second axis.*/
+  size_t                 ks0;  /* Kernel size along C's first axis.      */
+  size_t                 ks1;  /* Kernel size along C's second axis.     */
+  int                   nwcs;  /* Number of WCS headers.                 */
+  struct wcsprm         *wcs;  /* WCS structure.                         */
+  char                 *unit;  /* The unit string from the input.        */
+  char        *freqstepsname;  /* Name of file to check frequency steps. */
+  char             *meshname;  /* Name of file to check mesh tiles.      */
 };
 
 #endif
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 0d65275..13804a4 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -22,315 +22,192 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 **********************************************************************/
 #include <config.h>
 
-#include <math.h>
-#include <time.h>
+#include <argp.h>
 #include <errno.h>
 #include <error.h>
 #include <stdio.h>
-#include <stdlib.h>
-
-#include <nproc.h>               /* From Gnulib.                   */
+#include <string.h>
 
 #include <gnuastro/fits.h>
-#include <gnuastro/array.h>
-#include <gnuastro/statistics.h>
+#include <gnuastro/table.h>
+#include <gnuastro/linkedlist.h>
 
-#include <timing.h>              /* Includes time.h and sys/time.h */
+#include <timing.h>
+#include <options.h>
 #include <checkset.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. */
+#include "ui.h"
+#include "authors-cite.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
 
 
 
+/**************************************************************/
+/*********      Argp necessary global entities     ************/
+/**************************************************************/
+/* Definition parameters for the Argp: */
+const char *
+argp_program_version = PROGRAM_STRING "\n"
+                       GAL_STRINGS_COPYRIGHT
+                       "\n\nWritten/developed by "PROGRAM_AUTHORS;
 
+const char *
+argp_program_bug_address = PACKAGE_BUGREPORT;
 
+static char
+args_doc[] = "ASTRdata";
 
+const char
+doc[] = GAL_STRINGS_TOP_HELP_INFO PROGRAM_NAME" can be used to view the "
+  "information, select columns, or convert tables. The inputs and outputs "
+  "can be plain text (with whitespace or comma as delimiters), FITS ascii, "
+  "or FITS binary tables. The output columns can either be selected by "
+  "number (counting from 1), name or using regular expressions. For regular "
+  "expressions, enclose the value to the `--column' (`-c') option in "
+  "slashes (`\\', as in `-c\\^mag\\'). To print the selected columns on the "
+  "command-line, don't specify an output file.\n"
+  GAL_STRINGS_MORE_HELP_INFO
+  /* After the list of options: */
+  "\v"
+  PACKAGE_NAME" home page: "PACKAGE_URL;
 
-/**************************************************************/
-/**************       Options and parameters    ***************/
-/**************************************************************/
-void
-readconfig(char *filename, struct convolveparams *p)
+
+
+
+/* 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;
-  int zeroorone, spatialset=0, frequencyset=0;
-  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_MESH_GRID = GAL_OPTIONS_GROUP_AFTER_COMMON,
+};
 
-  /* 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, "minsharpspec")==0)
-        {
-          if(up->minsharpspecset) continue;
-          gal_checkset_double_l_0_s_1(value, &p->minsharpspec, "minsharpspec",
-                                     key, SPACK, filename, lineno);
-          up->minsharpspecset=1;
-        }
 
 
-      /* Outputs: */
-      else if(strcmp(name, "output")==0)
-        gal_checkset_allocate_copy_set(value, &cp->output,
-                                       &cp->outputset);
 
+/* Available letters for short options:
 
+   e f g i j l n r p t u v w x y z
+   A B E F G H I J M O Q R T W X Y Z  */
+enum option_keys_enum
+{
+  /* With short-option version. */
+  ARGS_OPTION_KEY_KERNEL         = 'k',
+  ARGS_OPTION_KEY_KHDU           = 'U',
+  ARGS_OPTION_KEY_MINSHARPSPEC   = 'c',
+  ARGS_OPTION_KEY_CHECKFREQSTEPS = 'C',
+  ARGS_OPTION_KEY_MESHSIZE       = 'c',
+  ARGS_OPTION_KEY_NCH1           = 'a',
+  ARGS_OPTION_KEY_NCH2           = 'b',
+  ARGS_OPTION_KEY_LASTMESHFRAC   = 'L',
+  ARGS_OPTION_KEY_DOMAIN         = 'd',
+  ARGS_OPTION_KEY_MAKEKERNEL     = 'm',
 
+  /* Only with long version (start with a value 1000, the rest will be set
+     automatically). */
+  ARGS_OPTION_KEY_NOKERNELFLIP = 1000,
+  ARGS_OPTION_KEY_NOKERNELNORM,
+  ARGS_OPTION_KEY_CHECKMESH,
+  ARGS_OPTION_KEY_FULLCONVOLUTION,
+};
 
-      /* Mesh grid: */
-      else if(strcmp(name, "meshsize")==0)
-        {
-          if(up->meshsizeset) continue;
-          gal_checkset_sizet_l_zero(value, &p->mp.meshsize, name, key,
-                                    SPACK, filename, lineno);
-          up->meshsizeset=1;
-        }
-      else if(strcmp(name, "nch1")==0)
-        {
-          if(up->nch1set) continue;
-          gal_checkset_sizet_l_zero(value, &p->mp.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->mp.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->mp.lastmeshfrac, name,
-                                     key, SPACK, filename, lineno);
-          up->lastmeshfracset=1;
-        }
-      else if(strcmp(name, "fullconvolution")==0)
-        {
-          if(up->fullconvolutionset) continue;
-          gal_checkset_int_zero_or_one(value, &p->mp.fullconvolution, name,
-                                       key, SPACK, filename, lineno);
-          up->fullconvolutionset=1;
-        }
 
 
 
-      /* Operating modes: */
-      else if(strcmp(name, "spatial")==0)
-        {
-          gal_checkset_int_zero_or_one(value, &zeroorone, name, key,
-                                       SPACK, filename, lineno);
-          if(zeroorone)
-            {
-              spatialset=1;
-              if(frequencyset)
-                error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                              "Spatial and frequency modes cannot be called "
-                              "together. It is ambiguous.");
-              if(up->spatialset==0)
-                {
-                  p->spatial=1;
-                  p->frequency=0;
-                  up->spatialset=up->frequencyset=1;
-                }
-            }
-        }
-      else if(strcmp(name, "frequency")==0)
-        {
-          gal_checkset_int_zero_or_one(value, &zeroorone, name, key,
-                                       SPACK, filename, lineno);
-          if(zeroorone)
-            {
-              frequencyset=1;
-              if(spatialset)
-                error_at_line(EXIT_FAILURE, 0, filename, lineno,
-                              "Spatial and frequency modes cannot be "
-                              "called together. It is ambiguous.");
-              if(up->frequencyset==0)
-                {
-                  p->spatial=0;
-                  p->frequency=1;
-                  up->spatialset=up->frequencyset=1;
-                }
-            }
-        }
-      else if(strcmp(name, "makekernel")==0)
-        {
-          if(up->makekernelset) continue;
-          gal_checkset_int_el_zero(value, &p->makekernel, name, key,
-                                   SPACK, filename, lineno);
-          up->makekernelset=1;
-        }
 
-      /* 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 convolveparams *p)
-{
-  struct uiparams *up=&p->up;
-  struct gal_mesh_params *mp=&p->mp;
-  struct gal_commonparams *cp=&p->cp;
-
-  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->mhduset)
-    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->khduset)
-    GAL_CHECKSET_PRINT_STRING_MAYBE_WITH_SPACE("khdu", up->khdu);
-  if(up->minsharpspecset)
-    fprintf(fp, CONF_SHOWFMT"%f\n", "minsharpspec", p->minsharpspec);
-
-
-
-  fprintf(fp, "\n# Output:\n");
-  if(cp->outputset)
-    fprintf(fp, CONF_SHOWFMT"%s\n", "output", cp->output);
-
-
-  fprintf(fp, "\n# Mesh grid:\n");
-  if(up->meshsizeset)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "meshsize", mp->meshsize);
-  if(up->nch1set)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "nch1", mp->nch1);
-  if(up->nch2set)
-    fprintf(fp, CONF_SHOWFMT"%zu\n", "nch2", mp->nch2);
-  if(up->lastmeshfracset)
-    fprintf(fp, CONF_SHOWFMT"%.3f\n", "lastmeshfrac", mp->lastmeshfrac);
-  if(up->fullconvolutionset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "fullconvolution",
-            mp->fullconvolution);
-
-
-  /* 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 modes:\n");
-  GAL_CONFIGFILES_PRINT_COMMONOPTIONS;
-  if(up->spatialset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "spatial", p->spatial);
-  if(up->frequencyset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "frequency", p->frequency);
-  if(up->makekernelset)
-    fprintf(fp, CONF_SHOWFMT"%d\n", "makekernel", p->makekernel);
-}
 
 
 
 
 
-void
-checkifset(struct convolveparams *p)
+/**************************************************************/
+/*********    Initialize & Parse command-line    **************/
+/**************************************************************/
+static void
+ui_initialize_options(struct convolveparams *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;
+
+
+  /* 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;
+  cp->numthreads         = gal_threads_number();
+
+
+  /* Set the mandatory common options. */
+  for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
+    switch(cp->coptions[i].key)
+      {
+      case GAL_OPTIONS_KEY_HDU:
+      case GAL_OPTIONS_KEY_MINMAPSIZE:
+        cp->coptions[i].mandatory=GAL_OPTIONS_MANDATORY;
+        break;
+      }
+}
 
-  int intro=0;
 
 
-  /* Input: */
-  if(cp->hduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("hdu");
-  if(up->kernelnameset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("kernel");
-  if(up->khduset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("khdu");
-  if(p->makekernel && up->minsharpspecset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("minsharpspec");
 
 
-  /* Mesh grid: */
-  if(up->meshsizeset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("meshsize");
-  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->fullconvolutionset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("fullconvolution");
+/* Parse a single option: */
+error_t
+parse_opt(int key, char *arg, struct argp_state *state)
+{
+  struct convolveparams *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->filename)
+        argp_error(state, "only one argument (input file) should be given");
+      else
+        p->filename=arg;
+      break;
 
-  /* Operating mode: */
-  if(up->spatialset==0 && up->frequencyset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("spatial or frequency");
-  if(up->makekernelset==0)
-    GAL_CONFIGFILES_REPORT_NOTSET("makekernel");
 
+    /* This is an option, set its value. */
+    default:
+      return gal_options_set_from_key(key, arg, p->cp.poptions, &p->cp);
+    }
 
-  GAL_CONFIGFILES_END_OF_NOTSET_REPORT;
+  return 0;
 }
 
 
@@ -351,60 +228,23 @@ checkifset(struct convolveparams *p)
 
 
 
+
 /**************************************************************/
-/************         Prepare the arrays          *************/
+/***************       Sanity Check         *******************/
 /**************************************************************/
-void
-sanitycheck(struct convolveparams *p)
+static void
+ui_check_options_and_arguments(struct convolveparams *p)
 {
-  char *outsuffix = p->makekernel ? "_kernel.fits" : "_convolved.fits";
+  /* Make sure an input file name was given and if it was a FITS file, that
+     a HDU is also given. */
+  if(p->filename==NULL)
+    error(EXIT_FAILURE, 0, "no input file is specified");
+}
 
-  /* Make sure the input file exists. */
-  gal_checkset_check_file(p->up.inputname);
 
-  /* Set maskname 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");
 
-  /* Check the output file name: */
-  if(p->cp.outputset)
-    {
-      if( gal_checkset_dir_0_file_1(p->cp.output, p->cp.dontdelete) == 0 )
-        error(EXIT_FAILURE, 0, "your output name (%s) is a directory",
-              p->cp.output);
-    }
-  else
-    {
-      gal_checkset_automatic_output(p->up.inputname, outsuffix,
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->cp.output);
-      p->cp.outputset=1;
-    }
-  if(p->frequency && p->viewfreqsteps)
-    gal_checkset_automatic_output(p->up.inputname, "_freqsteps.fits",
-                    p->cp.removedirinfo, p->cp.dontdelete,
-                    &p->up.freqstepsname);
 
-  /* Check output names: */
-  if(p->meshname)
-    {
-      p->meshname=NULL;           /* Was not allocated before!  */
-      gal_checkset_automatic_output(p->up.inputname, "_mesh.fits",
-                                    p->cp.removedirinfo, p->cp.dontdelete,
-                                    &p->meshname);
-    }
 
-  /* makekernel can only operate in frequency mode: */
-  if(p->makekernel && p->spatial)
-    error(EXIT_FAILURE, 0, "`--makekernel' (`-m') can only be defined "
-          "in frequency domain operations, not spatial domain. You can "
-          "either explicitly call for frequency mode on the command line "
-          "or change your nearest configuration file so Convolve defaults "
-          "to the frequency domain. Please see the Gnuastro for more "
-          "information. On the command line, the manual can be seen with "
-          "the `info gnuastro' command");
-}
 
 
 
@@ -420,41 +260,107 @@ sanitycheck(struct convolveparams *p)
 
 
 
+/**************************************************************/
+/***************       Preparations         *******************/
+/**************************************************************/
+static void
+ui_read_domain(struct convolveparams *p)
+{
+  if( !strcmp("spatial", p->domainstr) )
+    p->domain=CONVOLVE_DOMAIN_SPATIAL;
+  else if( !strcmp("frequency", p->domainstr) )
+    p->domain=CONVOLVE_DOMAIN_FREQUENCY;
+  else
+    error(EXIT_FAILURE, 0, "domain value `%s' not recognized. Please use "
+          "either `spatial' or `frequency'", p->domainstr);
+}
 
 
 
 
 
-/**************************************************************/
-/************         Prepare the arrays          *************/
-/**************************************************************/
-void
-preparearrays(struct convolveparams *p)
+static void
+ui_read_kernel(struct convolveparams *p)
 {
+  double zero=0.0f;
+  gal_data_t *data;
+
+  /* Read the image into file. */
+  data=gal_fits_read_to_type(p->kernelname, p->khdu, GAL_DATA_TYPE_FLOAT,
+                             p->cp.minmapsize);
+
+  /* Put its values into the main program structure. */
+  p->ks0=data->dsize[0];
+  p->ks1=data->dsize[1];
+  p->kernel=data->array;
+
+  /* Convert all the NaN pixels to zero if the kernel contains blank
+     pixels. */
+  if(gal_data_has_blank(data))
+    gal_data_blank_to_value(data, &zero);
+
+  /* Clean up. Note that we need the array, so it must be set to NULL. */
+  data->array=NULL;
+  gal_data_free(data);
+}
+
+
+
+
+
+static void
+ui_preparations(struct convolveparams *p)
+{
+  double sum;
   size_t i, size;
-  int bitpix, anyblank;
-  struct uiparams *up=&p->up;
-  struct gal_commonparams *cp=&p->cp;
-  float *f, *fp, tmp, *kernel, sum;
-
-  /* First read the input image: */
-  gal_fits_file_to_float(up->inputname, up->maskname, cp->hdu, up->mhdu,
-                              &p->input, &bitpix, &p->anyblank,
-                              &p->is0, &p->is1);
-  gal_fits_read_wcs(up->inputname, cp->hdu, 0, 0, &p->nwcs, &p->wcs);
-  if(p->frequency && p->anyblank)
+  gal_data_t *data;
+  float *f, *ff, tmp;
+  char *outsuffix = p->makekernel ? "_kernel.fits" : "_convolved.fits";
+
+
+  /* Read the domain */
+  ui_read_domain(p);
+
+
+  /* Set the output name if the user hasn't set it. */
+  if(p->cp.output==NULL)
+    p->cp.output=gal_checkset_automatic_output(&p->cp, p->filename,
+                                               outsuffix);
+  if(p->checkfreqsteps)
+    p->freqstepsname=gal_checkset_automatic_output(&p->cp, p->filename,
+                                                   "_freqsteps.fits");
+  if(p->checkmesh)
+    p->meshname=gal_checkset_automatic_output(&p->cp, p->filename,
+                                              "_mesh.fits");
+
+
+  /* Read the input image as a float array and its WCS info. */
+  data=gal_fits_read_to_type(p->filename, p->cp.hdu, GAL_DATA_TYPE_FLOAT,
+                             p->cp.minmapsize);
+  gal_fits_read_wcs(p->filename, p->cp.hdu, 0, 0, &p->nwcs, &p->wcs);
+  p->unit=data->unit;
+  data->unit=NULL;
+
+
+  /* See if there are any blank values. */
+  if(gal_data_has_blank(data) && p->domain==CONVOLVE_DOMAIN_FREQUENCY)
     fprintf(stderr, "\n----------------------------------------\n"
             "######## %s WARNING ########\n"
-            "There are blank (masked) pixels in %s (hdu: %s) and you "
-            "have asked for frequency domain convolution.%s All the "
-            "convolved pixels will become blank. Only spatial domain "
-            "convolution can account for blank (masked) pixels in the "
-            "input data.\n"
+            "There are blank pixels in `%s' (hdu: `%s') and you have asked "
+            "for frequency domain convolution. As a result, all the pixels "
+            "in `%s' will be blank. Only spatial domain convolution can "
+            "account for blank pixels in the input data. You can run %s "
+            "again with `--domain=spatial'\n"
             "----------------------------------------\n\n",
-            SPACK_NAME, up->inputname, cp->hdu, up->maskname ?
-            "" : " Even though you have not provided any mask image, "
-            "these are the blank pixels in the input image, see the `Blank "
-            "pixels' section of the Gnuastro manual for more information.");
+            PROGRAM_NAME, p->filename, p->cp.hdu, p->cp.output, PROGRAM_NAME);
+
+
+  /* Get all the information from `gal_data_t' then free it. */
+  p->is0=data->dsize[0];
+  p->is1=data->dsize[1];
+  p->input=data->array;
+  data->array=NULL;
+  gal_data_free(data);
 
 
   /* Read the file specified by --kernel. If makekernel is specified, then
@@ -463,73 +369,72 @@ preparearrays(struct convolveparams *p)
   if(p->makekernel)
     {
       /* Read in the kernel array: */
-      gal_fits_file_to_float(up->kernelname, NULL, up->khdu, NULL,
-                             &p->kernel, &bitpix, &anyblank,
-                             &p->ks0, &p->ks1);
+      ui_read_kernel(p);
+
+      /* Make sure the size of the kernel is the same as the input */
       if(p->ks0!=p->is0 || p->ks1!=p->is1)
         error(EXIT_FAILURE, 0, "with the `--makekernel' (`-m') option, "
-              "the input image and the image specified with the kernel "
-              "option should have the same size. The lower resolution "
-              "input image (%s) has %zux%zu pixels while the higher "
-              "resolution image (%s) specified with the kernel option has "
-              "%zux%zu pixels", up->inputname, p->is1, p->is0,
-              up->kernelname, p->ks1, p->ks0);
+              "the input image and the image specified with the `--kernel' "
+              "(`-k') option should have the same size. The lower resolution "
+              "input image (%s) has %zux%zu pixels while the sharper image "
+              "(%s) specified with the kernel option has %zux%zu pixels",
+              p->filename, p->is1, p->is0, p->kernelname, p->ks1, p->ks0);
 
       /* Divide both images by their sum so their lowest frequency
          becomes 1 (and their division would be meaningful!).*/
       size=p->is0*p->is1;
-      sum=gal_statistics_float_sum(p->input, size);
-      gal_array_fmultip_const(p->input, size, 1/sum);
-      sum=gal_statistics_float_sum(p->kernel, size);
-      gal_array_fmultip_const(p->kernel, size, 1/sum);
+      sum=0.0f; ff=(f=p->input)+size; do sum+=*f++; while(f<ff);
+      f=p->input; do *f++ /= sum; while(f<ff);
+      sum=0.0f; ff=(f=p->kernel)+size; do sum+=*f++; while(f<ff);
+      f=p->kernel; do *f++ /= sum; while(f<ff);
     }
 
   /* Read the kernel. If there is anything particular to Convolve, then
      don't use the standard kernel reading function in fits.c. Otherwise
      just use the same one that all programs use. The standard one is
      faster because it mixes the NaN conversion and also the normalization
-     into one loop.*/
+     into one loop. */
   else
     {
-      if(p->kernelnorm==0 || p->kernelflip==0)
+      if(p->nokernelnorm || p->nokernelflip)
         {
           /* Read in the kernel array: */
-          gal_fits_file_to_float(up->kernelname, NULL, up->khdu, NULL,
-                                      &p->kernel, &bitpix, &anyblank,
-                                      &p->ks0, &p->ks1);
+          ui_read_kernel(p);
           size=p->ks0*p->ks1;
-          kernel=p->kernel;
 
+          /* Check its size (must be odd). */
           if(p->ks0%2==0 || p->ks1%2==0)
             error(EXIT_FAILURE, 0, "the kernel image has to have an odd "
                   "number of pixels on both sides (there has to be on pixel "
                   "in the center). %s (hdu: %s) is %zu by %zu",
-                  p->up.kernelname, p->up.khdu, p->ks1, p->ks0);
-
-          /* Convert all the NaN pixels to zero if the kernel contains
-             blank pixels. */
-          if(anyblank)
-            { fp=(f=kernel)+size; do if(isnan(*f)) *f=0.0f; while(++f<fp); }
+                  p->kernelname, p->khdu, p->ks1, p->ks0);
 
           /* Normalize the kernel: */
-          if(p->kernelnorm)
+          if( !p->nokernelnorm )
             {
-              sum=gal_statistics_float_sum(kernel, size);
-              gal_array_fmultip_const(kernel, size, 1/sum);
+              sum=0.0f; ff=(f=p->kernel)+size; do sum+=*f++; while(f<ff);
+              f=p->kernel; do *f++ /= sum; while(f<ff);
             }
 
           /* Flip the kernel: */
-          if(p->spatial && p->kernelflip)
+          if( !p->nokernelflip )
             for(i=0;i<size/2;++i)
               {
-                tmp=kernel[i];
-                kernel[i]=kernel[size-i-1];
-                kernel[size-i-1]=tmp;
+                tmp = p->kernel[i];
+                p->kernel[i] = p->kernel[size-i-1];
+                p->kernel[size-i-1]=tmp;
               }
         }
       else
-        gal_fits_prep_float_kernel(up->kernelname, up->khdu, &p->kernel,
-                                        &p->ks0, &p->ks1);
+        {
+          data=gal_fits_read_float_kernel(p->kernelname, p->khdu,
+                                          p->cp.minmapsize);
+          p->ks0=data->dsize[0];
+          p->ks1=data->dsize[1];
+          p->kernel=data->array;
+          data->array=NULL;
+          gal_data_free(data);
+        }
     }
 }
 
@@ -551,58 +456,72 @@ preparearrays(struct convolveparams *p)
 
 
 
-
 /**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
+static void
+ui_print_intro(struct convolveparams *p)
+{
+  printf("%s started on %s", PROGRAM_NAME, ctime(&p->rawtime));
+  printf("  - Using %zu CPU threads.\n", p->cp.numthreads);
+  printf("  - Input: %s (hdu: %s)\n", p->filename, p->cp.hdu);
+  printf("  - Kernel: %s (hdu: %s)\n", p->kernelname, p->khdu);
+}
+
+
+
+
+
 void
-setparams(int argc, char *argv[], struct convolveparams *p)
+ui_read_check_inputs_setup(int argc, char *argv[], struct convolveparams *p)
 {
-  struct gal_commonparams *cp=&p->cp;
+  struct gal_options_common_params *cp=&p->cp;
+
 
-  /* 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;
+  /* 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 non-zero options: */
-  p->kernelflip     = 1;
-  p->kernelnorm     = 1;
 
-  /* Read the arguments. */
+  /* Initialize the options and necessary information.  */
+  ui_initialize_options(p, program_options, gal_commonopts_options);
+
+
+  /* Read the command-line options and arguments. */
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
 
-  /* 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);
 
-  /* Print the values for each parameter. */
-  if(cp->printparams)
-    GAL_CONFIGFILES_REPORT_PARAMETERS_SET;
 
-  /* Do a sanity check, then remove the possibly existing log file
-     created by gal_txtarray_txt_to_array. */
-  sanitycheck(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);
 
-  /* Prepare the necessary arrays: */
-  preparearrays(p);
 
-  /* Everything is ready, notify the user of the program starting. */
-  if(cp->verb)
-    {
-      printf(SPACK_NAME" started on %s", ctime(&p->rawtime));
-      printf("  - Using %zu CPU threads.\n", p->cp.numthreads);
-      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);
-      printf("  - Kernel: %s (hdu: %s)\n", p->up.kernelname, p->up.khdu);
-    }
+  /* 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);
+
+
+  /* Everything is ready, print the intro if not in quiet mode. */
+  if(!p->cp.quiet)
+    ui_print_intro(p);
 }
 
 
@@ -628,22 +547,15 @@ setparams(int argc, char *argv[], struct convolveparams 
*p)
 /************      Free allocated, report         *************/
 /**************************************************************/
 void
-freeandreport(struct convolveparams *p, struct timeval *t1)
+ui_free_report(struct convolveparams *p, struct timeval *t1)
 {
-  free(p->input);
+  /* Free the allocated arrays: */
+  free(p->khdu);
   free(p->kernel);
   free(p->cp.hdu);
-  free(p->up.khdu);
-  free(p->meshname);
   free(p->cp.output);
-  wcsvfree(&p->nwcs, &p->wcs);
-
-  /* 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);
 
   /* Print the final message. */
-  if(p->cp.verb)
-    gal_timing_report(t1, SPACK_NAME" finished in: ", 0);
+  if(!p->cp.quiet)
+    gal_timing_report(t1, PROGRAM_NAME" finished in: ", 0);
 }
diff --git a/bin/convolve/ui.h b/bin/convolve/ui.h
index 47b0a65..937df9c 100644
--- a/bin/convolve/ui.h
+++ b/bin/convolve/ui.h
@@ -24,9 +24,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define UI_H
 
 void
-setparams(int argc, char *argv[], struct convolveparams *p);
+ui_read_check_inputs_setup(int argc, char *argv[], struct convolveparams *p);
 
 void
-freeandreport(struct convolveparams *p, struct timeval *t1);
+ui_free_report(struct convolveparams *p, struct timeval *t1);
 
 #endif
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index d53448c..a22c959 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -7395,25 +7395,43 @@ Section of the input image which you want to be 
cropped. See @ref{Crop
 section syntax} for a complete explanation on the syntax required for this
 input.
 
address@hidden -i INT
address@hidden --xcol=INT
-Column number of the first FITS axis position of the box center in a
-catalog, starting from zero. In SAO ds9, the first FITS axis is the
-horizontal axis.
-
address@hidden -j INT
address@hidden --ycol=INT
-Column number of the second FITS axis position of the box center, starting
-from zero. In SAO ds9, the second FITS axis is the vertical axis.
-
address@hidden -f INT
address@hidden --racol=INT
-Column number of Right Ascension (RA) in the input catalog, starting from
-zero.
-
address@hidden -g INT
address@hidden --deccol=INT
-Column number of declination in the input catalog, starting from zero.
address@hidden -i STR/INT
address@hidden --xcol=STR/INT
+Column selection for the first FITS axis position of the box center in a
+catalog. In SAO ds9, the first FITS axis is the horizontal axis. The value
+can be either the column number (starting from 1), or a match/search in the
+table meta-data, see @ref{Selecting table columns}.
+
address@hidden -j STR/INT
address@hidden --ycol=STR/INT
+Column selection for the second FITS axis position of the box center. In
+SAO ds9, the second FITS axis is the vertical axis. The value can be either
+the column number (starting from 1), or a match/search in the table
+meta-data, see @ref{Selecting table columns}.
+
address@hidden -f STR/INT
address@hidden --racol=STR/INT
+Column selection for Right Ascension (RA) in the input catalog. The value
+can be either the column number (starting from 1), or a match/search in the
+table meta-data, see @ref{Selecting table columns}.
+
address@hidden -g STR/INT
address@hidden --deccol=STR/INT
+Column selection of declination in the input catalog. The value can be
+either the column number (starting from 1), or a match/search in the table
+meta-data, see @ref{Selecting table columns}.
+
address@hidden -n STR/INT
address@hidden --namecol=STR/INT
+Column selection of crop file name. The value can be either the column
+number (starting from 1), or a match/search in the table meta-data, see
address@hidden table columns}. This option can be used both in Image and
+WCS modes, and not a mandatory. When a column is given to this option, the
+final crop base file name will be taken from the contents of this
+column. The directory will be determined by the @option{--output} option
+(current directory if not given) and the value to @option{--suffix} will be
+appended. When this column isn't given, the row number will be used
+instead.
 
 @end table
 
@@ -9504,24 +9522,20 @@ applied to the kernel.
 Do not normalize the kernel after reading it, such that the sum of its
 pixels is unity.
 
address@hidden -f
address@hidden --frequency
address@hidden -d STR
address@hidden --domain=STR
 @cindex Discrete Fourier transform
-Convolve using discrete Fourier transform in the frequency domain: The
-Fourier transform of both arrays is first calculated and
-multiplied. Then the inverse Fourier transform is applied to the
-product to give the final convolved image.
+The domain to use for the convolution. The acceptable values are
address@hidden' and address@hidden', corresponding to the respective
+domain.
 
-For large images, this process will be more efficient than convolving
-in the spatial domain. However, the edges of the image will loose some
-flux, see @ref{Edges in the spatial domain}.
-
address@hidden -p
address@hidden --spatial
-Convolve in the spatial domain, see @ref{Convolution process}.
+For large images, the frequency domain process will be more efficient than
+convolving in the spatial domain. However, the edges of the image will
+loose some flux (see @ref{Edges in the spatial domain}) and the image must
+not contain any blank pixels, see @ref{Spatial vs. Frequency domain}.
 
 
address@hidden --viewfreqsteps
address@hidden --checkfreqsteps
 With this option a file with the initial name of the output file will
 be created that is suffixed with @file{_freqsteps.fits}, all the steps
 done to arrive at the final convolved image are saved as extensions in
diff --git a/lib/data.c b/lib/data.c
index 2a4cf8f..212e3a4 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -383,11 +383,20 @@ gal_data_copy_wcs(gal_data_t *in, gal_data_t *out)
 {
   if(in->wcs)
     {
+      /* Allocate the output WCS structure. */
       errno=0;
       out->wcs=malloc(sizeof *out->wcs);
       if(out->wcs==NULL)
         error(EXIT_FAILURE, errno, "%zu bytes for out->wcs in "
               "gal_data_copy_wcs", sizeof *out->wcs);
+
+      /* Initialize the allocated WCS structure. The WCSLIB manual says "On
+         the first invokation, and only the first invokation, wcsprm::flag
+         must be set to -1 to initialize memory management"*/
+      out->wcs->flag=-1;
+      wcsini(1, out->ndim, out->wcs);
+
+      /* Copy the input WCS to the output WSC structure. */
       wcscopy(1, in->wcs, out->wcs);
     }
   else
diff --git a/lib/fits.c b/lib/fits.c
index dcde619..34667de 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -31,6 +31,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <string.h>
 #include <unistd.h>
 
+#include <gsl/gsl_version.h>
+
 #include <gnuastro/git.h>
 #include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
@@ -1034,7 +1036,7 @@ gal_fits_write_keys_version(fitsfile *fptr, struct 
gal_fits_key_ll *headers,
   fits_update_key(fptr, TSTRING, "CFITSIO", cfitsioversion,
                   "CFITSIO version.", &status);
 
-  /* Write the WCSLIB version */
+  /* Write the WCSLIB version. */
 #ifdef GAL_CONFIG_HAVE_WCSLIB_VERSION
   wcslibversion_const=wcslib_version(wcslibvers);
   strcpy(wcslibversion, wcslibversion_const);
@@ -1042,6 +1044,10 @@ gal_fits_write_keys_version(fitsfile *fptr, struct 
gal_fits_key_ll *headers,
                   "WCSLIB version.", &status);
 #endif
 
+  /* Write the GSL version. */
+  fits_update_key(fptr, TSTRING, "GSL", GSL_VERSION,
+                  "GNU Scientific Library version.", &status);
+
   /* Write the Gnuastro version. */
   fits_update_key(fptr, TSTRING, "GNUASTRO", PACKAGE_VERSION,
                   "GNU Astronomy Utilities version.", &status);
@@ -1380,7 +1386,7 @@ gal_fits_read_float_kernel(char *filename, char *hdu, 
size_t minmapsize)
      number. If they are all an odd number, then the for each dimension,
      check will be incremented once. */
   for(i=0;i<kernel->ndim;++i)
-    check=kernel->dsize[i]%2;
+    check += kernel->dsize[i]%2;
   if(check!=kernel->ndim)
     error(EXIT_FAILURE, 0, "the kernel image has to have an odd number "
           "of pixels in all dimensions (there has to be one element/pixel "
@@ -1441,9 +1447,13 @@ gal_fits_write_img_fitsptr(gal_data_t *data, char 
*filename)
   else
     fits_create_file(&fptr, filename, &status);
 
-  /* Create the FITS file and put the image into it. */
+  /* Create the FITS file and remove the two initial lines of comments */
   fits_create_img(fptr, gal_fits_type_to_bitpix(data->type),
                   data->ndim, naxes, &status);
+  fits_delete_key(fptr, "COMMENT", &status);
+  fits_delete_key(fptr, "COMMENT", &status);
+
+  /* Write the image into the file. */
   fits_write_img(fptr, datatype, fpixel, data->size, data->array, &status);
 
   /* If we have blank pixels, we need to define a BLANK keyword when we are
diff --git a/lib/gnuastro/mesh.h b/lib/gnuastro/mesh.h
index 580cade..66ac5ba 100644
--- a/lib/gnuastro/mesh.h
+++ b/lib/gnuastro/mesh.h
@@ -142,7 +142,7 @@ struct gal_mesh_params
   float          *kernel; /* Convolution kernel.                         */
   size_t             ks0; /* Size of kernel along first C axis.          */
   size_t             ks1; /* Size of kernel along second C axis.         */
-  int    fullconvolution; /* ==1: Convove over all channels.             */
+  unsigned char fullconvolution; /* ==1: Convove over all channels.      */
 
   /* Mesh types and information: */
   int     meshbasedcheck; /* ==1: use one pixel for each mesh in checks. */
diff --git a/tests/convolve/frequency.sh b/tests/convolve/frequency.sh
index 2b9d76f..10b6a80 100755
--- a/tests/convolve/frequency.sh
+++ b/tests/convolve/frequency.sh
@@ -49,4 +49,4 @@ if [ ! -f $execname ] || [ ! -f $img ] || [ ! -f $psf ]; then 
exit 77; fi
 
 # Actual test script
 # ==================
-$execname $img --kernel=$psf --frequency --output=convolve_frequency.fits
+$execname $img --kernel=$psf --domain=frequency 
--output=convolve_frequency.fits
diff --git a/tests/convolve/spatial.sh b/tests/convolve/spatial.sh
index e6fee81..d9cebc2 100755
--- a/tests/convolve/spatial.sh
+++ b/tests/convolve/spatial.sh
@@ -49,4 +49,4 @@ if [ ! -f $execname ] || [ ! -f $img ] || [ ! -f $psf ]; then 
exit 77; fi
 
 # Actual test script
 # ==================
-$execname $img --kernel=$psf --spatial --output=convolve_spatial.fits
+$execname $img --kernel=$psf --domain=spatial --output=convolve_spatial.fits
diff --git a/tmpfs-config-make b/tmpfs-config-make
index 5310a84..656087a 100755
--- a/tmpfs-config-make
+++ b/tmpfs-config-make
@@ -130,9 +130,10 @@ cd $build_dir
 #
 # ####################################
 if [ ! -f Makefile ]; then
-    $srcdir/configure --srcdir=$srcdir --disable-shared CFLAGS="-g -O0"      \
-                      --enable-arithmetic --enable-cosmiccal --enable-header \
-                      --enable-imgcrop --enable-mkprof --enable-table
+    $srcdir/configure --srcdir=$srcdir --disable-shared CFLAGS="-g -O0"       \
+                      --enable-arithmetic --enable-convolve --enable-cosmiccal\
+                      --enable-header --enable-imgcrop --enable-mkprof        \
+                      --enable-table
 fi
 
 



reply via email to

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