gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master b555011a 5/6: Library (arithmetic.h): new trim


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master b555011a 5/6: Library (arithmetic.h): new trim operator
Date: Tue, 11 Jul 2023 22:04:09 -0400 (EDT)

branch: master
commit b555011a769b021d007db2d387c9ba952937571b
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (arithmetic.h): new trim operator
    
    Until now, there was no easy way to trim blank rows and columns in an
    image. But this is an oftenly necessary operator, especially within the
    context of the dithering pattern that we are adding in this branch.
    
    With this commit, a first draft implementation of this operator has been
    added and will be tested more during the work on this branch.
    
    Also, with this commit:
    - The process of writing a tutorial for the dither simulation installed
      script has begun.
    - Furthermore, the tutorial on re-gridding different filters into the same
      grid for producing a color image has also been moved to the Tutorials
      chapter (previously it was under the ConvertType program, making it hard
      to find for a new user).
    
    - The reminder parts of the book that didn't follow the
      one-sentence-per-line convention have been corrected.
---
 bin/arithmetic/arithmetic.c   |   13 +
 bin/script/Makefile.am        |    5 +-
 bin/script/dither-simulate.in |    6 +-
 doc/gnuastro.texi             | 3854 ++++++++++++++++-------------------------
 lib/arithmetic.c              |   13 +-
 lib/blank.c                   |  236 ++-
 lib/gnuastro/arithmetic.h     |    1 +
 lib/gnuastro/blank.h          |    6 +
 8 files changed, 1758 insertions(+), 2376 deletions(-)

diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index 7e3dfed0..0d0f5045 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -1520,6 +1520,11 @@ arithmetic_operator_run(struct arithmeticparams *p, int 
operator,
           d1=arithmetic_prepare_meta(d1, d2, d3);
           break;
 
+        /* Operators that also modify the reference WCS. */
+        case GAL_ARITHMETIC_OP_TRIM:
+          d1->wcs=gal_wcs_copy(p->refdata.wcs);
+          break;
+
         /* Operators that need/modify the WCS. */
         case GAL_ARITHMETIC_OP_POOLMAX:
         case GAL_ARITHMETIC_OP_POOLMIN:
@@ -1558,6 +1563,14 @@ arithmetic_operator_run(struct arithmeticparams *p, int 
operator,
       operands_add(p, NULL, gal_arithmetic(operator, p->cp.numthreads,
                                            flags, d1, d2, d3, d4));
 
+      /* Operators with special attention afterwards. */
+      switch(operator)
+        {
+        case GAL_ARITHMETIC_OP_TRIM:
+          gal_wcs_free(p->refdata.wcs);
+          p->refdata.wcs=gal_wcs_copy(p->operands->data->wcs);
+          break;
+        }
     }
 
   /* No need to call the arithmetic library, call the proper wrappers
diff --git a/bin/script/Makefile.am b/bin/script/Makefile.am
index 21791a6a..788c8c8a 100644
--- a/bin/script/Makefile.am
+++ b/bin/script/Makefile.am
@@ -24,7 +24,9 @@
 
 # Data files (necessary for various components like desktop files for GUIs
 # or Makefiles that are called within scripts).
-pkgdata_DATA = astscript-fits-view.desktop zeropoint.mk
+pkgdata_DATA = zeropoint.mk \
+               dither-simulate.mk \
+               astscript-fits-view.desktop
 astscript-fits-view.desktop: $(srcdir)/fits-view.desktop.in Makefile
        sed -e 's|@PREFIX[@]|$(exec_prefix)|g' \
            $(srcdir)/fits-view.desktop.in > $@
@@ -59,6 +61,7 @@ EXTRA_DIST = fits-view.in \
              sort-by-night.in \
              radial-profile.in \
              dither-simulate.in \
+             dither-simulate.mk \
              psf-select-stars.in \
              psf-scale-factor.in \
              fits-view.desktop.in
diff --git a/bin/script/dither-simulate.in b/bin/script/dither-simulate.in
index bf591010..97f2082f 100644
--- a/bin/script/dither-simulate.in
+++ b/bin/script/dither-simulate.in
@@ -327,7 +327,11 @@ fi
 # this configuration file (and the variables within it).
 counter=1;
 config=$tmpdir/dither-simulate.conf
-ndither=$(astfits $cat --hdu=$hdu --keyvalue=NAXIS2 --quiet)
+if astfits $cat &> /dev/null; then
+    ndither=$(astfits $cat --hdu=$hdu --keyvalue=NAXIS2 --quiet)
+else
+    ndither=$(awk '!/^#/ && NF>1' $cat | wc -l)
+fi
 echo "img = $img" > $config
 echo "width = $width" >> $config
 echo "quiet = $quiet" >> $config
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 8ad5dbd8..0f11433a 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -274,6 +274,8 @@ Tutorials
 * Building the extended PSF::   How to extract an extended PSF from science 
data.
 * Sufi simulates a detection::  Simulating a detection.
 * Detecting lines and extracting spectra in 3D data::  Extracting spectra and 
emission line properties.
+* Color channels in same pixel grid::  Aligning images to same grid to build 
color image.
+* Dither pattern design::       Simulate the output image of a given dither 
pattern.
 
 General program usage tutorial
 
@@ -463,7 +465,6 @@ ConvertType
 * Raster and Vector graphics::  Images coming from nature, and the abstract.
 * Recognized file formats::     Recognized file formats
 * Color::                       Some explanations on color.
-* Color channels in same pixel grid::  When the WCS slightly differs.
 * Annotations for figure in paper::  Adding coordinates or physical scale.
 * Invoking astconvertt::        Options and arguments to ConvertType.
 
@@ -781,7 +782,6 @@ Invoking astscript-zeropoint
 
 Dithering pattern simulation
 
-* Stack from a cross-shaped dither::
 * Invoking astscript-dither-simulate::  Options and running mode.
 
 PSF construction and subtraction
@@ -2026,6 +2026,8 @@ For an explanation of the conventions we use in the 
example codes through the bo
 * Building the extended PSF::   How to extract an extended PSF from science 
data.
 * Sufi simulates a detection::  Simulating a detection.
 * Detecting lines and extracting spectra in 3D data::  Extracting spectra and 
emission line properties.
+* Color channels in same pixel grid::  Aligning images to same grid to build 
color image.
+* Dither pattern design::       Simulate the output image of a given dither 
pattern.
 @end menu
 
 
@@ -7798,7 +7800,7 @@ It was nearly sunset and they had to begin preparing for 
the night's measurement
 
 
 
-@node Detecting lines and extracting spectra in 3D data,  , Sufi simulates a 
detection, Tutorials
+@node Detecting lines and extracting spectra in 3D data, Color channels in 
same pixel grid, Sufi simulates a detection, Tutorials
 @section Detecting lines and extracting spectra in 3D data
 
 @cindex IFU
@@ -8679,6 +8681,165 @@ Click on the scroll-down menu in front of ``Table'' and 
select @file{2: collapse
 Afterwards, you will see the optimized pseudo-narrow-band image radial profile 
as blue points.
 @end enumerate
 
+@node Color channels in same pixel grid, Dither pattern design, Detecting 
lines and extracting spectra in 3D data, Tutorials
+@section Color channels in same pixel grid
+
+In order to use different images as color channels, it is important that the 
images be properly aligned and on the same pixel grid.
+When your inputs are high-level products of the same survey, this is usually 
the case.
+However, in many other situations the images you plan to use as different 
color channels lie on different sky positions, even if they may have the same 
number of pixels.
+In this section we will show how to solve this problem.
+
+For an example dataset, let's use the same SDSS field that we used in 
@ref{Detecting large extended targets}: the field covering the outer parts of 
the M51 group.
+With the commands below, we'll make an @file{inputs} directory and download 
and prepare the three g, r and i band images of SDSS over the same field there:
+
+@example
+$ mkdir inputs
+$ sdssurl=https://dr12.sdss.org/sas/dr12/boss/photoObj/frames
+$ for f in g r i; do \
+      wget $sdssurl/301/3716/6/frame-$f-003716-6-0117.fits.bz2 \
+           -O$f.fits.bz2; \
+      bunzip2 $f.fits.bz2; \
+      astfits $f.fits --copy=0 -oinputs/$f.fits; \
+      rm $f.fits; \
+  done
+@end example
+
+With the commands below, first we'll check the size of all three images to 
confirm that they have exactly the same number of pixels.
+Then we'll use them as three color channels to construct a PDF image:
+
+@example
+## Check the number of pixels along each axis of all images.
+$ astfits inputs/*.fits --keyvalue=NAXIS1,NAXIS2
+
+## Create a color image from the non-yet-aligned inputs.
+$ astconvertt inputs/i.fits inputs/r.fits inputs/g.fits -g1 \
+              --fluxhigh=1 -om51-not-aligned.pdf
+@end example
+
+Open @file{m51-not-aligned.pdf} with your PDF viewer, and zoom-in to some part 
of the image with fewer sources.
+You will clearly see that for each object, there are three copies, one in red 
(from the reddest filter; i), one in green (from the middle filter; r), and one 
in blue (the bluest filter; g).
+Did you see the Warning message that was printed after your latest command?
+We have implemented a check in Warp to inform you when the images are not 
aligned and can produce bad (in most cases!) outputs like this.
+
+To solve this problem, you need to align the three color channels into the 
same pixel grid.
+To do that, we will use the @ref{Warp} program and in particular, its 
@ref{Align pixels with WCS considering distortions}.
+
+Let's take the middle (r band) filter as the reference to define our grid.
+With the first command below, let's align the r band filter to the celestial 
coordinates (so the M51 group's position angle doesn't depend on the 
orientation of the telescope when it took this image).
+With the next two commands, let's use the @option{--gridfile} to ensure that 
the pixel grid and WCS comes from the r band image, but the pixel values come 
from the other two filters.
+Finally, in the last command, we'll produce the color PDF from the three 
aligned images (that aren't in the @file{inputs/} directory any more):
+
+@example
+## Put all three channels in the same pixel grid.
+$ astwarp inputs/r.fits                   --output=r.fits
+$ astwarp inputs/g.fits --gridfile=r.fits --output=g.fits
+$ astwarp inputs/i.fits --gridfile=r.fits --output=i.fits
+
+## Create a color image from the aligned inputs.
+$ astconvertt i.fits r.fits g.fits -g1 --fluxhigh=1 -om51.pdf
+@end example
+
+Open the new @file{m51.pdf} and compare it with the old 
@file{m51-not-aligned.pdf}.
+The difference is obvious!
+When you zoom-in, the stars are very clear and the different color channels of 
the same object in the sky don't fall on different pixels.
+If you look closely on the two longer edges of the image, you will see that 
one edge has a thin green shadow and the other has a thin red shadow.
+This shows how green and red channels have been slightly shifted to put your 
astronomical sources on the same grid.
+
+If you don't want to have those, or if you want the outer parts of the final 
image (where there was no data) to be white, some more complex commands are 
necessary.
+We'll leave those as an exercise for you to try your self using @ref{Warp} 
and/or @ref{Crop} to pre-process the inputs before converting it to a color 
image.
+
+@node Dither pattern design,  , Color channels in same pixel grid, Tutorials
+@section Dither pattern design
+
+Dithering is one of the most important steps when planning your observation 
strategy.
+Dithering is the process of (slightly) moving each exposure compared to the 
previous one and is done for several reasons like increasing resolution, 
expending the area of the observation and etc.
+For a more complete introduction to dithering, see @ref{Dithering pattern 
simulation}.
+As of version 0.21, Gnuastro comes with the 
@command{astscript-dither-simulate} script to help design the best observation 
strategy for your scientific goal.
+
+In this tutorial, let's assume you want to make a deep observation of 
@url{https://en.wikipedia.org/wiki/Messier_94, M94} in the H-alpha and rSDSS 
filters@footnote{For the full list of available filters, see the 
@url{https://oaj.cefca.es/telescopes/t80cam, T80Cam description}.} (to study 
the extended star formation in the outer rings of this beautiful galaxy!).
+Including the outer parts of the rings, the galaxy is half a degree in 
diameter!
+This is very large, and you want to design a dither pattern that will cover 
this area with the maximum depth!
+Therefore, you need an instrument with a large field of view.
+Here, we'll assume you want to write a proposal for the 
@url{https://oaj.cefca.es/telescopes/jast80, JAST80 telescope} at 
@url{https://oaj.cefca.es, Observatorio Astrofísico de Javalambre}, 
OAJ@footnote{For full disclosure, Gnuastro is being developed at CEFCA (Centro 
de Estudios de F@'isica del Cosmos de Arag@'on); which also hosts OAJ.}, in 
Teruel (Spain).
+
+As described in @ref{Dithering pattern simulation}, it is just important to 
remember that the ideal dither pattern depends primarily on your scientific 
objective for the observation, as well as the limitations of the instrument you 
are observing with.
+Therefore, there is no single dither pattern for all purposes.
+However, the tools and methods to check if your dither pattern satisfies your 
scientific requirement are similar.
+Therefore, you can use the same methods/tools here to simulate or verify that 
your dither pattern will produce the products you expect after the observation.
+The hypothetical scenario above is just an example to show the usage.
+
+To start simulating a dither pattern for a certain telescope, you just need a 
single-exposure image of that telescope with WCS information.
+In other words, after astrometry, but before warping into any other pixel grid 
(to combine into a deeper stack).
+The image will give us the default number of the camera's pixels, its pixel 
scale (width of pixel on the in arcseconds) and the camera distortion.
+These are reference parameters that are independent of the position of the 
image on the sky.
+
+Because the actual position of the reference image is irrelevant, let's assume 
that in a previous project, persumably on 
@url{https://en.wikipedia.org/wiki/NGC_4395, NGC 4395}, you had the download 
command of the following single exposure image.
+
+@example
+$ siapurl=https://archive.cefca.es/catalogues/vo/siap
+$ wget $siapurl/jplus-dr3/reduced/get_fits?id=1050345 \
+       -Ojplus-1050345.fits.fz
+@end example
+
+In case you haven't already used images from your target telescope (to use as 
reference), you can find such images from their public archives; or contacting 
them.
+A single exposure images is rarely of any scientific value (post-processing 
and stacking is necessary to make high-level and science-ready products).
+
+The T80Cam images are large (9216 by 9232 pixels).
+Therefore, to simplify the dither testing, let's down-sample the image above 
by a factor of 10 to help speed up the testing.
+This step is optional and you can safely use the full resolution, which will 
give you a more precise stack, but which will be slower.
+We will call the output @file{ref.fits} because it is the reference image).
+
+@example
+$ astwarp jplus-1050345.fits.fz --scale=1/10 -oref.fits
+@end example
+
+For a first trial, let's create a cross-shaped dither pattern around M94 
(which is centered at RA and Dec of 192.721250, 41.120556).
+We'll center one exposure on the center of the galaxy, and include 4 more 
exposures that are each 10 arcminutes away along the RA and Dec axies.
+To simplify the actual command, we'll include the column names through two 
lines of metadata.
+Instead of this, you could use the @option{--racol=1} and @option{--deccol=2} 
options, but having metadata is always preferred (will avoid many bugs!).
+
+@example
+$ step_arcmin=10
+$ center_ra=192.721250
+$ center_dec=41.120556
+
+$ echo "# Column 1: RA  [deg, f64] Right Ascension"  > dither.txt
+$ echo "# Column 2: Dec [deg, f64] Declination"     >> dither.txt
+
+$ echo $center_ra $center_dec \
+       | awk '@{step='$step_arcmin'/60; fmt="%-10.6f %-10.6f\n"; \
+               printf fmt, $1,      $2; \
+               printf fmt, $1+step, $2; \
+               printf fmt, $1,      $2+step; \
+               printf fmt, $1-step, $2; \
+               printf fmt, $1,      $2-step@}' \
+       >> dither.txt
+
+$ cat dither.txt
+# Column 1: RA  [deg, f64] Right Ascension
+# Column 2: DEC [deg, f64] Declination
+192.721250 41.120556
+192.887917 41.120556
+192.721250 41.287223
+192.554583 41.120556
+192.721250 40.953889
+@end example
+
+We are now ready to generate the exposure map of the dither pattern above 
using the reference image that we made before it.
+We'll put the center of our final stack to be on the center of the galaxy, and 
we'll assume the stack has a size of 2 degrees.
+With the second command, you can see the exposure map of the final stack.
+Recall that in this image, each pixel shows the number of input images that 
went into it.
+
+@example
+$ astscript-dither-simulate dither.txt --output=stack.fits \
+           --img=ref.fits --center=$center_ra,$center_dec \
+           --width=2
+
+$ astscript-fits-view stack.fits
+@end example
+
+
+
 @node Installation, Common program behavior, Tutorials, Top
 @chapter Installation
 
@@ -13908,7 +14069,6 @@ A tutorial on how to add markers over an image is then 
given in @ref{Marking obj
 * Raster and Vector graphics::  Images coming from nature, and the abstract.
 * Recognized file formats::     Recognized file formats
 * Color::                       Some explanations on color.
-* Color channels in same pixel grid::  When the WCS slightly differs.
 * Annotations for figure in paper::  Adding coordinates or physical scale.
 * Invoking astconvertt::        Options and arguments to ConvertType.
 @end menu
@@ -14080,7 +14240,7 @@ To print to the standard output, set the output name to 
`@file{stdout}'.
 
 @end table
 
-@node Color, Color channels in same pixel grid, Recognized file formats, 
ConvertType
+@node Color, Annotations for figure in paper, Recognized file formats, 
ConvertType
 @subsection Color
 
 @cindex RGB
@@ -14216,75 +14376,7 @@ $ astconvertt --listcolors
 @caption{Recognized color names in Gnuastro, shown with their numerical 
identifiers.}
 @end float
 
-
-@node Color channels in same pixel grid, Annotations for figure in paper, 
Color, ConvertType
-@subsection Color channels in same pixel grid
-
-In order to use different images as color channels, it is important that the 
images be properly aligned and on the same pixel grid.
-When your inputs are high-level products of the same survey, this is usually 
the case.
-However, in many other situations the images you plan to use as different 
color channels lie on different sky positions, even if they may have the same 
number of pixels.
-In this section we will show how to solve this problem.
-
-For an example dataset, let's use the same SDSS field that we used in 
@ref{Detecting large extended targets}: the field covering the outer parts of 
the M51 group.
-With the commands below, we'll make an @file{inputs} directory and download 
and prepare the three g, r and i band images of SDSS over the same field there:
-
-@example
-$ mkdir inputs
-$ sdssurl=https://dr12.sdss.org/sas/dr12/boss/photoObj/frames
-$ for f in g r i; do \
-      wget $sdssurl/301/3716/6/frame-$f-003716-6-0117.fits.bz2 \
-           -O$f.fits.bz2; \
-      bunzip2 $f.fits.bz2; \
-      astfits $f.fits --copy=0 -oinputs/$f.fits; \
-      rm $f.fits; \
-  done
-@end example
-
-With the commands below, first we'll check the size of all three images to 
confirm that they have exactly the same number of pixels.
-Then we'll use them as three color channels to construct a PDF image:
-
-@example
-## Check the number of pixels along each axis of all images.
-$ astfits inputs/*.fits --keyvalue=NAXIS1,NAXIS2
-
-## Create a color image from the non-yet-aligned inputs.
-$ astconvertt inputs/i.fits inputs/r.fits inputs/g.fits -g1 \
-              --fluxhigh=1 -om51-not-aligned.pdf
-@end example
-
-Open @file{m51-not-aligned.pdf} with your PDF viewer, and zoom-in to some part 
of the image with fewer sources.
-You will clearly see that for each object, there are three copies, one in red 
(from the reddest filter; i), one in green (from the middle filter; r), and one 
in blue (the bluest filter; g).
-Did you see the Warning message that was printed after your latest command?
-We have implemented a check in Warp to inform you when the images are not 
aligned and can produce bad (in most cases!) outputs like this.
-
-To solve this problem, you need to align the three color channels into the 
same pixel grid.
-To do that, we will use the @ref{Warp} program and in particular, its 
@ref{Align pixels with WCS considering distortions}.
-
-Let's take the middle (r band) filter as the reference to define our grid.
-With the first command below, let's align the r band filter to the celestial 
coordinates (so the M51 group's position angle doesn't depend on the 
orientation of the telescope when it took this image).
-With the next two commands, let's use the @option{--gridfile} to ensure that 
the pixel grid and WCS comes from the r band image, but the pixel values come 
from the other two filters.
-Finally, in the last command, we'll produce the color PDF from the three 
aligned images (that aren't in the @file{inputs/} directory any more):
-
-@example
-## Put all three channels in the same pixel grid.
-$ astwarp inputs/r.fits                   --output=r.fits
-$ astwarp inputs/g.fits --gridfile=r.fits --output=g.fits
-$ astwarp inputs/i.fits --gridfile=r.fits --output=i.fits
-
-## Create a color image from the aligned inputs.
-$ astconvertt i.fits r.fits g.fits -g1 --fluxhigh=1 -om51.pdf
-@end example
-
-Open the new @file{m51.pdf} and compare it with the old 
@file{m51-not-aligned.pdf}.
-The difference is obvious!
-When you zoom-in, the stars are very clear and the different color channels of 
the same object in the sky don't fall on different pixels.
-If you look closely on the two longer edges of the image, you will see that 
one edge has a thin green shadow and the other has a thin red shadow.
-This shows how green and red channels have been slightly shifted to put your 
astronomical sources on the same grid.
-
-If you don't want to have those, or if you want the outer parts of the final 
image (where there was no data) to be white, some more complex commands are 
necessary.
-We'll leave those as an exercise for you to try your self using @ref{Warp} 
and/or @ref{Crop} to pre-process the inputs before converting it to a color 
image.
-
-@node Annotations for figure in paper, Invoking astconvertt, Color channels in 
same pixel grid, ConvertType
+@node Annotations for figure in paper, Invoking astconvertt, Color, ConvertType
 @subsection Annotations for figure in paper
 
 @cindex Image annotation
@@ -19171,6 +19263,41 @@ This leaves the the two @mymath{300\times300} images 
on the stack (see @ref{Reve
 We finally stitch those two along the second (vertical) dimension.
 This operator is therefore useful in scenarios like placing the CCD amplifiers 
into one image.
 
+@item trim
+Trim all blank elements from the outer edges of the input operand (it only 
takes a single operand).
+For example see the commands below using Table's @ref{Column arithmetic}:
+
+@example
+$  cat table.txt
+nan
+nan
+nan
+3
+4
+nan
+5
+6
+nan
+
+$ asttable table.txt -Y -c'arith $1 trim'
+3.000000
+4.000000
+nan
+5.000000
+6.000000
+@end example
+
+Similarly, on 2D images or 3D cubes, all outer rows/columns or slices that are 
fully blank get ``trim''ed with this operator.
+This is therefore a very useful operator for extracting a certain feature 
within your dataset.
+
+For example, let's assume that you have set @ref{NoiseChisel} and 
@ref{Segment} on an image to extract all clumps and objects.
+With the command below on Segment's output, you will have a smaller image that 
only contains the sky-subtracted input pixels corresponding to object 263.
+
+@example
+$ astarithmetic seg.fits -hINPUT seg.fits -hOBJECTS \
+                263 ne nan where trim --output=obj-263.fits
+@end example
+
 @item collapse-sum
 Collapse the given dataset (second popped operand), by summing all elements 
along the first popped operand (a dimension in FITS standard: counting from 
one, from fastest dimension).
 The returned dataset has one dimension less compared to the input.
@@ -31916,40 +32043,15 @@ For example in the XDF survey is focused on very high 
redshift (most distant!) g
 These are very small objects and within that small footprint (of just 1 
arcmin) we have thousands of them.
 However, the LIGHTS survey is focused on the halos of large nearby galaxies 
(that can be more than 10 arcminutes wide!).
 
-In @ref{Invoking astscript-dither-simulate} we describe one of Gnuastro's 
@ref{Installed scripts} that is designed to simplify the process of selecting 
the best dithering pattern for your observation strategy.
+In @ref{Invoking astscript-dither-simulate} of Gnuastro's @ref{Installed 
scripts} is described in detail.
+This script is designed to simplify the process of selecting the best 
dithering pattern for your observation strategy.
+For a more practical tutorial, see @ref{Dither pattern design}.
 
 @menu
-* Stack from a cross-shaped dither:: A tutorial on how to use this script.
 * Invoking astscript-dither-simulate::  Options and running mode.
 @end menu
 
-@node Stack from a cross-shaped dither, Invoking astscript-dither-simulate, 
Dithering pattern simulation, Dithering pattern simulation
-@subsection Stack from a cross-shaped dither
-
-The example usage below shows how to simulate a dither pattern centered on the 
RA,Dec of 10,10 with 5 pointings that are 0.1 degrees away from the central one 
, in a +-shaped orientation (see contents of @file{dither.fits} in the first 
command below).
-Since it depends on the camera distortion and orientation, an input image is 
necessary; here we'll download an SDSS image with the second command.
-This script (which is called in the second command) will produce a final image 
showing the exposure map that will be produced after stacking these 5 exposures.
-
-@example
-$ asttable dither.fits -O
-# Column 1: RA  [deg, f32] Right Ascension of pointing center
-# Column 2: DEC [deg, f32] Declination of pointing center
-10.0   10.0
-10.1   10.0
-10.0   10.1
--9.9   10.0
--9.9   -9.9
-
-$ wget $sdssurl/301/3716/6/frame-r-003716-6-0117.fits.bz2 \
-       -Or.fits.bz2
-$ bunzip2 r.fits.bz2
-
-$ astscript-dither-simulate dither.fits --center=10,10 --width=1,1 \
-                            --img=r.fits --output=stack.fits
-@end example
-
-
-@node Invoking astscript-dither-simulate,  , Stack from a cross-shaped dither, 
Dithering pattern simulation
+@node Invoking astscript-dither-simulate,  , Dithering pattern simulation, 
Dithering pattern simulation
 @subsection Invoking astscript-dither-simulate
 
 This installed script will simulate a final stacked image from a certain 
dither pattern (given as a table).
@@ -31960,7 +32062,7 @@ $ astscript-dither-simulate [OPTION...] pointings.fits
 @end example
 
 @noindent
-Examples (for a tutorial, see @ref{Stack from a cross-shaped dither}):
+Examples (for a tutorial, see @ref{Dither pattern design}):
 
 @example
 $ astscript-dither-simulate dither.fits --output=stack.fits \
@@ -34485,28 +34587,19 @@ If @code{quietmmap} is non-zero, then a warning will 
be printed for the user to
 
 @node Library blank values, Library data container, Pointers, Gnuastro library
 @subsection Library blank values (@file{blank.h})
-When the position of an element in a dataset is important (for example, a
-pixel in an image), a place-holder is necessary for the element if we do not
-have a value to fill it with (for example, the CCD cannot read those
-pixels). We cannot simply shift all the other pixels to fill in the one we
-have no value for. In other cases, it often occurs that the field of sky
-that you are studying is not a clean rectangle to nicely fit into the
-boundaries of an image. You need a way to separate the pixels outside your
-scientific field from those inside it. Blank values act as these place
-holders in a dataset. They have no usable value but they have a position.
+When the position of an element in a dataset is important (for example, a 
pixel in an image), a place-holder is necessary for the element if we do not 
have a value to fill it with (for example, the CCD cannot read those pixels).
+We cannot simply shift all the other pixels to fill in the one we have no 
value for.
+In other cases, it often occurs that the field of sky that you are studying is 
not a clean rectangle to nicely fit into the boundaries of an image.
+You need a way to separate the pixels outside your scientific field from those 
inside it.
+Blank values act as these place holders in a dataset.
+They have no usable value but they have a position.
 
 @cindex NaN
-Every type needs a corresponding blank value (see @ref{Numeric data types}
-and @ref{Library data types}). Floating point types have a unique value
-identified by IEEE known as Not-a-Number (or NaN) which is a unique value
-that is recognized by the compiler. However, integer and string types do not
-have any standard value. For integers, in Gnuastro we take an extremum of
-the given type: for signed types (that allow negatives), the minimum
-possible value is used as blank and for unsigned types (that only accept
-positives), the maximum possible value is used. To be generic and easy to
-read/write we define a macro for these blank values and strongly encourage
-you only use these, and never make any assumption on the value of a type's
-blank value.
+Every type needs a corresponding blank value (see @ref{Numeric data types} and 
@ref{Library data types}).
+Floating point types have a unique value identified by IEEE known as 
Not-a-Number (or NaN) which is a unique value that is recognized by the 
compiler.
+However, integer and string types do not have any standard value.
+For integers, in Gnuastro we take an extremum of the given type: for signed 
types (that allow negatives), the minimum possible value is used as blank and 
for unsigned types (that only accept positives), the maximum possible value is 
used.
+To be generic and easy to read/write we define a macro for these blank values 
and strongly encourage you only use these, and never make any assumption on the 
value of a type's blank value.
 
 @cindex NaN
 The IEEE NaN blank value type is defined to fail on any comparison, so if you 
are dealing with floating point types, you cannot use equality (a NaN will 
@emph{not} be equal to a NaN).
@@ -34547,18 +34640,15 @@ Blank value for a signed, 64-bit integer.
 @end deffn
 
 @deffn {Global integer}  GAL_BLANK_INT
-Blank value for @code{int} type (@code{int16_t} or @code{int32_t} depending
-on the system.
+Blank value for @code{int} type (@code{int16_t} or @code{int32_t} depending on 
the system.
 @end deffn
 
 @deffn {Global integer}  GAL_BLANK_UINT
-Blank value for @code{int} type (@code{int16_t} or @code{int32_t} depending
-on the system.
+Blank value for @code{int} type (@code{int16_t} or @code{int32_t} depending on 
the system.
 @end deffn
 
 @deffn {Global integer}  GAL_BLANK_LONG
-Blank value for @code{long} type (@code{int32_t} or @code{int64_t} in
-32-bit or 64-bit systems).
+Blank value for @code{long} type (@code{int32_t} or @code{int64_t} in 32-bit 
or 64-bit systems).
 @end deffn
 
 @deffn {Global integer}  GAL_BLANK_ULONG
@@ -34573,14 +34663,12 @@ Blank value for @code{size_t} type (@code{uint32_t} 
or @code{uint64_t} in
 
 @cindex NaN
 @deffn {Global integer}  GAL_BLANK_FLOAT32
-Blank value for a single precision, 32-bit floating point type (IEEE NaN
-value).
+Blank value for a single precision, 32-bit floating point type (IEEE NaN 
value).
 @end deffn
 
 @cindex NaN
 @deffn {Global integer}  GAL_BLANK_FLOAT64
-Blank value for a double precision, 64-bit floating point type (IEEE NaN
-value).
+Blank value for a double precision, 64-bit floating point type (IEEE NaN 
value).
 @end deffn
 
 @deffn {Global integer}  GAL_BLANK_STRING
@@ -34617,35 +34705,26 @@ If @code{width!=0}, then the final string will be 
padded with white space charac
 @end deftypefun
 
 @deftypefun int gal_blank_is (void @code{*pointer}, uint8_t @code{type})
-Return 1 if the contents of @code{pointer} (assuming a type of @code{type})
-is blank. Otherwise, return 0. Note that this function only works on one
-element of the given type. So if @code{pointer} is an array, only its first
-element will be checked. Therefore for strings, the type of @code{pointer}
-is assumed to be @code{char *}. To check if an array/dataset has blank
-elements or to find which elements in an array are blank, you can use
-@code{gal_blank_present} or @code{gal_blank_flag} respectively (described
-below).
+Return 1 if the contents of @code{pointer} (assuming a type of @code{type}) is 
blank.
+Otherwise, return 0.
+Note that this function only works on one element of the given type.
+So if @code{pointer} is an array, only its first element will be checked.
+Therefore for strings, the type of @code{pointer} is assumed to be @code{char 
*}.
+To check if an array/dataset has blank elements or to find which elements in 
an array are blank, you can use @code{gal_blank_present} or 
@code{gal_blank_flag} respectively (described below).
 @end deftypefun
 
 
 @deftypefun int gal_blank_present (gal_data_t @code{*input}, int 
@code{updateflag})
-Return 1 if the dataset has a blank value and zero if it does not. Before
-checking the dataset, this function will look at @code{input}'s flags. If
-the @code{GAL_DATA_FLAG_BLANK_CH} bit of @code{input->flag} is on, this
-function will not do any check and will just use the information in the
-flags. This can greatly speed up processing when a dataset needs to be
-checked multiple times.
+Return 1 if the dataset has a blank value and zero if it does not.
+Before checking the dataset, this function will look at @code{input}'s flags.
+If the @code{GAL_DATA_FLAG_BLANK_CH} bit of @code{input->flag} is on, this 
function will not do any check and will just use the information in the flags.
+This can greatly speed up processing when a dataset needs to be checked 
multiple times.
 
-When the dataset's flags were not used and @code{updateflags} is non-zero,
-this function will set the flags appropriately to avoid having to re-check
-the dataset in future calls. When @code{updateflags==0}, this function has
-no side-effects on the dataset: it will not toggle the flags.
+When the dataset's flags were not used and @code{updateflags} is non-zero, 
this function will set the flags appropriately to avoid having to re-check the 
dataset in future calls.
+When @code{updateflags==0}, this function has no side-effects on the dataset: 
it will not toggle the flags.
 
-If you want to re-check a dataset with the blank-value-check flag already
-set (for example, if you have made changes to it), then explicitly set the
-@code{GAL_DATA_FLAG_BLANK_CH} bit to zero before calling this
-function. When there are no other flags, you can just set the flags to zero
-(@code{input->flag=0}), otherwise you can use this expression:
+If you want to re-check a dataset with the blank-value-check flag already set 
(for example, if you have made changes to it), then explicitly set the 
@code{GAL_DATA_FLAG_BLANK_CH} bit to zero before calling this function.
+When there are no other flags, you can just set the flags to zero 
(@code{input->flag=0}), otherwise you can use this expression:
 
 @example
 input->flag &= ~GAL_DATA_FLAG_BLANK_CH;
@@ -34667,6 +34746,19 @@ Return a ``flag'' dataset with the same size as the 
input, but with an @code{uin
 Return a ``flag'' dataset with the same size as the input, but with an 
@code{uint8_t} type that has a value of 1 for data elements that are @emph{not} 
blank and 0 for those that are blank.
 @end deftypefun
 
+@deftypefun {size_t *} gal_blank_not_minmax_coords (gal_data_t @code{*input})
+Find the minimum and maximum coordinates of the non-blank regions within the 
input dataset.
+The coordinates are in C order: starting from 0, and with the slowest dimsion 
being first.
+The output is an allocated array (that should be freed later) with 
@mymath{2\times N} elements; where @mymath{N} is the number of dimensions.
+The first two elements contain the minimum and maximum of regions containing 
non-blank elements along the 0-th dimension (the slowest), the second two 
elements contain the next dimension's extrema; and so on.
+@end deftypefun
+
+@deftypefun {gal_data_t *} gal_blank_trim (gal_data_t @code{*input}, int 
@code{inplace})
+Trim all the outer layers of blank values from the input dataset.
+For example in the 2D image, ``layers'' would correspond to columns or rows 
that are fully blank and touching the edge of the image.
+For a more complete description, see the description of the @code{trim} 
operator in @ref{Dimensionality changing operators}.
+@end deftypefun
+
 @deftypefun void gal_blank_flag_apply (gal_data_t @code{*input}, gal_data_t 
@code{*flag})
 Set all non-zero and non-blank elements of @code{flag} to blank in 
@code{input}.
 @code{flag} has to have an unsigned 8-bit type and be the same size as 
@code{input}.
@@ -34717,16 +34809,10 @@ In any case (no matter which columns are checked for 
blanks), the selected rows
 @node Library data container, Dimensions, Library blank values, Gnuastro 
library
 @subsection Data container (@file{data.h})
 
-Astronomical datasets have various dimensions, for example, 1D spectra or
-table columns, 2D images, or 3D Integral field data cubes. Datasets can
-also have various numeric data types, depending on the operation/purpose,
-for example, processed images are commonly stored in floating point format,
-but their mask images are integers (allowing bit-wise flags to identify
-certain classes of pixels to keep or mask, see @ref{Numeric data
-types}). Certain other information about a dataset are also commonly
-necessary, for example, the units of the dataset, the name of the dataset
-and some comments. To deal with any generic dataset, Gnuastro defines the
-@code{gal_data_t} as input or output.
+Astronomical datasets have various dimensions, for example, 1D spectra or 
table columns, 2D images, or 3D Integral field data cubes.
+Datasets can also have various numeric data types, depending on the 
operation/purpose, for example, processed images are commonly stored in 
floating point format, but their mask images are integers (allowing bit-wise 
flags to identify certain classes of pixels to keep or mask, see @ref{Numeric 
data types}).
+Certain other information about a dataset are also commonly necessary, for 
example, the units of the dataset, the name of the dataset and some comments.
+To deal with any generic dataset, Gnuastro defines the @code{gal_data_t} as 
input or output.
 
 @menu
 * Generic data container::      Definition of Gnuastro's generic container.
@@ -35079,15 +35165,12 @@ This function is just a wrapper for the 
@code{gal_type_string_to_number}, but wi
 @node Dimensions, Linked lists, Library data container, Gnuastro library
 @subsection Dimensions (@file{dimension.h})
 
-An array is a contiguous region of memory.  Hence, at the lowest level,
-every element of an array just has one single-valued position: the number
-of elements that lie between it and the first element in the array. This is
-also known as the @emph{index} of the element within the array. A dataset's
-number of dimensions is high-level abstraction (meta-data) that we project
-onto that contiguous patch of memory. When the array is interpreted as a
-one-dimensional dataset, this index is also the @emph{coordinate} of the
-element. But once we associate the patch of memory with a higher dimension,
-there must also be one coordinate for each dimension.
+An array is a contiguous region of memory.
+Hence, at the lowest level, every element of an array just has one 
single-valued position: the number of elements that lie between it and the 
first element in the array.
+This is also known as the @emph{index} of the element within the array.
+A dataset's number of dimensions is high-level abstraction (meta-data) that we 
project onto that contiguous patch of memory.
+When the array is interpreted as a one-dimensional dataset, this index is also 
the @emph{coordinate} of the element.
+But once we associate the patch of memory with a higher dimension, there must 
also be one coordinate for each dimension.
 
 The functions and macros in this section provide you with the tools to
 convert an index into a coordinate and vice-versa along with several other
@@ -35095,42 +35178,33 @@ issues for example, issues with the neighbors of an 
element in a
 multi-dimensional context.
 
 @deftypefun size_t gal_dimension_total_size (size_t @code{ndim}, size_t 
@code{*dsize})
-Return the total number of elements for a dataset with @code{ndim}
-dimensions that has @code{dsize} elements along each dimension.
+Return the total number of elements for a dataset with @code{ndim} dimensions 
that has @code{dsize} elements along each dimension.
 @end deftypefun
 
 @deftypefun int gal_dimension_is_different (gal_data_t @code{*first}, 
gal_data_t @code{*second})
-Return @code{1} (one) if the two datasets do not have the same size along
-all dimensions. This function will also return @code{1} when the number of
-dimensions of the two datasets are different.
+Return @code{1} (one) if the two datasets do not have the same size along all 
dimensions.
+This function will also return @code{1} when the number of dimensions of the 
two datasets are different.
 @end deftypefun
 
 @deftypefun {size_t *} gal_dimension_increment (size_t @code{ndim}, size_t 
@code{*dsize})
-Return an allocated array that has the number of elements necessary to
-increment an index along every dimension. For example, along the fastest
-dimension (last element in the @code{dsize} and returned arrays), the value
-is @code{1} (one).
+Return an allocated array that has the number of elements necessary to 
increment an index along every dimension.
+For example, along the fastest dimension (last element in the @code{dsize} and 
returned arrays), the value is @code{1} (one).
 @end deftypefun
 
 @deftypefun size_t gal_dimension_num_neighbors (size_t @code{ndim})
-The maximum number of neighbors (any connectivity) that a data element can
-have in @code{ndim} dimensions. Effectively, this function just returns
-@mymath{3^n-1} (where @mymath{n} is the number of dimensions).
+The maximum number of neighbors (any connectivity) that a data element can 
have in @code{ndim} dimensions.
+Effectively, this function just returns @mymath{3^n-1} (where @mymath{n} is 
the number of dimensions).
 @end deftypefun
 
 @deffn {Function-like macro} GAL_DIMENSION_FLT_TO_INT (@code{FLT})
-Calculate the integer pixel position that the floating point @code{FLT}
-number belongs to. In the FITS format (and thus in Gnuastro), the center of
-each pixel is allocated on an integer (not it edge), so the pixel which
-hosts a floating point number cannot simply be found with internal type
-conversion.
+Calculate the integer pixel position that the floating point @code{FLT} number 
belongs to.
+In the FITS format (and thus in Gnuastro), the center of each pixel is 
allocated on an integer (not it edge), so the pixel which hosts a floating 
point number cannot simply be found with internal type conversion.
 @end deffn
 
 @deftypefun void gal_dimension_add_coords (size_t @code{*c1}, size_t 
@code{*c2}, size_t @code{*out}, size_t @code{ndim})
-For every dimension, add the coordinates in @code{c1} with @code{c2} and
-put the result into @code{out}. In other words, for dimension @code{i} run
-@code{out[i]=c1[i]+c2[i];}. Hence @code{out} may be equal to any one of
-@code{c1} or @code{c2}.
+For every dimension, add the coordinates in @code{c1} with @code{c2} and put 
the result into @code{out}.
+In other words, for dimension @code{i} run @code{out[i]=c1[i]+c2[i];}.
+Hence @code{out} may be equal to any one of @code{c1} or @code{c2}.
 @end deftypefun
 
 @deftypefun size_t gal_dimension_coord_to_index (size_t @code{ndim}, size_t 
@code{*dsize}, size_t @code{*coord})
@@ -35140,12 +35214,9 @@ size of the dataset along each dimension is in the 
@code{dsize} array.
 @end deftypefun
 
 @deftypefun void gal_dimension_index_to_coord (size_t @code{index}, size_t 
@code{ndim}, size_t @code{*dsize}, size_t @code{*coord})
-Fill in the @code{coord} array with the coordinates that correspond to
-@code{index} assuming the dataset has @code{ndim} elements and the size of
-the dataset along each dimension is in the @code{dsize} array. Note that
-both @code{index} and each value in @code{coord} are assumed to start from
-@code{0} (zero). Also that the space which @code{coord} points to must
-already be allocated before calling this function.
+Fill in the @code{coord} array with the coordinates that correspond to 
@code{index} assuming the dataset has @code{ndim} elements and the size of the 
dataset along each dimension is in the @code{dsize} array.
+Note that both @code{index} and each value in @code{coord} are assumed to 
start from @code{0} (zero).
+Also that the space which @code{coord} points to must already be allocated 
before calling this function.
 @end deftypefun
 
 @deftypefun size_t gal_dimension_dist_manhattan (size_t @code{*a}, size_t 
@code{*b}, size_t @code{ndim})
@@ -35171,7 +35242,8 @@ Return the radial distance between the two coordinates 
@code{a} and
 @cindex Ellipsoidal distance
 @cindex Distance, elliptical/ellipsoidal
 Return the elliptical/ellipsoidal distance of the single point @code{point} 
(containing @code{ndim} values: coordinates of the point in each dimension) 
from an ellipse that is defined by @code{center}, @code{pa_deg} and @code{q}.
-@code{center} is the coordinates of the ellipse center (also with @code{ndim} 
elements). @code{pa} is the position-angle in degrees (the angle of the 
semi-major axis from the first dimension in a 2D ellipse) and @code{q} is the 
axis ratio.
+@code{center} is the coordinates of the ellipse center (also with @code{ndim} 
elements).
+@code{pa} is the position-angle in degrees (the angle of the semi-major axis 
from the first dimension in a 2D ellipse) and @code{q} is the axis ratio.
 
 In a 2D ellipse, @code{pa} and @code{q} are a single-element array.
 However, in a 3D ellipsoid, @code{pa} must have three elements, and @code{q} 
must have 2 elements.
@@ -35298,29 +35370,17 @@ This macro works fully within its own @code{@{@}} 
block and except for the @code
 
 @cindex Array
 @cindex Linked list
-An array is a contiguous region of memory that is very efficient and easy
-to use for recording and later accessing any random element as fast as any
-other. This makes array the primary data container when you have many
-elements (for example, an image which has millions of pixels). One major
-problem with an array is that the number of elements that go into it must
-be known in advance and adding or removing an element will require a re-set
-of all the other elements. For example, if you want to remove the 3rd
-element in a 1000 element array, all 997 subsequent elements have to pulled
-back by one position, the reverse will happen if you need to add an
-element.
-
-In many contexts such situations never come up, for example, you do not want
-to shift all the pixels in an image by one or two pixels from some random
-position in the image: their positions have scientific value. But in other
-contexts you will find yourself frequently adding/removing an a-priori
-unknown number of elements. Linked lists (or @emph{lists} for short) are
-the data-container of choice in such situations. As in a chain, each
-@emph{node} in a list is an independent C structure, keeping its own data
-along with pointer(s) to its immediate neighbor(s). Below, you can see one
-simple linked list node structure along with an ASCII art schematic of how
-we can use the @code{next} pointer to add any number of elements to the
-list that we want. By convention, a list is terminated when @code{next} is
-the @code{NULL} pointer.
+An array is a contiguous region of memory that is very efficient and easy to 
use for recording and later accessing any random element as fast as any other.
+This makes array the primary data container when you have many elements (for 
example, an image which has millions of pixels).
+One major problem with an array is that the number of elements that go into it 
must be known in advance and adding or removing an element will require a 
re-set of all the other elements.
+For example, if you want to remove the 3rd element in a 1000 element array, 
all 997 subsequent elements have to pulled back by one position, the reverse 
will happen if you need to add an element.
+
+In many contexts such situations never come up, for example, you do not want 
to shift all the pixels in an image by one or two pixels from some random 
position in the image: their positions have scientific value.
+But in other contexts you will find yourself frequently adding/removing an 
a-priori unknown number of elements.
+Linked lists (or @emph{lists} for short) are the data-container of choice in 
such situations.
+As in a chain, each @emph{node} in a list is an independent C structure, 
keeping its own data along with pointer(s) to its immediate neighbor(s).
+Below, you can see one simple linked list node structure along with an ASCII 
art schematic of how we can use the @code{next} pointer to add any number of 
elements to the list that we want.
+By convention, a list is terminated when @code{next} is the @code{NULL} 
pointer.
 
 @c The second and last lines lines are pushed line space forward, because
 @c the `@{' at the start of the line is only seen as `{' in the book.
@@ -35332,11 +35392,10 @@ struct list_float          /*     ---------    
---------           */
 @}                          /*     ---------    ---------           */
 @end example
 
-The schematic shows another great advantage of linked lists: it is very
-easy to add or remove/pop a node anywhere in the list. If you want to
-modify the first node, you just have to change one pointer. If it is in the
-middle, you just have to change two. You initially define a variable of
-this type with a @code{NULL} pointer as shown below:
+The schematic shows another great advantage of linked lists: it is very easy 
to add or remove/pop a node anywhere in the list.
+If you want to modify the first node, you just have to change one pointer.
+If it is in the middle, you just have to change two.
+You initially define a variable of this type with a @code{NULL} pointer as 
shown below:
 
 @example
 struct list_float *mylist=NULL;
@@ -35349,41 +35408,28 @@ for the respective type in the sections below.
 @cindex last-in-first-out
 @cindex first-in-first-out
 @noindent
-When you add an element to the list, it is conventionally added to the
-``top'' of the list: the general list pointer will point to the newly
-created node, which will point to the previously created node and so on. So
-when you ``pop'' from the top of the list, you are actually retrieving the
-last value you put in and changing the list pointer to the next youngest
-node. This is thus known as a ``last-in-first-out'' list. This is the most
-efficient type of linked list (easier to implement and faster to
-process). Alternatively, you can add each newly created node at the end of
-the list. If you do that, you will get a ``first-in-first-out'' list. But
-that will force you to go through the whole list for each new element that
-is created (this will slow down the processing)@footnote{A better way to
-get a first-in-first-out is to first keep the data as last-in-first-out
-until they are all read. Afterwards, reverse the list by popping each node
-and immediately add it to the new list. This practically reverses the
-last-in-first-out list to a first-in-first-out one. All the list types
-discussed in this chapter have a function with a @code{_reverse} suffix for
-this job.}.
-
-The node example above creates the simplest kind of a list. We can define
-each node with two pointers to both the next and previous neighbors, this
-is called a ``Doubly linked list''. In general, lists are very powerful and
-simple constructs that can be very useful. But going into more detail would
-be out of the scope of this short introduction in this
-book. @url{https://en.wikipedia.org/wiki/Linked_list, Wikipedia} has a nice
-and more thorough discussion of the various types of lists. To
-appreciate/use the beauty and elegance of these powerful constructs even
-further, see Chapter 2 (Information Structures, in volume 1) of Donald
-Knuth's ``The art of computer programming''.
-
-In this section we will review the functions and structures that are
-available in Gnuastro for working on lists. They differ by the type of data
-that each node can keep. For each linked-list node structure, we will first
-introduce the structure, then the functions for working on the
-structure. All these structures and functions are defined and declared in
-@file{gnuastro/list.h}.
+When you add an element to the list, it is conventionally added to the ``top'' 
of the list: the general list pointer will point to the newly created node, 
which will point to the previously created node and so on.
+So when you ``pop'' from the top of the list, you are actually retrieving the 
last value you put in and changing the list pointer to the next youngest node.
+This is thus known as a ``last-in-first-out'' list.
+This is the most efficient type of linked list (easier to implement and faster 
to process).
+Alternatively, you can add each newly created node at the end of the list.
+If you do that, you will get a ``first-in-first-out'' list.
+But that will force you to go through the whole list for each new element that 
is created (this will slow down the processing)@footnote{A better way to get a 
first-in-first-out is to first keep the data as last-in-first-out until they 
are all read.
+Afterwards, reverse the list by popping each node and immediately add it to 
the new list.
+This practically reverses the last-in-first-out list to a first-in-first-out 
one.
+All the list types discussed in this chapter have a function with a 
@code{_reverse} suffix for this job.}.
+
+The node example above creates the simplest kind of a list.
+We can define each node with two pointers to both the next and previous 
neighbors, this is called a ``Doubly linked list''.
+In general, lists are very powerful and simple constructs that can be very 
useful.
+But going into more detail would be out of the scope of this short 
introduction in this book.
+@url{https://en.wikipedia.org/wiki/Linked_list, Wikipedia} has a nice and more 
thorough discussion of the various types of lists.
+To appreciate/use the beauty and elegance of these powerful constructs even 
further, see Chapter 2 (Information Structures, in volume 1) of Donald Knuth's 
``The art of computer programming''.
+
+In this section we will review the functions and structures that are available 
in Gnuastro for working on lists.
+They differ by the type of data that each node can keep.
+For each linked-list node structure, we will first introduce the structure, 
then the functions for working on the structure.
+All these structures and functions are defined and declared in 
@file{gnuastro/list.h}.
 
 
 @menu
@@ -35488,12 +35534,10 @@ This is necessary, otherwise, a function like 
@code{gal_list_str_extract} will n
 @node List of int32_t, List of size_t, List of strings, Linked lists
 @subsubsection List of @code{int32_t}
 
-Signed integers are the best types when you are dealing with a positive or
-negative integers. The are generally useful in many contexts, for example
-when you want to keep the order of a series of states (each state stored as
-a given number in an @code{enum} for example). On many modern systems,
-@code{int32_t} is just an alias for @code{int}, so you can use them
-interchangeably. To make sure, check the size of @code{int} on your system:
+Signed integers are the best types when you are dealing with a positive or 
negative integers.
+The are generally useful in many contexts, for example when you want to keep 
the order of a series of states (each state stored as a given number in an 
@code{enum} for example).
+On many modern systems, @code{int32_t} is just an alias for @code{int}, so you 
can use them interchangeably.
+To make sure, check the size of @code{int} on your system:
 
 @deftp {Type (C @code{struct})} gal_list_i32_t
 A single node in a list containing a 32-bit signed integer (see
@@ -35509,10 +35553,8 @@ typedef struct gal_list_i32_t
 
 
 @deftypefun void gal_list_i32_add (gal_list_i32_t @code{**list}, int32_t 
@code{value})
-Add a new node (containing @code{value}) to the top of the @code{list} of
-@code{int32_t}s (@code{uint32_t} is equal to @code{int} on many modern
-systems), and update @code{list}. Here is one short example of initializing
-and adding elements to a string list:
+Add a new node (containing @code{value}) to the top of the @code{list} of 
@code{int32_t}s (@code{uint32_t} is equal to @code{int} on many modern 
systems), and update @code{list}.
+Here is one short example of initializing and adding elements to a string list:
 
 @example
 gal_list_i32_t *i32list=NULL;
@@ -35523,10 +35565,9 @@ gal_list_i32_add(&i32list, -4);
 @end deftypefun
 
 @deftypefun {int32_t} gal_list_i32_pop (gal_list_i32_t @code{**list})
-Pop the top element of @code{list} and return the value. This function will
-also change @code{list} to point to the next node in the list. If
-@code{*list==NULL}, then this function will also return
-@code{GAL_BLANK_INT32} (see @ref{Library blank values}).
+Pop the top element of @code{list} and return the value.
+This function will also change @code{list} to point to the next node in the 
list.
+If @code{*list==NULL}, then this function will also return 
@code{GAL_BLANK_INT32} (see @ref{Library blank values}).
 @end deftypefun
 
 @deftypefun size_t gal_list_i32_number (gal_list_i32_t @code{*list})
@@ -35538,13 +35579,12 @@ Return a pointer to the last node in @code{list}.
 @end deftypefun
 
 @deftypefun void gal_list_i32_print (gal_list_i32_t @code{*list})
-Print the integers within each node of @code{*list} on the standard output
-in the same order that they are stored. Each integer is printed on one
-line. This function is mainly good for checking/debugging your program. For
-program outputs, it is best to make your own implementation with a better,
-more user-friendly format. For example, the following code snippet. You can
-also modify it to print all values in one line, etc., depending on the
-context of your program.
+Print the integers within each node of @code{*list} on the standard output in 
the same order that they are stored.
+Each integer is printed on one line.
+This function is mainly good for checking/debugging your program.
+For program outputs, it is best to make your own implementation with a better, 
more user-friendly format.
+For example, the following code snippet.
+You can also modify it to print all values in one line, etc., depending on the 
context of your program.
 
 @example
 size_t i;
@@ -35560,13 +35600,10 @@ calling this function becomes the bottom node after 
it.
 @end deftypefun
 
 @deftypefun {int32_t *} gal_list_i32_to_array (gal_list_i32_t @code{*list}, 
int @code{reverse}, size_t @code{*num})
-Dynamically allocate an array and fill it with the values in
-@code{list}. The function will return a pointer to the allocated array and
-put the number of elements in the array into the @code{num} pointer. If
-@code{reverse} has a non-zero value, the array will be filled in the
-opposite order of elements in @code{list}. This function can be
-useful after you have finished reading an initially unknown number of
-values and want to put them in an array for easy random access.
+Dynamically allocate an array and fill it with the values in @code{list}.
+The function will return a pointer to the allocated array and put the number 
of elements in the array into the @code{num} pointer.
+If @code{reverse} has a non-zero value, the array will be filled in the 
opposite order of elements in @code{list}.
+This function can be useful after you have finished reading an initially 
unknown number of values and want to put them in an array for easy random 
access.
 @end deftypefun
 
 @deftypefun void gal_list_i32_free (gal_list_i32_t @code{*list})
@@ -35581,24 +35618,13 @@ Free every node in @code{list}.
 @node List of size_t, List of float, List of int32_t, Linked lists
 @subsubsection List of @code{size_t}
 
-The @code{size_t} type is a unique type in C: as the name suggests it is
-defined to store sizes, or more accurately, the distances between memory
-locations. Hence it is always positive (an @code{unsigned} type) and it is
-directly related to the address-able spaces on the host system: on 32-bit
-and 64-bit systems it is an alias for @code{uint32_t} and @code{uint64_t},
-respectively (see @ref{Numeric data types}).
-
-@code{size_t} is the default compiler type to index an array (recall that
-an array index in C is just a pointer increment of a given
-@emph{size}). Since it is unsigned, it is a great type for counting (where
-negative is not defined), you are always sure it will never exceed the
-system's (virtual) memory and since its name has the word ``size'' inside
-it, it provides a good level of documentation@footnote{So you know that a
-variable of this type is not used to store some generic state for
-example.}. In Gnuastro, we do all counting and array indexing with this
-type, so this list is very handy. As discussed above, @code{size_t} maps to
-different types on different machines, so a portable way to print them with
-@code{printf} is to use C99's @code{%zu} format.
+The @code{size_t} type is a unique type in C: as the name suggests it is 
defined to store sizes, or more accurately, the distances between memory 
locations.
+Hence it is always positive (an @code{unsigned} type) and it is directly 
related to the address-able spaces on the host system: on 32-bit and 64-bit 
systems it is an alias for @code{uint32_t} and @code{uint64_t}, respectively 
(see @ref{Numeric data types}).
+
+@code{size_t} is the default compiler type to index an array (recall that an 
array index in C is just a pointer increment of a given @emph{size}).
+Since it is unsigned, it is a great type for counting (where negative is not 
defined), you are always sure it will never exceed the system's (virtual) 
memory and since its name has the word ``size'' inside it, it provides a good 
level of documentation@footnote{So you know that a variable of this type is not 
used to store some generic state for example.}.
+In Gnuastro, we do all counting and array indexing with this type, so this 
list is very handy.
+As discussed above, @code{size_t} maps to different types on different 
machines, so a portable way to print them with @code{printf} is to use C99's 
@code{%zu} format.
 
 @deftp {Type (C @code{struct})} gal_list_sizet_t
 A single node in a list containing a @code{size_t} value (which maps to
@@ -35615,9 +35641,8 @@ typedef struct gal_list_sizet_t
 
 
 @deftypefun void gal_list_sizet_add (gal_list_sizet_t @code{**list}, size_t 
@code{value})
-Add a new node (containing @code{value}) to the top of the @code{list} of
-@code{size_t}s and update @code{list}.  Here is one short example of
-initializing and adding elements to a string list:
+Add a new node (containing @code{value}) to the top of the @code{list} of 
@code{size_t}s and update @code{list}.
+Here is one short example of initializing and adding elements to a string list:
 
 @example
 gal_list_sizet_t *slist=NULL;
@@ -35628,10 +35653,9 @@ gal_list_sizet_add(&slist, 930484);
 @end deftypefun
 
 @deftypefun {sizet_t} gal_list_sizet_pop (gal_list_sizet_t @code{**list})
-Pop the top element of @code{list} and return the value. This function will
-also change @code{list} to point to the next node in the list. If
-@code{*list==NULL}, then this function will also return
-@code{GAL_BLANK_SIZE_T} (see @ref{Library blank values}).
+Pop the top element of @code{list} and return the value.
+This function will also change @code{list} to point to the next node in the 
list.
+If @code{*list==NULL}, then this function will also return 
@code{GAL_BLANK_SIZE_T} (see @ref{Library blank values}).
 @end deftypefun
 
 @deftypefun size_t gal_list_sizet_number (gal_list_sizet_t @code{*list})
@@ -35643,13 +35667,12 @@ Return a pointer to the last node in @code{list}.
 @end deftypefun
 
 @deftypefun void gal_list_sizet_print (gal_list_sizet_t @code{*list})
-Print the values within each node of @code{*list} on the standard output in
-the same order that they are stored. Each integer is printed on one
-line. This function is mainly good for checking/debugging your program. For
-program outputs, it is best to make your own implementation with a better,
-more user-friendly format. For example, the following code snippet. You can
-also modify it to print all values in one line, etc., depending on the
-context of your program.
+Print the values within each node of @code{*list} on the standard output in 
the same order that they are stored.
+Each integer is printed on one line.
+This function is mainly good for checking/debugging your program.
+For program outputs, it is best to make your own implementation with a better, 
more user-friendly format.
+For example, the following code snippet.
+You can also modify it to print all values in one line, etc., depending on the 
context of your program.
 
 @example
 size_t i;
@@ -35665,13 +35688,10 @@ calling this function becomes the bottom node after 
it.
 @end deftypefun
 
 @deftypefun {size_t *} gal_list_sizet_to_array (gal_list_sizet_t @code{*list}, 
int @code{reverse}, size_t @code{*num})
-Dynamically allocate an array and fill it with the values in
-@code{list}. The function will return a pointer to the allocated array and
-put the number of elements in the array into the @code{num} pointer. If
-@code{reverse} has a non-zero value, the array will be filled in the
-inverse of the order of elements in @code{list}. This function can be
-useful after you have finished reading an initially unknown number of
-values and want to put them in an array for easy random access.
+Dynamically allocate an array and fill it with the values in @code{list}.
+The function will return a pointer to the allocated array and put the number 
of elements in the array into the @code{num} pointer.
+If @code{reverse} has a non-zero value, the array will be filled in the 
inverse of the order of elements in @code{list}.
+This function can be useful after you have finished reading an initially 
unknown number of values and want to put them in an array for easy random 
access.
 @end deftypefun
 
 @deftypefun void gal_list_sizet_free (gal_list_sizet_t @code{*list})
@@ -35683,12 +35703,9 @@ Free every node in @code{list}.
 @node List of float, List of double, List of size_t, Linked lists
 @subsubsection List of @code{float}
 
-Single precision floating point numbers can accurately store real number
-until 7.2 decimals and only consume 4 bytes (32-bits) of memory, see
-@ref{Numeric data types}. Since astronomical data rarely reach that level
-of precision, single precision floating points are the type of choice to
-keep and read data. However, when processing the data, it is best to use
-double precision floating points (since errors propagate).
+Single precision floating point numbers can accurately store real number until 
7.2 decimals and only consume 4 bytes (32-bits) of memory, see @ref{Numeric 
data types}.
+Since astronomical data rarely reach that level of precision, single precision 
floating points are the type of choice to keep and read data.
+However, when processing the data, it is best to use double precision floating 
points (since errors propagate).
 
 @deftp {Type (C @code{struct})} gal_list_f32_t
 A single node in a list containing a 32-bit single precision @code{float}
@@ -35704,9 +35721,8 @@ typedef struct gal_list_f32_t
 
 
 @deftypefun void gal_list_f32_add (gal_list_f32_t @code{**list}, float 
@code{value})
-Add a new node (containing @code{value}) to the top of the @code{list} of
-@code{float}s and update @code{list}.  Here is one short example of
-initializing and adding elements to a string list:
+Add a new node (containing @code{value}) to the top of the @code{list} of 
@code{float}s and update @code{list}.
+Here is one short example of initializing and adding elements to a string list:
 
 @example
 gal_list_f32_t *flist=NULL;
@@ -35717,10 +35733,9 @@ gal_list_f32_add(&flist, 1.23e-20);
 @end deftypefun
 
 @deftypefun {float} gal_list_f32_pop (gal_list_f32_t @code{**list})
-Pop the top element of @code{list} and return the value. This function will
-also change @code{list} to point to the next node in the list. If
-@code{*list==NULL}, then this function will return @code{GAL_BLANK_FLOAT32}
-(NaN, see @ref{Library blank values}).
+Pop the top element of @code{list} and return the value.
+This function will also change @code{list} to point to the next node in the 
list.
+If @code{*list==NULL}, then this function will return @code{GAL_BLANK_FLOAT32} 
(NaN, see @ref{Library blank values}).
 @end deftypefun
 
 @deftypefun size_t gal_list_f32_number (gal_list_f32_t @code{*list})
@@ -35732,13 +35747,12 @@ Return a pointer to the last node in @code{list}.
 @end deftypefun
 
 @deftypefun void gal_list_f32_print (gal_list_f32_t @code{*list})
-Print the values within each node of @code{*list} on the standard output in
-the same order that they are stored. Each floating point number is printed
-on one line. This function is mainly good for checking/debugging your
-program. For program outputs, it is best to make your own implementation with
-a better, more user-friendly format. For example, in the following code
-snippet. You can also modify it to print all values in one line, etc.,
-depending on the context of your program.
+Print the values within each node of @code{*list} on the standard output in 
the same order that they are stored.
+Each floating point number is printed on one line.
+This function is mainly good for checking/debugging your program.
+For program outputs, it is best to make your own implementation with a better, 
more user-friendly format.
+For example, in the following code snippet.
+You can also modify it to print all values in one line, etc., depending on the 
context of your program.
 
 @example
 size_t i;
@@ -35754,13 +35768,10 @@ calling this function becomes the bottom node after 
it.
 @end deftypefun
 
 @deftypefun {float *} gal_list_f32_to_array (gal_list_f32_t @code{*list}, int 
@code{reverse}, size_t @code{*num})
-Dynamically allocate an array and fill it with the values in
-@code{list}. The function will return a pointer to the allocated array and
-put the number of elements in the array into the @code{num} pointer. If
-@code{reverse} has a non-zero value, the array will be filled in the
-inverse of the order of elements in @code{list}. This function can be
-useful after you have finished reading an initially unknown number of
-values and want to put them in an array for easy random access.
+Dynamically allocate an array and fill it with the values in @code{list}.
+The function will return a pointer to the allocated array and put the number 
of elements in the array into the @code{num} pointer.
+If @code{reverse} has a non-zero value, the array will be filled in the 
inverse of the order of elements in @code{list}.
+This function can be useful after you have finished reading an initially 
unknown number of values and want to put them in an array for easy random 
access.
 @end deftypefun
 
 @deftypefun void gal_list_f32_free (gal_list_f32_t @code{*list})
@@ -36103,14 +36114,10 @@ each.
 @node Array input output, Table input output, Linked lists, Gnuastro library
 @subsection Array input output
 
-Getting arrays (commonly images or cubes) from a file into your program or
-writing them after the processing into an output file are some of the most
-common operations. The functions in this section are designed for such
-operations with the known file types. The functions here are thus just
-wrappers around functions of lower-level file type functions of this
-library, for example, @ref{FITS files} or @ref{TIFF files}. If the file type
-of the input/output file is already known, you can use the functions in
-those sections respectively.
+Getting arrays (commonly images or cubes) from a file into your program or 
writing them after the processing into an output file are some of the most 
common operations.
+The functions in this section are designed for such operations with the known 
file types.
+The functions here are thus just wrappers around functions of lower-level file 
type functions of this library, for example, @ref{FITS files} or @ref{TIFF 
files}.
+If the file type of the input/output file is already known, you can use the 
functions in those sections respectively.
 
 @deftypefun int gal_array_name_recognized (char @code{*filename})
 Return 1 if the given file name corresponds to one of the recognized file
@@ -36129,29 +36136,20 @@ See the description of 
@code{gal_fits_file_recognized} for more (@ref{FITS macro
 @end deftypefun
 
 @deftypefun gal_data_t gal_array_read (char @code{*filename}, char 
@code{*extension}, gal_list_str_t @code{*lines}, size_t @code{minmapsize}, int 
@code{quietmmap})
-Read the array within the given extension (@code{extension}) of
-@code{filename}, or the @code{lines} list (see below). If the array is
-larger than @code{minmapsize} bytes, then it will not be read into RAM, but a
-file on the HDD/SSD (no difference for the programmer). Messages about the
-memory-mapped file can be disabled with @code{quietmmap}.
-
-@code{extension} will be ignored for files that do not support them (for
-example JPEG or text). For FITS files, @code{extension} can be a number or
-a string (name of the extension), but for TIFF files, it has to be
-number. In both cases, counting starts from zero.
-
-For multi-channel formats (like RGB images in JPEG or TIFF), this function
-will return a @ref{List of gal_data_t}: one data structure per
-channel. Thus if you just want a single array (and want to check if the
-user has not given a multi-channel input), you can check the @code{next}
-pointer of the returned @code{gal_data_t}.
-
-@code{lines} is a list of strings with each node representing one line
-(including the new-line character), see @ref{List of strings}. It will
-mostly be the output of @code{gal_txt_stdin_read}, which is used to read
-the program's input as separate lines from the standard input (see
-@ref{Text files}). Note that @code{filename} and @code{lines} are mutually
-exclusive and one of them must be @code{NULL}.
+Read the array within the given extension (@code{extension}) of 
@code{filename}, or the @code{lines} list (see below).
+If the array is larger than @code{minmapsize} bytes, then it will not be read 
into RAM, but a file on the HDD/SSD (no difference for the programmer).
+Messages about the memory-mapped file can be disabled with @code{quietmmap}.
+
+@code{extension} will be ignored for files that do not support them (for 
example JPEG or text).
+For FITS files, @code{extension} can be a number or a string (name of the 
extension), but for TIFF files, it has to be number.
+In both cases, counting starts from zero.
+
+For multi-channel formats (like RGB images in JPEG or TIFF), this function 
will return a @ref{List of gal_data_t}: one data structure per channel.
+Thus if you just want a single array (and want to check if the user has not 
given a multi-channel input), you can check the @code{next} pointer of the 
returned @code{gal_data_t}.
+
+@code{lines} is a list of strings with each node representing one line 
(including the new-line character), see @ref{List of strings}.
+It will mostly be the output of @code{gal_txt_stdin_read}, which is used to 
read the program's input as separate lines from the standard input (see 
@ref{Text files}).
+Note that @code{filename} and @code{lines} are mutually exclusive and one of 
them must be @code{NULL}.
 @end deftypefun
 
 @deftypefun void gal_array_read_to_type (char @code{*filename}, char 
@code{*extension}, gal_list_str_t @code{*lines}, uint8_t @code{type}, size_t 
@code{minmapsize}, int @code{quietmmap})
@@ -36162,16 +36160,11 @@ have a numeric data type of @code{type}, see 
@ref{Numeric data types}.
 @deftypefun void gal_array_read_one_ch (char @code{*filename}, char 
@code{*extension}, gal_list_str_t @code{*lines}, size_t @code{minmapsize}, int 
@code{quietmmap})
 @cindex Channel
 @cindex Color channel
-Read the dataset within @code{filename} (extension/hdu/dir
-@code{extension}) and make sure it is only a single channel. This is just a
-simple wrapper around @code{gal_array_read} that checks if there was more
-than one dataset and aborts with an informative error if there is more than
-one channel in the dataset.
+Read the dataset within @code{filename} (extension/hdu/dir @code{extension}) 
and make sure it is only a single channel.
+This is just a simple wrapper around @code{gal_array_read} that checks if 
there was more than one dataset and aborts with an informative error if there 
is more than one channel in the dataset.
 
-Formats like JPEG or TIFF support multiple channels per input, but it may
-happen that your program only works on a single dataset. This function can
-be a convenient way to make sure that the data that comes into your program
-is only one channel.
+Formats like JPEG or TIFF support multiple channels per input, but it may 
happen that your program only works on a single dataset.
+This function can be a convenient way to make sure that the data that comes 
into your program is only one channel.
 @end deftypefun
 
 @deftypefun void gal_array_read_one_ch_to_type (char @code{*filename}, char 
@code{*extension}, gal_list_str_t @code{*lines}, uint8_t @code{type}, size_t 
@code{minmapsize}, int @code{quietmmap})
@@ -36182,22 +36175,15 @@ has a numeric data type of @code{type}, see 
@ref{Numeric data types}.
 @node Table input output, FITS files, Array input output, Gnuastro library
 @subsection Table input output (@file{table.h})
 
-Tables are a collection of one dimensional datasets that are packed
-together into one file. They are the single most common format to store
-high-level (processed) information, hence they play a very important role
-in Gnuastro. For a more thorough introduction, please see
-@ref{Table}. Gnuastro's Table program, and all the other programs that can
-read from and write into tables, use the functions of this section for
-reading and writing their input/output tables. For a simple demonstration
-of using the constructs introduced here, see @ref{Library demo - reading
-and writing table columns}.
-
-Currently only plain text (see @ref{Gnuastro text table format}) and FITS
-(ASCII and binary) tables are supported by Gnuastro. However, the low-level
-table infra-structure is written such that accommodating other formats is
-also possible and in future releases more formats will hopefully be
-supported. Please do not hesitate to suggest your favorite format so it can
-be implemented when possible.
+Tables are a collection of one dimensional datasets that are packed together 
into one file.
+They are the single most common format to store high-level (processed) 
information, hence they play a very important role in Gnuastro.
+For a more thorough introduction, please see @ref{Table}.
+Gnuastro's Table program, and all the other programs that can read from and 
write into tables, use the functions of this section for reading and writing 
their input/output tables.
+For a simple demonstration of using the constructs introduced here, see 
@ref{Library demo - reading and writing table columns}.
+
+Currently only plain text (see @ref{Gnuastro text table format}) and FITS 
(ASCII and binary) tables are supported by Gnuastro.
+However, the low-level table infra-structure is written such that 
accommodating other formats is also possible and in future releases more 
formats will hopefully be supported.
+Please do not hesitate to suggest your favorite format so it can be 
implemented when possible.
 
 @deffn  Macro GAL_TABLE_DEF_WIDTH_STR
 @deffnx Macro GAL_TABLE_DEF_WIDTH_INT
@@ -36208,11 +36194,8 @@ be implemented when possible.
 @deffnx Macro GAL_TABLE_DEF_PRECISION_FLT
 @deffnx Macro GAL_TABLE_DEF_PRECISION_DBL
 @cindex @code{printf}
-The default width and precision for generic types to use in writing numeric
-types into a text file (plain text and FITS ASCII tables). When the dataset
-does not have any pre-set width and precision (see @code{disp_width} and
-@code{disp_precision} in @ref{Generic data container}) these will be
-directly used in C's @code{printf} command to write the number as a string.
+The default width and precision for generic types to use in writing numeric 
types into a text file (plain text and FITS ASCII tables).
+When the dataset does not have any pre-set width and precision (see 
@code{disp_width} and @code{disp_precision} in @ref{Generic data container}) 
these will be directly used in C's @code{printf} command to write the number as 
a string.
 @end deffn
 
 @deffn  Macro GAL_TABLE_DISPLAY_FMT_STRING
@@ -36223,11 +36206,9 @@ directly used in C's @code{printf} command to write 
the number as a string.
 @deffnx Macro GAL_TABLE_DISPLAY_FMT_FIXED
 @deffnx Macro GAL_TABLE_DISPLAY_FMT_EXP
 @deffnx Macro GAL_TABLE_DISPLAY_FMT_GENERAL
-The display format used in C's @code{printf} to display data of different
-types. The @code{_STRING} and @code{_DECIMAL} are unique for printing
-strings and signed integers, they are mainly here for
-completeness. However, unsigned integers and floating points can be
-displayed in multiple formats:
+The display format used in C's @code{printf} to display data of different 
types.
+The @code{_STRING} and @code{_DECIMAL} are unique for printing strings and 
signed integers, they are mainly here for completeness.
+However, unsigned integers and floating points can be displayed in multiple 
formats:
 
 @table @asis
 @item Unsigned integer
@@ -36249,19 +36230,17 @@ the two for the given number.
 @deffnx Macro GAL_TABLE_FORMAT_TXT
 @deffnx Macro GAL_TABLE_FORMAT_AFITS
 @deffnx Macro GAL_TABLE_FORMAT_BFITS
-All the current acceptable table formats to Gnuastro. The @code{AFITS} and
-@code{BFITS} represent FITS ASCII tables and FITS Binary tables. You can
-use these anywhere you see the @code{tableformat} variable.
+All the current acceptable table formats to Gnuastro.
+The @code{AFITS} and @code{BFITS} represent FITS ASCII tables and FITS Binary 
tables.
+You can use these anywhere you see the @code{tableformat} variable.
 @end deffn
 
 @deffn  Macro GAL_TABLE_SEARCH_INVALID
 @deffnx Macro GAL_TABLE_SEARCH_NAME
 @deffnx Macro GAL_TABLE_SEARCH_UNIT
 @deffnx Macro GAL_TABLE_SEARCH_COMMENT
-When the desired column is not a number, these values determine if the
-string to match, or regular expression to search, be in the @emph{name},
-@emph{units} or @emph{comments} of the column metadata. These values
-should be used for the @code{searchin} variables of the functions.
+When the desired column is not a number, these values determine if the string 
to match, or regular expression to search, be in the @emph{name}, @emph{units} 
or @emph{comments} of the column metadata.
+These values should be used for the @code{searchin} variables of the functions.
 @end deffn
 
 @deftypefun uint8_t gal_table_displayflt_from_str (char @code{*string})
@@ -36426,25 +36405,17 @@ For more on vector columns in tables, see @ref{Vector 
columns}.
 
 @cindex FITS
 @cindex CFITSIO
-The FITS format is the most common format to store data (images and tables)
-in astronomy. The CFITSIO library already provides a very good low-level
-collection of functions for manipulating FITS data. The low-level nature of
-CFITSIO is defined for versatility and portability. As a result, even a
-simple and basic operation, like reading an image or table column into
-memory, will require a special sequence of CFITSIO function calls which can
-be inconvenient and buggy to manage in separate locations. To ease this
-process, Gnuastro's library provides wrappers for CFITSIO functions. With
-these, it much easier to read, write, or modify FITS file data, header
-keywords and extensions. Hence, if you feel these functions do not exactly
-do what you want, we strongly recommend reading the CFITSIO manual to use
-its great features directly (afterwards, send us your wrappers so we can
-include it here for others to benefit also).
-
-All the functions and macros introduced in this section are declared in
-@file{gnuastro/fits.h}.  When you include this header, you are also
-including CFITSIO's @file{fitsio.h} header. So you do not need to explicitly
-include @file{fitsio.h} anymore and can freely use any of its macros or
-functions in your code along with those discussed here.
+The FITS format is the most common format to store data (images and tables) in 
astronomy.
+The CFITSIO library already provides a very good low-level collection of 
functions for manipulating FITS data.
+The low-level nature of CFITSIO is defined for versatility and portability.
+As a result, even a simple and basic operation, like reading an image or table 
column into memory, will require a special sequence of CFITSIO function calls 
which can be inconvenient and buggy to manage in separate locations.
+To ease this process, Gnuastro's library provides wrappers for CFITSIO 
functions.
+With these, it much easier to read, write, or modify FITS file data, header 
keywords and extensions.
+Hence, if you feel these functions do not exactly do what you want, we 
strongly recommend reading the CFITSIO manual to use its great features 
directly (afterwards, send us your wrappers so we can include it here for 
others to benefit also).
+
+All the functions and macros introduced in this section are declared in 
@file{gnuastro/fits.h}.
+When you include this header, you are also including CFITSIO's @file{fitsio.h} 
header.
+So you do not need to explicitly include @file{fitsio.h} anymore and can 
freely use any of its macros or functions in your code along with those 
discussed here.
 
 
 @menu
@@ -36459,34 +36430,27 @@ functions in your code along with those discussed 
here.
 @node FITS macros errors filenames, CFITSIO and Gnuastro types, FITS files, 
FITS files
 @subsubsection FITS Macros, errors and filenames
 
-Some general constructs provided by Gnuastro's FITS handling functions are
-discussed here. In particular there are several useful functions about FITS
-file names.
+Some general constructs provided by Gnuastro's FITS handling functions are 
discussed here.
+In particular there are several useful functions about FITS file names.
 
 @deffn Macro GAL_FITS_MAX_NDIM
-The maximum number of dimensions a dataset can have in FITS format,
-according to the FITS standard this is 999.
+The maximum number of dimensions a dataset can have in FITS format, according 
to the FITS standard this is 999.
 @end deffn
 
 @deftypefun void gal_fits_io_error (int @code{status}, char @code{*message})
-If @code{status} is non-zero, this function will print the CFITSIO error
-message corresponding to status, print @code{message} (optional) in the
-next line and abort the program. If @code{message==NULL}, it will print a
-default string after the CFITSIO error.
+If @code{status} is non-zero, this function will print the CFITSIO error 
message corresponding to status, print @code{message} (optional) in the next 
line and abort the program.
+If @code{message==NULL}, it will print a default string after the CFITSIO 
error.
 @end deftypefun
 
 @deftypefun int gal_fits_name_is_fits (char @code{*name})
-If the @code{name} is an acceptable CFITSIO FITS filename return @code{1}
-(one), otherwise return @code{0} (zero). The currently acceptable FITS
-suffixes are @file{.fits}, @file{.fit}, @file{.fits.gz}, @file{.fits.Z},
-@file{.imh}, @file{.fits.fz}. IMH is the IRAF format which is acceptable to
-CFITSIO.
+If the @code{name} is an acceptable CFITSIO FITS filename return @code{1} 
(one), otherwise return @code{0} (zero).
+The currently acceptable FITS suffixes are @file{.fits}, @file{.fit}, 
@file{.fits.gz}, @file{.fits.Z}, @file{.imh}, @file{.fits.fz}.
+IMH is the IRAF format which is acceptable to CFITSIO.
 @end deftypefun
 
 @deftypefun int gal_fits_suffix_is_fits (char @code{*suffix})
-Similar to @code{gal_fits_name_is_fits}, but only for the suffix. The
-suffix does not have to start with `@key{.}': this function will return
-@code{1} (one) for both @code{fits} and @code{.fits}.
+Similar to @code{gal_fits_name_is_fits}, but only for the suffix.
+The suffix does not have to start with `@key{.}': this function will return 
@code{1} (one) for both @code{fits} and @code{.fits}.
 @end deftypefun
 
 @deftypefun int gal_fits_file_recognized (char @code{*name})
@@ -36497,37 +36461,27 @@ In the process of opening the file, CFITSIO will just 
to open the file, no readi
 @end deftypefun
 
 @deftypefun {char *} gal_fits_name_save_as_string (char @code{*filename}, char 
@code{*hdu})
-If the name is a FITS name, then put a @code{(hdu: ...)} after it and
-return the string. If it is not a FITS file, just print the name, if
-@code{filename==NULL}, then return the string @code{stdin}. Note that the
-output string's space is allocated.
+If the name is a FITS name, then put a @code{(hdu: ...)} after it and return 
the string.
+If it is not a FITS file, just print the name, if @code{filename==NULL}, then 
return the string @code{stdin}.
+Note that the output string's space is allocated.
 
-This function is useful when you want to report a random file to the user
-which may be FITS or not (for a FITS file, simply the filename is not
-enough, the HDU is also necessary).
+This function is useful when you want to report a random file to the user 
which may be FITS or not (for a FITS file, simply the filename is not enough, 
the HDU is also necessary).
 @end deftypefun
 
 
 @node CFITSIO and Gnuastro types, FITS HDUs, FITS macros errors filenames, 
FITS files
 @subsubsection CFITSIO and Gnuastro types
 
-Both Gnuastro and CFITSIO have special identifiers for each type that they
-accept. Gnuastro's type identifiers are fully described in @ref{Library
-data types} and are usable for all kinds of datasets (images, table columns,
-etc) as part of Gnuastro's @ref{Generic data container}. However,
-following the FITS standard, CFITSIO has different identifiers for images
-and tables. Following CFITSIO's own convention, we will use @code{bitpix}
-for image type identifiers and @code{datatype} for its internal identifiers
-(and mainly used in tables). The functions introduced in this section can
-be used to convert between CFITSIO and Gnuastro's type identifiers.
-
-One important issue to consider is that CFITSIO's types are not fixed width
-(for example, @code{long} may be 32-bits or 64-bits on different
-systems). However, Gnuastro's types are defined by their width. These
-functions will use information on the host system to do the proper
-conversion. To have a portable (usable on different systems) code, is thus
-recommended to use these functions and not to assume a fixed correspondence
-between CFITSIO and Gnuastro's types.
+Both Gnuastro and CFITSIO have special and different identifiers for each type 
that they accept.
+Gnuastro's type identifiers are fully described in @ref{Library data types} 
and are usable for all kinds of datasets (images, table columns, etc) as part 
of Gnuastro's @ref{Generic data container}.
+However, following the FITS standard, CFITSIO has different identifiers for 
images and tables.
+Following CFITSIO's own convention, we will use @code{bitpix} for image type 
identifiers and @code{datatype} for its internal identifiers (and mainly used 
in tables).
+The functions introduced in this section can be used to convert between 
CFITSIO and Gnuastro's type identifiers.
+
+One important issue to consider is that CFITSIO's types are not fixed width 
(for example, @code{long} may be 32-bits or 64-bits on different systems).
+However, Gnuastro's types are defined by their width.
+These functions will use information on the host system to do the proper 
conversion.
+To have a portable (usable on different systems) code, is thus recommended to 
use these functions and not to assume a fixed correspondence between CFITSIO 
and Gnuastro's types.
 
 @deftypefun uint8_t gal_fits_bitpix_to_type (int @code{bitpix})
 Return the Gnuastro type identifier that corresponds to CFITSIO's
@@ -36550,11 +36504,9 @@ Return the CFITSIO @code{datatype} that corresponds to 
Gnuastro's
 @end deftypefun
 
 @deftypefun uint8_t gal_fits_datatype_to_type (int @code{datatype}, int 
@code{is_table_column})
-Return Gnuastro's type identifier that corresponds to the CFITSIO
-@code{datatype}. Note that when dealing with CFITSIO's @code{TLONG}, the
-fixed width type differs between tables and images. So if the corresponding
-dataset is a table column, put a non-zero value into
-@code{is_table_column}.
+Return Gnuastro's type identifier that corresponds to the CFITSIO 
@code{datatype}.
+Note that when dealing with CFITSIO's @code{TLONG}, the fixed width type 
differs between tables and images.
+So if the corresponding dataset is a table column, put a non-zero value into 
@code{is_table_column}.
 @end deftypefun
 
 @node FITS HDUs, FITS header keywords, CFITSIO and Gnuastro types, FITS files
@@ -36623,32 +36575,24 @@ When your program needs one of these formats, you can 
call this function so if t
 @node FITS header keywords, FITS arrays, FITS HDUs, FITS files
 @subsubsection FITS header keywords
 
-Each FITS extension/HDU contains a raw dataset which can either be a table
-or an image along with some header keywords. The keywords can be used to
-store meta-data about the actual dataset. The functions in this section
-describe Gnuastro's high-level functions for reading and writing FITS
-keywords. Similar to all Gnuastro's FITS-related functions, these functions
-are all wrappers for CFITSIO's low-level functions.
-
-The necessary meta-data (header keywords) for a particular dataset are
-commonly numerous, it is much more efficient to list them in one variable
-and call the reading/writing functions once. Hence the functions in this
-section use linked lists, a thorough introduction to them is given in
-@ref{Linked lists}. To reading FITS keywords, these functions use a list of
-Gnuastro's generic dataset format that is discussed in @ref{List of
-gal_data_t}. To write FITS keywords we define the
-@code{gal_fits_list_key_t} node that is defined below.
+Each FITS extension/HDU contains a raw dataset which can either be a table or 
an image along with some header keywords.
+The keywords can be used to store meta-data about the actual dataset.
+The functions in this section describe Gnuastro's high-level functions for 
reading and writing FITS keywords.
+Similar to all Gnuastro's FITS-related functions, these functions are all 
wrappers for CFITSIO's low-level functions.
+
+The necessary meta-data (header keywords) for a particular dataset are 
commonly numerous, it is much more efficient to list them in one variable and 
call the reading/writing functions once.
+Hence the functions in this section use linked lists, a thorough introduction 
to them is given in @ref{Linked lists}.
+To reading FITS keywords, these functions use a list of Gnuastro's generic 
dataset format that is discussed in @ref{List of gal_data_t}.
+To write FITS keywords we define the @code{gal_fits_list_key_t} node that is 
defined below.
 
 @deftp {Type (C @code{struct})} gal_fits_list_key_t
 @cindex Linked list
 @cindex last-in-first-out
 @cindex first-in-first-out
-Structure for writing FITS keywords. This structure is used for one keyword
-and you do not need to set all elements. With the @code{next} element, you
-can link it to another keyword thus creating a linked list to add any
-number of keywords easily and at any step during your program (see
-@ref{Linked lists} for an introduction on lists). See the functions below
-for adding elements to the list.
+Structure for writing FITS keywords.
+This structure is used for one keyword and you do not need to set all elements.
+With the @code{next} element, you can link it to another keyword thus creating 
a linked list to add any number of keywords easily and at any step during your 
program (see @ref{Linked lists} for an introduction on lists).
+See the functions below for adding elements to the list.
 
 @example
 typedef struct gal_fits_list_key_t
@@ -36674,40 +36618,26 @@ Return 1 (true) if the opened FITS file pointer 
contains the requested keyword a
 @end deftypefun
 
 @deftypefun {void *} gal_fits_key_img_blank (uint8_t @code{type})
-Returns a pointer to an allocated space containing the value to the FITS
-@code{BLANK} header keyword, when the input array has a type of
-@code{type}. This is useful when you want to write the @code{BLANK} keyword
-using CFITSIO's @code{fits_write_key} function.
-
-According to the FITS standard: ``If the @code{BSCALE} and @code{BZERO}
-keywords do not have the default values of 1.0 and 0.0, respectively, then
-the value of the @code{BLANK} keyword must equal the actual value in the
-FITS data array that is used to represent an undefined pixel and not the
-corresponding physical value''. Therefore a special @code{BLANK} value is
-needed for datasets containing signed 8-bit, unsigned 16-bit, unsigned
-32-bit, and unsigned 64-bit integers (types that are defined with
-@code{BSCALE} and @code{BZERO} in the FITS standard).
+Returns a pointer to an allocated space containing the value to the FITS 
@code{BLANK} header keyword, when the input array has a type of @code{type}.
+This is useful when you want to write the @code{BLANK} keyword using CFITSIO's 
@code{fits_write_key} function.
+
+According to the FITS standard: ``If the @code{BSCALE} and @code{BZERO} 
keywords do not have the default values of 1.0 and 0.0, respectively, then the 
value of the @code{BLANK} keyword must equal the actual value in the FITS data 
array that is used to represent an undefined pixel and not the corresponding 
physical value''.
+Therefore a special @code{BLANK} value is needed for datasets containing 
signed 8-bit, unsigned 16-bit, unsigned 32-bit, and unsigned 64-bit integers 
(types that are defined with @code{BSCALE} and @code{BZERO} in the FITS 
standard).
 
 @cartouche
 @noindent
-@strong{Not usable when reading a dataset:} As quoted from the FITS
-standard above, the value returned by this function can only be generically
-used for the writing of the @code{BLANK} keyword header. It @emph{must not}
-be used as the blank pointer when when reading a FITS array using
-CFITSIO. When reading an array with CFITSIO, you can use
-@code{gal_blank_alloc_write} to generate the necessary pointer.
+@strong{Not usable when reading a dataset:} As quoted from the FITS standard 
above, the value returned by this function can only be generically used for the 
writing of the @code{BLANK} keyword header.
+It @emph{must not} be used as the blank pointer when when reading a FITS array 
using CFITSIO.
+When reading an array with CFITSIO, you can use @code{gal_blank_alloc_write} 
to generate the necessary pointer.
 @end cartouche
 @end deftypefun
 
 @deftypefun void gal_fits_key_clean_str_value (char @code{*string})
-Remove the single quotes and possible extra spaces around the keyword values
-that CFITSIO returns when reading a string keyword. CFITSIO does not remove
-the two single quotes around the string value of a keyword. Hence the
-strings it reads are like: @code{'value '}, or
-@code{'some_very_long_value'}. To use the value during your processing, it
-is commonly necessary to remove the single quotes (and possible extra
-spaces). This function will do this within the allocated space of the
-string.
+Remove the single quotes and possible extra spaces around the keyword values 
that CFITSIO returns when reading a string keyword.
+CFITSIO does not remove the two single quotes around the string value of a 
keyword.
+Hence the strings it reads are like: @code{'value '}, or 
@code{'some_very_long_value'}.
+To use the value during your processing, it is commonly necessary to remove 
the single quotes (and possible extra spaces).
+This function will do this within the allocated space of the string.
 @end deftypefun
 
 @deftypefun {char *} gal_fits_key_date_to_struct_tm (char @code{*fitsdate}, 
struct tm @code{*tp})
@@ -36920,10 +36850,8 @@ For more on the input @code{keylist}, see the 
description and example for @code{
 @end deftypefun
 
 @deftypefun void gal_fits_key_write_version (gal_fits_list_key_t 
@code{**keylist}, char @code{*title}, char @code{*filename}, char @code{*hdu})
-Write the (optional, when @code{keylist!=NULL}) given list of keywords
-under the optional FITS keyword @code{title}, then print all the important
-version and date information. This is basically, just a wrapper over
-@code{gal_fits_key_write_version_in_ptr}.
+Write the (optional, when @code{keylist!=NULL}) given list of keywords under 
the optional FITS keyword @code{title}, then print all the important version 
and date information.
+This is basically, just a wrapper over 
@code{gal_fits_key_write_version_in_ptr}.
 @end deftypefun
 
 @deftypefun void gal_fits_key_write_version_in_ptr (gal_fits_list_key_t 
@code{**keylist}, char @code{*title}, fitsfile @code{*fptr})
@@ -36933,23 +36861,16 @@ along with the versions of CFITSIO, WCSLIB (when 
available), GSL, Gnuastro,
 and (the possible) commit information into the header as described in
 @ref{Output FITS files}.
 
-Since the data processing depends on the versions of the libraries you have
-used, it is strongly recommended to include this information in every FITS
-output. @code{gal_fits_img_write} and @code{gal_fits_tab_write} will
-automatically use this function.
+Since the data processing depends on the versions of the libraries you have 
used, it is strongly recommended to include this information in every FITS 
output.
+@code{gal_fits_img_write} and @code{gal_fits_tab_write} will automatically use 
this function.
 @end deftypefun
 
 @deftypefun void gal_fits_key_write_config (gal_fits_list_key_t 
@code{**keylist}, char @code{*title}, char @code{*extname}, char 
@code{*filename}, char @code{*hdu})
-Write the given keyword list (@code{keylist}) into the @code{hdu} extension
-of @code{filename}, ending it with version information. This function will
-write @code{extname} as the name of the extension (value to the standard
-@code{EXTNAME} FITS keyword). The list of keywords will then be printed
-under a title called @code{title}.
+Write the given keyword list (@code{keylist}) into the @code{hdu} extension of 
@code{filename}, ending it with version information.
+This function will write @code{extname} as the name of the extension (value to 
the standard @code{EXTNAME} FITS keyword).
+The list of keywords will then be printed under a title called @code{title}.
 
-This function is used by many Gnuastro programs and is primarily intended
-for writing configuration settings of a program into the zero-th extension
-of their FITS outputs (which is empty when the FITS file is created by
-Gnuastro's program and this library).
+This function is used by many Gnuastro programs and is primarily intended for 
writing configuration settings of a program into the zero-th extension of their 
FITS outputs (which is empty when the FITS file is created by Gnuastro's 
program and this library).
 @end deftypefun
 
 @deftypefun {gal_list_str_t *} gal_fits_with_keyvalue (gal_list_str_t *files, 
char *hdu, char *name, gal_list_str_t *values)
@@ -36967,18 +36888,13 @@ Given a list of FITS file names (@code{files}), a 
certain HDU (@code{hdu}), a ce
 @node FITS arrays, FITS tables, FITS header keywords, FITS files
 @subsubsection FITS arrays (images)
 
-Images (or multi-dimensional arrays in general) are one of the common data
-formats that is stored in FITS files. Only one image may be stored in each
-FITS HDU/extension. The functions described here can be used to get the
-information of, read, or write images in FITS files.
+Images (or multi-dimensional arrays in general) are one of the common data 
formats that is stored in FITS files.
+Only one image may be stored in each FITS HDU/extension.
+The functions described here can be used to get the information of, read, or 
write images in FITS files.
 
 @deftypefun void gal_fits_img_info (fitsfile @code{*fptr}, int @code{*type}, 
size_t @code{*ndim}, size_t @code{**dsize}, char @code{**name}, char 
@code{**unit})
-Read the type (see @ref{Library data types}), number of dimensions, and
-size along each dimension of the CFITSIO @code{fitsfile} into the
-@code{type}, @code{ndim}, and @code{dsize} pointers respectively. If
-@code{name} and @code{unit} are not @code{NULL} (point to a @code{char *}),
-then if the image has a name and units, the respective string will be put
-in these pointers.
+Read the type (see @ref{Library data types}), number of dimensions, and size 
along each dimension of the CFITSIO @code{fitsfile} into the @code{type}, 
@code{ndim}, and @code{dsize} pointers respectively.
+If @code{name} and @code{unit} are not @code{NULL} (point to a @code{char *}), 
then if the image has a name and units, the respective string will be put in 
these pointers.
 @end deftypefun
 
 @deftypefun {size_t *} gal_fits_img_info_dim (char @code{*filename}, char 
@code{*hdu}, size_t @code{*ndim})
@@ -36988,18 +36904,13 @@ along each dimension as an allocated array with 
@code{*ndim} elements.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_fits_img_read (char @code{*filename}, char 
@code{*hdu}, size_t @code{minmapsize}, int @code{quietmmap})
-Read the contents of the @code{hdu} extension/HDU of @code{filename} into a
-Gnuastro generic data container (see @ref{Generic data container}) and
-return it. If the necessary space is larger than @code{minmapsize}, then
-do not keep the data in RAM, but in a file on the HDD/SSD. For more on
-@code{minmapsize} and @code{quietmmap} see the description under the same
-name in @ref{Generic data container}.
-
-Note that this function only reads the main data within the requested FITS
-extension, the WCS will not be read into the returned dataset. To read the
-WCS, you can use @code{gal_wcs_read} function as shown below. Afterwards,
-the @code{gal_data_free} function will free both the dataset and any WCS
-structure (if there are any).
+Read the contents of the @code{hdu} extension/HDU of @code{filename} into a 
Gnuastro generic data container (see @ref{Generic data container}) and return 
it.
+If the necessary space is larger than @code{minmapsize}, then do not keep the 
data in RAM, but in a file on the HDD/SSD.
+For more on @code{minmapsize} and @code{quietmmap} see the description under 
the same name in @ref{Generic data container}.
+
+Note that this function only reads the main data within the requested FITS 
extension, the WCS will not be read into the returned dataset.
+To read the WCS, you can use @code{gal_wcs_read} function as shown below.
+Afterwards, the @code{gal_data_free} function will free both the dataset and 
any WCS structure (if there are any).
 @example
 data=gal_fits_img_read(filename, hdu, -1, 1);
 data->wcs=gal_wcs_read(filename, hdu, 0, 0, 0, &data->wcs->nwcs);
@@ -37007,36 +36918,26 @@ data->wcs=gal_wcs_read(filename, hdu, 0, 0, 0, 
&data->wcs->nwcs);
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_fits_img_read_to_type (char @code{*inputname}, 
char @code{*inhdu}, uint8_t @code{type}, size_t @code{minmapsize}, int 
@code{quietmmap})
-Read the contents of the @code{hdu} extension/HDU of @code{filename} into a
-Gnuastro generic data container (see @ref{Generic data container}) of type
-@code{type} and return it.
+Read the contents of the @code{hdu} extension/HDU of @code{filename} into a 
Gnuastro generic data container (see @ref{Generic data container}) of type 
@code{type} and return it.
 
-This is just a wrapper around @code{gal_fits_img_read} (to read the
-image/array of any type) and @code{gal_data_copy_to_new_type_free} (to
-convert it to @code{type} and free the initially read dataset). See the
-description there for more.
+This is just a wrapper around @code{gal_fits_img_read} (to read the 
image/array of any type) and @code{gal_data_copy_to_new_type_free} (to convert 
it to @code{type} and free the initially read dataset).
+See the description there for more.
 @end deftypefun
 
 @cindex NaN
 @cindex Convolution kernel
 @cindex Kernel, convolution
 @deftypefun {gal_data_t *} gal_fits_img_read_kernel (char @code{*filename}, 
char @code{*hdu}, size_t @code{minmapsize}, int @code{quietmmap})
-Read the @code{hdu} of @code{filename} as a convolution kernel. A
-convolution kernel must have an odd size along all dimensions, it must not
-have blank (NaN in floating point types) values and must be flipped around
-the center to make the proper convolution (see @ref{Convolution
-process}). If there are blank values, this function will change the blank
-values to @code{0.0}. If the input image does not have the other two
-requirements, this function will abort with an error describing the
-condition to the user. The finally returned dataset will have a
-@code{float32} type.
+Read the @code{hdu} of @code{filename} as a convolution kernel.
+A convolution kernel must have an odd size along all dimensions, it must not 
have blank (NaN in floating point types) values and must be flipped around the 
center to make the proper convolution (see @ref{Convolution process}).
+If there are blank values, this function will change the blank values to 
@code{0.0}.
+If the input image does not have the other two requirements, this function 
will abort with an error describing the condition to the user.
+The finally returned dataset will have a @code{float32} type.
 @end deftypefun
 
 @deftypefun {fitsfile *} gal_fits_img_write_to_ptr (gal_data_t @code{*input}, 
char @code{*filename})
-Write the @code{input} dataset into a FITS file named @file{filename} and
-return the corresponding CFITSIO @code{fitsfile} pointer. This function
-will not close @code{fitsfile}, so you can still add other extensions to it
-after this function or make other modifications.
+Write the @code{input} dataset into a FITS file named @file{filename} and 
return the corresponding CFITSIO @code{fitsfile} pointer.
+This function will not close @code{fitsfile}, so you can still add other 
extensions to it after this function or make other modifications.
 @end deftypefun
 
 @deftypefun void gal_fits_img_write (gal_data_t @code{*data}, char 
@code{*filename}, gal_fits_list_key_t @code{*headers}, char 
@code{*program_string})
@@ -37046,34 +36947,26 @@ along with your program's name 
(@code{program_string}).
 @end deftypefun
 
 @deftypefun void gal_fits_img_write_to_type (gal_data_t @code{*data}, char 
@code{*filename}, gal_fits_list_key_t @code{*headers}, char 
@code{*program_string}, int @code{type})
-Convert the @code{input} dataset into @code{type}, then write it into the
-FITS file named @file{filename}. Also add the @code{headers} keywords to
-the newly created HDU/extension along with your program's name
-(@code{program_string}). After the FITS file is written, this function will
-free the copied dataset (with type @code{type}) from memory.
+Convert the @code{input} dataset into @code{type}, then write it into the FITS 
file named @file{filename}.
+Also add the @code{headers} keywords to the newly created HDU/extension along 
with your program's name (@code{program_string}).
+After the FITS file is written, this function will free the copied dataset 
(with type @code{type}) from memory.
 
-This is just a wrapper for the @code{gal_data_copy_to_new_type} and
-@code{gal_fits_img_write} functions.
+This is just a wrapper for the @code{gal_data_copy_to_new_type} and 
@code{gal_fits_img_write} functions.
 @end deftypefun
 
 @deftypefun void gal_fits_img_write_corr_wcs_str (gal_data_t @code{*data}, 
char @code{*filename}, char @code{*wcsstr}, int @code{nkeyrec}, double 
@code{*crpix}, gal_fits_list_key_t @code{*headers}, char @code{*program_string})
-Write the @code{input} dataset into @file{filename} using the @code{wcsstr}
-while correcting the @code{CRPIX} values.
+Write the @code{input} dataset into @file{filename} using the @code{wcsstr} 
while correcting the @code{CRPIX} values.
 
-This function is mainly useful when you want to make FITS files in parallel
-(from one main WCS structure, with just differing CRPIX). This can happen
-in the following cases for example:
+This function is mainly useful when you want to make FITS files in parallel 
(from one main WCS structure, with just differing CRPIX).
+This can happen in the following cases for example:
 
 @itemize
 @item
-When a large number of FITS images (with WCS) need to be created in
-parallel, it can be much more efficient to write the header's WCS keywords
-once at first, write them in the FITS file, then just correct the CRPIX
-values.
+When a large number of FITS images (with WCS) need to be created in parallel, 
it can be much more efficient to write the header's WCS keywords once at first, 
write them in the FITS file, then just correct the CRPIX values.
 
 @item
-WCSLIB's header writing function is not thread safe. So when writing FITS
-images in parallel, we cannot write the header keywords in each thread.
+WCSLIB's header writing function is not thread safe.
+So when writing FITS images in parallel, we cannot write the header keywords 
in each thread.
 @end itemize
 @end deftypefun
 
@@ -37081,43 +36974,32 @@ images in parallel, we cannot write the header 
keywords in each thread.
 @node FITS tables,  , FITS arrays, FITS files
 @subsubsection FITS tables
 
-Tables are one of the common formats of data that is stored in FITS
-files. Only one table may be stored in each FITS HDU/extension, but each
-table column must be viewed as a different dataset (with its own name,
-units and numeric data type for example). The only constraint of the column
-datasets in a table is that they must be one-dimensional and have the same
-number of elements as the other columns. The functions described here can
-be used to get the information of, read, or write columns into FITS tables.
+Tables are one of the common formats of data that is stored in FITS files.
+Only one table may be stored in each FITS HDU/extension, but each table column 
must be viewed as a different dataset (with its own name, units and numeric 
data type for example).
+The only constraint of the column datasets in a table is that they must be 
one-dimensional and have the same number of elements as the other columns.
+The functions described here can be used to get the information of, read, or 
write columns into FITS tables.
 
 @deftypefun void gal_fits_tab_size (fitsfile @code{*fitsptr}, size_t 
@code{*nrows}, size_t @code{*ncols})
-Read the number of rows and columns in the table within CFITSIO's
-@code{fitsptr}.
+Read the number of rows and columns in the table within CFITSIO's 
@code{fitsptr}.
 @end deftypefun
 
 @deftypefun int gal_fits_tab_format (fitsfile @code{*fitsptr})
-Return the format of the FITS table contained in CFITSIO's
-@code{fitsptr}. Recall that FITS tables can be in binary or ASCII
-formats. This function will return @code{GAL_TABLE_FORMAT_AFITS} or
-@code{GAL_TABLE_FORMAT_BFITS} (defined in @ref{Table input output}). If the
-@code{fitsptr} is not a table, this function will abort the program with an
-error message informing the user of the problem.
+Return the format of the FITS table contained in CFITSIO's @code{fitsptr}.
+Recall that FITS tables can be in binary or ASCII formats.
+This function will return @code{GAL_TABLE_FORMAT_AFITS} or 
@code{GAL_TABLE_FORMAT_BFITS} (defined in @ref{Table input output}).
+If the @code{fitsptr} is not a table, this function will abort the program 
with an error message informing the user of the problem.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_fits_tab_info (char @code{*filename}, char 
@code{*hdu}, size_t @code{*numcols}, size_t @code{*numrows}, int 
@code{*tableformat})
-Store the information of each column in @code{hdu} of @code{filename} into
-an array of data structures with @code{numcols} elements (one data
-structure for each column) see @ref{Arrays of datasets}. The total number
-of rows in the table is also put into the memory that @code{numrows} points
-to. The format of the table (e.g., FITS binary or ASCII table) will be put
-in @code{tableformat} (macros defined in @ref{Table input output}).
-
-This function is just for column information. Therefore it only stores
-meta-data like column name, units and comments. No actual data (contents of
-the columns for example, the @code{array} or @code{dsize} elements) will be
-allocated by this function. This is a low-level function particular to
-reading tables in FITS format. To be generic, it is recommended to use
-@code{gal_table_info} which will allow getting information from a variety
-of table formats based on the filename (see @ref{Table input output}).
+Store the information of each column in @code{hdu} of @code{filename} into an 
array of data structures with @code{numcols} elements (one data structure for 
each column) see @ref{Arrays of datasets}.
+The total number of rows in the table is also put into the memory that 
@code{numrows} points to.
+The format of the table (e.g., FITS binary or ASCII table) will be put in 
@code{tableformat} (macros defined in @ref{Table input output}).
+
+This function is just for column information.
+Therefore it only stores meta-data like column name, units and comments.
+No actual data (contents of the columns for example, the @code{array} or 
@code{dsize} elements) will be allocated by this function.
+This is a low-level function particular to reading tables in FITS format.
+To be generic, it is recommended to use @code{gal_table_info} which will allow 
getting information from a variety of table formats based on the filename (see 
@ref{Table input output}).
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_fits_tab_read (char @code{*filename}, char 
@code{*hdu}, size_t @code{numrows}, gal_data_t @code{*colinfo}, 
gal_list_sizet_t @code{*indexll}, size_t @code{numthreads}, size_t 
@code{minmapsize}, int @code{quietmmap})
@@ -37137,18 +37019,13 @@ It is recommended to use @code{gal_table_read} for 
generic reading of tables, se
 @end deftypefun
 
 @deftypefun void gal_fits_tab_write (gal_data_t @code{*cols}, gal_list_str_t 
@code{*comments}, int @code{tableformat}, char @code{*filename}, char 
@code{*extname})
-Write the list of datasets in @code{cols} (see @ref{List of gal_data_t}) as
-separate columns in a FITS table in @code{filename}. If @code{filename}
-already exists then this function will write the table as a new extension
-called @code{extname}, after all existing ones. The format of the table
-(ASCII or binary) may be specified with the @code{tableformat} (see
-@ref{Table input output}). If @code{comments!=NULL}, each node of the list
-of strings will be written as a @code{COMMENT} keywords in the output FITS
-file (see @ref{List of strings}.
+Write the list of datasets in @code{cols} (see @ref{List of gal_data_t}) as 
separate columns in a FITS table in @code{filename}.
+If @code{filename} already exists then this function will write the table as a 
new extension called @code{extname}, after all existing ones.
+The format of the table (ASCII or binary) may be specified with the 
@code{tableformat} (see @ref{Table input output}).
+If @code{comments!=NULL}, each node of the list of strings will be written as 
a @code{COMMENT} keywords in the output FITS file (see @ref{List of strings}.
 
-This is a low-level function for tables. It is recommended to use
-@code{gal_table_write} for generic writing of tables in a variety of
-formats, see @ref{Table input output}.
+This is a low-level function for tables.
+It is recommended to use @code{gal_table_write} for generic writing of tables 
in a variety of formats, see @ref{Table input output}.
 @end deftypefun
 
 
@@ -37158,13 +37035,9 @@ formats, see @ref{Table input output}.
 @node File input output, World Coordinate System, FITS files, Gnuastro library
 @subsection File input output
 
-The most commonly used file format in astronomical data analysis is the
-FITS format (see @ref{Fits} for an introduction), therefore Gnuastro's
-library provides a large and separate collection of functions to read/write
-data from/to them (see @ref{FITS files}). However, FITS is not well
-recognized outside the astronomical community and cannot be imported into
-documents or slides. Therefore, in this section, we discuss the other
-different file formats that Gnuastro's library recognizes.
+The most commonly used file format in astronomical data analysis is the FITS 
format (see @ref{Fits} for an introduction), therefore Gnuastro's library 
provides a large and separate collection of functions to read/write data 
from/to them (see @ref{FITS files}).
+However, FITS is not well recognized outside the astronomical community and 
cannot be imported into documents or slides.
+Therefore, in this section, we discuss the other different file formats that 
Gnuastro's library recognizes.
 
 @menu
 * Text files::                  Reading and writing from/to plain text files.
@@ -37737,24 +37610,19 @@ Remove the given FITS dimension from the given 
@code{wcs} structure.
 @end deftypefun
 
 @deftypefun void gal_wcs_on_tile (gal_data_t @code{*tile})
-Create a WCSLIB @code{wcsprm} structure for @code{tile} using WCS
-parameters of the tile's allocated block dataset, see @ref{Tessellation
-library} for the definition of tiles. If @code{tile} already has a WCS
-structure, this function will not do anything.
+Create a WCSLIB @code{wcsprm} structure for @code{tile} using WCS parameters 
of the tile's allocated block dataset, see @ref{Tessellation library} for the 
definition of tiles.
+If @code{tile} already has a WCS structure, this function will not do anything.
 
-In many cases, tiles are created for internal/low-level processing. Hence
-for performance reasons, when creating the tiles they do not have any WCS
-structure. When needed, this function can be used to add a WCS structure to
-each tile tile by copying the WCS structure of its block and correcting the
-reference point's coordinates within the tile.
+In many cases, tiles are created for internal/low-level processing.
+Hence for performance reasons, when creating the tiles they do not have any 
WCS structure.
+When needed, this function can be used to add a WCS structure to each tile 
tile by copying the WCS structure of its block and correcting the reference 
point's coordinates within the tile.
 @end deftypefun
 
 @deftypefun {double *} gal_wcs_warp_matrix (struct wcsprm @code{*wcs})
-Return the Warping matrix of the given WCS structure as an array of double
-precision floating points. This will be the final matrix, irrespective of
-the type of storage in the WCS structure. Recall that the FITS standard has
-several methods to store the matrix. The output is an allocated square
-matrix with each side equal to the number of dimensions.
+Return the Warping matrix of the given WCS structure as an array of double 
precision floating points.
+This will be the final matrix, irrespective of the type of storage in the WCS 
structure.
+Recall that the FITS standard has several methods to store the matrix.
+The output is an allocated square matrix with each side equal to the number of 
dimensions.
 @end deftypefun
 
 @deftypefun void gal_wcs_clean_small_errors (struct wcsprm @code{*wcs})
@@ -37765,21 +37633,14 @@ When the FITS keyword @code{CRDER} (optional) is 
defined it will be used as a re
 @end deftypefun
 
 @deftypefun void gal_wcs_decompose_pc_cdelt (struct wcsprm @code{*wcs})
-Decompose the @code{PCi_j} and @code{CDELTi} elements of
-@code{wcs}. According to the FITS standard, in the @code{PCi_j} WCS
-formalism, the rotation matrix elements @mymath{m_{ij}} are encoded in the
-@code{PCi_j} keywords and the scale factors are encoded in the
-@code{CDELTi} keywords. There is also another formalism (the @code{CDi_j}
-formalism) which merges the two into one matrix.
-
-However, WCSLIB's internal operations are apparently done in the
-@code{PCi_j} formalism. So its outputs are also all in that format by
-default. When the input is a @code{CDi_j}, WCSLIB will still read the
-matrix directly into the @code{PCi_j} matrix and the @code{CDELTi} values
-are set to @code{1} (one). This function is designed to correct such
-issues: after it is finished, the @code{CDELTi} values in @code{wcs} will
-correspond to the pixel scale, and the @code{PCi_j} will correction show
-the rotation.
+Decompose the @code{PCi_j} and @code{CDELTi} elements of @code{wcs}.
+According to the FITS standard, in the @code{PCi_j} WCS formalism, the 
rotation matrix elements @mymath{m_{ij}} are encoded in the @code{PCi_j} 
keywords and the scale factors are encoded in the @code{CDELTi} keywords.
+There is also another formalism (the @code{CDi_j} formalism) which merges the 
two into one matrix.
+
+However, WCSLIB's internal operations are apparently done in the @code{PCi_j} 
formalism.
+So its outputs are also all in that format by default.
+When the input is a @code{CDi_j}, WCSLIB will still read the matrix directly 
into the @code{PCi_j} matrix and the @code{CDELTi} values are set to @code{1} 
(one).
+This function is designed to correct such issues: after it is finished, the 
@code{CDELTi} values in @code{wcs} will correspond to the pixel scale, and the 
@code{PCi_j} will correction show the rotation.
 @end deftypefun
 
 @deftypefun void gal_wcs_to_cd (struct wcsprm @code{*wcs})
@@ -37852,10 +37713,9 @@ gal_fits_img_write(data, "tpv.fits", NULL, NULL);
 @end deftypefun
 
 @deftypefun double gal_wcs_angular_distance_deg (double @code{r1}, double 
@code{d1}, double @code{r2}, double @code{d2})
-Return the angular distance (in degrees) between a point located at
-(@code{r1}, @code{d1}) to (@code{r2}, @code{d2}). All input coordinates are
-in degrees. The distance (along a great circle) on a sphere between two
-points is calculated with the equation below.
+Return the angular distance (in degrees) between a point located at 
(@code{r1}, @code{d1}) to (@code{r2}, @code{d2}).
+All input coordinates are in degrees.
+The distance (along a great circle) on a sphere between two points is 
calculated with the equation below.
 
 @dispmath {\cos(d)=\sin(d_1)\sin(d_2)+\cos(d_1)\cos(d_2)\cos(r_1-r_2)}
 
@@ -37965,7 +37825,9 @@ Each flag is described below:
 
 @table @code
 @item GAL_ARITHMETIC_FLAG_INPLACE
-Do the operation in-place (in the input dataset, thus modifying it) to improve 
CPU and memory usage. If this flag is used, after @code{gal_arithmetic} 
finishes, the input dataset will be modified. It is thus useful if you have no 
more need for the input after the operation.
+Do the operation in-place (in the input dataset, thus modifying it) to improve 
CPU and memory usage.
+If this flag is used, after @code{gal_arithmetic} finishes, the input dataset 
will be modified.
+It is thus useful if you have no more need for the input after the operation.
 
 @item GAL_ARITHMETIC_FLAG_FREE
 Free (all the) input dataset(s) after the operation is done.
@@ -38197,7 +38059,8 @@ See the description of the @code{stitch} operator in 
Arithmetic (@ref{Dimensiona
 @end deffn
 
 @deffn Macro GAL_ARITHMETIC_OP_POW
-Binary operator to-power operator. When @code{gal_arithmetic} is called with 
any of these operators, it will expect two operands: raising the first by the 
second (returning a floating point, inputs can be integers).
+Binary operator to-power operator.
+When @code{gal_arithmetic} is called with any of these operators, it will 
expect two operands: raising the first by the second (returning a floating 
point, inputs can be integers).
 @end deffn
 
 @deffn  Macro GAL_ARITHMETIC_OP_BITAND
@@ -38300,7 +38163,8 @@ They are given separate macros here to help the 
higher-level callers to manage t
 @end deffn
 
 @deffn Macro GAL_ARITHMETIC_OP_SIZE
-Size operator that will return a single value for datasets of any kind. When 
@code{gal_arithmetic} is called with this operator, it requires two arguments.
+Size operator that will return a single value for datasets of any kind.
+When @code{gal_arithmetic} is called with this operator, it requires two 
arguments.
 The first is the dataset, and the second is a single integer value.
 The output type is a single integer.
 @end deffn
@@ -38395,20 +38259,15 @@ See @ref{Table input output} for the macros that can 
be given to @code{searchin}
 @node Tessellation library, Bounding box, Arithmetic on datasets, Gnuastro 
library
 @subsection Tessellation library (@file{tile.h})
 
-In many contexts, it is desirable to slice the dataset into subsets or
-tiles (overlapping or not). In such a way that you can work on each tile
-independently. One method would be to copy that region to a separate
-allocated space, but in many contexts this is not necessary and in fact can
-be a big burden on CPU/Memory usage. The @code{block} pointer in Gnuastro's
-@ref{Generic data container} is defined for such situations: where
-allocation is not necessary. You just want to read the data or write to it
-independently (or in coordination with) other regions of the dataset. Added
-with parallel processing, this can greatly improve the time/memory
-consumption.
+In many contexts, it is desirable to slice the dataset into subsets or tiles 
(overlapping or not).
+In such a way that you can work on each tile independently.
+One method would be to copy that region to a separate allocated space, but in 
many contexts this is not necessary and in fact can be a big burden on 
CPU/Memory usage.
+The @code{block} pointer in Gnuastro's @ref{Generic data container} is defined 
for such situations: where allocation is not necessary.
+You just want to read the data or write to it independently (or in 
coordination with) other regions of the dataset.
+Added with parallel processing, this can greatly improve the time/memory 
consumption.
 
-See the figure below for example: assume the @code{larger} dataset is a
-contiguous block of memory that you are interpreting as a 2D array. But
-you only want to work on the smaller @code{tile} region.
+See the figure below for example: assume the @code{larger} dataset is a 
contiguous block of memory that you are interpreting as a 2D array.
+But you only want to work on the smaller @code{tile} region.
 
 @example
                             larger
@@ -38426,41 +38285,23 @@ you only want to work on the smaller @code{tile} 
region.
               ---------------------------------
 @end example
 
-To use @code{gal_data_t}'s @code{block} concept, you allocate a
-@code{gal_data_t *tile} which is initialized with the pointer to the first
-element in the sub-array (as its @code{array} argument). Note that this is
-not necessarily the first element in the larger array. You can set the size
-of the tile along with the initialization as you please. Recall that, when
-given a non-@code{NULL} pointer as @code{array}, @code{gal_data_initialize}
-(and thus @code{gal_data_alloc}) do not allocate any space and just uses
-the given pointer for the new @code{array} element of the
-@code{gal_data_t}. So your @code{tile} data structure will not be pointing
-to a separately allocated space.
-
-After the allocation is done, you just point @code{tile->block} to the
-@code{larger} dataset which hosts the full block of memory. Where relevant,
-Gnuastro's library functions will check the @code{block} pointer of their
-input dataset to see how to deal with dimensions and increments so they can
-always remain within the tile. The tools introduced in this section are
-designed to help in defining and working with tiles that are created in
-this manner.
-
-Since the block structure is defined as a pointer, arbitrary levels of
-tessellation/grid-ing are possible (@code{tile->block} may itself be a tile
-in an even larger allocated space). Therefore, just like a linked-list (see
-@ref{Linked lists}), it is important to have the @code{block} pointer of
-the largest (allocated) dataset set to @code{NULL}. Normally, you will not
-have to worry about this, because @code{gal_data_initialize} (and thus
-@code{gal_data_alloc}) will set the @code{block} element to @code{NULL} by
-default, just remember not to change it. You can then only change the
-@code{block} element for the tiles you define over the allocated space.
-
-Below, we will first review constructs for @ref{Independent tiles} and then
-define the current approach to fully tessellating a dataset (or covering
-every pixel/data-element with a non-overlapping tile grid in @ref{Tile
-grid}. This approach to dealing with parts of a larger block was inspired
-from a similarly named concept in the GNU Scientific Library (GSL), see its
-``Vectors and Matrices'' chapter for their implementation.
+To use @code{gal_data_t}'s @code{block} concept, you allocate a 
@code{gal_data_t *tile} which is initialized with the pointer to the first 
element in the sub-array (as its @code{array} argument).
+Note that this is not necessarily the first element in the larger array.
+You can set the size of the tile along with the initialization as you please.
+Recall that, when given a non-@code{NULL} pointer as @code{array}, 
@code{gal_data_initialize} (and thus @code{gal_data_alloc}) do not allocate any 
space and just uses the given pointer for the new @code{array} element of the 
@code{gal_data_t}.
+So your @code{tile} data structure will not be pointing to a separately 
allocated space.
+
+After the allocation is done, you just point @code{tile->block} to the 
@code{larger} dataset which hosts the full block of memory.
+Where relevant, Gnuastro's library functions will check the @code{block} 
pointer of their input dataset to see how to deal with dimensions and 
increments so they can always remain within the tile.
+The tools introduced in this section are designed to help in defining and 
working with tiles that are created in this manner.
+
+Since the block structure is defined as a pointer, arbitrary levels of 
tessellation/grid-ing are possible (@code{tile->block} may itself be a tile in 
an even larger allocated space).
+Therefore, just like a linked-list (see @ref{Linked lists}), it is important 
to have the @code{block} pointer of the largest (allocated) dataset set to 
@code{NULL}.
+Normally, you will not have to worry about this, because 
@code{gal_data_initialize} (and thus @code{gal_data_alloc}) will set the 
@code{block} element to @code{NULL} by default, just remember not to change it.
+You can then only change the @code{block} element for the tiles you define 
over the allocated space.
+
+Below, we will first review constructs for @ref{Independent tiles} and then 
define the current approach to fully tessellating a dataset (or covering every 
pixel/data-element with a non-overlapping tile grid in @ref{Tile grid}.
+This approach to dealing with parts of a larger block was inspired from a 
similarly named concept in the GNU Scientific Library (GSL), see its ``Vectors 
and Matrices'' chapter for their implementation.
 
 
 
@@ -38472,31 +38313,21 @@ from a similarly named concept in the GNU Scientific 
Library (GSL), see its
 @node Independent tiles, Tile grid, Tessellation library, Tessellation library
 @subsubsection Independent tiles
 
-The most general application of tiles is to treat each independently, for
-example they may overlap, or they may not cover the full image. This
-section provides functions to help in checking/inspecting such tiles. In
-@ref{Tile grid} we will discuss functions that define/work-with a tile grid
-(where the tiles do not overlap and fully cover the input
-dataset). Therefore, the functions in this section are general and can be
-used for the tiles produced by that section also.
+The most general application of tiles is to treat each independently, for 
example they may overlap, or they may not cover the full image.
+This section provides functions to help in checking/inspecting such tiles.
+In @ref{Tile grid} we will discuss functions that define/work-with a tile grid 
(where the tiles do not overlap and fully cover the input dataset).
+Therefore, the functions in this section are general and can be used for the 
tiles produced by that section also.
 
 @deftypefun void gal_tile_start_coord (gal_data_t @code{*tile}, size_t 
@code{*start_coord})
-Calculate the starting coordinates of a tile in its allocated block of
-memory and write them in the memory that @code{start_coord} points to
-(which must have @code{tile->ndim} elements).
+Calculate the starting coordinates of a tile in its allocated block of memory 
and write them in the memory that @code{start_coord} points to (which must have 
@code{tile->ndim} elements).
 @end deftypefun
 
 @deftypefun void gal_tile_start_end_coord (gal_data_t @code{*tile}, size_t 
@code{*start_end}, int @code{rel_block})
-Put the starting and ending (end point is not inclusive) coordinates of
-@code{tile} into the @code{start_end} array. It is assumed that a space of
-@code{2*tile->ndim} has been already allocated (static or dynamic) for
-@code{start_end} before this function is called.
+Put the starting and ending (end point is not inclusive) coordinates of 
@code{tile} into the @code{start_end} array.
+It is assumed that a space of @code{2*tile->ndim} has been already allocated 
(static or dynamic) for @code{start_end} before this function is called.
 
-@code{rel_block} (or relative-to-block) is only relevant when @code{tile}
-has an intermediate tile between it and the allocated space (like a
-channel, see @code{gal_tile_full_two_layers}). If it does not
-(@code{tile->block} points the allocated dataset), then the value to
-@code{rel_block} is irrelevant.
+@code{rel_block} (or relative-to-block) is only relevant when @code{tile} has 
an intermediate tile between it and the allocated space (like a channel, see 
@code{gal_tile_full_two_layers}).
+If it does not (@code{tile->block} points the allocated dataset), then the 
value to @code{rel_block} is irrelevant.
 
 When @code{tile->block} is itself a larger block and @code{rel_block} is
 set to 0, then the starting and ending positions will be based on the
@@ -38504,31 +38335,22 @@ position within @code{tile->block}, not the allocated 
space.
 @end deftypefun
 
 @deftypefun {void *} gal_tile_start_end_ind_inclusive (gal_data_t 
@code{*tile}, gal_data_t @code{*work}, size_t @code{*start_end_inc})
-Put the indices of the first/start and last/end pixels (inclusive) in a tile
-into the @code{start_end} array (that must have two elements). NOTE: this
-function stores the index of each point, not its coordinates. It will then
-return the pointer to the start of the tile in the @code{work} data
-structure (which does not have to be equal to @code{tile->block}.
+Put the indices of the first/start and last/end pixels (inclusive) in a tile 
into the @code{start_end} array (that must have two elements).
+NOTE: this function stores the index of each point, not its coordinates.
+It will then return the pointer to the start of the tile in the @code{work} 
data structure (which does not have to be equal to @code{tile->block}.
 
-The outputs of this function are defined to make it easy to parse over an
-n-dimensional tile. For example, this function is one of the most important
-parts of the internal processing of in @code{GAL_TILE_PARSE_OPERATE}
-function-like macro that is described below.
+The outputs of this function are defined to make it easy to parse over an 
n-dimensional tile.
+For example, this function is one of the most important parts of the internal 
processing of in @code{GAL_TILE_PARSE_OPERATE} function-like macro that is 
described below.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_tile_series_from_minmax (gal_data_t 
@code{*block}, size_t @code{*minmax}, size_t @code{number})
-Construct a list of tile(s) given coordinates of the minimum and maximum of
-each tile. The minimum and maximums are assumed to be inclusive and in C
-order (slowest dimension first). The returned pointer is an allocated
-@code{gal_data_t} array that can later be freed with
-@code{gal_data_array_free} (see @ref{Arrays of datasets}). Internally, each
-element of the output array points to the next element, so the output may
-also be treated as a list of datasets (see @ref{List of gal_data_t}) and
-passed onto the other functions described in this section.
+Construct a list of tile(s) given coordinates of the minimum and maximum of 
each tile.
+The minimum and maximums are assumed to be inclusive and in C order (slowest 
dimension first).
+The returned pointer is an allocated @code{gal_data_t} array that can later be 
freed with @code{gal_data_array_free} (see @ref{Arrays of datasets}).
+Internally, each element of the output array points to the next element, so 
the output may also be treated as a list of datasets (see @ref{List of 
gal_data_t}) and passed onto the other functions described in this section.
 
-The array keeping the minimum and maximum coordinates for each tile must
-have the following format. So in total @code{minmax} must have
-@code{2*ndim*number} elements.
+The array keeping the minimum and maximum coordinates for each tile must have 
the following format.
+So in total @code{minmax} must have @code{2*ndim*number} elements.
 
 @example
 | min0_d0 | min0_d1 | max0_d0 | max0_d1 | ...
@@ -38537,166 +38359,120 @@ have the following format. So in total 
@code{minmax} must have
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_tile_block (gal_data_t @code{*tile})
-Return the dataset that contains @code{tile}'s allocated block of
-memory. If tile is immediately defined as part of the allocated block, then
-this is equivalent to @code{tile->block}. However, it is possible to have
-multiple layers of tiles (where @code{tile->block} is itself a tile). So
-this function is the most generic way to get to the actual allocated
-dataset.
+Return the dataset that contains @code{tile}'s allocated block of memory.
+If tile is immediately defined as part of the allocated block, then this is 
equivalent to @code{tile->block}.
+However, it is possible to have multiple layers of tiles (where 
@code{tile->block} is itself a tile).
+So this function is the most generic way to get to the actual allocated 
dataset.
 @end deftypefun
 
 @deftypefun size_t gal_tile_block_increment (gal_data_t @code{*block}, size_t 
@code{*tsize}, size_t @code{num_increment}, size_t @code{*coord})
-Return the increment necessary to start at the next contiguous patch memory
-associated with a tile. @code{block} is the allocated block of memory and
-@code{tsize} is the size of the tile along every dimension. If @code{coord}
-is @code{NULL}, it is ignored. Otherwise, it will contain the coordinate of
-the start of the next contiguous patch of memory.
+Return the increment necessary to start at the next contiguous patch memory 
associated with a tile.
+@code{block} is the allocated block of memory and @code{tsize} is the size of 
the tile along every dimension.
+If @code{coord} is @code{NULL}, it is ignored.
+Otherwise, it will contain the coordinate of the start of the next contiguous 
patch of memory.
 
-This function is intended to be used in a loop and @code{num_increment} is
-the main variable to this function. For the first time you call this
-function, it should be @code{1}. In subsequent calls (while you are parsing
-a tile), it should be increased by one.
+This function is intended to be used in a loop and @code{num_increment} is the 
main variable to this function.
+For the first time you call this function, it should be @code{1}.
+In subsequent calls (while you are parsing a tile), it should be increased by 
one.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_tile_block_write_const_value (gal_data_t 
@code{*tilevalues}, gal_data_t @code{*tilesll}, int @code{withblank}, int 
@code{initialize})
-Write a constant value for each tile over the area it covers in an
-allocated dataset that is the size of @code{tile}'s allocated block of
-memory (found through @code{gal_tile_block} described above). The arguments
-to this function are:
+Write a constant value for each tile over the area it covers in an allocated 
dataset that is the size of @code{tile}'s allocated block of memory (found 
through @code{gal_tile_block} described above).
+The arguments to this function are:
 
 @table @code
 @item tilevalues
-This must be an array that has the same number of elements as the nodes in
-in @code{tilesll} and in the same order that `tilesll' elements are parsed
-(from top to bottom, see @ref{Linked lists}). As a result the array's
-number of dimensions is irrelevant, it will be parsed contiguously.
+This must be an array that has the same number of elements as the nodes in in 
@code{tilesll} and in the same order that `tilesll' elements are parsed (from 
top to bottom, see @ref{Linked lists}).
+As a result the array's number of dimensions is irrelevant, it will be parsed 
contiguously.
 
 @item tilesll
-The list of input tiles (see @ref{List of gal_data_t}). Internally, it
-might be stored as an array (for example, the output of
-@code{gal_tile_series_from_minmax} described above), but this function
-does not care, it will parse the @code{next} elements to go to the next
-tile. This function will not pop-from or free the @code{tilesll}, it will
-only parse it from start to end.
+The list of input tiles (see @ref{List of gal_data_t}).
+Internally, it might be stored as an array (for example, the output of 
@code{gal_tile_series_from_minmax} described above), but this function does not 
care, it will parse the @code{next} elements to go to the next tile.
+This function will not pop-from or free the @code{tilesll}, it will only parse 
it from start to end.
 
 @item withblank
-If the block containing the tiles has blank elements, those blank elements
-will be blank in the output of this function also, hence the array will be
-initialized with blank values when this option is called (see below).
+If the block containing the tiles has blank elements, those blank elements 
will be blank in the output of this function also, hence the array will be 
initialized with blank values when this option is called (see below).
 
 @item initialize
-Initialize the allocated space with blank values before writing in the
-constant values. This can be useful when the tiles do not cover the full
-allocated block.
+Initialize the allocated space with blank values before writing in the 
constant values.
+This can be useful when the tiles do not cover the full allocated block.
 @end table
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_tile_block_check_tiles (gal_data_t 
@code{*tilesll})
-Make a copy of the memory block and fill it with the index of each tile in
-@code{tilesll} (counting from 0). The non-filled areas will have blank
-values. The output dataset will have a type of @code{GAL_TYPE_INT32} (see
-@ref{Library data types}).
+Make a copy of the memory block and fill it with the index of each tile in 
@code{tilesll} (counting from 0).
+The non-filled areas will have blank values.
+The output dataset will have a type of @code{GAL_TYPE_INT32} (see @ref{Library 
data types}).
 
-This function can be used when you want to check the coverage of each tile
-over the allocated block of memory. It is just a wrapper over the
-@code{gal_tile_block_write_const_value} (with @code{withblank} set to zero).
+This function can be used when you want to check the coverage of each tile 
over the allocated block of memory.
+It is just a wrapper over the @code{gal_tile_block_write_const_value} (with 
@code{withblank} set to zero).
 @end deftypefun
 
 @deftypefun {void *} gal_tile_block_relative_to_other (gal_data_t 
@code{*tile}, gal_data_t @code{*other})
-Return the pointer corresponding to the start of the region covered by
-@code{tile} over the @code{other} dataset. See the examples in
-@code{GAL_TILE_PARSE_OPERATE} for some example applications of this
-function.
+Return the pointer corresponding to the start of the region covered by 
@code{tile} over the @code{other} dataset.
+See the examples in @code{GAL_TILE_PARSE_OPERATE} for some example 
applications of this function.
 @end deftypefun
 
 
 @deftypefun void gal_tile_block_blank_flag (gal_data_t @code{*tilell}, size_t 
@code{numthreads})
-Check if each tile in the list has blank values and update its @code{flag}
-to mark this check and its result (see @ref{Generic data container}). The
-operation will be done on @code{numthreads} threads.
+Check if each tile in the list has blank values and update its @code{flag} to 
mark this check and its result (see @ref{Generic data container}).
+The operation will be done on @code{numthreads} threads.
 @end deftypefun
 
 
 @deffn {Function-like macro} GAL_TILE_PARSE_OPERATE (@code{IN}, @code{OTHER}, 
@code{PARSE_OTHER}, @code{CHECK_BLANK}, @code{OP})
-Parse @code{IN} (which can be a tile or a fully allocated block of memory)
-and do the @code{OP} operation on it. @code{OP} can be any combination of C
-expressions. If @code{OTHER!=NULL}, @code{OTHER} will be interpreted as a
-dataset and this macro will allow access to its element(s) and it can
-optionally be parsed while parsing over @code{IN}.
-
-If @code{OTHER} is a fully allocated block of memory (not a tile), then the
-same region that is covered by @code{IN} within its own block will be
-parsed (the same starting pixel with the same number of pixels in each
-dimension). Hence, in this case, the blocks of @code{OTHER} and @code{IN}
-must have the same size. When @code{OTHER} is a tile it must have the same
-size as @code{IN} and parsing will start from its starting element/pixel.
-Also, the respective allocated blocks of @code{OTHER} and @code{IN} (if
-different) may have different sizes. Using @code{OTHER} (along with
-@code{PARSE_OTHER}), this function-like macro will thus enable you to parse
-and define your own operation on two fixed size regions in one or two
-blocks of memory. In the latter case, they may have different numeric
-data types, see @ref{Numeric data types}).
-
-The input arguments to this macro are explained below, the expected type of
-each argument are also written following the argument name:
+Parse @code{IN} (which can be a tile or a fully allocated block of memory) and 
do the @code{OP} operation on it.
+@code{OP} can be any combination of C expressions.
+If @code{OTHER!=NULL}, @code{OTHER} will be interpreted as a dataset and this 
macro will allow access to its element(s) and it can optionally be parsed while 
parsing over @code{IN}.
+
+If @code{OTHER} is a fully allocated block of memory (not a tile), then the 
same region that is covered by @code{IN} within its own block will be parsed 
(the same starting pixel with the same number of pixels in each dimension).
+Hence, in this case, the blocks of @code{OTHER} and @code{IN} must have the 
same size.
+When @code{OTHER} is a tile it must have the same size as @code{IN} and 
parsing will start from its starting element/pixel.
+Also, the respective allocated blocks of @code{OTHER} and @code{IN} (if 
different) may have different sizes.
+Using @code{OTHER} (along with @code{PARSE_OTHER}), this function-like macro 
will thus enable you to parse and define your own operation on two fixed size 
regions in one or two blocks of memory.
+In the latter case, they may have different numeric data types, see 
@ref{Numeric data types}).
+
+The input arguments to this macro are explained below, the expected type of 
each argument are also written following the argument name:
 
 @table @code
 @item IN (gal_data_t)
 Input dataset, this can be a tile or an allocated block of memory.
 
 @item OTHER (gal_data_t)
-Dataset (@code{gal_data_t}) to parse along with @code{IN}. It can be
-@code{NULL}. In that case, @code{o} (see description of @code{OP} below)
-will be @code{NULL} and should not be used. If @code{PARSE_OTHER} is zero,
-only its first element will be used and the size of this dataset is
-irrelevant.
+Dataset (@code{gal_data_t}) to parse along with @code{IN}. It can be 
@code{NULL}. In that case, @code{o} (see description of @code{OP} below) will 
be @code{NULL} and should not be used. If @code{PARSE_OTHER} is zero, only its 
first element will be used and the size of this dataset is irrelevant.
 
-When @code{OTHER} is a block of memory, it has to have the same size as the
-allocated block of @code{IN}. When it s a tile, it has to have the same size
-as @code{IN}.
+When @code{OTHER} is a block of memory, it has to have the same size as the 
allocated block of @code{IN}.
+When it s a tile, it has to have the same size as @code{IN}.
 
 @item PARSE_OTHER (int)
-Parse the other dataset along with the input. When this is non-zero and
-@code{OTHER!=NULL}, then the @code{o} pointer will be incremented to cover
-the @code{OTHER} tile at the same rate as @code{i}, see description of
-@code{OP} for @code{i} and @code{o}.
+Parse the other dataset along with the input.
+When this is non-zero and @code{OTHER!=NULL}, then the @code{o} pointer will 
be incremented to cover the @code{OTHER} tile at the same rate as @code{i}, see 
description of @code{OP} for @code{i} and @code{o}.
 
 @item CHECK_BLANK (int)
-If it is non-zero, then the input will be checked for blank values and
-@code{OP} will only be called when we are not on a blank element.
+If it is non-zero, then the input will be checked for blank values and 
@code{OP} will only be called when we are not on a blank element.
 
 @item OP
-Operator: this can be any number of C expressions. This macro is going to
-define a @code{itype *i} variable which will increment over each element of
-the input array/tile. @code{itype} will be replaced with the C type that
-corresponds to the type of @code{INPUT}. As an example, if @code{INPUT}'s
-type is @code{GAL_DATA_UINT16} or @code{GAL_DATA_FLOAT32}, @code{i} will be
-defined as @code{uint16} or @code{float} respectively.
-
-This function-like macro will also define an @code{otype *o} which you can
-use to access an element of the @code{OTHER} dataset (if
-@code{OTHER!=NULL}). @code{o} will correspond to the type of @code{OTHER}
-(similar to @code{itype} and @code{INPUT} discussed above). If
-@code{PARSE_OTHER} is non-zero, then @code{o} will also be incremented to
-the same index element but in the other array. You can use these along with
-any other variable you define before this macro to process the input and/or
-the other.
-
-All variables within this function-like macro begin with @code{tpo_} except
-for the three variables listed below. Therefore, as long as you do not start
-the names of your variables with this prefix everything will be fine. Note
-that @code{i} (and possibly @code{o}) will be incremented once by this
-function-like macro, so do not increment them within @code{OP}.
+Operator: this can be any number of C expressions.
+This macro is going to define a @code{itype *i} variable which will increment 
over each element of the input array/tile.
+@code{itype} will be replaced with the C type that corresponds to the type of 
@code{INPUT}.
+As an example, if @code{INPUT}'s type is @code{GAL_DATA_UINT16} or 
@code{GAL_DATA_FLOAT32}, @code{i} will be defined as @code{uint16} or 
@code{float} respectively.
+
+This function-like macro will also define an @code{otype *o} which you can use 
to access an element of the @code{OTHER} dataset (if @code{OTHER!=NULL}).
+@code{o} will correspond to the type of @code{OTHER} (similar to @code{itype} 
and @code{INPUT} discussed above).
+If @code{PARSE_OTHER} is non-zero, then @code{o} will also be incremented to 
the same index element but in the other array.
+You can use these along with any other variable you define before this macro 
to process the input and/or the other.
+
+All variables within this function-like macro begin with @code{tpo_} except 
for the three variables listed below.
+Therefore, as long as you do not start the names of your variables with this 
prefix everything will be fine.
+Note that @code{i} (and possibly @code{o}) will be incremented once by this 
function-like macro, so do not increment them within @code{OP}.
 
 @table @code
 @item i
-Pointer to the element of @code{INPUT} that is being parsed with the proper
-type.
+Pointer to the element of @code{INPUT} that is being parsed with the proper 
type.
 
 @item o
-Pointer to the element of @code{OTHER} that is being parsed with the proper
-type. @code{o} can only be used if @code{OTHER!=NULL} and it will be
-parsed/incremented if @code{PARSE_OTHER} is non-zero.
+Pointer to the element of @code{OTHER} that is being parsed with the proper 
type.
+@code{o} can only be used if @code{OTHER!=NULL} and it will be 
parsed/incremented if @code{PARSE_OTHER} is non-zero.
 
 @item b
 Blank value in the type of @code{INPUT}.
@@ -38727,11 +38503,9 @@ tile->array=tarray;
 tile->block=tblock;
 @end example
 
-You can work on the same region of another block in one run of this
-function-like macro. To do that, you can make a fake tile and pass that as
-the @code{OTHER} argument. Below is a demonstration, @code{tile} is the
-actual tile that you start with and @code{new} is the other block of
-allocated memory.
+You can work on the same region of another block in one run of this 
function-like macro.
+To do that, you can make a fake tile and pass that as the @code{OTHER} 
argument.
+Below is a demonstration, @code{tile} is the actual tile that you start with 
and @code{new} is the other block of allocated memory.
 
 @example
 size_t zero=0;
@@ -38857,7 +38631,8 @@ This array is allocated internally by this function.
 
 @deftypefun void gal_tile_full_sanity_check (char @code{*filename}, char 
@code{*hdu}, gal_data_t @code{*input}, struct gal_tile_two_layer_params 
@code{*tl})
 Make sure that the input parameters (in @code{tl}, short for two-layer) 
correspond to the input dataset.
-@code{filename} and @code{hdu} are only required for error messages. Also, 
allocate and fill the @code{tl->channelsize} array.
+@code{filename} and @code{hdu} are only required for error messages.
+Also, allocate and fill the @code{tl->channelsize} array.
 @end deftypefun
 
 @deftypefun void gal_tile_full_two_layers (gal_data_t @code{*input}, struct 
gal_tile_two_layer_params @code{*tl})
@@ -39213,47 +38988,32 @@ Finally, both these arrays are merged together to get 
the final sorted array of
 @subsection Qsort functions (@file{qsort.h})
 
 @cindex @code{qsort}
-When sorting a dataset is necessary, the C programming language provides
-the @code{qsort} (Quick sort) function. @code{qsort} is a generic function
-which allows you to sort any kind of data structure (not just a single
-array of numbers). To define ``greater'' and ``smaller'' (for sorting),
-@code{qsort} needs another function, even for simple numerical types. The
-functions introduced in this section are to passed onto @code{qsort}.
+When sorting a dataset is necessary, the C programming language provides the 
@code{qsort} (Quick sort) function.
+@code{qsort} is a generic function which allows you to sort any kind of data 
structure (not just a single array of numbers).
+To define ``greater'' and ``smaller'' (for sorting), @code{qsort} needs 
another function, even for simple numerical types.
+The functions introduced in this section are to passed onto @code{qsort}.
 
 @cindex NaN
-Note that larger and smaller operators are not defined on NaN
-elements. Therefore, if the input array is a floating point type, and
-contains NaN values, the relevant functions of this section are going to
-put the NaN elements at the end of the list (after the sorted non-NaN
-elements), irrespective of the requested sorting order (increasing or
-decreasing).
-
-The first class of functions below (with @code{TYPE} in their names) can be
-used for sorting a simple numeric array. Just replace @code{TYPE} with the
-dataset's numeric datatype. The second set of functions can be used to sort
-indices (leave the actual numbers untouched). To use the second set of
-functions, a global variable or structure are also necessary as described
-below.
+Note that larger and smaller operators are not defined on NaN elements.
+Therefore, if the input array is a floating point type, and contains NaN 
values, the relevant functions of this section are going to put the NaN 
elements at the end of the list (after the sorted non-NaN elements), 
irrespective of the requested sorting order (increasing or decreasing).
+
+The first class of functions below (with @code{TYPE} in their names) can be 
used for sorting a simple numeric array.
+Just replace @code{TYPE} with the dataset's numeric datatype.
+The second set of functions can be used to sort indices (leave the actual 
numbers untouched).
+To use the second set of functions, a global variable or structure are also 
necessary as described below.
 
 @deffn {Global variable} {gal_qsort_index_single}
 @cindex Thread safety
 @cindex Multi-threaded operation
-Pointer to an array (for example, @code{float *} or @code{int *}) to use as
-a reference in @code{gal_qsort_index_single_TYPE_d} or
-@code{gal_qsort_index_single_TYPE_i}, see the explanation of these
-functions for more. Note that if @emph{more than one} array is to be sorted
-in a multi-threaded operation, these functions will not work as
-expected. However, when all the threads just sort the indices based on a
-@emph{single array}, this global variable can safely be used in a
-multi-threaded scenario.
+Pointer to an array (for example, @code{float *} or @code{int *}) to use as a 
reference in @code{gal_qsort_index_single_TYPE_d} or 
@code{gal_qsort_index_single_TYPE_i}, see the explanation of these functions 
for more.
+Note that if @emph{more than one} array is to be sorted in a multi-threaded 
operation, these functions will not work as expected.
+However, when all the threads just sort the indices based on a @emph{single 
array}, this global variable can safely be used in a multi-threaded scenario.
 @end deffn
 
 @deftp {Type (C @code{struct})} gal_qsort_index_multi
-Structure to get the sorted indices of multiple datasets on multiple threads
-with @code{gal_qsort_index_multi_d} or @code{gal_qsort_index_multi_i}. Note
-that the @code{values} array will not be changed by these functions, it is
-only read. Therefore all the @code{values} elements in the (to be sorted)
-array of @code{gal_qsort_index_multi} must point to the same place.
+Structure to get the sorted indices of multiple datasets on multiple threads 
with @code{gal_qsort_index_multi_d} or @code{gal_qsort_index_multi_i}.
+Note that the @code{values} array will not be changed by these functions, it 
is only read.
+Therefore all the @code{values} elements in the (to be sorted) array of 
@code{gal_qsort_index_multi} must point to the same place.
 
 @example
 struct gal_qsort_index_multi
@@ -39265,29 +39025,20 @@ struct gal_qsort_index_multi
 @end deftp
 
 @deftypefun int gal_qsort_TYPE_d (const void @code{*a}, const void @code{*b})
-When passed to @code{qsort}, this function will sort a @code{TYPE} array in
-decreasing order (first element will be the largest). Please replace
-@code{TYPE} (in the function name) with one of the @ref{Numeric data
-types}, for example, @code{gal_qsort_int32_d}, or
-@code{gal_qsort_float64_d}.
+When passed to @code{qsort}, this function will sort a @code{TYPE} array in 
decreasing order (first element will be the largest).
+Please replace @code{TYPE} (in the function name) with one of the @ref{Numeric 
data types}, for example, @code{gal_qsort_int32_d}, or 
@code{gal_qsort_float64_d}.
 @end deftypefun
 
 @deftypefun int gal_qsort_TYPE_i (const void @code{*a}, const void @code{*b})
-When passed to @code{qsort}, this function will sort a @code{TYPE} array in
-increasing order (first element will be the smallest). Please replace
-@code{TYPE} (in the function name) with one of the @ref{Numeric data
-types}, for example, @code{gal_qsort_int32_i}, or
-@code{gal_qsort_float64_i}.
+When passed to @code{qsort}, this function will sort a @code{TYPE} array in 
increasing order (first element will be the smallest).
+Please replace @code{TYPE} (in the function name) with one of the @ref{Numeric 
data types}, for example, @code{gal_qsort_int32_i}, or 
@code{gal_qsort_float64_i}.
 @end deftypefun
 
 @deftypefun int gal_qsort_index_single_TYPE_d (const void @code{*a}, const 
void @code{*b})
-When passed to @code{qsort}, this function will sort a @code{size_t} array
-based on decreasing values in the @code{gal_qsort_index_single}. The global
-@code{gal_qsort_index_single} pointer has a @code{void *} pointer which
-will be cast to the proper type based on this function: for example
-@code{gal_qsort_index_single_uint16_d} will cast the array to an unsigned
-16-bit integer type. The array that @code{gal_qsort_index_single} points to
-will not be changed, it is only read. For example, see this demo program:
+When passed to @code{qsort}, this function will sort a @code{size_t} array 
based on decreasing values in the @code{gal_qsort_index_single}.
+The global @code{gal_qsort_index_single} pointer has a @code{void *} pointer 
which will be cast to the proper type based on this function: for example 
@code{gal_qsort_index_single_uint16_d} will cast the array to an unsigned 
16-bit integer type.
+The array that @code{gal_qsort_index_single} points to will not be changed, it 
is only read.
+For example, see this demo program:
 
 @example
 #include <stdio.h>
@@ -39317,17 +39068,12 @@ increasing order.
 @end deftypefun
 
 @deftypefun int gal_qsort_index_multi_d (const void @code{*a}, const void 
@code{*b})
-When passed to @code{qsort} with an array of @code{gal_qsort_index_multi},
-this function will sort the array based on the values of the given
-indices. The sorting will be ordered according to the @code{values} pointer
-of @code{gal_qsort_index_multi}. Note that @code{values} must point to the
-same place in all the structures of the @code{gal_qsort_index_multi} array.
+When passed to @code{qsort} with an array of @code{gal_qsort_index_multi}, 
this function will sort the array based on the values of the given indices.
+The sorting will be ordered according to the @code{values} pointer of 
@code{gal_qsort_index_multi}.
+Note that @code{values} must point to the same place in all the structures of 
the @code{gal_qsort_index_multi} array.
 
-This function is only useful when the indices of multiple arrays on
-multiple threads are to be sorted. If your program is single threaded, or
-all the indices belong to a single array (sorting different sub-sets of
-indices in a single array on multiple threads), it is recommended to use
-@code{gal_qsort_index_single_d}.
+This function is only useful when the indices of multiple arrays on multiple 
threads are to be sorted.
+If your program is single threaded, or all the indices belong to a single 
array (sorting different sub-sets of indices in a single array on multiple 
threads), it is recommended to use @code{gal_qsort_index_single_d}.
 @end deftypefun
 
 @deftypefun int gal_qsort_index_multi_i (const void @code{*a}, const void 
*@code{b})
@@ -39542,12 +39288,10 @@ main (void)
 @node Permutations, Matching, K-d tree, Gnuastro library
 @subsection Permutations (@file{permutation.h})
 @cindex permutation
-Permutation is the technical name for re-ordering of values. The need for
-permutations occurs a lot during (mainly low-level) processing. To do
-permutation, you must provide two inputs: an array of values (that you want
-to re-order in place) and a permutation array which contains the new index
-of each element (let's call it @code{perm}). The diagram below shows the
-input array before and after the re-ordering.
+Permutation is the technical name for re-ordering of values.
+The need for permutations occurs a lot during (mainly low-level) processing.
+To do permutation, you must provide two inputs: an array of values (that you 
want to re-order in place) and a permutation array which contains the new index 
of each element (let's call it @code{perm}).
+The diagram below shows the input array before and after the re-ordering.
 
 @example
 permute:    AFTER[ i       ] = BEFORE[ perm[i] ]     i = 0 .. N-1
@@ -39671,25 +39415,19 @@ If internal allocation is necessary and the space is 
larger than @code{minmapsiz
 @node Statistical operations, Fitting functions, Matching, Gnuastro library
 @subsection Statistical operations (@file{statistics.h})
 
-After reading a dataset into memory from a file or fully simulating it with
-another process, the most common processes that will be done on it are
-statistical operations to let you quantify different aspects of the
-data. the functions in this section describe Gnuastro's current set of
-tools for this job. All these functions can work on any numeric data type
-natively (see @ref{Numeric data types}) and can also work on tiles over a
-dataset. Hence the inputs and outputs are in Gnuastro's @ref{Generic data
-container}.
+After reading a dataset into memory from a file or fully simulating it with 
another process, the most common processes that will be done on it are 
statistical operations to let you quantify different aspects of the data.
+the functions in this section describe Gnuastro's current set of tools for 
this job.
+All these functions can work on any numeric data type natively (see 
@ref{Numeric data types}) and can also work on tiles over a dataset.
+Hence the inputs and outputs are in Gnuastro's @ref{Generic data container}.
 
 @deffn  Macro GAL_STATISTICS_SIG_CLIP_MAX_CONVERGE
-The maximum number of clips, when @mymath{\sigma}-clipping should be done
-by convergence. If the clipping does not converge before making this many
-clips, all @mymath{\sigma}-clipping outputs will be NaN.
+The maximum number of clips, when @mymath{\sigma}-clipping should be done by 
convergence.
+If the clipping does not converge before making this many clips, all 
@mymath{\sigma}-clipping outputs will be NaN.
 @end deffn
 
 @deffn  Macro GAL_STATISTICS_MODE_GOOD_SYM
-The minimum acceptable symmetricity of the mode calculation. If the
-symmetricity of the derived mode is less than this value, all the returned
-values by @code{gal_statistics_mode} will have a value of NaN.
+The minimum acceptable symmetricity of the mode calculation.
+If the symmetricity of the derived mode is less than this value, all the 
returned values by @code{gal_statistics_mode} will have a value of NaN.
 @end deffn
 
 @deffn  Macro GAL_STATISTICS_BINS_INVALID
@@ -39700,22 +39438,19 @@ Macros used to identify if the regularity of the bins 
when defining bins.
 
 @cindex Number
 @deftypefun {gal_data_t *} gal_statistics_number (gal_data_t @code{*input})
-Return a single-element dataset with type @code{size_t} which contains the
-number of non-blank elements in @code{input}.
+Return a single-element dataset with type @code{size_t} which contains the 
number of non-blank elements in @code{input}.
 @end deftypefun
 
 @cindex Minimum
 @deftypefun {gal_data_t *} gal_statistics_minimum (gal_data_t @code{*input})
-Return a single-element dataset containing the minimum non-blank value in
-@code{input}. The numerical datatype of the output is the same as
-@code{input}.
+Return a single-element dataset containing the minimum non-blank value in 
@code{input}.
+The numerical datatype of the output is the same as @code{input}.
 @end deftypefun
 
 @cindex Maximum
 @deftypefun {gal_data_t *} gal_statistics_maximum (gal_data_t @code{*input})
-Return a single-element dataset containing the maximum non-blank value in
-@code{input}. The numerical datatype of the output is the same as
-@code{input}.
+Return a single-element dataset containing the maximum non-blank value in 
@code{input}.
+The numerical datatype of the output is the same as @code{input}.
 @end deftypefun
 
 @cindex Sum
@@ -39738,15 +39473,11 @@ containing the standard deviation of the non-blank 
values in @code{input}.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_mean_std (gal_data_t @code{*input})
-Return a two-element (@code{double} or @code{float64}) dataset containing
-the mean and standard deviation of the non-blank values in
-@code{input}. The first element of the returned dataset is the mean and the
-second is the standard deviation.
+Return a two-element (@code{double} or @code{float64}) dataset containing the 
mean and standard deviation of the non-blank values in @code{input}.
+The first element of the returned dataset is the mean and the second is the 
standard deviation.
 
-This function will calculate both values in one pass over the
-dataset. Hence when both the mean and standard deviation of a dataset are
-necessary, this function is much more efficient than calling
-@code{gal_statistics_mean} and @code{gal_statistics_std} separately.
+This function will calculate both values in one pass over the dataset.
+Hence when both the mean and standard deviation of a dataset are necessary, 
this function is much more efficient than calling @code{gal_statistics_mean} 
and @code{gal_statistics_std} separately.
 @end deftypefun
 
 @deftypefun double gal_statistics_std_from_sums (double @code{sum}, double 
@code{sump2}, size_t @code{num})
@@ -39758,16 +39489,12 @@ It is the lower-level function that is used in 
functions like @code{gal_statisti
 
 @cindex Median
 @deftypefun {gal_data_t *} gal_statistics_median (gal_data_t @code{*input}, 
int @code{inplace})
-Return a single-element dataset containing the median of the non-blank
-values in @code{input}. The numerical datatype of the output is the same as
-@code{input}.
+Return a single-element dataset containing the median of the non-blank values 
in @code{input}.
+The numerical datatype of the output is the same as @code{input}.
 
-Calculating the median involves sorting the dataset and removing blank
-values, for better performance (and less memory usage), you can give a
-non-zero value to the @code{inplace} argument. In this case, the sorting
-and removal of blank elements will be done directly on the input
-dataset. However, after this function the original dataset may have changed
-(if it was not sorted or had blank values).
+Calculating the median involves sorting the dataset and removing blank values, 
for better performance (and less memory usage), you can give a non-zero value 
to the @code{inplace} argument.
+In this case, the sorting and removal of blank elements will be done directly 
on the input dataset.
+However, after this function the original dataset may have changed (if it was 
not sorted or had blank values).
 @end deftypefun
 
 @cindex Quantile
@@ -39777,18 +39504,15 @@ assuming the dataset has @code{size} elements.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_quantile (gal_data_t @code{*input}, 
double @code{quantile}, int @code{inplace})
-Return a single-element dataset containing the value with in a quantile
-@code{quantile} of the non-blank values in @code{input}. The numerical
-datatype of the output is the same as @code{input}. See
-@code{gal_statistics_median} for a description of @code{inplace}.
+Return a single-element dataset containing the value with in a quantile 
@code{quantile} of the non-blank values in @code{input}.
+The numerical datatype of the output is the same as @code{input}.
+See @code{gal_statistics_median} for a description of @code{inplace}.
 @end deftypefun
 
 @deftypefun size_t gal_statistics_quantile_function_index (gal_data_t 
@code{*input}, gal_data_t @code{*value}, int @code{inplace})
-Return the index of the quantile function (inverse quantile) of
-@code{input} at @code{value}. In other words, this function will return the
-index of the nearest element (of a sorted and non-blank) @code{input} to
-@code{value}. If the value is outside the range of the input, then this
-function will return @code{GAL_BLANK_SIZE_T}.
+Return the index of the quantile function (inverse quantile) of @code{input} 
at @code{value}.
+In other words, this function will return the index of the nearest element (of 
a sorted and non-blank) @code{input} to @code{value}.
+If the value is outside the range of the input, then this function will return 
@code{GAL_BLANK_SIZE_T}.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_quantile_function (gal_data_t 
@code{*input}, gal_data_t @code{*value}, int @code{inplace})
@@ -39816,17 +39540,12 @@ If the dataset doesn't have a numeric type (as in a 
string), this function will
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_mode (gal_data_t @code{*input}, 
float @code{mirrordist}, int @code{inplace})
-Return a four-element (@code{double} or @code{float64}) dataset that
-contains the mode of the @code{input} distribution. This function
-implements the non-parametric algorithm to find the mode that is described
-in Appendix C of @url{https://arxiv.org/abs/1505.01664, Akhlaghi and
-Ichikawa [2015]}.
-
-In short it compares the actual distribution and its ``mirror
-distribution'' to find the mode. In order to be efficient, you can
-determine how far the comparison goes away from the mirror through the
-@code{mirrordist} parameter (think of it as a multiple of sigma/error). See
-@code{gal_statistics_median} for a description of @code{inplace}.
+Return a four-element (@code{double} or @code{float64}) dataset that contains 
the mode of the @code{input} distribution.
+This function implements the non-parametric algorithm to find the mode that is 
described in Appendix C of @url{https://arxiv.org/abs/1505.01664, Akhlaghi and 
Ichikawa [2015]}.
+
+In short it compares the actual distribution and its ``mirror distribution'' 
to find the mode.
+In order to be efficient, you can determine how far the comparison goes away 
from the mirror through the @code{mirrordist} parameter (think of it as a 
multiple of sigma/error).
+See @code{gal_statistics_median} for a description of @code{inplace}.
 
 The output array has the following elements (in the given order, note that
 counting in C starts from 0).
@@ -39839,11 +39558,8 @@ array[3]: value at the end of symmetricity.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_mode_mirror_plots (gal_data_t 
@code{*input}, gal_data_t @code{*value}, size_t @code{numbins}, int 
@code{inplace}, double @code{*mirror_val})
-Make a mirrored histogram and cumulative frequency plot (with
-@code{numbins}) with the mirror distribution of the @code{input} having a
-value in @code{value}. If all the input elements are blank, or the mirror
-value is outside the range of the input, this function will return a
-@code{NULL} pointer.
+Make a mirrored histogram and cumulative frequency plot (with @code{numbins}) 
with the mirror distribution of the @code{input} having a value in @code{value}.
+If all the input elements are blank, or the mirror value is outside the range 
of the input, this function will return a @code{NULL} pointer.
 
 The output is a list of data structures (see @ref{List of gal_data_t}): the
 first is the bins with one bin at the mirror point, the second is the
@@ -39853,26 +39569,15 @@ plot (with a maximum of one).
 
 
 @deftypefun int gal_statistics_is_sorted (gal_data_t @code{*input}, int 
@code{updateflags})
-Return @code{0} if the input is not sorted, if it is sorted, this function
-will return @code{1} and @code{2} if it is increasing or decreasing,
-respectively. This function will abort with an error if @code{input} has
-zero elements and will return @code{1} (sorted, increasing) when there is
-only one element. This function will only look into the dataset if the
-@code{GAL_DATA_FLAG_SORT_CH} bit of @code{input->flag} is @code{0}, see
-@ref{Generic data container}.
-
-When the flags do not indicate a previous check @emph{and}
-@code{updateflags} is non-zero, this function will set the flags
-appropriately to avoid having to re-check the dataset in future calls (this
-can be very useful when repeated checks are necessary). When
-@code{updateflags==0}, this function has no side-effects on the dataset: it
-will not toggle the flags.
-
-If you want to re-check a dataset with the blank-value-check flag already
-set (for example, if you have made changes to it), then explicitly set the
-@code{GAL_DATA_FLAG_SORT_CH} bit to zero before calling this function. When
-there are no other flags, you can simply set the flags to zero (with
-@code{input->flag=0}), otherwise you can use this expression:
+Return @code{0} if the input is not sorted, if it is sorted, this function 
will return @code{1} and @code{2} if it is increasing or decreasing, 
respectively.
+This function will abort with an error if @code{input} has zero elements and 
will return @code{1} (sorted, increasing) when there is only one element.
+This function will only look into the dataset if the 
@code{GAL_DATA_FLAG_SORT_CH} bit of @code{input->flag} is @code{0}, see 
@ref{Generic data container}.
+
+When the flags do not indicate a previous check @emph{and} @code{updateflags} 
is non-zero, this function will set the flags appropriately to avoid having to 
re-check the dataset in future calls (this can be very useful when repeated 
checks are necessary).
+When @code{updateflags==0}, this function has no side-effects on the dataset: 
it will not toggle the flags.
+
+If you want to re-check a dataset with the blank-value-check flag already set 
(for example, if you have made changes to it), then explicitly set the 
@code{GAL_DATA_FLAG_SORT_CH} bit to zero before calling this function.
+When there are no other flags, you can simply set the flags to zero (with 
@code{input->flag=0}), otherwise you can use this expression:
 
 @example
 input->flag &= ~GAL_DATA_FLAG_SORT_CH;
@@ -39890,27 +39595,21 @@ sort-related bit flags accordingly.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_no_blank_sorted (gal_data_t 
@code{*input}, int @code{inplace})
-Remove all the blanks and sort the input dataset. If @code{inplace} is
-non-zero this will happen on the input dataset (in the allocated space of
-the input dataset). However, if @code{inplace} is zero, this function will
-allocate a new copy of the dataset and work on that. Therefore if
-@code{inplace==0}, the input dataset will be modified.
-
-This function uses the bit flags of the input, so if you have modified the
-dataset, set @code{input->flag=0} before calling this function. Also note
-that @code{inplace} is only for the dataset elements. Therefore even when
-@code{inplace==0}, if the input is already sorted @emph{and} has no blank
-values, then the flags will be updated to show this.
-
-If all the elements were blank, then the returned dataset's @code{size}
-will be zero. This is thus a good parameter to check after calling this
-function to see if there actually were any non-blank elements in the input
-or not and take the appropriate measure. This can help avoid strange bugs
-in later steps. The flags of a zero-sized returned dataset will indicate
-that it has no blanks and is sorted in an increasing order. Even if having
-blank values or being sorted is not defined on a zero-element dataset, it
-is up to the caller to choose what they will do with a zero-element
-dataset. The flags have to be set after this function any way.
+Remove all the blanks and sort the input dataset.
+If @code{inplace} is non-zero this will happen on the input dataset (in the 
allocated space of the input dataset).
+However, if @code{inplace} is zero, this function will allocate a new copy of 
the dataset and work on that.
+Therefore if @code{inplace==0}, the input dataset will be modified.
+
+This function uses the bit flags of the input, so if you have modified the 
dataset, set @code{input->flag=0} before calling this function.
+Also note that @code{inplace} is only for the dataset elements.
+Therefore even when @code{inplace==0}, if the input is already sorted 
@emph{and} has no blank values, then the flags will be updated to show this.
+
+If all the elements were blank, then the returned dataset's @code{size} will 
be zero.
+This is thus a good parameter to check after calling this function to see if 
there actually were any non-blank elements in the input or not and take the 
appropriate measure.
+This can help avoid strange bugs in later steps.
+The flags of a zero-sized returned dataset will indicate that it has no blanks 
and is sorted in an increasing order.
+Even if having blank values or being sorted is not defined on a zero-element 
dataset, it is up to the caller to choose what they will do with a zero-element 
dataset.
+The flags have to be set after this function any way.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_statistics_regular_bins (gal_data_t 
@code{*input}, gal_data_t @code{*inrange}, size_t @code{numbins}, double 
@code{onebinstart})
@@ -39995,20 +39694,16 @@ When a histogram is given and it is normalized, the 
CFP will also be normalized
 
 
 @deftypefun {gal_data_t *} gal_statistics_sigma_clip (gal_data_t 
@code{*input}, float @code{multip}, float @code{param}, int @code{inplace}, int 
@code{quiet})
-Apply @mymath{\sigma}-clipping on a given dataset and return a dataset that
-contains the results. For a description of @mymath{\sigma}-clipping see
-@ref{Sigma clipping}. @code{multip} is the multiple of the standard
-deviation (or @mymath{\sigma}, that is used to define outliers in each
-round of clipping).
+Apply @mymath{\sigma}-clipping on a given dataset and return a dataset that 
contains the results.
+For a description of @mymath{\sigma}-clipping see @ref{Sigma clipping}.
+@code{multip} is the multiple of the standard deviation (or @mymath{\sigma}, 
that is used to define outliers in each round of clipping).
 
-The role of @code{param} is determined based on its value. If @code{param}
-is larger than @code{1} (one), it must be an integer and will be
-interpreted as the number clips to do. If it is less than @code{1} (one),
-it is interpreted as the tolerance level to stop the iteration.
+The role of @code{param} is determined based on its value.
+If @code{param} is larger than @code{1} (one), it must be an integer and will 
be interpreted as the number clips to do.
+If it is less than @code{1} (one), it is interpreted as the tolerance level to 
stop the iteration.
 
-The returned dataset (let's call it @code{out}) contains a four-element
-array with type @code{GAL_TYPE_FLOAT32}. The final number of clips is
-stored in the @code{out->status}.
+The returned dataset (let's call it @code{out}) contains a four-element array 
with type @code{GAL_TYPE_FLOAT32}.
+The final number of clips is stored in the @code{out->status}.
 @example
 float *array=out->array;
 array[0]: Number of points used.
@@ -40060,48 +39755,30 @@ The Fourth and fifth (in parenthesis) are the median 
and standard deviation of t
 
 @deftypefun {gal_data_t *} gal_statistics_outlier_flat_cfp (gal_data_t 
@code{*input}, size_t @code{numprev}, float @code{sigclip_multip}, float 
@code{sigclip_param}, float @code{thresh}, size_t @code{numcontig}, int 
@code{inplace}, int @code{quiet}, size_t @code{*index})
 
-Return the first element in the given dataset where the cumulative
-frequency plot first becomes significantly flat for a sufficient number of
-elements. The returned dataset only has one element (with the same type as
-the input). If @code{index!=NULL}, the index (counting from zero, after
-sorting the dataset and removing any blanks) is written in the space that
-@code{index} points to. If no sufficiently flat portion is found, the
-returned pointer will be @code{NULL}.
+Return the first element in the given dataset where the cumulative frequency 
plot first becomes significantly flat for a sufficient number of elements.
+The returned dataset only has one element (with the same type as the input).
+If @code{index!=NULL}, the index (counting from zero, after sorting the 
dataset and removing any blanks) is written in the space that @code{index} 
points to.
+If no sufficiently flat portion is found, the returned pointer will be 
@code{NULL}.
 
 @cindex Sigma-clipping
-The flatness on the cumulative frequency plot is defined like this (see
-@ref{Histogram and Cumulative Frequency Plot}): on the sorted dataset, for
-every point (@mymath{a_i}), we calculate @mymath{d_i=a_{i+2}-a_{i-2}}. This
-done on the first @mymath{N} elements (value of @code{numprev}). After
-element @mymath{a_{N+2}}, we start estimating the flatness as follows: for
-every element we use the @mymath{N}, @mymath{d_i} measurements before it as
-the reference. Let's call this set @mymath{D_i} for element @mymath{i}. The
-@mymath{\sigma}-clipped median (@mymath{m}) and standard deviation
-(@mymath{s}) of @mymath{D_i} are then calculated. The
-@mymath{\sigma}-clipping can be configured with the two
-@code{sigclip_param} and @code{sigclip_multip} arguments.
+The flatness on the cumulative frequency plot is defined like this (see 
@ref{Histogram and Cumulative Frequency Plot}): on the sorted dataset, for 
every point (@mymath{a_i}), we calculate @mymath{d_i=a_{i+2}-a_{i-2}}.
+This done on the first @mymath{N} elements (value of @code{numprev}).
+After element @mymath{a_{N+2}}, we start estimating the flatness as follows: 
for every element we use the @mymath{N}, @mymath{d_i} measurements before it as 
the reference.
+Let's call this set @mymath{D_i} for element @mymath{i}.
+The @mymath{\sigma}-clipped median (@mymath{m}) and standard deviation 
(@mymath{s}) of @mymath{D_i} are then calculated.
+The @mymath{\sigma}-clipping can be configured with the two 
@code{sigclip_param} and @code{sigclip_multip} arguments.
 
-Taking @mymath{t} as the significance threshold (value to @code{thresh}), a
-point is considered flat when @mymath{a_i>m+t\sigma}. But a single point
-satisfying this condition will probably just be due to noise. To make a
-more robust estimate, this significance/condition has to hold for
-@code{numcontig} contiguous elements after @mymath{a_i}. When this is
-satisfied, @mymath{a_i} is returned as the point where the distribution's
-cumulative frequency plot becomes flat.
+Taking @mymath{t} as the significance threshold (value to @code{thresh}), a 
point is considered flat when @mymath{a_i>m+t\sigma}.
+But a single point satisfying this condition will probably just be due to 
noise.
+To make a more robust estimate, this significance/condition has to hold for 
@code{numcontig} contiguous elements after @mymath{a_i}.
+When this is satisfied, @mymath{a_i} is returned as the point where the 
distribution's cumulative frequency plot becomes flat.
 
-To get a good estimate of @mymath{m} and @mymath{s}, it is thus recommended
-to set @code{numprev} as large as possible. However, be careful not to set
-it too high: the checks in the paragraph above are not done on the first
-@code{numprev} elements and this function assumes the flatness occurs
-after them. Also, be sure that the value to @code{numcontig} is much less
-than @code{numprev}, otherwise @mymath{\sigma}-clipping may not be able to
-remove the immediate outliers in @mymath{D_i} near the boundary of the flat
-region.
+To get a good estimate of @mymath{m} and @mymath{s}, it is thus recommended to 
set @code{numprev} as large as possible.
+However, be careful not to set it too high: the checks in the paragraph above 
are not done on the first @code{numprev} elements and this function assumes the 
flatness occurs after them.
+Also, be sure that the value to @code{numcontig} is much less than 
@code{numprev}, otherwise @mymath{\sigma}-clipping may not be able to remove 
the immediate outliers in @mymath{D_i} near the boundary of the flat region.
 
-When @code{quiet==0}, the basic measurements done on each element are
-printed on the command-line (good for finding the best parameters). When
-@code{inplace!=0}, the sorting and removal of blank elements is done on the
-input dataset, so the input may be altered after this function.
+When @code{quiet==0}, the basic measurements done on each element are printed 
on the command-line (good for finding the best parameters).
+When @code{inplace!=0}, the sorting and removal of blank elements is done on 
the input dataset, so the input may be altered after this function.
 @end deftypefun
 
 
@@ -40289,62 +39966,40 @@ Being a list, helps in easily printing the output 
columns to a table (see @ref{T
 @cindex Thresholding
 @cindex Binary datasets
 @cindex Dataset: binary
-Binary datasets only have two (usable) values: 0 (also known as background)
-or 1 (also known as foreground). They are created after some binary
-classification is applied to the dataset. The most common is thresholding:
-for example, in an image, pixels with a value above the threshold are given
-a value of 1 and those with a value less than the threshold are assigned a
-value of 0.
+Binary datasets only have two (usable) values: 0 (also known as background) or 
1 (also known as foreground).
+They are created after some binary classification is applied to the dataset.
+The most common is thresholding: for example, in an image, pixels with a value 
above the threshold are given a value of 1 and those with a value less than the 
threshold are assigned a value of 0.
 
 @cindex Connectivity
 @cindex Immediate neighbors
 @cindex Neighbors, immediate
-Since there is only two values, in the processing of binary images, you are
-usually concerned with the positioning of an element and its vicinity
-(neighbors). When a dataset has more than one dimension, multiple classes
-of immediate neighbors (that are touching the element) can be defined for
-each data-element. To separate these different classes of immediate
-neighbors, we define @emph{connectivity}.
-
-The classification is done by the distance from element center to the
-neighbor's center. The nearest immediate neighbors have a connectivity of
-1, the second nearest class of neighbors have a connectivity of 2 and so
-on. In total, the largest possible connectivity for data with @code{ndim}
-dimensions is @code{ndim}. For example, in a 2D dataset, 4-connected
-neighbors (that share an edge and have a distance of 1 pixel) have a
-connectivity of 1. The other 4 neighbors that only share a vertice (with a
-distance of @mymath{\sqrt{2}} pixels) have a connectivity of
-2. Conventionally, the class of connectivity-2 neighbors also includes the
-connectivity 1 neighbors, so for example, we call them 8-connected neighbors
-in 2D datasets.
-
-Ideally, one bit is sufficient for each element of a binary
-dataset. However, CPUs are not designed to work on individual bits, the
-smallest unit of memory addresses is a byte (containing 8 bits on modern
-CPUs). Therefore, in Gnuastro, the type used for binary dataset is
-@code{uint8_t} (see @ref{Numeric data types}). Although it does take
-8-times more memory, this choice offers much better performance and the
-some extra (useful) features.
-
-The advantage of using a full byte for each element of a binary dataset is
-that you can also have other values (that will be ignored in the
-processing). One such common ``other'' value in real datasets is a blank
-value (to mark regions that should not be processed because there is no
-data). The constant @code{GAL_BLANK_UINT8} value must be used in these
-cases (see @ref{Library blank values}). Another is some temporary value(s)
-that can be given to a processed pixel to avoid having another copy of the
-dataset as in @code{GAL_BINARY_TMP_VALUE} that is described below.
+Since there is only two values, in the processing of binary images, you are 
usually concerned with the positioning of an element and its vicinity 
(neighbors).
+When a dataset has more than one dimension, multiple classes of immediate 
neighbors (that are touching the element) can be defined for each data-element.
+To separate these different classes of immediate neighbors, we define 
@emph{connectivity}.
+
+The classification is done by the distance from element center to the 
neighbor's center.
+The nearest immediate neighbors have a connectivity of 1, the second nearest 
class of neighbors have a connectivity of 2 and so on.
+In total, the largest possible connectivity for data with @code{ndim} 
dimensions is @code{ndim}.
+For example, in a 2D dataset, 4-connected neighbors (that share an edge and 
have a distance of 1 pixel) have a connectivity of 1.
+The other 4 neighbors that only share a vertice (with a distance of 
@mymath{\sqrt{2}} pixels) have a connectivity of 2.
+Conventionally, the class of connectivity-2 neighbors also includes the 
connectivity 1 neighbors, so for example, we call them 8-connected neighbors in 
2D datasets.
+
+Ideally, one bit is sufficient for each element of a binary dataset.
+However, CPUs are not designed to work on individual bits, the smallest unit 
of memory addresses is a byte (containing 8 bits on modern CPUs).
+Therefore, in Gnuastro, the type used for binary dataset is @code{uint8_t} 
(see @ref{Numeric data types}).
+Although it does take 8-times more memory, this choice offers much better 
performance and the some extra (useful) features.
+
+The advantage of using a full byte for each element of a binary dataset is 
that you can also have other values (that will be ignored in the processing).
+One such common ``other'' value in real datasets is a blank value (to mark 
regions that should not be processed because there is no data).
+The constant @code{GAL_BLANK_UINT8} value must be used in these cases (see 
@ref{Library blank values}).
+Another is some temporary value(s) that can be given to a processed pixel to 
avoid having another copy of the dataset as in @code{GAL_BINARY_TMP_VALUE} that 
is described below.
 
 @deffn Macro GAL_BINARY_TMP_VALUE
-The functions described below work on a @code{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. This temporary value has a special meaning for
-the operation and will be operated on. So if your input datasets have
-values other than 0 and 1 that you do not want these functions to work on,
-be sure they are not equal to this macro's value. Note that this value is
-also different from @code{GAL_BLANK_UINT8}, so your input datasets may also
-contain blank elements.
+The functions described below work on a @code{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.
+This temporary value has a special meaning for the operation and will be 
operated on.
+So if your input datasets have values other than 0 and 1 that you do not want 
these functions to work on, be sure they are not equal to this macro's value.
+Note that this value is also different from @code{GAL_BLANK_UINT8}, so your 
input datasets may also contain blank elements.
 @end deffn
 
 
@@ -40352,47 +40007,36 @@ contain blank elements.
 Do @code{num} erosions on the @code{connectivity}-connected neighbors of
 @code{input} (see above for the definition of connectivity).
 
-If @code{inplace} is non-zero @emph{and} the input's type is
-@code{GAL_TYPE_UINT8}, then the erosion will be done within the input
-dataset and the returned pointer will be @code{input}. Otherwise,
-@code{input} is copied (and converted if necessary) to
-@code{GAL_TYPE_UINT8} and erosion will be done on this new dataset which
-will also be returned. This function will only work on the elements with a
-value of 1 or 0. It will leave all the rest unchanged.
+If @code{inplace} is non-zero @emph{and} the input's type is 
@code{GAL_TYPE_UINT8}, then the erosion will be done within the input dataset 
and the returned pointer will be @code{input}.
+Otherwise, @code{input} is copied (and converted if necessary) to 
@code{GAL_TYPE_UINT8} and erosion will be done on this new dataset which will 
also be returned.
+This function will only work on the elements with a value of 1 or 0.
+It will leave all the rest unchanged.
 
 @cindex Erosion
 @cindex Mathematical morphology
-Erosion (inverse of dilation) is an operation in mathematical morphology
-where each foreground pixel that is touching a background pixel is flipped
-(changed to background). The @code{connectivity} value determines the
-definition of ``touching''. Erosion will thus decrease the area of the
-foreground regions by one layer of pixels.
+Erosion (inverse of dilation) is an operation in mathematical morphology where 
each foreground pixel that is touching a background pixel is flipped (changed 
to background).
+The @code{connectivity} value determines the definition of ``touching''.
+Erosion will thus decrease the area of the foreground regions by one layer of 
pixels.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_binary_dilate (gal_data_t @code{*input}, size_t 
@code{num}, int @code{connectivity}, int @code{inplace})
-Do @code{num} dilations on the @code{connectivity}-connected neighbors of
-@code{input} (see above for the definition of connectivity). For more on
-@code{inplace} and the output, see @code{gal_binary_erode}.
+Do @code{num} dilations on the @code{connectivity}-connected neighbors of 
@code{input} (see above for the definition of connectivity).
+For more on @code{inplace} and the output, see @code{gal_binary_erode}.
 
 @cindex Dilation
-Dilation (inverse of erosion) is an operation in mathematical morphology
-where each background pixel that is touching a foreground pixel is flipped
-(changed to foreground). The @code{connectivity} value determines the
-definition of ``touching''. Dilation will thus increase the area of the
-foreground regions by one layer of pixels.
+Dilation (inverse of erosion) is an operation in mathematical morphology where 
each background pixel that is touching a foreground pixel is flipped (changed 
to foreground).
+The @code{connectivity} value determines the definition of ``touching''.
+Dilation will thus increase the area of the foreground regions by one layer of 
pixels.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_binary_open (gal_data_t @code{*input}, size_t 
@code{num}, int @code{connectivity}, int @code{inplace})
-Do @code{num} openings on the @code{connectivity}-connected neighbors of
-@code{input} (see above for the definition of connectivity). For more on
-@code{inplace} and the output, see @code{gal_binary_erode}.
+Do @code{num} openings on the @code{connectivity}-connected neighbors of 
@code{input} (see above for the definition of connectivity).
+For more on @code{inplace} and the output, see @code{gal_binary_erode}.
 
 @cindex Opening (Mathematical morphology)
-Opening is an operation in mathematical morphology which is defined as
-erosion followed by dilation (see above for the definitions of erosion and
-dilation). Opening will thus remove the outer structure of the
-foreground. In this implementation, @code{num} erosions are going to be
-applied on the dataset, then @code{num} dilations.
+Opening is an operation in mathematical morphology which is defined as erosion 
followed by dilation (see above for the definitions of erosion and dilation).
+Opening will thus remove the outer structure of the foreground.
+In this implementation, @code{num} erosions are going to be applied on the 
dataset, then @code{num} dilations.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_binary_number_neighbors (gal_data_t 
@code{*input}, int @code{connectivity}, int @code{inplace})
@@ -40404,25 +40048,18 @@ The neighbors are defined through the 
@code{connectivity} argument (see above) a
 @deftypefun size_t gal_binary_connected_components (gal_data_t @code{*binary}, 
gal_data_t @code{**out}, int @code{connectivity})
 @cindex Breadth first search
 @cindex Connected component labeling
-Return the number of connected components in @code{binary} through the
-breadth first search algorithm (finding all pixels belonging to one
-component before going on to the next). Connection between two pixels is
-defined based on the value to @code{connectivity}. @code{out} is a dataset
-with the same size as @code{binary} with @code{GAL_TYPE_INT32} type. Every
-pixel in @code{out} will have the label of the connected component it
-belongs to. The labeling of connected components starts from 1, so a label
-of zero is given to the input's background pixels.
-
-When @code{*out!=NULL} (its space is already allocated), it will be cleared
-(to zero) at the start of this function. Otherwise, when @code{*out==NULL},
-the necessary dataset to keep the output will be allocated by this
-function.
-
-@code{binary} must have a type of @code{GAL_TYPE_UINT8}, otherwise this
-function will abort with an error. Other than blank pixels (with a value of
-@code{GAL_BLANK_UINT8} defined in @ref{Library blank values}), all other
-non-zero pixels in @code{binary} will be considered as foreground (and will
-be labeled). Blank pixels in the input will also be blank in the output.
+Return the number of connected components in @code{binary} through the breadth 
first search algorithm (finding all pixels belonging to one component before 
going on to the next).
+Connection between two pixels is defined based on the value to 
@code{connectivity}.
+@code{out} is a dataset with the same size as @code{binary} with 
@code{GAL_TYPE_INT32} type.
+Every pixel in @code{out} will have the label of the connected component it 
belongs to.
+The labeling of connected components starts from 1, so a label of zero is 
given to the input's background pixels.
+
+When @code{*out!=NULL} (its space is already allocated), it will be cleared 
(to zero) at the start of this function.
+Otherwise, when @code{*out==NULL}, the necessary dataset to keep the output 
will be allocated by this function.
+
+@code{binary} must have a type of @code{GAL_TYPE_UINT8}, otherwise this 
function will abort with an error.
+Other than blank pixels (with a value of @code{GAL_BLANK_UINT8} defined in 
@ref{Library blank values}), all other non-zero pixels in @code{binary} will be 
considered as foreground (and will be labeled).
+Blank pixels in the input will also be blank in the output.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_binary_connected_indexs(gal_data_t 
@code{*binary}, int @code{connectivity})
@@ -40491,97 +40128,69 @@ For more on @code{minmapsize} and @code{quietmmap}, 
see @ref{Memory management}.
 @end deftypefun
 
 @deftypefun {gal_data_t *} gal_binary_holes_label (gal_data_t @code{*input}, 
int @code{connectivity}, size_t @code{*numholes})
-Label all the holes in the foreground (non-zero elements in input) as
-independent regions. Holes are background regions (zero-valued in input)
-that are fully surrounded by the foreground, as defined by
-@code{connectivity}. The returned dataset has a 32-bit signed integer type
-with the size of the input. All holes in the input will have
-labels/counters greater or equal to @code{1}. The rest of the background
-regions will still have a value of @code{0} and the initial foreground
-pixels will have a value of @code{-1}. The total number of holes will be
-written where @code{numholes} points to.
+Label all the holes in the foreground (non-zero elements in input) as 
independent regions.
+Holes are background regions (zero-valued in input) that are fully surrounded 
by the foreground, as defined by @code{connectivity}.
+The returned dataset has a 32-bit signed integer type with the size of the 
input.
+All holes in the input will have labels/counters greater or equal to @code{1}.
+The rest of the background regions will still have a value of @code{0} and the 
initial foreground pixels will have a value of @code{-1}.
+The total number of holes will be written where @code{numholes} points to.
 @end deftypefun
 
 @deftypefun void gal_binary_holes_fill (gal_data_t @code{*input}, int 
@code{connectivity}, size_t @code{maxsize})
-Fill all the holes (0 valued pixels surrounded by 1 valued pixels) of the
-binary @code{input} dataset. The connectivity of the holes can be set with
-@code{connectivity}. Holes larger than @code{maxsize} are not filled. This
-function currently only works on a 2D dataset.
+Fill all the holes (0 valued pixels surrounded by 1 valued pixels) of the 
binary @code{input} dataset.
+The connectivity of the holes can be set with @code{connectivity}.
+Holes larger than @code{maxsize} are not filled.
+This function currently only works on a 2D dataset.
 @end deftypefun
 
 @node Labeled datasets, Convolution functions, Binary datasets, Gnuastro 
library
 @subsection Labeled datasets (@file{label.h})
 
-A labeled dataset is one where each element/pixel has an integer label (or
-counter). The label identifies the group/class that the element belongs
-to. This form of labeling allows the higher-level study of all pixels
-within a certain class.
-
-For example, to detect objects/targets in an image/dataset, you can apply a
-threshold to separate the noise from the signal (to detect diffuse signal,
-a threshold is useless and more advanced methods are necessary, for example
-@ref{NoiseChisel}). But the output of detection is a binary dataset (which
-is just a very low-level labeling of @code{0} for noise and @code{1} for
-signal).
-
-The raw detection map is therefore hardly useful for any kind of analysis
-on objects/targets in the image. One solution is to use a
-connected-components algorithm (see @code{gal_binary_connected_components}
-in @ref{Binary datasets}). It is a simple and useful way to separate/label
-connected patches in the foreground. This higher-level (but still
-elementary) labeling therefore allows you to count how many connected
-patches of signal there are in the dataset and is a major improvement
-compared to the raw detection.
-
-However, when your objects/targets are touching, the simple connected
-components algorithm is not enough and a still higher-level labeling
-mechanism is necessary. This brings us to the necessity of the functions in
-this part of Gnuastro's library. The main inputs to the functions in this
-section are already labeled datasets (for example, with the connected
-components algorithm above).
-
-Each of the labeled regions are independent of each other (the labels
-specify different classes of targets). Therefore, especially in large
-datasets, it is often useful to process each label on independent CPU
-threads in parallel rather than in series. Therefore the functions of this
-section actually use an array of pixel/element indices (belonging to each
-label/class) as the main identifier of a region. Using indices will also
-allow processing of overlapping labels (for example, in deblending
-problems). Just note that overlapping labels are not yet implemented, but
-planned. You can use @code{gal_label_indexs} to generate lists of indices
-belonging to separate classes from the labeled input.
+A labeled dataset is one where each element/pixel has an integer label (or 
counter).
+The label identifies the group/class that the element belongs to.
+This form of labeling allows the higher-level study of all pixels within a 
certain class.
+
+For example, to detect objects/targets in an image/dataset, you can apply a 
threshold to separate the noise from the signal (to detect diffuse signal, a 
threshold is useless and more advanced methods are necessary, for example 
@ref{NoiseChisel}).
+But the output of detection is a binary dataset (which is just a very 
low-level labeling of @code{0} for noise and @code{1} for signal).
+
+The raw detection map is therefore hardly useful for any kind of analysis on 
objects/targets in the image.
+One solution is to use a connected-components algorithm (see 
@code{gal_binary_connected_components} in @ref{Binary datasets}).
+It is a simple and useful way to separate/label connected patches in the 
foreground.
+This higher-level (but still elementary) labeling therefore allows you to 
count how many connected patches of signal there are in the dataset and is a 
major improvement compared to the raw detection.
+
+However, when your objects/targets are touching, the simple connected 
components algorithm is not enough and a still higher-level labeling mechanism 
is necessary.
+This brings us to the necessity of the functions in this part of Gnuastro's 
library.
+The main inputs to the functions in this section are already labeled datasets 
(for example, with the connected components algorithm above).
+
+Each of the labeled regions are independent of each other (the labels specify 
different classes of targets).
+Therefore, especially in large datasets, it is often useful to process each 
label on independent CPU threads in parallel rather than in series.
+Therefore the functions of this section actually use an array of pixel/element 
indices (belonging to each label/class) as the main identifier of a region.
+Using indices will also allow processing of overlapping labels (for example, 
in deblending problems).
+Just note that overlapping labels are not yet implemented, but planned.
+You can use @code{gal_label_indexs} to generate lists of indices belonging to 
separate classes from the labeled input.
 
 @deffn  Macro GAL_LABEL_INIT
 @deffnx Macro GAL_LABEL_RIVER
 @deffnx Macro GAL_LABEL_TMPCHECK
-Special negative integer values used internally by some of the functions in
-this section. Recall that meaningful labels are considered to be positive
-integers (@mymath{\geq1}). Zero is conventionally kept for regions with no
-labels, therefore negative integers can be used for any extra
-classification in the labeled datasets.
+Special negative integer values used internally by some of the functions in 
this section.
+Recall that meaningful labels are considered to be positive integers 
(@mymath{\geq1}).
+Zero is conventionally kept for regions with no labels, therefore negative 
integers can be used for any extra classification in the labeled datasets.
 @end deffn
 
 @deftypefun {gal_data_t *} gal_label_indexs (gal_data_t @code{*labels}, size_t 
@code{numlabs}, size_t @code{minmapsize}, int @code{quietmmap})
 
-Return an array of @code{gal_data_t} containers, each containing the pixel
-indices of the respective label (see @ref{Generic data
-container}). @code{labels} contains the label of each element and has to
-have an @code{GAL_TYPE_INT32} type (see @ref{Library data types}). Only
-positive (greater than zero) values in @code{labels} will be used/indexed,
-other elements will be ignored.
-
-Meaningful labels start from @code{1} and not @code{0}, therefore the
-output array of @code{gal_data_t} will contain @code{numlabs+1} elements.
-The first (zero-th) element of the output (@code{indexs[0]} in the example
-below) will be initialized to a dataset with zero elements. This will allow
-easy (non-confusing) access to the indices of each (meaningful) label.
-
-@code{numlabs} is the number of labels in the dataset. If it is given a
-value of zero, then the maximum value in the input (largest label) will be
-found and used. Therefore if it is given, but smaller than the actual
-number of labels, this function may/will crash (it will write in
-unallocated space). @code{numlabs} is therefore useful in a highly
-optimized/checked environment.
+Return an array of @code{gal_data_t} containers, each containing the pixel 
indices of the respective label (see @ref{Generic data container}).
+@code{labels} contains the label of each element and has to have an 
@code{GAL_TYPE_INT32} type (see @ref{Library data types}).
+Only positive (greater than zero) values in @code{labels} will be 
used/indexed, other elements will be ignored.
+
+Meaningful labels start from @code{1} and not @code{0}, therefore the output 
array of @code{gal_data_t} will contain @code{numlabs+1} elements.
+The first (zero-th) element of the output (@code{indexs[0]} in the example 
below) will be initialized to a dataset with zero elements.
+This will allow easy (non-confusing) access to the indices of each 
(meaningful) label.
+
+@code{numlabs} is the number of labels in the dataset.
+If it is given a value of zero, then the maximum value in the input (largest 
label) will be found and used.
+Therefore if it is given, but smaller than the actual number of labels, this 
function may/will crash (it will write in unallocated space).
+@code{numlabs} is therefore useful in a highly optimized/checked environment.
 
 For example, if the returned array is called @code{indexs}, then
 @code{indexs[10].size} contains the number of elements that have a label of
@@ -40589,69 +40198,42 @@ For example, if the returned array is called 
@code{indexs}, then
 casting to @code{size_t *}) containing the indices of each one of those
 elements/pixels.
 
-By @emph{index} we mean the 1D position: the input number of dimensions is
-irrelevant (any dimensionality is supported). In other words, each
-element's index is the number of elements/pixels between it and the
-dataset's first element/pixel. Therefore it is always greater or equal to
-zero and stored in @code{size_t} type.
+By @emph{index} we mean the 1D position: the input number of dimensions is 
irrelevant (any dimensionality is supported).
+In other words, each element's index is the number of elements/pixels between 
it and the dataset's first element/pixel.
+Therefore it is always greater or equal to zero and stored in @code{size_t} 
type.
 @end deftypefun
 
 @deftypefun size_t gal_label_watershed (gal_data_t @code{*values}, gal_data_t 
@code{*indexs}, gal_data_t @code{*label}, size_t @code{*topinds}, int 
@code{min0_max1})
 @cindex Watershed algorithm
 @cindex Algorithm: watershed
-Use the watershed algorithm@footnote{The watershed algorithm was initially
-introduced by @url{https://doi.org/10.1109/34.87344, Vincent and
-Soille}. It starts from the minima and puts the pixels in, one by one, to
-grow them until the touch (create a watershed). For more, also see the
-Wikipedia article:
-@url{https://en.wikipedia.org/wiki/Watershed_%28image_processing%29}.} to
-``over-segment'' the pixels in the @code{indexs} dataset based on values in
-the @code{values} dataset. Internally, each local extrema (maximum or
-minimum, based on @code{min0_max1}) and its surrounding pixels will be
-given a unique label. For demonstration, see Figures 8 and 9 of
-@url{http://arxiv.org/abs/1505.01664, Akhlaghi and Ichikawa [2015]}. If
-@code{topinds!=NULL}, it is assumed to point to an already allocated space
-to write the index of each clump's local extrema, otherwise, it is ignored.
-
-The @code{values} dataset must have a 32-bit floating point type
-(@code{GAL_TYPE_FLOAT32}, see @ref{Library data types}) and will only be
-read by this function. @code{indexs} must contain the indices of the
-elements/pixels that will be over-segmented by this function and have a
-@code{GAL_TYPE_SIZE_T} type, see the description of
-@code{gal_label_indexs}, above. The final labels will be written in the
-respective positions of @code{labels}, which must have a
-@code{GAL_TYPE_INT32} type and be the same size as @code{values}.
-
-When @code{indexs} is already sorted, this function will ignore
-@code{min0_max1}. To judge if the dataset is sorted or not (by the values
-the indices correspond to in @code{values}, not the actual indices), this
-function will look into the bits of @code{indexs->flag}, for the respective
-bit flags, see @ref{Generic data container}. If @code{indexs} is not
-already sorted, this function will sort it according to the values of the
-respective pixel in @code{values}. The increasing/decreasing order will be
-determined by @code{min0_max1}. Note that if this function is called on
-multiple threads @emph{and} @code{values} points to a different array on
-each thread, this function will not return a reasonable result. In this
-case, please sort @code{indexs} prior to calling this function (see
-@code{gal_qsort_index_multi_d} in @ref{Qsort functions}).
+Use the watershed algorithm@footnote{The watershed algorithm was initially 
introduced by @url{https://doi.org/10.1109/34.87344, Vincent and Soille}.
+It starts from the minima and puts the pixels in, one by one, to grow them 
until the touch (create a watershed).
+For more, also see the Wikipedia article: 
@url{https://en.wikipedia.org/wiki/Watershed_%28image_processing%29}.} to 
``over-segment'' the pixels in the @code{indexs} dataset based on values in the 
@code{values} dataset.
+Internally, each local extrema (maximum or minimum, based on @code{min0_max1}) 
and its surrounding pixels will be given a unique label.
+For demonstration, see Figures 8 and 9 of 
@url{http://arxiv.org/abs/1505.01664, Akhlaghi and Ichikawa [2015]}.
+If @code{topinds!=NULL}, it is assumed to point to an already allocated space 
to write the index of each clump's local extrema, otherwise, it is ignored.
+
+The @code{values} dataset must have a 32-bit floating point type 
(@code{GAL_TYPE_FLOAT32}, see @ref{Library data types}) and will only be read 
by this function.
+@code{indexs} must contain the indices of the elements/pixels that will be 
over-segmented by this function and have a @code{GAL_TYPE_SIZE_T} type, see the 
description of @code{gal_label_indexs}, above.
+The final labels will be written in the respective positions of @code{labels}, 
which must have a @code{GAL_TYPE_INT32} type and be the same size as 
@code{values}.
+
+When @code{indexs} is already sorted, this function will ignore 
@code{min0_max1}.
+To judge if the dataset is sorted or not (by the values the indices correspond 
to in @code{values}, not the actual indices), this function will look into the 
bits of @code{indexs->flag}, for the respective bit flags, see @ref{Generic 
data container}.
+If @code{indexs} is not already sorted, this function will sort it according 
to the values of the respective pixel in @code{values}.
+The increasing/decreasing order will be determined by @code{min0_max1}.
+Note that if this function is called on multiple threads @emph{and} 
@code{values} points to a different array on each thread, this function will 
not return a reasonable result.
+In this case, please sort @code{indexs} prior to calling this function (see 
@code{gal_qsort_index_multi_d} in @ref{Qsort functions}).
 
 When @code{indexs} is decreasing (increasing), or @code{min0_max1} is
 @code{1} (@code{0}), local minima (maxima), are considered rivers
 (watersheds) and given a label of @code{GAL_LABEL_RIVER} (see above).
 
-Note that rivers/watersheds will also be formed on the edges of the labeled
-regions or when the labeled pixels touch a blank pixel. Therefore this
-function will need to check for the presence of blank values. To be most
-efficient, it is thus recommended to use @code{gal_blank_present} (with
-@code{updateflag=1}) prior to calling this function (see @ref{Library blank
-values}. Once the flag has been set, no other function (including this one)
-that needs special behavior for blank pixels will have to parse the dataset
-to see if it has blank values any more.
+Note that rivers/watersheds will also be formed on the edges of the labeled 
regions or when the labeled pixels touch a blank pixel.
+Therefore this function will need to check for the presence of blank values.
+To be most efficient, it is thus recommended to use @code{gal_blank_present} 
(with @code{updateflag=1}) prior to calling this function (see @ref{Library 
blank values}.
+Once the flag has been set, no other function (including this one) that needs 
special behavior for blank pixels will have to parse the dataset to see if it 
has blank values any more.
 
-If you are sure your dataset does not have blank values (by the design of
-your software), to avoid an extra parsing of the dataset and improve
-performance, you can set the two bits manually (see the description of
-@code{flags} in @ref{Generic data container}):
+If you are sure your dataset does not have blank values (by the design of your 
software), to avoid an extra parsing of the dataset and improve performance, 
you can set the two bits manually (see the description of @code{flags} in 
@ref{Generic data container}):
 @example
 input->flag |=  GAL_DATA_FLAG_BLANK_CH; /* Set bit to 1. */
 input->flag &= ~GAL_DATA_FLAG_HASBLANK; /* Set bit to 0. */
@@ -40664,49 +40246,31 @@ This function is usually called after 
@code{gal_label_watershed}, and is
 used as a measure to identify which over-segmented ``clumps'' are real and
 which are noise.
 
-A measurement is done on each clump (using the @code{values} and @code{std}
-datasets, see below). To help in multi-threaded environments, the operation
-is only done on pixels which are indexed in @code{indexs}. It is expected
-for @code{indexs} to be sorted by their values in @code{values}. If not
-sorted, the measurement may not be reliable. If sorted in a decreasing
-order, then clump building will start from their highest value and
-vice-versa. See the description of @code{gal_label_watershed} for more on
-@code{indexs}.
-
-Each ``clump'' (identified by a positive integer) is assumed to be
-surrounded by at least one river/watershed pixel (with a non-positive
-label). This function will parse the pixels identified in @code{indexs} and
-make a measurement on each clump and over all the river/watershed
-pixels. The number of clumps (@code{numclumps}) must be given as an input
-argument and any clump that is smaller than @code{minarea} is ignored
-(because of scatter). If @code{variance} is non-zero, then the @code{std}
-dataset is interpreted as variance, not standard deviation.
-
-The @code{values} and @code{std} datasets must have a @code{float} (32-bit
-floating point) type. Also, @code{label} and @code{indexs} must
-respectively have @code{int32} and @code{size_t} types. @code{values} and
-@code{label} must have the same size, but @code{std} can have three
-possible sizes: 1) a single element (which will be used for the whole
-dataset, 2) the same size as @code{values} (so a different error can be
-assigned to every pixel), 3) a single value for each tile, based on the
-@code{tl} tessellation (see @ref{Tile grid}). In the last case, a
-tile/value will be associated to each clump based on its flux-weighted
-(only positive values) center.
-
-The main output is an internally allocated, 1-dimensional array with one
-value per label. The array information (length, type, etc.) will be
-written into the @code{sig} generic data container. Therefore
-@code{sig->array} must be @code{NULL} when this function is called. After
-this function, the details of the array (number of elements, type and size,
-etc) will be written in to the various components of @code{sig}, see
-the definition of @code{gal_data_t} in @ref{Generic data
-container}. Therefore @code{sig} must already be allocated before calling
-this function.
-
-Optionally (when @code{sigind!=NULL}, similar to @code{sig}) the clump
-labels of each measurement in @code{sig} will be written in
-@code{sigind->array}. If @code{keepsmall} zero, small clumps (where no
-measurement is made) will not be included in the output table.
+A measurement is done on each clump (using the @code{values} and @code{std} 
datasets, see below).
+To help in multi-threaded environments, the operation is only done on pixels 
which are indexed in @code{indexs}.
+It is expected for @code{indexs} to be sorted by their values in @code{values}.
+If not sorted, the measurement may not be reliable.
+If sorted in a decreasing order, then clump building will start from their 
highest value and vice-versa.
+See the description of @code{gal_label_watershed} for more on @code{indexs}.
+
+Each ``clump'' (identified by a positive integer) is assumed to be surrounded 
by at least one river/watershed pixel (with a non-positive label).
+This function will parse the pixels identified in @code{indexs} and make a 
measurement on each clump and over all the river/watershed pixels.
+The number of clumps (@code{numclumps}) must be given as an input argument and 
any clump that is smaller than @code{minarea} is ignored (because of scatter).
+If @code{variance} is non-zero, then the @code{std} dataset is interpreted as 
variance, not standard deviation.
+
+The @code{values} and @code{std} datasets must have a @code{float} (32-bit 
floating point) type.
+Also, @code{label} and @code{indexs} must respectively have @code{int32} and 
@code{size_t} types.
+@code{values} and @code{label} must have the same size, but @code{std} can 
have three possible sizes: 1) a single element (which will be used for the 
whole dataset, 2) the same size as @code{values} (so a different error can be 
assigned to every pixel), 3) a single value for each tile, based on the 
@code{tl} tessellation (see @ref{Tile grid}).
+In the last case, a tile/value will be associated to each clump based on its 
flux-weighted (only positive values) center.
+
+The main output is an internally allocated, 1-dimensional array with one value 
per label.
+The array information (length, type, etc.) will be written into the @code{sig} 
generic data container.
+Therefore @code{sig->array} must be @code{NULL} when this function is called.
+After this function, the details of the array (number of elements, type and 
size, etc) will be written in to the various components of @code{sig}, see the 
definition of @code{gal_data_t} in @ref{Generic data container}.
+Therefore @code{sig} must already be allocated before calling this function.
+
+Optionally (when @code{sigind!=NULL}, similar to @code{sig}) the clump labels 
of each measurement in @code{sig} will be written in @code{sigind->array}.
+If @code{keepsmall} zero, small clumps (where no measurement is made) will not 
be included in the output table.
 
 This function is initially intended for a multi-threaded environment.
 In such cases, you will be writing arrays of clump measures from different 
regions in parallel into an array of @code{gal_data_t}s.
@@ -40754,55 +40318,36 @@ For example, in a 2D dataset, a connectivity of 
@code{1} and @code{2} correspond
 @node Convolution functions, Pooling functions, Labeled datasets, Gnuastro 
library
 @subsection Convolution functions (@file{convolve.h})
 
-Convolution is a very common operation during data analysis and is
-thoroughly described as part of Gnuastro's @ref{Convolve} program which is
-fully devoted to this job. Because of the complete introduction that was
-presented there, we will directly skip onto the currently available
-convolution functions in Gnuastro's library.
+Convolution is a very common operation during data analysis and is thoroughly 
described as part of Gnuastro's @ref{Convolve} program which is fully devoted 
to this job.
+Because of the complete introduction that was presented there, we will 
directly skip onto the currently available convolution functions in Gnuastro's 
library.
 
-As of this version, only spatial domain convolution is available in
-Gnuastro's libraries. We have not had the time to liberate the frequency
-domain function convolution and de-convolution functions that are available
-in the Convolve program@footnote{Hence any help would be greatly
-appreciated.}.
+As of this version, only spatial domain convolution is available in Gnuastro's 
libraries.
+We have not had the time to liberate the frequency domain function convolution 
and de-convolution functions that are available in the Convolve 
program@footnote{Hence any help would be greatly appreciated.}.
 
 @deftypefun {gal_data_t *} gal_convolve_spatial (gal_data_t @code{*tiles}, 
gal_data_t @code{*kernel}, size_t @code{numthreads}, int @code{edgecorrection}, 
int @code{convoverch})
-Convolve the given @code{tiles} dataset (possibly a list of tiles, see
-@ref{List of gal_data_t} and @ref{Tessellation library}) with @code{kernel}
-on @code{numthreads} threads. When @code{edgecorrection} is non-zero, it
-will correct for the edge dimming effects as discussed in @ref{Edges in the
-spatial domain}.
-
-@code{tiles} can be a single/complete dataset, but in that case the speed
-will be very slow. Therefore, for larger images, it is recommended to give
-a list of tiles covering a dataset. To create a tessellation that fully
-covers an input image, you may use @code{gal_tile_full}, or
-@code{gal_tile_full_two_layers} to also define channels over your input
-dataset. These functions are discussed in @ref{Tile grid}. You may then
-pass the list of tiles to this function. This is the recommended way to
-call this function because spatial domain convolution is slow and breaking
-the job into many small tiles and working on simultaneously on several
-threads can greatly speed up the processing.
-
-If the tiles are defined within a channel (a larger tile), by default
-convolution will be done within the channel, so pixels on the edge of a
-channel will not be affected by their neighbors that are in another
-channel. See @ref{Tessellation} for the necessity of channels in
-astronomical data analysis. This behavior may be disabled when
-@code{convoverch} is non-zero. In this case, it will ignore channel borders
-(if they exist) and mix all pixels that cover the kernel within the
-dataset.
+Convolve the given @code{tiles} dataset (possibly a list of tiles, see 
@ref{List of gal_data_t} and @ref{Tessellation library}) with @code{kernel} on 
@code{numthreads} threads.
+When @code{edgecorrection} is non-zero, it will correct for the edge dimming 
effects as discussed in @ref{Edges in the spatial domain}.
+
+@code{tiles} can be a single/complete dataset, but in that case the speed will 
be very slow.
+Therefore, for larger images, it is recommended to give a list of tiles 
covering a dataset.
+To create a tessellation that fully covers an input image, you may use 
@code{gal_tile_full}, or @code{gal_tile_full_two_layers} to also define 
channels over your input dataset.
+These functions are discussed in @ref{Tile grid}.
+You may then pass the list of tiles to this function.
+This is the recommended way to call this function because spatial domain 
convolution is slow and breaking the job into many small tiles and working on 
simultaneously on several threads can greatly speed up the processing.
+
+If the tiles are defined within a channel (a larger tile), by default 
convolution will be done within the channel, so pixels on the edge of a channel 
will not be affected by their neighbors that are in another channel.
+See @ref{Tessellation} for the necessity of channels in astronomical data 
analysis.
+This behavior may be disabled when @code{convoverch} is non-zero.
+In this case, it will ignore channel borders (if they exist) and mix all 
pixels that cover the kernel within the dataset.
 @end deftypefun
 
 @deftypefun void gal_convolve_spatial_correct_ch_edge (gal_data_t 
@code{*tiles}, gal_data_t @code{*kernel}, size_t @code{numthreads}, int 
@code{edgecorrection}, gal_data_t @code{*tocorrect})
-Correct the edges of channels in an already convolved image when it was
-initially convolved with @code{gal_convolve_spatial} and
-@code{convoverch==0}. In that case, strong boundaries might exist on the
-channel edges. So if you later need to remove those boundaries at later
-steps of your processing, you can call this function. It will only do
-convolution on the tiles that are near the edge and were effected by the
-channel borders. Other pixels in the image will not be touched. Hence, it
-is much faster.
+Correct the edges of channels in an already convolved image when it was 
initially convolved with @code{gal_convolve_spatial} and @code{convoverch==0}.
+In that case, strong boundaries might exist on the channel edges.
+So if you later need to remove those boundaries at later steps of your 
processing, you can call this function.
+It will only do convolution on the tiles that are near the edge and were 
effected by the channel borders.
+Other pixels in the image will not be touched.
+Hence, it is much faster.
 @end deftypefun
 
 @node Pooling functions, Interpolation, Convolution functions, Gnuastro library
@@ -40909,76 +40454,60 @@ require any additional memory.
 @deffn Macro GAL_INTERPOLATE_1D_POLYNOMIAL
 @cindex Polynomial interpolation
 @cindex Interpolation: Polynomial
-[From GSL:] Polynomial interpolation. This method should only be used for
-interpolating small numbers of points because polynomial interpolation
-introduces large oscillations, even for well-behaved datasets. The number
-of terms in the interpolating polynomial is equal to the number of points.
+[From GSL:] Polynomial interpolation.
+This method should only be used for interpolating small numbers of points 
because polynomial interpolation introduces large oscillations, even for 
well-behaved datasets.
+The number of terms in the interpolating polynomial is equal to the number of 
points.
 @end deffn
 @deffn Macro GAL_INTERPOLATE_1D_CSPLINE
 @cindex Interpolation: Spline
 @cindex Cubic spline interpolation
 @cindex Spline (cubic) interpolation
-[From GSL:] Cubic spline with natural boundary conditions. The resulting
-curve is piecewise cubic on each interval, with matching first and second
-derivatives at the supplied data-points.  The second derivative is chosen
-to be zero at the first point and last point.
+[From GSL:] Cubic spline with natural boundary conditions.
+The resulting curve is piecewise cubic on each interval, with matching first 
and second derivatives at the supplied data-points.
+The second derivative is chosen to be zero at the first point and last point.
 @end deffn
 @deffn Macro GAL_INTERPOLATE_1D_CSPLINE_PERIODIC
-[From GSL:] Cubic spline with periodic boundary conditions.  The resulting
-curve is piecewise cubic on each interval, with matching first and second
-derivatives at the supplied data-points.  The derivatives at the first and
-last points are also matched.  Note that the last point in the data must
-have the same y-value as the first point, otherwise the resulting periodic
-interpolation will have a discontinuity at the boundary.
+[From GSL:] Cubic spline with periodic boundary conditions.
+The resulting curve is piecewise cubic on each interval, with matching first 
and second derivatives at the supplied data-points.
+The derivatives at the first and last points are also matched.
+Note that the last point in the data must have the same y-value as the first 
point, otherwise the resulting periodic interpolation will have a discontinuity 
at the boundary.
 @end deffn
 @deffn Macro GAL_INTERPOLATE_1D_AKIMA
 @cindex Interpolation: Akima spline
 @cindex Akima spline interpolation
 @cindex Spline (Akima) interpolation
-[From GSL:] Non-rounded Akima spline with natural boundary conditions. This
-method uses the non-rounded corner algorithm of Wodicka.
+[From GSL:] Non-rounded Akima spline with natural boundary conditions.
+This method uses the non-rounded corner algorithm of Wodicka.
 @end deffn
 @deffn Macro GAL_INTERPOLATE_1D_AKIMA_PERIODIC
-[From GSL:] Non-rounded Akima spline with periodic boundary
-conditions. This method uses the non-rounded corner algorithm of Wodicka.
+[From GSL:] Non-rounded Akima spline with periodic boundary conditions.
+This method uses the non-rounded corner algorithm of Wodicka.
 @end deffn
 @deffn Macro GAL_INTERPOLATE_1D_STEFFEN
 @cindex Steffen interpolation
 @cindex Interpolation: Steffen
 @cindex Interpolation: monotonic
-[From GSL:] Steffen's
-method@footnote{@url{http://adsabs.harvard.edu/abs/1990A%26A...239..443S}}
-guarantees the monotonicity of the interpolating function between the given
-data points. Therefore, minima and maxima can only occur exactly at the
-data points, and there can never be spurious oscillations between data
-points. The interpolated function is piecewise cubic in each interval. The
-resulting curve and its first derivative are guaranteed to be continuous,
-but the second derivative may be discontinuous.
+[From GSL:] Steffen's 
method@footnote{@url{http://adsabs.harvard.edu/abs/1990A%26A...239..443S}} 
guarantees the monotonicity of the interpolating function between the given 
data points.
+Therefore, minima and maxima can only occur exactly at the data points, and 
there can never be spurious oscillations between data points.
+The interpolated function is piecewise cubic in each interval.
+The resulting curve and its first derivative are guaranteed to be continuous, 
but the second derivative may be discontinuous.
 @end deffn
 
 @deftypefun {gsl_spline *} gal_interpolate_1d_make_gsl_spline (gal_data_t 
@code{*X}, gal_data_t @code{*Y}, int @code{type_1d})
 @cindex GNU Scientific Library
-Allocate and initialize a GNU Scientific Library (GSL) 1D @code{gsl_spline}
-structure using the non-blank elements of @code{Y}. @code{type_1d}
-identifies the interpolation scheme and must be one of the
-@code{GAL_INTERPOLATE_1D_*} macros defined above.
+Allocate and initialize a GNU Scientific Library (GSL) 1D @code{gsl_spline} 
structure using the non-blank elements of @code{Y}.
+@code{type_1d} identifies the interpolation scheme and must be one of the 
@code{GAL_INTERPOLATE_1D_*} macros defined above.
 
-If @code{X==NULL}, the X-axis is assumed to be integers starting from zero
-(the index of each element in @code{Y}). Otherwise, the values in @code{X}
-will be used to initialize the interpolation structure. Note that when
-given, @code{X} must @emph{not} contain any blank elements and it must be
-sorted (in increasing order).
+If @code{X==NULL}, the X-axis is assumed to be integers starting from zero 
(the index of each element in @code{Y}).
+Otherwise, the values in @code{X} will be used to initialize the interpolation 
structure.
+Note that when given, @code{X} must @emph{not} contain any blank elements and 
it must be sorted (in increasing order).
 
-Each interpolation scheme needs a minimum number of elements to
-successfully operate. If the number of non-blank values in @code{Y} is less
-than this number, this function will return a @code{NULL} pointer.
+Each interpolation scheme needs a minimum number of elements to successfully 
operate.
+If the number of non-blank values in @code{Y} is less than this number, this 
function will return a @code{NULL} pointer.
 
 To be as generic and modular as possible, GSL's tools are low-level.
-Therefore before doing the interpolation, many steps are necessary (like
-preparing your dataset, then allocating and initializing
-@code{gsl_spline}). The metadata available in Gnuastro's @ref{Generic data
-container} make it easy to hide all those preparations within this
-function.
+Therefore before doing the interpolation, many steps are necessary (like 
preparing your dataset, then allocating and initializing @code{gsl_spline}).
+The metadata available in Gnuastro's @ref{Generic data container} make it easy 
to hide all those preparations within this function.
 
 Once @code{gsl_spline} has been initialized by this function, the
 interpolation can be evaluated for any X value within the non-blank range
@@ -41065,19 +40594,14 @@ $ astbuildprog sample-interp.c --quiet
 
 
 @deftypefun void gal_interpolate_1d_blank (gal_data_t @code{*in}, int 
@code{type_1d})
-Fill the blank elements of @code{in} using the rest of the elements and the
-given interpolation. The interpolation scheme can be set through
-@code{type_1d}, which accepts any of the @code{GAL_INTERPOLATE_1D_*} macros
-above. The interpolation is internally done in 64-bit floating point type
-(@code{double}). However the evaluated/interpolated values (originally
-blank) will be written (in @code{in}) with its original numeric datatype,
-using C's standard type conversion.
+Fill the blank elements of @code{in} using the rest of the elements and the 
given interpolation.
+The interpolation scheme can be set through @code{type_1d}, which accepts any 
of the @code{GAL_INTERPOLATE_1D_*} macros above.
+The interpolation is internally done in 64-bit floating point type 
(@code{double}).
+However the evaluated/interpolated values (originally blank) will be written 
(in @code{in}) with its original numeric datatype, using C's standard type 
conversion.
 
-By definition, interpolation is only defined ``between'' valid
-points. Therefore, if any number of elements on the start or end of the 1D
-array are blank, those elements will not be interpolated and will remain
-blank. To see if any blank (non-interpolated) elements remain, you can use
-@code{gal_blank_present} on @code{in} after this function is finished.
+By definition, interpolation is only defined ``between'' valid points.
+Therefore, if any number of elements on the start or end of the 1D array are 
blank, those elements will not be interpolated and will remain blank.
+To see if any blank (non-interpolated) elements remain, you can use 
@code{gal_blank_present} on @code{in} after this function is finished.
 @end deftypefun
 
 
@@ -41211,7 +40735,8 @@ For more, see @ref{Moire pattern and its correction}.
 
 @deftypefun gal_warp_wcsalign_t gal_warp_wcsalign_template (void)
 A high-level helper function that returns a clean @code{gal_warp_wcsalign_t} 
struct with all values initialized
-This function returns a copy of a statically allocated structure. So you don't 
need to free the returned structure.
+This function returns a copy of a statically allocated structure.
+So you don't need to free the returned structure.
 
 The Warp library decides on the program flow based on this struct.
 Uninitialized pointers can point to random space in RAM which can create 
segmentation faults, or even worse, produce unnoticed side-effects.
@@ -41307,35 +40832,23 @@ It is up to the caller to have the space for three 
32-bit floating point numbers
 
 @cindex Git
 @cindex libgit2
-Git is one of the most common tools for version control and it can often be
-useful during development, for example, see @code{COMMIT} keyword in
-@ref{Output FITS files}. At installation time, Gnuastro will also check for
-the existence of libgit2, and store the value in the
-@code{GAL_CONFIG_HAVE_LIBGIT2}, see @ref{Configuration information} and
-@ref{Optional dependencies}. @file{gnuastro/git.h} includes
-@file{gnuastro/config.h} internally, so you will not have to include both for
-this macro.
+Git is one of the most common tools for version control and it can often be 
useful during development, for example, see @code{COMMIT} keyword in 
@ref{Output FITS files}.
+At installation time, Gnuastro will also check for the existence of libgit2, 
and store the value in the @code{GAL_CONFIG_HAVE_LIBGIT2}, see 
@ref{Configuration information} and @ref{Optional dependencies}.
+@file{gnuastro/git.h} includes @file{gnuastro/config.h} internally, so you 
will not have to include both for this macro.
 
 @deftypefun {char *} gal_git_describe ( )
-When libgit2 is present and the program is called within a directory that
-is version controlled, this function will return a string containing the
-commit description (similar to Gnuastro's unofficial version number, see
-@ref{Version numbering}). If there are uncommitted changes in the running
-directory, it will add a `@code{-dirty}' prefix to the description. When
-there is no tagged point in the previous commit, this function will return
-a uniquely abbreviated commit object as fallback. This function is used for
-generating the value of the @code{COMMIT} keyword in @ref{Output FITS
-files}. The output string is similar to the output of the following
-command:
+When libgit2 is present and the program is called within a directory that is 
version controlled, this function will return a string containing the commit 
description (similar to Gnuastro's unofficial version number, see @ref{Version 
numbering}).
+If there are uncommitted changes in the running directory, it will add a 
`@code{-dirty}' prefix to the description.
+When there is no tagged point in the previous commit, this function will 
return a uniquely abbreviated commit object as fallback.
+This function is used for generating the value of the @code{COMMIT} keyword in 
@ref{Output FITS files}.
+The output string is similar to the output of the following command:
 
 @example
 $ git describe --dirty --always
 @end example
 
-Space for the output string is allocated within this function, so after
-using the value you have to @code{free} the output string. If libgit2 is
-not installed or the program calling this function is not within a version
-controlled directory, then the output will be the @code{NULL} pointer.
+Space for the output string is allocated within this function, so after using 
the value you have to @code{free} the output string.
+If libgit2 is not installed or the program calling this function is not within 
a version controlled directory, then the output will be the @code{NULL} pointer.
 @end deftypefun
 
 @node Python interface, Unit conversion library, Git wrappers, Gnuastro library
@@ -41822,17 +41335,12 @@ gal_speclines_line_redshift_code(8000, 
GAL_SPECLINES_H_alpha);
 @node Cosmology library, SAO DS9 library, Spectral lines library, Gnuastro 
library
 @subsection Cosmology library (@file{cosmology.h})
 
-This library does the main cosmological calculations that are commonly
-necessary in extra-galactic astronomical studies. The main variable in this
-context is the redshift (@mymath{z}). The cosmological input parameters in
-the functions below are @code{H0}, @code{o_lambda_0}, @code{o_matter_0},
-@code{o_radiation_0} which respectively represent the current (at redshift
-0) expansion rate (Hubble constant in units of km/sec/Mpc), cosmological
-constant (@mymath{\Lambda}), matter and radiation densities.
+This library does the main cosmological calculations that are commonly 
necessary in extra-galactic astronomical studies.
+The main variable in this context is the redshift (@mymath{z}).
+The cosmological input parameters in the functions below are @code{H0}, 
@code{o_lambda_0}, @code{o_matter_0}, @code{o_radiation_0} which respectively 
represent the current (at redshift 0) expansion rate (Hubble constant in units 
of km/sec/Mpc), cosmological constant (@mymath{\Lambda}), matter and radiation 
densities.
 
-All these functions are declared in @file{gnuastro/cosmology.h}. For a more
-extended introduction/discussion of the cosmological parameters, please see
-@ref{CosmicCalculator}.
+All these functions are declared in @file{gnuastro/cosmology.h}.
+For a more extended introduction/discussion of the cosmological parameters, 
please see @ref{CosmicCalculator}.
 
 @deftypefun double gal_cosmology_age (double @code{z}, double @code{H0}, 
double @code{o_lambda_0}, double @code{o_matter_0}, double @code{o_radiation_0})
 Returns the age of the universe at redshift @code{z} in units of Giga
@@ -41869,9 +41377,8 @@ Return the distance modulus at redshift @code{z} (with 
no units).
 @end deftypefun
 
 @deftypefun double gal_cosmology_to_absolute_mag (double @code{z}, double 
@code{H0}, double @code{o_lambda_0}, double @code{o_matter_0}, double 
@code{o_radiation_0})
-Return the conversion from apparent to absolute magnitude for an object at
-redshift @code{z}. This value has to be added to the apparent magnitude to
-give the absolute magnitude of an object at redshift @code{z}.
+Return the conversion from apparent to absolute magnitude for an object at 
redshift @code{z}.
+This value has to be added to the apparent magnitude to give the absolute 
magnitude of an object at redshift @code{z}.
 @end deftypefun
 
 @deftypefun double gal_cosmology_velocity_from_z (double @code{z})
@@ -41938,13 +41445,9 @@ polygon(53.187414,-27.779152,53.159507,-27.759633,...)
 @node Library demo programs,  , Gnuastro library, Library
 @section Library demo programs
 
-In this final section of @ref{Library}, we give some example Gnuastro
-programs to demonstrate various features in the library. All these programs
-have been tested and once Gnuastro is installed you can compile and run
-them with Gnuastro's @ref{BuildProgram} program that will take care of
-linking issues. If you do not have any FITS file to experiment on, you can
-use those that are generated by Gnuastro after @command{make check} in the
-@file{tests/} directory, see @ref{Quick start}.
+In this final section of @ref{Library}, we give some example Gnuastro programs 
to demonstrate various features in the library.
+All these programs have been tested and once Gnuastro is installed you can 
compile and run them with Gnuastro's @ref{BuildProgram} program that will take 
care of linking issues.
+If you do not have any FITS file to experiment on, you can use those that are 
generated by Gnuastro after @command{make check} in the @file{tests/} 
directory, see @ref{Quick start}.
 
 
 @menu
@@ -42706,27 +42209,15 @@ main(void)
 @node Developing, Other useful software, Library, Top
 @chapter Developing
 
-The basic idea of GNU Astronomy Utilities is for an interested astronomer
-to be able to easily understand the code of any of the programs or
-libraries, be able to modify the code if s/he feels there is an improvement
-and finally, to be able to add new programs or libraries for their own
-benefit, and the larger community if they are willing to share it. In
-short, we hope that at least from the software point of view, the
-``obscurantist faith in the expert's special skill and in his personal
-knowledge and authority'' can be broken, see @ref{Science and its
-tools}. With this aim in mind, Gnuastro was designed to have a very basic,
-simple, and easy to understand architecture for any interested inquirer.
-
-This chapter starts with very general design choices, in particular
-@ref{Why C} and @ref{Program design philosophy}. It will then get a little
-more technical about the Gnuastro code and file/directory structure in
-@ref{Coding conventions} and @ref{Program source}. @ref{The TEMPLATE
-program} discusses a minimal (and working) template to help in creating new
-programs or easier learning of a program's internal structure. Some other
-general issues about documentation, building and debugging are then
-discussed. This chapter concludes with how you can learn about the
-development and get involved in @ref{Gnuastro project webpage},
-@ref{Developing mailing lists} and @ref{Contributing to Gnuastro}.
+The basic idea of GNU Astronomy Utilities is for an interested astronomer to 
be able to easily understand the code of any of the programs or libraries, be 
able to modify the code if s/he feels there is an improvement and finally, to 
be able to add new programs or libraries for their own benefit, and the larger 
community if they are willing to share it.
+In short, we hope that at least from the software point of view, the 
``obscurantist faith in the expert's special skill and in his personal 
knowledge and authority'' can be broken, see @ref{Science and its tools}.
+With this aim in mind, Gnuastro was designed to have a very basic, simple, and 
easy to understand architecture for any interested inquirer.
+
+This chapter starts with very general design choices, in particular @ref{Why 
C} and @ref{Program design philosophy}.
+It will then get a little more technical about the Gnuastro code and 
file/directory structure in @ref{Coding conventions} and @ref{Program source}.
+@ref{The TEMPLATE program} discusses a minimal (and working) template to help 
in creating new programs or easier learning of a program's internal structure.
+Some other general issues about documentation, building and debugging are then 
discussed.
+This chapter concludes with how you can learn about the development and get 
involved in @ref{Gnuastro project webpage}, @ref{Developing mailing lists} and 
@ref{Contributing to Gnuastro}.
 
 
 @menu
@@ -42753,142 +42244,77 @@ development and get involved in @ref{Gnuastro 
project webpage},
 @cindex C++ programming language
 @cindex Java programming language
 @cindex Python programming language
-Currently the programming languages that are commonly used in scientific
-applications are C++@footnote{@url{https://isocpp.org/}},
-Java@footnote{@url{https://en.wikipedia.org/wiki/Java_(programming_language)}};
-Python@footnote{@url{https://www.python.org/}}, and
-Julia@footnote{@url{https://julialang.org/}} (which is a newcomer but
-swiftly gaining ground). One of the main reasons behind choosing these is
-their high-level abstractions. However, GNU Astronomy Utilities is fully
-written in the C programming
-language@footnote{@url{https://en.wikipedia.org/wiki/C_(programming_language)}}.
 The
-reasons can be summarized with simplicity, portability and
-efficiency/speed. All four are very important in a scientific software and
-we will discuss them below.
+Currently the programming languages that are commonly used in scientific 
applications are C++@footnote{@url{https://isocpp.org/}}, 
Java@footnote{@url{https://en.wikipedia.org/wiki/Java_(programming_language)}}; 
Python@footnote{@url{https://www.python.org/}}, and 
Julia@footnote{@url{https://julialang.org/}} (which is a newcomer but swiftly 
gaining ground).
+One of the main reasons behind choosing these is their high-level abstractions.
+However, GNU Astronomy Utilities is fully written in the C programming 
language@footnote{@url{https://en.wikipedia.org/wiki/C_(programming_language)}}.
+The reasons can be summarized with simplicity, portability and 
efficiency/speed.
+All four are very important in a scientific software and we will discuss them 
below.
 
 @cindex ANSI C
 @cindex ISO C90
 @cindex Ritchie, Dennis
 @cindex Kernighan, Brian
 @cindex Stroustrup, Bjarne
-Simplicity can best be demonstrated in a comparison of the main books of
-C++ and C. The ``C programming language''@footnote{Brian Kernighan, Dennis
-Ritchie. @emph{The C programming language}. Prentice Hall, Inc., Second
-edition, 1988. It is also commonly known as K&R and is based on the ANSI C
-and ISO C90 standards.} book, written by the authors of C, is only 286
-pages and covers a very good fraction of the language, it has also remained
-unchanged from 1988. C is the main programming language of nearly all
-operating systems and there is no plan of any significant update. On the
-other hand, the most recent ``C++ programming language''@footnote{Bjarne
-Stroustrup. @emph{The C++ programming language}. Addison-Wesley
-Professional; 4 edition, 2013.}  book, also written by its author, has 1366
-pages and its fourth edition came out in 2013!  As discussed in
-@ref{Science and its tools}, it is very important for other scientists to
-be able to readily read the code of a program at their will with minimum
-requirements.
+Simplicity can best be demonstrated in a comparison of the main books of C++ 
and C.
+The ``C programming language''@footnote{Brian Kernighan, Dennis Ritchie. 
@emph{The C programming language}. Prentice Hall, Inc., Second edition, 1988.
+It is also commonly known as K&R and is based on the ANSI C and ISO C90 
standards.} book, written by the authors of C, is only 286 pages and covers a 
very good fraction of the language, it has also remained unchanged from 1988.
+C is the main programming language of nearly all operating systems and there 
is no plan of any significant update.
+On the other hand, the most recent ``C++ programming 
language''@footnote{Bjarne Stroustrup.
+@emph{The C++ programming language}. Addison-Wesley Professional; 4 edition, 
2013.}  book, also written by its author, has 1366 pages and its fourth edition 
came out in 2013!  As discussed in @ref{Science and its tools}, it is very 
important for other scientists to be able to readily read the code of a program 
at their will with minimum requirements.
 
 @cindex Object oriented programming
-In C++ or Java, inheritance in the object oriented programming paradigm and
-their internal functions make the code very easy to write for a programmer
-who is deeply invested in those objects and understands all their relations
-well. But it simultaneously makes reading the program for a first time
-reader (a curious scientist who wants to know only how a small step was
-done) extremely hard. Before understanding the methods, the scientist has
-to invest a lot of time and energy in understanding those objects and their
-relations. But in C, everything is done with basic language types for
-example @code{int}s or @code{float}s and their pointers to define
-arrays. So when an outside reader is only interested in one part of the
-program, that part is all they have to understand.
-
-Recently it is also becoming common to write scientific software in Python,
-or a combination of it with C or C++. Python is a high level scripting
-language which does not need compilation. It is very useful when you want to
-do something on the go and do not want to be halted by the troubles of
-compiling, linking, memory checking, etc. When the datasets are small and
-the job is temporary, this ability of Python is great and is highly
-encouraged. A very good example might be plotting, in which Python is
-undoubtedly one of the best.
-
-But as the data sets increase in size and the processing becomes more
-complicated, the speed of Python scripts significantly decrease. So when
-the program does not change too often and is widely used in a large
-community, mostly on large data sets (like astronomical images), using
-Python will waste a lot of valuable research-hours. It is possible to wrap
-C or C++ functions with Python to fix the speed issue. But this creates
-further complexity, because the interested scientist has to master two
-programming languages and their connection (which is not trivial).
-
-Like C++, Python is object oriented, so as explained above, it needs a high
-level of experience with that particular program to reasonably understand
-its inner workings. To make things worse, since it is mainly for on-the-go
-programming@footnote{Note that Python is good for fast programming, not
-fast programs.}, it can undergo significant changes. One recent example is
-how Python 2.x and Python 3.x are not compatible. Lots of research teams
-that invested heavily in Python 2.x cannot benefit from Python 3.x or
-future versions any more. Some converters are available, but since they are
-automatic, lots of complications might arise in the conversion@footnote{For
-example see @url{https://arxiv.org/abs/1712.00461, Jenness (2017)} which
-describes how LSST is managing the transition.}.
-If a research project begins using Python 3.x today, there is no telling
-how compatible their investments will be when Python 4.x or 5.x will come
-out.
+In C++ or Java, inheritance in the object oriented programming paradigm and 
their internal functions make the code very easy to write for a programmer who 
is deeply invested in those objects and understands all their relations well.
+But it simultaneously makes reading the program for a first time reader (a 
curious scientist who wants to know only how a small step was done) extremely 
hard.
+Before understanding the methods, the scientist has to invest a lot of time 
and energy in understanding those objects and their relations.
+But in C, everything is done with basic language types for example @code{int}s 
or @code{float}s and their pointers to define arrays.
+So when an outside reader is only interested in one part of the program, that 
part is all they have to understand.
+
+Recently it is also becoming common to write scientific software in Python, or 
a combination of it with C or C++.
+Python is a high level scripting language which does not need compilation.
+It is very useful when you want to do something on the go and do not want to 
be halted by the troubles of compiling, linking, memory checking, etc.
+When the datasets are small and the job is temporary, this ability of Python 
is great and is highly encouraged.
+A very good example might be plotting, in which Python is undoubtedly one of 
the best.
+
+But as the data sets increase in size and the processing becomes more 
complicated, the speed of Python scripts significantly decrease.
+So when the program does not change too often and is widely used in a large 
community, mostly on large data sets (like astronomical images), using Python 
will waste a lot of valuable research-hours.
+It is possible to wrap C or C++ functions with Python to fix the speed issue.
+But this creates further complexity, because the interested scientist has to 
master two programming languages and their connection (which is not trivial).
+
+Like C++, Python is object oriented, so as explained above, it needs a high 
level of experience with that particular program to reasonably understand its 
inner workings.
+To make things worse, since it is mainly for on-the-go 
programming@footnote{Note that Python is good for fast programming, not fast 
programs.}, it can undergo significant changes.
+One recent example is how Python 2.x and Python 3.x are not compatible.
+Lots of research teams that invested heavily in Python 2.x cannot benefit from 
Python 3.x or future versions any more.
+Some converters are available, but since they are automatic, lots of 
complications might arise in the conversion@footnote{For example see 
@url{https://arxiv.org/abs/1712.00461, Jenness (2017)} which describes how LSST 
is managing the transition.}.
+If a research project begins using Python 3.x today, there is no telling how 
compatible their investments will be when Python 4.x or 5.x will come out.
 
 @cindex JVM: Java virtual machine
 @cindex Java Virtual Machine (JVM)
-Java is also fully object-oriented, but uses a different paradigm: its
-compilation generates a hardware-independent @emph{bytecode}, and a
-@emph{Java Virtual Machine} (JVM) is required for the actual execution of
-this bytecode on a computer. Java also evolved with time, and tried to
-remain backward compatible, but inevitably some evolutions required
-discontinuities and replacements of a few Java components which were first
-declared as becoming @emph{deprecated}, and removed from later versions.
+Java is also fully object-oriented, but uses a different paradigm: its 
compilation generates a hardware-independent @emph{bytecode}, and a @emph{Java 
Virtual Machine} (JVM) is required for the actual execution of this bytecode on 
a computer.
+Java also evolved with time, and tried to remain backward compatible, but 
inevitably some evolutions required discontinuities and replacements of a few 
Java components which were first declared as becoming @emph{deprecated}, and 
removed from later versions.
 
 @cindex Reproducibility
-This stems from the core principles of high-level languages like Python or
-Java: that they evolve significantly on the scale of roughly 5 to 10
-years. They are therefore useful when you want to solve a short-term
-problem and you are ready to pay the high cost of keeping your software up
-to date with all the changes in the language. This is fine for private
-companies, but usually too expensive for scientific projects that have
-limited funding for a fixed period. As a result, the reproducibility of the
-result (ability to regenerate the result in the future, which is a core
-principal of any scientific result) and reusability of all the investments
-that went into the science software will be lost to future generations!
-Rebuilding all the dependencies of a software in an obsolete language is
-not easy, or even not possible. Future-proof code (as long as current
-operating systems will be used) is therefore written in C.
-
-The portability of C is best demonstrated by the fact that C++, Java and
-Python are part of the C-family of programming languages which also include
-Julia, Perl, and many other languages. C libraries can be immediately
-included in C++, and it is easy to write wrappers for them in all C-family
-programming languages. This will allow other scientists to benefit from C
-libraries using any C-family language that they prefer. As a result,
-Gnuastro's library is already usable in C and C++, and wrappers will
-be@footnote{@url{http://savannah.gnu.org/task/?13786}} added for
-higher-level languages like Python, Julia and Java.
+This stems from the core principles of high-level languages like Python or 
Java: that they evolve significantly on the scale of roughly 5 to 10 years.
+They are therefore useful when you want to solve a short-term problem and you 
are ready to pay the high cost of keeping your software up to date with all the 
changes in the language.
+This is fine for private companies, but usually too expensive for scientific 
projects that have limited funding for a fixed period.
+As a result, the reproducibility of the result (ability to regenerate the 
result in the future, which is a core principal of any scientific result) and 
reusability of all the investments that went into the science software will be 
lost to future generations!  Rebuilding all the dependencies of a software in 
an obsolete language is not easy, or even not possible.
+Future-proof code (as long as current operating systems will be used) is 
therefore written in C.
+
+The portability of C is best demonstrated by the fact that C++, Java and 
Python are part of the C-family of programming languages which also include 
Julia, Perl, and many other languages.
+C libraries can be immediately included in C++, and it is easy to write 
wrappers for them in all C-family programming languages.
+This will allow other scientists to benefit from C libraries using any 
C-family language that they prefer.
+As a result, Gnuastro's library is already usable in C and C++, and wrappers 
will be@footnote{@url{http://savannah.gnu.org/task/?13786}} added for 
higher-level languages like Python, Julia and Java.
 
 @cindex Low level programming
 @cindex Programming, low level
-The final reason was speed. This is another very important aspect of C
-which is not independent of simplicity (first reason discussed above). The
-abstractions provided by the higher-level languages (which also makes
-learning them harder for a newcomer) come at the cost of speed. Since C is
-a low-level language@footnote{Low-level languages are those that directly
-operate the hardware like assembly languages. So C is actually a high-level
-language, but it can be considered one of the lowest-level languages among
-all high-level languages.} (closer to the hardware), it has a direct access
-to the CPU@footnote{for instance the @emph{long double} numbers with at
-least 64-bit mantissa are not accessible in Python or Java.}, is generally
-considered as being faster in its execution, and is much less complex for
-both the human reader @emph{and} the computer. The benefits of simplicity
-for a human were discussed above. Simplicity for the computer translates
-into more efficient (faster) programs. This creates a much closer relation
-between the scientist/programmer (or their program) and the actual data and
-processing. The GNU coding
-standards@footnote{@url{http://www.gnu.org/prep/standards/}} also encourage
-the use of C over all other languages when generality of usage and ``high
-speed'' is desired.
+The final reason was speed.
+This is another very important aspect of C which is not independent of 
simplicity (first reason discussed above).
+The abstractions provided by the higher-level languages (which also makes 
learning them harder for a newcomer) come at the cost of speed.
+Since C is a low-level language@footnote{Low-level languages are those that 
directly operate the hardware like assembly languages.
+So C is actually a high-level language, but it can be considered one of the 
lowest-level languages among all high-level languages.} (closer to the 
hardware), it has a direct access to the CPU@footnote{for instance the 
@emph{long double} numbers with at least 64-bit mantissa are not accessible in 
Python or Java.}, is generally considered as being faster in its execution, and 
is much less complex for both the human reader @emph{and} the computer.
+The benefits of simplicity for a human were discussed above.
+Simplicity for the computer translates into more efficient (faster) programs.
+This creates a much closer relation between the scientist/programmer (or their 
program) and the actual data and processing.
+The GNU coding standards@footnote{@url{http://www.gnu.org/prep/standards/}} 
also encourage the use of C over all other languages when generality of usage 
and ``high speed'' is desired.
 
 
 
@@ -42898,61 +42324,35 @@ speed'' is desired.
 @section Program design philosophy
 
 @cindex Gnulib
-The core processing functions of each program (and all libraries) are
-written mostly with the basic ISO C90 standard. We do make lots of use of
-the GNU additions to the C language in the GNU C library@footnote{Gnuastro
-uses many GNU additions to the C library. However, thanks to the GNU
-Portability library (Gnulib) which is included in the Gnuastro tarball,
-users of non-GNU/Linux operating systems can also benefit from all these
-features when using Gnuastro.}, but these functions are mainly used in the
-user interface functions (reading your inputs and preparing them prior to
-or after the analysis). The actual algorithms, which most scientists would
-be more interested in, are much more closer to ISO C90. For this reason,
-program source files that deal with user interface issues and those doing
-the actual processing are clearly separated, see @ref{Program source}. If
-anything particular to the GNU C library is used in the processing
-functions, it is explained in the comments in between the code.
+The core processing functions of each program (and all libraries) are written 
mostly with the basic ISO C90 standard.
+We do make lots of use of the GNU additions to the C language in the GNU C 
library@footnote{Gnuastro uses many GNU additions to the C library.
+However, thanks to the GNU Portability library (Gnulib) which is included in 
the Gnuastro tarball, users of non-GNU/Linux operating systems can also benefit 
from all these features when using Gnuastro.}, but these functions are mainly 
used in the user interface functions (reading your inputs and preparing them 
prior to or after the analysis).
+The actual algorithms, which most scientists would be more interested in, are 
much more closer to ISO C90.
+For this reason, program source files that deal with user interface issues and 
those doing the actual processing are clearly separated, see @ref{Program 
source}.
+If anything particular to the GNU C library is used in the processing 
functions, it is explained in the comments in between the code.
 
 @cindex GNU Coreutils
-All the Gnuastro programs provide very low level and modular operations
-(modeled on GNU Coreutils). Almost all the basic command-line programs like
-@command{ls}, @command{cp} or @command{rm} on GNU/Linux operating systems
-are part of GNU Coreutils. This enables you to use shell scripting
-languages (for example, GNU Bash) to operate on a large number of files or
-do very complex things through the creative combinations of these tools
-that the authors had never dreamed of. We have put a few simple examples in
-@ref{Tutorials}.
+All the Gnuastro programs provide very low level and modular operations 
(modeled on GNU Coreutils).
+Almost all the basic command-line programs like @command{ls}, @command{cp} or 
@command{rm} on GNU/Linux operating systems are part of GNU Coreutils.
+This enables you to use shell scripting languages (for example, GNU Bash) to 
operate on a large number of files or do very complex things through the 
creative combinations of these tools that the authors had never dreamed of.
+We have put a few simple examples in @ref{Tutorials}.
 
 @cindex @LaTeX{}
 @cindex GNU Bash
 @cindex Python Matplotlib
 @cindex Matplotlib, Python
 @cindex PGFplots in @TeX{} or @LaTeX{}
-For example, all the analysis output can be saved as ASCII tables which can
-be fed into your favorite plotting program to inspect visually. Python's
-Matplotlib is very useful for fast plotting of the tables to immediately
-check your results. If you want to include the plots in a document, you can
-use the PGFplots package within @LaTeX{}, no attempt is made to include
-such operations in Gnuastro. In short, Bash can act as a glue to connect
-the inputs and outputs of all these various Gnuastro programs (and other
-programs) in any fashion. Of course, Gnuastro's programs are just
-front-ends to the main workhorse (@ref{Gnuastro library}), allowing a user
-to create their own programs (for example, with @ref{BuildProgram}). So once
-the functions within programs become mature enough, they will be moved
-within the libraries for even more general applications.
-
-The advantage of this architecture is that the programs become small and
-transparent: the starting and finishing point of every program is clearly
-demarcated. For nearly all operations on a modern computer (fast file
-input-output) with a modest level of complexity, the read/write speed is
-insignificant compared to the actual processing a program does. Therefore
-the complexity which arises from sharing memory in a large application is
-simply not worth the speed gain. Gnuastro's design is heavily influenced
-from Eric Raymond's ``The Art of Unix Programming''@footnote{Eric
-S. Raymond, 2004, @emph{The Art of Unix Programming}, Addison-Wesley
-Professional Computing Series.}  which beautifully describes the design
-philosophy and practice which lead to the success of Unix-based operating
-systems@footnote{KISS principle: Keep It Simple, Stupid!}.
+For example, all the analysis output can be saved as ASCII tables which can be 
fed into your favorite plotting program to inspect visually.
+Python's Matplotlib is very useful for fast plotting of the tables to 
immediately check your results.
+If you want to include the plots in a document, you can use the PGFplots 
package within @LaTeX{}, no attempt is made to include such operations in 
Gnuastro.
+In short, Bash can act as a glue to connect the inputs and outputs of all 
these various Gnuastro programs (and other programs) in any fashion.
+Of course, Gnuastro's programs are just front-ends to the main workhorse 
(@ref{Gnuastro library}), allowing a user to create their own programs (for 
example, with @ref{BuildProgram}).
+So once the functions within programs become mature enough, they will be moved 
within the libraries for even more general applications.
+
+The advantage of this architecture is that the programs become small and 
transparent: the starting and finishing point of every program is clearly 
demarcated.
+For nearly all operations on a modern computer (fast file input-output) with a 
modest level of complexity, the read/write speed is insignificant compared to 
the actual processing a program does.
+Therefore the complexity which arises from sharing memory in a large 
application is simply not worth the speed gain.
+Gnuastro's design is heavily influenced from Eric Raymond's ``The Art of Unix 
Programming''@footnote{Eric S. Raymond, 2004, @emph{The Art of Unix 
Programming}, Addison-Wesley Professional Computing Series.}  which beautifully 
describes the design philosophy and practice which lead to the success of 
Unix-based operating systems@footnote{KISS principle: Keep It Simple, Stupid!}.
 
 
 
@@ -42963,83 +42363,58 @@ systems@footnote{KISS principle: Keep It Simple, 
Stupid!}.
 
 @cindex GNU coding standards
 @cindex Gnuastro coding convention
-In Gnuastro, we try our best to follow the GNU coding standards. Added to
-those, Gnuastro defines the following conventions. It is very important for
-readability that the whole package follows the same convention.
+In Gnuastro, we try our best to follow the GNU coding standards.
+Added to those, Gnuastro defines the following conventions.
+It is very important for readability that the whole package follows the same 
convention.
 
 @itemize
 
 @item
-The code must be easy to read by eye. So when the order of several lines
-within a function does not matter (for example, when defining variables at
-the start of a function). You should put the lines in the order of
-increasing length and group the variables with similar types such that this
-half-pyramid of declarations becomes most visible. If the reader is
-interested, a simple search will show them the variable they are interested
-in. However, this visual aid greatly helps in general inspections of the
-code and help the reader get a grip of the function's processing.
+The code must be easy to read by eye.
+So when the order of several lines within a function does not matter (for 
example, when defining variables at the start of a function).
+You should put the lines in the order of increasing length and group the 
variables with similar types such that this half-pyramid of declarations 
becomes most visible.
+If the reader is interested, a simple search will show them the variable they 
are interested in.
+However, this visual aid greatly helps in general inspections of the code and 
help the reader get a grip of the function's processing.
 
 @item
-A function that cannot be fully displayed (vertically) in your monitor is
-probably too long and may be more useful if it is broken up into multiple
-functions. 40 lines is usually a good reference. When the start and end of
-a function are clearly visible in one glance, the function is much more
-easier to understand. This is most important for low-level functions (which
-usually define a lot of variables). Low-level functions do most of the
-processing, they will also be the most interesting part of a program for an
-inquiring astronomer. This convention is less important for higher level
-functions that do not define too many variables and whose only purpose is to
-run the lower-level functions in a specific order and with checks.
+A function that cannot be fully displayed (vertically) in your monitor is 
probably too long and may be more useful if it is broken up into multiple 
functions.
+40 lines is usually a good reference.
+When the start and end of a function are clearly visible in one glance, the 
function is much more easier to understand.
+This is most important for low-level functions (which usually define a lot of 
variables).
+Low-level functions do most of the processing, they will also be the most 
interesting part of a program for an inquiring astronomer.
+This convention is less important for higher level functions that do not 
define too many variables and whose only purpose is to run the lower-level 
functions in a specific order and with checks.
 
 @cindex Optimization flag
 @cindex GCC: GNU Compiler Collection
 @cindex GNU Compiler Collection (GCC)
-In general you can be very liberal in breaking up the functions into
-smaller parts, the GNU Compiler Collection (GCC) will automatically compile
-the functions as inline functions when the optimizations are turned on. So
-you do not have to worry about decreasing the speed. By default Gnuastro
-will compile with the @option{-O3} optimization flag.
+In general you can be very liberal in breaking up the functions into smaller 
parts, the GNU Compiler Collection (GCC) will automatically compile the 
functions as inline functions when the optimizations are turned on.
+So you do not have to worry about decreasing the speed.
+By default Gnuastro will compile with the @option{-O3} optimization flag.
 
 @cindex Buffers (Emacs)
 @cindex Emacs buffers
 @item
-All Gnuastro hand-written text files (C source code, Texinfo documentation
-source, and version control commit messages) should not exceed @strong{75}
-characters per line. Monitors today are certainly much wider, but with this
-limit, reading the functions becomes much more easier. Also for the
-developers, it allows multiple files (or multiple views of one file) to be
-displayed beside each other on wide monitors.
-
-Emacs's buffers are excellent for this capability, setting a buffer width
-of 80 with `@key{C-u 80 C-x 3}' will allow you to view and work on several
-files or different parts of one file using the wide monitors common
-today. Emacs buffers can also be used as a shell prompt and compile the
-program (with @key{M-x compile}), and 80 characters is the default width in
-most terminal emulators. If you use Emacs, Gnuastro sets the 75 character
-@command{fill-column} variable automatically for you, see cartouche below.
-
-For long comments you can use press @key{Alt-q} in Emacs to separate them
-into separate lines automatically. For long literal strings, you can use
-the fact that in C, two strings immediately after each other are
-concatenated, for example, @code{"The first part, " "and the second part."}.
-Note the space character in the end of the first part. Since they are now
-separated, you can easily break a long literal string into several lines
-and adhere to the maximum 75 character line length policy.
+All Gnuastro hand-written text files (C source code, Texinfo documentation 
source, and version control commit messages) should not exceed @strong{75} 
characters per line.
+Monitors today are certainly much wider, but with this limit, reading the 
functions becomes much more easier.
+Also for the developers, it allows multiple files (or multiple views of one 
file) to be displayed beside each other on wide monitors.
+
+Emacs's buffers are excellent for this capability, setting a buffer width of 
80 with `@key{C-u 80 C-x 3}' will allow you to view and work on several files 
or different parts of one file using the wide monitors common today.
+Emacs buffers can also be used as a shell prompt and compile the program (with 
@key{M-x compile}), and 80 characters is the default width in most terminal 
emulators.
+If you use Emacs, Gnuastro sets the 75 character @command{fill-column} 
variable automatically for you, see cartouche below.
+
+For long comments you can use press @key{Alt-q} in Emacs to separate them into 
separate lines automatically.
+For long literal strings, you can use the fact that in C, two strings 
immediately after each other are concatenated, for example, @code{"The first 
part, " "and the second part."}.
+Note the space character in the end of the first part.
+Since they are now separated, you can easily break a long literal string into 
several lines and adhere to the maximum 75 character line length policy.
 
 @cindex Header file
 @item
-The headers required by each source file (ending with @file{.c}) should be
-defined inside of it. All the headers a complete program needs should
-@emph{not} be stacked in another header to include in all source files (for
-example @file{main.h}). Although most `professional' programmers choose
-this single header method, Gnuastro is primarily written for
-professional/inquisitive astronomers (who are generally amateur
-programmers). The list of header files included provides valuable general
-information and helps the reader. @file{main.h} may only include the header
-file(s) that define types that the main program structure needs, see
-@file{main.h} in @ref{Program source}. Those particular header files that
-are included in @file{main.h} can of course be ignored (not included) in
-separate source files.
+The headers required by each source file (ending with @file{.c}) should be 
defined inside of it.
+All the headers a complete program needs should @emph{not} be stacked in 
another header to include in all source files (for example @file{main.h}).
+Although most `professional' programmers choose this single header method, 
Gnuastro is primarily written for professional/inquisitive astronomers (who are 
generally amateur programmers).
+The list of header files included provides valuable general information and 
helps the reader.
+@file{main.h} may only include the header file(s) that define types that the 
main program structure needs, see @file{main.h} in @ref{Program source}.
+Those particular header files that are included in @file{main.h} can of course 
be ignored (not included) in separate source files.
 
 @item
 The headers should be classified (by an empty line) into separate
@@ -43050,188 +42425,133 @@ groups:
 @cindex Gnulib: GNU Portability Library
 @cindex GNU Portability Library (Gnulib)
 @item
-@code{#include <config.h>}: This must be the first code line (not commented
-or blank) in each source file @emph{within Gnuastro}. It sets macros that
-the GNU Portability Library (Gnulib) will use for a unified environment
-(GNU C Library), even when the user is building on a system that does not
-use the GNU C library.
+@code{#include <config.h>}: This must be the first code line (not commented or 
blank) in each source file @emph{within Gnuastro}.
+It sets macros that the GNU Portability Library (Gnulib) will use for a 
unified environment (GNU C Library), even when the user is building on a system 
that does not use the GNU C library.
 
 @item
-The C library header files, for example, @file{stdio.h}, @file{stdlib.h}, or
-@file{math.h}.
+The C library header files, for example, @file{stdio.h}, @file{stdlib.h}, or 
@file{math.h}.
 @item
-Installed library header files, including Gnuastro's installed headers (for
-example @file{cfitsio.h} or @file{gsl/gsl_rng.h}, or
-@file{gnuastro/fits.h}).
+Installed library header files, including Gnuastro's installed headers (for 
example @file{cfitsio.h} or @file{gsl/gsl_rng.h}, or @file{gnuastro/fits.h}).
 @item
-Gnuastro's internal headers (that are not installed), for example
-@file{gnuastro-internal/options.h}.
+Gnuastro's internal headers (that are not installed), for example 
@file{gnuastro-internal/options.h}.
 @item
-For programs, the @file{main.h} file (which is needed by the next group of
-headers).
+For programs, the @file{main.h} file (which is needed by the next group of 
headers).
 @item
-That particular program's header files, for example, @file{mkprof.h}, or
-@file{noisechisel.h}.
+That particular program's header files, for example, @file{mkprof.h}, or 
@file{noisechisel.h}.
 @end enumerate
 
 @noindent
-As much as order does not matter when you include the header of each group,
-sort them by length, as described above.
+As much as order does not matter when you include the header of each group, 
sort them by length, as described above.
 
 @item
-All function names, variables, etc., should be in lower case.  Macros and
-constant global @code{enum}s should be in upper case.
+All function names, variables, etc., should be in lower case.
+Macros and constant global @code{enum}s should be in upper case.
 
 @item
-For the naming of exported header files, functions, variables, macros, and
-library functions, we adopt similar conventions to those used by the GNU
-Scientific Library
-(GSL)@footnote{@url{https://www.gnu.org/software/gsl/design/gsl-design.html#SEC15}}.
-In particular, in order to avoid clashes with the names of functions and
-variables coming from other libraries the name-space `@code{gal_}' is
-prefixed to them. GAL stands for @emph{G}NU @emph{A}stronomy
-@emph{L}ibrary.
+For the naming of exported header files, functions, variables, macros, and 
library functions, we adopt similar conventions to those used by the GNU 
Scientific Library 
(GSL)@footnote{@url{https://www.gnu.org/software/gsl/design/gsl-design.html#SEC15}}.
+In particular, in order to avoid clashes with the names of functions and 
variables coming from other libraries the name-space `@code{gal_}' is prefixed 
to them.
+GAL stands for @emph{G}NU @emph{A}stronomy @emph{L}ibrary.
 
 @item
-All installed header files should be in the @file{lib/gnuastro} directory
-(under the top Gnuastro source directory). After installation, they will be
-put in the @file{$prefix/include/gnuastro} directory (see @ref{Installation
-directory} for @file{$prefix}). Therefore with this convention Gnuastro's
-headers can be included in internal (to Gnuastro) and external (a library
-user) source files with the same line
+All installed header files should be in the @file{lib/gnuastro} directory 
(under the top Gnuastro source directory).
+After installation, they will be put in the @file{$prefix/include/gnuastro} 
directory (see @ref{Installation directory} for @file{$prefix}).
+Therefore with this convention Gnuastro's headers can be included in internal 
(to Gnuastro) and external (a library user) source files with the same line
 @example
 # include <gnuastro/headername.h>
 @end example
-Note that the GSL convention for header file names is
-@file{gsl_specialname.h}, so your include directive for a GSL header must
-be something like @code{#include <gsl/gsl_specialname.h>}. Gnuastro does not
-follow this GSL guideline because of the repeated @code{gsl} in the include
-directive. It can be confusing and cause bugs for beginners. All Gnuastro
-(and GSL) headers must be located within a unique directory and will not be
-mixed with other headers. Therefore the `@file{gsl_}' prefix to the header
-file names is redundant@footnote{For GSL, this prefix has an internal
-technical application: GSL's architecture mixes installed and not-installed
-headers in the same directory. This prefix is used to identify their
-installation status. Therefore this filename prefix in GSL a technical
-internal issue (for developers, not users).}.
+Note that the GSL convention for header file names is 
@file{gsl_specialname.h}, so your include directive for a GSL header must be 
something like @code{#include <gsl/gsl_specialname.h>}.
+Gnuastro does not follow this GSL guideline because of the repeated @code{gsl} 
in the include directive.
+It can be confusing and cause bugs for beginners.
+All Gnuastro (and GSL) headers must be located within a unique directory and 
will not be mixed with other headers.
+Therefore the `@file{gsl_}' prefix to the header file names is 
redundant@footnote{For GSL, this prefix has an internal technical application: 
GSL's architecture mixes installed and not-installed headers in the same 
directory.
+This prefix is used to identify their installation status.
+Therefore this filename prefix in GSL a technical internal issue (for 
developers, not users).}.
 
 @item
 @cindex GNU coding standards
-All installed functions and variables should also include the base-name of
-the file in which they are defined as prefix, using underscores to separate
-words@footnote{The convention to use underscores to separate words, called
-``snake case'' (or ``snake_case''). This is also recommended by the GNU
-coding standards.}. The same applies to exported macros, but in upper case.
-For example, in Gnuastro's top source directory, the prototype of function
-@code{gal_box_border_from_center} is in @file{lib/gnuastro/box.h}, and the
-macro @code{GAL_POLYGON_MAX_CORNERS} is defined in
-@code{lib/gnuastro/polygon.h}.
-
-This is necessary to give any user (who is not familiar with the library
-structure) the ability to follow the code. This convention does make the
-function names longer (a little harder to write), but the extra
-documentation it provides plays an important role in Gnuastro and is worth
-the cost.
+All installed functions and variables should also include the base-name of the 
file in which they are defined as prefix, using underscores to separate 
words@footnote{The convention to use underscores to separate words, called 
``snake case'' (or ``snake_case'').
+This is also recommended by the GNU coding standards.}.
+The same applies to exported macros, but in upper case.
+For example, in Gnuastro's top source directory, the prototype of function 
@code{gal_box_border_from_center} is in @file{lib/gnuastro/box.h}, and the 
macro @code{GAL_POLYGON_MAX_CORNERS} is defined in 
@code{lib/gnuastro/polygon.h}.
+
+This is necessary to give any user (who is not familiar with the library 
structure) the ability to follow the code.
+This convention does make the function names longer (a little harder to 
write), but the extra documentation it provides plays an important role in 
Gnuastro and is worth the cost.
 
 @item
 @cindex GNU Emacs
 @cindex Trailing space
-There should be no trailing white space in a line. To do this
-automatically every time you save a file in Emacs, add the following
-line to your @file{~/.emacs} file.
+There should be no trailing white space in a line.
+To do this automatically every time you save a file in Emacs, add the 
following line to your @file{~/.emacs} file.
 @example
 (add-hook 'before-save-hook 'delete-trailing-whitespace)
 @end example
 
 @item
 @cindex Tabs are evil
-There should be no tabs in the indentation@footnote{If you use Emacs,
-Gnuastro's @file{.dir-locals.el} file will automatically never use tabs for
-indentation. To make this a default in all your Emacs sessions, you can add
-the following line to your @file{~/.emacs} file: @command{(setq-default
-indent-tabs-mode nil)}}.
+There should be no tabs in the indentation@footnote{If you use Emacs, 
Gnuastro's @file{.dir-locals.el} file will automatically never use tabs for 
indentation.
+To make this a default in all your Emacs sessions, you can add the following 
line to your @file{~/.emacs} file: @command{(setq-default indent-tabs-mode 
nil)}}.
 
 @item
 @cindex GNU Emacs
 @cindex Function groups
 @cindex Groups of similar functions
-Individual, contextually similar, functions in a source file are separated
-by 5 blank lines to be easily seen to be related in a group when parsing
-the source code by eye. In Emacs you can use @key{CTRL-u 5 CTRL-o}.
+Individual, contextually similar, functions in a source file are separated by 
5 blank lines to be easily seen to be related in a group when parsing the 
source code by eye.
+In Emacs you can use @key{CTRL-u 5 CTRL-o}.
 
 @item
-One group of contextually similar functions in a source file is separated
-from another with 20 blank lines. In Emacs you can use @key{CTRL-u 20
-CTRL-o}. Each group of functions has short descriptive title of the
-functions in that group. This title is surrounded by asterisks (@key{*}) to
-make it clearly distinguishable. Such contextual grouping and clear title
-are very important for easily understanding the code.
+One group of contextually similar functions in a source file is separated from 
another with 20 blank lines.
+In Emacs you can use @key{CTRL-u 20 CTRL-o}.
+Each group of functions has short descriptive title of the functions in that 
group.
+This title is surrounded by asterisks (@key{*}) to make it clearly 
distinguishable.
+Such contextual grouping and clear title are very important for easily 
understanding the code.
 
 @item
-Always read the comments before the patch of code under it. Similarly, try
-to add as many comments as you can regarding every patch of
-code. Effectively, we want someone to get a good feeling of the steps,
-without having to read the C code and only by reading the comments. This
-follows similar principles as
-@url{https://en.wikipedia.org/wiki/Literate_programming, Literate
-programming}.
+Always read the comments before the patch of code under it.
+Similarly, try to add as many comments as you can regarding every patch of 
code.
+Effectively, we want someone to get a good feeling of the steps, without 
having to read the C code and only by reading the comments.
+This follows similar principles as 
@url{https://en.wikipedia.org/wiki/Literate_programming, Literate programming}.
 
 @end itemize
 
-The last two conventions are not common and might benefit from a short
-discussion here. With a good experience in advanced text editor operations,
-the last two are redundant for a professional developer. However, recall
-that Gnuastro aspires to be friendly to unfamiliar, and inexperienced (in
-programming) eyes. In other words, as discussed in @ref{Science and its
-tools}, we want the code to appear welcoming to someone who is completely
-new to coding (and text editors) and only has a scientific curiosity.
-
-Newcomers to coding and development, who are curious enough to venture into
-the code, will probably not be using (or have any knowledge of) advanced
-text editors. They will see the raw code in the web page or on a simple text
-editor (like Gedit) as plain text. Trying to learn and understand a file
-with dense functions that are all spaced with one or two blank lines can be
-very taunting for a newcomer. But when they scroll through the file and see
-clear titles and meaningful spaces for similar functions, we are helping
-them find and focus on the part they are most interested in sooner and
-easier.
+The last two conventions are not common and might benefit from a short 
discussion here.
+With a good experience in advanced text editor operations, the last two are 
redundant for a professional developer.
+However, recall that Gnuastro aspires to be friendly to unfamiliar, and 
inexperienced (in programming) eyes.
+In other words, as discussed in @ref{Science and its tools}, we want the code 
to appear welcoming to someone who is completely new to coding (and text 
editors) and only has a scientific curiosity.
+
+Newcomers to coding and development, who are curious enough to venture into 
the code, will probably not be using (or have any knowledge of) advanced text 
editors.
+They will see the raw code in the web page or on a simple text editor (like 
Gedit) as plain text.
+Trying to learn and understand a file with dense functions that are all spaced 
with one or two blank lines can be very taunting for a newcomer.
+But when they scroll through the file and see clear titles and meaningful 
spaces for similar functions, we are helping them find and focus on the part 
they are most interested in sooner and easier.
 
 @cartouche
 @cindex GNU Emacs
 @noindent
-@strong{GNU Emacs, the recommended text editor:} GNU Emacs is an
-extensible and easily customizable text editor which many programmers
-rely on for developing due to its countless features. Among them, it
-allows specification of certain settings that are applied to a single
-file or to all files in a directory and its sub-directories. In order
-to harmonize code coming from different contributors, Gnuastro comes
-with a @file{.dir-locals.el} file which automatically configures Emacs
-to satisfy most of the coding conventions above when you are using it
-within Gnuastro's directories. Thus, Emacs users can readily start
-hacking into Gnuastro. If you are new to developing, we strongly
-recommend this editor. Emacs was the first project released by GNU and
-is still one of its flagship projects. Some resources can be found at:
+@strong{GNU Emacs, the recommended text editor:} GNU Emacs is an extensible 
and easily customizable text editor which many programmers rely on for 
developing due to its countless features.
+Among them, it allows specification of certain settings that are applied to a 
single file or to all files in a directory and its sub-directories.
+In order to harmonize code coming from different contributors, Gnuastro comes 
with a @file{.dir-locals.el} file which automatically configures Emacs to 
satisfy most of the coding conventions above when you are using it within 
Gnuastro's directories.
+Thus, Emacs users can readily start hacking into Gnuastro.
+If you are new to developing, we strongly recommend this editor.
+Emacs was the first project released by GNU and is still one of its flagship 
projects.
+Some resources can be found at:
 
 @table @asis
 @item Official manual
-At @url{https://www.gnu.org/software/emacs/manual/emacs.html}. This is a
-great and very complete manual which is being improved for over 30 years
-and is the best starting point to learn it. It just requires a little
-patience and practice, but rest assured that you will be rewarded. If you
-install Emacs, you also have access to this manual on the command-line with
-the following command (see @ref{Info}).
+At @url{https://www.gnu.org/software/emacs/manual/emacs.html}.
+This is a great and very complete manual which is being improved for over 30 
years and is the best starting point to learn it.
+It just requires a little patience and practice, but rest assured that you 
will be rewarded.
+If you install Emacs, you also have access to this manual on the command-line 
with the following command (see @ref{Info}).
 
 @example
 $ info emacs
 @end example
 
 @item A guided tour of emacs
-At @url{https://www.gnu.org/software/emacs/tour/}. A short visual tour
-of Emacs, officially maintained by the Emacs developers.
+At @url{https://www.gnu.org/software/emacs/tour/}.
+A short visual tour of Emacs, officially maintained by the Emacs developers.
 
 @item Unofficial mini-manual
-At @url{https://tuhdo.github.io/emacs-tutor.html}. A shorter manual
-which contains nice animated images of using Emacs.
+At @url{https://tuhdo.github.io/emacs-tutor.html}.
+A shorter manual which contains nice animated images of using Emacs.
 
 @end table
 @end cartouche
@@ -43246,17 +42566,12 @@ which contains nice animated images of using Emacs.
 @cindex Program structure convention
 @cindex Convention for program source
 @cindex Gnuastro program structure convention
-Besides the fact that all the programs share some functions that were
-explained in @ref{Library}, everything else about each program is
-completely independent. Recall that Gnuastro is written for an active
-astronomer/scientist (not a passive one who just uses a software). It must
-thus be easily navigable. Hence there are fixed source files (that contain
-fixed operations) that must be present in all programs, these are discussed
-fully in @ref{Mandatory source code files}. To easily understand the
-explanations in this section you can use @ref{The TEMPLATE program} which
-contains the bare minimum code for one working program. This template can
-also be used to easily add new utilities: just copy and paste the directory
-and change @code{TEMPLATE} with your program's name.
+Besides the fact that all the programs share some functions that were 
explained in @ref{Library}, everything else about each program is completely 
independent.
+Recall that Gnuastro is written for an active astronomer/scientist (not a 
passive one who just uses a software).
+It must thus be easily navigable.
+Hence there are fixed source files (that contain fixed operations) that must 
be present in all programs, these are discussed fully in @ref{Mandatory source 
code files}.
+To easily understand the explanations in this section you can use @ref{The 
TEMPLATE program} which contains the bare minimum code for one working program.
+This template can also be used to easily add new utilities: just copy and 
paste the directory and change @code{TEMPLATE} with your program's name.
 
 
 
@@ -43268,16 +42583,13 @@ and change @code{TEMPLATE} with your program's name.
 @node Mandatory source code files, The TEMPLATE program, Program source, 
Program source
 @subsection Mandatory source code files
 
-Some programs might need lots of source files and if there is no fixed
-convention, navigating them can become very hard for a new inquirer into
-the code. The following source files exist in every program's source
-directory (which is located in @file{bin/progname}). For small programs,
-these files are enough. Larger programs will need more files and developers
-are encouraged to define any number of new files. It is just important that
-the following list of files exist and do what is described here. When
-creating other source files, please choose filenames that are a complete
-single word: do not abbreviate (abbreviations are cryptic). For a minimal
-program containing all these files, see @ref{The TEMPLATE program}.
+Some programs might need lots of source files and if there is no fixed 
convention, navigating them can become very hard for a new inquirer into the 
code.
+The following source files exist in every program's source directory (which is 
located in @file{bin/progname}).
+For small programs, these files are enough.
+Larger programs will need more files and developers are encouraged to define 
any number of new files.
+It is just important that the following list of files exist and do what is 
described here.
+When creating other source files, please choose filenames that are a complete 
single word: do not abbreviate (abbreviations are cryptic).
+For a minimal program containing all these files, see @ref{The TEMPLATE 
program}.
 
 @vtable @file
 
@@ -43405,27 +42717,15 @@ During Gnuastro's build, all these Bash completion 
files are merged into one fil
 @node The TEMPLATE program,  , Mandatory source code files, Program source
 @subsection The TEMPLATE program
 
-The extra creativity offered by libraries comes at a cost: you have to
-actually write your @code{main} function and get your hands dirty in
-managing user inputs: are all the necessary parameters given a value? is
-the input in the correct format? do the options and the inputs correspond?
-and many other similar checks. So when an operation has well-defined inputs
-and outputs and is commonly needed, it is much more worthwhile to simply do
-use all the great features that Gnuastro has already defined for such
-operations.
-
-To make it easier to learn/apply the internal program infra-structure
-discussed in @ref{Mandatory source code files}, in the @ref{Version
-controlled source}, Gnuastro ships with a template program. This template
-program is not available in the Gnuastro tarball so it does not confuse
-people using the tarball. The @file{bin/TEMPLATE} directory in Gnuastro's
-Git repository contains the bare-minimum files necessary to define a new
-program and all the basic/necessary files/functions are pre-defined
-there.
-
-Below you can see a list of initial steps to take for customizing this
-template. We just assume that after cloning Gnuastro's history, you have
-already bootstrapped Gnuastro, if not, please see @ref{Bootstrapping}.
+The extra creativity offered by libraries comes at a cost: you have to 
actually write your @code{main} function and get your hands dirty in managing 
user inputs: are all the necessary parameters given a value? is the input in 
the correct format? do the options and the inputs correspond?  and many other 
similar checks.
+So when an operation has well-defined inputs and outputs and is commonly 
needed, it is much more worthwhile to simply do use all the great features that 
Gnuastro has already defined for such operations.
+
+To make it easier to learn/apply the internal program infra-structure 
discussed in @ref{Mandatory source code files}, in the @ref{Version controlled 
source}, Gnuastro ships with a template program.
+This template program is not available in the Gnuastro tarball so it does not 
confuse people using the tarball.
+The @file{bin/TEMPLATE} directory in Gnuastro's Git repository contains the 
bare-minimum files necessary to define a new program and all the 
basic/necessary files/functions are pre-defined there.
+
+Below you can see a list of initial steps to take for customizing this 
template.
+We just assume that after cloning Gnuastro's history, you have already 
bootstrapped Gnuastro, if not, please see @ref{Bootstrapping}.
 
 @enumerate
 @item
@@ -43438,44 +42738,31 @@ $ cp -R bin/TEMPLATE bin/myprog
 @end example
 
 @item
-As with all source files in Gnuastro, all the files in template also have a
-copyright notice at their top. Open all the files and correct these
-notices: 1) The first line contains a single-line description of the
-program. 2) In the second line only the name or your program needs to be
-fixed and 3) Add your name and email as a ``Contributing author''. As your
-program grows, you will need to add new files, do not forget to add this
-notice in those new files too, just put your name and email under
-``Original author'' and correct the copyright years.
+As with all source files in Gnuastro, all the files in template also have a 
copyright notice at their top.
+Open all the files and correct these notices: 1) The first line contains a 
single-line description of the program.
+2) In the second line only the name or your program needs to be fixed and 3) 
Add your name and email as a ``Contributing author''.
+As your program grows, you will need to add new files, do not forget to add 
this notice in those new files too, just put your name and email under 
``Original author'' and correct the copyright years.
 
 @item
-Open @file{configure.ac} in the top Gnuastro source. This file manages the
-operations that are done when a user runs @file{./configure}. Going down
-the file, you will notice repetitive parts for each program. You will
-notice that the program names follow an alphabetic ordering in each
-part. There is also a commented line/patch for the @file{TEMPLATE} program
-in each part. You can copy one line/patch (from the program above or below
-your desired name for example) and paste it in the proper place for your
-new program. Then correct the names of the copied program to your new
-program name. There are multiple places where this has to be done, so be
-patient and go down to the bottom of the file. Ultimately add
-@file{bin/myprog/Makefile} to @code{AC_CONFIG_FILES}, only here the
-ordering depends on the length of the name (it is not alphabetical).
+Open @file{configure.ac} in the top Gnuastro source.
+This file manages the operations that are done when a user runs 
@file{./configure}.
+Going down the file, you will notice repetitive parts for each program.
+You will notice that the program names follow an alphabetic ordering in each 
part.
+There is also a commented line/patch for the @file{TEMPLATE} program in each 
part.
+You can copy one line/patch (from the program above or below your desired name 
for example) and paste it in the proper place for your new program.
+Then correct the names of the copied program to your new program name.
+There are multiple places where this has to be done, so be patient and go down 
to the bottom of the file.
+Ultimately add @file{bin/myprog/Makefile} to @code{AC_CONFIG_FILES}, only here 
the ordering depends on the length of the name (it is not alphabetical).
 
 @item
-Open @file{Makefile.am} in the top Gnuastro source. Similar to the previous
-step, add your new program similar to all the other programs. Here there
-are only two places: 1) at the top where we define the conditionals (three
-lines per program), and 2) immediately under it as part of the value for
-@code{SUBDIRS}.
+Open @file{Makefile.am} in the top Gnuastro source.
+Similar to the previous step, add your new program similar to all the other 
programs.
+Here there are only two places: 1) at the top where we define the conditionals 
(three lines per program), and 2) immediately under it as part of the value for 
@code{SUBDIRS}.
 
 @item
-Open @file{doc/Makefile.am} and similar to @file{Makefile.am} (above), add
-the proper entries for the man-page of your program to be created (here,
-the variable that keeps all the man-pages to be created is
-@code{dist_man_MANS}). Then scroll down and add a rule to build the
-man-page similar to the other existing rules (in alphabetical order). Do Not
-forget to add a short one-line description here, it will be displayed on
-top of the man-page.
+Open @file{doc/Makefile.am} and similar to @file{Makefile.am} (above), add the 
proper entries for the man-page of your program to be created (here, the 
variable that keeps all the man-pages to be created is @code{dist_man_MANS}).
+Then scroll down and add a rule to build the man-page similar to the other 
existing rules (in alphabetical order).
+Do Not forget to add a short one-line description here, it will be displayed 
on top of the man-page.
 
 @item
 Change @code{TEMPLATE.c} and @code{TEMPLATE.h} to @code{myprog.c} and
@@ -43489,11 +42776,10 @@ $ mv TEMPLATE.h myprog.h
 
 @item
 @cindex GNU Grep
-Correct all occurrences of @code{TEMPLATE} in the input files to
-@code{myprog} (in short or long format). You can get a list of all
-occurrences with the following command. If you use Emacs, it will be able to
-parse the Grep output and open the proper file and line automatically. So
-this step can be very easy.
+Correct all occurrences of @code{TEMPLATE} in the input files to @code{myprog} 
(in short or long format).
+You can get a list of all occurrences with the following command.
+If you use Emacs, it will be able to parse the Grep output and open the proper 
file and line automatically.
+So this step can be very easy.
 
 @example
 $ grep --color -nHi -e template *
@@ -43510,12 +42796,9 @@ $ make
 @end example
 
 @item
-You are done! You can now start customizing your new program to do your
-special processing. When it is complete, just do not forget to add checks
-also, so it can be tested at least once on a user's system with
-@command{make check}, see @ref{Test scripts}. Finally, if you would like to
-share it with all Gnuastro users, inform us so we merge it into Gnuastro's
-main history.
+You are done! You can now start customizing your new program to do your 
special processing.
+When it is complete, just do not forget to add checks also, so it can be 
tested at least once on a user's system with @command{make check}, see 
@ref{Test scripts}.
+Finally, if you would like to share it with all Gnuastro users, inform us so 
we merge it into Gnuastro's main history.
 @end enumerate
 
 
@@ -43527,75 +42810,47 @@ main history.
 @node Documentation, Building and debugging, Program source, Developing
 @section Documentation
 
-Documentation (this book) is an integral part of Gnuastro (see @ref{Science
-and its tools}).  Documentation is not considered a separate project and
-must be written by its developers. Users can make edits/corrections, but
-the initial writing must be by the developer. So, no change is considered
-valid for implementation unless the respective parts of the book have also
-been updated. The following procedure can be a good suggestion to take when
-you have a new idea and are about to start implementing it.
+Documentation (this book) is an integral part of Gnuastro (see @ref{Science 
and its tools}).
+Documentation is not considered a separate project and must be written by its 
developers.
+Users can make edits/corrections, but the initial writing must be by the 
developer.
+So, no change is considered valid for implementation unless the respective 
parts of the book have also been updated.
+The following procedure can be a good suggestion to take when you have a new 
idea and are about to start implementing it.
 
-The steps below are not a requirement, the important thing is that when you
-send your work to be included in Gnuastro, the book and the code have to
-both be fully up-to-date and compatible, with the purpose of the update
-very clearly explained. You can follow any strategy you like, the following
-strategy was what we have found to be most useful until now.
+The steps below are not a requirement, the important thing is that when you 
send your work to be included in Gnuastro, the book and the code have to both 
be fully up-to-date and compatible, with the purpose of the update very clearly 
explained.
+You can follow any strategy you like, the following strategy was what we have 
found to be most useful until now.
 
 @enumerate
 @item
-Edit the book and fully explain your desired change, such that your idea is
-completely embedded in the general context of the book with no sense of
-discontinuity for a first time reader. This will allow you to plan the idea
-much more accurately and in the general context of Gnuastro (a particular
-program or library). Later on, when you are coding, this general context
-will significantly help you as a road-map.
+Edit the book and fully explain your desired change, such that your idea is 
completely embedded in the general context of the book with no sense of 
discontinuity for a first time reader.
+This will allow you to plan the idea much more accurately and in the general 
context of Gnuastro (a particular program or library).
+Later on, when you are coding, this general context will significantly help 
you as a road-map.
 
 A very important part of this process is the program/library introduction.
-These first few paragraphs explain the purposes of the program or library
-and are fundamental to Gnuastro. Before actually starting to code, explain
-your idea's purpose thoroughly in the start of the respective/new section
-you wish to work on. While actually writing its purpose for a new reader,
-you will probably get some valuable and interesting ideas that you had not
-thought of before. This has occurred several times during the creation of
-Gnuastro.
-
-If an introduction already exists, embed or blend your idea's purpose with
-the existing introduction. We emphasize that doing this is equally useful
-for you (as the programmer) as it is useful for the user (reader). Recall
-that the purpose of a program is very important, see @ref{Program design
-philosophy}.
-
-As you have already noticed for every program/library, it is very important
-that the basics of the science and technique be explained in separate
-subsections prior to the `Invoking Programname' subsection. If you are
-writing a new program or your addition to an existing program involves a
-new concept, also include such subsections and explain the concepts so a
-person completely unfamiliar with the concepts can get a general initial
-understanding. You do not have to go deep into the details, just enough to
-get an interested person (with absolutely no background) started with some
-good pointers/links to where they can continue studying if they are more
-interested. If you feel you cannot do that, then you have probably not
-understood the concept yourself. If you feel you do not have the time, then
-think about yourself as the reader in one year: you will forget almost all
-the details, so now that you have done all the theoretical preparations,
-add a few more hours and document it. Therefore in one year, when you find
-a bug or want to add a new feature, you do not have to prepare as much. Have
-in mind that your only limitation in length is the fatigue of the reader
-after reading a long text, nothing else. So as long as you keep it
-relevant/interesting for the reader, there is no page number limit/cost.
-
-It might also help if you start discussing the usage of your idea in the
-`Invoking ProgramName' subsection (explaining the options and arguments you
-have in mind) at this stage too. Actually starting to write it here will
-really help you later when you are coding.
-
-@item
-After you have finished adding your initial intended plan to the book, then
-start coding your change or new program within the Gnuastro source
-files. While you are coding, you will notice that somethings should be
-different from what you wrote in the book (your initial plan). So correct
-them as you are actually coding, but do not worry too much about missing a
-few things (see the next step).
+These first few paragraphs explain the purposes of the program or library and 
are fundamental to Gnuastro.
+Before actually starting to code, explain your idea's purpose thoroughly in 
the start of the respective/new section you wish to work on.
+While actually writing its purpose for a new reader, you will probably get 
some valuable and interesting ideas that you had not thought of before.
+This has occurred several times during the creation of Gnuastro.
+
+If an introduction already exists, embed or blend your idea's purpose with the 
existing introduction.
+We emphasize that doing this is equally useful for you (as the programmer) as 
it is useful for the user (reader).
+Recall that the purpose of a program is very important, see @ref{Program 
design philosophy}.
+
+As you have already noticed for every program/library, it is very important 
that the basics of the science and technique be explained in separate 
subsections prior to the `Invoking Programname' subsection.
+If you are writing a new program or your addition to an existing program 
involves a new concept, also include such subsections and explain the concepts 
so a person completely unfamiliar with the concepts can get a general initial 
understanding.
+You do not have to go deep into the details, just enough to get an interested 
person (with absolutely no background) started with some good pointers/links to 
where they can continue studying if they are more interested.
+If you feel you cannot do that, then you have probably not understood the 
concept yourself.
+If you feel you do not have the time, then think about yourself as the reader 
in one year: you will forget almost all the details, so now that you have done 
all the theoretical preparations, add a few more hours and document it.
+Therefore in one year, when you find a bug or want to add a new feature, you 
do not have to prepare as much.
+Have in mind that your only limitation in length is the fatigue of the reader 
after reading a long text, nothing else.
+So as long as you keep it relevant/interesting for the reader, there is no 
page number limit/cost.
+
+It might also help if you start discussing the usage of your idea in the 
`Invoking ProgramName' subsection (explaining the options and arguments you 
have in mind) at this stage too.
+Actually starting to write it here will really help you later when you are 
coding.
+
+@item
+After you have finished adding your initial intended plan to the book, then 
start coding your change or new program within the Gnuastro source files.
+While you are coding, you will notice that somethings should be different from 
what you wrote in the book (your initial plan).
+So correct them as you are actually coding, but do not worry too much about 
missing a few things (see the next step).
 
 @item
 After your work has been fully implemented, read the section documentation
@@ -43622,49 +42877,38 @@ If the change is notable, also update the @file{NEWS} 
file.
 @cindex GNU Autoconf
 @cindex GNU Automake
 @cindex GNU build system
-To build the various programs and libraries in Gnuastro, the GNU build
-system is used which defines the steps in @ref{Quick start}. It consists of
-GNU Autoconf, GNU Automake and GNU Libtool which are collectively known as
-GNU Autotools. They provide a very portable system to check the hosts
-environment and compile Gnuastro based on that. They also make installing
-everything in their standard places very easy for the programmer. Most of
-the small caps files that you see in the top source directory of the
-tarball are created by these three tools (see @ref{Version controlled
-source}). To facilitate the building and testing of your work during
-development, Gnuastro comes with two useful scripts:
+To build the various programs and libraries in Gnuastro, the GNU build system 
is used which defines the steps in @ref{Quick start}.
+It consists of GNU Autoconf, GNU Automake and GNU Libtool which are 
collectively known as GNU Autotools.
+They provide a very portable system to check the hosts environment and compile 
Gnuastro based on that.
+They also make installing everything in their standard places very easy for 
the programmer.
+Most of the small caps files that you see in the top source directory of the 
tarball are created by these three tools (see @ref{Version controlled source}).
+To facilitate the building and testing of your work during development, 
Gnuastro comes with two useful scripts:
 
 @table @file
 @cindex @file{developer-build}
 @item developer-build
-This is more fully described in @ref{Configure and build in RAM}. During
-development, you will usually run this command only once (at the start of
-your work).
+This is more fully described in @ref{Configure and build in RAM}.
+During development, you will usually run this command only once (at the start 
of your work).
 
 @cindex @file{tests/during-dev.sh}
 @item tests/during-dev.sh
-This script is designed to be run each time you make a change and want to
-test your work (with some possible input and output). The script itself is
-heavily commented and thoroughly describes the best way to use it, so we
-will not repeat it here. For a usage example, see @ref{Forking tutorial}.
-
-As a short summary: you specify the build directory, an output directory
-(for the built program to be run in, and also contains the inputs), the
-program's short name and the arguments and options that it should be run
-with. This script will then build Gnuastro, go to the output directory and
-run the built executable from there. One option for the output directory
-might be your desktop, so you can easily see the output files and delete
-them when you are finished. The main purpose of these scripts is to keep
-your source directory clean and facilitate your development.
+This script is designed to be run each time you make a change and want to test 
your work (with some possible input and output).
+The script itself is heavily commented and thoroughly describes the best way 
to use it, so we will not repeat it here.
+For a usage example, see @ref{Forking tutorial}.
+
+As a short summary: you specify the build directory, an output directory (for 
the built program to be run in, and also contains the inputs), the program's 
short name and the arguments and options that it should be run with.
+This script will then build Gnuastro, go to the output directory and run the 
built executable from there.
+One option for the output directory might be your desktop, so you can easily 
see the output files and delete them when you are finished.
+The main purpose of these scripts is to keep your source directory clean and 
facilitate your development.
 @end table
 
 @cindex Debugging
 @cindex Optimization
-By default all the programs are compiled with optimization flags for
-increased speed. A side effect of optimization is that valuable debugging
-information is lost. All the libraries are also linked as shared libraries
-by default. Shared libraries further complicate the debugging process and
-significantly slow down the compilation (the @command{make} command). So
-during development it is recommended to configure Gnuastro as follows:
+By default all the programs are compiled with optimization flags for increased 
speed.
+A side effect of optimization is that valuable debugging information is lost.
+All the libraries are also linked as shared libraries by default.
+Shared libraries further complicate the debugging process and significantly 
slow down the compilation (the @command{make} command).
+So during development it is recommended to configure Gnuastro as follows:
 
 @example
 $ ./configure --enable-debug
@@ -43674,11 +42918,8 @@ $ ./configure --enable-debug
 In @file{developer-build} you can ask for this behavior through the
 @option{--debug} option, see @ref{Separate build and source directories}.
 
-In order to understand the building process, you can go through the
-Autoconf, Automake and Libtool manuals, like all GNU manuals they provide
-both a great tutorial and technical documentation. The ``A small Hello
-World'' section in Automake's manual (in chapter 2) can be a good starting
-guide after you have read the separate introductions.
+In order to understand the building process, you can go through the Autoconf, 
Automake and Libtool manuals, like all GNU manuals they provide both a great 
tutorial and technical documentation.
+The ``A small Hello World'' section in Automake's manual (in chapter 2) can be 
a good starting guide after you have read the separate introductions.
 
 
 
@@ -43689,52 +42930,32 @@ guide after you have read the separate introductions.
 
 @cindex Test scripts
 @cindex Gnuastro test scripts
-As explained in @ref{Tests}, for every program some simple tests are
-written to check the various independent features of the program. All the
-tests are placed in the @file{tests/} directory. The
-@file{tests/prepconf.sh} script is the first `test' that will be run. It
-will copy all the configuration files from the various directories to a
-@file{tests/.gnuastro} directory (which it will make) so the various tests
-can set the default values. This script will also make sure the programs
-do not go searching for user and system wide configuration files to avoid
-the mixing of values with different Gnuastro version on the system.
-
-For each program, the tests are placed inside directories with the
-program name. Each test is written as a shell script. The last line of
-this script is the test which runs the program with certain
-parameters. The return value of this script determines the fate of the
-test, see the ``Support for test suites'' chapter of the Automake
-manual for a very nice and complete explanation. In every script, two
-variables are defined at first: @code{prog} and @code{execname}. The
-first specifies the program name and the second the location of the
-executable.
+As explained in @ref{Tests}, for every program some simple tests are written 
to check the various independent features of the program.
+All the tests are placed in the @file{tests/} directory.
+The @file{tests/prepconf.sh} script is the first `test' that will be run.
+It will copy all the configuration files from the various directories to a 
@file{tests/.gnuastro} directory (which it will make) so the various tests can 
set the default values.
+This script will also make sure the programs do not go searching for user and 
system wide configuration files to avoid the mixing of values with different 
Gnuastro version on the system.
+
+For each program, the tests are placed inside directories with the program 
name.
+Each test is written as a shell script.
+The last line of this script is the test which runs the program with certain 
parameters.
+The return value of this script determines the fate of the test, see the 
``Support for test suites'' chapter of the Automake manual for a very nice and 
complete explanation.
+In every script, two variables are defined at first: @code{prog} and 
@code{execname}.
+The first specifies the program name and the second the location of the 
executable.
 
 @cindex Build tree
 @cindex Source tree
 @cindex @file{developer-build}
-The most important thing to have in mind about all the test scripts is that
-they are run from inside the @file{tests/} directory in the ``build
-tree''. Which can be different from the directory they are stored in (known
-as the ``source tree'')@footnote{The @file{developer-build} script also
-uses this feature to keep the source and build directories separate (see
-@ref{Separate build and source directories}).}. This distinction is made by
-GNU Autoconf and Automake (which configure, build and install Gnuastro) so
-that you can install the program even if you do not have write access to the
-directory keeping the source files. See the ``Parallel build trees (a.k.a
-VPATH builds)'' in the Automake manual for a nice explanation.
-
-Because of this, any necessary inputs that are distributed in the
-tarball@footnote{In many cases, the inputs of a test are outputs of
-previous tests, this does not apply to this class of inputs. Because all
-outputs of previous tests are in the ``build tree''.}, for example, the
-catalogs necessary for checks in MakeProfiles and Crop, must be identified
-with the @command{$topsrc} prefix instead of @command{../} (for the top
-source directory that is unpacked). This @command{$topsrc} variable points
-to the source tree where the script can find the source data (it is defined
-in @file{tests/Makefile.am}). The executables and other test products were
-built in the build tree (where they are being run), so they do not need to
-be prefixed with that variable. This is also true for images or files that
-were produced by other tests.
+The most important thing to have in mind about all the test scripts is that 
they are run from inside the @file{tests/} directory in the ``build tree''.
+Which can be different from the directory they are stored in (known as the 
``source tree'')@footnote{The @file{developer-build} script also uses this 
feature to keep the source and build directories separate (see @ref{Separate 
build and source directories}).}.
+This distinction is made by GNU Autoconf and Automake (which configure, build 
and install Gnuastro) so that you can install the program even if you do not 
have write access to the directory keeping the source files.
+See the ``Parallel build trees (a.k.a VPATH builds)'' in the Automake manual 
for a nice explanation.
+
+Because of this, any necessary inputs that are distributed in the 
tarball@footnote{In many cases, the inputs of a test are outputs of previous 
tests, this does not apply to this class of inputs.
+Because all outputs of previous tests are in the ``build tree''.}, for 
example, the catalogs necessary for checks in MakeProfiles and Crop, must be 
identified with the @command{$topsrc} prefix instead of @command{../} (for the 
top source directory that is unpacked).
+This @command{$topsrc} variable points to the source tree where the script can 
find the source data (it is defined in @file{tests/Makefile.am}).
+The executables and other test products were built in the build tree (where 
they are being run), so they do not need to be prefixed with that variable.
+This is also true for images or files that were produced by other tests.
 
 
 @node Bash programmable completion, Developer's checklist, Test scripts, 
Developing
@@ -44123,34 +43344,23 @@ See @ref{Production workflow} and @ref{Forking 
tutorial}.
 @cindex Management hub
 @cindex Feature request
 @cindex Central management
-@url{https://savannah.gnu.org/projects/gnuastro/, Gnuastro's central
-management hub}@footnote{@url{https://savannah.gnu.org/projects/gnuastro/}}
-is located on @url{https://savannah.gnu.org/, GNU
-Savannah}@footnote{@url{https://savannah.gnu.org/}}. Savannah is the
-central software development management system for many GNU
-projects. Through this central hub, you can view the list of activities
-that the developers are engaged in, their activity on the version
-controlled source, and other things. Each defined activity in the
-development cycle is known as an `issue' (or `item'). An issue can be a bug
-(see @ref{Report a bug}), or a suggested feature (see @ref{Suggest new
-feature}) or an enhancement or generally any @emph{one} job that is to be
-done. In Savannah, issues are classified into three categories or
-`tracker's:
+@url{https://savannah.gnu.org/projects/gnuastro/, Gnuastro's central 
management hub}@footnote{@url{https://savannah.gnu.org/projects/gnuastro/}} is 
located on @url{https://savannah.gnu.org/, GNU 
Savannah}@footnote{@url{https://savannah.gnu.org/}}.
+Savannah is the central software development management system for many GNU 
projects.
+Through this central hub, you can view the list of activities that the 
developers are engaged in, their activity on the version controlled source, and 
other things.
+Each defined activity in the development cycle is known as an `issue' (or 
`item').
+An issue can be a bug (see @ref{Report a bug}), or a suggested feature (see 
@ref{Suggest new feature}) or an enhancement or generally any @emph{one} job 
that is to be done.
+In Savannah, issues are classified into three categories or `tracker's:
 
 @table @asis
 
 @cindex Mailing list: bug-gnuastro
 @item Support
-This tracker is a way that (possibly anonymous) users can get in touch
-with the Gnuastro developers. It is a complement to the bug-gnuastro
-mailing list (see @ref{Report a bug}). Anyone can post an issue to
-this tracker. The developers will not submit an issue to this
-list. They will only reassign the issues in this list to the other two
-trackers if they are valid@footnote{Some of the issues registered here
-might be due to a mistake on the user's side, not an actual bug in the
-program.}. Ideally (when the developers have time to put on Gnuastro,
-please do not forget that Gnuastro is a volunteer effort), there should
-be no open items in this tracker.
+This tracker is a way that (possibly anonymous) users can get in touch with 
the Gnuastro developers.
+It is a complement to the bug-gnuastro mailing list (see @ref{Report a bug}).
+Anyone can post an issue to this tracker.
+The developers will not submit an issue to this list.
+They will only reassign the issues in this list to the other two trackers if 
they are valid@footnote{Some of the issues registered here might be due to a 
mistake on the user's side, not an actual bug in the program.}.
+Ideally (when the developers have time to put on Gnuastro, please do not 
forget that Gnuastro is a volunteer effort), there should be no open items in 
this tracker.
 
 @item Bugs
 This tracker contains all the known bugs in Gnuastro (problems with
@@ -44163,36 +43373,20 @@ features/capabilities) that are to be added to 
Gnuastro.
 @end table
 
 @noindent
-All the trackers can be browsed by a (possibly anonymous) visitor, but to
-edit and comment on the Bugs and Tasks trackers, you have to be a
-registered on Savannah. When posting an issue to a tracker, it is very
-important to choose the `Category' and `Item Group' options accurately. The
-first contains a list of all Gnuastro's programs along with `Installation',
-`New program' and `Webpage'. The ``Item Group'' contains the nature of the
-issue, for example, if it is a `Crash' in the software (a bug), or a problem
-in the documentation (also a bug) or a feature request or an enhancement.
-
-The set of horizontal links on the top of the page (Starting with
-`Main' and `Homepage' and finishing with `News') are the easiest way
-to access these trackers (and other major aspects of the project) from
-any part of the project web page. Hovering your mouse over them will
-open a drop down menu that will link you to the different things you
-can do on each tracker (for example, `Submit new' or `Browse').  When
-you browse each tracker, you can use the ``Display Criteria'' link
-above the list to limit the displayed issues to what you are
-interested in. The `Category' and `Group Item' (explained above) are a
-good starting point.
+All the trackers can be browsed by a (possibly anonymous) visitor, but to edit 
and comment on the Bugs and Tasks trackers, you have to be a registered on 
Savannah.
+When posting an issue to a tracker, it is very important to choose the 
`Category' and `Item Group' options accurately.
+The first contains a list of all Gnuastro's programs along with 
`Installation', `New program' and `Webpage'.
+The ``Item Group'' contains the nature of the issue, for example, if it is a 
`Crash' in the software (a bug), or a problem in the documentation (also a bug) 
or a feature request or an enhancement.
+
+The set of horizontal links on the top of the page (Starting with `Main' and 
`Homepage' and finishing with `News') are the easiest way to access these 
trackers (and other major aspects of the project) from any part of the project 
web page.
+Hovering your mouse over them will open a drop down menu that will link you to 
the different things you can do on each tracker (for example, `Submit new' or 
`Browse').
+When you browse each tracker, you can use the ``Display Criteria'' link above 
the list to limit the displayed issues to what you are interested in.
+The `Category' and `Group Item' (explained above) are a good starting point.
 
 @cindex Mailing list: gnuastro-devel
-Any new issue that is submitted to any of the trackers, or any comments
-that are posted for an issue, is directly forwarded to the gnuastro-devel
-mailing list (@url{https://lists.gnu.org/mailman/listinfo/gnuastro-devel},
-see @ref{Developing mailing lists} for more). This will allow anyone
-interested to be up to date on the over-all development activity in
-Gnuastro and will also provide an alternative (to Savannah) archiving for
-the development discussions. Therefore, it is not recommended to directly
-post an email to this mailing list, but do all the activities (for example
-add new issues, or comment on existing ones) on Savannah.
+Any new issue that is submitted to any of the trackers, or any comments that 
are posted for an issue, is directly forwarded to the gnuastro-devel mailing 
list (@url{https://lists.gnu.org/mailman/listinfo/gnuastro-devel}, see 
@ref{Developing mailing lists} for more).
+This will allow anyone interested to be up to date on the over-all development 
activity in Gnuastro and will also provide an alternative (to Savannah) 
archiving for the development discussions.
+Therefore, it is not recommended to directly post an email to this mailing 
list, but do all the activities (for example add new issues, or comment on 
existing ones) on Savannah.
 
 
 @cartouche
@@ -44200,13 +43394,12 @@ add new issues, or comment on existing ones) on 
Savannah.
 @strong{Do I need to be a member in Savannah to contribute to Gnuastro?}
 No.
 
-The full version controlled history of Gnuastro is available for anonymous
-download or cloning. See @ref{Production workflow} for a description of
-Gnuastro's Integration-Manager Workflow. In short, you can either send in
-patches, or make your own fork. If you choose the latter, you can push your
-changes to your own fork and inform us. We will then pull your changes and
-merge them into the main project. Please see @ref{Forking tutorial} for a
-tutorial.
+The full version controlled history of Gnuastro is available for anonymous 
download or cloning.
+See @ref{Production workflow} for a description of Gnuastro's 
Integration-Manager Workflow.
+In short, you can either send in patches, or make your own fork.
+If you choose the latter, you can push your changes to your own fork and 
inform us.
+We will then pull your changes and merge them into the main project.
+Please see @ref{Forking tutorial} for a tutorial.
 @end cartouche
 
 
@@ -44223,34 +43416,24 @@ subscribe to:
 @itemx (at @url{https://lists.gnu.org/mailman/listinfo/gnuastro-devel})
 
 @cindex Mailing list: gnuastro-devel
-All the posts made in the support, bugs and tasks discussions of
-@ref{Gnuastro project webpage} are also sent to this mailing address and
-archived. By subscribing to this list you can stay up to date with the
-discussions that are going on between the developers before, during and
-(possibly) after working on an issue. All discussions are either in the
-context of bugs or tasks which are done on Savannah and circulated to all
-interested people through this mailing list. Therefore it is not
-recommended to post anything directly to this mailing list. Any mail that
-is sent to it from Savannah to this list has a link under the title ``Reply
-to this item at:''. That link will take you directly to the issue
-discussion page, where you can read the discussion history or join it.
-
-While you are posting comments on the Savannah issues, be sure to update
-the meta-data. For example, if the task/bug is not assigned to anyone and
-you would like to take it, change the ``Assigned to'' box, or if you want
-to report that it has been applied, change the status and so on. All these
-changes will also be circulated with the email very clearly.
+All the posts made in the support, bugs and tasks discussions of @ref{Gnuastro 
project webpage} are also sent to this mailing address and archived.
+By subscribing to this list you can stay up to date with the discussions that 
are going on between the developers before, during and (possibly) after working 
on an issue.
+All discussions are either in the context of bugs or tasks which are done on 
Savannah and circulated to all interested people through this mailing list.
+Therefore it is not recommended to post anything directly to this mailing list.
+Any mail that is sent to it from Savannah to this list has a link under the 
title ``Reply to this item at:''.
+That link will take you directly to the issue discussion page, where you can 
read the discussion history or join it.
+
+While you are posting comments on the Savannah issues, be sure to update the 
meta-data.
+For example, if the task/bug is not assigned to anyone and you would like to 
take it, change the ``Assigned to'' box, or if you want to report that it has 
been applied, change the status and so on.
+All these changes will also be circulated with the email very clearly.
 
 @item @command{gnuastro-commits@@gnu.org}
 @itemx (at @url{https://lists.gnu.org/mailman/listinfo/gnuastro-commits})
 
 @cindex Mailing list: gnuastro-commits
-This mailing list is defined to circulate all commits that are done in
-Gnuastro's version controlled source, see @ref{Version controlled
-source}. If you have any ideas, or suggestions on the commits, please use
-the bug and task trackers on Savannah to followup the discussion, do not
-post to this list. All the commits that are made for an already defined
-issue or task will state the respective ID so you can find it easily.
+This mailing list is defined to circulate all commits that are done in 
Gnuastro's version controlled source, see @ref{Version controlled source}.
+If you have any ideas, or suggestions on the commits, please use the bug and 
task trackers on Savannah to followup the discussion, do not post to this list.
+All the commits that are made for an already defined issue or task will state 
the respective ID so you can find it easily.
 
 @end table
 
@@ -44262,27 +43445,17 @@ issue or task will state the respective ID so you can 
find it easily.
 @node Contributing to Gnuastro,  , Developing mailing lists, Developing
 @section Contributing to Gnuastro
 
-You have this great idea or have found a good fix to a problem which you
-would like to implement in Gnuastro. You have also become familiar with the
-general design of Gnuastro in the previous sections of this chapter (see
-@ref{Developing}) and want to start working on and sharing your new
-addition/change with the whole community as part of the official
-release. This is great and your contribution is most welcome. This section
-and the next (see @ref{Developer's checklist}) are written in the hope of
-making it as easy as possible for you to share your great idea with the
-community.
+You have this great idea or have found a good fix to a problem which you would 
like to implement in Gnuastro.
+You have also become familiar with the general design of Gnuastro in the 
previous sections of this chapter (see @ref{Developing}) and want to start 
working on and sharing your new addition/change with the whole community as 
part of the official release.
+This is great and your contribution is most welcome.
+This section and the next (see @ref{Developer's checklist}) are written in the 
hope of making it as easy as possible for you to share your great idea with the 
community.
 
 @cindex FSF
 @cindex Free Software Foundation
-In this section we discuss the final steps you have to take: legal and
-technical. From the legal perspective, the copyright of any work you do on
-Gnuastro has to be assigned to the Free Software Foundation (FSF) and the
-GNU operating system, or you have to sign a disclaimer. We do this to
-ensure that Gnuastro can remain free in the future, see @ref{Copyright
-assignment}. From the technical point of view, in this section we also
-discuss commit guidelines (@ref{Commit guidelines}) and the general version
-control workflow of Gnuastro in @ref{Production workflow}, along with a
-tutorial in @ref{Forking tutorial}.
+In this section we discuss the final steps you have to take: legal and 
technical.
+From the legal perspective, the copyright of any work you do on Gnuastro has 
to be assigned to the Free Software Foundation (FSF) and the GNU operating 
system, or you have to sign a disclaimer.
+We do this to ensure that Gnuastro can remain free in the future, see 
@ref{Copyright assignment}.
+From the technical point of view, in this section we also discuss commit 
guidelines (@ref{Commit guidelines}) and the general version control workflow 
of Gnuastro in @ref{Production workflow}, along with a tutorial in @ref{Forking 
tutorial}.
 
 Recall that before starting the work on your idea, be sure to checkout the
 bugs and tasks trackers in @ref{Gnuastro project webpage} and announce your
@@ -44339,34 +43512,25 @@ The FSF's copyright clerk will kindly help you 
decide, please consult the follow
 @node Commit guidelines, Production workflow, Copyright assignment, 
Contributing to Gnuastro
 @subsection Commit guidelines
 
-To be able to cleanly integrate your work with the other developers,
-@strong{never commit on the @file{master} branch} (see @ref{Production
-workflow} for a complete discussion and @ref{Forking tutorial} for a
-cookbook example). In short, leave @file{master} only for changes you
-fetch, or pull from the official repository (see
-@ref{Synchronizing}).
+To be able to cleanly integrate your work with the other developers, 
@strong{never commit on the @file{master} branch} (see @ref{Production 
workflow} for a complete discussion and @ref{Forking tutorial} for a cookbook 
example).
+In short, leave @file{master} only for changes you fetch, or pull from the 
official repository (see @ref{Synchronizing}).
 
-In the Gnuastro commit messages, we strive to follow these standards. Note
-that in the early phases of Gnuastro's development, we are experimenting
-and so if you notice earlier commits do not satisfy some of the guidelines
-below, it is because they predate that guideline.
+In the Gnuastro commit messages, we strive to follow these standards.
+Note that in the early phases of Gnuastro's development, we are experimenting 
and so if you notice earlier commits do not satisfy some of the guidelines 
below, it is because they predate that guideline.
 
 @table @asis
 
 @item Commit title
-The commits have to start with one short descriptive title. The title is
-separated from the body with one blank line. Run @command{git log} to see
-some of the most recent commit messages as an example. In general, the
-title should satisfy the following conditions:
+The commits have to start with one short descriptive title.
+The title is separated from the body with one blank line.
+Run @command{git log} to see some of the most recent commit messages as an 
example.
+In general, the title should satisfy the following conditions:
 
 @itemize
 @item
-It is best for the title to be short, about 60 (or even 50)
-characters. Most emulated command-line terminals are about 80
-characters wide. However, we should also allow for the commit hashes
-which are printed in @command{git log --oneline}, and also branch
-names or the graph structure outputs of @command{git log} which are
-also commonly used.
+It is best for the title to be short, about 60 (or even 50) characters.
+Most emulated command-line terminals are about 80 characters wide.
+However, we should also allow for the commit hashes which are printed in 
@command{git log --oneline}, and also branch names or the graph structure 
outputs of @command{git log} which are also commonly used.
 
 @item
 The title should not finish with any full-stops or periods (`@key{.}').
@@ -44375,59 +43539,38 @@ The title should not finish with any full-stops or 
periods (`@key{.}').
 
 @item Commit body
 @cindex Mailing list: gnuastro-commits
-The body of the commit message is separated from the title by one empty
-line. Recall that anyone who has subscribed to @command{gnuastro-commits}
-mailing list will get the commit in their email after it has been pushed to
-@file{master}. People will also read them when they synchronize with the
-main Gnuastro repository (see @ref{Synchronizing}). Finally, the commit
-messages will later be used to update the @file{NEWS} file on each
-release. Therefore the commit message body plays a very important role in
-the development of Gnuastro, so please adhere to the following guidelines.
+The body of the commit message is separated from the title by one empty line.
+Recall that anyone who has subscribed to @command{gnuastro-commits} mailing 
list will get the commit in their email after it has been pushed to 
@file{master}.
+People will also read them when they synchronize with the main Gnuastro 
repository (see @ref{Synchronizing}).
+Finally, the commit messages will later be used to update the @file{NEWS} file 
on each release.
+Therefore the commit message body plays a very important role in the 
development of Gnuastro, so please adhere to the following guidelines.
 
 @itemize
 
 
 @item
-The body should be very descriptive. Start the commit message body by
-explaining what changes your commit makes from a user's perspective (added,
-changed, or removed options, or arguments to programs or libraries, or
-modified algorithms, or new installation step, etc.).
+The body should be very descriptive.
+Start the commit message body by explaining what changes your commit makes 
from a user's perspective (added, changed, or removed options, or arguments to 
programs or libraries, or modified algorithms, or new installation step, etc.).
 
 @item
 @cindex Mailing list: gnuastro-commits
-Try to explain the committed contents as best as you can. Recall that the
-readers of your commit message do not necessarily have your current
-background. After some time you will also forget the context, so this
-request is not just for
-others@footnote{@url{http://catb.org/esr/writings/unix-koans/prodigy.html}}. 
Therefore
-be very descriptive and explain as much as possible: what the bug/task was,
-justify the way you fixed it and discuss other possible solutions that you
-might not have included. For the last item, it is best to discuss them
-thoroughly as comments in the appropriate section of the code, but only
-give a short summary in the commit message. Note that all added and removed
-source code lines will also be circulated in the @command{gnuastro-commits}
-mailing list.
-
-@item
-Like all other Gnuastro's text files, the lines in the commit body should
-not be longer than 75 characters, see @ref{Coding conventions}. This is to
-ensure that on standard terminal emulators (with 80 character width), the
-@command{git log} output can be cleanly displayed (note that the commit
-message is indented in the output of @command{git log}). If you use Emacs,
-Gnuastro's @file{.dir-locals.el} file will ensure that your commits satisfy
-this condition (using @key{M-q}).
+Try to explain the committed contents as best as you can.
+Recall that the readers of your commit message do not necessarily have your 
current background.
+After some time you will also forget the context, so this request is not just 
for others@footnote{@url{http://catb.org/esr/writings/unix-koans/prodigy.html}}.
+Therefore be very descriptive and explain as much as possible: what the 
bug/task was, justify the way you fixed it and discuss other possible solutions 
that you might not have included.
+For the last item, it is best to discuss them thoroughly as comments in the 
appropriate section of the code, but only give a short summary in the commit 
message.
+Note that all added and removed source code lines will also be circulated in 
the @command{gnuastro-commits} mailing list.
+
+@item
+Like all other Gnuastro's text files, the lines in the commit body should not 
be longer than 75 characters, see @ref{Coding conventions}.
+This is to ensure that on standard terminal emulators (with 80 character 
width), the @command{git log} output can be cleanly displayed (note that the 
commit message is indented in the output of @command{git log}).
+If you use Emacs, Gnuastro's @file{.dir-locals.el} file will ensure that your 
commits satisfy this condition (using @key{M-q}).
 
 @item
 @cindex Mailing list: gnuastro-commits
-When the commit is related to a task or a bug, please include the
-respective ID (in the format of @code{bug/task #ID}, note the space) in the
-commit message (from @ref{Gnuastro project webpage}) for interested people
-to be able to followup the discussion that took place there. If the commit
-fixes a bug or finishes a task, the recommended way is to add a line after
-the body with `@code{This fixes bug #ID.}', or `@code{This finishes task
-#ID.}'. Do Not assume that the reader has internet access to check the bug's
-full description when reading the commit message, so give a short
-introduction too.
+When the commit is related to a task or a bug, please include the respective 
ID (in the format of @code{bug/task #ID}, note the space) in the commit message 
(from @ref{Gnuastro project webpage}) for interested people to be able to 
followup the discussion that took place there.
+If the commit fixes a bug or finishes a task, the recommended way is to add a 
line after the body with `@code{This fixes bug #ID.}', or `@code{This finishes 
task #ID.}'.
+Do Not assume that the reader has internet access to check the bug's full 
description when reading the commit message, so give a short introduction too.
 @end itemize
 @end table
 
@@ -44438,23 +43581,16 @@ After reading this, please run @command{git log} on 
the @code{master} branch and
 @example
 The first line should be the title of the commit
 
-An empty line is necessary after the title so Git does not confuse
-lines. This top paragraph of the body of the commit usually describes
-the reason this commit was done. Therefore it usually starts with
-"Until now ...". It is very useful to explain the reason behind the
-change, things that are not immediately obvious when looking into the
-code. You do not need to list the names of the files, or what lines
-have been changed, do not forget that the code changes are fully
-stored within Git :-).
-
-In the second paragraph (or any later paragraph!) of the body, we
-describe the solution and why (not "how"!) the particular solution
-was implemented. So we usually start this part of the commit body
-with "With this commit ...". Again, you do not need to go into the
-details that can be seen from the 'git diff' command (like the
-file names that have been changed or the code that has been
-implemented). The important thing here is the things that are not
-immediately obvious from looking into the code.
+An empty line is necessary after the title so Git does not confuse lines.
+This top paragraph of the body of the commit usually describes the reason this 
commit was done.
+Therefore it usually starts with "Until now ...".
+It is very useful to explain the reason behind the change, things that are not 
immediately obvious when looking into the code.
+You do not need to list the names of the files, or what lines have been 
changed, do not forget that the code changes are fully stored within Git :-).
+
+In the second paragraph (or any later paragraph!) of the body, we describe the 
solution and why (not "how"!) the particular solution was implemented.
+So we usually start this part of the commit body with "With this commit ...".
+Again, you do not need to go into the details that can be seen from the 'git 
diff' command (like the file names that have been changed or the code that has 
been implemented).
+The important thing here is the things that are not immediately obvious from 
looking into the code.
 
 You can continue the explanation and it is encouraged to be very
 explicit about the "human factor" of the change as much as possible,
@@ -44637,9 +43773,8 @@ This will enable you to start your branch (work) from 
the most recent commit and
 @node Other useful software, GNU Free Doc License, Developing, Top
 @appendix Other useful software
 
-In this appendix the installation of programs and libraries that are
-not direct Gnuastro dependencies are discussed. However they can be
-useful for working with Gnuastro.
+In this appendix the installation of programs and libraries that are not 
direct Gnuastro dependencies are discussed.
+However they can be useful for working with Gnuastro.
 
 @menu
 * SAO DS9::                     Viewing FITS images.
@@ -44796,33 +43931,26 @@ export PATH="$HOME/.local/bin:$PATH"
 @cindex PGPLOT
 @cindex C, plotting
 @cindex Plotting directly in C
-PGPLOT is a package for making plots in C. It is not directly needed
-by Gnuastro, but can be used by WCSLIB, see @ref{WCSLIB}. As
-explained in @ref{WCSLIB}, you can install WCSLIB without it too. It
-is very old (the most recent version was released early 2001!), but
-remains one of the main packages for plotting directly in C. WCSLIB
-uses this package to make plots if you want it to make plots. If you
-are interested you can also use it for your own purposes.
+PGPLOT is a package for making plots in C.
+It is not directly needed by Gnuastro, but can be used by WCSLIB, see 
@ref{WCSLIB}.
+As explained in @ref{WCSLIB}, you can install WCSLIB without it too.
+It is very old (the most recent version was released early 2001!), but remains 
one of the main packages for plotting directly in C.
+WCSLIB uses this package to make plots if you want it to make plots.
+If you are interested you can also use it for your own purposes.
 
 @cindex Python Matplotlib
 @cindex Matplotlib, Python
 @cindex PGFplots in @TeX{} or @LaTeX{}
-If you want your plotting codes in between your C program, PGPLOT is
-currently one of your best options. The recommended alternative to
-this method is to get the raw data for the plots in text files and
-input them into any of the various more modern and capable plotting
-tools separately, for example, the Matplotlib library in Python or
-PGFplots in @LaTeX{}. This will also significantly help code
-readability. Let's get back to PGPLOT for the sake of
-WCSLIB. Installing it is a little tricky (mainly because it is so
-old!).
-
-You can download the most recent version from the FTP link in its
-web page@footnote{@url{http://www.astro.caltech.edu/~tjp/pgplot/}}. You can
-unpack it with the @command{tar xf} command. Let's assume the directory you
-have unpacked it to is @file{PGPLOT}, most probably it is:
-@file{/home/username/Downloads/pgplot/}.  open the @file{drivers.list}
-file:
+If you want your plotting codes in between your C program, PGPLOT is currently 
one of your best options.
+The recommended alternative to this method is to get the raw data for the 
plots in text files and input them into any of the various more modern and 
capable plotting tools separately, for example, the Matplotlib library in 
Python or PGFplots in @LaTeX{}.
+This will also significantly help code readability.
+Let's get back to PGPLOT for the sake of WCSLIB.
+Installing it is a little tricky (mainly because it is so old!).
+
+You can download the most recent version from the FTP link in its web 
page@footnote{@url{http://www.astro.caltech.edu/~tjp/pgplot/}}.
+You can unpack it with the @command{tar xf} command.
+Let's assume the directory you have unpacked it to is @file{PGPLOT}, most 
probably it is: @file{/home/username/Downloads/pgplot/}.
+Open the @file{drivers.list} file:
 @example
 $ gedit drivers.list
 @end example
@@ -44845,11 +43973,9 @@ Open the @file{PGPLOT/sys_linux/g77_gcc.conf} file:
 $ gedit PGPLOT/sys_linux/g77_gcc.conf
 @end example
 @noindent
-change the line saying: @code{FCOMPL="g77"} to
-@code{FCOMPL="gfortran"}, and save it. This is a very important step
-during the compilation of the code if you are in GNU/Linux. You now
-have to create a folder in @file{/usr/local}, do not forget to replace
-@file{PGPLOT} with your unpacked address:
+change the line saying: @code{FCOMPL="g77"} to @code{FCOMPL="gfortran"}, and 
save it.
+This is a very important step during the compilation of the code if you are in 
GNU/Linux.
+You now have to create a folder in @file{/usr/local}, do not forget to replace 
@file{PGPLOT} with your unpacked address:
 @example
 $ su
 # mkdir /usr/local/pgplot
@@ -44861,19 +43987,16 @@ To make the Makefile, type the following command:
 # PGPLOT/makemake PGPLOT linux g77_gcc
 @end example
 @noindent
-It should finish by saying: @command{Determining object file
-dependencies}. You have done the hard part! The rest is easy: run
-these three commands in order:
+It should finish by saying: @command{Determining object file dependencies}.
+You have done the hard part! The rest is easy: run these three commands in 
order:
 @example
 # make
 # make clean
 # make cpg
 @end example
 
-Finally you have to place the position of this directory you just made
-into the @command{LD_LIBRARY_PATH} environment variable and define the
-environment variable @command{PGPLOT_DIR}. To do that, you have to
-edit your @file{.bashrc} file:
+Finally you have to place the position of this directory you just made into 
the @command{LD_LIBRARY_PATH} environment variable and define the environment 
variable @command{PGPLOT_DIR}.
+To do that, you have to edit your @file{.bashrc} file:
 @example
 $ cd ~
 $ gedit .bashrc
@@ -44887,11 +44010,8 @@ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/pgplot/
 export LD_LIBRARY_PATH
 @end example
 @noindent
-You need to log out and log back in again so these definitions take
-effect. After you logged back in, you want to see the result of all
-this labor, right? Tim Pearson has done that for you, create a
-temporary folder in your home directory and copy all the demonstration
-files in it:
+You need to log out and log back in again so these definitions take effect.
+After you logged back in, you want to see the result of all this labor, right? 
Tim Pearson has done that for you, create a temporary folder in your home 
directory and copy all the demonstration files in it:
 @example
 $ cd ~
 $ mkdir temp
@@ -44899,10 +44019,8 @@ $ cd temp
 $ cp /usr/local/pgplot/pgdemo* ./
 $ ls
 @end example
-You will see a lot of pgdemoXX files, where XX is a number. In order
-to execute them type the following command and drink your coffee while
-looking at all the beautiful plots! You are now ready to create your
-own.
+You will see a lot of pgdemoXX files, where XX is a number.
+In order to execute them type the following command and drink your coffee 
while looking at all the beautiful plots! You are now ready to create your own.
 @example
 $ ./pgdemoXX
 @end example
@@ -44949,15 +44067,11 @@ $ ./pgdemoXX
 @c Print the index and finish:
 @node Index,  , GNU General Public License, Top
 @unnumbered Index: Macros, structures and functions
-All Gnuastro library's exported macros start with @code{GAL_}, and its
-exported structures and functions start with @code{gal_}. This abbreviation
-stands for @emph{G}NU @emph{A}stronomy @emph{L}ibrary. The next element in
-the name is the name of the header which declares or defines them, so to
-use the @code{gal_array_fset_const} function, you have to @code{#include
-<gnuastro/array.h>}. See @ref{Gnuastro library} for more. The
-@code{pthread_barrier} constructs are our implementation and are only
-available on systems that do not have them, see @ref{Implementation of
-pthread_barrier}.
+All Gnuastro library's exported macros start with @code{GAL_}, and its 
exported structures and functions start with @code{gal_}.
+This abbreviation stands for @emph{G}NU @emph{A}stronomy @emph{L}ibrary.
+The next element in the name is the name of the header which declares or 
defines them, so to use the @code{gal_array_fset_const} function, you have to 
@code{#include <gnuastro/array.h>}.
+See @ref{Gnuastro library} for more.
+The @code{pthread_barrier} constructs are our implementation and are only 
available on systems that do not have them, see @ref{Implementation of 
pthread_barrier}.
 @printindex fn
 @unnumbered Index
 @printindex cp
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 48a62846..d2645f2e 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -31,6 +31,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <stdlib.h>
 #include <stdarg.h>
 
+#include <wcslib/wcs.h>
 #include <gsl/gsl_rng.h>
 #include <gsl/gsl_math.h>
 #include <gsl/gsl_randist.h>
@@ -1132,8 +1133,8 @@ arithmetic_to_1d(int operator, int flags, gal_data_t 
*input)
 {
   size_t i;
 
-  /* Set absurd value to cause a crash if values that shouldn't be used are
-     used! */
+  /* Set absurd value to cause a crash if values that shouldn't be used
+     are used! */
   for(i=1;i<input->ndim;++i) input->dsize[i]=GAL_BLANK_UINT64;
 
   /* Reset the metadata and return.*/
@@ -3343,6 +3344,8 @@ gal_arithmetic_set_operator(char *string, size_t 
*num_operands)
     { op=GAL_ARITHMETIC_OP_TO1D;              *num_operands=1;  }
   else if (!strcmp(string, "stitch"))
     { op=GAL_ARITHMETIC_OP_STITCH;            *num_operands=-1; }
+  else if (!strcmp(string, "trim"))
+    { op=GAL_ARITHMETIC_OP_TRIM;              *num_operands=1; }
 
   /* Conditional operators. */
   else if (!strcmp(string, "lt" ))
@@ -3577,6 +3580,7 @@ gal_arithmetic_operator_string(int operator)
     case GAL_ARITHMETIC_OP_RANDOM_FROM_HIST_RAW:return "random-from-hist-raw";
 
     case GAL_ARITHMETIC_OP_SIZE:            return "size";
+    case GAL_ARITHMETIC_OP_TRIM:            return "trim";
     case GAL_ARITHMETIC_OP_TO1D:            return "to-1d";
     case GAL_ARITHMETIC_OP_STITCH:          return "stitch";
 
@@ -3816,8 +3820,11 @@ gal_arithmetic(int operator, size_t numthreads, int 
flags, ...)
 
     /* Dimensionality changing operators. */
     case GAL_ARITHMETIC_OP_TO1D:
+    case GAL_ARITHMETIC_OP_TRIM:
       d1 = va_arg(va, gal_data_t *);
-      out=arithmetic_to_1d(operator, flags, d1);
+      out = ( operator==GAL_ARITHMETIC_OP_TO1D
+              ? arithmetic_to_1d(operator, flags, d1)
+              : gal_blank_trim(d1, flags & GAL_ARITHMETIC_FLAG_FREE) );
       break;
     case GAL_ARITHMETIC_OP_STITCH:
       d1 = va_arg(va, gal_data_t *);
diff --git a/lib/blank.c b/lib/blank.c
index c1bdf19b..78264ebf 100644
--- a/lib/blank.c
+++ b/lib/blank.c
@@ -29,6 +29,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <stdlib.h>
 #include <inttypes.h>
 
+#include <gnuastro/wcs.h>
 #include <gnuastro/data.h>
 #include <gnuastro/tile.h>
 #include <gnuastro/blank.h>
@@ -609,7 +610,10 @@ blank_flag(gal_data_t *input, int blank1_not0)
 
         /* String. */
         case GAL_TYPE_STRING:
-          do *o++ = !strcmp(*str,GAL_BLANK_STRING); while(++str<strf);
+          if(blank1_not0)
+            do *o++ = strcmp(*str,GAL_BLANK_STRING)==0; while(++str<strf);
+          else
+            do *o++ = strcmp(*str,GAL_BLANK_STRING)!=0; while(++str<strf);
           break;
 
         /* Currently unsupported types. */
@@ -668,6 +672,236 @@ gal_blank_flag_not(gal_data_t *input)
 
 
 
+#define NMM_CRDS_CHECK                                                  \
+  gal_dimension_index_to_coord(a-as, ndim, input->dsize, c);            \
+  for(i=0;i<ndim;++i)                                                   \
+    { if(c[i]<min[i]) min[i]=c[i]; if(c[i]>max[i]) max[i]=c[i]; }
+
+#define NMM_CRDS(IT) {                                                  \
+  IT b, *a=input->array, *as=a, *af=a+input->size;                      \
+  gal_blank_write(&b, input->type);                                     \
+  if(b==b) /* Blank value can be checked with the equal. */             \
+    do { if(*a!=b)  {NMM_CRDS_CHECK} } while(++a<af);                   \
+  else     /* Blank value will fail with the equal comparison. */       \
+    do { if(*a==*a) {NMM_CRDS_CHECK} } while(++a<af);                   \
+  }
+
+size_t *
+gal_blank_not_minmax_coords(gal_data_t *input)
+{
+  char **strarr=input->array;
+  size_t c[3], i, ndim, *out, *min, *max;
+
+  /* Sanity check. */
+  if(input==NULL) error(EXIT_FAILURE, 0, "%s: input is NULL", __func__);
+
+  /* Allocate the output and min/max datasets; and initialize the 'min'
+     dataset (note that the 'max' dataset has already been "clear"ed to
+     zero; which is what we want). */
+  ndim=input->ndim;
+  min=gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 0, __func__, "min");
+  max=gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 1, __func__, "max");
+  out=gal_pointer_allocate(GAL_TYPE_SIZE_T, 2*ndim, 0, __func__, "out");
+  for(i=0;i<ndim;++i) min[i]=GAL_BLANK_SIZE_T;
+
+  /* The input dataset may be empty. In this case, the output should also
+     be empty, but with the standard 'uint8' type of a flag (we can have
+     tables and images with 0 rows or pixels!). */
+  if(input->size==0 || input->array==NULL)
+    for(i=0;i<2*ndim;++i)
+      out[i]=GAL_BLANK_SIZE_T;
+
+  /* Do all the checks and allocations if a blank is actually present! */
+  if( gal_blank_present(input, 0) )
+    {
+      /* Go over the pixels and set the output values. */
+      switch(input->type)
+        {
+        /* Numeric types */
+        case GAL_TYPE_UINT8:     NMM_CRDS( uint8_t  );    break;
+        case GAL_TYPE_INT8:      NMM_CRDS( int8_t   );    break;
+        case GAL_TYPE_UINT16:    NMM_CRDS( uint16_t );    break;
+        case GAL_TYPE_INT16:     NMM_CRDS( int16_t  );    break;
+        case GAL_TYPE_UINT32:    NMM_CRDS( uint32_t );    break;
+        case GAL_TYPE_INT32:     NMM_CRDS( int32_t  );    break;
+        case GAL_TYPE_UINT64:    NMM_CRDS( uint64_t );    break;
+        case GAL_TYPE_INT64:     NMM_CRDS( int64_t  );    break;
+        case GAL_TYPE_FLOAT32:   NMM_CRDS( float    );    break;
+        case GAL_TYPE_FLOAT64:   NMM_CRDS( double   );    break;
+
+        /* String. */
+        case GAL_TYPE_STRING:
+          for(i=0;i<input->size;++i)
+            if(strcmp(strarr[i],GAL_BLANK_STRING))
+              {
+                gal_dimension_index_to_coord(i, ndim, input->dsize, c);
+                for(i=0;i<ndim;++i)
+                  { if(c[i]<min[i]) min[i]=c[i];
+                    if(c[i]>max[i]) max[i]=c[i]; }
+            }
+          break;
+
+        /* Currently unsupported types. */
+        case GAL_TYPE_BIT:
+        case GAL_TYPE_COMPLEX32:
+        case GAL_TYPE_COMPLEX64:
+          error(EXIT_FAILURE, 0, "%s: %s type not yet supported",
+                __func__, gal_type_name(input->type, 1));
+
+        /* Bad input. */
+        default:
+          error(EXIT_FAILURE, 0, "%s: type value (%d) not recognized",
+                __func__, input->type);
+        }
+
+      /* Write the values into the output. For the maximum ranges, we are
+         adding by one so the callers can simply calculate the number of
+         pixels by subtracting the two (since counting starts from 0). */
+      for(i=0;i<ndim;++i) { out[i*2]=min[i]; out[i*2+1]=max[i]+1; }
+    }
+
+  /* Input had no blanks, just fill the output using the size of the
+     input. */
+  else for(i=0;i<ndim;++i) { out[i*2]=0; out[i*2+1]=input->dsize[i]; }
+
+  /* For a check:
+  for(i=0;i<ndim;++i)
+    printf("%s:%zu: %zu:%zu\n", __func__, i, out[i*2], out[i*2+1]);
+  printf("%s: GOOD\n", __func__); exit(0);
+  */
+
+  /* Clean up and return. */
+  free(min);
+  free(max);
+  return out;
+}
+
+
+
+
+
+/* Trim all NaN-valued rows (in 1D) or columns/rows (in 2D). If 'inplace'
+   is non-zero, no new array will be allocated. */
+gal_data_t *
+gal_blank_trim(gal_data_t *input, int inplace)
+{
+  int coversall=1;
+  void *to, *from;
+  gal_data_t *out=NULL;
+  struct wcsprm *owcs=NULL;
+  size_t *odsize, *idsize, *mmc;
+  size_t i, j, cbytes, osize, opsize, ipsize, ndim;
+
+  /* Sanity checks. */
+  if(input==NULL) error(EXIT_FAILURE, 0, "%s: input is NULL", __func__);
+  ndim=input->ndim;
+  if(ndim>3)
+    error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at '%s' to "
+          "fix the problem. This function is currently not implemented "
+          "for %zu-dimensional inputs", __func__, PACKAGE_BUGREPORT,
+          ndim);
+
+  /* Find the smallest/largest coordinates containing the  */
+  mmc=gal_blank_not_minmax_coords(input);
+
+  /* In case the extrema cover the full image, then just return the input
+     (no trimming necessary!). We first assume that that 'coversall' is
+     true (1). We then parse over the dimensions and check the minimum and
+     maximum and multiply the result of the check (0 or 1) to
+     'coversall'. As a result, if a single dimesion doesn't cover the full
+     range, 'coversall' will be zero.*/
+  for(i=0;i<ndim;++i)
+    coversall *= mmc[i*2]==0 && mmc[i*2+1]==input->dsize[i];
+  if(coversall) return input;
+
+  /* Triming is necessary, so prepare the output. If the input can be
+     freed, then we'll just use its already allocated space. Otherwise,
+     we'll allocate a new dataset. */
+  odsize=gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 0, __func__,
+                              "odsize");
+  for(i=0;i<ndim;++i) odsize[i]=mmc[i*2+1]-mmc[i*2];
+  if(inplace) out=input;
+  else
+    {
+      owcs=gal_wcs_copy(input->wcs);
+      out=gal_data_alloc(NULL, input->type, input->ndim, odsize, owcs,
+                         0, input->minmapsize, input->quietmmap, NULL,
+                         NULL, NULL);
+    }
+
+  /* Copy (along the fastest dimension). */
+  idsize=input->dsize;
+  cbytes = odsize[ndim-1] * gal_type_sizeof(input->type);
+  switch(ndim)
+    {
+    /* 1D data. */
+    case 1:
+      to=out->array;
+      from=gal_pointer_increment(input->array, mmc[0], input->type);
+      if(inplace) memmove(to, from, cbytes); /* Overlap is possible. */
+      else        memcpy(to, from, cbytes); /* Overlap not possible. */
+      break;
+
+    /* 2D data. */
+    case 2:
+      for(i=mmc[0]; i<mmc[1]; ++i)
+        {
+          to=gal_pointer_increment(out->array, (i-mmc[0])*odsize[1],
+                                   out->type);
+          from=gal_pointer_increment(input->array,
+                                     i*idsize[1]+mmc[2],
+                                     input->type);
+          if(inplace) memmove(to, from, cbytes); /* Overlap is possible. */
+          else        memcpy(to, from, cbytes); /* Overlap not possible. */
+        }
+      break;
+
+    /* 3D data. */
+    case 3:
+      opsize=odsize[1]*odsize[2]; /* These are "plane"-sizes: number of */
+      ipsize=idsize[1]*idsize[2]; /* elements to change the slowest dim. */
+      for(i=mmc[0]; i<mmc[1]; ++i)
+        for(j=mmc[2]; j<mmc[3]; ++j)
+          {
+            to=gal_pointer_increment(out->array,
+                                     (i-mmc[0])*opsize+(j-mmc[2])*odsize[2],
+                                     out->type);
+            from=gal_pointer_increment(input->array,
+                                       i*ipsize+j*idsize[2]+mmc[4],
+                                       input->type);
+            if(inplace) memmove(to, from, cbytes); /* Overlap is possible. */
+            else        memcpy(to, from, cbytes); /* Overlap not possible. */
+          }
+      break;
+
+    /* Other dimensions. */
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at '%s' to "
+            "find and fix it. This function does not support "
+            "%zu-dimensional inputs", __func__, PACKAGE_BUGREPORT, ndim);
+    }
+
+  /* Correct the dimensionality of the output (only relevant when the
+     output is not "in-place"). */
+  osize=1;
+  if(inplace)
+    {
+      for(i=0;i<ndim;++i) osize *= (out->dsize[i]=odsize[i]);
+      out->size=osize;
+    }
+
+  /* Correct the WCS of the output (if it has any!). Recall that in WCSLIB,
+     the coordinates are in FITS order, not C order.*/
+  if(out->wcs) for(i=0;i<ndim;++i) out->wcs->crpix[ndim-1-i] -= mmc[i*2];
+
+  /* Clean up and return the output. */
+  free(mmc);
+  free(odsize);
+  return out;
+}
+
+
+
 
 
 /* Write a blank value in the input anywhere that the flag dataset is not
diff --git a/lib/gnuastro/arithmetic.h b/lib/gnuastro/arithmetic.h
index ec5be066..9b7af3ad 100644
--- a/lib/gnuastro/arithmetic.h
+++ b/lib/gnuastro/arithmetic.h
@@ -197,6 +197,7 @@ enum gal_arithmetic_operators
 
   GAL_ARITHMETIC_OP_STITCH,       /* Stitch multiple datasets together.    */
   GAL_ARITHMETIC_OP_TO1D,         /* Make they output into a 1D array.     */
+  GAL_ARITHMETIC_OP_TRIM,         /* Trim blank rows or columns in image.  */
 
   GAL_ARITHMETIC_OP_TO_UINT8,     /* Convert to uint8_t.                   */
   GAL_ARITHMETIC_OP_TO_INT8,      /* Convert to int8_t.                    */
diff --git a/lib/gnuastro/blank.h b/lib/gnuastro/blank.h
index 89207264..07265de2 100644
--- a/lib/gnuastro/blank.h
+++ b/lib/gnuastro/blank.h
@@ -131,6 +131,12 @@ gal_blank_flag(gal_data_t *data);
 gal_data_t *
 gal_blank_flag_not(gal_data_t *input);
 
+size_t *
+gal_blank_not_minmax_coords(gal_data_t *input);
+
+gal_data_t *
+gal_blank_trim(gal_data_t *input, int inplace);
+
 void
 gal_blank_flag_apply(gal_data_t *input, gal_data_t *flag);
 



reply via email to

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