gnuastro (0.22)

(root)/
share/
info/
gnuastro.info-9
This is gnuastro.info, produced by makeinfo version 7.1 from
gnuastro.texi.

This book documents version 0.22 of the GNU Astronomy Utilities
(Gnuastro).  Gnuastro provides various programs and libraries for
astronomical data manipulation and analysis.

   Copyright © 2015-2024 Free Software Foundation, Inc.

     Permission is granted to copy, distribute and/or modify this
     document under the terms of the GNU Free Documentation License,
     Version 1.3 or any later version published by the Free Software
     Foundation; with no Invariant Sections, no Front-Cover Texts, and
     no Back-Cover Texts.  A copy of the license is included in the
     section entitled "GNU Free Documentation License".
INFO-DIR-SECTION Astronomy
START-INFO-DIR-ENTRY
* Gnuastro: (gnuastro).       GNU Astronomy Utilities.
* libgnuastro: (gnuastro)Gnuastro library. Full Gnuastro library doc.

* help-gnuastro: (gnuastro)help-gnuastro mailing list. Getting help.

* bug-gnuastro: (gnuastro)Report a bug. How to report bugs

* Arithmetic: (gnuastro)Arithmetic. Arithmetic operations on pixels.
* astarithmetic: (gnuastro)Invoking astarithmetic. Options to Arithmetic.

* BuildProgram: (gnuastro)BuildProgram. Compile and run programs using Gnuastro's library.
* astbuildprog: (gnuastro)Invoking astbuildprog. Options to BuildProgram.

* ConvertType: (gnuastro)ConvertType. Convert different file types.
* astconvertt: (gnuastro)Invoking astconvertt. Options to ConvertType.

* Convolve: (gnuastro)Convolve. Convolve an input file with kernel.
* astconvolve: (gnuastro)Invoking astconvolve. Options to Convolve.

* CosmicCalculator: (gnuastro)CosmicCalculator. For cosmological params.
* astcosmiccal: (gnuastro)Invoking astcosmiccal. Options to CosmicCalculator.

* Crop: (gnuastro)Crop. Crop region(s) from image(s).
* astcrop: (gnuastro)Invoking astcrop. Options to Crop.

* Fits: (gnuastro)Fits. View and manipulate FITS extensions and keywords.
* astfits: (gnuastro)Invoking astfits. Options to Fits.

* MakeCatalog: (gnuastro)MakeCatalog. Make a catalog from labeled image.
* astmkcatalog: (gnuastro)Invoking astmkcatalog. Options to MakeCatalog.

* MakeProfiles: (gnuastro)MakeProfiles. Make mock profiles.
* astmkprof: (gnuastro)Invoking astmkprof. Options to MakeProfiles.

* Match: (gnuastro)Match. Match two separate catalogs.
* astmatch: (gnuastro)Invoking astmatch. Options to Match.

* NoiseChisel: (gnuastro)NoiseChisel. Detect signal in noise.
* astnoisechisel: (gnuastro)Invoking astnoisechisel. Options to NoiseChisel.

* Segment: (gnuastro)Segment. Segment detections based on signal structure.
* astsegment: (gnuastro)Invoking astsegment. Options to Segment.

* Query: (gnuastro)Query. Access remote databases for downloading data.
* astquery: (gnuastro)Invoking astquery. Options to Query.

* Statistics: (gnuastro)Statistics. Get image Statistics.
* aststatistics: (gnuastro)Invoking aststatistics. Options to Statistics.

* Table: (gnuastro)Table. Read and write FITS binary or ASCII tables.
* asttable: (gnuastro)Invoking asttable. Options to Table.

* Warp: (gnuastro)Warp. Warp a dataset to a new grid.
* astwarp: (gnuastro)Invoking astwarp. Options to Warp.

* astscript: (gnuastro)Installed scripts. Gnuastro's installed scripts.
* astscript-ds9-region: (gnuastro)Invoking astscript-ds9-region. Options to this script
* astscript-fits-view: (gnuastro)Invoking astscript-fits-view. Options to this script
* astscript-pointing-simulate: (gnuastro)Invoking astscript-pointing-simulate. Options to this script
* astscript-psf-scale-factor: (gnuastro)Invoking astscript-psf-scale-factor. Options to this script
* astscript-psf-select-stars: (gnuastro)Invoking astscript-psf-select-stars. Options to this script
* astscript-psf-stamp: (gnuastro)Invoking astscript-psf-stamp. Options to this script
* astscript-psf-subtract: (gnuastro)Invoking astscript-psf-subtract. Options to this script
* astscript-psf-unite: (gnuastro)Invoking astscript-psf-unite. Options to this script
* astscript-radial-profile: (gnuastro)Invoking astscript-radial-profile. Options to this script
* astscript-sort-by-night: (gnuastro)Invoking astscript-sort-by-night. Options to this script
* astscript-zeropoint: (gnuastro)Invoking astscript-zeropoint. Options to this script
END-INFO-DIR-ENTRY


File: gnuastro.info,  Node: Library data container,  Next: Dimensions,  Prev: Library blank values,  Up: Gnuastro library

12.3.6 Data container (‘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 *note 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 ‘gal_data_t’ as input or output.

* Menu:

* Generic data container::      Definition of Gnuastro's generic container.
* Dataset allocation::          Allocate, initialize and free a dataset.
* Arrays of datasets::          Functions to help with array of datasets.
* Copying datasets::            Functions to copy a dataset to a new one.


File: gnuastro.info,  Node: Generic data container,  Next: Dataset allocation,  Prev: Library data container,  Up: Library data container

12.3.6.1 Generic data container (‘gal_data_t’)
..............................................

To be able to deal with any dataset (various dimensions, numeric data
types, units and higher-level structures), Gnuastro defines the
‘gal_data_t’ type which is the input/output container of choice for many
of Gnuastro library's functions.  It is defined in ‘gnuastro/data.h’.
If you will be using ('‘# include’'ing) those libraries, you do not need
to include this header explicitly, it is already included by any library
header that uses ‘gal_data_t’.

 -- Type (C struct): gal_data_t
     The main container for datasets in Gnuastro.  It can host data of
     any dimensions, with any numeric data type.  It is actually a
     structure, but ‘typedef’'d as a new type to avoid having to write
     the ‘struct’ before any declaration.  The actual structure is shown
     below which is followed by a description of each element.

          typedef struct gal_data_t
          {
            void     *restrict array;  /* Basic array information.   */
            uint8_t             type;
            size_t              ndim;
            size_t            *dsize;
            size_t              size;
            int            quietmmap;
            char           *mmapname;
            size_t        minmapsize;

            int                 nwcs;  /* WCS information.           */
            struct wcsprm       *wcs;

            uint8_t             flag;  /* Content description.       */
            int               status;
            char               *name;
            char               *unit;
            char            *comment;

            int             disp_fmt;  /* For text printing.         */
            int           disp_width;
            int       disp_precision;

            struct gal_data_t  *next;  /* For higher-level datasets. */
            struct gal_data_t *block;
          } gal_data_t;

The list below contains a description for each ‘gal_data_t’ element.

‘void *restrict array’
     This is the pointer to the main array of the dataset containing the
     raw data (values).  All the other elements in this data-structure
     are actually meta-data enabling us to use/understand the series of
     values in this array.  It must allow data of any type (see *note
     Numeric data types::), so it is defined as a ‘void *’ pointer.  A
     ‘void *’ array is not directly usable in C, so you have to cast it
     to proper type before using it, please see *note Library demo -
     reading a image:: for a demonstration.

     The ‘restrict’ keyword was formally introduced in C99 and is used
     to tell the compiler that at any moment only this pointer will
     modify what it points to (a pixel in an image for example)(1).
     This extra piece of information can greatly help in compiler
     optimizations and thus the running time of the program.  But older
     compilers might not have this capability, so at ‘./configure’ time,
     Gnuastro checks this feature and if the user's compiler does not
     support ‘restrict’, it will be removed from this definition.

‘uint8_t type’
     A fixed code (integer) used to identify the type of data in ‘array’
     (see *note Numeric data types::).  For the list of acceptable
     values to this variable, please see *note Library data types::.

‘size_t ndim’
     The dataset's number of dimensions.

‘size_t *dsize’
     The size of the dataset along each dimension.  This is an array
     (with ‘ndim’ elements), of positive integers in row-major order(2)
     (based on C). When a data file is read into memory with Gnuastro's
     libraries, this array is dynamically allocated based on the number
     of dimensions that the dataset has.

     It is important to remember that C's row-major ordering is the
     opposite of the FITS standard which is in column-major order: in
     the FITS standard the fastest dimension's size is specified by
     ‘NAXIS1’, and slower dimensions follow.  The FITS standard was
     defined mainly based on the FORTRAN language which is the opposite
     of C's approach to multi-dimensional arrays (and also starts
     counting from 1 not 0).  Hence if a FITS image has ‘NAXIS1==20’ and
     ‘NAXIS2==50’, the ‘dsize’ array must be filled with ‘dsize[0]==50’
     and ‘dsize[1]==20’.

     The fastest dimension is the one that is contiguous in memory: to
     increment by one along that dimension, just go to the next element
     in the array.  As we go to slower dimensions, the number of memory
     cells we have to skip for an increment along that dimension becomes
     larger.

‘size_t size’
     The total number of elements in the dataset.  This is actually a
     multiplication of all the values in the ‘dsize’ array, so it is not
     an independent parameter.  However, low-level operations with the
     dataset (irrespective of its dimensions) commonly need this number,
     so this element is designed to avoid calculating it every time.

‘int quietmmap’
     When this value is zero, and the dataset must not be allocated in
     RAM (see ‘mmapname’ and ‘minmapsize’ below), a warning will be
     printed to inform the user when the file is created and when it is
     deleted.  The warning includes the filename, the size in bytes, and
     the fact that they can toggle this behavior through ‘--minmapsize’
     option in Gnuastro's programs.

‘char *mmapname’
     Name of file hosting the ‘mmap’'d contents of ‘array’.  If the
     value of this variable is ‘NULL’, then the contents of ‘array’ are
     actually stored in RAM, not in a file on the HDD/SSD. See the
     description of ‘minmapsize’ below for more.

     If a file is used, it will be kept in the ‘gnuastro_mmap’ directory
     of the running directory.  Its name is randomly selected to allow
     multiple arrays at the same time, see description of ‘--minmapsize’
     in *note Processing options::.  When ‘gal_data_free’ is called the
     randomly named file will be deleted.

‘size_t minmapsize’
     The minimum size of an array (in bytes) to store the contents of
     ‘array’ as a file (on the non-volatile HDD/SSD), not in RAM. This
     can be very useful for large datasets which can be very memory
     intensive and the user's RAM might not be sufficient to
     keep/process it.  A random filename is assigned to the array which
     is available in the ‘mmapname’ element of ‘gal_data_t’ (above), see
     there for more.  ‘minmapsize’ is stored in each ‘gal_data_t’, so it
     can be passed on to subsequent/derived datasets.

     See the description of the ‘--minmapsize’ option in *note
     Processing options:: for more on using this value.

‘nwcs’
     The number of WCS coordinate representations (for WCSLIB).

‘struct wcsprm *wcs’
     The main WCSLIB structure keeping all the relevant information
     necessary for WCSLIB to do its processing and convert data-set
     positions into real-world positions.  When it is given a ‘NULL’
     value, all possible WCS calculations/measurements will be ignored.

‘uint8_t flag’
     Bit-wise flags to describe general properties of the dataset.  The
     number of bytes available in this flag is stored in the
     ‘GAL_DATA_FLAG_SIZE’ macro.  Note that you should use bit-wise
     operators(3) to check these flags.  The currently recognized bits
     are stored in these macros:

     ‘GAL_DATA_FLAG_BLANK_CH’
          Marking that the dataset has been checked for blank values or
          not.  When a dataset does not have any blank values, the
          ‘GAL_DATA_FLAG_HASBLANK’ bit will be zero.  But upon
          initialization, all bits also get a value of zero.  Therefore,
          a checker needs this flag to see if the value in
          ‘GAL_DATA_FLAG_HASBLANK’ is reliable (dataset has actually
          been parsed for a blank value) or not.

          Also, if it is necessary to re-check the presence of flags,
          you just have to set this flag to zero and call
          ‘gal_blank_present’ for example, to parse the dataset and
          check for blank values.  Note that for improved efficiency,
          when this flag is set, ‘gal_blank_present’ will not actually
          parse the dataset, it will just use ‘GAL_DATA_FLAG_HASBLANK’.

     ‘GAL_DATA_FLAG_HASBLANK’
          This bit has a value of ‘1’ when the given dataset has blank
          values.  If this bit is ‘0’ and ‘GAL_DATA_FLAG_BLANK_CH’ is
          ‘1’, then the dataset has been checked and it did not have any
          blank values, so there is no more need for further checks.

     ‘GAL_DATA_FLAG_SORT_CH’
          Marking that the dataset is already checked for being sorted
          or not and thus that the possible ‘0’ values in
          ‘GAL_DATA_FLAG_SORTED_I’ and ‘GAL_DATA_FLAG_SORTED_D’ are
          meaningful.  The logic behind this is similar to that in
          ‘GAL_DATA_FLAG_BLANK_CH’.

     ‘GAL_DATA_FLAG_SORTED_I’
          This bit has a value of ‘1’ when the given dataset is sorted
          in an increasing manner.  If this bit is ‘0’ and
          ‘GAL_DATA_FLAG_SORT_CH’ is ‘1’, then the dataset has been
          checked and was not sorted (increasing), so there is no more
          need for further checks.

     ‘GAL_DATA_FLAG_SORTED_D’
          This bit has a value of ‘1’ when the given dataset is sorted
          in a decreasing manner.  If this bit is ‘0’ and
          ‘GAL_DATA_FLAG_SORT_CH’ is ‘1’, then the dataset has been
          checked and was not sorted (decreasing), so there is no more
          need for further checks.

     The macro ‘GAL_DATA_FLAG_MAXFLAG’ contains the largest internally
     used bit-position.  Higher-level flags can be defined with the
     bit-wise shift operators using this macro to define internal flags
     for libraries/programs that depend on Gnuastro without causing any
     possible conflict with the internal flags discussed above or having
     to check the values manually on every release.

‘int status’
     A context-specific status values for this data-structure.  This
     integer will not be set by Gnuastro's libraries.  You can use it
     keep some additional information about the dataset (with integer
     constants) depending on your applications.

‘char *name’
     The name of the dataset.  If the dataset is a multi-dimensional
     array and read/written as a FITS image, this will be the value in
     the ‘EXTNAME’ FITS keyword.  If the dataset is a one-dimensional
     table column, this will be the column name.  If it is set to ‘NULL’
     (by default), it will be ignored.

‘char *unit’
     The units of the dataset (for example, ‘BUNIT’ in the standard FITS
     keywords) that will be read from or written to files/tables along
     with the dataset.  If it is set to ‘NULL’ (by default), it will be
     ignored.

‘char *comment’
     Any further explanation about the dataset which will be written to
     any output file if present.

‘disp_fmt’
     Format to use for printing each element of the dataset to a plain
     text file, the acceptable values to this element are defined in
     *note Table input output::.  Based on C's ‘printf’ standards.

‘disp_width’
     Width of printing each element of the dataset to a plain text file,
     the acceptable values to this element are defined in *note Table
     input output::.  Based on C's ‘printf’ standards.

‘disp_precision’
     Precision of printing each element of the dataset to a plain text
     file, the acceptable values to this element are defined in *note
     Table input output::.  Based on C's ‘printf’ standards.

‘gal_data_t *next’
     Through this pointer, you can link a ‘gal_data_t’ with other
     datasets related datasets, for example, the different columns in a
     dataset each have one ‘gal_data_t’ associate with them and they are
     linked to each other using this element.  There are several
     functions described below to facilitate using ‘gal_data_t’ as a
     linked list.  See *note Linked lists:: for more on these wonderful
     high-level constructs.

‘gal_data_t *block’
     Pointer to the start of the complete allocated block of memory.
     When this pointer is not ‘NULL’, the dataset is not treated as a
     contiguous patch of memory.  Rather, it is seen as covering only a
     portion of the larger patch of memory that ‘block’ points to.  See
     *note Tessellation library:: for a more thorough explanation and
     functions to help work with tiles that are created from this
     pointer.

   ---------- Footnotes ----------

   (1) Also see <https://en.wikipedia.org/wiki/Restrict>.

   (2) Also see
<https://en.wikipedia.org/wiki/Row-_and_column-major_order>.

   (3) See <https://en.wikipedia.org/wiki/Bitwise_operations_in_C>.


File: gnuastro.info,  Node: Dataset allocation,  Next: Arrays of datasets,  Prev: Generic data container,  Up: Library data container

12.3.6.2 Dataset allocation
...........................

Gnuastro's main data container was defined in *note Generic data
container::.  The functions listed in this section describe the most
basic operations on ‘gal_data_t’: those related to allocation and
freeing.  These functions are declared in ‘gnuastro/data.h’ which is
also visible from the function names (see *note Gnuastro library::).

 -- Function:
          gal_data_t *
          gal_data_alloc (void *array, uint8_t type, size_t ndim, size_t
          *dsize, struct wcsprm *wcs, int clear, size_t minmapsize, int
          quietmmap, char *name, char *unit, char *comment)

     Dynamically allocate a ‘gal_data_t’ and initialize it will all the
     given values.  See the description of ‘gal_data_initialize’ and
     *note Generic data container:: for more information.  This function
     will often be the most frequently used because it allocates the
     ‘gal_data_t’ hosting all the values _and_ initializes it.  Once you
     are done with the dataset, be sure to clean up all the allocated
     spaces with ‘gal_data_free’.

 -- Function:
          void
          gal_data_initialize (gal_data_t *data, void *array, uint8_t
          type, size_t ndim, size_t *dsize, struct wcsprm *wcs, int
          clear, size_t minmapsize, int quietmmap, char *name, char
          *unit, char *comment)

     Initialize the given data structure (‘data’) with all the given
     values.  Note that the raw input ‘gal_data_t’ must already have
     been allocated before calling this function.  For a description of
     each variable see *note Generic data container::.  It will set the
     values and do the necessary allocations.  If they are not ‘NULL’,
     all input arrays (‘dsize’, ‘wcs’, ‘name’, ‘unit’, ‘comment’) are
     separately copied (allocated) by this function for usage in ‘data’,
     so you can safely use one value to initialize many datasets or use
     statically allocated variables in this function call.  Once you are
     done with the dataset, you can free all the allocated spaces with
     ‘gal_data_free_contents’.

     If ‘array’ is not ‘NULL’, it will be directly copied into
     ‘data->array’ (based on the total number of elements calculated
     from ‘dsize’) and no new space will be allocated for the array of
     this dataset, this has many low-level advantages and can be used to
     work on regions of a dataset instead of the whole allocated array
     (see the description under ‘block’ in *note Generic data
     container:: for one example).  If the given pointer is not the
     start of an allocated block of memory or it is used in multiple
     datasets, be sure to set it to ‘NULL’ (with ‘data->array=NULL’)
     before cleaning up with ‘gal_data_free_contents’.

     ‘ndim’ may be zero.  In this case no allocation will occur,
     ‘data->array’ and ‘data->dsize’ will be set to ‘NULL’ and
     ‘data->size’ will be zero.  However (when necessary) ‘dsize’ must
     not have any zero values (a dimension of length zero is not
     defined).

 -- Function:
          gal_data_t *
          gal_data_alloc_empty (size_t ndim, size_t minmapsize, int
          quietmmap)
     Allocate an empty dataset with a certain number of dimensions, but
     no 'array' component.  The ‘size’ element will be set to zero and
     the ‘dsize’ array will be properly allocated (based on the number
     of dimensions), but all elements will be zero.  This is useful in
     scenarios where you just need a ‘gal_data_t’ for metadata.

 -- Function:
          void
          gal_data_free_contents (gal_data_t *data)
     Free all the non-‘NULL’ pointers in ‘gal_data_t’ except for ‘next’
     and ‘block’.  All freed arrays are set to ‘NULL’.  If ‘data’ is
     actually a tile (‘data->block!=NULL’, see *note Tessellation
     library::), then ‘data->array’ is not freed.  For a complete
     description of ‘gal_data_t’ and its contents, see *note Generic
     data container::.

 -- Function:
          void
          gal_data_free (gal_data_t *data)
     Free all the non-‘NULL’ pointers in ‘gal_data_t’, then free the
     actual data structure.


File: gnuastro.info,  Node: Arrays of datasets,  Next: Copying datasets,  Prev: Dataset allocation,  Up: Library data container

12.3.6.3 Arrays of datasets
...........................

Gnuastro's generic data container (‘gal_data_t’) is a very versatile
structure that can be used in many higher-level contexts.  One such
higher-level construct is an array of ‘gal_data_t’ structures to
simplify the allocation (and later cleaning) of several ‘gal_data_t’s
that are related.

   For example, each column in a table is usually represented by one
‘gal_data_t’ (so it has its own name, data type, units, etc.).  A table
(with many columns) can be seen as an array of ‘gal_data_t’s (when the
number of columns is known a-priori).  The functions below are defined
to create a cleared array of data structures and to free them when none
are necessary any more.  These functions are declared in
‘gnuastro/data.h’ which is also visible from the function names (see
*note Gnuastro library::).

 -- Function:
          gal_data_t *
          gal_data_array_calloc (size_t size)
     Allocate an array of ‘gal_data_t’ with ‘size’ elements.  This
     function will also initialize all the values (‘NULL’ for pointers
     and 0 for other types).  You can use ‘gal_data_initialize’ to fill
     each element of the array afterwards.  The following code snippet
     is one example of doing this.

          size_t i;
          gal_data_t *dataarr;
          dataarr=gal_data_array_calloc(10);
          for(i=0;i<10;++i) gal_data_initialize(&dataarr[i], ...);
          ...
          gal_data_array_free(dataarr, 10, 1);

 -- Function:
          void
          gal_data_array_free (gal_data_t *dataarr, size_t num, int
          free_array)
     Free all the ‘num’ elements within ‘dataarr’ and the actual
     allocated array.  If ‘free_array’ is not zero, then the ‘array’
     element of all the datasets will also be freed, see *note Generic
     data container::.

 -- Function:
          gal_data_t **
          gal_data_array_ptr_calloc (size_t size)
     Allocate an array of pointers to Gnuastro's generic data structure
     and initialize all pointers to ‘NULL’.  This is useful when you
     want to allocate individual datasets later (for example, with
     ‘gal_data_alloc’).

 -- Function:
          void
          gal_data_array_ptr_free (gal_data_t **dataptr, size_t size,
          int free_array);
     Free all the individual datasets within the elements of ‘dataptr’,
     then free ‘dataptr’ itself (the array of pointers that was probably
     allocated with ‘gal_data_array_ptr_calloc’.


File: gnuastro.info,  Node: Copying datasets,  Prev: Arrays of datasets,  Up: Library data container

12.3.6.4 Copying datasets
.........................

The functions in this section describes Gnuastro's facilities to copy a
given dataset into another.  The new dataset can have a different type
(including a string), it can be already allocated (in which case only
the values will be written into it).  In all these cases, if the input
dataset is a tile or a list, only the data within the given tile, or the
given node in a list, are copied.  If the input is a list, the ‘next’
pointer will also be copied to the output, see *note List of
gal_data_t::.

   In many of the functions here, it is possible to copy the dataset to
a new numeric data type (see *note Numeric data types::.  In such cases,
Gnuastro's library is going to use the native conversion by C. So if you
are converting to a smaller type, it is up to you to make sure that the
values fit into the output type.

 -- Function:
          gal_data_t *
          gal_data_copy (gal_data_t *in)
     Return a new dataset that is a copy of ‘in’, all of ‘in’'s
     meta-data will also copied into the output, except for ‘block’.  If
     the dataset is a tile/list, only the given tile/node will be
     copied, the ‘next’ pointer will also be copied however.

 -- Function:
          gal_data_t *
          gal_data_copy_to_new_type (gal_data_t *in, uint8_t newtype)
     Return a copy of the dataset ‘in’, converted to ‘newtype’, see
     *note Library data types:: for Gnuastro library's type identifiers.
     The returned dataset will have all meta-data except their type and
     ‘block’ equal to the input's metadata.  If the dataset is a
     tile/list, only the given tile/node will be copied, the ‘next’
     pointer will also be copied however.

 -- Function:
          gal_data_t *
          gal_data_copy_to_new_type_free (gal_data_t *in, uint8_t
          newtype)
     Return a copy of the dataset ‘in’ that is converted to ‘newtype’
     and free the input dataset.  See *note Library data types:: for
     Gnuastro library's type identifiers.  The returned dataset will
     have all meta-data, except their type, equal to the input's
     metadata (including ‘next’).  Note that if the input is a tile
     within a larger block, it will not be freed.  This function is
     similar to ‘gal_data_copy_to_new_type’, except that it will free
     the input dataset.

 -- Function:
          void
          gal_data_copy_to_allocated (gal_data_t *in, gal_data_t *out)
     Copy the contents of the array in ‘in’ into the already allocated
     array in ‘out’.  The types of the input and output may be
     different, type conversion will be done internally.  When ‘in->size
     != out->size’ this function will behave as follows:

     ‘out->size < in->size’
          This function will not re-allocate the necessary space, it
          will abort with an error, so please check before calling this
          function.

     ‘out->size > in->size’
          This function will write the values in ‘out->size’ and
          ‘out->dsize’ from the same values of ‘in’.  So if you want to
          use a pre-allocated space/dataset multiple times with varying
          input sizes, be sure to reset ‘out->size’ before every call to
          this function.

 -- Function:
          gal_data_t *
          gal_data_copy_string_to_number (char *string)
     Read ‘string’ into the smallest type that can store the value (see
     *note Numeric data types::).  This function is just a wrapper for
     the ‘gal_type_string_to_number’, but will put the value into a
     single-element dataset.


File: gnuastro.info,  Node: Dimensions,  Next: Linked lists,  Prev: Library data container,  Up: Gnuastro library

12.3.7 Dimensions (‘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 _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 _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 issues for example, issues with the neighbors of an element in a
multi-dimensional context.

 -- Function:
          size_t
          gal_dimension_total_size (size_t ndim, size_t *dsize)
     Return the total number of elements for a dataset with ‘ndim’
     dimensions that has ‘dsize’ elements along each dimension.

 -- Function:
          int
          gal_dimension_is_different (gal_data_t *first, gal_data_t
          *second)
     Return ‘1’ (one) if the two datasets do not have the same size
     along all dimensions.  This function will also return ‘1’ when the
     number of dimensions of the two datasets are different.

 -- Function:
          size_t *
          gal_dimension_increment (size_t ndim, size_t *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 ‘dsize’ and returned
     arrays), the value is ‘1’ (one).

 -- Function:
          size_t
          gal_dimension_num_neighbors (size_t ndim)
     The maximum number of neighbors (any connectivity) that a data
     element can have in ‘ndim’ dimensions.  Effectively, this function
     just returns $3^n-1$ (where $n$ is the number of dimensions).

 -- Function-like macro: GAL_DIMENSION_FLT_TO_INT (FLT)
     Calculate the integer pixel position that the floating point ‘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.

 -- Function:
          void
          gal_dimension_add_coords (size_t *c1, size_t *c2, size_t *out,
          size_t ndim)
     For every dimension, add the coordinates in ‘c1’ with ‘c2’ and put
     the result into ‘out’.  In other words, for dimension ‘i’ run
     ‘out[i]=c1[i]+c2[i];’.  Hence ‘out’ may be equal to any one of ‘c1’
     or ‘c2’.

 -- Function:
          size_t
          gal_dimension_coord_to_index (size_t ndim, size_t *dsize,
          size_t *coord)
     Return the index (counting from zero) from the coordinates in
     ‘coord’ (counting from zero) assuming the dataset has ‘ndim’
     elements and the size of the dataset along each dimension is in the
     ‘dsize’ array.

 -- Function:
          void
          gal_dimension_index_to_coord (size_t index, size_t ndim,
          size_t *dsize, size_t *coord)
     Fill in the ‘coord’ array with the coordinates that correspond to
     ‘index’ assuming the dataset has ‘ndim’ elements and the size of
     the dataset along each dimension is in the ‘dsize’ array.  Note
     that both ‘index’ and each value in ‘coord’ are assumed to start
     from ‘0’ (zero).  Also that the space which ‘coord’ points to must
     already be allocated before calling this function.

 -- Function:
          size_t
          gal_dimension_dist_manhattan (size_t *a, size_t *b, size_t
          ndim)
     Return the manhattan distance (see Wikipedia
     (https://en.wikipedia.org/wiki/Taxicab_geometry)) between the two
     coordinates ‘a’ and ‘b’ (each an array of ‘ndim’ elements).

 -- Function:
          float
          gal_dimension_dist_radial (size_t *a, size_t *b, size_t ndim)
     Return the radial distance between the two coordinates ‘a’ and ‘b’
     (each an array of ‘ndim’ elements).

 -- Function:
          float
          gal_dimension_dist_elliptical (double *center, double *pa_deg,
          double *q, size_t ndim, double *point)
     Return the elliptical/ellipsoidal distance of the single point
     ‘point’ (containing ‘ndim’ values: coordinates of the point in each
     dimension) from an ellipse that is defined by ‘center’, ‘pa_deg’
     and ‘q’.  ‘center’ is the coordinates of the ellipse center (also
     with ‘ndim’ elements).  ‘pa’ is the position-angle in degrees (the
     angle of the semi-major axis from the first dimension in a 2D
     ellipse) and ‘q’ is the axis ratio.

     In a 2D ellipse, ‘pa’ and ‘q’ are a single-element array.  However,
     in a 3D ellipsoid, ‘pa’ must have three elements, and ‘q’ must have
     2 elements.  For more see *note Defining an ellipse and
     ellipsoid::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sum (gal_data_t *in, size_t c_dim,
          gal_data_t *weight)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by summing all elements in that direction.  If
     ‘weight!=NULL’, it must be a single-dimensional array, with the
     same size as the dimension to be collapsed.  The respective weight
     will be multiplied to each element during the collapse.

     For generality, the returned dataset will have a ‘GAL_TYPE_FLOAT64’
     type.  See *note Copying datasets:: for converting the returned
     dataset to a desired type.  Also, for more on the application of
     this function, see the Arithmetic program's ‘collapse-sum’ operator
     (which uses this function) in *note Arithmetic operators::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mean (gal_data_t *in, size_t c_dim,
          gal_data_t *weight)
     Similar to ‘gal_dimension_collapse_sum’ (above), but the collapse
     will be done by calculating the mean along the requested dimension,
     not summing over it.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_number (gal_data_t *in, size_t c_dim)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by counting how many non-blank elements there are along
     that dimension.

     For generality, the returned dataset will have a ‘GAL_TYPE_INT32’
     type.  See *note Copying datasets:: for converting the returned
     dataset to a desired type.  Also, for more on the application of
     this function, see the Arithmetic program's ‘collapse-number’
     operator (which uses this function) in *note Arithmetic
     operators::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_minmax (gal_data_t *in, size_t c_dim,
          int max1_min0)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by using the largest/smallest non-blank value along
     that dimension.  If ‘max1_min0’ is non-zero, then the collapsed
     dataset will have the maximum value along the given dimension and
     if it is zero, the minimum.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_median (gal_data_t *in, size_t c_dim,
          size_t numthreads, size_t minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the median non-blank value along that
     dimension.  Since the median involves sorting, this operator
     benefits from many threads (which needs to be set with
     ‘numthreads’).  For more on ‘minmapsize’ and ‘quietmmap’ see *note
     Memory management::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_std (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the standard deviation of pixels along that
     dimension after sigma-clipping.  Since sigma-clipping involves
     sorting, this operator benefits from many threads (which needs to
     be set with ‘numthreads’).  For more on ‘minmapsize’ and
     ‘quietmmap’ see *note Memory management::.  For more on sigma
     clipping, see *note Sigma clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_fill_std (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_sclip_std’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_mad (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the median absolute deviation (MAD) of
     pixels along that dimension after sigma-clipping.  Since
     sigma-clipping involves sorting, this operator benefits from many
     threads (which needs to be set with ‘numthreads’).  For more on
     ‘minmapsize’ and ‘quietmmap’ see *note Memory management::.  For
     more on sigma clipping, see *note Sigma clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_fill_mad (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_sclip_mad’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_mean (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the mean of pixels along that dimension
     after sigma-clipping.  Since sigma-clipping involves sorting, this
     operator benefits from many threads (which needs to be set with
     ‘numthreads’).  For more on ‘minmapsize’ and ‘quietmmap’ see *note
     Memory management::.  For more on sigma clipping, see *note Sigma
     clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_fill_mean (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_sclip_mean’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_median (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the median of pixels along that dimension
     after sigma-clipping.  Since sigma-clipping involves sorting, this
     operator benefits from many threads (which needs to be set with
     ‘numthreads’).  For more on ‘minmapsize’ and ‘quietmmap’ see *note
     Memory management::.  For more on sigma clipping, see *note Sigma
     clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_fill_median (gal_data_t *in,
          size_t c_dim, float multip, float param, size_t numthreads,
          size_t minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_sclip_median’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_number (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the number of pixels along that dimension
     after sigma-clipping.  Since sigma-clipping involves sorting, this
     operator benefits from many threads (which needs to be set with
     ‘numthreads’).  For more on ‘minmapsize’ and ‘quietmmap’ see *note
     Memory management::.  For more on sigma clipping, see *note Sigma
     clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_sclip_fill_number (gal_data_t *in,
          size_t c_dim, float multip, float param, size_t numthreads,
          size_t minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_sclip_number’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_std (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the standard deviation of pixels along that
     dimension after median absolute deviation (MAD) clipping.  Since
     MAD-clipping involves sorting, this operator benefits from many
     threads (which needs to be set with ‘numthreads’).  For more on
     ‘minmapsize’ and ‘quietmmap’ see *note Memory management::.  For
     more on MAD-clipping, see *note MAD clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_fill_std (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_mclip_std’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_mad (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the median absolute deviation (MAD) of
     pixels along that dimension after median absolute deviation (MAD)
     clipping.  Since MAD-clipping involves sorting, this operator
     benefits from many threads (which needs to be set with
     ‘numthreads’).  For more on ‘minmapsize’ and ‘quietmmap’ see *note
     Memory management::.  For more on MAD-clipping, see *note MAD
     clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_fill_mad (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_mclip_mad’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_mean (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the mean of pixels along that dimension
     after median absolute deviation (MAD) clipping.  Since MAD-clipping
     involves sorting, this operator benefits from many threads (which
     needs to be set with ‘numthreads’).  For more on ‘minmapsize’ and
     ‘quietmmap’ see *note Memory management::.  For more on
     MAD-clipping, see *note MAD clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_fill_mean (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_mclip_mean’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_median (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the median of pixels along that dimension
     after median absolute deviation (MAD) clipping.  Since MAD-clipping
     involves sorting, this operator benefits from many threads (which
     needs to be set with ‘numthreads’).  For more on ‘minmapsize’ and
     ‘quietmmap’ see *note Memory management::.  For more on
     MAD-clipping, see *note MAD clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_fill_median (gal_data_t *in,
          size_t c_dim, float multip, float param, size_t numthreads,
          size_t minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_mclip_median’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_number (gal_data_t *in, size_t
          c_dim, float multip, float param, size_t numthreads, size_t
          minmapsize, int quietmmap)
     Collapse the input dataset (‘in’) along the given dimension
     (‘c_dim’, in C definition: starting from zero, from the slowest
     dimension), by finding the number of pixels along that dimension
     after median absolute deviation (MAD) clipping.  Since MAD-clipping
     involves sorting, this operator benefits from many threads (which
     needs to be set with ‘numthreads’).  For more on ‘minmapsize’ and
     ‘quietmmap’ see *note Memory management::.  For more on
     MAD-clipping, see *note MAD clipping::.

 -- Function:
          gal_data_t *
          gal_dimension_collapse_mclip_fill_number (gal_data_t *in,
          size_t c_dim, float multip, float param, size_t numthreads,
          size_t minmapsize, int quietmmap)
     Similar to ‘gal_dimension_collapse_mclip_number’, but with filled
     re-clipping (see *note Filled re-clipping::).

 -- Function:
          size_t
          gal_dimension_remove_extra (size_t ndim, size_t *dsize, struct
          wcsprm *wcs)
     Remove extra dimensions (those that only have a length of 1) from
     the basic size information of a dataset.  ‘ndim’ is the number of
     dimensions and ‘dsize’ is an array with ‘ndim’ elements containing
     the size along each dimension in the C dimension order.  When
     ‘wcs!=NULL’, the respective dimension will also be removed from the
     WCS.

     This function will return the new number of dimensions and the
     ‘dsize’ elements will contain the length along each new dimension.

 -- Function-like macro: GAL_DIMENSION_NEIGHBOR_OP (index, ndim, dsize,
          connectivity, dinc, operation)
     Parse the neighbors of the element located at ‘index’ and do the
     requested operation on them.  This is defined as a macro to allow
     easy definition of any operation on the neighbors of a given
     element without having to use loops within your source code (the
     loops are implemented by this macro).  For an example of using this
     function, please see *note Library demo - inspecting neighbors::.
     The input arguments to this function-like macro are described
     below:

     ‘index’
          Distance of this element from the first element in the array
          on a contiguous patch of memory (starting from 0), see the
          discussion above.
     ‘ndim’
          The number of dimensions associated with the contiguous patch
          of memory.
     ‘dsize’
          The full array size along each dimension.  This must be an
          array and is assumed to have the same number elements as
          ‘ndim’.  See the discussion under the same element in *note
          Generic data container::.
     ‘connectivity’
          Most distant neighbors to consider.  Depending on the number
          of dimensions, different neighbors may be defined for each
          element.  This function-like macro distinguish between these
          different neighbors with this argument.  It has a value
          between ‘1’ (one) and ‘ndim’.  For example, in a 2D dataset,
          4-connected neighbors have a connectivity of ‘1’ and
          8-connected neighbors have a connectivity of ‘2’.  Note that
          this is inclusive, so in this example, a connectivity of ‘2’
          will also include connectivity ‘1’ neighbors.
     ‘dinc’
          An array keeping the length necessary to increment along each
          dimension.  You can make this array with the following
          function.  Just do not forget to free the array after you are
          done with it:

               size_t *dinc=gal_dimension_increment(ndim, dsize);
               free(dinc);

          ‘dinc’ depends on ‘ndim’ and ‘dsize’, but it must be defined
          outside this function-like macro since it involves allocation
          to help in performance.

     ‘operation’
          Any C operation that you would like to do on the neighbor.
          This macro will provide you a ‘nind’ variable that can be used
          as the index of the neighbor that is currently being studied.
          It is defined as '‘size_t ndim;’'.  Note that ‘operation’ will
          be repeated the number of times there is a neighbor for this
          element.

     This macro works fully within its own ‘{}’ block and except for the
     ‘nind’ variable that shows the neighbor's index, all the variables
     within this macro's block start with ‘gdn_’.


File: gnuastro.info,  Node: Linked lists,  Next: Array input output,  Prev: Dimensions,  Up: Gnuastro library

12.3.8 Linked lists (‘list.h’)
------------------------------

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 _lists_ for short) are the data-container of choice in such
situations.  As in a chain, each _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 ‘next’ pointer
to add any number of elements to the list that we want.  By convention,
a list is terminated when ‘next’ is the ‘NULL’ pointer.

     struct list_float          /*     ---------    ---------           */
     {                          /*     | Value |    | Value |           */
       float             value; /*     |  ---  |    |  ---  |           */
       struct list_float *next; /*     |  next-|--> |  next-|--> NULL   */
     }                          /*     ---------    ---------           */

   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 ‘NULL’ pointer as shown below:

     struct list_float *list=NULL;

To add or remove/pop a node from the list you can use functions provided
for the respective type in the sections below.

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)(1).

   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.  Wikipedia (https://en.wikipedia.org/wiki/Linked_list) 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 ‘gnuastro/list.h’.

* Menu:

* List of strings::             Simply linked list of strings.
* List of int32_t::             Simply linked list of int32_ts.
* List of size_t::              Simply linked list of size_ts.
* List of float::               Simply linked list of floats.
* List of double::              Simply linked list of doubles
* List of void::                Simply linked list of void * pointers.
* Ordered list of size_t::      Simply linked, ordered list of size_t.
* Doubly linked ordered list of size_t::  Definition and functions.
* List of gal_data_t::          Simply linked list Gnuastro's generic datatype.

   ---------- Footnotes ----------

   (1) 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 ‘_reverse’ suffix for this job.


File: gnuastro.info,  Node: List of strings,  Next: List of int32_t,  Prev: Linked lists,  Up: Linked lists

12.3.8.1 List of strings
........................

Probably one of the most common lists you will be using are lists of
strings.  They are the best tools when you are reading the user's
inputs, or when adding comments to the output files.  Below you can see
Gnuastro's string list type and several functions to help in adding,
removing/popping, reversing and freeing the list.

 -- Type (C struct): gal_list_str_t
     A single node in a list containing a string of characters.
          typedef struct gal_list_str_t
          {
            char *v;
            struct gal_list_str_t *next;
          } gal_list_str_t;

 -- Function:
          void
          gal_list_str_add (gal_list_str_t **list, char *value, int
          allocate)
     Add a new node to the list of strings (‘list’) and update it.  The
     new node will contain the string ‘value’.  If ‘allocate’ is not
     zero, space will be allocated specifically for the string of the
     new node and the contents of ‘value’ will be copied into it.  This
     can be useful when your string may be changed later in the program,
     but you want your list to remain.  Here is one short/simple example
     of initializing and adding elements to a string list:

          gal_list_str_t *list=NULL;
          gal_list_str_add(&list, "bottom of list.", 1);
          gal_list_str_add(&list, "second last element of list.", 1);

 -- Function:
          char *
          gal_list_str_pop (gal_list_str_t **list)
     Pop the top element of ‘list’, change ‘list’ to point to the next
     node in the list, and return the string that was in the popped
     node.  If ‘*list==NULL’, then this function will also return a
     ‘NULL’ pointer.

 -- Function:
          size_t
          gal_list_str_number (gal_list_str_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          gal_list_str_t *
          gal_list_str_last (gal_list_str_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_str_print (gal_list_str_t *list)
     Print the strings within each node of ‘*list’ on the standard
     output in the same order that they are stored.  Each string 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.

          size_t i=0;
          gal_list_str_t *tmp;
          for(tmp=list; tmp!=NULL; tmp=tmp->next)
            printf("String %zu: %s\n", ++i, tmp->v);

 -- Function:
          void
          gal_list_str_reverse (gal_list_str_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          void
          gal_list_str_free (gal_list_str_t *list, int freevalue)
     Free every node in ‘list’.  If ‘freevalue’ is not zero, also free
     the string within the nodes.

 -- Function:
          gal_list_str_t *
          gal_list_str_extract (char *string)
     Extract space-separated components of the input string.  If any
     space element should be kept (and not considered as a delimiter
     between two tokens), precede it with a backslash (‘\’).  Be aware
     that in C programming, when including a backslash character within
     a string literal, the correct format is indeed to use two
     backslashes ("\\") to represent a single backslash:

          gal_list_str_extract("bottom of\\ list");

 -- Function:
          char *
          gal_list_str_cat (gal_list_str_t *list, char delimiter)
     Concatenate (append) the input list of strings into a single string
     where each node is separated from the next with the given
     ‘delimiter’.  The space for the output string is allocated by this
     function and should be freed when you have finished with it.

     If there is any delimiter characters are present in any of the
     elements, a backslash (‘\’) will be printed before the SPACE
     character.  This is necessary, otherwise, a function like
     ‘gal_list_str_extract’ will not be able to extract the elements
     back into separate elements in a list.


File: gnuastro.info,  Node: List of int32_t,  Next: List of size_t,  Prev: List of strings,  Up: Linked lists

12.3.8.2 List of ‘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 ‘enum’ for example).  On many
modern systems, ‘int32_t’ is just an alias for ‘int’, so you can use
them interchangeably.  To make sure, check the size of ‘int’ on your
system:

 -- Type (C struct): gal_list_i32_t
     A single node in a list containing a 32-bit signed integer (see
     *note Numeric data types::).
          typedef struct gal_list_i32_t
          {
            int32_t v;
            struct gal_list_i32_t *next;
          } gal_list_i32_t;

 -- Function:
          void
          gal_list_i32_add (gal_list_i32_t **list, int32_t value)
     Add a new node (containing ‘value’) to the top of the ‘list’ of
     ‘int32_t’s (‘uint32_t’ is equal to ‘int’ on many modern systems),
     and update ‘list’.  Here is one short example of initializing and
     adding elements to a string list:

          gal_list_i32_t *list=NULL;
          gal_list_i32_add(&list, 52);
          gal_list_i32_add(&list, -4);

 -- Function:
          int32_t
          gal_list_i32_pop (gal_list_i32_t **list)
     Pop the top element of ‘list’ and return the value.  This function
     will also change ‘list’ to point to the next node in the list.  If
     ‘*list==NULL’, then this function will also return
     ‘GAL_BLANK_INT32’ (see *note Library blank values::).

 -- Function:
          size_t
          gal_list_i32_number (gal_list_i32_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          size_t
          gal_list_i32_last (gal_list_i32_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_i32_print (gal_list_i32_t *list)
     Print the integers within each node of ‘*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.

          size_t i=0;
          gal_list_i32_t *tmp;
          for(tmp=list; tmp!=NULL; tmp=tmp->next)
            printf("Number %zu: %s\n", ++i, tmp->v);

 -- Function:
          void
          gal_list_i32_reverse (gal_list_i32_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          int32_t *
          gal_list_i32_to_array (gal_list_i32_t *list, int reverse,
          size_t *num)
     Dynamically allocate an array and fill it with the values in
     ‘list’.  The function will return a pointer to the allocated array
     and put the number of elements in the array into the ‘num’ pointer.
     If ‘reverse’ has a non-zero value, the array will be filled in the
     opposite order of elements in ‘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.

 -- Function:
          void
          gal_list_i32_free (gal_list_i32_t *list)
     Free every node in ‘list’.


File: gnuastro.info,  Node: List of size_t,  Next: List of float,  Prev: List of int32_t,  Up: Linked lists

12.3.8.3 List of ‘size_t’
.........................

The ‘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 ‘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 ‘uint32_t’ and ‘uint64_t’,
respectively (see *note Numeric data types::).

   ‘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 _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(1).  In Gnuastro, we do all
counting and array indexing with this type, so this list is very handy.
As discussed above, ‘size_t’ maps to different types on different
machines, so a portable way to print them with ‘printf’ is to use C99's
‘%zu’ format.

 -- Type (C struct): gal_list_sizet_t
     A single node in a list containing a ‘size_t’ value (which maps to
     ‘uint32_t’ or ‘uint64_t’ on 32-bit and 64-bit systems), see *note
     Numeric data types::.
          typedef struct gal_list_sizet_t
          {
            size_t v;
            struct gal_list_sizet_t *next;
          } gal_list_sizet_t;

 -- Function:
          void
          gal_list_sizet_add (gal_list_sizet_t **list, size_t value)
     Add a new node (containing ‘value’) to the top of the ‘list’ of
     ‘size_t’s and update ‘list’.  Here is one short example of
     initializing and adding elements to a string list:

          gal_list_sizet_t *list=NULL;
          gal_list_sizet_add(&list, 45493);
          gal_list_sizet_add(&list, 930484);

 -- Function:
          sizet_t
          gal_list_sizet_pop (gal_list_sizet_t **list)
     Pop the top element of ‘list’ and return the value.  This function
     will also change ‘list’ to point to the next node in the list.  If
     ‘*list==NULL’, then this function will also return
     ‘GAL_BLANK_SIZE_T’ (see *note Library blank values::).

 -- Function:
          size_t
          gal_list_sizet_number (gal_list_sizet_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          size_t
          gal_list_sizet_last (gal_list_sizet_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_sizet_print (gal_list_sizet_t *list)
     Print the values within each node of ‘*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.

          size_t i=0;
          gal_list_sizet_t *tmp;
          for(tmp=list; tmp!=NULL; tmp=tmp->next)
            printf("Number %zu: %zu\n", ++i, tmp->v);

 -- Function:
          void
          gal_list_sizet_reverse (gal_list_sizet_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          size_t *
          gal_list_sizet_to_array (gal_list_sizet_t *list, int reverse,
          size_t *num)
     Dynamically allocate an array and fill it with the values in
     ‘list’.  The function will return a pointer to the allocated array
     and put the number of elements in the array into the ‘num’ pointer.
     If ‘reverse’ has a non-zero value, the array will be filled in the
     inverse of the order of elements in ‘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.

 -- Function:
          void
          gal_list_sizet_free (gal_list_sizet_t *list)
     Free every node in ‘list’.

   ---------- Footnotes ----------

   (1) So you know that a variable of this type is not used to store
some generic state for example.


File: gnuastro.info,  Node: List of float,  Next: List of double,  Prev: List of size_t,  Up: Linked lists

12.3.8.4 List of ‘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
*note 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).

 -- Type (C struct): gal_list_f32_t
     A single node in a list containing a 32-bit single precision
     ‘float’ value: see *note Numeric data types::.
          typedef struct gal_list_f32_t
          {
            float v;
            struct gal_list_f32_t *next;
          } gal_list_f32_t;

 -- Function:
          void
          gal_list_f32_add (gal_list_f32_t **list, float value)
     Add a new node (containing ‘value’) to the top of the ‘list’ of
     ‘float’s and update ‘list’.  Here is one short example of
     initializing and adding elements to a string list:

          gal_list_f32_t *list=NULL;
          gal_list_f32_add(&list, 3.89);
          gal_list_f32_add(&list, 1.23e-20);

 -- Function:
          float
          gal_list_f32_pop (gal_list_f32_t **list)
     Pop the top element of ‘list’ and return the value.  This function
     will also change ‘list’ to point to the next node in the list.  If
     ‘*list==NULL’, then this function will return ‘GAL_BLANK_FLOAT32’
     (NaN, see *note Library blank values::).

 -- Function:
          size_t
          gal_list_f32_number (gal_list_f32_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          size_t
          gal_list_f32_last (gal_list_f32_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_f32_print (gal_list_f32_t *list)
     Print the values within each node of ‘*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.

          size_t i=0;
          gal_list_f32_t *tmp;
          for(tmp=list; tmp!=NULL; tmp=tmp->next)
            printf("Number %zu: %f\n", ++i, tmp->v);

 -- Function:
          void
          gal_list_f32_reverse (gal_list_f32_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          float *
          gal_list_f32_to_array (gal_list_f32_t *list, int reverse,
          size_t *num)
     Dynamically allocate an array and fill it with the values in
     ‘list’.  The function will return a pointer to the allocated array
     and put the number of elements in the array into the ‘num’ pointer.
     If ‘reverse’ has a non-zero value, the array will be filled in the
     inverse of the order of elements in ‘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.

 -- Function:
          void
          gal_list_f32_free (gal_list_f32_t *list)
     Free every node in ‘list’.


File: gnuastro.info,  Node: List of double,  Next: List of void,  Prev: List of float,  Up: Linked lists

12.3.8.5 List of ‘double’
.........................

Double precision floating point numbers can accurately store real number
until 15.9 decimals and consume 8 bytes (64-bits) of memory, see *note
Numeric data types::.  This level of precision makes them very good for
serious processing in the middle of a program's execution: in many
cases, the propagation of errors will still be insignificant compared to
actual observational errors in a data set.  But since they consume 8
bytes and more CPU processing power, they are often not the best choice
for storing and transferring of data.

 -- Type (C struct): gal_list_f64_t
     A single node in a list containing a 64-bit double precision
     ‘double’ value: see *note Numeric data types::.
          typedef struct gal_list_f64_t
          {
            double v;
            struct gal_list_f64_t *next;
          } gal_list_f64_t;

 -- Function:
          void
          gal_list_f64_add (gal_list_f64_t **list, double value)
     Add a new node (containing ‘value’) to the top of the ‘list’ of
     ‘double’s and update ‘list’.  Here is one short example of
     initializing and adding elements to a string list:

          gal_list_f64_t *list=NULL;
          gal_list_f64_add(&list, 3.8129395763193);
          gal_list_f64_add(&list, 1.239378923931e-20);

 -- Function:
          double
          gal_list_f64_pop (gal_list_f64_t **list)
     Pop the top element of ‘list’ and return the value.  This function
     will also change ‘list’ to point to the next node in the list.  If
     ‘*list==NULL’, then this function will return ‘GAL_BLANK_FLOAT64’
     (NaN, see *note Library blank values::).

 -- Function:
          size_t
          gal_list_f64_number (gal_list_f64_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          size_t
          gal_list_f64_last (gal_list_f64_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_f64_print (gal_list_f64_t *list)
     Print the values within each node of ‘*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.

          size_t i=0;
          gal_list_f64_t *tmp;
          for(tmp=list; tmp!=NULL; tmp=tmp->next)
            printf("Number %zu: %f\n", ++i, tmp->v);

 -- Function:
          void
          gal_list_f64_reverse (gal_list_f64_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          double *
          gal_list_f64_to_array (gal_list_f64_t *list, int reverse,
          size_t *num)
     Dynamically allocate an array and fill it with the values in
     ‘list’.  The function will return a pointer to the allocated array
     and put the number of elements in the array into the ‘num’ pointer.
     If ‘reverse’ has a non-zero value, the array will be filled in the
     inverse of the order of elements in ‘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.

 -- Function:
          gal_data_t *
          gal_list_f64_to_data (gal_list_f64_t *list, uint8_t type,
          size_t minmapsize, int quietmmap)
     Write the values in the given ‘list’ into a ‘gal_data_t’ dataset of
     the requested ‘type’.  The order of the values in the dataset will
     be the same as the order from the top of the list.

 -- Function:
          void
          gal_list_f64_free (gal_list_f64_t *list)
     Free every node in ‘list’.


File: gnuastro.info,  Node: List of void,  Next: Ordered list of size_t,  Prev: List of double,  Up: Linked lists

12.3.8.6 List of ‘void *’
.........................

In C, ‘void *’ is the most generic pointer.  Usually pointers are
associated with the type of content they point to.  For example, ‘int *’
means a pointer to an integer.  This ancillary information about the
contents of the memory location is very useful for the compiler,
catching bad errors and also documentation (it helps the reader see what
the address in memory actually contains).  However, ‘void *’ is just a
raw address (pointer), it contains no information on the contents it
points to.

   These properties make the ‘void *’ very useful when you want to treat
the contents of an address in different ways.  You can use the ‘void *’
list defined in this section and its function on any kind of data: for
example, you can use it to keep a list of custom data structures that
you have built for your own separate program.  Each node in the list can
keep anything and this gives you great versatility.  But in using ‘void
*’, please beware that "with great power comes great responsibility".

 -- Type (C struct): gal_list_void_t
     A single node in a list containing a ‘void *’ pointer.
          typedef struct gal_list_void_t
          {
            void *v;
            struct gal_list_void_t *next;
          } gal_list_void_t;

 -- Function:
          void
          gal_list_void_add (gal_list_void_t **list, void *value)
     Add a new node (containing ‘value’) to the top of the ‘list’ of
     ‘void *’s and update ‘list’.  Here is one short example of
     initializing and adding elements to a string list:

          gal_list_void_t *list=NULL;
          gal_list_f64_add(&list, some_pointer);
          gal_list_f64_add(&list, another_pointer);

 -- Function:
          void *
          gal_list_void_pop (gal_list_void_t **list)
     Pop the top element of ‘list’ and return the value.  This function
     will also change ‘list’ to point to the next node in the list.  If
     ‘*list==NULL’, then this function will return ‘NULL’.

 -- Function:
          size_t
          gal_list_void_number (gal_list_void_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          size_t
          gal_list_void_last (gal_list_void_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_void_reverse (gal_list_void_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          void
          gal_list_void_free (gal_list_void_t *list)
     Free every node in ‘list’.


File: gnuastro.info,  Node: Ordered list of size_t,  Next: Doubly linked ordered list of size_t,  Prev: List of void,  Up: Linked lists

12.3.8.7 Ordered list of ‘size_t’
.................................

Positions/sizes in a dataset are conventionally in the ‘size_t’ type
(see *note List of size_t::) and it sometimes occurs that you want to
parse and read the values in a specific order.  For example, you want to
start from one pixel and add pixels to the list based on their distance
to that pixel.  So that ever time you pop an element from the list, you
know it is the nearest that has not yet been studied.  The
‘gal_list_osizet_t’ type and its functions in this section are designed
to facilitate such operations.

 -- Type (C struct): gal_list_osizet_t
     Each node in this singly-linked list contains a ‘size_t’ value and
     a floating point value.  The floating point value is used as a
     reference to add new nodes in a sorted manner.  At any moment, the
     first popped node in this list will have the smallest ‘tosort’
     value, and subsequent nodes will have larger to values.
     typedef struct gal_list_osizet_t
     {
       size_t v;                       /* The actual value. */
       float  s;                       /* The parameter to sort by. */
       struct gal_list_osizet_t *next;
     } gal_list_osizet_t;

 -- Function:
          void
          gal_list_osizet_add (gal_list_osizet_t **list, size_t value,
          float tosort)
     Allocate space for a new node in ‘list’, and store ‘value’ and
     ‘tosort’ into it.  The new node will not necessarily be at the
     "top" of the list.  If ‘*list!=NULL’, then the ‘tosort’ values of
     existing nodes is inspected and the given node is placed in the
     list such that the top element (which is popped with
     ‘gal_list_osizet_pop’) has the smallest ‘tosort’ value.

 -- Function:
          size_t
          gal_list_osizet_pop (gal_list_osizet_t **list, float
          *sortvalue)
     Pop a node from the top of ‘list’, return the node's ‘value’ and
     put its sort value in the space that ‘sortvalue’ points to.  This
     function will also free the allocated space for the popped node and
     after this function, ‘list’ will point to the next node (which has
     a larger ‘tosort’ element).

 -- Function:
          void
          gal_list_osizet_to_sizet_free (gal_list_osizet_t *in,
          gal_list_sizet_t **out)
     Convert the ordered list of ‘size_t’s into an ordinary ‘size_t’
     linked list.  This can be useful when all the elements have been
     added and you just need to pop-out elements and do not care about
     the sorting values any more.  After the conversion is done, this
     function will free the input list.  Note that the ‘out’ list does
     not have to be empty.  If it already contains some nodes, the new
     nodes will be added on top of them.


File: gnuastro.info,  Node: Doubly linked ordered list of size_t,  Next: List of gal_data_t,  Prev: Ordered list of size_t,  Up: Linked lists

12.3.8.8 Doubly linked ordered list of ‘size_t’
...............................................

An ordered list of indices is required in many contexts, one example was
discussed at the beginning of *note Ordered list of size_t::.  But the
list that was introduced there only has one point of entry: you can
always only parse the list from smallest to largest.  In this section,
the doubly-linked ‘gal_list_dosizet_t’ node is defined which will allow
us to parse the values in ascending or descending order.

 -- Type (C struct): gal_list_dosizet_t

     Doubly-linked, ordered ‘size_t’ list node structure.  Each node in
     this Doubly-linked list contains a ‘size_t’ value and a floating
     point value.  The floating point value is used as a reference to
     add new nodes in a sorted manner.  In the functions here, this
     linked list can be pointed to by two pointers (largest and
     smallest) with the following format:
                      largest pointer
                      |
             NULL <-- (v0,s0) <--> (v1,s1) <--> ... (vn,sn) --> NULL
                                                    |
                                     smallest pointer
     At any moment, the two pointers will point to the nodes containing
     the "largest" and "smallest" values and the rest of the nodes will
     be sorted.  This is useful when an unknown number of nodes are
     being added continuously and during the operations it is important
     to have the nodes in a sorted format.

          typedef struct gal_list_dosizet_t
          {
            size_t v;                       /* The actual value. */
            float s;                        /* The parameter to sort by. */
            struct gal_list_dosizet_t *prev;
            struct gal_list_dosizet_t *next;
          } gal_list_dosizet_t;

 -- Function:
          void
          gal_list_dosizet_add (gal_list_dosizet_t **largest,
          gal_list_dosizet_t **smallest, size_t value, float tosort)
     Allocate space for a new node in ‘list’, and store ‘value’ and
     ‘tosort’ into it.  If the list is empty, both ‘largest’ and
     ‘smallest’ must be ‘NULL’.

 -- Function:
          size_t
          gal_list_dosizet_pop_smallest (gal_list_dosizet_t **largest,
          gal_list_dosizet_t **smallest, float tosort)
     Pop the value with the smallest reference from the doubly linked
     list and store the reference into the space pointed to by ‘tosort’.
     Note that even though only the smallest pointer will be popped,
     when there was only one node in the list, the ‘largest’ pointer
     also has to change, so we need both.

 -- Function:
          void
          gal_list_dosizet_print (gal_list_dosizet_t *largest,
          gal_list_dosizet_t *smallest)
     Print the largest and smallest values sequentially until the list
     is parsed.

 -- Function:
          void
          gal_list_dosizet_to_sizet (gal_list_dosizet_t *in,
          gal_list_sizet_t **out)
     Convert the doubly linked, ordered ‘size_t’ list into a
     singly-linked list of ‘size_t’.

 -- Function:
          void
          gal_list_dosizet_free (gal_list_dosizet_t *largest)
     Free the doubly linked, ordered ‘sizet_t’ list.


File: gnuastro.info,  Node: List of gal_data_t,  Prev: Doubly linked ordered list of size_t,  Up: Linked lists

12.3.8.9 List of ‘gal_data_t’
.............................

Gnuastro's generic data container has a ‘next’ element which enables it
to be used as a singly-linked list (see *note Generic data container::).
The ability to connect the different data containers offers great
advantages.  For example, each column in a table in an independent
dataset: with its own name, units, numeric data type (see *note Numeric
data types::).  Another application is in Tessellating an input dataset
into separate tiles or only studying particular regions, or tiles, of a
larger dataset (see *note Tessellation:: and *note Tessellation
library::).  Each independent tile over the dataset can be connected to
the others as a linked list and thus any number of tiles can be
represented with one variable.

 -- Function:
          void
          gal_list_data_add (gal_data_t **list, gal_data_t *newnode)
     Add an already allocated dataset (‘newnode’) to top of ‘list’.
     Note that if ‘newnode->next!=NULL’ (‘newnode’ is itself a list),
     then ‘list’ will be added to its end.

     In this example multiple images are linked together as a list:
          int quietmmap=1;
          size_t minmapsize=-1;
          gal_data_t *tmp, *list=NULL;
          tmp = gal_fits_img_read("file1.fits", "1", minmapsize, quietmmap,
                                  NULL);
          gal_list_data_add( &list, tmp );
          tmp = gal_fits_img_read("file2.fits", "1", minmapsize, quietmmap,
                                  NULL);
          gal_list_data_add( &list, tmp );

 -- Function:
          void
          gal_list_data_add_alloc (gal_data_t **list, void *array,
          uint8_t type, size_t ndim, size_t *dsize, struct wcsprm *wcs,
          int clear, size_t minmapsize, int quietmmap, char *name, char
          *unit, char *comment)
     Allocate a new dataset (with ‘gal_data_alloc’ in *note Dataset
     allocation::) and put it as the first element of ‘list’.  Note that
     if this is the first node to be added to the list, ‘list’ must be
     ‘NULL’.

 -- Function:
          gal_data_t *
          gal_list_data_pop (gal_data_t **list)
     Pop the top node from ‘list’ and return it.

 -- Function:
          void
          gal_list_data_remove (gal_data_t **list, gal_data_t *node)
     Remove ‘node’ from the given ‘list’.  After finding the given node,
     this function will just set ‘node->next=NULL’ and correct the
     ‘next’ node of its previous element to its next element (thus
     "removing" it from the list).  If ‘node’ doesn't exist in the list,
     this function won't make any change to list.

 -- Function:
          gal_data_t *
          gal_list_data_select_by_name (gal_data_t *list, char *name)
     Select the dataset within the list, that has a ‘name’ element that
     is identical (case-sensitive) to the given ‘name’.  If not found, a
     ‘NULL’ pointer will be returned.

     Note that this dataset will not be popped from the list, only a
     pointer to it will be returned and if you free it or change its
     ‘next’ element, it may harm your original list.

 -- Function:
          gal_data_t *
          gal_list_data_select_by_id (gal_data_t *table, char *idstr,
          size_t *index)
     Select the dataset within the list that can be identified with the
     string given to ‘idstr’ (which can be a counter, starting from 1,
     or a name).  If not found, a ‘NULL’ pointer will be returned.

     Note that this dataset will not be popped from the list, only a
     pointer to it will be returned and if you free it or change its
     ‘next’ element, it may harm your original list.

 -- Function:
          void
          gal_list_data_reverse (gal_data_t **list)
     Reverse the order of the list such that the top node in the list
     before calling this function becomes the bottom node after it.

 -- Function:
          gal_data_t **
          gal_list_data_to_array_ptr (gal_data_t *list, size_t *num)
     Allocate and return an array of ‘gal_data_t *’ pointers with the
     same number of elements as the nodes in ‘list’.  The pointers will
     be put in the same order that the list is parsed.  Hence the N-th
     element in the array will point to the same dataset that the N-th
     node in the list points to.

 -- Function:
          size_t
          gal_list_data_number (gal_data_t *list)
     Return the number of nodes in ‘list’.

 -- Function:
          gal_data_t *
          gal_list_data_last (gal_data_t *list)
     Return a pointer to the last node in ‘list’.

 -- Function:
          void
          gal_list_data_free (gal_data_t *list)
     Free all the datasets in ‘list’ along with all the allocated spaces
     in each.


File: gnuastro.info,  Node: Array input output,  Next: Table input output,  Prev: Linked lists,  Up: Gnuastro library

12.3.9 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, *note FITS files:: or *note TIFF files::.  If
the file type of the input/output file is already known, you can use the
functions in those sections respectively.

 -- Function:
          int
          gal_array_name_recognized (char *filename)
     Return 1 if the given file name corresponds to one of the
     recognized file types for reading arrays.

 -- Function:
          int
          gal_array_name_recognized_multiext (char *filename)
     Return 1 if the given file name corresponds to one of the
     recognized file types for reading arrays which may contain multiple
     extensions (for example FITS or TIFF) formats.

 -- Function:
          int
          gal_array_file_recognized (char *filename)
     Similar to ‘gal_array_name_recognized’, but for FITS files, it will
     also check the contents of the file if the recognized file name
     suffix is not found.  See the description of
     ‘gal_fits_file_recognized’ for more (*note FITS macros errors
     filenames::).

 -- Function:
          gal_data_t
          gal_array_read (char *filename, char *extension,
          gal_list_str_t *lines, size_t minmapsize, int quietmmap, char
          *hdu_option_name)
     Read the array within the given extension (‘extension’) of
     ‘filename’, or the ‘lines’ list (see below).  If the array is
     larger than ‘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
     ‘quietmmap’.

     ‘extension’ will be ignored for files that do not support them (for
     example JPEG or text).  For FITS files, ‘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 *note 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 ‘next’ pointer of the returned ‘gal_data_t’.

     ‘lines’ is a list of strings with each node representing one line
     (including the new-line character), see *note List of strings::.
     It will mostly be the output of ‘gal_txt_stdin_read’, which is used
     to read the program's input as separate lines from the standard
     input (see *note Text files::).  Note that ‘filename’ and ‘lines’
     are mutually exclusive and one of them must be ‘NULL’.

     ‘hdu_option_name’ is used in error messages related to extensions
     (e.g., HDUs in FITS) and is expected to be the command-line option
     name that users of your program can specify to select an input HDU
     for this particular input; for example, if the kernel is used as
     the input, users should determine ‘--khdu’ for this option.  If the
     given ‘extension’ doesn't exist in ‘filename’, a descriptive error
     message is printed instructing the users how to find and fix the
     problem.  This error message also suggests the option to use in
     order to help users of your program to inform them what option they
     should give a HDU to.  If you don't have an option that is
     configured by the users of your program, you can set this to ‘NONE’
     or ‘NULL’.

 -- Function:
          void
          gal_array_read_to_type (char *filename, char *extension,
          gal_list_str_t *lines, uint8_t type, size_t minmapsize, int
          quietmmap, char *hdu_option_name)
     Similar to ‘gal_array_read’, but the output data structure(s) will
     have a numeric data type of ‘type’, see *note Numeric data types::.

 -- Function:
          void
          gal_array_read_one_ch (char *filename, char *extension,
          gal_list_str_t *lines, size_t minmapsize, int quietmmap, char
          *hdu_option_name)
     Read the dataset within ‘filename’ (extension/hdu/dir ‘extension’)
     and make sure it is only a single channel.  This is just a simple
     wrapper around ‘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.

     Regarding ‘*hdu_option_name’, see the description for the same
     argument in the description of ‘gal_array_read’.

 -- Function:
          void
          gal_array_read_one_ch_to_type (char *filename, char
          *extension, gal_list_str_t *lines, uint8_t type, size_t
          minmapsize, int quietmmap, char *hdu_option_name)
     Similar to ‘gal_array_read_one_ch’, but the output data structure
     will has a numeric data type of ‘type’, see *note Numeric data
     types::.


File: gnuastro.info,  Node: Table input output,  Next: FITS files,  Prev: Array input output,  Up: Gnuastro library

12.3.10 Table input output (‘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 *note
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 *note Library
demo - reading and writing table columns::.

   Currently only plain text (see *note 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.

 -- Macro: GAL_TABLE_DEF_WIDTH_STR
 -- Macro: GAL_TABLE_DEF_WIDTH_INT
 -- Macro: GAL_TABLE_DEF_WIDTH_LINT
 -- Macro: GAL_TABLE_DEF_WIDTH_FLT
 -- Macro: GAL_TABLE_DEF_WIDTH_DBL
 -- Macro: GAL_TABLE_DEF_PRECISION_INT
 -- Macro: GAL_TABLE_DEF_PRECISION_FLT
 -- Macro: GAL_TABLE_DEF_PRECISION_DBL
     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
     ‘disp_width’ and ‘disp_precision’ in *note Generic data
     container::) these will be directly used in C's ‘printf’ command to
     write the number as a string.

 -- Macro: GAL_TABLE_DISPLAY_FMT_STRING
 -- Macro: GAL_TABLE_DISPLAY_FMT_DECIMAL
 -- Macro: GAL_TABLE_DISPLAY_FMT_UDECIMAL
 -- Macro: GAL_TABLE_DISPLAY_FMT_OCTAL
 -- Macro: GAL_TABLE_DISPLAY_FMT_HEX
 -- Macro: GAL_TABLE_DISPLAY_FMT_FIXED
 -- Macro: GAL_TABLE_DISPLAY_FMT_EXP
 -- Macro: GAL_TABLE_DISPLAY_FMT_GENERAL
     The display format used in C's ‘printf’ to display data of
     different types.  The ‘_STRING’ and ‘_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:

     Unsigned integer
          For unsigned integers, it is possible to choose from
          ‘_UDECIMAL’ (unsigned decimal), ‘_OCTAL’ (octal notation, for
          example, ‘125’ in decimal will be displayed as ‘175’), and
          ‘_HEX’ (hexadecimal notation, for example, ‘125’ in decimal
          will be displayed as ‘7D’).

     Floating point
          For floating point, it is possible to display the number in
          ‘_FLOAT’ (floating point, for example, ‘1500.345’), ‘_EXP’
          (exponential, for example, ‘1.500345e+03’), or ‘_GENERAL’
          which is the best of the two for the given number.

 -- Macro: GAL_TABLE_FORMAT_INVALID
 -- Macro: GAL_TABLE_FORMAT_TXT
 -- Macro: GAL_TABLE_FORMAT_AFITS
 -- Macro: GAL_TABLE_FORMAT_BFITS
     All the current acceptable table formats to Gnuastro.  The ‘AFITS’
     and ‘BFITS’ represent FITS ASCII tables and FITS Binary tables.
     You can use these anywhere you see the ‘tableformat’ variable.

 -- Macro: GAL_TABLE_SEARCH_INVALID
 -- Macro: GAL_TABLE_SEARCH_NAME
 -- Macro: GAL_TABLE_SEARCH_UNIT
 -- 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
     _name_, _units_ or _comments_ of the column metadata.  These values
     should be used for the ‘searchin’ variables of the functions.

 -- Function:
          uint8_t
          gal_table_displayflt_from_str (char *string)
     Convert the input ‘string’ into one of the
     ‘GAL_TABLE_DISPLAY_FMT_FIXED’ (for fixed-point notation) or
     ‘GAL_TABLE_DISPLAY_FMT_EXP’ (for exponential notation).

 -- Function:
          char *
          gal_table_displayflt_to_str (uint8_t id)
     Convert the input identifier (one of the
     ‘GAL_TABLE_DISPLAY_FMT_FIXED’; for fixed-point notation, or
     ‘GAL_TABLE_DISPLAY_FMT_EXP’; for exponential notation) into a
     standard string that is used to identify them.

 -- Function:
          gal_data_t *
          gal_table_info (char *filename, char *hdu, gal_list_str_t
          *lines, size_t *numcols, size_t *numrows, int *tableformat)

     Store the information of each column of a table into an array of
     meta-data ‘gal_data_t’s.  In a metadata ‘gal_data_t’, the size
     elements are zero (‘ndim=size=0’ and ‘dsize=NULL’) but other
     relevant elements are filled).  See the end of this description for
     the exact components of each ‘gal_data_t’ that are filled.

     The returned array of ‘gal_data_t’s has ‘numcols’ datasets (one
     data structure for each column).  The number of rows in each
     dataset is stored in ‘numrows’ (in a table, all the columns have
     the same number of rows).  The format of the table (e.g., ASCII
     text file, or FITS binary or ASCII table) will be put in
     ‘tableformat’ (macros defined above).  If the ‘filename’ is not a
     FITS file, then ‘hdu’ will not be used (can be ‘NULL’).

     The input must be either a file (specified by ‘filename’) or a list
     of strings (‘lines’).  ‘lines’ is a list of strings with each node
     representing one line (including the new-line character), see *note
     List of strings::.  It will mostly be the output of
     ‘gal_txt_stdin_read’, which is used to read the program's input as
     separate lines from the standard input (see *note Text files::).
     Note that ‘filename’ and ‘lines’ are mutually exclusive and one of
     them must be ‘NULL’.

     In the output datasets, only the meta-data strings (column name,
     units and comments), will be allocated and set as shown below.
     This function is just for column information (meta-data), not
     column contents.

          *restrict array  ->  Blank value (if present, in col's own type).
                     type  ->  Type of column data.
                     ndim  ->  0
                   *dsize  ->  NULL
                     size  ->  0
                quietmmap  ->  ------------
                *mmapname  ->  ------------
               minmapsize  ->  Repeat (length of vector; 1 if not vector).
                     nwcs  ->  ------------
                     *wcs  ->  ------------
                     flag  ->  'GAL_TABLEINTERN_FLAG_*' macros.
                   status  ->  ------------
                    *name  ->  Column name.
                    *unit  ->  Column unit.
                 *comment  ->  Column comments.
                 disp_fmt  ->  'GAL_TABLE_DISPLAY_FMT' macros.
               disp_width  ->  Width of string columns.
           disp_precision  ->  ------------
                    *next  ->  Pointer to next column's metadata
                   *block  ->  ------------

 -- Function:
          void
          gal_table_print_info (gal_data_t *allcols, size_t numcols,
          size_t numrows, char *hdu_option_name)
     Print the column information for all the columns (output of
     ‘gal_table_info’) to standard output.  The output is in the same
     format as this command with Gnuastro Table program (see *note
     Invoking asttable::):
          $ asttable --info table.fits

 -- Function:
          gal_data_t *
          gal_table_read (char *filename, char *hdu, gal_list_str_t
          *lines, gal_list_str_t *cols, int searchin, int ignorecase,
          size_t numthreads, size_t minmapsize, int quietmmap, size_t
          *colmatch, char *hdu_option_name)

     Read the specified columns in a file (named ‘filename’), or list of
     strings (‘lines’) into a linked list of data structures.  If the
     file is FITS, then ‘hdu’ will also be used, otherwise, ‘hdu’ is
     ignored.  For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

     ‘lines’ is a list of strings with each node representing one line
     (including the new-line character), see *note List of strings::.
     It will mostly be the output of ‘gal_txt_stdin_read’, which is used
     to read the program's input as separate lines from the standard
     input (see *note Text files::).  Note that ‘filename’ and ‘lines’
     are mutually exclusive and one of them must be ‘NULL’.

     The information to search for columns should be specified by the
     ‘cols’ list of strings (see *note List of strings::).  The string
     in each node of the list may be a number, an exact match to a
     column name, or a regular expression (in GNU AWK format) enclosed
     in ‘/ /’.  The ‘searchin’ value must be one of the macros defined
     above.  If ‘cols’ is NULL, then this function will read the full
     table.  Also, the ‘ignorecase’ value should be 1 if you want to
     ignore the case of alphabetic characters while matching/searching
     column meta-data (see *note Input output options::).

     For FITS tables, each column will be read independently.  Therefore
     they will be read in ‘numthreads’ CPU threads to greatly speed up
     the reading when there are many columns and rows.  However, this
     only happens if CFITSIO was configured with ‘--enable-reentrant’.
     This test has been done at Gnuastro's configuration time; if so,
     ‘GAL_CONFIG_HAVE_FITS_IS_REENTRANT’ will have a value of 1,
     otherwise, it will have a value of 0.  For more on this macro, see
     *note Configuration information::).  Multi-threaded table reading
     is not currently applicable to other table formats (only for FITS
     tables).

     The output is an individually allocated list of datasets (see *note
     List of gal_data_t::) with the same order of the ‘cols’ list.  Note
     that one column node in the ‘cols’ list might give multiple columns
     (for example, from regular expressions), in this case, the order of
     output columns that correspond to that one input, are in order of
     the table (which column was read first).  So the first requested
     column is the first popped data structure and so on.

     if ‘colmatch!=NULL’, it is assumed to be an array that has at least
     the same number of elements as nodes in the ‘cols’ list.  The
     number of columns that matched each input column will be stored in
     each element.

 -- Function:
          gal_list_sizet_t *
          gal_table_list_of_indexs (gal_list_str_t *cols, gal_data_t
          *allcols, size_t numcols, int searchin, int ignorecase, char
          *filename, char *hdu, size_t *colmatch)
     Returns a list of indices (starting from 0) of the input columns
     that match the names/numbers given to ‘cols’.  This is a low-level
     operation which is called by ‘gal_table_read’ (described above),
     see there for more on each argument's description.  ‘allcols’ is
     the returned array of ‘gal_table_info’.

 -- Function:
          void
          gal_table_comments_add_intro (gal_list_str_t **comments, char
          *program_string, time_t *rawtime)
     Add some basic information to the list of ‘comments’.  This basic
     information includes the following information
        • If the program is run in a Git version controlled directory,
          Git's description is printed (see description under ‘COMMIT’
          in *note Output FITS files::).
        • The calendar time that is stored in ‘rawtime’ (‘time_t’ is C's
          calendar time format defined in ‘time.h’).  You can calculate
          the time in this format with the following expressions:
               time_t rawtime;
               time(&rawtime);
        • The name of your program in ‘program_string’.  If it is
          ‘NULL’, this line is ignored.

 -- Function:
          void
          gal_table_write (gal_data_t *cols, struct gal_fits_list_key_t
          **keylist, gal_list_str_t *comments, int tableformat, char
          *filename, char *extname, uint8_t colinfoinstdout, int
          freekeys)

     Write ‘cols’ (a list of datasets, see *note List of gal_data_t::)
     into a table stored in ‘filename’.  The format of the table can be
     determined with ‘tableformat’ that accepts the macros defined
     above.  When ‘filename==NULL’, the column information will be
     printed on the standard output (command-line).

     If ‘comments!=NULL’, the list of comments (see *note List of
     strings::) will also be printed into the output table.  When the
     output table is a plain text file, every node of ‘comments’ will be
     printed after a ‘#’ (so it can be considered as a comment) and in
     FITS table they will follow a ‘COMMENT’ keyword.

     If a file named ‘filename’ already exists, the operation depends on
     the type of output.  When ‘filename’ is a FITS file, the table will
     be added as a new extension after all existing extensions.  If
     ‘filename’ is a plain text file, this function will abort with an
     error.

     If ‘filename’ is a FITS file, the table extension will have the
     name ‘extname’.

     When ‘colinfoinstdout!=0’ and ‘filename==NULL’ (columns are printed
     in the standard output), the dataset metadata will also printed in
     the standard output.  When printing to the standard output, the
     column information can be piped into another program for further
     processing and thus the meta-data (lines starting with a ‘#’) must
     be ignored.  In such cases, you only print the column values by
     passing ‘0’ to ‘colinfoinstdout’.

 -- Function:
          void
          gal_table_write_log (gal_data_t *logll, char *program_string,
          time_t *rawtime, gal_list_str_t *comments, char *filename, int
          quiet)
     Write the ‘logll’ list of datasets into a table in ‘filename’ (see
     *note List of gal_data_t::).  This function is just a wrapper
     around ‘gal_table_comments_add_intro’ and ‘gal_table_write’ (see
     above).  If ‘quiet’ is non-zero, this function will print a message
     saying that the ‘filename’ has been created.

 -- Function:
          gal_data_t *
          gal_table_col_vector_extract (gal_data_t *vector,
          gal_list_sizet_t *indexs)
     Given the "vector" column ‘vector’ (which is assumed to be a 2D
     dataset), extract the tokens that are identified in the ‘indexs’
     list into a list of one dimensional datasets.  For more on vector
     columns in tables, see *note Vector columns::.

 -- Function:
          gal_data_t *
          gal_table_cols_to_vector (gal_data_t *list)
     Merge the one-dimensional datasets in the given list into one
     2-dimensional dataset that can be treated as a vector column.  All
     the input datasets have to have the same size and type.  For more
     on vector columns in tables, see *note Vector columns::.


File: gnuastro.info,  Node: FITS files,  Next: File input output,  Prev: Table input output,  Up: Gnuastro library

12.3.11 FITS files (‘fits.h’)
-----------------------------

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 ‘gnuastro/fits.h’.  When you include this header, you are also
including CFITSIO's ‘fitsio.h’ header.  So you do not need to explicitly
include ‘fitsio.h’ anymore and can freely use any of its macros or
functions in your code along with those discussed here.

* Menu:

* FITS macros errors filenames::  General macros, errors and checking names.
* CFITSIO and Gnuastro types::  Conversion between FITS and Gnuastro types.
* FITS HDUs::                   Opening and getting information about HDUs.
* FITS header keywords::        Reading and writing FITS header keywords.
* FITS arrays::                 Reading and writing FITS images/arrays.
* FITS tables::                 Reading and writing FITS tables.


File: gnuastro.info,  Node: FITS macros errors filenames,  Next: CFITSIO and Gnuastro types,  Prev: FITS files,  Up: FITS files

12.3.11.1 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.

 -- 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.

 -- Function:
          void
          gal_fits_io_error (int status, char *message)
     If ‘status’ is non-zero, this function will print the CFITSIO error
     message corresponding to status, print ‘message’ (optional) in the
     next line and abort the program.  If ‘message==NULL’, it will print
     a default string after the CFITSIO error.

 -- Function:
          int
          gal_fits_name_is_fits (char *name)
     If the ‘name’ is an acceptable CFITSIO FITS filename return ‘1’
     (one), otherwise return ‘0’ (zero).  The currently acceptable FITS
     suffixes are ‘.fits’, ‘.fit’, ‘.fits.gz’, ‘.fits.Z’, ‘.imh’,
     ‘.fits.fz’.  IMH is the IRAF format which is acceptable to CFITSIO.

 -- Function:
          int
          gal_fits_suffix_is_fits (char *suffix)
     Similar to ‘gal_fits_name_is_fits’, but only for the suffix.  The
     suffix does not have to start with '<.>': this function will return
     ‘1’ (one) for both ‘fits’ and ‘.fits’.

 -- Function:
          int
          gal_fits_file_recognized (char *name)
     Return ‘1’ if the given file name (possibly including its contents)
     is a FITS file.  This is necessary in when the contents of a FITS
     file do follow the FITS standard, but it the file does not have a
     Gnuastro-recognized FITS suffix.  Therefore, it will first call
     ‘gal_fits_name_is_fits’, if the result is negative, then this
     function will attempt to open the file with CFITSIO and if it
     works, it will close it again and return 1.  In the process of
     opening the file, CFITSIO will just to open the file, no reading
     will take place, so it should have minimal CPU footprint.

 -- Function:
          char *
          gal_fits_name_save_as_string (char *filename, char *hdu)
     If the name is a FITS name, then put a ‘(hdu: ...)’ after it and
     return the string.  If it is not a FITS file, just print the name,
     if ‘filename==NULL’, then return the string ‘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).


File: gnuastro.info,  Node: CFITSIO and Gnuastro types,  Next: FITS HDUs,  Prev: FITS macros errors filenames,  Up: FITS files

12.3.11.2 CFITSIO and Gnuastro types
....................................

Both Gnuastro and CFITSIO have special and different identifiers for
each type that they accept.  Gnuastro's type identifiers are fully
described in *note Library data types:: and are usable for all kinds of
datasets (images, table columns, etc) as part of Gnuastro's *note
Generic data container::.  However, following the FITS standard, CFITSIO
has different identifiers for images and tables.  Following CFITSIO's
own convention, we will use ‘bitpix’ for image type identifiers and
‘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, ‘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.

 -- Function:
          uint8_t
          gal_fits_bitpix_to_type (int bitpix)
     Return the Gnuastro type identifier that corresponds to CFITSIO's
     ‘bitpix’ on this system.

 -- Function:
          int
          gal_fits_type_to_bitpix (uint8_t type)
     Return the CFITSIO ‘bitpix’ value that corresponds to Gnuastro's
     ‘type’.

 -- Function:
          char
          gal_fits_type_to_bin_tform (uint8_t type)
     Return the FITS standard binary table ‘TFORM’ character that
     corresponds to Gnuastro's ‘type’.

 -- Function:
          int
          gal_fits_type_to_datatype (uint8_t type)
     Return the CFITSIO ‘datatype’ that corresponds to Gnuastro's ‘type’
     on this machine.

 -- Function:
          uint8_t
          gal_fits_datatype_to_type (int datatype, int is_table_column)
     Return Gnuastro's type identifier that corresponds to the CFITSIO
     ‘datatype’.  Note that when dealing with CFITSIO's ‘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
     ‘is_table_column’.


File: gnuastro.info,  Node: FITS HDUs,  Next: FITS header keywords,  Prev: CFITSIO and Gnuastro types,  Up: FITS files

12.3.11.3 FITS HDUs
...................

A FITS file can contain multiple HDUs/extensions.  The functions in this
section can be used to get basic information about the extensions or
open them.  Note that ‘fitsfile’ is defined in CFITSIO's ‘fitsio.h’
which is automatically included by Gnuastro's ‘gnuastro/fits.h’.

 -- Function:
          fitsfile *
          gal_fits_open_to_write (char *filename)
     If ‘filename’ exists, open it and return the ‘fitsfile’ pointer
     that corresponds to it.  If ‘filename’ does not exist, the file
     will be created which contains a blank first extension and the
     pointer to its next extension will be returned.

 -- Function:
          size_t
          gal_fits_hdu_num (char *filename)
     Return the number of HDUs/extensions in ‘filename’.

 -- Function:
          unsigned long
          gal_fits_hdu_datasum (char *filename, char *hdu, char
          *hdu_option_name)
     Return the ‘DATASUM’ of the given HDU in the given FITS file.  For
     more on ‘DATASUM’ in the FITS standard, see *note Keyword
     inspection and manipulation:: (under the ‘checksum’ component of
     ‘--write’).  For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

 -- Function:
          unsigned long
          gal_fits_hdu_datasum_encoded (char *filename, char *hdu, char
          *hdu_option_name)
     Similar to ‘gal_fits_hdu_datasum’, but the returned value is always
     a 16-character string following the encoding that is described in
     the FITS standard (primarily for the ‘CHECKSUM’ keyword, but can
     also be used for ‘DATASUM’.

 -- Function:
          unsigned long
          gal_fits_hdu_datasum_ptr (fitsfile *fptr)
     Return the ‘DATASUM’ of the already opened HDU in ‘fptr’.  For more
     on ‘DATASUM’ in the FITS standard, see *note Keyword inspection and
     manipulation:: (under the ‘checksum’ component of ‘--write’).

 -- Function:
          int
          gal_fits_hdu_format (char *filename, char *hdu, char
          *hdu_option_name)
     Return the format of the HDU as one of CFITSIO's recognized macros:
     ‘IMAGE_HDU’, ‘ASCII_TBL’, or ‘BINARY_TBL’.  For more on
     ‘hdu_option_name’ see the description of ‘gal_array_read’ in *note
     Array input output::.

 -- Function:
          int
          gal_fits_hdu_is_healpix (fitsfile *fptr)
     Return ‘1’ if the dataset may be a HEALpix grid and ‘0’ otherwise.
     Technically, it is considered to be a HEALPix if the HDU is not an
     ASCII table, and has the ‘NSIDE’, ‘FIRSTPIX’ and ‘LASTPIX’.

 -- Function:
          fitsfile *
          gal_fits_hdu_open (char *filename, char *hdu, int iomode, int
          exitonerror, char *hdu_option_name)
     Open the HDU/extension ‘hdu’ from ‘filename’ and return a pointer
     to CFITSIO's ‘fitsfile’.  ‘iomode’ determines how the FITS file
     will be opened using CFITSIO's macros: ‘READONLY’ or ‘READWRITE’.

     The string in ‘hdu’ will be appended to ‘filename’ in square
     brackets so CFITSIO only opens this extension.  You can use any
     formatting for the ‘hdu’ that is acceptable to CFITSIO. See the
     description under ‘--hdu’ in *note Input output options:: for more.

     If ‘exitonerror!=0’ and the given HDU cannot be opened for any
     reason, the function will exit the program, and print an
     informative message.  Otherwise, when the HDU cannot be opened, it
     will just return a NULL pointer.  For more on ‘hdu_option_name’ see
     the description of ‘gal_array_read’ in *note Array input output::.

 -- Function:
          fitsfile *
          gal_fits_hdu_open_format (char *filename, char *hdu, int
          img0_tab1, char *hdu_option_name)
     Open (in read-only format) the ‘hdu’ HDU/extension of ‘filename’ as
     an image or table.  When ‘img0_tab1’ is ‘0’(zero) but the HDU is a
     table, this function will abort with an error.  It will also abort
     with an error when ‘img0_tab1’ is ‘1’ (one), but the HDU is an
     image.  For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

     A FITS HDU may contain both tables or images.  When your program
     needs one of these formats, you can call this function so if the
     user provided the wrong HDU/file, it will abort and inform the user
     that the file/HDU is has the wrong format.


File: gnuastro.info,  Node: FITS header keywords,  Next: FITS arrays,  Prev: FITS HDUs,  Up: FITS files

12.3.11.4 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 *note Linked lists::.  To reading FITS keywords, these
functions use a list of Gnuastro's generic dataset format that is
discussed in *note List of gal_data_t::.  To write FITS keywords we
define the ‘gal_fits_list_key_t’ node that is defined below.

 -- Type (C struct): gal_fits_list_key_t
     Structure for writing FITS keywords.  This structure is used for
     one keyword and you do not need to set all elements.  With the
     ‘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 *note Linked lists:: for an introduction
     on lists).  See the functions below for adding elements to the
     list.

          typedef struct gal_fits_list_key_t
          {
            int                        tfree; /* ==1, free title string.  */
            int                        kfree; /* ==1, free keyword name.  */
            int                        vfree; /* ==1, free keyword value. */
            int                        cfree; /* ==1, free comment.       */
            int                        ufree; /* ==1, free unit.          */
            uint8_t                     type; /* Keyword value type.      */
            char                      *title; /* !=NULL, only print title.*/
            char                    *keyname; /* Keyword Name.            */
            void                      *value; /* Keyword value.           */
            char                    *comment; /* Keyword comment.         */
            char                       *unit; /* Keyword unit.            */
            struct gal_fits_list_key_t *next; /* Pointer next keyword.    */
          } gal_fits_list_key_t;

 -- Function:
          int
          gal_fits_key_exists_fptr (fitsfile *fptr, char *keyname)
     Return 1 (true) if the opened FITS file pointer contains the
     requested keyword and 0 (false) otherwise.

 -- Function:
          void *
          gal_fits_key_img_blank (uint8_t type)
     Returns a pointer to an allocated space containing the value to the
     FITS ‘BLANK’ header keyword, when the input array has a type of
     ‘type’.  This is useful when you want to write the ‘BLANK’ keyword
     using CFITSIO's ‘fits_write_key’ function.

     According to the FITS standard: "If the ‘BSCALE’ and ‘BZERO’
     keywords do not have the default values of 1.0 and 0.0,
     respectively, then the value of the ‘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 ‘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 ‘BSCALE’ and ‘BZERO’ in the
     FITS standard).

     *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 ‘BLANK’ keyword header.  It
     _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 ‘gal_blank_alloc_write’ to generate the necessary pointer.

 -- Function:
          void
          gal_fits_key_clean_str_value (char *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: ‘'value
     '’, or ‘'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.

 -- Function:
          char *
          gal_fits_key_date_to_struct_tm (char *fitsdate, struct tm *tp)
     Parse ‘fitsdate’ as a FITS date format string (most generally:
     ‘YYYY-MM-DDThh:mm:ss.ddd...’) into the C library's broken-down time
     structure, or ‘struct tm’ (declared in ‘time.h’) and return a
     pointer to a newly allocated array for the sub-second part of the
     format (‘.ddd...’).  Therefore it needs to be freed afterwards (if
     it is not ‘NULL’) When there is no sub-second portion, this pointer
     will be ‘NULL’.

     This is a relatively low-level function, an easier function to use
     is ‘gal_fits_key_date_to_seconds’ which will return the sub-seconds
     as double precision floating point.

     Note that the FITS date format mentioned above is the most complete
     representation.  The following two formats are also acceptable:
     ‘YYYY-MM-DDThh:mm:ss’ and ‘YYYY-MM-DD’.  This option can also
     interpret the older FITS date format where only two characters are
     given to the year and the date format is reversed
     (‘DD/MM/YYThh:mm:ss.ddd...’).  In this case (following the GNU C
     Library), this option will make the following assumption: values 68
     to 99 correspond to the years 1969 to 1999, and values 0 to 68 as
     the years 2000 to 2068.

 -- Function:
          size_t
          gal_fits_key_date_to_seconds (char *fitsdate, char
          **subsecstr, double *subsec)
     Return the Unix epoch time (number of seconds that have passed
     since 00:00:00 Thursday, January 1st, 1970) corresponding to the
     FITS date format string ‘fitsdate’ (see description of
     ‘gal_fits_key_date_to_struct_tm’ above).  This function will return
     ‘GAL_BLANK_SIZE_T’ if the broken-down time could not be converted
     to seconds.

     The Unix epoch time is in units of seconds, but the FITS date
     format allows sub-second accuracy.  The last two arguments are for
     the optional sub-second portion.  If you do not want sub-second
     information, just set the second argument to ‘NULL’.

     If ‘fitsdate’ contains sub-second accuracy and ‘subsecstr!=NULL’,
     then the starting of the sub-second part's string is stored in
     ‘subsecstr’ (malloc'ed), and ‘subsec’ will be the corresponding
     numerical value (between 0 and 1, in double precision floating
     point).  So to avoid leaking memory, if a sub-second string is
     requested, it must be freed after calling this function.  When a
     sub-second string does not exist (and it is requested), then a
     value of ‘NULL’ and NaN will be written in ‘*subsecstr’ and
     ‘*subsec’ respectively.

     This is a very useful function for operations on the FITS date
     values, for example, sorting FITS files by their dates, or finding
     the time difference between two FITS files.  The advantage of
     working with the Unix epoch time is that you do not have to worry
     about calendar details (such as the number of days in different
     months or leap years).

 -- Function:
          void
          gal_fits_key_read_from_ptr (fitsfile *fptr, gal_data_t
          *keysll, int readcomment, int readunit)

     Read the list of keyword values from a FITS pointer.  The input
     should be a linked list of Gnuastro's generic data container
     (‘gal_data_t’).  Before calling this function, you just have to set
     the ‘name’, and optionally, the desired ‘type’ of the value of each
     keyword.  The given ‘name’ value will be directly passed to CFITSIO
     to read the desired keyword name.  This function will allocate
     space to keep the value.  If no pre-defined type is requested for a
     certain keyword's value, the smallest possible type to host the
     value will be found and used.  If ‘readcomment’ and ‘readunit’ are
     non-zero, this function will also try to read the possible comments
     and units of the keyword.

     Here is one example of using this function:

          /* Allocate an array of datasets. */
          gal_data_t *keysll=gal_data_array_calloc(N);

          /* Make the array usable as a list too (by setting `next'). */
          for(i=0;i<N-1;++i) keysll[i].next=&keysll[i+1];

          /* Fill the datasets with a `name' and a `type'. */
          keysll[0].name="NAME1";     keysll[0].type=GAL_TYPE_INT32;
          keysll[1].name="NAME2";     keysll[1].type=GAL_TYPE_STRING;
          ...
          ...

          /* Call this function. */
          gal_fits_key_read_from_ptr(fptr, keysll, 0, 0);

          /* Use the values as you like... */

          /* Free all the allocated spaces. Note that `name' was not
             allocated in this example, so we should explicitly set
             it to NULL before calling `gal_data_array_free'. */
          for(i=0;i<N;++i) keysll[i].name=NULL;
          gal_data_array_free(keysll, N, 1);

     If the ‘array’ pointer of each keyword's dataset is not ‘NULL’,
     then it is assumed that the space to keep the value has already
     been allocated.  If it is ‘NULL’, space will be allocated for the
     value by this function.

     Strings need special consideration: the reason is that generally,
     ‘gal_data_t’ needs to also allow for array of strings (as it
     supports arrays of integers for example).  Hence when reading a
     string value, two allocations may be done by this function (one if
     ‘array!=NULL’).

     Therefore, when using the values of strings after this function,
     ‘keysll[i].array’ must be interpreted as ‘char **’: one allocation
     for the pointer, one for the actual characters.  If you use
     something like the example, above you do not have to worry about
     the freeing, ‘gal_data_array_free’ will free both allocations.  So
     to read a string, one easy way would be the following:

          char *str, **strarray;
          strarr = keysll[i].array;
          str    = strarray[0];

     If CFITSIO is unable to read a keyword for any reason the ‘status’
     element of the respective ‘gal_data_t’ will be non-zero.  If it is
     zero, then the keyword was found and successfully read.  Otherwise,
     it is a CFITSIO status value.  You can use CFITSIO's error
     reporting tools or ‘gal_fits_io_error’ (see *note FITS macros
     errors filenames::) for reporting the reason of the failure.  A
     tip: when the keyword does not exist, CFITSIO's status value will
     be ‘KEY_NO_EXIST’.

     CFITSIO will start searching for the keywords from the last place
     in the header that it searched for a keyword.  So it is much more
     efficient if the order that you ask for keywords is based on the
     order they are stored in the header.

 -- Function:
          void
          gal_fits_key_read (char *filename, char *hdu, gal_data_t
          *keysll, int readcomment, int readunit, char *hdu_option_name)
     Same as ‘gal_fits_read_keywords_fptr’ (see above), but accepts the
     filename and HDU as input instead of an already opened CFITSIO
     ‘fitsfile’ pointer.

 -- Function:
          void
          gal_fits_key_list_add (gal_fits_list_key_t **list, uint8_t
          type, char *keyname, int kfree, void *value, int vfree, char
          *comment, int cfree, char *unit, int ufree)
     Add a keyword to the top of list of header keywords that need to be
     written into a FITS file.  In the end, the keywords will have to be
     freed, so it is important to know before hand if they were
     allocated or not (hence the presence of the arguments ending in
     ‘free’).  If the space for the respective element is not allocated,
     set these arguments to ‘0’ (zero).

     You can call this function multiple times on a single list add
     several keys that will be written in one call to
     ‘gal_fits_key_write’ or ‘gal_fits_key_write_in_ptr’.  However, the
     resulting list will be a last-in-first-out list (for more on lists,
     see *note Linked lists::).  Hence, the written keys will have the
     inverse order of your calls to this function.  To avoid this
     problem, you can either use ‘gal_fits_key_list_add_end’ instead
     (which will add each key to the end of the list, not to the top
     like this function).  Alternatively, you can use
     ‘gal_fits_key_list_reverse’ after adding all the keys with this
     function.

     *Important note for strings*: the value should be the pointer to
     the string its-self (‘char *’), not a pointer to a pointer (‘char
     **’).

 -- Function:
          void
          gal_fits_key_list_add_end (gal_fits_list_key_t **list, uint8_t
          type, char *keyname, int kfree, void *value, int vfree, char
          *comment, int cfree, char *unit, int ufree)
     Similar to ‘gal_fits_key_list_add’, but add the given keyword to
     the end of the list, see the description of ‘gal_fits_key_list_add’
     for more.  Use this function if you want the keywords to be written
     in the same order that you add nodes to the list of keywords.

 -- Function:
          void
          gal_fits_key_list_title_add (gal_fits_list_key_t **list, char
          *title, int tfree)
     Add a special "title" keyword (with the ‘title’ string) to the top
     of the keywords list.  If ‘cfree’ is non-zero, the space allocated
     for ‘comment’ will be freed immediately after writing the keyword
     (in another function).

 -- Function:
          void
          gal_fits_key_list_title_add_end (gal_fits_list_key_t **list,
          char *title, int tfree)
     Similar to ‘gal_fits_key_list_title_add’, but put the comments at
     the end of the list.

 -- Function:
          void
          gal_fits_key_list_fullcomment_add (gal_fits_list_key_t **list,
          char *comment, int fcfree)
     Add a ‘COMMENT’ keyword to the top of the keywords list.  If the
     comment is longer than 70 characters, CFITSIO will automatically
     break it into multiple ‘COMMENT’ keywords.  If ‘fcfree’ is
     non-zero, the space allocated for ‘comment’ will be freed
     immediately after writing the keyword (in another function).

 -- Function:
          void
          gal_fits_key_list_fullcomment_add_end (gal_fits_list_key_t
          **list, char *comment, int fcfree)
     Similar to ‘gal_fits_key_list_comment_add’, but put the comments at
     the end of the list.

 -- Function:
          void
          gal_fits_key_list_add_date (gal_fits_list_key_t **keylist,
          char *comment)
     Add a ‘DATE’ keyword to the input list of keywords containing the
     date this function was activated in the format of
     ‘YYYY-MM-DDThh:mm:ss’.  This function will also add a ‘DATEUTC’
     keyword that specifies if the date is in UTC or local time (this
     depends on CFITSIO being able to detect UTC in the running
     operating system or not).

     The comment of the keyword should also be specified as the second
     argument.  The comment is useful to inform users what this date
     refers to; for example the program starting time, its ending time,
     or etc.  For more, see the description under ‘DATE’ in *note Output
     FITS files::.

 -- Function:
          void
          gal_fits_key_list_add_software_versions (gal_fits_list_key_t
          **keylist)
     Add the version of Gnuastro *note Mandatory dependencies:: to the
     list of keywords.  Each software's keyword has the same name as the
     software itself (for example ‘GNUASTRO’ or ‘GSL’.  For the full
     list of software, see *note Output FITS files::.

 -- Function:
          void
          gal_fits_key_list_add_git_commit (gal_fits_list_key_t
          **keylist)
     If the optional libgit2 dependency is installed and your program is
     being run in a directory that is under version control, a ‘COMMIT’
     keyword will be added on the top of the list of keywords.  For
     more, see the description of ‘COMMIT’ in *note Output FITS files::.

 -- Function:
          void
          gal_fits_key_list_reverse (gal_fits_list_key_t **list)
     Reverse the input list of keywords.

 -- Function:
          void
          gal_fits_key_write_title_in_ptr (char *title, fitsfile *fptr)
     Add two lines of "title" keywords to the given CFITSIO ‘fptr’
     pointer.  The first line will be blank and the second will have the
     string in ‘title’ roughly in the middle of the line (a fixed
     distance from the start of the keyword line).  A title in the list
     of keywords helps in classifying the keywords into groups and
     inspecting them by eye.  If ‘title==NULL’, this function will not
     do anything.

 -- Function:
          void
          gal_fits_key_write_filename (char *keynamebase, char
          *filename, gal_fits_list_key_t **list, int top1end0, int
          quiet)
     Put ‘filename’ into the ‘gal_fits_list_key_t’ list (possibly broken
     up into multiple keywords) to later write into a HDU header.  The
     ‘keynamebase’ string will be appended with a ‘_N’ (N>0) and used as
     the keyword name.  If ‘top1end0!=0’, then the keywords containing
     the filename will be added to the top of the list.

     The FITS standard sets a maximum length of 69 characters for the
     string values of a keyword(1).  This creates problems with file
     names (which include directories) because file names/addresses can
     become longer than the maximum number of characters in a FITS
     keyword (around 70 characters).  Therefore, when ‘filename’ is
     longer than the maximum length of a FITS keyword value, this
     function will break it into several keywords (breaking up the
     string on directory separators).  So the full file/directory
     address (including directories) can be longer than 69 characters.
     However, if a single file or directory name (within a larger
     address) is longer than 69 characters, this function will truncate
     the name and print a warning.  If ‘quiet!=0’, then the warning will
     not be printed.

 -- Function:
          void
          gal_fits_key_write_wcsstr (fitsfile *fptr, struct wcsprm wcs,
          char *wcsstr, int nkeyrec)

     Write the WCS header string (produced with WCSLIB's ‘wcshdo’
     function) into the CFITSIO ‘fitsfile’ pointer.  ‘nkeyrec’ is the
     number of FITS header keywords in ‘wcsstr’.  This function will put
     a few blank keyword lines along with a comment ‘WCS information’
     before writing each keyword record.

 -- Function:
          void
          gal_fits_key_write (gal_fits_list_key_t **keylist, char
          *filename, char *hdu, char *hdu_option_name, int freekeys, int
          create_fits_not_exists)
     Write the list of keywords in ‘keylist’ into the ‘hdu’ extension of
     the file called ‘filename’.  If the file may not exist before this
     function is activated, set ‘create_fits_not_exists’ to non-zero and
     set the HDU to ‘"0"’.  If the keywords should be freed after they
     are written, set the ‘freekeys’ value to non-zero.  For more on
     ‘hdu_option_name’ see the description of ‘gal_array_read’ in *note
     Array input output::.

     The list nodes are meant to be dynamically allocated (because they
     will be freed after being written).  We thus recommend using the
     ‘gal_fits_key_list_add’ or ‘gal_fits_key_list_add_end’ to create
     and fill the list.  Below is one fully working example of using
     this function to write a keyword into an existing FITS file.

          #include <stdio.h>
          #include <stdlib.h>
          #include <gnuastro/fits.h>

          int main()
          {
            char *filename="test.fits";
            gal_fits_list_key_t *keylist=NULL;

            char *unit="unit";
            float value=123.456;
            char *keyname="MYKEY";
            char *comment="A good description of the key";
            gal_fits_key_list_add_end(&keylist, GAL_TYPE_FLOAT32, keyname, 0,
                                      &value, 0, comment, 0, unit, 0);
            gal_fits_key_list_title_add(&keylist, "Matching metadata", 0);
            gal_fits_key_write(&keylist, filename, "1", "NONE", 1, 0);
            return EXIT_SUCCESS;
          }

 -- Function:
          void
          gal_fits_key_write_in_ptr (gal_fits_list_key_t **keylist,
          fitsfile *fptr, int freekeys)
     Write the list of keywords in ‘keylist’ into the given CFITSIO
     ‘fitsfile’ pointer and free keylist.  For more on the input
     ‘keylist’, see the description and example for
     ‘gal_fits_key_write’, above.

 -- Function:
          gal_list_str_t *
          gal_fits_with_keyvalue (gal_list_str_t *files, char *hdu, char
          *name, gal_list_str_t *values, char *hdu_option_name)
     Given a list of FITS file names (‘files’), a certain HDU (‘hdu’), a
     certain keyword name (‘name’), and a list of acceptable values
     (‘values’), return the subset of file names where the requested
     keyword name has one of the acceptable values.  For more on
     ‘hdu_option_name’ see the description of ‘gal_array_read’ in *note
     Array input output::.

 -- Function:
          gal_list_str_t *
          gal_fits_unique_keyvalues (gal_list_str_t *files, char *hdu,
          char *name, char *hdu_option_name)
     Given a list of FITS file names (‘files’), a certain HDU (‘hdu’), a
     certain keyword name (‘name’), return the list of unique values to
     that keyword name in all the files.  For more on ‘hdu_option_name’
     see the description of ‘gal_array_read’ in *note Array input
     output::.

   ---------- Footnotes ----------

   (1) The limit is actually 71 characters (which is the full 80
character length, subtracted by 8 for the keyword name and one character
for the <=>).  However, for strings, FITS also requires two single
quotes.


File: gnuastro.info,  Node: FITS arrays,  Next: FITS tables,  Prev: FITS header keywords,  Up: FITS files

12.3.11.5 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.

 -- Function:
          void
          gal_fits_img_info (fitsfile *fptr, int *type, size_t *ndim,
          size_t **dsize, char **name, char **unit)
     Read the type (see *note Library data types::), number of
     dimensions, and size along each dimension of the CFITSIO ‘fitsfile’
     into the ‘type’, ‘ndim’, and ‘dsize’ pointers respectively.  If
     ‘name’ and ‘unit’ are not ‘NULL’ (point to a ‘char *’), then if the
     image has a name and units, the respective string will be put in
     these pointers.

 -- Function:
          size_t *
          gal_fits_img_info_dim (char *filename, char *hdu, size_t
          *ndim, char *hdu_option_name)
     Put the number of dimensions in the ‘hdu’ extension of ‘filename’
     in the space that ‘ndim’ points to and return the size of the
     dataset along each dimension as an allocated array with ‘*ndim’
     elements.  For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

 -- Function:
          gal_data_t *
          gal_fits_img_read (char *filename, char *hdu, size_t
          minmapsize, int quietmmap, char *hdu_option_name)
     Read the contents of the ‘hdu’ extension/HDU of ‘filename’ into a
     Gnuastro generic data container (see *note Generic data
     container::) and return it.  If the necessary space is larger than
     ‘minmapsize’, then do not keep the data in RAM, but in a file on
     the HDD/SSD. For more on ‘minmapsize’ and ‘quietmmap’ see the
     description under the same name in *note Generic data container::.
     For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

     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 ‘gal_wcs_read’
     function as shown below.  Afterwards, the ‘gal_data_free’ function
     will free both the dataset and any WCS structure (if there are
     any).
          data=gal_fits_img_read(filename, hdu, -1, 1, NULL);
          data->wcs=gal_wcs_read(filename, hdu, 0, 0, 0, &data->wcs->nwcs,
                                 NULL);

 -- Function:
          gal_data_t *
          gal_fits_img_read_to_type (char *inputname, char *inhdu,
          uint8_t type, size_t minmapsize, int quietmmap, char
          *hdu_option_name)
     Read the contents of the ‘hdu’ extension/HDU of ‘filename’ into a
     Gnuastro generic data container (see *note Generic data
     container::) of type ‘type’ and return it.

     This is just a wrapper around ‘gal_fits_img_read’ (to read the
     image/array of any type) and ‘gal_data_copy_to_new_type_free’ (to
     convert it to ‘type’ and free the initially read dataset).  See the
     description there for more.

 -- Function:
          gal_data_t *
          gal_fits_img_read_kernel (char *filename, char *hdu, size_t
          minmapsize, int quietmmap, char *hdu_option_name)
     Read the ‘hdu’ of ‘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
     *note Convolution process::).  If there are blank values, this
     function will change the blank values to ‘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 ‘float32’ type.

     For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

 -- Function:
          fitsfile *
          gal_fits_img_write_to_ptr (gal_data_t *input, char *filename,
          gal_fits_list_key_t *keylist, int freekeys)
     Write the ‘input’ dataset into a FITS file named ‘filename’ and
     return the corresponding CFITSIO ‘fitsfile’ pointer.  This function
     will not close ‘fitsfile’, so you can still add other extensions to
     it after this function or make other modifications.

     In case you want to add keywords into the HDU that contain the
     data, you can use the second two arguments (see the description of
     ‘gal_fits_key_write’).  These keywords will be written into the HDU
     before writing the data: when there are more than roughly 5
     keywords (assuming your dataset has WCS) and your dataset is large,
     this can result in significant optimization of the running time
     (because adding a keyword beyond the 36 key slots will cause the
     whole data to shift for another block of 36 keywords).

 -- Function:
          void
          gal_fits_img_write (gal_data_t *data, char *filename,
          gal_fits_list_key_t *keylist, int freekeys)
     Write the ‘input’ dataset into the FITS file named ‘filename’.
     Also add the list of header keywords (‘keylist’) to the newly
     created HDU/extension The list of keywords will be freed after
     writing into the HDU, if you need them later, keep a separate copy
     of the list before calling this function.

     For the importance of why it is better to add your keywords in this
     function (before writing the data) or after it, see the description
     of ‘gal_fits_img_write_to_ptr’.

 -- Function:
          void
          gal_fits_img_write_to_type (gal_data_t *data, char *filename,
          gal_fits_list_key_t *keylist, int type, int freekeys)
     Convert the ‘input’ dataset into ‘type’, then write it into the
     FITS file named ‘filename’.  Also add the ‘keylist’ keywords to the
     newly created HDU/extension along with your program's name
     (‘program_string’).  After the FITS file is written, this function
     will free the copied dataset (with type ‘type’) from memory.

     For the importance of why it is better to add your keywords in this
     function (before writing the data) or after it, see the description
     of ‘gal_fits_img_write_to_ptr’.  This is just a wrapper for the
     ‘gal_data_copy_to_new_type’ and ‘gal_fits_img_write’ functions.

 -- Function:
          void
          gal_fits_img_write_corr_wcs_str (gal_data_t *data, char
          *filename, char *wcsstr, int nkeyrec, double *crpix,
          gal_fits_list_key_t *keylist, int freekeys)
     Write the ‘input’ dataset into ‘filename’ using the ‘wcsstr’ while
     correcting the ‘CRPIX’ values.  For the importance of why it is
     better to add your keywords in this function (before writing the
     data) or after it, see the description of
     ‘gal_fits_img_write_to_ptr’.

     This function is mainly useful when you want to make FITS files in
     parallel (from one main WCS structure, with just a differing
     CRPIX), for more on the arguments, see the description of
     ‘gal_fits_img_write’.  This can happen in the following cases for
     example:

        • 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.

        • 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.


File: gnuastro.info,  Node: FITS tables,  Prev: FITS arrays,  Up: FITS files

12.3.11.6 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.

 -- Function:
          void
          gal_fits_tab_size (fitsfile *fitsptr, size_t *nrows, size_t
          *ncols)
     Read the number of rows and columns in the table within CFITSIO's
     ‘fitsptr’.

 -- Function:
          int
          gal_fits_tab_format (fitsfile *fitsptr)
     Return the format of the FITS table contained in CFITSIO's
     ‘fitsptr’.  Recall that FITS tables can be in binary or ASCII
     formats.  This function will return ‘GAL_TABLE_FORMAT_AFITS’ or
     ‘GAL_TABLE_FORMAT_BFITS’ (defined in *note Table input output::).
     If the ‘fitsptr’ is not a table, this function will abort the
     program with an error message informing the user of the problem.

 -- Function:
          gal_data_t *
          gal_fits_tab_info (char *filename, char *hdu, size_t *numcols,
          size_t *numrows, int *tableformat, char *hdu_option_name)
     Store the information of each column in ‘hdu’ of ‘filename’ into an
     array of data structures with ‘numcols’ elements (one data
     structure for each column) see *note Arrays of datasets::.  The
     total number of rows in the table is also put into the memory that
     ‘numrows’ points to.  The format of the table (e.g., FITS binary or
     ASCII table) will be put in ‘tableformat’ (macros defined in *note
     Table input output::).  For more on ‘hdu_option_name’ see the
     description of ‘gal_array_read’ in *note Array 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 ‘array’ or ‘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 ‘gal_table_info’ which will allow
     getting information from a variety of table formats based on the
     filename (see *note Table input output::).

 -- Function:
          gal_data_t *
          gal_fits_tab_read (char *filename, char *hdu, size_t numrows,
          gal_data_t *colinfo, gal_list_sizet_t *indexll, size_t
          numthreads, size_t minmapsize, int quietmmap, char
          *hdu_option_name)
     Read the columns given in the list ‘indexll’ from a FITS table (in
     ‘filename’ and HDU/extension ‘hdu’) into the returned linked list
     of data structures, see *note List of size_t:: and *note List of
     gal_data_t::.  For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

     Each column will be read independently, therefore they will be read
     in ‘numthreads’ CPU threads to greatly speed up the reading when
     there are many columns and rows.  However, this only happens if
     CFITSIO was configured with ‘--enable-reentrant’.  This test has
     been done at Gnuastro's configuration time; if so,
     ‘GAL_CONFIG_HAVE_FITS_IS_REENTRANT’ will have a value of 1,
     otherwise, it will have a value of 0.  For more on this macro, see
     *note Configuration information::).

     If the necessary space for each column is larger than ‘minmapsize’,
     do not keep it in the RAM, but in a file in the HDD/SSD. For more
     on ‘minmapsize’ and ‘quietmmap’, see the description under the same
     name in *note Generic data container::.

     Each column will have ‘numrows’ rows and ‘colinfo’ contains any
     further information about the columns (returned by
     ‘gal_fits_tab_info’, described above).  Note that this is a
     low-level function, so the output data linked list is the inverse
     of the input indexes linked list.  It is recommended to use
     ‘gal_table_read’ for generic reading of tables, see *note Table
     input output::.

 -- Function:
          void
          gal_fits_tab_write (gal_data_t *cols, gal_list_str_t
          *comments, int tableformat, char *filename, char *extname,
          gal_fits_list_key_t *keywords, int freekeys)
     Write the list of datasets in ‘cols’ (see *note List of
     gal_data_t::) as separate columns in a FITS table in ‘filename’.
     If ‘filename’ already exists then this function will write the
     table as a new extension called ‘extname’, after all existing ones.
     The format of the table (ASCII or binary) may be specified with the
     ‘tableformat’ (see *note Table input output::).  If
     ‘comments!=NULL’, each node of the list of strings will be written
     as a ‘COMMENT’ keywords in the output FITS file (see *note List of
     strings::.

     In case your table needs metadata keywords, you can use the
     ‘listkeys’ and ‘freekeys’.  For more on these, see the description
     of ‘gal_fits_key_write_in_ptr’.

     This is a low-level function for tables.  It is recommended to use
     ‘gal_table_write’ for generic writing of tables in a variety of
     formats, see *note Table input output::.


File: gnuastro.info,  Node: File input output,  Next: World Coordinate System,  Prev: FITS files,  Up: Gnuastro library

12.3.12 File input output
-------------------------

The most commonly used file format in astronomical data analysis is the
FITS format (see *note Fits:: for an introduction), therefore Gnuastro's
library provides a large and separate collection of functions to
read/write data from/to them (see *note 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.
* TIFF files::                  Reading and writing from/to TIFF files.
* JPEG files::                  Reading and writing from/to JPEG files.
* EPS files::                   Writing to EPS files.
* PDF files::                   Writing to PDF files.


File: gnuastro.info,  Node: Text files,  Next: TIFF files,  Prev: File input output,  Up: File input output

12.3.12.1 Text files (‘txt.h’)
..............................

The most universal and portable format for data storage are plain text
files.  They can be viewed and edited on any text editor or even on the
command-line.  This section are describes some functions that help in
reading from and writing to plain text files.

   Lines are one of the most basic building blocks (delimiters) of a
text file.  Some operating systems like Microsoft Windows, terminate
their ASCII text lines with a carriage return character and a new-line
character (two characters, also known as CRLF line terminators).  While
Unix-like operating systems just use a single new-line character.  The
functions below that read an ASCII text file are able to identify lines
with both kinds of line terminators.

   Gnuastro defines a simple format for metadata of table columns in a
plain text file that is discussed in *note Gnuastro text table format::.
The functions to get information from, read from and write to plain text
files also follow those conventions.

 -- Macro: GAL_TXT_LINESTAT_INVALID
 -- Macro: GAL_TXT_LINESTAT_BLANK
 -- Macro: GAL_TXT_LINESTAT_COMMENT
 -- Macro: GAL_TXT_LINESTAT_DATAROW
     Status codes for lines in a plain text file that are returned by
     ‘gal_txt_line_stat’.  Lines which have a <#> character as their
     first non-white character are considered to be comments.  Lines
     with nothing but white space characters are considered blank.  The
     remaining lines are considered as containing data.

 -- Function:
          int
          gal_txt_line_stat (char *line)
     Check the contents of ‘line’ and see if it is a blank, comment, or
     data line.  The returned values are the macros that start with
     ‘GAL_TXT_LINESTAT’.

 -- Function:
          char *
          gal_txt_trim_space (char *str)
     Trim the white space characters before and after the given string.
     The operation is done within the allocated space of the string, so
     if you need the string untouched, please pass an allocated copy of
     the string to this function.  The returned pointer is within the
     input string.  If the input pointer is ‘NULL’, or the string only
     has white-space characters, the returned pointer will be ‘NULL’.

 -- Function:
          int
          gal_txt_contains_string (char *full, char *match)
     Return 1 if the string that ‘match’ points to, can be exactly found
     within the string that ‘full’ points to (character by character).
     The to-match string can be in any part of the full string.  If any
     of the two strings have zero length or are a ‘NULL’ pointer, this
     function will return 0.

 -- Function:
          gal_data_t *
          gal_txt_table_info (char *filename, gal_list_str_t *lines,
          size_t *numcols, size_t *numrows)
     Store the information of each column in a text file ‘filename’, or
     list of strings (‘lines’) into an array of data structures with
     ‘numcols’ elements (one data structure for each column) see *note
     Arrays of datasets::.  The total number of rows in the table is
     also put into the memory that ‘numrows’ points to.

     ‘lines’ is a list of strings with each node representing one line
     (including the new-line character), see *note List of strings::.
     It will mostly be the output of ‘gal_txt_stdin_read’, which is used
     to read the program's input as separate lines from the standard
     input (see below).  Note that ‘filename’ and ‘lines’ are mutually
     exclusive and one of them must be ‘NULL’.

     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 ‘array’ or ‘dsize’
     elements) will be allocated by this function.  This is a low-level
     function particular to reading tables in plain text format.  To be
     generic, it is recommended to use ‘gal_table_info’ which will allow
     getting information from a variety of table formats based on the
     filename (see *note Table input output::).

 -- Function:
          gal_data_t *
          gal_txt_table_read (char *filename, gal_list_str_t *lines,
          size_t numrows, gal_data_t *colinfo, gal_list_sizet_t
          *indexll, size_t minmapsize, int quietmmap)
     Read the columns given in the list ‘indexll’ from a plain text file
     (‘filename’) or list of strings (‘lines’), into a linked list of
     data structures (see *note List of size_t:: and *note List of
     gal_data_t::).  If the necessary space for each column is larger
     than ‘minmapsize’, do not keep it in the RAM, but in a file on the
     HDD/SSD. For more one ‘minmapsize’ and ‘quietmmap’, see the
     description under the same name in *note Generic data container::.

     ‘lines’ is a list of strings with each node representing one line
     (including the new-line character), see *note List of strings::.
     It will mostly be the output of ‘gal_txt_stdin_read’, which is used
     to read the program's input as separate lines from the standard
     input (see below).  Note that ‘filename’ and ‘lines’ are mutually
     exclusive and one of them must be ‘NULL’.

     Note that this is a low-level function, so the output data list is
     the inverse of the input indices linked list.  It is recommended to
     use ‘gal_table_read’ for generic reading of tables in any format,
     see *note Table input output::.

 -- Function:
          gal_data_t *
          gal_txt_image_read (char *filename, gal_list_str_t *lines,
          size_t minmapsize, int quietmmap)
     Read the 2D plain text dataset in file (‘filename’) or list of
     strings (‘lines’) into a dataset and return the dataset.  If the
     necessary space for the image is larger than ‘minmapsize’, do not
     keep it in the RAM, but in a file on the HDD/SSD. For more on
     ‘minmapsize’ and ‘quietmmap’, see the description under the same
     name in *note Generic data container::.

     ‘lines’ is a list of strings with each node representing one line
     (including the new-line character), see *note List of strings::.
     It will mostly be the output of ‘gal_txt_stdin_read’, which is used
     to read the program's input as separate lines from the standard
     input (see below).  Note that ‘filename’ and ‘lines’ are mutually
     exclusive and one of them must be ‘NULL’.

 -- Function:
          gal_list_str_t *
          gal_txt_stdin_read (long timeout_microsec)
     Read the complete standard input and return a list of strings with
     each line (including the new-line character) as one node of that
     list.  If the standard input is already filled (for example,
     connected to another program's output with a pipe), then this
     function will parse the whole stream.

     If Standard input is not pre-configured and the _first line_ is
     typed/written in the terminal before ‘timeout_microsec’
     micro-seconds, it will continue parsing until reaches an
     end-of-file character (<CTRL-D> after a new-line on the keyboard)
     with no time limit.  If nothing is entered before
     ‘timeout_microsec’ micro-seconds, it will return ‘NULL’.

     All the functions that can read plain text tables will accept a
     filename as well as a list of strings (intended to be the output of
     this function for using Standard input).  The reason for keeping
     the standard input is that once something is read from the standard
     input, it is hard to put it back.  We often need to read a text
     file several times: once to count how many columns it has and which
     ones are requested, and another time to read the desired columns.
     So it easier to keep it all in allocated memory and pass it on from
     the start for each round.

 -- Function:
          gal_list_str_t *
          gal_txt_read_to_list (char *filename)
     Read the contents of the given plain-text file and put each word
     (separated by a SPACE character, into a new node of the output
     list.  The order of nodes in the output is the same as the input.
     Any new-line character at the end of a word is removed in the
     output list.

 -- Function:
          void
          gal_txt_write (gal_data_t *cols, struct gal_fits_list_key_t
          **keylist, gal_list_str_t *comment, char *filename, uint8_t
          colinfoinstdout, int tab0_img1, int freekeys)
     Write ‘cols’ in a plain text file ‘filename’ (table when
     ‘tab0_img1==0’ and image when ‘tab0_img1==1’).  ‘cols’ may have one
     or two dimensions which determines the output:

     1D
          ‘cols’ is treated as a column and a list of datasets (see
          *note List of gal_data_t::): every node in the list is written
          as one column in a table.

     2D
          ‘cols’ is a two dimensional array, it cannot be treated as a
          list (only one 2D array can currently be written to a text
          file).  So if ‘cols->next!=NULL’ the next nodes in the list
          are ignored and will not be written.

     This is a low-level function for tables.  It is recommended to use
     ‘gal_table_write’ for generic writing of tables in a variety of
     formats, see *note Table input output::.

     It is possible to add two types of metadata to the printed table:
     comments and keywords.  Each string in the list given to ‘comments’
     will be printed into the file as a separate line, starting with
     ‘#’.  Keywords have a more specific and computer-parsable format
     and are passed through ‘keylist’.  Each keyword is also printed in
     one line, but with the format below.  Because of the various
     components in a keyword, it is thus necessary to use the
     ‘gal_fits_list_key_t’ data structure.  For more, see *note FITS
     header keywords::.

          # [key] NAME: VALUE / [UNIT] KEYWORD COMMENT.

     If ‘filename’ already exists this function will abort with an error
     and will not write over the existing file.  Before calling this
     function make sure if the file exists or not.  If ‘comments!=NULL’,
     a ‘#’ will be put at the start of each node of the list of strings
     and will be written in the file before the column meta-data in
     ‘filename’ (see *note List of strings::).

     When ‘filename==NULL’, the column information will be printed on
     the standard output (command-line).  When ‘colinfoinstdout!=0’ and
     ‘filename==NULL’ (columns are printed in the standard output), the
     dataset metadata will also printed in the standard output.  When
     printing to the standard output, the column information can be
     piped into another program for further processing and thus the
     meta-data (lines starting with a ‘#’) must be ignored.  In such
     cases, you only print the column values by passing ‘0’ to
     ‘colinfoinstdout’.


File: gnuastro.info,  Node: TIFF files,  Next: JPEG files,  Prev: Text files,  Up: File input output

12.3.12.2 TIFF files (‘tiff.h’)
...............................

Outside of astronomy, the TIFF standard is arguably the most commonly
used format to store high-precision data/images.  Unlike FITS however,
the TIFF standard only supports images (not tables), but like FITS, it
has support for all standard data types (see *note Numeric data types::)
which is the primary reason other fields use it.

   Another similarity of the TIFF and FITS standards is that TIFF
supports multiple images in one file.  The TIFF standard calls each one
of these images (and their accompanying meta-data) a 'directory'
(roughly equivalent to the FITS extensions).  Unlike FITS however, the
directories can only be identified by their number (counting from zero),
recall that in FITS you can also use the extension name to identify it.

   The functions described here allow easy reading (and later writing)
of TIFF files within Gnuastro or for users of Gnuastro's libraries.
Currently only reading is supported, but if you are interested, please
get in touch with us.

 -- Function:
          int
          gal_tiff_name_is_tiff (char *name)
     Return ‘1’ if ‘name’ has a TIFF suffix.  This can be used to make
     sure that a given input file is TIFF. See ‘gal_tiff_suffix_is_tiff’
     for a list of recognized suffixes.

 -- Function:
          int
          gal_tiff_suffix_is_tiff (char *name)
     Return ‘1’ if ‘suffix’ is a recognized TIFF suffix.  The recognized
     suffixes are ‘tif’, ‘tiff’, ‘TIFF’ and ‘TIFF’.

 -- Function:
          size_t
          gal_tiff_dir_string_read (char *string)
     Return the number within ‘string’ as a ‘size_t’ number to identify
     a TIFF directory.  Note that the directories start counting from
     zero.

 -- Function:
          gal_data_t *
          gal_tiff_read (char *filename, size_t dir, size_t minmapsize,
          int quietmmap)
     Read the ‘dir’ directory within the TIFF file ‘filename’ and return
     the contents of that TIFF directory as ‘gal_data_t’.  If the
     directory's image contains multiple channels, the output will be a
     list (see *note List of gal_data_t::).

 -- Function:
          void
          gal_tiff_write (gal_data_t *in, char *filename, int widthinpx,
          int heightinpix, int bitspersample, int numimg)
     Write the given dataset (‘in’) into ‘filename’ (a TIFF file) with
     the specified image width in pixels (‘widthinpix’),height in pixels
     (‘heightinpix’), bits per sample (‘bitspersample’), and number of
     images (‘numimg’).


File: gnuastro.info,  Node: JPEG files,  Next: EPS files,  Prev: TIFF files,  Up: File input output

12.3.12.3 JPEG files (‘jpeg.h’)
...............................

The JPEG file format is one of the most common formats for storing and
transferring images, recognized by almost all image rendering and
processing programs.  In particular, because of its lossy compression
algorithm, JPEG files can have low volumes, making it used heavily on
the internet.  For more on this file format, and a comparison with
others, please see *note Recognized file formats::.

   For scientific purposes, the lossy compression and very limited
dynamic range (8-bit integers) make JPEG very unattractive for storing
of valuable data.  However, because of its commonality, it will
inevitably be needed in some situations.  The functions here can be used
to read and write JPEG images into Gnuastro's *note Generic data
container::.  If the JPEG file has more than one color channel, each
channel is treated as a separate node in a list of datasets (see *note
List of gal_data_t::).

 -- Function:
          int
          gal_jpeg_name_is_jpeg (char *name)
     Return ‘1’ if ‘name’ has a JPEG suffix.  This can be used to make
     sure that a given input file is JPEG. See ‘gal_jpeg_suffix_is_jpeg’
     for a list of recognized suffixes.

 -- Function:
          int
          gal_jpeg_suffix_is_jpeg (char *name)
     Return ‘1’ if ‘suffix’ is a recognized JPEG suffix.  The recognized
     suffixes are ‘.jpg’, ‘.JPG’, ‘.jpeg’, ‘.JPEG’, ‘.jpe’, ‘.jif’,
     ‘.jfif’ and ‘.jfi’.

 -- Function:
          gal_data_t *
          gal_jpeg_read (char *filename, size_t minmapsize, int
          quietmmap)
     Read the JPEG file ‘filename’ and return the contents as
     ‘gal_data_t’.  If the directory's image contains multiple
     colors/channels, the output will be a list with one node per
     color/channel (see *note List of gal_data_t::).

 -- Function:
          void
          gal_jpeg_write (gal_data_t *in, char *filename, uint8_t
          quality, float widthincm)
     Write the given dataset (‘in’) into ‘filename’ (a JPEG file).  If
     ‘in’ is a list, then each node in the list will be a color channel,
     therefore there can only be 1, 3 or 4 nodes in the list.  If the
     number of nodes is different, then this function will abort the
     program with a message describing the cause.  The lossy JPEG
     compression level can be set through ‘quality’ which is a value
     between 0 and 100 (inclusive, 100 being the best quality).  The
     display width of the JPEG file in units of centimeters (to suggest
     to viewers/users, only a meta-data) can be set through ‘widthincm’.


File: gnuastro.info,  Node: EPS files,  Next: PDF files,  Prev: JPEG files,  Up: File input output

12.3.12.4 EPS files (‘eps.h’)
.............................

The Encapsulated PostScript (EPS) format is commonly used to store
images (or individual/single-page parts of a document) in the PostScript
documents.  For a more complete introduction, please see *note
Recognized file formats::.  To provide high quality graphics, the
Postscript language is a vectorized format, therefore pixels (elements
of a "rasterized" format) are not defined in their context.

   To display rasterized images, PostScript does allow arrays of pixels.
However, since the over-all EPS file may contain many vectorized
elements (for example, borders, text, or other lines over the text) and
interpreting them is not trivial or necessary within Gnuastro's scope,
Gnuastro only provides some functions to write a dataset (in the
‘gal_data_t’ format, see *note Generic data container::) into EPS.

 -- Macro: GAL_EPS_MARK_COLNAME_TEXT
 -- Macro: GAL_EPS_MARK_COLNAME_FONT
 -- Macro: GAL_EPS_MARK_COLNAME_XPIX
 -- Macro: GAL_EPS_MARK_COLNAME_YPIX
 -- Macro: GAL_EPS_MARK_COLNAME_SHAPE
 -- Macro: GAL_EPS_MARK_COLNAME_COLOR
 -- Macro: GAL_EPS_MARK_COLNAME_SIZE1
 -- Macro: GAL_EPS_MARK_COLNAME_SIZE2
 -- Macro: GAL_EPS_MARK_COLNAME_ROTATE
 -- Macro: GAL_EPS_MARK_COLNAME_FONTSIZE
 -- Macro: GAL_EPS_MARK_COLNAME_LINEWIDTH
     Name of column that the required property will be read from.

 -- Macro: GAL_EPS_MARK_DEFAULT_SHAPE
 -- Macro: GAL_EPS_MARK_DEFAULT_COLOR
 -- Macro: GAL_EPS_MARK_DEFAULT_SIZE1
 -- Macro: GAL_EPS_MARK_DEFAULT_SIZE2
 -- Macro: GAL_EPS_MARK_DEFAULT_SIZE2_ELLIPSE
 -- Macro: GAL_EPS_MARK_DEFAULT_ROTATE
 -- Macro: GAL_EPS_MARK_DEFAULT_LINEWIDTH
 -- Macro: GAL_EPS_MARK_DEFAULT_FONT
 -- Macro: GAL_EPS_MARK_DEFAULT_FONTSIZE
     Default values for the various mark properties.  These constants
     will be used if the caller has not provided any of the given
     property.

 -- Function:
          int
          gal_eps_name_is_eps (char *name)
     Return ‘1’ if ‘name’ has an EPS suffix.  This can be used to make
     sure that a given input file is EPS. See ‘gal_eps_suffix_is_eps’
     for a list of recognized suffixes.

 -- Function:
          int
          gal_eps_suffix_is_eps (char *name)
     Return ‘1’ if ‘suffix’ is a recognized EPS suffix.  The recognized
     suffixes are ‘.eps’, ‘.EPS’, ‘.epsf’, ‘.epsi’.

 -- Function:
          void
          gal_eps_to_pt (float widthincm, size_t *dsize, size_t
          *w_h_in_pt)
     Given a specific width in centimeters (‘widthincm’ and the number
     of he dataset's pixels in each dimension (‘dsize’) calculate the
     size of he output in PostScript points.  The output values are
     written in the ‘w_h_in_pt’ array (which has to be allocated before
     calling this unction).  The first element in ‘w_h_in_pt’ is the
     width and the second is the height of the image.

 -- Function:
          uint8_t
          gal_eps_shape_name_to_id (char *name)
     Return the shape ID of a mark from its name (which is not
     case-sensitive).

 -- Function:
          uint8_t
          gal_eps_shape_id_to_name (uint8_t id)
     Return the shape name from its ID.

 -- Function:
          void
          gal_eps_write (gal_data_t *in, char *filename, float
          widthincm, uint32_t borderwidth, uint8_t bordercolor, int hex,
          int dontoptimize, int forps, gal_data_t *marks)
     Write the ‘in’ dataset into an EPS file called ‘filename’.  ‘in’
     has to be an unsigned 8-bit character type ‘GAL_TYPE_UINT8’, see
     *note Numeric data types::).  The desired width of the image in
     human/non-pixel units can be set with he ‘widthincm’ argument.  If
     ‘borderwidth’ is non-zero, it is interpreted as the width (in
     points) of a solid black border around the mage.  A border can
     helpful when importing the EPS file into a document.  The color of
     the border can be set with ‘bordercolor’, use the macros in *note
     Color functions::.  If ‘forpdf’ is not zero, the output can be
     imported into a Postscript file directly (not as an "encapsulated"
     postscript, which is the default).

     EPS files are plain-text (can be opened/edited in a text editor),
     therefore there are different encodings to store the data (pixel
     values) within them.  Gnuastro supports the Hexadecimal and ASCII85
     encoding.  ASCII85 is more efficient (producing small file sizes),
     so it is the default encoding.  To use Hexadecimal encoding, set
     ‘hex’ to a non-zero value.

     By default, when the dataset only has two values, this function
     will use the PostScript optimization that allows setting the pixel
     values per bit, not byte (*note Recognized file formats::).  This
     can greatly help reduce the file size.  However, when
     ‘dontoptimize!=0’, this optimization is disabled: even though there
     are only two values (is binary), the difference between them does
     not correspond to the full contrast of black and white.

     If ‘marks!=NULL’, it is assumed to contain multiple columns of
     information to draw marks over the background image.  The multiple
     columns are a linked list of 1D ‘gal_data_t’ of the same size
     (number of rows) that are connected to each other through the
     ‘next’ element (this is the same format that Gnuastro's library
     uses for tables, see *note Table input output:: or *note Library
     demo - reading and writing table columns::).

     The macros defined above that have the format of
     ‘GAL_EPS_MARK_COLNAME_*’ show all the possible columns that you can
     provide in this linked list.  Only the two coordinate columns are
     mandatory (‘GAL_EPS_MARK_COLNAME_XPIX’ and
     ‘GAL_EPS_MARK_COLNAME_YPIX’.  If any of the other properties is not
     in the linked list, then the default properties of the
     ‘GAL_EPS_MARK_DEFAULT_*’ macros will be used (also defined above.

     The columns are identified based on the ‘name’ element of
     Gnuastro's generic data structure (see *note Generic data
     container::).  The names must have the pre-defined names of the
     ‘GAL_EPS_MARK_COLNAME_*’ macros (case sensitive).  Therefore, the
     order of columns in the list is irrelevant!


File: gnuastro.info,  Node: PDF files,  Prev: EPS files,  Up: File input output

12.3.12.5 PDF files (‘pdf.h’)
.............................

The portable document format (PDF) has arguably become the most common
format used for distribution of documents.  In practice, a PDF file is
just a compiled PostScript file.  For a more complete introduction,
please see *note Recognized file formats::.  To provide high quality
graphics, the PDF is a vectorized format, therefore pixels (elements of
a "rasterized" format) are not defined in their context.  As a result,
similar to *note EPS files::, Gnuastro only writes datasets to a PDF
file, not vice-versa.

 -- Function:
          int
          gal_pdf_name_is_pdf (char *name)
     Return ‘1’ if ‘name’ has an PDF suffix.  This can be used to make
     sure that a given input file is PDF. See ‘gal_pdf_suffix_is_pdf’
     for a list of recognized suffixes.

 -- Function:
          int
          gal_pdf_suffix_is_pdf (char *name)
     Return ‘1’ if ‘suffix’ is a recognized PDF suffix.  The recognized
     suffixes are ‘.pdf’ and ‘.PDF’.

 -- Function:
          void
          gal_pdf_write (gal_data_t *in, char *filename, float
          widthincm, uint32_t borderwidth, uint8_t bordercolor, int
          dontoptimize, gal_data_t *marks)
     Write the ‘in’ dataset into an EPS file called ‘filename’.  ‘in’
     has to be an unsigned 8-bit character type (‘GAL_TYPE_UINT8’, see
     *note Numeric data types::).  The desired width of the image in
     human/non-pixel units can be set with the ‘widthincm’ argument.  If
     ‘borderwidth’ is non-zero, it is interpreted as the width (in
     points) of a solid black border around the image.  A border can
     helpful when importing the PDF file into a document.  The color of
     the border can be set with ‘bordercolor’, use the macros in *note
     Color functions::.

     This function is just a wrapper for the ‘gal_eps_write’ function in
     *note EPS files::.  After making the EPS file, Ghostscript (with a
     version of 9.10 or above, see *note Optional dependencies::) will
     be used to compile the EPS file to a PDF file.  Therefore if
     Ghostscript does not exist, does not have the proper version, or
     fails for any other reason, the EPS file will remain.  It can be
     used to find the cause, or use another converter or PostScript
     compiler.

     By default, when the dataset only has two values, this function
     will use the PostScript optimization that allows setting the pixel
     values per bit,not byte (*note Recognized file formats::).  This
     can greatly help reduce the file size.  However, when
     ‘dontoptimize!=0’, this optimization is disabled: even though there
     are only two values (is binary), the difference between them does
     not correspond to the full contrast of black and white.

     If ‘marks!=NULL’, it is assumed to contain information on how to
     draw marks over the image.  This is directly fed to the
     ‘gal_eps_write’ function, so for more on how to provide the mark
     information, see the description of ‘gal_eps_write’ in *note EPS
     files::.


File: gnuastro.info,  Node: World Coordinate System,  Next: Arithmetic on datasets,  Prev: File input output,  Up: Gnuastro library

12.3.13 World Coordinate System (‘wcs.h’)
-----------------------------------------

The FITS standard defines the world coordinate system (WCS) as a
mechanism to associate physical values to positions within a dataset.
For example, it can be used to convert pixel coordinates in an image to
celestial coordinates like the right ascension and declination.  The
functions in this section are mainly just wrappers over CFITSIO, WCSLIB
and GSL library functions to help in common applications.

   [*Tread safety*] Since WCSLIB version 5.18 (released in January
2018), most WCSLIB functions are thread safe(1).  Gnuastro has
high-level functions to easily spin-off threads and speed up your
programs.  For a fully working example see *note Library demo -
multi-threaded operation::.  However you still need to be cautious in
the following scenarios below.
   • Many users or operating systems may still use an older version.
   • The ‘wcsprm’ structure of WCSLIB is not thread-safe: you can't use
     the same pointer on multiple threads.  For example, if you use
     ‘gal_wcs_img_to_world’ simultaneously on multiple threads, you
     shouldn't pass the same ‘wcsprm’ structure pointer.  You can use
     ‘gal_wcs_copy’ to keep and use separate copies the main structure
     within each thread, and later free the copies with ‘gal_wcs_free’.

   The full set of functions and global constants that are defined by
Gnuastro's ‘gnuastro/wcs.h’ are described below.

 -- Global integer: GAL_WCS_DISTORTION_TPD
 -- Global integer: GAL_WCS_DISTORTION_SIP
 -- Global integer: GAL_WCS_DISTORTION_TPV
 -- Global integer: GAL_WCS_DISTORTION_DSS
 -- Global integer: GAL_WCS_DISTORTION_WAT
 -- Global integer: GAL_WCS_DISTORTION_INVALID
     Gnuastro identifiers of the various WCS distortion conventions, for
     more, see Calabretta et al.  (2004, preprint)(2).  Among these, SIP
     is a prior distortion, the rest other are sequent distortions.  TPD
     is a superset of all these, hence it has both prior and sequeal
     distortion coefficients.  More information is given in the
     documentation of ‘dis.h’, from the WCSLIB manual(3).

 -- Global integer: GAL_WCS_COORDSYS_EQB1950
 -- Global integer: GAL_WCS_COORDSYS_EQJ2000
 -- Global integer: GAL_WCS_COORDSYS_ECB1950
 -- Global integer: GAL_WCS_COORDSYS_ECJ2000
 -- Global integer: GAL_WCS_COORDSYS_GALACTIC
 -- Global integer: GAL_WCS_COORDSYS_SUPERGALACTIC
 -- Global integer: GAL_WCS_COORDSYS_INVALID
     Recognized WCS coordinate systems in Gnuastro.  ‘EQ’ and ‘EC’ stand
     for the EQuatorial and ECliptic coordinate systems.  In the
     equatorial and ecliptic coordinates, ‘B1950’ stands for the
     Besselian 1950 epoch and ‘J2000’ stands for the Julian 2000 epoch.

 -- Global integer: GAL_WCS_LINEAR_MATRIX_PC
 -- Global integer: GAL_WCS_LINEAR_MATRIX_CD
 -- Global integer: GAL_WCS_LINEAR_MATRIX_INVALID
     Identifiers of the linear transformation matrix: either in the
     ‘PCi_j’ or the ‘CDi_j’ formalism.  For more, see the description of
     ‘--wcslinearmatrix’ in *note Input output options::.

 -- Global integer: GAL_WCS_PROJECTION_AZP
 -- Global integer: GAL_WCS_PROJECTION_SZP
 -- Global integer: GAL_WCS_PROJECTION_TAN
 -- Global integer: GAL_WCS_PROJECTION_STG
 -- Global integer: GAL_WCS_PROJECTION_SIN
 -- Global integer: GAL_WCS_PROJECTION_ARC
 -- Global integer: GAL_WCS_PROJECTION_ZPN
 -- Global integer: GAL_WCS_PROJECTION_ZEA
 -- Global integer: GAL_WCS_PROJECTION_AIR
 -- Global integer: GAL_WCS_PROJECTION_CYP
 -- Global integer: GAL_WCS_PROJECTION_CEA
 -- Global integer: GAL_WCS_PROJECTION_CAR
 -- Global integer: GAL_WCS_PROJECTION_MER
 -- Global integer: GAL_WCS_PROJECTION_SFL
 -- Global integer: GAL_WCS_PROJECTION_PAR
 -- Global integer: GAL_WCS_PROJECTION_MOL
 -- Global integer: GAL_WCS_PROJECTION_AIT
 -- Global integer: GAL_WCS_PROJECTION_COP
 -- Global integer: GAL_WCS_PROJECTION_COE
 -- Global integer: GAL_WCS_PROJECTION_COD
 -- Global integer: GAL_WCS_PROJECTION_COO
 -- Global integer: GAL_WCS_PROJECTION_BON
 -- Global integer: GAL_WCS_PROJECTION_PCO
 -- Global integer: GAL_WCS_PROJECTION_TSC
 -- Global integer: GAL_WCS_PROJECTION_CSC
 -- Global integer: GAL_WCS_PROJECTION_QSC
 -- Global integer: GAL_WCS_PROJECTION_HPX
 -- Global integer: GAL_WCS_PROJECTION_XPH
     The various types of recognized FITS WCS projections; for more
     details see *note Align pixels with WCS considering distortions::.

 -- Macro: GAL_WCS_FLTERROR
     Limit of rounding for floating point errors.

 -- Function:
          int
          gal_wcs_distortion_name_to_id (char *name)
     Convert the given string (assumed to be a FITS-standard,
     string-based distortion identifier) to a Gnuastro's integer-based
     distortion identifier (one of the ‘GAL_WCS_DISTORTION_*’ macros
     defined above).  The sting-based distortion identifiers have three
     characters and are all in capital letters.

 -- Function:
          int
          gal_wcs_distortion_name_from_id (int id)
     Convert the given Gnuastro integer-based distortion identifier (one
     of the ‘GAL_WCS_DISTORTION_*’ macros defined above) to the
     string-based distortion identifier) of the FITS standard.  The
     sting-based distortion identifiers have three characters and are
     all in capital letters.

 -- Function:
          int
          gal_wcs_coordsys_name_to_id (char *name)
     Convert the given string to Gnuastro's integer-based WCS coordinate
     system identifier (one of the ‘GAL_WCS_COORDSYS_*’, listed above).
     The expected strings can be seen in the description of the
     ‘--wcscoordsys’ option of the Fits program, see *note Keyword
     inspection and manipulation::.

 -- Function:
          int
          gal_wcs_distortion_name_to_id (char *name)
     Convert the given string (assumed to be a FITS-standard,
     string-based distortion identifier) to a Gnuastro's integer-based
     distortion identifier (one of the ‘GAL_WCS_DISTORTION_*’ macros
     defined above).  The sting-based distortion identifiers have three
     characters and are all in capital letters.

 -- Function:
          int
          gal_wcs_projection_name_from_id (int id)
     Convert the given Gnuastro integer-based projection identifier (one
     of the ‘GAL_WCS_PROJECTION_*’ macros defined above) to the
     string-based distortion identifier) of the FITS standard.  The
     string-based projection identifiers have three characters and are
     all in capital letters.  For a description of the various
     projections, see *note Align pixels with WCS considering
     distortions::.

 -- Function:
          int
          gal_wcs_projection_name_to_id (char *name)
     Convert the given string (assumed to be a FITS-standard,
     string-based projection identifier) to a Gnuastro's integer-based
     projection identifier (one of the ‘GAL_WCS_PROJECTION_*’ macros
     defined above).  The string-based projection identifiers have three
     characters and are all in capital letters.  For a description of
     the various projections, see *note Align pixels with WCS
     considering distortions::.

 -- Function:
          struct wcsprm *
          gal_wcs_create (double *crpix, double *crval, double *cdelt,
          double *pc, char **cunit, char **ctype, size_t ndim, int
          linearmatrix)
     Given all the most common standard components of the WCS standard,
     construct a ‘struct wcsprm’, initialize and set it for future
     processing.  See the FITS WCS standard for more on these keywords.
     All the arrays must have ‘ndim’ elements with them except for ‘pc’
     which should have ‘ndim*ndim’ elements (a square matrix).  Also,
     ‘cunit’ and ‘ctype’ are arrays of strings.  If
     ‘GAL_WCS_LINEAR_MATRIX_CD’ is passed to ‘linearmatrix’ then the
     output WCS structure will have a CD matrix (even though you have
     given a PC and CDELT matrix as input to this function).  Otherwise,
     the output will have a PC and CDELT matrix (which is the
     recommended format by WCSLIB).

          #include <stdio.h>
          #include <stdlib.h>
          #include <gnuastro/wcs.h>
          
          int
          main(void)
          {
            int status;
            size_t ndim=2;
            struct wcsprm *wcs;
            double crpix[]={50, 50};
            double pc[]={-1, 0, 0, 1};
            double cdelt[]={0.4, 0.4};
            double crval[]={178.23, 36.98};
            char   *cunit[]={"deg", "deg"};
            char   *ctype[]={"RA---TAN", "DEC--TAN"};
            int linearmatrix = GAL_WCS_LINEAR_MATRIX_PC;
          
            /* Allocate and fill the 'wcsprm' structure. */
            wcs=gal_wcs_create(crpix, crval, cdelt, pc, cunit,
          		     ctype, ndim, linearmatrix);
            printf("WCS structure created.\n");
          
            /*... Add any operation with the WCS structure here ...*/
          
            /* Free the WCS structure. */
            gal_wcs_free(wcs);
            printf("WCS structure freed.\n");
          
            /* Return successfully. */
            return EXIT_SUCCESS;
          }

 -- Function:
          struct wcsprm *
          gal_wcs_read_fitsptr (fitsfile *fptr, int linearmatrix, size_t
          hstartwcs, size_t hendwcs, int *nwcs)
     Return the WCSLIB ‘wcsprm’ structure that is read from the CFITSIO
     ‘fptr’ pointer to an opened FITS file.  With older WCSLIB versions
     (in particular below version 5.18) this function may not be
     thread-safe.

     Also put the number of coordinate representations found into the
     space that ‘nwcs’ points to.  To read the WCS structure directly
     from a filename, see ‘gal_wcs_read’ below.  After processing has
     finished, you should free the WCS structure that this function
     returns with ‘gal_wcs_free’.

     The ‘linearmatrix’ argument takes one of three values: ‘0’,
     ‘GAL_WCS_LINEAR_MATRIX_PC’ and ‘GAL_WCS_LINEAR_MATRIX_CD’.  It will
     determine the format of the WCS when it is later written to file
     with ‘gal_wcs_write’ or ‘gal_wcs_write_in_fitsptr’ (which is called
     by ‘gal_fits_img_write’) So if you do not want to write the WCS
     into a file later, just give it a value of ‘0’.  For more on the
     difference between these modes, see the description of
     ‘--wcslinearmatrix’ in *note Input output options::.

     If you do not want to search the full FITS header for WCS-related
     FITS keywords (for example, due to conflicting keywords), but only
     a specific range of the header keywords you can use the ‘hstartwcs’
     and ‘hendwcs’ arguments to specify the keyword number range
     (counting from zero).  If ‘hendwcs’ is larger than ‘hstartwcs’,
     then only keywords in the given range will be checked.  Hence, to
     ignore this feature (and search the full FITS header), give both
     these arguments the same value.

     If the WCS information could not be read from the FITS file, this
     function will return a ‘NULL’ pointer and put a zero in ‘nwcs’.  A
     WCSLIB error message will also be printed in ‘stderr’ if there was
     an error.

     This function is just a wrapper over WCSLIB's ‘wcspih’ function
     which is not thread-safe.  Therefore, be sure to not call this
     function simultaneously (over multiple threads).

 -- Function:
          struct wcsprm *
          gal_wcs_read (char *filename, char *hdu, int linearmatrix,
          size_t hstartwcs, size_t hendwcs, int *nwcs, char
          *hdu_option_name)
     [*Not thread-safe*] Return the WCSLIB structure that is read from
     the HDU/extension ‘hdu’ of the file ‘filename’.  Also put the
     number of coordinate representations found into the space that
     ‘nwcs’ points to.  Please see ‘gal_wcs_read_fitsptr’ for more.  For
     more on ‘hdu_option_name’ see the description of ‘gal_array_read’
     in *note Array input output::.

     After processing has finished, you should free the WCS structure
     that this function returns with ‘gal_wcs_free’.

 -- Function:
          void
          gal_wcs_free (struct wcsprm *wcs)
     Free the contents _and_ the space that ‘wcs’ points to.  WCSLIB's
     ‘wcsfree’ function only frees the contents of the ‘wcsprm’
     structure, not the actual pointer.  However, Gnuastro's ‘wcsprm’
     creation and reading functions allocate the structure also.  This
     higher-level function therefore simplifies the processing.  A
     complete working example is given in the description of
     ‘gal_wcs_create’.

 -- Function:
          char *
          gal_wcs_dimension_name (struct wcsprm *wcs, size_t dimension)
     Return an allocated string array (that should be freed later)
     containing the first part of the ‘CTYPEi’ FITS keyword (which
     contains the dimension name in the FITS standard).  For example, if
     ‘CTYPE1’ is ‘RA---TAN’, the string that function returns will be
     ‘RA’.  Recall that the second component of ‘CTYPEi’ contains the
     type of projection.

 -- Function:
          char *
          gal_wcs_write_wcsstr (struct wcsprm *wcs, int *nkeyrec)
     Return an allocated string which contains the respective FITS
     keywords for the given WCS structure into it.  The number of
     keywords is written in the space pointed by ‘nkeyrec’.  Each FITS
     keyword is 80 characters wide (according to the FITS standard), and
     the next one is placed immediately after it, so the full string has
     ‘80*nkeyrec’ bytes.  The output of this function can later be
     written into an opened FITS file using ‘gal_fits_key_write_wcsstr’
     (see *note FITS header keywords::).

 -- Function:
          void
          gal_wcs_write (struct wcsprm *wcs, char *filename, char
          *extname, gal_fits_list_key_t *keylist, int freekeys)
     Write the given WCS structure into the second extension of an empty
     FITS header.  The first/primary extension will be empty like the
     default format of all Gnuastro outputs.  When ‘extname!=NULL’ it
     will be used as the FITS extension name.  Any set of extra headers
     can also be written through the ‘keylist’ list.  If ‘freekeys!=0’
     then the list of keywords will be freed after they are written.

 -- Function:
          void
          gal_wcs_write_in_fitsptr (fitsfile *fptr, struct wcsprm *wcs)
     Convert the input ‘wcs’ structure (keeping the WCS
     programmatically) into FITS keywords and write them into the given
     FITS file pointer.  This is a relatively low-level function which
     assumes the FITS file has already been opened with CFITSIO. If you
     just want to write the WCS into an empty file, you can use
     ‘gal_wcs_write’ (which internally calls this function after
     creating the FITS file and later closes it safely).

 -- Function:
          struct wcsprm *
          gal_wcs_copy (struct wcsprm *wcs)
     Return a fully allocated (independent) copy of ‘wcs’.

 -- Function:
          struct wcsprm *
          gal_wcs_copy_new_crval (struct wcsprm *wcs, double *crval)
     Return a fully allocated (independent) copy of ‘wcs’ with a new set
     of ‘CRVAL’ values.  WCSLIB keeps a lot of extra information within
     ‘wcsprm’ and for optimizations, those extra information are used in
     its calculations.  Therefore, if you want to change parameters like
     the reference point's sky coordinate values (‘CRVAL’), simply
     changing the values in ‘wcs->crval[0]’ or ‘wcs->crval[1]’ will not
     affect WCSLIB's calculations; you need to call this function.

 -- Function:
          void
          gal_wcs_remove_dimension (struct wcsprm *wcs, size_t fitsdim)
     Remove the given FITS dimension from the given ‘wcs’ structure.

 -- Function:
          void
          gal_wcs_on_tile (gal_data_t *tile)
     Create a WCSLIB ‘wcsprm’ structure for ‘tile’ using WCS parameters
     of the tile's allocated block dataset, see *note Tessellation
     library:: for the definition of tiles.  If ‘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.

 -- Function:
          double *
          gal_wcs_warp_matrix (struct wcsprm *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.

 -- Function:
          void
          gal_wcs_clean_small_errors (struct wcsprm *wcs)
     Errors can make small differences between the pixel-scale elements
     (‘CDELT’) and can also lead to extremely small values in the ‘PC’
     matrix.  With this function, such errors will be "cleaned" as
     follows: 1) if the maximum difference between the ‘CDELT’ elements
     is smaller than the reference error, it will be set to the mean
     value.  When the FITS keyword ‘CRDER’ (optional) is defined it will
     be used as a reference, if not the default value is
     ‘GAL_WCS_FLTERROR’.  2) If any of the PC elements differ from 0, 1
     or -1 by less than ‘GAL_WCS_FLTERROR’, they will be rounded to the
     respective value.

 -- Function:
          void
          gal_wcs_decompose_pc_cdelt (struct wcsprm *wcs)
     Decompose the ‘PCi_j’ and ‘CDELTi’ elements of ‘wcs’.  According to
     the FITS standard, in the ‘PCi_j’ WCS formalism, the rotation
     matrix elements $m_{ij}$ are encoded in the ‘PCi_j’ keywords and
     the scale factors are encoded in the ‘CDELTi’ keywords.  There is
     also another formalism (the ‘CDi_j’ formalism) which merges the two
     into one matrix.

     However, WCSLIB's internal operations are apparently done in the
     ‘PCi_j’ formalism.  So its outputs are also all in that format by
     default.  When the input is a ‘CDi_j’, WCSLIB will still read the
     matrix directly into the ‘PCi_j’ matrix and the ‘CDELTi’ values are
     set to ‘1’ (one).  This function is designed to correct such
     issues: after it is finished, the ‘CDELTi’ values in ‘wcs’ will
     correspond to the pixel scale, and the ‘PCi_j’ will correction show
     the rotation.

 -- Function:
          void
          gal_wcs_to_cd (struct wcsprm *wcs)
     Make sure that the WCS structure's ‘PCi_j’ and ‘CDi_j’ keywords
     have the same value and that the ‘CDELTi’ keywords have a value of
     1.0.  Also, set the ‘wcs->altlin=2’ (for the ‘CDi_j’ formalism).
     With these changes ‘gal_wcs_write_in_fitsptr’ (and thus
     ‘gal_wcs_write’ and ‘gal_fits_img_write’ and its derivatives) will
     have an output file in the format of ‘CDi_j’.

 -- Function:
          int
          gal_wcs_coordsys_identify (struct wcsprm *wcs)
     Read the given WCS structure and return its coordinate system as
     one of Gnuastro's WCS coordinate system identifiers (the macros
     ‘GAL_WCS_COORDSYS_*’, listed above).

 -- Function:
          struct wcsprm *
          gal_wcs_coordsys_convert (struct wcsprm *inwcs, int
          coordsysid)
     Return a newly allocated WCS structure with the ‘coordsysid’
     coordinate system identifier.  The Gnuastro WCS distortion
     identifiers are defined in the ‘GAL_WCS_COORDSYS_*’ macros
     mentioned above.  Since the returned dataset is newly allocated, if
     you do not need the original dataset after this, use the WCSLIB
     library function ‘wcsfree’ to free the input, for example,
     ‘wcsfree(inwcs)’.

 -- Function:
          void
          gal_wcs_coordsys_convert_points (int sys1, double *lng1_d,
          double *lat1_d, int sys2, double *lng2_d, double *lat2_d,
          size_t number)
     Convert the input set of longitudes (‘lng1_d’, in degrees) and
     latitudes (‘lat1_d’, in degrees) within a recognized coordinate
     system (‘sys1’; one of the ‘GAL_WCS_COORDSYS_*’ macros above) into
     an output coordinate system (‘sys2’).  The output values are
     written in ‘lng2_d’ and ‘lng2_d’.  The total number of points
     should be given in ‘number’.  If you want the operation to be done
     in place (without allocating a new dataset), give the same pointers
     to the coordinate arguments.

 -- Function:
          void
          gal_wcs_coordsys_sys1_ref_in_sys2 (int sys1, int sys2, double
          *lng2, double *lat2)
     Return the longitude and latitude of the reference point (on the
     equator) of the first coordinate system (‘sys1’) within the second
     system (‘sys2’).  Coordinate systems are identified by the
     ‘GAL_WCS_COORDSYS_*’ macros above.

 -- Function:
          int
          gal_wcs_distortion_identify (struct wcsprm *wcs)
     Returns the Gnuastro identifier for the distortion of the input WCS
     structure.  The returned value is one of the ‘GAL_WCS_DISTORTION_*’
     macros defined above.  When the input pointer to a structure is
     ‘NULL’, or it does not contain a distortion, the returned value
     will be ‘GAL_WCS_DISTORTION_INVALID’.

 -- Function:
          struct wcsprm *
          gal_wcs_distortion_convert(struct wcsprm *inwcs, int
          outdisptype, size_t *fitsize)
     Return a newly allocated WCS structure, where the distortion is
     implemented in a different standard, identified by the identifier
     ‘outdisptype’.  The Gnuastro WCS distortion identifiers are defined
     in the ‘GAL_WCS_DISTORTION_*’ macros mentioned above.

     The available conversions in this function will grow.  Currently it
     only supports converting TPV to SIP and vice versa, following the
     recipe of Shupe et al.  (2012)(4).  Please get in touch with us if
     you need other types of conversions.

     For some conversions, direct analytical conversions do not exist.
     It is thus necessary to model and fit the two types.  In such
     cases, it is also necessary to specify the ‘fitsize’ array that is
     the size of the array along each C-ordered dimension, so you can
     simply pass the ‘dsize’ element of your ‘gal_data_t’ dataset, see
     *note Generic data container::.  Currently this is only necessary
     when converting TPV to SIP. For other conversions you may simply
     pass a ‘NULL’ pointer.

     For example, if you want to convert the TPV coefficients of your
     input ‘image.fits’ to SIP coefficients, you can use the following
     functions (which are also available as a command-line operation in
     *note Fits::).

          int nwcs;
          gal_data_t *data=gal_fits_img_read("image.fits", "1", -1, 1, NULL);
          inwcs=gal_wcs_read("image.fits", "1", 0, 0, 0, &nwcs, NULL);
          data->wcs=gal_wcs_distortion_convert(inwcs, GAL_WCS_DISTORTION_TPV,
                                               NULL);
          wcsfree(inwcs);
          gal_fits_img_write(data, "tpv.fits", NULL, 0);

 -- Function:
          double
          gal_wcs_angular_distance_deg (double r1, double d1, double r2,
          double d2)
     Return the angular distance (in degrees) between a point located at
     (‘r1’, ‘d1’) to (‘r2’, ‘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.

    $$\cos(d)=\sin(d_1)\sin(d_2)+\cos(d_1)\cos(d_2)\cos(r_1-r_2)$$

     However, since the pixel scales are usually very small numbers,
     this function will not use that direct formula.  It will be use the
     Haversine formula (https://en.wikipedia.org/wiki/Haversine_formula)
     which is better considering floating point errors:

$${\sin^2(d)\over 2}=\sin^2\left( {d_1-d_2\over 2} \right)+\cos(d_1)\cos(d_2)\sin^2\left( {r_1-r_2\over 2} \right)$$

 -- Function:
          void
          gal_wcs_box_vertices_from_center (double ra_center, double
          dec_center, double ra_delta, double dec_delta, double *out)
     Calculate the vertices of a rectangular box given the central RA
     and Dec and delta of each.  The vertice coordinates are written in
     the space that ‘out’ points to (assuming it has space for eight
     ‘double’s).

     Given the spherical nature of the coordinate system, the vertice
     lengths can't be calculated with a simple addition/subtraction.
     For the declination, a simple addition/subtraction is enough.
     Also, on the equator (where the RA is defined), a simple
     addition/subtraction along the RA is fine.  However, at other
     declinations, the new RA after a shift needs special treatment,
     such that close to the poles, a shift of 1 degree can correspond to
     a new RA that is much more distant than the original RA. Assuming a
     point at Right Ascension (RA) and Declination of $\alpha$ and
     $\delta$, a shift of $R$ degrees along the positive RA direction
     corresponds to a right ascension of
     $\alpha+\frac{R}{\cos(\delta)}$.  For more, see the description of
     ‘box-vertices-on-sphere’ in *note Coordinate and border
     operators::.

     The 8 coordinates of the 4 vertices of the box are written in the
     order below.  Where "bottom" corresponds to a lower declination and
     "top" to higher declination, "left" corresponds to a larger RA and
     "right" corresponds to lower RA.

          out[0]: bottom-left  RA
          out[1]: bottom-left  Dec
          out[2]: bottom-right RA
          out[3]: bottom-right Dec
          out[4]: top-right    RA
          out[5]: top-right    Dec
          out[6]: top-left     RA
          out[7]: top-left     Dec

 -- Function:
          double *
          gal_wcs_pixel_scale (struct wcsprm *wcs)
     Return the pixel scale for each dimension of ‘wcs’ in degrees.  The
     output is an allocated array of double precision floating point
     type with one element for each dimension.  If it is not successful,
     this function will return ‘NULL’.

 -- Function:
          double
          gal_wcs_pixel_area_arcsec2 (struct wcsprm *wcs)
     Return the pixel area of ‘wcs’ in arc-second squared.  This only
     works when the input dataset has at least two dimensions and the
     units of the first two dimensions (‘CUNIT’ keywords) are ‘deg’ (for
     degrees).  In other cases, this function will return a NaN.

 -- Function:
          int
          gal_wcs_coverage (char *filename, char *hdu, size_t *ondim,
          double **ocenter, double **owidth, double **omin, double
          **omax, char *hdu_option_name)
     Find the sky coverage of the image HDU (‘hdu’) within ‘filename’.
     The number of dimensions is written into ‘ndim’, and space for the
     various output arrays is internally allocated and filled with the
     respective values.  Therefore you need to free them afterwards.
     For more on ‘hdu_option_name’ see the description of
     ‘gal_array_read’ in *note Array input output::.

     Currently this function only supports images that are less than 180
     degrees in width (which is usually the case!).  This requirement
     has been necessary to account for images that cross the RA=0 hour
     circle on the sky.  Please get in touch with us at
     <mailto:bug-gnuastro@gnu.org> if you have an image that is larger
     than 180 degrees so we try to find a solution based on need.

 -- Function:
          gal_data_t *
          gal_wcs_world_to_img (gal_data_t *coords, struct wcsprm *wcs,
          int inplace)
     Convert the linked list of world coordinates in ‘coords’ to a
     linked list of image coordinates given the input WCS structure.
     ‘coords’ must be a linked list of data structures of float64
     ('double') type, see*note Linked lists:: and *note List of
     gal_data_t::.  The top (first popped/read) node of the linked list
     must be the first WCS coordinate (RA in an image usually) etc.
     Similarly, the top node of the output will be the first image
     coordinate (in the FITS standard).  In case WCSLIB fails to convert
     any of the coordinates (for example, the RA of one coordinate is
     given as 400!), the respective element in the output will be
     written as NaN.

     If ‘inplace’ is zero, then the output will be a newly allocated
     list and the input list will be untouched.  However, if ‘inplace’
     is non-zero, the output values will be written into the input's
     already allocated array and the returned pointer will be the same
     pointer to ‘coords’ (in other words, you can ignore the returned
     value).  Note that in the latter case, only the values will be
     changed, things like units or name (if present) will be untouched.

 -- Function:
          gal_data_t *
          gal_wcs_img_to_world (gal_data_t *coords, struct wcsprm *wcs,
          int inplace)
     Convert the linked list of image coordinates in ‘coords’ to a
     linked list of world coordinates given the input WCS structure.
     See the description of ‘gal_wcs_world_to_img’ for more details.

   ---------- Footnotes ----------

   (1) 
<https://www.atnf.csiro.au/people/mcalabre/WCS/wcslib/threads.html>

   (2) <https://www.atnf.csiro.au/people/mcalabre/WCS/dcs_20040422.pdf>

   (3) 
<https://www.atnf.csiro.au/people/mcalabre/WCS/wcslib/dis_8h.html>

   (4) Proc.  of SPIE Vol.  8451 84511M-1.
<https://doi.org/10.1117/12.925460>, also available at
<http://web.ipac.caltech.edu/staff/shupe/reprints/SIP_to_PV_SPIE2012.pdf>.


File: gnuastro.info,  Node: Arithmetic on datasets,  Next: Tessellation library,  Prev: World Coordinate System,  Up: Gnuastro library

12.3.14 Arithmetic on datasets (‘arithmetic.h’)
-----------------------------------------------

When the dataset's type and other information are already known, any
programming language (including C) provides some very good tools for
various operations (including arithmetic operations like addition) on
the dataset with a simple loop.  However, as an author of a program,
making assumptions about the type of data, its dimensions and other
basic characteristics will come with a large processing burden.

   For example, if you always read your data as double precision
floating points for a simple operation like addition with an integer
constant, you will be wasting a lot of CPU and memory when the input
dataset is ‘int32’ type for example, (see *note Numeric data types::).
This overhead may be small for small images, but as you scale your
process up and work with hundred/thousands of files that can be very
large, this overhead will take a significant portion of the processing
power.  The functions and macros in this section are designed precisely
for this purpose: to allow you to do any of the defined operations on
any dataset with no overhead (in the native type of the dataset).

   Gnuastro's Arithmetic program uses the functions and macros of this
section, so please also have a look at the *note Arithmetic:: program
and in particular *note Arithmetic operators:: for a better description
of the operators discussed here.

   The main function of this library is ‘gal_arithmetic’ that is
described below.  It can take an arbitrary number of arguments as
operands (depending on the operator, similar to ‘printf’).  Its first
two arguments are integers specifying the flags and operator.  So first
we will review the constants for the recognized flags and operators and
discuss them, then introduce the actual function.

 -- Macro: GAL_ARITHMETIC_FLAG_INPLACE
 -- Macro: GAL_ARITHMETIC_FLAG_FREE
 -- Macro: GAL_ARITHMETIC_FLAG_NUMOK
 -- Macro: GAL_ARITHMETIC_FLAG_ENVSEED
 -- Macro: GAL_ARITHMETIC_FLAG_QUIET
 -- Macro: GAL_ARITHMETIC_FLAGS_BASIC
     Bit-wise flags to pass onto ‘gal_arithmetic’ (see below).  To pass
     multiple flags, use the bitwise-or operator.  For example, if you
     pass ‘GAL_ARITHMETIC_FLAG_INPLACE | GAL_ARITHMETIC_FLAG_NUMOK’,
     then the operation will be done in-place (without allocating a new
     array), and a single number will also be acceptable (that will be
     applied to all the pixels).  Each flag is described below:

     ‘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 ‘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.

     ‘GAL_ARITHMETIC_FLAG_FREE’
          Free (all the) input dataset(s) after the operation is done.
          Hence the inputs are no longer usable after ‘gal_arithmetic’.

     ‘GAL_ARITHMETIC_FLAG_NUMOK’
          It is acceptable to use a number and an array together.  For
          example, if you want to add all the pixels in an image with a
          single number you can pass this flag to avoid having to
          allocate a constant array the size of the image (with all the
          pixels having the same number).

     ‘GAL_ARITHMETIC_FLAG_ENVSEED’
          Use the pre-defined environment variable for setting the
          random number generator seed when an operator needs it (for
          example, ‘mknoise-sigma’).  For more on random number
          generation in Gnuastro see *note Generating random numbers::.

     ‘GAL_ARITHMETIC_FLAG_QUIET’
          Do not print any warnings or messages for operators that may
          benefit from it.  For example, by default the ‘mknoise-sigma’
          operator prints the random number generator function and seed
          that it used (in case the user wants to reproduce this result
          later).  By activating this bit flag to the call, that extra
          information is not printed on the command-line.

     ‘GAL_ARITHMETIC_FLAGS_BASIC’
          A wrapper for activating the three "basic" operations that are
          commonly necessary together: ‘GAL_ARITHMETIC_FLAG_INPLACE’,
          ‘GAL_ARITHMETIC_FLAG_FREE’ and ‘GAL_ARITHMETIC_FLAG_NUMOK’.

 -- Macro: GAL_ARITHMETIC_OP_PLUS
 -- Macro: GAL_ARITHMETIC_OP_MINUS
 -- Macro: GAL_ARITHMETIC_OP_MULTIPLY
 -- Macro: GAL_ARITHMETIC_OP_DIVIDE
 -- Macro: GAL_ARITHMETIC_OP_LT
 -- Macro: GAL_ARITHMETIC_OP_LE
 -- Macro: GAL_ARITHMETIC_OP_GT
 -- Macro: GAL_ARITHMETIC_OP_GE
 -- Macro: GAL_ARITHMETIC_OP_EQ
 -- Macro: GAL_ARITHMETIC_OP_NE
 -- Macro: GAL_ARITHMETIC_OP_AND
 -- Macro: GAL_ARITHMETIC_OP_OR
     Binary operators (requiring two operands) that accept datasets of
     any recognized type (see *note Numeric data types::).  When
     ‘gal_arithmetic’ is called with any of these operators, it expects
     two datasets as arguments.  For a full description of these
     operators with the same name, see *note Arithmetic operators::.
     The first dataset/operand will be put on the left of the operator
     and the second will be put on the right.  The output type of the
     first four is determined from the input types (largest type of the
     inputs).  The rest (which are all conditional operators) will
     output a binary ‘uint8_t’ (or ‘unsigned char’) dataset with values
     of either ‘0’ (zero) or ‘1’ (one).

 -- Macro: GAL_ARITHMETIC_OP_NOT
     The logical NOT operator.  When ‘gal_arithmetic’ is called with
     this operator, it only expects one operand (dataset), since this is
     a unary operator.  The output is ‘uint8_t’ (or ‘unsigned char’)
     dataset of the same size as the input.  Any non-zero element in the
     input will be ‘0’ (zero) in the output and any ‘0’ (zero) will have
     a value of ‘1’ (one).

 -- Macro: GAL_ARITHMETIC_OP_ISBLANK
     A unary operator with output that is ‘1’ for any element in the
     input that is blank, and ‘0’ for any non-blank element.  When
     ‘gal_arithmetic’ is called with this operator, it will only expect
     one input dataset.  The output dataset will have ‘uint8_t’ (or
     ‘unsigned char’) type.

     ‘gal_arithmetic’ with this operator is just a wrapper for the
     ‘gal_blank_flag’ function of *note Library blank values:: and this
     operator is just included for completeness in arithmetic
     operations.  So in your program, it might be easier to just call
     ‘gal_blank_flag’.

 -- Macro: GAL_ARITHMETIC_OP_WHERE
     The three-operand _where_ operator thoroughly discussed in *note
     Arithmetic operators::.  When ‘gal_arithmetic’ is called with this
     operator, it will only expect three input datasets: the first
     (which is the same as the returned dataset) is the array that will
     be modified.  The second is the condition dataset (that must have a
     ‘uint8_t’ or ‘unsigned char’ type), and the third is the value to
     be used if condition is non-zero.

     As a result, note that the order of operands when calling
     ‘gal_arithmetic’ with ‘GAL_ARITHMETIC_OP_WHERE’ is the opposite of
     running Gnuastro's Arithmetic program with the ‘where’ operator
     (see *note Arithmetic::).  This is because the latter uses the
     reverse-Polish notation which is not necessary when calling a
     function (see *note Reverse polish notation::).

 -- Macro: GAL_ARITHMETIC_OP_SQRT
 -- Macro: GAL_ARITHMETIC_OP_LOG
 -- Macro: GAL_ARITHMETIC_OP_LOG10
     Unary operator functions for calculating the square root
     ($\sqrt{i}$), $ln(i)$ and $log(i)$ mathematical operators on each
     element of the input dataset.  The returned dataset will have a
     floating point type, but its precision is determined from the
     input: if the input is a 64-bit floating point, the output will
     also be 64-bit.  Otherwise, the returned dataset will be 32-bit
     floating point: you do not gain precision by using these operators,
     but you gain in operating speed if you use the sufficient
     precision.  See *note Numeric data types:: for more on the
     precision of floating point numbers to help in selecting your
     required floating point precision.

     If you want your output to be 64-bit floating point but your input
     is a different type, you can convert the input to a 64-bit floating
     point type with ‘gal_data_copy_to_new_type’ or
     ‘gal_data_copy_to_new_type_free’(see *note Copying datasets::).
     Alternatively, you can use the ‘GAL_ARITHMETIC_OP_TO_FLOAT64’
     operators in the arithmetic library.

 -- Macro: GAL_ARITHMETIC_OP_SIN
 -- Macro: GAL_ARITHMETIC_OP_COS
 -- Macro: GAL_ARITHMETIC_OP_TAN
 -- Macro: GAL_ARITHMETIC_OP_ASIN
 -- Macro: GAL_ARITHMETIC_OP_ACOS
 -- Macro: GAL_ARITHMETIC_OP_ATAN
 -- Macro: GAL_ARITHMETIC_OP_ATAN2
     Trigonometric functions (and their inverse).  All the angles,
     either inputs or outputs, are in units of degrees.

 -- Macro: GAL_ARITHMETIC_OP_SINH
 -- Macro: GAL_ARITHMETIC_OP_COSH
 -- Macro: GAL_ARITHMETIC_OP_TANH
 -- Macro: GAL_ARITHMETIC_OP_ASINH
 -- Macro: GAL_ARITHMETIC_OP_ACOSH
 -- Macro: GAL_ARITHMETIC_OP_ATANH
     Hyperbolic functions (and their inverse).

 -- Macro: GAL_ARITHMETIC_OP_RA_TO_DEGREE
 -- Macro: GAL_ARITHMETIC_OP_DEC_TO_DEGREE
 -- Macro: GAL_ARITHMETIC_OP_DEGREE_TO_RA
 -- Macro: GAL_ARITHMETIC_OP_DEGREE_TO_DEC
     Unary operators to convert between degrees (as a single floating
     point number) to the sexagesimal Right Ascension and Declination
     format (as strings, respectively in the format of ‘_h_m_s’ and
     ‘_d_m_s’).  The first two operators expect a string operand (in the
     sexagesimal formats mentioned above, but also in the ‘_:_:_’) and
     will return a double-precision floating point operand.  The latter
     two are the opposite.

 -- Macro: GAL_ARITHMETIC_OP_COUNTS_TO_MAG
 -- Macro: GAL_ARITHMETIC_OP_MAG_TO_COUNTS
 -- Macro: GAL_ARITHMETIC_OP_MAG_TO_SB
 -- Macro: GAL_ARITHMETIC_OP_SB_TO_MAG
 -- Macro: GAL_ARITHMETIC_OP_COUNTS_TO_JY
 -- Macro: GAL_ARITHMETIC_OP_JY_TO_COUNTS
 -- Macro: GAL_ARITHMETIC_OP_MAG_TO_JY
 -- Macro: GAL_ARITHMETIC_OP_JY_TO_MAG
 -- Macro: GAL_ARITHMETIC_OP_MAG_TO_NANOMAGGY
 -- Macro: GAL_ARITHMETIC_OP_NANOMAGGY_TO_MAG
     Binary operators for converting brightness and surface brightness
     units to and from each other.  The first operand to all of them are
     the values in the input unit (left of the ‘-TO-’, for example
     counts in ‘COUNTS_TO_MAG’).  The second popped operand is the zero
     point (right of the ‘-TO-’, for example magnitudes in
     ‘COUNTS_TO_MAG’).  The exceptions are the operators that involve
     surface brightness (those with ‘SB’).  For the surface brightness
     related operators, the second popped operand is the area in units
     of arcsec$^2$ and the third popped operand is the final unit.

 -- Macro: GAL_ARITHMETIC_OP_COUNTS_TO_SB
 -- Macro: GAL_ARITHMETIC_OP_SB_TO_COUNTS
     Operators for converting counts to surface brightness and
     vice-versa.  These operators take three operands: 1) the input
     dataset in units of counts or surface brightness (depending on the
     operator), 2) the zero point, 3) the area in units of arcsec$^2$.

 -- Macro: GAL_ARITHMETIC_OP_AU_TO_PC
 -- Macro: GAL_ARITHMETIC_OP_PC_TO_AU
 -- Macro: GAL_ARITHMETIC_OP_LY_TO_PC
 -- Macro: GAL_ARITHMETIC_OP_PC_TO_LY
 -- Macro: GAL_ARITHMETIC_OP_LY_TO_AU
 -- Macro: GAL_ARITHMETIC_OP_AU_TO_LY
     Unary operators to convert various distance units to and from each
     other: Astronomical Units (AU), Parsecs (PC) and Light years (LY).

 -- Macro: GAL_ARITHMETIC_OP_MINVAL
 -- Macro: GAL_ARITHMETIC_OP_MAXVAL
 -- Macro: GAL_ARITHMETIC_OP_NUMBERVAL
 -- Macro: GAL_ARITHMETIC_OP_SUMVAL
 -- Macro: GAL_ARITHMETIC_OP_MEANVAL
 -- Macro: GAL_ARITHMETIC_OP_STDVAL
 -- Macro: GAL_ARITHMETIC_OP_MEDIANVAL
     Unary operand statistical operators that will return a single value
     for datasets of any size.  These are just wrappers around similar
     functions in *note Statistical operations:: and are included in
     ‘gal_arithmetic’ only for completeness (to use easily in *note
     Arithmetic::).  In your programs, it will probably be easier if you
     use those ‘gal_statistics_’ functions directly.

 -- Macro: GAL_ARITHMETIC_OP_UNIQUE
 -- Macro: GAL_ARITHMETIC_OP_NOBLANK
     Unary operands that will remove some elements from the input
     dataset.  The first will return the unique elements, and the second
     will return the non-blank elements.  Due to the removal of
     elements, the dimensionality of the output will be lost.

     These are just wrappers over the ‘gal_statistics_unique’ and
     ‘gal_blank_remove’.  These are just wrappers around similar
     functions in *note Statistical operations:: and are included in
     ‘gal_arithmetic’ only for completeness (to use easily in *note
     Arithmetic::).  In your programs, it will probably be easier if you
     use those ‘gal_statistics_’ functions directly.

 -- Macro: GAL_ARITHMETIC_OP_ABS
     Unary operand absolute-value operator.

 -- Macro: GAL_ARITHMETIC_OP_MIN
 -- Macro: GAL_ARITHMETIC_OP_MAX
 -- Macro: GAL_ARITHMETIC_OP_NUMBER
 -- Macro: GAL_ARITHMETIC_OP_SUM
 -- Macro: GAL_ARITHMETIC_OP_MEAN
 -- Macro: GAL_ARITHMETIC_OP_STD
 -- Macro: GAL_ARITHMETIC_OP_MEDIAN
     Multi-operand statistical operations.  When ‘gal_arithmetic’ is
     called with any of these operators, it will expect only a single
     operand that will be interpreted as a list of datasets (see *note
     List of gal_data_t::).  These operators can work on multiple
     threads using the ‘numthreads’ argument.  See the discussion under
     the ‘min’ operator in *note Arithmetic operators::.

     The output will be a single dataset with each of its elements
     replaced by the respective statistical operation on the whole list.
     The type of the output is determined from the operator
     (irrespective of the input type): for ‘GAL_ARITHMETIC_OP_MIN’ and
     ‘GAL_ARITHMETIC_OP_MAX’, it will be the same type as the input, for
     ‘GAL_ARITHMETIC_OP_NUMBER’, the output will be ‘GAL_TYPE_UINT32’
     and for the rest, it will be ‘GAL_TYPE_FLOAT32’.

 -- Macro: GAL_ARITHMETIC_OP_QUANTILE
     Similar to the operands above (including ‘GAL_ARITHMETIC_MIN’),
     except that when ‘gal_arithmetic’ is called with these operators,
     it requires two arguments.  The first is the list of datasets like
     before, and the second is the 1-element dataset with the quantile
     value.  The output type is the same as the inputs.

 -- Macro: GAL_ARITHMETIC_OP_SIGCLIP_STD
 -- Macro: GAL_ARITHMETIC_OP_SIGCLIP_MEAN
 -- Macro: GAL_ARITHMETIC_OP_SIGCLIP_MEDIAN
 -- Macro: GAL_ARITHMETIC_OP_SIGCLIP_NUMBER
     Similar to the operands above (including ‘GAL_ARITHMETIC_MIN’),
     except that when ‘gal_arithmetic’ is called with these operators,
     it requires two arguments.  The first is the list of datasets like
     before, and the second is the 2-element list of $\sigma$-clipping
     parameters.  The first element in the parameters list is the
     multiple of sigma and the second is the termination criteria (see
     *note Sigma clipping::).  The output type of
     ‘GAL_ARITHMETIC_OP_SIGCLIP_NUMBER’ will be ‘GAL_TYPE_UINT32’ and
     for the rest it will be ‘GAL_TYPE_FLOAT32’.

 -- Macro: GAL_ARITHMETIC_OP_MKNOISE_SIGMA
 -- Macro: GAL_ARITHMETIC_OP_MKNOISE_POISSON
 -- Macro: GAL_ARITHMETIC_OP_MKNOISE_UNIFORM
     Add noise to the input dataset.  These operators take two
     arguments: the first is the input data set (can have any
     dimensionality or number of elements.  The second argument is the
     noise specifier (a single element, of any type): for a fixed-sigma
     noise, it is the Gaussian standard deviation, for the Poisson
     noise, it is the background (see *note Photon counting noise::) and
     for the uniform distribution it is the width of the interval around
     each element of the input dataset.

     By default, a separate random number generator seed will be used on
     each separate run of these operators.  Therefore two identical runs
     on the same input will produce different results.  You can get
     reproducible results by setting the ‘GAL_RNG_SEED’ environment
     variable and activating the ‘GAL_ARITHMETIC_FLAG_ENVSEED’ flag.
     For more on random number generation in Gnuastro, see *note
     Generating random numbers::.

     By default these operators will print the random number generator
     function and seed (in case the user wants to reproduce the result
     later), but this can be disabled by activating the bit-flag
     ‘GAL_ARITHMETIC_FLAG_QUIET’ described above.

 -- Macro: GAL_ARITHMETIC_OP_RANDOM_FROM_HIST
 -- Macro: GAL_ARITHMETIC_OP_RANDOM_FROM_HIST_RAW
     Select random values from a custom distribution (defined by a
     histogram).  For more, see the description of the respective
     operators in *note Generating random numbers::.

 -- Macro: GAL_ARITHMETIC_OP_STITCH
     Stitch a list of input datasets along the requested dimension.  See
     the description of the ‘stitch’ operator in Arithmetic (*note
     Dimensionality changing operators::).

 -- Macro: GAL_ARITHMETIC_OP_POW
     Binary operator to-power operator.  When ‘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).

 -- Macro: GAL_ARITHMETIC_OP_BITAND
 -- Macro: GAL_ARITHMETIC_OP_BITOR
 -- Macro: GAL_ARITHMETIC_OP_BITXOR
 -- Macro: GAL_ARITHMETIC_OP_BITLSH
 -- Macro: GAL_ARITHMETIC_OP_BITRSH
 -- Macro: GAL_ARITHMETIC_OP_MODULO
     Binary integer-only operand operators.  These operators are only
     defined on integer data types.  When ‘gal_arithmetic’ is called
     with any of these operators, it will expect two operands: the first
     is put on the left of the operator and the second on the right.
     The ones starting with ‘BIT’ are the respective bit-wise operators
     in C and ‘MODULO’ is the modulo/remainder operator.  For a
     discussion on these operators, please see *note Arithmetic
     operators::.

     The output type is determined from the input types and C's internal
     conversions: it is strongly recommended that both inputs have the
     same type (any integer type), otherwise the bit-wise behavior will
     be determined by your compiler.

 -- Macro: GAL_ARITHMETIC_OP_BITNOT
     The unary bit-wise NOT operator.  When ‘gal_arithmetic’ is called
     with any of these operators, it will expect one operand of an
     integer type and preform the bitwise-NOT operation on it.  The
     output will have the same type as the input.

 -- Macro: GAL_ARITHMETIC_OP_TO_UINT8
 -- Macro: GAL_ARITHMETIC_OP_TO_INT8
 -- Macro: GAL_ARITHMETIC_OP_TO_UINT16
 -- Macro: GAL_ARITHMETIC_OP_TO_INT16
 -- Macro: GAL_ARITHMETIC_OP_TO_UINT32
 -- Macro: GAL_ARITHMETIC_OP_TO_INT32
 -- Macro: GAL_ARITHMETIC_OP_TO_UINT64
 -- Macro: GAL_ARITHMETIC_OP_TO_INT64
 -- Macro: GAL_ARITHMETIC_OP_TO_FLOAT32
 -- Macro: GAL_ARITHMETIC_OP_TO_FLOAT64
     Unary type-conversion operators.  When ‘gal_arithmetic’ is called
     with any of these operators, it will expect one operand and convert
     it to the requested type.  Note that with these operators,
     ‘gal_arithmetic’ is just a wrapper over the
     ‘gal_data_copy_to_new_type’ or ‘gal_data_copy_to_new_type_free’
     that are discussed in ‘Copying datasets’.  It accepts these
     operators only for completeness and easy usage in *note
     Arithmetic::.  So in your programs, it might be preferable to
     directly use those functions.

 -- Macro: GAL_ARITHMETIC_OP_E
 -- Macro: GAL_ARITHMETIC_OP_C
 -- Macro: GAL_ARITHMETIC_OP_G
 -- Macro: GAL_ARITHMETIC_OP_H
 -- Macro: GAL_ARITHMETIC_OP_AU
 -- Macro: GAL_ARITHMETIC_OP_LY
 -- Macro: GAL_ARITHMETIC_OP_PI
 -- Macro: GAL_ARITHMETIC_OP_AVOGADRO
 -- Macro: GAL_ARITHMETIC_OP_FINESTRUCTURE

     Return the respective mathematical constant.  For their description
     please see *note Constants::.  The constant values are taken from
     the GNU Scientific Library's headers (defined in ‘gsl/gsl_math.h’).

 -- Macro: GAL_ARITHMETIC_OP_BOX_AROUND_ELLIPSE
     Return the width (along horizontal) and height (along vertical) of
     a box that encompasses an ellipse with the same center point.  For
     more on the three input operands to this operator see the
     description of ‘box-around-ellipse’.  This function returns two
     datasets as a ‘gal_data_t’ linked list.  The top element of the
     list is the height and its next element is the width.

 -- Macro: GAL_ARITHMETIC_OP_BOX_VERTICES_ON_SPHERE
     Return the vertices of a (possibly rectangular) box on a sphere,
     given its center RA, Dec and the width of the box along the two
     dimensions.  It will take the spherical nature of the coordinate
     system into account (for more, see the description of
     ‘gal_wcs_box_vertices_from_center’ in *note World Coordinate
     System::).  This function returns 8 datasets as a ‘gal_data_t’
     linked list in the following order: bottom-left RA, bottom-left
     Dec, bottom-right RA, bottom-right Dec, top-right RA, top-right
     Dec, top-left RA, top-left Dec.

 -- Macro: GAL_ARITHMETIC_OP_MAKENEW
     Create a new, zero-valued dataset with an unsigned 8-bit data type.
     The length along each dimension of the dataset should be given as a
     single list of ‘gal_data_t’s.  The number of dimensions is derived
     from the number of nodes in the list and the length along each
     dimension is the single-valued element within that list.  Just note
     that the list should be in the reverse of the desired dimensions.

 -- Macro: GAL_ARITHMETIC_OP_MAKENEW
     Given a dataset and a constant,

 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_HDU
 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_FILE
 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_PREFIX
 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_HDU_LEN
 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_FILE_LEN
 -- Macro: GAL_ARITHMETIC_OPSTR_LOADCOL_PREFIX_LEN
     Constant components of the ‘load-col-’ operator (see *note Loading
     external columns::).  These are just fixed strings (and their
     lengths) that are placed in between the various components of that
     operator to allow choosing a certain column of a certain HDU of a
     certain file.

 -- Macro: GAL_ARITHMETIC_OP_INDEX
 -- Macro: GAL_ARITHMETIC_OP_COUNTER
 -- Macro: GAL_ARITHMETIC_OP_INDEXONLY
 -- Macro: GAL_ARITHMETIC_OP_COUNTERONLY
     Return a dataset with the same number of elements and
     dimensionality as the first (and only!)  input dataset.  But each
     output pixel's value will be replaced by its index (counting from
     0) or counter (counting from 1).  Note that the
     ‘GAL_ARITHMETIC_OP_INDEX’ and ‘GAL_ARITHMETIC_OP_INDEXONLY’
     operators are identical within the library (same for the counter
     operators).  They are given separate macros here to help the
     higher-level callers to manage their inputs separately (see *note
     Size and position operators::).

 -- Macro: GAL_ARITHMETIC_OP_SIZE
     Size operator that will return a single value for datasets of any
     kind.  When ‘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.

 -- Macro: GAL_ARITHMETIC_OP_SWAP
     Return the first dataset, but with the second dataset being placed
     in the ‘next’ element of the first.  This is useful to swap the
     operators on the stacks of the higher-level programs that call the
     arithmetic library.

 -- Macro: GAL_ARITHMETIC_OP_EQB1950_TO_EQJ2000
 -- Macro: GAL_ARITHMETIC_OP_EQB1950_TO_ECB1950
 -- Macro: GAL_ARITHMETIC_OP_EQB1950_TO_ECJ2000
 -- Macro: GAL_ARITHMETIC_OP_EQB1950_TO_GALACTIC
 -- Macro: GAL_ARITHMETIC_OP_EQB1950_TO_SUPERGALACTIC
 -- Macro: GAL_ARITHMETIC_OP_EQJ2000_TO_EQB1950
 -- Macro: GAL_ARITHMETIC_OP_EQJ2000_TO_ECB1950
 -- Macro: GAL_ARITHMETIC_OP_EQJ2000_TO_ECJ2000
 -- Macro: GAL_ARITHMETIC_OP_EQJ2000_TO_GALACTIC
 -- Macro: GAL_ARITHMETIC_OP_EQJ2000_TO_SUPERGALACTIC
 -- Macro: GAL_ARITHMETIC_OP_ECB1950_TO_EQB1950
 -- Macro: GAL_ARITHMETIC_OP_ECB1950_TO_EQJ2000
 -- Macro: GAL_ARITHMETIC_OP_ECB1950_TO_ECJ2000
 -- Macro: GAL_ARITHMETIC_OP_ECB1950_TO_GALACTIC
 -- Macro: GAL_ARITHMETIC_OP_ECB1950_TO_SUPERGALACTIC
 -- Macro: GAL_ARITHMETIC_OP_ECJ2000_TO_EQB1950
 -- Macro: GAL_ARITHMETIC_OP_ECJ2000_TO_EQJ2000
 -- Macro: GAL_ARITHMETIC_OP_ECJ2000_TO_ECB1950
 -- Macro: GAL_ARITHMETIC_OP_ECJ2000_TO_GALACTIC
 -- Macro: GAL_ARITHMETIC_OP_ECJ2000_TO_SUPERGALACTIC
 -- Macro: GAL_ARITHMETIC_OP_GALACTIC_TO_EQB1950
 -- Macro: GAL_ARITHMETIC_OP_GALACTIC_TO_EQJ2000
 -- Macro: GAL_ARITHMETIC_OP_GALACTIC_TO_ECB1950
 -- Macro: GAL_ARITHMETIC_OP_GALACTIC_TO_ECJ2000
 -- Macro: GAL_ARITHMETIC_OP_GALACTIC_TO_SUPERGALACTIC
 -- Macro: GAL_ARITHMETIC_OP_SUPERGALACTIC_TO_EQB1950
 -- Macro: GAL_ARITHMETIC_OP_SUPERGALACTIC_TO_EQJ2000
 -- Macro: GAL_ARITHMETIC_OP_SUPERGALACTIC_TO_ECB1950
 -- Macro: GAL_ARITHMETIC_OP_SUPERGALACTIC_TO_ECJ2000
 -- Macro: GAL_ARITHMETIC_OP_SUPERGALACTIC_TO_GALACTIC
     Operators that convert recognized celestial coordinates to and from
     each other.  They all take two operands and return two
     ‘gal_data_t’s (as a list).  For more on celestial coordinate
     conversion, see *note Coordinate conversion operators::.

 -- Function:
          gal_data_t *
          gal_arithmetic (int operator, size_t numthreads, int flags,
          ...)
     Apply the requested arithmetic operator on the operand(s).  The
     _operator_ is identified through the macros above (that start with
     ‘GAL_ARITHMETIC_OP_’).  The number of necessary operands (number of
     arguments to replace '‘...’' in the declaration of this function,
     above) depends on the operator and is described under each
     operator, above.  Each operand has a type of '‘gal_data_t *’' (see
     last paragraph with example).

     If the operator can work on multiple threads, the number of threads
     can be specified with ‘numthreads’.  When the operator is
     single-threaded, ‘numthreads’ will be ignored.  Special conditions
     can also be specified with the ‘flag’ operator (a bit-flag with
     bits described above, for example, ‘GAL_ARITHMETIC_FLAG_INPLACE’ or
     ‘GAL_ARITHMETIC_FLAG_FREE’).

     ‘gal_arithmetic’ is a multi-argument function (like C's ‘printf’).
     In other words, the number of necessary arguments is not fixed and
     depends on the value to ‘operator’.  Below, you can see a minimal,
     fully working example, showing how different operators need
     different numbers of arguments.

          #include <stdio.h>
          #include <stdlib.h>
          #include <gnuastro/fits.h>
          #include <gnuastro/arithmetic.h>

          int
          main(void)
          {
            /* Define the datasets and flag. */
            gal_data_t *in1, *in2, *out1, *out2;
            int flag=GAL_ARITHMETIC_FLAGS_BASIC;

            /* Read the input images. */
            in1=gal_fits_img_read("image1.fits", "1", -1, 1, NULL);
            in2=gal_fits_img_read("image2.fits", "1", -1, 1, NULL);

            /* Take the logarithm (base-e) of the first input. */
            out1=gal_arithmetic(GAL_ARITHMETIC_OP_LOG, 1, flag, in1);

            /* Add the second input with the logarithm of the first. */
            out2=gal_arithmetic(GAL_ARITHMETIC_OP_PLUS, 1, flag, in2, out1);

            /* Write the output into a file. */
            gal_fits_img_write(out2, "out.fits", NULL, 0);

            /* Clean up. Due to the in-place flag (in
             * 'GAL_ARITHMETIC_FLAGS_BASIC'), 'out1' and 'out2' point to the
             * same array in memory and due to the freeing flag, any input
             * dataset(s) that were not returned have been freed internally
             * by 'gal_arithmetic'. Therefore it is only necessary to free
             * 'out2': all other allocated spaces have been freed internally.
             * before reaching this point. */
            gal_data_free(out2);

            /* Return control back to the OS (saying that we succeeded). */
            return EXIT_SUCCESS;
          }

     As you see above, you can feed the returned dataset from one call
     of ‘gal_arithmetic’ to another call.  The advantage of using
     ‘gal_arithmetic’ (as opposed to manually writing a ‘for’ or ‘while’
     loop and doing the operation with the ‘+’ operator and ‘log()’
     function yourself), is that you do not have to worry about the type
     of the input data (for a list of acceptable data types in Gnuastro,
     see *note Library data types::).  Arithmetic will automatically
     deal with the data types internally and choose the best output type
     depending on the operator.

 -- Function:
          int
          gal_arithmetic_set_operator (char *string, size_t
          *num_operands)
     Return the operator macro/code that corresponds to ‘string’.  The
     number of operands that it needs are written into the space that
     ‘*num_operands’ points to.  If the string could not be interpreted
     as an operator, this function will return
     ‘GAL_ARITHMETIC_OP_INVALID’.

     This function will check ‘string’ with the fixed human-readable
     names (using ‘strcmp’) for the operators and return the two
     numbers.  Note that ‘string’ must only contain the single operator
     name and nothing else (not even any extra white space).

 -- Function:
          char *
          gal_arithmetic_operator_string (int operator)
     Return the human-readable standard string that corresponds to the
     given operator.  For example, when the input is
     ‘GAL_ARITHMETIC_OP_PLUS’ or ‘GAL_ARITHMETIC_OP_MEAN’, the strings
     ‘+’ or ‘mean’ will be returned.

 -- Function:
          gal_data_t *
          gal_arithmetic_load_col (char *str, int searchin, int
          ignorecase, size_t minmapsize, int quietmmap)
     Return the column that corresponds to the identifier in the input
     string (‘str’).  ‘str’ is expected to be in the format of the
     ‘load-col-’ operator (see *note Loading external columns::).  This
     function will extract the column identifier, the file name and the
     HDU (if necessary) from the string, read the requested column in
     memory and return it.

     See *note Table input output:: for the macros that can be given to
     ‘searchin’ and ‘ignorecase’ and *note Generic data container:: for
     the definitions of ‘minmapsize’ and ‘quietmmap’.


File: gnuastro.info,  Node: Tessellation library,  Next: Bounding box,  Prev: Arithmetic on datasets,  Up: Gnuastro library

12.3.15 Tessellation library (‘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 ‘block’ pointer in
Gnuastro's *note 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 ‘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 ‘tile’ region.

                                 larger
                   ---------------------------------
                   |                               |
                   |              tile             |
                   |           ----------          |
                   |           |        |          |
                   |           |_       |          |
                   |           |*|      |          |
                   |           ----------          |
                   |       tile->block = larger    |
                   |_                              |
                   |*|                             |
                   ---------------------------------

   To use ‘gal_data_t’'s ‘block’ concept, you allocate a ‘gal_data_t
*tile’ which is initialized with the pointer to the first element in the
sub-array (as its ‘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-‘NULL’ pointer as ‘array’, ‘gal_data_initialize’ (and thus
‘gal_data_alloc’) do not allocate any space and just uses the given
pointer for the new ‘array’ element of the ‘gal_data_t’.  So your ‘tile’
data structure will not be pointing to a separately allocated space.

   After the allocation is done, you just point ‘tile->block’ to the
‘larger’ dataset which hosts the full block of memory.  Where relevant,
Gnuastro's library functions will check the ‘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 (‘tile->block’ may itself be a
tile in an even larger allocated space).  Therefore, just like a
linked-list (see *note Linked lists::), it is important to have the
‘block’ pointer of the largest (allocated) dataset set to ‘NULL’.
Normally, you will not have to worry about this, because
‘gal_data_initialize’ (and thus ‘gal_data_alloc’) will set the ‘block’
element to ‘NULL’ by default, just remember not to change it.  You can
then only change the ‘block’ element for the tiles you define over the
allocated space.

   Below, we will first review constructs for *note 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
*note 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.

* Menu:

* Independent tiles::           Work on or check independent tiles.
* Tile grid::                   Cover a full dataset with non-overlapping tiles.


File: gnuastro.info,  Node: Independent tiles,  Next: Tile grid,  Prev: Tessellation library,  Up: Tessellation library

12.3.15.1 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 *note 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.

 -- Function:
          void
          gal_tile_start_coord (gal_data_t *tile, size_t *start_coord)
     Calculate the starting coordinates of a tile in its allocated block
     of memory and write them in the memory that ‘start_coord’ points to
     (which must have ‘tile->ndim’ elements).

 -- Function:
          void
          gal_tile_start_end_coord (gal_data_t *tile, size_t *start_end,
          int rel_block)
     Put the starting and ending (end point is not inclusive)
     coordinates of ‘tile’ into the ‘start_end’ array.  It is assumed
     that a space of ‘2*tile->ndim’ has been already allocated (static
     or dynamic) for ‘start_end’ before this function is called.

     ‘rel_block’ (or relative-to-block) is only relevant when ‘tile’ has
     an intermediate tile between it and the allocated space (like a
     channel, see ‘gal_tile_full_two_layers’).  If it does not
     (‘tile->block’ points the allocated dataset), then the value to
     ‘rel_block’ is irrelevant.

     When ‘tile->block’ is itself a larger block and ‘rel_block’ is set
     to 0, then the starting and ending positions will be based on the
     position within ‘tile->block’, not the allocated space.

 -- Function:
          void *
          gal_tile_start_end_ind_inclusive (gal_data_t *tile, gal_data_t
          *work, size_t *start_end_inc)
     Put the indices of the first/start and last/end pixels (inclusive)
     in a tile into the ‘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 ‘work’ data structure (which does not have to be equal
     to ‘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
     ‘GAL_TILE_PARSE_OPERATE’ function-like macro that is described
     below.

 -- Function:
          gal_data_t *
          gal_tile_series_from_minmax (gal_data_t *block, size_t
          *minmax, size_t 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 ‘gal_data_t’ array that can later be freed
     with ‘gal_data_array_free’ (see *note 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 *note 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 ‘minmax’ must have
     ‘2*ndim*number’ elements.

          | min0_d0 | min0_d1 | max0_d0 | max0_d1 | ...
                          ... | minN_d0 | minN_d1 | maxN_d0 | maxN_d1 |

 -- Function:
          gal_data_t *
          gal_tile_block (gal_data_t *tile)
     Return the dataset that contains ‘tile’'s allocated block of
     memory.  If tile is immediately defined as part of the allocated
     block, then this is equivalent to ‘tile->block’.  However, it is
     possible to have multiple layers of tiles (where ‘tile->block’ is
     itself a tile).  So this function is the most generic way to get to
     the actual allocated dataset.

 -- Function:
          size_t
          gal_tile_block_increment (gal_data_t *block, size_t *tsize,
          size_t num_increment, size_t *coord)
     Return the increment necessary to start at the next contiguous
     patch memory associated with a tile.  ‘block’ is the allocated
     block of memory and ‘tsize’ is the size of the tile along every
     dimension.  If ‘coord’ is ‘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 ‘num_increment’
     is the main variable to this function.  For the first time you call
     this function, it should be ‘1’.  In subsequent calls (while you
     are parsing a tile), it should be increased by one.

 -- Function:
          gal_data_t *
          gal_tile_block_write_const_value (gal_data_t *tilevalues,
          gal_data_t *tilesll, int withblank, int initialize)
     Write a constant value for each tile over the area it covers in an
     allocated dataset that is the size of ‘tile’'s allocated block of
     memory (found through ‘gal_tile_block’ described above).  The
     arguments to this function are:

     ‘tilevalues’
          This must be an array that has the same number of elements as
          the nodes in in ‘tilesll’ and in the same order that 'tilesll'
          elements are parsed (from top to bottom, see *note Linked
          lists::).  As a result the array's number of dimensions is
          irrelevant, it will be parsed contiguously.

     ‘tilesll’
          The list of input tiles (see *note List of gal_data_t::).
          Internally, it might be stored as an array (for example, the
          output of ‘gal_tile_series_from_minmax’ described above), but
          this function does not care, it will parse the ‘next’ elements
          to go to the next tile.  This function will not pop-from or
          free the ‘tilesll’, it will only parse it from start to end.

     ‘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).

     ‘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.

 -- Function:
          gal_data_t *
          gal_tile_block_check_tiles (gal_data_t *tilesll)
     Make a copy of the memory block and fill it with the index of each
     tile in ‘tilesll’ (counting from 0).  The non-filled areas will
     have blank values.  The output dataset will have a type of
     ‘GAL_TYPE_INT32’ (see *note 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 ‘gal_tile_block_write_const_value’ (with ‘withblank’ set
     to zero).

 -- Function:
          void *
          gal_tile_block_relative_to_other (gal_data_t *tile, gal_data_t
          *other)
     Return the pointer corresponding to the start of the region covered
     by ‘tile’ over the ‘other’ dataset.  See the examples in
     ‘GAL_TILE_PARSE_OPERATE’ for some example applications of this
     function.

 -- Function:
          void
          gal_tile_block_blank_flag (gal_data_t *tilell, size_t
          numthreads)
     Check if each tile in the list has blank values and update its
     ‘flag’ to mark this check and its result (see *note Generic data
     container::).  The operation will be done on ‘numthreads’ threads.

 -- Function-like macro: GAL_TILE_PARSE_OPERATE (IN, OTHER, PARSE_OTHER,
          CHECK_BLANK, OP)
     Parse ‘IN’ (which can be a tile or a fully allocated block of
     memory) and do the ‘OP’ operation on it.  ‘OP’ can be any
     combination of C expressions.  If ‘OTHER!=NULL’, ‘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 ‘IN’.

     If ‘OTHER’ is a fully allocated block of memory (not a tile), then
     the same region that is covered by ‘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 ‘OTHER’ and
     ‘IN’ must have the same size.  When ‘OTHER’ is a tile it must have
     the same size as ‘IN’ and parsing will start from its starting
     element/pixel.  Also, the respective allocated blocks of ‘OTHER’
     and ‘IN’ (if different) may have different sizes.  Using ‘OTHER’
     (along with ‘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 *note 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:

     ‘IN (gal_data_t)’
          Input dataset, this can be a tile or an allocated block of
          memory.

     ‘OTHER (gal_data_t)’
          Dataset (‘gal_data_t’) to parse along with ‘IN’.  It can be
          ‘NULL’.  In that case, ‘o’ (see description of ‘OP’ below)
          will be ‘NULL’ and should not be used.  If ‘PARSE_OTHER’ is
          zero, only its first element will be used and the size of this
          dataset is irrelevant.

          When ‘OTHER’ is a block of memory, it has to have the same
          size as the allocated block of ‘IN’.  When it s a tile, it has
          to have the same size as ‘IN’.

     ‘PARSE_OTHER (int)’
          Parse the other dataset along with the input.  When this is
          non-zero and ‘OTHER!=NULL’, then the ‘o’ pointer will be
          incremented to cover the ‘OTHER’ tile at the same rate as ‘i’,
          see description of ‘OP’ for ‘i’ and ‘o’.

     ‘CHECK_BLANK (int)’
          If it is non-zero, then the input will be checked for blank
          values and ‘OP’ will only be called when we are not on a blank
          element.

     ‘OP’
          Operator: this can be any number of C expressions.  This macro
          is going to define a ‘itype *i’ variable which will increment
          over each element of the input array/tile.  ‘itype’ will be
          replaced with the C type that corresponds to the type of
          ‘INPUT’.  As an example, if ‘INPUT’'s type is
          ‘GAL_DATA_UINT16’ or ‘GAL_DATA_FLOAT32’, ‘i’ will be defined
          as ‘uint16’ or ‘float’ respectively.

          This function-like macro will also define an ‘otype *o’ which
          you can use to access an element of the ‘OTHER’ dataset (if
          ‘OTHER!=NULL’).  ‘o’ will correspond to the type of ‘OTHER’
          (similar to ‘itype’ and ‘INPUT’ discussed above).  If
          ‘PARSE_OTHER’ is non-zero, then ‘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
          ‘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
          ‘i’ (and possibly ‘o’) will be incremented once by this
          function-like macro, so do not increment them within ‘OP’.

          ‘i’
               Pointer to the element of ‘INPUT’ that is being parsed
               with the proper type.

          ‘o’
               Pointer to the element of ‘OTHER’ that is being parsed
               with the proper type.  ‘o’ can only be used if
               ‘OTHER!=NULL’ and it will be parsed/incremented if
               ‘PARSE_OTHER’ is non-zero.

          ‘b’
               Blank value in the type of ‘INPUT’.

     You can use a given tile (‘tile’ on a dataset that it was not
     initialized with but has the same size, let's call it ‘new’) with
     the following steps:

          void *tarray;
          gal_data_t *tblock;

          /* `tile->block' must be corrected AFTER `tile->array'. */
          tarray      = tile->array;
          tblock      = tile->block;
          tile->array = gal_tile_block_relative_to_other(tile, new);
          tile->block = new;

          /* Parse and operate over this region of the `new' dataset. */
          GAL_TILE_PARSE_OPERATE(tile, NULL, 0, 0, {
              YOUR_PROCESSING;
            });

          /* Reset `tile->block' and `tile->array'. */
          tile->array=tarray;
          tile->block=tblock;

     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 ‘OTHER’ argument.  Below is a demonstration, ‘tile’ is
     the actual tile that you start with and ‘new’ is the other block of
     allocated memory.

          size_t zero=0;
          gal_data_t *faketile;

          /* Allocate the fake tile, these can be done outside a loop
           * (over many tiles). */
          faketile=gal_data_alloc(NULL, new->type, 1, &zero,
                                  NULL, 0, -1, 1, NULL, NULL, NULL);
          free(faketile->array);               /* To keep things clean. */
          free(faketile->dsize);               /* To keep things clean. */
          faketile->block = new;
          faketile->ndim  = new->ndim;

          /* These can be done in a loop (over many tiles). */
          faketile->size  = tile->size;
          faketile->dsize = tile->dsize;
          faketile->array = gal_tile_block_relative_to_other(tile, new);

          /* Do your processing.... in a loop (over many tiles). */
          GAL_TILE_PARSE_OPERATE(tile, faketile, 1, 1, {
              YOUR_PROCESSING_EXPRESSIONS;
            });

          /* Clean up (outside the loop). */
          faketile->array=NULL;
          faketile->dsize=NULL;
          gal_data_free(faketile);


File: gnuastro.info,  Node: Tile grid,  Prev: Independent tiles,  Up: Tessellation library

12.3.15.2 Tile grid
...................

One very useful application of tiles is to completely cover an input
dataset with tiles.  Such that you know every pixel/data-element of the
input image is covered by only one tile.  The constructs in this section
allow easy definition of such a tile structure.  They will create lists
of tiles that are also usable by the general tools discussed in *note
Independent tiles::.

   As discussed in *note Tessellation::, (mainly raw) astronomical
images will mostly require two layers of tessellation, one for amplifier
channels which all have the same size and another (smaller tile-size)
tessellation over each channel.  Hence, in this section we define a
general structure to keep the main parameters of this two-layer
tessellation and help in benefiting from it.

 -- Type (C struct): gal_tile_two_layer_params
     The general structure to keep all the necessary parameters for a
     two-layer tessellation.

          struct gal_tile_two_layer_params
          {
            /* Inputs */
            size_t             *tilesize;  /*******************************/
            size_t          *numchannels;  /* These parameters have to be */
            float          remainderfrac;  /* filled manually before      */
            uint8_t           workoverch;  /* calling the functions in    */
            uint8_t           checktiles;  /* this section.               */
            uint8_t       oneelempertile;  /*******************************/

            /* Internal parameters. */
            size_t                  ndim;
            size_t              tottiles;
            size_t          tottilesinch;
            size_t           totchannels;
            size_t          *channelsize;
            size_t             *numtiles;
            size_t         *numtilesinch;
            char          *tilecheckname;
            size_t          *permutation;
            size_t           *firsttsize;

            /* Tile and channel arrays (which are also lists). */
            gal_data_t            *tiles;
            gal_data_t         *channels;
          };

 -- Function:
          size_t *
          gal_tile_full (gal_data_t *input, size_t *regular, float
          remainderfrac, gal_data_t **out, size_t multiple, size_t
          **firsttsize)
     Cover the full dataset with (mostly) identical tiles and return the
     number of tiles created along each dimension.  The regular tile
     size (along each dimension) is determined from the ‘regular’ array.
     If ‘input’'s size is not an exact multiple of ‘regular’ for each
     dimension, then the tiles touching the edges in that dimension will
     have a different size to fully cover every element of the input
     (depending on ‘remainderfrac’).

     The output is an array with the same dimensions as ‘input’ which
     contains the number of tiles along each dimension.  See *note
     Tessellation:: for a description of its application in Gnuastro's
     programs and ‘remainderfrac’, just note that this function defines
     only one layer of tiles.

     This is a low-level function (independent of the
     ‘gal_tile_two_layer_params’ structure defined above).  If you want
     a two-layer tessellation, directly call ‘gal_tile_full_two_layers’
     that is described below.  The input arguments to this function are:

     ‘input’
          The main dataset (allocated block) which you want to create a
          tessellation over (only used for its sizes).  So ‘input’ may
          be a tile also.

     ‘regular’
          The size of the regular tiles along each of the input's
          dimensions.  So it must have the same number of elements as
          the dimensions of ‘input’ (or ‘input->ndim’).

     ‘remainderfrac’
          The significant fraction of the remainder space to see if it
          should be split into two and put on both sides of a dimension
          or not.  This is thus only relevant ‘input’ length along a
          dimension is not an exact multiple of the regular tile size
          along that dimension.  See *note Tessellation:: for a more
          thorough discussion.

     ‘out’
          Pointer to the array of data structures that will keep all the
          tiles (see *note Arrays of datasets::).  If ‘*out==NULL’, then
          the necessary space to keep all the tiles will be allocated.
          If not, then all the tile information will be filled from the
          dataset that ‘*out’ points to, see ‘multiple’ for more.

     ‘multiple’
          When ‘*out==NULL’ (and thus will be allocated by this
          function), allocate space for ‘multiple’ times the number of
          tiles needed.  This can be very useful when you have several
          more identically sized ‘inputs’, and you want all their tiles
          to be allocated (and thus indexed) together, even though they
          have different ‘block’ datasets (that then link to one
          allocated space).  See the definition of channels in *note
          Tessellation:: and ‘gal_tile_full_two_layers’ below.

     ‘firsttsize’
          The size of the first tile along every dimension.  This is
          only different from the regular tile size when ‘regular’ is
          not an exact multiple of ‘input’'s length along every
          dimension.  This array is allocated internally by this
          function.

 -- Function:
          void
          gal_tile_full_sanity_check (char *filename, char *hdu,
          gal_data_t *input, struct gal_tile_two_layer_params *tl)
     Make sure that the input parameters (in ‘tl’, short for two-layer)
     correspond to the input dataset.  ‘filename’ and ‘hdu’ are only
     required for error messages.  Also, allocate and fill the
     ‘tl->channelsize’ array.

 -- Function:
          void
          gal_tile_full_two_layers (gal_data_t *input, struct
          gal_tile_two_layer_params *tl)
     Create the two layered tessellation in ‘tl’.  The general set of
     steps you need to take to define the two-layered tessellation over
     an image can be seen in the example code below.

          gal_data_t *input;
          struct gal_tile_two_layer_params tl;
          char *filename="input.fits", *hdu="1";

          /* Set all the inputs shown in the structure definition. */
          ...

          /* Read the input dataset. */
          input=gal_fits_img_read(filename, hdu, -1, 1, NULL);

          /* Do a sanity check and preparations. */
          gal_tile_full_sanity_check(filename, hdu, input, &tl);

          /* Build the two-layer tessellation*/
          gal_tile_full_two_layers(input, &tl);

          /* `tl.tiles' and `tl.channels' are now a lists of tiles.*/

 -- Function:
          void
          gal_tile_full_permutation (struct gal_tile_two_layer_params
          *tl)
     Make a permutation to allow the conversion of tile location in
     memory to its location in the full input dataset and put it in
     ‘tl->permutation’.  If a permutation has already been defined for
     the tessellation, this function will not do anything.  If
     permutation will not be necessary (there is only one channel or one
     dimension), then this function will not do anything
     (‘tl->permutation’ must have been initialized to ‘NULL’).

     When there is only one channel OR one dimension, the tiles are
     allocated in memory in the same order that they represent the input
     data.  However, to make channel-independent processing possible in
     a generic way, the tiles of each channel are allocated
     contiguously.  So, when there is more than one channel AND more
     than one dimension, the index of the tile does not correspond to
     its position in the grid covering the input dataset.

     The example below may help clarify: assume you have a 6x6
     tessellation with two channels in the horizontal and one in the
     vertical.  On the left you can see how the tile IDs correspond to
     the input dataset.  NOTE how '03' is on the second row, not on the
     first after '02'.  On the right, you can see how the tiles are
     stored in memory (and shown if you simply write the array into a
     FITS file for example).

             Corresponding to input               In memory
             ----------------------             --------------
               15 16 17 33 34 35               30 31 32 33 34 35
               12 13 14 30 31 32               24 25 26 27 28 29
               09 10 11 27 28 29               18 19 20 21 22 23
               06 07 08 24 25 26      <--      12 13 14 15 16 17
               03 04 05 21 22 23               06 07 08 09 10 11
               00 01 02 18 19 20               00 01 02 03 04 05

     As a result, if your values are stored in same order as the tiles,
     and you want them in over-all memory (for example, to save as a
     FITS file), you need to permute the values:

          gal_permutation_apply(values, tl->permutation);

     If you have values over-all and you want them in tile-order, you
     can apply the inverse permutation:

          gal_permutation_apply_inverse(values, tl->permutation);

     Recall that this is the definition of permutation in this context:

          permute:    IN_ALL[ i       ]   =   IN_MEMORY[ perm[i] ]
          inverse:    IN_ALL[ perm[i] ]   =   IN_MEMORY[ i       ]

 -- Function:
          void
          gal_permutation_apply_onlydim0 (gal_data_t *input, size_t
          *permutation)
     Similar to ‘gal_permutation_apply’, but when the dataset is
     2-dimensional, permute each row (dimension 1 in C) as one element.
     In other words, only permute along dimension 0.  The ‘permutation’
     array should therefore only have ‘input->dsize[0]’ elements.

 -- Function:
          void
          gal_tile_full_values_write (gal_data_t *tilevalues, struct
          gal_tile_two_layer_params *tl, int withblank, char *filename,
          gal_fits_list_key_t *keys, int freekeys)
     Write one value for each tile into a file.  It is important to note
     that the values in ‘tilevalues’ must be ordered in the same manner
     as the tiles, so ‘tilevalues->array[i]’ is the value that should be
     given to ‘tl->tiles[i]’.  The ‘tl->permutation’ array must have
     been initialized before calling this function with
     ‘gal_tile_full_permutation’.

     If ‘withblank’ is non-zero, then block structure of the tiles will
     be checked and all blank pixels in the block will be blank in the
     final output file also.

 -- Function:
          gal_data_t *
          gal_tile_full_values_smooth (gal_data_t *tilevalues, struct
          gal_tile_two_layer_params *tl, size_t width, size_t
          numthreads)
     Smooth the given values with a flat kernel of the given ‘width’.
     This cannot be done manually because if ‘tl->workoverch==0’, tiles
     in different channels must not be mixed/smoothed.  Also the tiles
     are contiguous within the channel, not within the image, see the
     description under ‘gal_tile_full_permutation’.

 -- Function:
          size_t
          gal_tile_full_id_from_coord (struct gal_tile_two_layer_params
          *tl, size_t *coord)
     Return the ID of the tile that corresponds to the coordinates
     ‘coord’.  Having this ID, you can use the ‘tl->tiles’ array to get
     to the proper tile or read/write a value into an array that has one
     value per tile.

 -- Function:
          void
          gal_tile_full_free_contents (struct gal_tile_two_layer_params
          *tl)
     Free all the allocated arrays within ‘tl’.


File: gnuastro.info,  Node: Bounding box,  Next: Polygons,  Prev: Tessellation library,  Up: Gnuastro library

12.3.16 Bounding box (‘box.h’)
------------------------------

Functions related to reporting the bounding box of certain inputs are
declared in ‘gnuastro/box.h’.  All coordinates in this header are in the
FITS format (first axis is the horizontal and the second axis is
vertical).

 -- Function:
          void
          gal_box_bound_ellipse_extent (double a, double b, double
          theta_deg, double *extent)
     Return the maximum extent along each dimension of the given ellipse
     from the center of the ellipse.  Therefore this is half the extent
     of the box in each dimension.  ‘a’ is the ellipse semi-major axis,
     ‘b’ is the semi-minor axis, ‘theta_deg’ is the position angle in
     degrees.  The extent in each dimension is in floating point format
     and stored in ‘extent’ which must already be allocated before this
     function.

 -- Function:
          void
          gal_box_bound_ellipse (double a, double b, double theta_deg,
          long *width)
     Any ellipse can be enclosed into a rectangular box.  This function
     will write the height and width of that box where ‘width’ points
     to.  It assumes the center of the ellipse is located within the
     central pixel of the box.  ‘a’ is the ellipse semi-major axis
     length, ‘b’ is the semi-minor axis, ‘theta_deg’ is the position
     angle in degrees.  The ‘width’ array will contain the output size
     in long integer type.  ‘width[0]’, and ‘width[1]’ are the number of
     pixels along the first and second FITS axis.  Since the ellipse
     center is assumed to be in the center of the box, all the values in
     ‘width’ will be an odd integer.

 -- Function:
          void
          gal_box_bound_ellipsoid_extent (double *semiaxes, double
          *euler_deg, double *extent)
     Return the maximum extent along each dimension of the given
     ellipsoid from its center.  Therefore this is half the extent of
     the box in each dimension.  The semi-axis lengths of the ellipsoid
     must be present in the 3 element ‘semiaxis’ array.  The ‘euler_deg’
     array contains the three ellipsoid Euler angles in degrees.  For a
     description of the Euler angles, see description of
     ‘gal_box_bound_ellipsoid’ below.  The extent in each dimension is
     in floating point format and stored in ‘extent’ which must already
     be allocated before this function.

 -- Function:
          void
          gal_box_bound_ellipsoid (double *semiaxes, double *euler_deg,
          long *width)
     Any ellipsoid can be enclosed into a rectangular volume/box.  The
     purpose of this function is to give the integer size/width of that
     box.  The semi-axes lengths of the ellipse must be in the
     ‘semiaxes’ array (with three elements).  The major axis length must
     be the first element of ‘semiaxes’.  The only other condition is
     that the next two semi-axes must both be smaller than the first.
     The orientation of the major axis is defined through three proper
     Euler angles (ZXZ order in degrees) that are given in the
     ‘euler_deg’ array.  The ‘width’ array will contain the output size
     in long integer type (in FITS axis order).  Since the ellipsoid
     center is assumed to be in the center of the box, all the values in
     ‘width’ will be an odd integer.

     The proper Euler angles can be defined in many ways (which axes to
     rotate about).  For a full description of the Euler angles, please
     see Wikipedia (https://en.wikipedia.org/wiki/Euler_angles).  Here
     we adopt the ZXZ (or $Z_1X_2Z_3$) proper Euler angles were the
     first rotation is done around the Z axis, the second one about the
     (rotated) X axis and the third about the (rotated) Z axis.

 -- Function:
          void
          gal_box_border_from_center (double center, size_t ndim, long
          *width, long *fpixel, long *lpixel)
     Given the center coordinates in ‘center’ and the ‘width’ (along
     each dimension) of a box, return the coordinates of the first
     (‘fpixel’) and last (‘lpixel’) pixels.  All arrays must have ‘ndim’
     elements (one for each dimension).

 -- Function:
          void
          gal_box_border_rotate_around_center (long *fpixel, long
          *lpixel, size_t ndim, float rotate_deg)
     Modify the input first and last pixels (‘fpixel’ and ‘lpixel’, that
     you can estimate with ‘gal_box_border_from_center’) to account for
     the given rotation (in units of degrees) in 2D (currently ‘ndim’
     can only have a value of ‘2’).

 -- Function:
          int
          gal_box_overlap (long *naxes, long *fpixel_i, long *lpixel_i,
          long *fpixel_o, long *lpixel_o, size_t ndim)
     An ‘ndim’-dimensional dataset of size ‘naxes’ (along each
     dimension, in FITS order) and a box with first and last (inclusive)
     coordinate of ‘fpixel_i’ and ‘lpixel_i’ is given.  This box does
     not necessarily have to lie within the dataset, it can be outside
     of it, or only partially overlap.  This function will change the
     values of ‘fpixel_i’ and ‘lpixel_i’ to exactly cover the overlap in
     the input dataset's coordinates.

     This function will return 1 if there is an overlap and 0 if there
     is not.  When there is an overlap, the coordinates of the first and
     last pixels of the overlap will be put in ‘fpixel_o’ and
     ‘lpixel_o’.


File: gnuastro.info,  Node: Polygons,  Next: Qsort functions,  Prev: Bounding box,  Up: Gnuastro library

12.3.17 Polygons (‘polygon.h’)
------------------------------

Polygons are commonly necessary in image processing.  For example, in
Crop they are used for cutting out non-rectangular regions of a image
(see *note Crop::), and in Warp, for mapping different pixel grids over
each other (see *note Warp::).

   Polygons come in two classes: convex and concave (or generally,
non-convex!), see below for a demonstration.  Convex polygons are those
where all inner angles are less than 180 degrees.  By contrast, a convex
polygon is one where an inner angle may be more than 180 degress.

                 Concave Polygon        Convex Polygon

                  D --------C          D------------- C
                   \        |        E /              |
                    \E      |          \              |
                    /       |           \             |
                   A--------B             A ----------B

   In all the functions here the vertices (and points) are defined as an
array.  So a polygon with 4 vertices will be identified with an array of
8 elements with the first two elements keeping the 2D coordinates of the
first vertice and so on.

 -- Macro: GAL_POLYGON_MAX_CORNERS
     The largest number of vertices a polygon can have in this library.

 -- Macro: GAL_POLYGON_ROUND_ERR
     We have to consider floating point round-off errors when dealing
     with polygons.  For example, we will take ‘A’ as the maximum of ‘A’
     and ‘B’ when ‘A>B-GAL_POLYGON_ROUND_ERR’.

 -- Function:
          void
          gal_polygon_vertices_sort_convex (double *in, size_t n, size_t
          *ordinds)
     We have a simple polygon (that can result from projection, so its
     edges do not collide or it does not have holes) and we want to
     order its corners in an anticlockwise fashion.  This is necessary
     for clipping it and finding its area later.  The input vertices can
     have practically any order.

     The input (‘in’) is an array containing the coordinates (two
     values) of each vertice.  ‘n’ is the number of corners.  So ‘in’
     should have ‘2*n’ elements.  The output (‘ordinds’) is an array
     with ‘n’ elements specifying the indices in order.  This array must
     have been allocated before calling this function.  The indexes are
     output for more generic usage, for example, in a homographic
     transform (necessary in warping an image, see *note Linear warping
     basics::), the necessary order of vertices is the same for all the
     pixels.  In other words, only the positions of the vertices change,
     not the way they need to be ordered.  Therefore, this function
     would only be necessary once.

     As a summary, the input is unchanged, only ‘n’ values will be put
     in the ‘ordinds’ array.  Such that calling the input coordinates in
     the following fashion will give an anti-clockwise order when there
     are 4 vertices:

          1st vertice: in[ordinds[0]*2], in[ordinds[0]*2+1]
          2nd vertice: in[ordinds[1]*2], in[ordinds[1]*2+1]
          3rd vertice: in[ordinds[2]*2], in[ordinds[2]*2+1]
          4th vertice: in[ordinds[3]*2], in[ordinds[3]*2+1]

     The implementation of this is very similar to the Graham scan in
     finding the Convex Hull.  However, in projection we will never have
     a concave polygon (the left condition below, where this algorithm
     will get to E before D), we will always have a convex polygon
     (right case) or E will not exist!  This is because we are always
     going to be calculating the area of the overlap between a
     quadrilateral and the pixel grid or the quadrilateral itself.

     The ‘GAL_POLYGON_MAX_CORNERS’ macro is defined so there will be no
     need to allocate these temporary arrays separately.  Since we are
     dealing with pixels, the polygon cannot really have too many
     vertices.

 -- Function:
          int
          gal_polygon_is_convex (double *v, size_t n)
     Returns ‘1’ if the polygon is convex with vertices defined by ‘v’
     and ‘0’ if it is a concave polygon.  Note that the vertices of the
     polygon should be sorted in an anti-clockwise manner.

 -- Function:
          double
          gal_polygon_area_flat (double *v, size_t n)
     Find the area of a polygon with vertices defined in ‘v’ on a
     euclidian (flat) coordinate system.  ‘v’ points to an array of
     doubles which keep the positions of the vertices such that ‘v[0]’
     and ‘v[1]’ are the positions of the first vertice to be considered.

 -- Function:
          double
          gal_polygon_area_sky (double *v, size_t n)
     Find the area of a polygon with vertices defined in ‘v’ on a
     celestial coordinate system.  This is a coordinate system where the
     first coordinate goes from 0 to 360 (increasing to the right),
     while the second coordinate ranges from -90 to +90 (on the poles).
     ‘v’ points to an array of doubles which keep the positions of the
     vertices such that ‘v[0]’ and ‘v[1]’ are the positions of the first
     vertice to be considered.

     This function uses an approximation to account for the curvature of
     the sky and the different nature of spherical coordinates with
     respect to the flat coordinate system.  Bug 64617
     (https://savannah.gnu.org/bugs/index.php?64617) has been defined in
     Gnuastro to address this problem.  Please check that bug in case it
     has been fixed.  Until this bug is fixed, here are some tips:
        • Subtract the RA and Dec of all the vertice coordinates from a
          constant so the center of the polygon falls on (RA, Dec) of
          (180,0).  The sphere has a similar nature everywhere on it, so
          shifting the polygon vertices will not change its area; this
          also removes issues with the RA=0 or RA=360 coordinate and
          decrease issues caused by RA depending on declination.
        • These approximations should not cause any statistically
          significant error on normal (less than a few degrees) scales.
          But it won't hurt to do a small sanity check for your
          particular usage scenario.
        • Any help (even in the mathematics of the problem; not
          necessary programming) would be appreciated (we didn't have
          time to derive the necessary equations), so if you have some
          background in this and can prepare the mathematical
          description of the problem, please get in touch.

 -- Function:
          int
          gal_polygon_is_inside (double *v, double *p, size_t n)
     Returns ‘0’ if point ‘p’ in inside a polygon, either convex or
     concave.  The vertices of the polygon are defined by ‘v’ and ‘0’
     otherwise, they have to be ordered in an anti-clockwise manner.
     This function uses the winding number algorithm
     (https://en.wikipedia.org/wiki/Point_in_polygon#Winding_number_algorithm),
     to check the points.  Note that this is a generic function (working
     on both concave and convex polygons, so if you know before-hand
     that your polygon is convex, it is much more efficient to use
     ‘gal_polygon_is_inside_convex’.

 -- Function:
          int
          gal_polygon_is_inside_convex (double *v, double *p, size_t n)
     Return ‘1’ if the point ‘p’ is within the polygon whose vertices
     are defined by ‘v’.  The polygon is assumed to be convex, for a
     more generic function that deals with concave and convex polygons,
     see ‘gal_polygon_is_inside’.  Note that the vertices of the polygon
     have to be sorted in an anti-clock-wise manner.

 -- Function:
          int
          gal_polygon_ppropin (double *v, double *p, size_t n)
     Similar to ‘gal_polygon_is_inside_convex’, except that if the point
     ‘p’ is on one of the edges of a polygon, this will return ‘0’.

 -- Function:
          int
          gal_polygon_is_counterclockwise (double *v, size_t n)
     Returns ‘1’ if the sorted polygon has a counter-clockwise
     orientation and ‘0’ otherwise.  This function uses the concept of
     "winding", which defines the relative order in which the vertices
     of a polygon are listed to determine the orientation of vertices.
     For complex polygons (where edges, or sides, intersect), the most
     significant orientation is returned.  In a complex polygon, when
     the alternative windings are equal (for example, an ‘8’-shape) it
     will return ‘1’ (as if it was counter-clockwise).  Note that the
     polygon vertices have to be sorted before calling this function.

 -- Function:
          int
          gal_polygon_to_counterclockwise (double *v, size_t n)
     Arrange the vertices of the sorted polygon in place, to be in a
     counter-clockwise direction.  If the input polygon already has a
     counter-clockwise direction it will not touch the input.  The
     return value is ‘1’ on successful execution.  This function is just
     a wrapper over ‘gal_polygon_is_counterclockwise’, and will reverse
     the order of the vertices when necessary.

 -- Function:
          void
          gal_polygon_clip (double *s, size_t n, double *c, size_t m,
          double *o, size_t *numcrn)
     Clip (find the overlap of) two polygons.  This function uses the
     Sutherland-Hodgman
     (https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)
     polygon clipping algorithm.  Note that the vertices of both
     polygons have to be sorted in an anti-clock-wise manner.

     The Pseudocode from Wikipedia:
     List outputList = subjectPolygon;
     for (Edge clipEdge in clipPolygon) do
       List inputList = outputList;
       outputList.clear();
       Point S = inputList.last;
       for (Point E in inputList) do
          if (E inside clipEdge) then
             if (S not inside clipEdge) then
                outputList.add(ComputeIntersection(S,E,clipEdge));
             end if
             outputList.add(E);
          else if (S inside clipEdge) then
             outputList.add(ComputeIntersection(S,E,clipEdge));
          end if
          S = E;
       done
     done

     The difference is that we are not using lists, but arrays to keep
     polygon vertices.  The two polygons are called Subject ‘s’ and Clip
     ‘c’ with ‘n’ and ‘m’ vertices respectively.  The output is stored
     in ‘o’ and the number of elements in the output are stored in what
     ‘*numcrn’ (for number of corners) points to.

 -- Function:
          void
          gal_polygon_vertices_sort (double *vertices, size_t n, size_t
          *ordinds)
     Sort the indices of the un-ordered ‘vertices’ array to a
     counter-clockwise polygon in the already allocated space of
     ‘ordinds’.  It is assumed that there are ‘n’ vertices, and thus
     that ‘vertices’ contains ‘2*n’ elements where the two coordinates
     of the first vertice occupy the first two elements of the array and
     so on.

     The polygon can be both concave and convex (see the start of this
     section).  However, note that for concave polygons there is no
     unique sort from an un-ordered set of vertices.  So after this
     function you may want to use ‘gal_polygon_is_convex’ and print a
     warning to check the output if the polygon was concave.

     Note that the contents of the ‘vertices’ array are left untouched
     by this function.  If you want to write the ordered vertice
     coordinates in another array with the same size, you can use a loop
     like this:

          for(i=0;i<n;++i)
          {
            ordered[i*2  ] = vertices[ ordinds[i]*2    ];
            ordered[i*2+1] = vertices[ ordinds[i]*2 + 1];
          }

     In this algorithm, we find the rightmost and leftmost points (based
     on their x-coordinate) and use the diagonal vector between those
     points to group the points in arrays based on their position with
     respect to this vector.  For anticlockwise sorting, all the points
     below the vector are sorted by their ascending x-coordinates and
     points above the vector are sorted in decreasing order using
     ‘qsort’.  Finally, both these arrays are merged together to get the
     final sorted array of points, from which the points are indexed
     into the ‘ordinds’ using linear search.