gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 96ab804 098/125: Working on tiles implemented


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 96ab804 098/125: Working on tiles implemented in tile checking
Date: Sun, 23 Apr 2017 22:36:47 -0400 (EDT)

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

    Working on tiles implemented in tile checking
    
    The most basic thing to do on tiles before actually working on them is to
    check them. All the programs that use tiles have the `--checktiles'
    (previously `--checkmesh') option for the user to see if their selected
    tiles suite their purpose. So the `gal_tile_block_check_tiles' library
    function was defined to do this and has been tested with this commit.
    
    The function also surved as a great test-bed to define a general way to
    parse a tile over an allocated block of memory. The old `lastmeshfrac'
    option has also been renamed to `remainderfrac' to be more clear.
    
    In the process the following changes were also made:
    
     - The two `gal_data_ptr_increment' and `gal_data_ptr_dist' have been
       defined to allow arithmetic on `void *' pointers given a certain
       type. These were necessary for working directy with the `array' element
       of `gal_data_t' (which is `void *').
    
     - The `gal_multidim_add_coords' function was added for easy addition of
       coordinates (with any dimension).
---
 bin/convolve/args.h           |  13 ++
 bin/convolve/astconvolve.conf |   1 +
 bin/convolve/convolve.c       |  19 ++-
 bin/convolve/main.h           |   1 +
 bin/convolve/ui.c             |  15 ++-
 bin/convolve/ui.h             |   3 +-
 doc/gnuastro.texi             |  26 ++--
 lib/convolve.c                |  21 ++++
 lib/data.c                    |  36 ++++++
 lib/fits.c                    |   2 +-
 lib/gnuastro/convolve.h       |   7 +-
 lib/gnuastro/data.h           |   6 +
 lib/gnuastro/multidim.h       |   3 +
 lib/gnuastro/tile.h           |  32 +++--
 lib/multidim.c                |  11 ++
 lib/tile.c                    | 286 +++++++++++++++++++++++++++++++++++++-----
 16 files changed, 414 insertions(+), 68 deletions(-)

diff --git a/bin/convolve/args.h b/bin/convolve/args.h
index cbda046..ab310b4 100644
--- a/bin/convolve/args.h
+++ b/bin/convolve/args.h
@@ -154,6 +154,19 @@ struct argp_option program_options[] =
       gal_options_parse_sizes_reverse
     },
     {
+      "remainderfrac",
+      ARGS_OPTION_KEY_REMAINDERFRAC,
+      "FLT",
+      0,
+      "Fraction of remainers in each dim to chop.",
+      ARGS_GROUP_MESH_GRID,
+      &p->remainderfrac,
+      GAL_DATA_TYPE_FLOAT32,
+      GAL_OPTIONS_RANGE_GT_0_LT_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+    },
+    {
       "convoverch",
       ARGS_OPTION_KEY_CONVOVERCH,
       0,
diff --git a/bin/convolve/astconvolve.conf b/bin/convolve/astconvolve.conf
index 908f523..941e714 100644
--- a/bin/convolve/astconvolve.conf
+++ b/bin/convolve/astconvolve.conf
@@ -27,6 +27,7 @@
 # Mesh grid:
  tile               30,30
  numchannels        1,1
+ remainderfrac      0.1
  convoverch         0
 
 # Operating mode:
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index ba51617..3c7d1c0 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -33,6 +33,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/tile.h>
 #include <gnuastro/fits.h>
 #include <gnuastro/threads.h>
+#include <gnuastro/convolve.h>
 #include <gnuastro/spatialconvolve.h>
 
 #include <timing.h>
@@ -768,29 +769,25 @@ frequencyconvolve(struct convolveparams *p)
 void
 convolve(struct convolveparams *p)
 {
-  size_t ntiles, nch;
-  gal_data_t *tiles, *channels=NULL;
+  gal_data_t *tiles, *channels=NULL; /* `channels' has to be initialized. */
 
   /* Do the convolution. */
   if(p->domain==CONVOLVE_DOMAIN_SPATIAL)
     {
       /* Prepare the mesh structure. */
       gal_tile_all_position_two_layers(p->input, p->channel, p->tile,
-                                       &channels, &tiles, &ntiles, &nch);
+                                       p->remainderfrac, &channels, &tiles);
 
-      /* Save it to the output if requested. */
+      /* Save the tile IDs if they are requested. */
       if(p->tilesname)
-        error(EXIT_FAILURE, 0, "saving mesh structure to a file is not "
-              "yet implemented");
+        gal_tile_block_check_tiles(tiles, p->tilesname, PROGRAM_NAME);
 
       /* Do the spatial convolution. */
-
-
-      /* Replace the input image array with the convolved array: */
+      gal_convolve_spatial(tiles, p->kernel);
 
       /* Clean up */
-      gal_data_array_free(tiles, ntiles, 0);
-      gal_data_array_free(channels, nch, 0);
+      gal_data_array_free(tiles, gal_data_num_in_ll(tiles), 0);
+      gal_data_array_free(channels, gal_data_num_in_ll(channels), 0);
     }
   else
     frequencyconvolve(p);
diff --git a/bin/convolve/main.h b/bin/convolve/main.h
index 55b785f..ab8d157 100644
--- a/bin/convolve/main.h
+++ b/bin/convolve/main.h
@@ -81,6 +81,7 @@ struct convolveparams
   uint8_t     checkfreqsteps;  /* View the frequency domain steps.        */
   size_t               *tile;  /* Size of tiles along each dim. (C order).*/
   size_t        *numchannels;  /* No. of tiles along each dim. (C order). */
+  float        remainderfrac;  /* Frac. of remainers in each dim to cut.  */
   uint8_t         convoverch;  /* Convolve over channel borders.          */
   uint8_t         checktiles;  /* Tile IDs in an img, the size of input.  */
   char            *domainstr;  /* String value specifying domain.         */
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index ebaee5f..8ccf534 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -322,12 +322,19 @@ ui_preparations(struct convolveparams *p)
   if(p->cp.output==NULL)
     p->cp.output=gal_checkset_automatic_output(&p->cp, p->filename,
                                                outsuffix);
+  gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
   if(p->checkfreqsteps)
-    p->freqstepsname=gal_checkset_automatic_output(&p->cp, p->filename,
-                                                   "_freqsteps.fits");
+    {
+      p->freqstepsname=gal_checkset_automatic_output(&p->cp, p->filename,
+                                                     "_freqsteps.fits");
+      gal_checkset_check_remove_file(p->freqstepsname, 0, p->cp.dontdelete);
+    }
   if(p->checktiles)
-    p->tilesname=gal_checkset_automatic_output(&p->cp, p->filename,
-                                               "_tiled.fits");
+    {
+      p->tilesname=gal_checkset_automatic_output(&p->cp, p->filename,
+                                                 "_tiled.fits");
+      gal_checkset_check_remove_file(p->tilesname, 0, p->cp.dontdelete);
+    }
 
 
   /* Read the input image as a float64 array and its WCS info. */
diff --git a/bin/convolve/ui.h b/bin/convolve/ui.h
index 85fe4c1..a4df9f5 100644
--- a/bin/convolve/ui.h
+++ b/bin/convolve/ui.h
@@ -29,7 +29,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 /* Available letters for short options:
 
-   a b e f g i j l n p r s v w x y z
+   a b e f g i j l n p s v w x y z
    A B E F G J L M O Q R W X Y Z
 */
 enum option_keys_enum
@@ -41,6 +41,7 @@ enum option_keys_enum
   ARGS_OPTION_KEY_CHECKFREQSTEPS = 'C',
   ARGS_OPTION_KEY_TILE           = 't',
   ARGS_OPTION_KEY_NUMCHANNELS    = 'c',
+  ARGS_OPTION_KEY_REMAINDERFRAC  = 'r',
   ARGS_OPTION_KEY_DOMAIN         = 'd',
   ARGS_OPTION_KEY_MAKEKERNEL     = 'm',
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 5fdd9cd..2623302 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -6095,7 +6095,7 @@ END
 @cindex Operations on files
 @cindex General file operations
 The most low-level and basic property of a dataset is how it is stored. To
-process, archive and transmit the data you need a container to store it
+process, archive and transmit the data, you need a container to store it
 first. From the start of the computer age, different formats have been
 difined to store data, optimized for pariticular applications, one
 format/container can never be useful for all applications. In astronomy,
@@ -6112,21 +6112,23 @@ and processed FITS images or spectra as figures within 
slides, reports, or
 papers. The FITS format is not defined for such applications. Thus,
 Gnuastro also comes with the ConvertType program (see @ref{ConvertType})
 which can be used to convert a FITS image to and from (where possible)
-other formats like plain text and JPEG which allow two way conversion,
+other formats like plain text and JPEG (which allow two way conversion),
 along with EPS and PDF (which can only be created from FITS, not the other
 way round).
 
 Finally, the FITS format is not just for images, it can also store
-tables. Binary tables in particular can be very useful in storing very
-large catalogs or tables compared to a plain text file. However, unlike
-images (where all elements/pixels have one data type), tables contain
-multiple columns and each column can have different properties (numerical
-types, or even character based columns, like names). In practice, each
-column can be viewed a separate data-container that is grouped with others
-in the table. To allow easy manipulation/viewing of table columns, Gnuastro
-has the Table program (see @ref{Table}). It can be used to choose certain
-table columns in a FITS table and see them as a human readable output on
-the command-line, or to save them into another plain text or FITS table.
+tables. Binary tables in particular can be very useful in storing catalogs
+that have more than a few tens of columns and rows. However, unlike images
+(where all elements/pixels have one data type), tables contain multiple
+columns and each column can have different properties: independent data
+types (see @ref{Numeric data types}) and meta-data. In practice, each
+column can be viewed as a separate container that is grouped with others in
+the table. The only shared property of the colums in a FITS table is thus
+the number of elements they contain. To allow easy inspection/manipulation
+of table columns, Gnuastro has the Table program (see @ref{Table}). It can
+be used to select certain table columns in a FITS table and see them as a
+human readable output on the command-line, or to save them into another
+plain text or FITS table.
 
 @menu
 * Fits::                        View and manipulate extensions and keywords.
diff --git a/lib/convolve.c b/lib/convolve.c
index ad75704..802c50d 100644
--- a/lib/convolve.c
+++ b/lib/convolve.c
@@ -28,3 +28,24 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <stdlib.h>
 
 #include <gnuastro/tile.h>
+
+
+
+/* Do spatial convolution on each mesh. */
+static void *
+gal_convolve_spatial_on_thread(void *inparm)
+{
+  return NULL;
+}
+
+
+
+
+
+/* Convolve a dataset with a given kernel in the spatial domain. Since
+   spatial convolution can be very series of tiles arranged as an array. */
+void
+gal_convolve_spatial(gal_data_t *tiles, gal_data_t *kernel)
+{
+
+}
diff --git a/lib/data.c b/lib/data.c
index 8168ce4..1ad6b21 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -364,6 +364,42 @@ gal_data_sizeof(uint8_t type)
 
 
 
+/* Increment a give pointer depending on the given type.
+
+   When working with the `array' elements of `gal_data_t', we are actually
+   dealing with `void *' pointers. Pointer arithmetic doesn't apply to
+   `void *', because the system doesn't know how much space each element
+   has to increment the pointer respectively.
+
+   So, here, we will use the type information to find the increment. This
+   is mainly useful when dealing with the `block' pointer of a tile over a
+   larger image. This function reads the address as a `char *' type (note
+   that `char' is guaranteed to have a size of 1 (byte)). It then
+   increments the `char *' by `increment*sizeof(type)' */
+void *
+gal_data_ptr_increment(void *pointer, size_t increment, uint8_t type)
+{
+  char *p=(char *)pointer;
+  return p + increment * gal_data_sizeof(type);
+}
+
+
+
+
+
+/* Find the distance between two void pointers with a given type. See the
+   explanations before `gal_data_ptr_increment'. */
+size_t
+gal_data_ptr_dist(void *earlier, void *later, uint8_t type)
+{
+  char *e=(char *)earlier, *l=(char *)later;
+  return (l-e)/gal_data_sizeof(type);
+}
+
+
+
+
+
 /* Copy the WCS structure from the input to the output structure. */
 void
 gal_data_copy_wcs(gal_data_t *in, gal_data_t *out)
diff --git a/lib/fits.c b/lib/fits.c
index 161c6c9..2f7aa5a 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -503,7 +503,7 @@ gal_fits_open_to_write(char *filename)
     }
 
   /* Open the file, ready for later steps. */
-  if( fits_open_file(&fptr,filename, READWRITE, &status) )
+  if( fits_open_file(&fptr, filename, READWRITE, &status) )
     gal_fits_io_error(status, NULL);
 
   /* Return the pointer. */
diff --git a/lib/gnuastro/convolve.h b/lib/gnuastro/convolve.h
index 1a18d53..9ed035f 100644
--- a/lib/gnuastro/convolve.h
+++ b/lib/gnuastro/convolve.h
@@ -20,8 +20,8 @@ General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/
-#ifndef __GAL_TILE_H__
-#define __GAL_TILE_H__
+#ifndef __GAL_CONVOLVE_H__
+#define __GAL_CONVOLVE_H__
 
 /* Include other headers if necessary here. Note that other header files
    must be included before the C++ preparations below */
@@ -44,7 +44,8 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
-
+void
+gal_convolve_spatial(gal_data_t *tiles, gal_data_t *kernel);
 
 
 
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index d1f4fa9..a7b8799 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -263,6 +263,12 @@ size_t
 gal_data_sizeof(uint8_t type);
 
 void *
+gal_data_ptr_increment(void *pointer, size_t increment, uint8_t type);
+
+size_t
+gal_data_ptr_dist(void *earlier, void *later, uint8_t type);
+
+void *
 gal_data_malloc_array(uint8_t type, size_t size);
 
 void *
diff --git a/lib/gnuastro/multidim.h b/lib/gnuastro/multidim.h
index df51d4d..3f37d8f 100644
--- a/lib/gnuastro/multidim.h
+++ b/lib/gnuastro/multidim.h
@@ -55,6 +55,9 @@ gal_multidim_total_size(size_t ndim, size_t *dsize);
 /************************************************************************/
 /********************          Coordinates         **********************/
 /************************************************************************/
+void
+gal_multidim_add_coords(size_t *c1, size_t *c2, size_t *out, size_t ndim);
+
 size_t
 gal_multidim_coord_to_index(size_t ndim, size_t *dsize, size_t *coord);
 
diff --git a/lib/gnuastro/tile.h b/lib/gnuastro/tile.h
index b53d683..6891d4d 100644
--- a/lib/gnuastro/tile.h
+++ b/lib/gnuastro/tile.h
@@ -46,14 +46,31 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 
 
+
+
+
 /***********************************************************************/
 /**************             About block           **********************/
 /***********************************************************************/
-size_t *
-gal_tile_block_size(gal_data_t *input);
+gal_data_t *
+gal_tile_block(gal_data_t *input);
 
 void
-gal_tile_block_tile_start_coord(gal_data_t *tile, size_t *start_coord);
+gal_tile_block_start_coord(gal_data_t *tile, size_t *start_coord);
+
+void *
+gal_tile_block_start_end(gal_data_t *tile, gal_data_t *work,
+                         size_t *start_end);
+
+size_t
+gal_tile_block_increment(gal_data_t *block, size_t *tsize,
+                         size_t num_increment);
+
+void
+gal_tile_block_check_tiles(gal_data_t *tiles, char *filename,
+                           char *program_name);
+
+
 
 
 /***********************************************************************/
@@ -64,14 +81,13 @@ gal_tile_all_sanity_check(char *filename, char *hdu, 
gal_data_t *input,
                           size_t *tile, size_t *numchannels);
 
 size_t
-gal_tile_all_position(gal_data_t *input, size_t *regular, gal_data_t **out,
-                      size_t multiple);
+gal_tile_all_position(gal_data_t *input, size_t *regular,
+                      float remainderfrac, gal_data_t **out, size_t multiple);
 
 void
 gal_tile_all_position_two_layers(gal_data_t *input, size_t *channel_size,
-                                 size_t *tile_size, gal_data_t **channels,
-                                 gal_data_t **tiles, size_t *numchannels,
-                                 size_t *numtiles);
+                                 size_t *tile_size, float remainderfrac,
+                                 gal_data_t **channels, gal_data_t **tiles);
 
 
 
diff --git a/lib/multidim.c b/lib/multidim.c
index 837f1f4..d092770 100644
--- a/lib/multidim.c
+++ b/lib/multidim.c
@@ -66,6 +66,17 @@ gal_multidim_total_size(size_t ndim, size_t *dsize)
 /************************************************************************/
 /********************          Coordinates         **********************/
 /************************************************************************/
+void
+gal_multidim_add_coords(size_t *c1, size_t *c2, size_t *out, size_t ndim)
+{
+  size_t *end=c1+ndim;
+  do *out++ = *c1++ + *c2++; while(c1<end);
+}
+
+
+
+
+
 /* Return the index of an element from its coordinates. The index is the
    position in the contiguous array (assuming it is a 1D arrray). */
 size_t
diff --git a/lib/tile.c b/lib/tile.c
index 7bd9bb1..f1f742d 100644
--- a/lib/tile.c
+++ b/lib/tile.c
@@ -26,11 +26,15 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <errno.h>
 #include <error.h>
 #include <stdlib.h>
+#include <string.h>
 
+#include <gnuastro/fits.h>
 #include <gnuastro/tile.h>
+#include <gnuastro/blank.h>
+#include <gnuastro/convolve.h>
 #include <gnuastro/multidim.h>
 
-
+#include "checkset.h"
 
 
 
@@ -56,23 +60,242 @@ gal_tile_block(gal_data_t *input)
 /* Calculate the starting coordinates of a tile in the allocated block of
    memory. */
 void
-gal_tile_block_tile_start_coord(gal_data_t *tile, size_t *start_coord)
+gal_tile_block_start_coord(gal_data_t *tile, size_t *start_coord)
 {
-  size_t *s, *sf, ind;
+  size_t ind, ndim=tile->ndim;
   gal_data_t *block=gal_tile_block(tile);
 
-  /* If the input tile is actually the same as the block, then the
-     reference is all zeros. */
+  /* If the input tile is actually the same as the block, then the start is
+     at 0 (in all dimensions). */
   if(block==tile)
+    memset(start_coord, 0, ndim*gal_data_sizeof(GAL_DATA_TYPE_SIZE_T));
+  else
+    {
+      /* Calculate the coordinates of the first pixel of the tile. */
+      ind = gal_data_ptr_dist(block->array, tile->array, block->type);
+      gal_multidim_index_to_coord(ind, ndim, block->dsize, start_coord);
+    }
+}
+
+
+
+
+/* Given a tile  */
+void *
+gal_tile_block_start_end(gal_data_t *tile, gal_data_t *work,
+                         size_t *start_end)
+{
+  size_t ndim=tile->ndim, *s, *sf;
+  gal_data_t *block=gal_tile_block(tile);
+  size_t *start_coord = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  size_t *end_coord   = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+
+
+  /* The starting index can be found from the distance of the `tile->array'
+     pointer and `block->array' pointer. IMPORTANT: with the type of the
+     block array.  */
+  start_end[0]=gal_data_ptr_dist(block->array, tile->array, block->type);
+
+
+  /* To find the end index, we need to know the coordinates of the starting
+     point in the allocated block.  */
+  gal_multidim_index_to_coord(start_end[0], ndim, block->dsize, start_coord);
+
+
+  /* Adding the coordinates of the starting point with the tile's
+     dimensions, we will get the ending point's coordinates. */
+  gal_multidim_add_coords(start_coord, tile->dsize, end_coord, ndim);
+
+
+  /* `end_coord' is one unit ahead of the last element in the tile in every
+     dimension. To have less potential for bugs, we will remove that extra
+     value, so we get the coordinates of the last pixel in the tile
+     (inclusive). We will finally, increment that value by one to get to
+     the pixel immediately outside of the tile.*/
+  sf=(s=end_coord)+ndim; do *s-=1; while(++s<sf);
+
+
+  /* Convert the (inclusive) ending point's coordinates into an index. */
+  start_end[1]=gal_multidim_coord_to_index(ndim, block->dsize, end_coord);
+
+
+  /* Increment the (inclusive) ending point's index by one to be
+     immediately outside the tile. */
+  ++start_end[1];
+
+
+  /* For a check:
+  printf("\ntile_dsize: %zu, %zu, %zu\n", tile->dsize[0], tile->dsize[1],
+         tile->dsize[2]);
+  printf("start_coord: %zu, %zu, %zu\n", start_coord[0], start_coord[1],
+         start_coord[2]);
+  printf("end_coord: %zu, %zu, %zu\n", end_coord[0], end_coord[1],
+         end_coord[2]);
+  printf("start_index: %zu\n", start_end[0]);
+  printf("end_index: %zu\n", start_end[1]);
+  exit(1);
+  */
+
+
+  /* Clean up and return the pointer in the work array that the tile starts
+     from. */
+  free(end_coord);
+  free(start_coord);
+  return gal_data_ptr_increment(work->array, start_end[0], work->type);
+}
+
+
+
+
+
+/* Return the increment necessary to start at the next series of contiguous
+   memory (fastest dimension) associated with a tile. See
+   `gal_tile_block_check_tiles' as one example application of this
+   function.
+
+   1D and 2D cases are simple and need no extra explanation, but the case
+   for higher dimensions can be alittle more complicated, So we will go
+   over some examples. The notations below are:
+
+       `n'     number of dimensions (same in tile and block).
+       `t[]'   size of the tile in each dimension.
+       `b[]'   size of the allocated block in each dimension.
+
+   It is just important to see the output of this function as an increment
+   from the the last patch of contiguous memory associated with the
+   tile. So when the increment number is `t[n-1]' (the first 2D slice of
+   the tile has been parsed), simply incrementing by `b[n-2] * b[n-1]' will
+   take us to the last row of
+
+        num_increment              increment
+        -------------              ---------
+             0               b[n-1]: fastest dimension of the block.
+             1               Similar to previous
+             .                         .
+             .                         .
+           t[n-2]            (b[n-2] * b[n-1]) - ( (t[n-2]-1) * b[n-1] )
+           t[n-2] + 1        b[n-1]
+             .                         .
+             .                         .
+          2 * t[n-2]         b[n-2] * b[n-1]
+           t[n-2]+1          b[n-1]
+             .                         .
+             .                         .
+      t[n-3] * t[n-2]        b[n-3] * b[n-2] * b[n-1]
+
+ */
+size_t
+gal_tile_block_increment(gal_data_t *block, size_t *tsize,
+                         size_t num_increment)
+{
+  size_t n=block->ndim;
+  size_t *b=block->dsize, *t=tsize;
+
+  if(n>3)
+    error(EXIT_FAILURE, 0, "`gal_tile_block-increment' is currently only "
+          "implemented for at most 3 dimensions");
+
+  switch(n)
     {
-      sf = (s=start_coord) + tile->ndim;
-      do *s++=0; while(s<sf);
-      return;
+    case 0:
+      error(EXIT_FAILURE, 0, "zero dimensional input is not acceptable in "
+            "`gal_tile_block_parse'");
+
+    /* 1D: the increment is just the tile size. */
+    case 1:
+      return t[0];
+      break;
+
+    /* 2D: the increment is the block's number of fastest axis pixels. */
+    case 2:
+      return b[1];
+      break;
+
+    /* Higher dimensions. */
+    default:
+      if(num_increment % t[n-2]) return b[n-1];
+      else return (b[n-2] * b[n-1]) - ( (t[n-2]-1) * b[n-1] );
+      break;
     }
+}
+
 
-  /* Calculate the coordinates of the first pixel of the tile. */
-  ind = tile->array - block->array;
-  gal_multidim_index_to_coord(ind, tile->ndim, block->dsize, start_coord);
+
+
+
+/* Make a copy of the memory block in integer type and fill it with the ID
+   of each tile, the non-filled areas have blank values. Finally, save the
+   final array into a FITS file, specified with `filename'. This is done
+   mainly for inspecting the positioning of tiles. We are using a signed
+   32-bit type because this is the standard FITS standard type for
+   integers. */
+void
+gal_tile_block_check_tiles(gal_data_t *tiles, char *filename,
+                           char *program_name)
+{
+  size_t num_increment;
+  gal_data_t *tofill, *tile;
+  gal_data_t *block=gal_tile_block(tiles);
+  int32_t *p, *pf, tile_index=0, *start=NULL;
+  size_t ndim=tiles->ndim, increment, start_end[2];
+
+  /***************************************************************/
+  /*************            For a check           ****************
+  float c=0;
+  block->wcs=NULL;
+  ndim=block->ndim=tiles->ndim=3;
+  block->dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  block->dsize[0]=5; block->dsize[1]=5; block->dsize[2]=5;
+
+  tiles->dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+  tiles->dsize[0]=2; tiles->dsize[1]=3; tiles->dsize[2]=3;
+  tiles->array=gal_data_ptr_increment(block->array, 36, block->type);
+  tiles->next=NULL;
+  **************************************************************/
+
+  /* Allocate the output array. */
+  tofill=gal_data_alloc(NULL, GAL_DATA_TYPE_INT32, ndim, block->dsize,
+                        block->wcs, 0, block->minmapsize, "TILE_CHECK",
+                        "counts", "indexs of all tiles");
+
+  /* Initialize the allocated space with blank characters for this type. */
+  pf=(p=tofill->array)+tofill->size; do *p++=GAL_BLANK_INT32; while(p<pf);
+
+  /* Fill in the labels of each tile. */
+  for(tile=tiles; tile!=NULL; tile=tile->next)
+    {
+      /* Set the starting and ending indexs of this tile over the allocated
+         block. */
+      start=gal_tile_block_start_end(tile, tofill, start_end);
+
+      /* Go over the full area of this tile. The loop will stop as soon as
+         the incrementation will go over the last index of the tile. Note
+         that num_increment has to start from 1 because having a remainder
+         of zero is meaningful in the calculation of the increment. */
+      increment=0;
+      num_increment=1;
+      while( start_end[0] + increment < start_end[1] )
+        {
+          /* Parse the elements in the fastest-dimension (the contiguous
+             patch of memory associated with this tile). */
+          pf = ( p = start + increment ) + tile->dsize[ndim-1];
+          do *p++=tile_index; while(p<pf);
+
+          /* Increase the increment from the start of the tile for the next
+             contiguous patch. */
+          increment += gal_tile_block_increment(block, tile->dsize,
+                                                num_increment++);
+        }
+
+      /* Increment the index for the next tile. */
+      ++tile_index;
+    }
+
+  /* Save the indexs into a file. */
+  gal_fits_img_write(tofill, filename, NULL, program_name);
+
+  /* Clean up. */
+  gal_data_free(tofill);
 }
 
 
@@ -306,8 +529,8 @@ gal_tile_all_regular_first(gal_data_t *parent, size_t 
*regular,
            dimension (we don't want to go out of the paren't range).
 */
 size_t
-gal_tile_all_position(gal_data_t *input, size_t *regular, gal_data_t **out,
-                      size_t multiple)
+gal_tile_all_position(gal_data_t *input, size_t *regular,
+                      float remainderfrac, gal_data_t **out, size_t multiple)
 {
   size_t i, d, tind, numtiles, *start=NULL;
   gal_data_t *tiles, *block=gal_tile_block(input);
@@ -320,7 +543,8 @@ gal_tile_all_position(gal_data_t *input, size_t *regular, 
gal_data_t **out,
 
   /* Set the first tile size and total number of tiles along each
      dimension, then allocate the array of tiles. */
-  gal_tile_all_regular_first(input, regular, 0.3, first, last, tsize);
+  gal_tile_all_regular_first(input, regular, remainderfrac,
+                             first, last, tsize);
   numtiles=gal_multidim_total_size(input->ndim, tsize);
 
 
@@ -335,7 +559,7 @@ gal_tile_all_position(gal_data_t *input, size_t *regular, 
gal_data_t **out,
   if(input->block)
     {
       start=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-      gal_tile_block_tile_start_coord(input, start);
+      gal_tile_block_start_coord(input, start);
     }
 
 
@@ -372,7 +596,7 @@ gal_tile_all_position(gal_data_t *input, size_t *regular, 
gal_data_t **out,
       /* Now that we have the index of this tile's starting point compared
          to the allocated block, put it in to the tile's `array'
          pointer. */
-      tiles[i].array=block->array+tind;
+      tiles[i].array=gal_data_ptr_increment(block->array, tind, block->type);
 
       /* Set the sizes of the tile. */
       tiles[i].ndim=input->ndim;
@@ -393,8 +617,11 @@ gal_tile_all_position(gal_data_t *input, size_t *regular, 
gal_data_t **out,
             tiles[i].dsize[d]=regular[d];
         }
 
-      /* Set the block structure for this tile to the `input'. */
-      tiles[i].block=input;
+      /* Set the block structure for this tile to the `input', and set the
+         next pointer as the next tile. Note that only when we are dealing
+         with the last tile should the `next' pointer be set to NULL.*/
+      tiles[i].block = input;
+      tiles[i].next = i==numtiles-1 ? NULL : &tiles[i+1];
 
       /* For a check:
       printf("%zu:\n\tStart index: %zu\n\tsize: %zu x %zu\n", i, tind,
@@ -432,9 +659,8 @@ gal_tile_all_position(gal_data_t *input, size_t *regular, 
gal_data_t **out,
            gradients over each channel and thus over the whole image.  */
 void
 gal_tile_all_position_two_layers(gal_data_t *input, size_t *channel_size,
-                                 size_t *tile_size, gal_data_t **channels,
-                                 gal_data_t **tiles, size_t *numchannels,
-                                 size_t *numtiles)
+                                 size_t *tile_size, float remainderfrac,
+                                 gal_data_t **channels, gal_data_t **tiles)
 {
   gal_data_t *ch, *t;
   size_t i, nch, ntiles_in_ch;
@@ -450,7 +676,8 @@ gal_tile_all_position_two_layers(gal_data_t *input, size_t 
*channel_size,
   else
     /* Note that the actual allocated input array will be the direct
        `block' of each channel. */
-    nch=gal_tile_all_position(input, channel_size, channels, 1);
+    nch=gal_tile_all_position(input, channel_size, remainderfrac,
+                              channels, 1);
 
 
   /* Now, tile each channel. While tiling the first channel, we are also
@@ -458,14 +685,17 @@ gal_tile_all_position_two_layers(gal_data_t *input, 
size_t *channel_size,
      pointers. */
   *tiles=NULL;
   ch=*channels;
-  ntiles_in_ch = gal_tile_all_position(ch, tile_size, tiles, nch);
+  ntiles_in_ch = gal_tile_all_position(ch, tile_size, remainderfrac,
+                                       tiles, nch);
   for(i=1;i<nch;++i)
     {
+      /* Set the first tile in this channel. Then use it it fill the `next'
+         pointer of the previous channel's tiles. Note that
+         `gal_tile_all_position' set this `next' element to NULL. */
       t = *tiles + i*ntiles_in_ch;
-      gal_tile_all_position(&ch[i], tile_size, &t, 1);
-    }
+      (*tiles)[ i * ntiles_in_ch - 1 ].next = t;
 
-  /* Return the total number of channels and tiles */
-  *numchannels = nch;
-  *numtiles    = nch * ntiles_in_ch;
+      /* Fill in the information for all the tiles in this channel. */
+      gal_tile_all_position(&ch[i], tile_size, remainderfrac, &t, 1);
+    }
 }



reply via email to

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