gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 67cc39d 107/125: Structure to keep tessellatio


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 67cc39d 107/125: Structure to keep tessellation information
Date: Sun, 23 Apr 2017 22:36:49 -0400 (EDT)

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

    Structure to keep tessellation information
    
    The Convolve program was the first to benefit from the new tessellation
    infra-structure of `lib/tile.c'. However, it was arguably the easiest
    application: it did not need to manage a single value for each tile and
    interpolation for example. However, now that the tile structure is being
    implemented in Statistics, we have a single value for each tile. Given the
    possiblity of multiple channels, the tile IDs and 2/3D positions don't
    simply correspond to each other and many pieces of information about the
    tessellation are necessary to deduce the proper conversion.
    
    So to make things easier, a `gal_tile_two_layer_params' structure was
    defined in `lib/gnuastro/tile.h' keeping all the input and internally
    necessary parameters to avoid having copy around different arrays. Many
    things got much more cleaner now and easier to manage. Allowing us easily
    to convert tile IDs into positions in the dataset and vice-versa which is
    needed for the final interpolation.
    
    `gal_tile_two_layer_params' is now part of `gal_options_common_params' and
    thus available to any program. Thus the main program parameter
    initialization has been corrected in all the programs to also initialize
    this structure's values. Library users can also easily fill it up and call
    `gal_tile_full_two_layers' to generate the two layer tessellation. This
    will be explained in the manual.
    
    Finally, having this structure also allowed the creation of
    `gal_tile_full_free_contents' to easily free all the allocated space for
    the tessellation.
---
 bin/TEMPLATE/main.c         |   2 +-
 bin/arithmetic/main.c       |   2 +-
 bin/convertt/main.c         |   2 +-
 bin/convolve/convolve.c     |  25 ++--
 bin/convolve/main.c         |   2 +-
 bin/convolve/ui.c           |  43 +++----
 bin/cosmiccal/main.c        |   2 +-
 bin/crop/main.c             |   2 +-
 bin/fits/main.c             |   2 +-
 bin/mkcatalog/main.c        |   2 +-
 bin/mknoise/main.c          |   2 +-
 bin/mkprof/main.c           |   2 +-
 bin/noisechisel/main.c      |   2 +-
 bin/statistics/main.c       |   2 +-
 bin/statistics/statistics.c |  41 +++----
 bin/statistics/ui.c         |  14 +--
 bin/subtractsky/main.c      |   2 +-
 bin/table/main.c            |   2 +-
 bin/warp/main.c             |   2 +-
 lib/commonopts.h            |  10 +-
 lib/fits.c                  |   3 +-
 lib/gnuastro/tile.h         |  46 +++++--
 lib/options.h               |  14 +--
 lib/tile.c                  | 293 ++++++++++++++++++++++++--------------------
 24 files changed, 274 insertions(+), 245 deletions(-)

diff --git a/bin/TEMPLATE/main.c b/bin/TEMPLATE/main.c
index 3561a65..ec466f7 100644
--- a/bin/TEMPLATE/main.c
+++ b/bin/TEMPLATE/main.c
@@ -45,7 +45,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 main (int argc, char *argv[])
 {
-  struct TEMPLATEparams p={{0}, {0}, 0};
+  struct TEMPLATEparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/arithmetic/main.c b/bin/arithmetic/main.c
index 3f1b1f5..b0eea01 100644
--- a/bin/arithmetic/main.c
+++ b/bin/arithmetic/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct imgarithparams p={{0}, 0};
+  struct imgarithparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/convertt/main.c b/bin/convertt/main.c
index 73489e1..443680b 100644
--- a/bin/convertt/main.c
+++ b/bin/convertt/main.c
@@ -35,7 +35,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 main(int argc, char *argv[])
 {
-  struct converttparams p={{0}, 0};
+  struct converttparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index 8195342..63333d3 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -759,9 +759,7 @@ convolve_frequency(struct convolveparams *p)
 void
 convolve(struct convolveparams *p)
 {
-  size_t *tsize;
   gal_data_t *out, *check;
-  gal_data_t *tiles, *channels;
   struct gal_options_common_params *cp=&p->cp;
 
 
@@ -769,15 +767,13 @@ convolve(struct convolveparams *p)
   if(p->domain==CONVOLVE_DOMAIN_SPATIAL)
     {
       /* Prepare the mesh structure. */
-      tsize=gal_tile_all_position_two_layers(p->input, cp->channelsize,
-                                             cp->tilesize, cp->remainderfrac,
-                                             &channels, &tiles);
+      gal_tile_full_two_layers(p->input, &cp->tl);
 
       /* Save the tile IDs if they are requested. */
-      if(cp->tilecheckname)
+      if(cp->tl.tilecheckname)
         {
-          check=gal_tile_block_check_tiles(tiles);
-          gal_fits_img_write(check, cp->tilecheckname, NULL, PROGRAM_NAME);
+          check=gal_tile_block_check_tiles(cp->tl.tiles);
+          gal_fits_img_write(check, cp->tl.tilecheckname, NULL, PROGRAM_NAME);
           gal_data_free(check);
         }
 
@@ -785,16 +781,13 @@ convolve(struct convolveparams *p)
          want to do spatial domain convolution with this Convolve program
          is edge correction. So by default we assume it and will only
          ignore it if the user asks.*/
-      out=gal_convolve_spatial(tiles, p->kernel, cp->numthreads,
-                               !p->noedgecorrection, cp->workoverch);
+      out=gal_convolve_spatial(cp->tl.tiles, p->kernel, cp->numthreads,
+                               !p->noedgecorrection, cp->tl.workoverch);
 
-      /* Clean up */
-      free(tsize);
+      /* Clean up: free the actual input and replace it's pointer with the
+         convolved dataset to save as output. */
+      gal_tile_full_free_contents(&cp->tl);
       gal_data_free(p->input);
-      gal_data_array_free(tiles, gal_data_num_in_ll(tiles), 0);
-      gal_data_array_free(channels, gal_data_num_in_ll(channels), 0);
-
-      /* Put the convolved dataset into the `input' to save as output. */
       p->input=out;
     }
   else
diff --git a/bin/convolve/main.c b/bin/convolve/main.c
index a4483d6..bdf018b 100644
--- a/bin/convolve/main.c
+++ b/bin/convolve/main.c
@@ -36,7 +36,7 @@ int
 main(int argc, char *argv[])
 {
   struct timeval t1;
-  struct convolveparams p={{0}, 0};
+  struct convolveparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/bin/convolve/ui.c b/bin/convolve/ui.c
index 2963ac6..4b1225d 100644
--- a/bin/convolve/ui.c
+++ b/bin/convolve/ui.c
@@ -235,16 +235,16 @@ ui_read_check_only_options(struct convolveparams *p)
   /* If we are in the spatial domain, make sure that the necessary
      parameters are set. */
   if( p->domain==CONVOLVE_DOMAIN_SPATIAL )
-    if( cp->tilesize==NULL || cp->numchannels==NULL )
+    if( cp->tl.tilesize==NULL || cp->tl.numchannels==NULL )
       {
-        if( cp->tilesize==NULL && cp->numchannels==NULL )
+        if( cp->tl.tilesize==NULL && cp->tl.numchannels==NULL )
           error(EXIT_FAILURE, 0, "in spatial convolution, `--numchannels' "
                 "and `--tilesize' are mandatory");
         else
           error(EXIT_FAILURE, 0, "in spatial convolution, `--%s' is "
                 "mandatory: you should use it to set the %s",
-                cp->tilesize ? "numchannels" : "tilesize",
-                ( cp->tilesize
+                cp->tl.tilesize ? "numchannels" : "tilesize",
+                ( cp->tl.tilesize
                   ? "number of channels along each dimension of the input"
                   : "size of tiles to cover the input along each "
                   "dimension" ) );
@@ -321,29 +321,28 @@ ui_preparations(struct convolveparams *p)
   char *outsuffix = p->makekernel ? "_kernel.fits" : "_convolved.fits";
 
   /* Set the output name if the user hasn't set it. */
-  if(p->cp.output==NULL)
-    p->cp.output=gal_checkset_automatic_output(&p->cp, p->filename,
-                                               outsuffix);
-  gal_checkset_check_remove_file(p->cp.output, 0, p->cp.dontdelete);
+  if(cp->output==NULL)
+    cp->output=gal_checkset_automatic_output(cp, p->filename, outsuffix);
+  gal_checkset_check_remove_file(cp->output, 0, cp->dontdelete);
   if(p->checkfreqsteps)
     {
-      p->freqstepsname=gal_checkset_automatic_output(&p->cp, p->filename,
+      p->freqstepsname=gal_checkset_automatic_output(cp, p->filename,
                                                      "_freqsteps.fits");
-      gal_checkset_check_remove_file(p->freqstepsname, 0, p->cp.dontdelete);
+      gal_checkset_check_remove_file(p->freqstepsname, 0, cp->dontdelete);
     }
-  if(cp->checktiles)
+  if(cp->tl.checktiles)
     {
-      p->cp.tilecheckname=gal_checkset_automatic_output(&p->cp, p->filename,
-                                                        "_tiled.fits");
-      gal_checkset_check_remove_file(p->cp.tilecheckname, 0,
-                                     p->cp.dontdelete);
+      cp->tl.tilecheckname=gal_checkset_automatic_output(cp, p->filename,
+                                                         "_tiled.fits");
+      gal_checkset_check_remove_file(cp->tl.tilecheckname, 0,
+                                     cp->dontdelete);
     }
 
 
   /* Read the input image as a float64 array and its WCS info. */
-  p->input=gal_fits_img_read_to_type(p->filename, p->cp.hdu,
-                                     GAL_DATA_TYPE_FLOAT32, p->cp.minmapsize);
-  gal_wcs_read(p->filename, p->cp.hdu, 0, 0, &p->input->nwcs, &p->input->wcs);
+  p->input=gal_fits_img_read_to_type(p->filename, cp->hdu,
+                                     GAL_DATA_TYPE_FLOAT32, cp->minmapsize);
+  gal_wcs_read(p->filename, cp->hdu, 0, 0, &p->input->nwcs, &p->input->wcs);
 
 
   /* See if there are any blank values. */
@@ -359,13 +358,11 @@ ui_preparations(struct convolveparams *p)
                 "in the input data. You can run %s again with "
                 "`--domain=spatial'\n"
                 "----------------------------------------\n\n",
-                PROGRAM_NAME, p->filename, p->cp.hdu, p->cp.output,
+                PROGRAM_NAME, p->filename, cp->hdu, cp->output,
                 PROGRAM_NAME);
     }
   else
-    cp->channelsize=gal_tile_all_sanity_check(p->filename, p->cp.hdu,
-                                              p->input, cp->tilesize,
-                                              cp->numchannels);
+    gal_tile_full_sanity_check(p->filename, cp->hdu, p->input, &cp->tl);
 
 
 
@@ -445,7 +442,7 @@ ui_preparations(struct convolveparams *p)
         }
       else
         p->kernel = gal_fits_img_read_kernel(p->kernelname, p->khdu,
-                                             p->cp.minmapsize);
+                                             cp->minmapsize);
     }
 }
 
diff --git a/bin/cosmiccal/main.c b/bin/cosmiccal/main.c
index cd99936..d4906ad 100644
--- a/bin/cosmiccal/main.c
+++ b/bin/cosmiccal/main.c
@@ -35,7 +35,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 main (int argc, char *argv[])
 {
-  struct cosmiccalparams p={{0}, 0};
+  struct cosmiccalparams p={{{0},0},0};
 
   /* Get the starting time. */
   time(&p.rawtime);
diff --git a/bin/crop/main.c b/bin/crop/main.c
index 7837864..bf2a589 100644
--- a/bin/crop/main.c
+++ b/bin/crop/main.c
@@ -37,7 +37,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct cropparams p={{0}, 0};
+  struct cropparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/bin/fits/main.c b/bin/fits/main.c
index a944b64..4f3eefb 100644
--- a/bin/fits/main.c
+++ b/bin/fits/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   int r;
-  struct fitsparams p={{0}, 0};
+  struct fitsparams p={{{0},0},0};
 
   /* Get the starting time. */
   time(&p.rawtime);
diff --git a/bin/mkcatalog/main.c b/bin/mkcatalog/main.c
index 345dda9..6524da9 100644
--- a/bin/mkcatalog/main.c
+++ b/bin/mkcatalog/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct mkcatalogparams p={{0}, {0}, 0};
+  struct mkcatalogparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/mknoise/main.c b/bin/mknoise/main.c
index a8132f7..12e9c73 100644
--- a/bin/mknoise/main.c
+++ b/bin/mknoise/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct mknoiseparams p={{0}, 0};
+  struct mknoiseparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/bin/mkprof/main.c b/bin/mkprof/main.c
index 58a2fd2..e47f538 100644
--- a/bin/mkprof/main.c
+++ b/bin/mkprof/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct mkprofparams p={{0}, 0};
+  struct mkprofparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/bin/noisechisel/main.c b/bin/noisechisel/main.c
index 9ce5bf5..d385593 100644
--- a/bin/noisechisel/main.c
+++ b/bin/noisechisel/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct noisechiselparams p={{0}, {0}, {0}, {0}, 0};
+  struct noisechiselparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/statistics/main.c b/bin/statistics/main.c
index 93ce912..eb3df66 100644
--- a/bin/statistics/main.c
+++ b/bin/statistics/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct statisticsparams p={{0}, 0};
+  struct statisticsparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/statistics/statistics.c b/bin/statistics/statistics.c
index c882f61..f5743c6 100644
--- a/bin/statistics/statistics.c
+++ b/bin/statistics/statistics.c
@@ -235,33 +235,31 @@ statistics_on_tile(struct statisticsparams *p)
 {
   double arg;
   uint8_t type;
+  size_t tind, dsize=1, mind;
   gal_data_t *tmp, *tmpv, *ttmp;
+  gal_data_t *check, *tile, *values;
   struct gal_linkedlist_ill *operation;
-  size_t ntiles, *tsize, tind, dsize=1, mind;
-  gal_data_t *channels, *tiles, *check, *tile, *values;
+  struct gal_options_common_params *cp=&p->cp;
+  struct gal_tile_two_layer_params *tl=&p->cp.tl;
 
   /* Set the output name. */
-  if(p->cp.output==NULL)
-    p->cp.output=gal_checkset_automatic_output(&p->cp, p->inputname,
-                                               "_ontile.fits");
+  if(cp->output==NULL)
+    cp->output=gal_checkset_automatic_output(cp, p->inputname,
+                                             "_ontile.fits");
 
   /* Make the tile structure. */
-  tsize=gal_tile_all_position_two_layers(p->input, p->cp.channelsize,
-                                         p->cp.tilesize, p->cp.remainderfrac,
-                                         &channels, &tiles);
+  gal_tile_full_two_layers(p->input, tl);
 
-  /* Number of tiles. */
-  ntiles=gal_multidim_total_size(p->input->ndim, tsize);
 
   /* Save the tile IDs if they are requested. */
-  if(p->cp.tilecheckname)
+  if(tl->tilecheckname)
     {
-      check=gal_tile_block_check_tiles(tiles);
+      check=gal_tile_block_check_tiles(tl->tiles);
       if(p->inputformat==INPUT_FORMAT_IMAGE)
-        gal_fits_img_write(check, p->cp.tilecheckname, NULL, PROGRAM_NAME);
+        gal_fits_img_write(check, tl->tilecheckname, NULL, PROGRAM_NAME);
       else
-        gal_table_write(check, NULL, p->cp.tableformat, p->cp.tilecheckname,
-                        p->cp.dontdelete);
+        gal_table_write(check, NULL, cp->tableformat, tl->tilecheckname,
+                        cp->dontdelete);
       gal_data_free(check);
     }
 
@@ -296,8 +294,8 @@ statistics_on_tile(struct statisticsparams *p)
         }
 
       /* Allocate the space necessary to keep the value for each tile. */
-      values=gal_data_alloc(NULL, type, p->input->ndim, tsize, NULL, 0,
-                            p->input->minmapsize, NULL, NULL, NULL);
+      values=gal_data_alloc(NULL, type, p->input->ndim, tl->numtiles, NULL,
+                            0, p->input->minmapsize, NULL, NULL, NULL);
 
       /* Read the argument for those operations that need it. This is done
          here, because below, the functions are repeated on each tile. */
@@ -316,7 +314,7 @@ statistics_on_tile(struct statisticsparams *p)
 
       /* Do the operation on each tile. */
       tind=0;
-      for(tile=tiles; tile!=NULL; tile=tile->next)
+      for(tile=tl->tiles; tile!=NULL; tile=tile->next)
         {
           /* Do the proper operation. */
           switch(operation->v)
@@ -381,18 +379,15 @@ statistics_on_tile(struct statisticsparams *p)
         }
 
       /* Save the values. */
-      gal_fits_img_write(values, p->cp.output, NULL, PROGRAM_STRING);
+      gal_fits_img_write(values, cp->output, NULL, PROGRAM_STRING);
       gal_data_free(values);
 
       /* Clean up. */
       if(operation->v==ARGS_OPTION_KEY_QUANTFUNC) gal_data_free(tmpv);
     }
 
-
   /* Clean up. */
-  free(tsize);
-  gal_data_array_free(tiles, ntiles, 0);
-  gal_data_array_free(channels, gal_data_num_in_ll(channels), 0);
+  gal_tile_full_free_contents(tl);
 }
 
 
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index 208d337..56f7199 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -821,17 +821,15 @@ ui_preparations(struct statisticsparams *p)
   if(p->ontile)
     {
       /* Check the tiles. */
-      cp->channelsize=gal_tile_all_sanity_check(p->inputname, p->cp.hdu,
-                                                p->input, cp->tilesize,
-                                                cp->numchannels);
+      gal_tile_full_sanity_check(p->inputname, p->cp.hdu, p->input, &cp->tl);
 
       /* Set the tile file name if the user wants to check the tiles. */
-      if(cp->checktiles)
+      if(cp->tl.checktiles)
         {
-          cp->tilecheckname=gal_checkset_automatic_output(&p->cp,
-                                                          p->inputname,
-                                                          "_tiled.fits");
-          gal_checkset_check_remove_file(cp->tilecheckname, 0,
+          cp->tl.tilecheckname=gal_checkset_automatic_output(&p->cp,
+                                                             p->inputname,
+                                                             "_tiled.fits");
+          gal_checkset_check_remove_file(cp->tl.tilecheckname, 0,
                                          cp->dontdelete);
         }
     }
diff --git a/bin/subtractsky/main.c b/bin/subtractsky/main.c
index f405c7c..7a9729f 100644
--- a/bin/subtractsky/main.c
+++ b/bin/subtractsky/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct subtractskyparams p={{0}, {0}, {0}, 0};
+  struct subtractskyparams p={{{0},0},0};
 
   /* Set the starting time. */
   time(&p.rawtime);
diff --git a/bin/table/main.c b/bin/table/main.c
index 663c8ce..d896bbb 100644
--- a/bin/table/main.c
+++ b/bin/table/main.c
@@ -37,7 +37,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 int
 main (int argc, char *argv[])
 {
-  struct tableparams p={{0}, 0};
+  struct tableparams p={{{0},0},0};
 
   /* Set they starting time. */
   time(&p.rawtime);
diff --git a/bin/warp/main.c b/bin/warp/main.c
index bb1799d..c999657 100644
--- a/bin/warp/main.c
+++ b/bin/warp/main.c
@@ -36,7 +36,7 @@ int
 main (int argc, char *argv[])
 {
   struct timeval t1;
-  struct warpparams p={{0}, 0};
+  struct warpparams p={{{0},0},0};
 
   /* Set the starting time.*/
   time(&p.rawtime);
diff --git a/lib/commonopts.h b/lib/commonopts.h
index 59ea715..873ed2c 100644
--- a/lib/commonopts.h
+++ b/lib/commonopts.h
@@ -99,7 +99,7 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Regular tile size on each dim. (FITS order).",
       GAL_OPTIONS_GROUP_TESSELLATION,
-      &cp->tilesize,
+      &cp->tl.tilesize,
       GAL_DATA_TYPE_SIZE_T,
       GAL_OPTIONS_RANGE_GT_0,
       GAL_OPTIONS_NOT_MANDATORY,
@@ -113,7 +113,7 @@ struct argp_option gal_commonopts_options[] =
       0,
       "No. of channels along each dim. (FITS order).",
       GAL_OPTIONS_GROUP_TESSELLATION,
-      &cp->numchannels,
+      &cp->tl.numchannels,
       GAL_DATA_TYPE_STRING,
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
@@ -127,7 +127,7 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Fraction of remainder to split last tile.",
       GAL_OPTIONS_GROUP_TESSELLATION,
-      &cp->remainderfrac,
+      &cp->tl.remainderfrac,
       GAL_DATA_TYPE_FLOAT32,
       GAL_OPTIONS_RANGE_GT_0_LT_1,
       GAL_OPTIONS_NOT_MANDATORY,
@@ -140,7 +140,7 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Work (not tile) over channel edges.",
       GAL_OPTIONS_GROUP_TESSELLATION,
-      &cp->workoverch,
+      &cp->tl.workoverch,
       GAL_OPTIONS_NO_ARG_TYPE,
       GAL_OPTIONS_RANGE_0_OR_1,
       GAL_OPTIONS_NOT_MANDATORY,
@@ -153,7 +153,7 @@ struct argp_option gal_commonopts_options[] =
       0,
       "Tile IDs in an image, the size of input.",
       GAL_OPTIONS_GROUP_TESSELLATION,
-      &cp->checktiles,
+      &cp->tl.checktiles,
       GAL_OPTIONS_NO_ARG_TYPE,
       GAL_OPTIONS_RANGE_0_OR_1,
       GAL_OPTIONS_NOT_MANDATORY,
diff --git a/lib/fits.c b/lib/fits.c
index 2f7aa5a..b1ccb59 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -557,7 +557,8 @@ gal_fits_hdu_open(char *filename, char *hdu, int iomode)
   if( fits_open_file(&fptr, ffname, iomode, &status) )
     gal_fits_io_error(status, "reading this FITS file");
 
-  /* Return the pointer. */
+  /* Clean up and the pointer. */
+  free(ffname);
   return fptr;
 }
 
diff --git a/lib/gnuastro/tile.h b/lib/gnuastro/tile.h
index 3f5e478..f60fe15 100644
--- a/lib/gnuastro/tile.h
+++ b/lib/gnuastro/tile.h
@@ -61,6 +61,8 @@ gal_tile_start_end_ind_inclusive(gal_data_t *tile, gal_data_t 
*work,
 
 
 
+
+
 /***********************************************************************/
 /**************           Allocated block         **********************/
 /***********************************************************************/
@@ -77,22 +79,48 @@ gal_tile_block_check_tiles(gal_data_t *tiles);
 
 
 
+
 /***********************************************************************/
 /**************           Tile full dataset         ********************/
 /***********************************************************************/
-size_t *
-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,
-                      float remainderfrac, gal_data_t **out, size_t multiple);
+struct gal_tile_two_layer_params
+{
+  /* Inputs */
+  size_t             *tilesize; /* Tile size along each dim. (C order).   */
+  size_t          *numchannels; /* Channel no. along each dim. (C order). */
+  float          remainderfrac; /* Frac. of remainers in each dim to cut. */
+  uint8_t           workoverch; /* Convolve over channel borders.         */
+  uint8_t           checktiles; /* Tile IDs in an img, the size of input. */
+
+  /* Internal parameters. */
+  size_t              tottiles; /* Total number of tiles in all dim.      */
+  size_t          tottilesinch; /* Number of tiles in one channel.        */
+  size_t           totchannels; /* Total number of channels in all dim.   */
+  size_t          *channelsize; /* Size of channels along each dimension. */
+  size_t             *numtiles; /* Tile no. in each dim. over-all.        */
+  size_t         *numtilesinch; /* Tile no. in each dim. on one channel.  */
+  char          *tilecheckname; /* Name of file to check tiles.           */
+
+  /* Actual tile and channel data structures. */
+  gal_data_t            *tiles; /* Tiles array (also linked with `next'). */
+  gal_data_t         *channels; /* Channels array (linked with `next').   */
+};
 
 size_t *
-gal_tile_all_position_two_layers(gal_data_t *input, size_t *channel_size,
-                                 size_t *tile_size, float remainderfrac,
-                                 gal_data_t **channels, gal_data_t **tiles);
+gal_tile_full(gal_data_t *input, size_t *regular,
+              float remainderfrac, gal_data_t **out, size_t multiple);
+
+void
+gal_tile_full_sanity_check(char *filename, char *hdu, gal_data_t *input,
+                           struct gal_tile_two_layer_params *tl);
 
+void
+gal_tile_full_two_layers(gal_data_t *input,
+                         struct gal_tile_two_layer_params *tl);
+
+void
+gal_tile_full_free_contents(struct gal_tile_two_layer_params *tl);
 
 
 
diff --git a/lib/options.h b/lib/options.h
index 86ddb11..fe76904 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -25,7 +25,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <argp.h>
 
 #include <gnuastro/data.h>
-
+#include <gnuastro/tile.h>
 
 
 
@@ -158,18 +158,14 @@ enum gal_options_set_values
    programs. */
 struct gal_options_common_params
 {
+  /* Tessellation. */
+  struct gal_tile_two_layer_params tl; /* Two layer tessellation params.  */
+
   /* Input. */
   char                    *hdu; /* Image extension.                       */
   uint8_t             searchin; /* Column meta-data to match/search.      */
   uint8_t           ignorecase; /* Ignore case when matching col info.    */
 
-  /* Tessellation. */
-  size_t             *tilesize; /* Tile size along each dim. (C order).   */
-  size_t          *numchannels; /* Channel no. along each dim. (C order). */
-  float          remainderfrac; /* Frac. of remainers in each dim to cut. */
-  uint8_t           workoverch; /* Convolve over channel borders.         */
-  uint8_t           checktiles; /* Tile IDs in an img, the size of input. */
-
   /* Output. */
   char                 *output; /* Directory containg output.             */
   uint8_t                 type; /* Data type of output.                   */
@@ -191,8 +187,6 @@ struct gal_options_common_params
 
   /* For internal (to option processing) purposes. */
   uint8_t                 keep; /* Output file can exist.                 */
-  size_t          *channelsize; /* Size of channels along each dimension. */
-  char          *tilecheckname; /* Name of file to check tiles.           */
   void         *program_struct; /* Host program's main variable struct.   */
   char           *program_name; /* Official name to be used in text.      */
   char           *program_exec; /* Program's executable name.             */
diff --git a/lib/tile.c b/lib/tile.c
index 2981f0a..789e19f 100644
--- a/lib/tile.c
+++ b/lib/tile.c
@@ -79,9 +79,8 @@ gal_tile_start_coord(gal_data_t *tile, size_t *start_coord)
 
    `rel_block' (or relative-to-block) is only relevant when the tile has an
    intermediate tile between it and the allocated space (like a channel,
-   see `gal_tile_all_position_two_layers'). If it doesn't (`tile->block'
-   points the allocated dataset), then the value to `rel_block' is
-   irrelevant.
+   see `gal_tile_full_two_layers'). If it doesn't (`tile->block' points the
+   allocated dataset), then the value to `rel_block' is irrelevant.
 
    However, when `tile->block' is its self a larger block and `rel_block'
    is set to 0, then the starting and ending positions will be based on the
@@ -406,90 +405,6 @@ gal_tile_block_check_tiles(gal_data_t *tiles)
 /***********************************************************************/
 /**************           Tile full dataset         ********************/
 /***********************************************************************/
-/* This option is mainly used by Gnuastro's programs to see if the user's
-   given values for the tile size (`tile') and number of channels
-   (`channels') corresponds to the input dataset. */
-size_t *
-gal_tile_all_sanity_check(char *filename, char *hdu, gal_data_t *input,
-                          size_t *tile, size_t *numchannels)
-{
-  double d;
-  size_t i, *out;
-
-  /* Check the tile's dimensions. */
-  for(i=0;tile[i]!=-1;++i)
-    {
-      /* Not equal to zero. */
-      if(tile[i]==0)
-        error(EXIT_FAILURE, 0, "the tile size must be larger than zero");
-
-      /* If the tile size is larger than the dataset size in this
-         dimension, then change the tile size to the dataset size. */
-      if(tile[i]>input->dsize[i]) tile[i]=input->dsize[i];
-    }
-
-
-  /* Make sure the number of tile sizes (tile dimensions) are the same as
-     the dataset's dimensions). */
-  if(i!=input->ndim)
-    error(EXIT_FAILURE, 0, "%s (hdu: %s): has %zu dimensions, but only %zu "
-          "value(s) given for the tile size (`--tilesize' option).",
-          filename, hdu, input->ndim, i);
-
-
-  /* Check the channel's dimensions. */
-  for(i=0;numchannels[i]!=-1;++i)
-    if(tile[i]==0)
-      error(EXIT_FAILURE, 0, "the number of channels must be larger than "
-            "zero");
-  if(i!=input->ndim)
-    error(EXIT_FAILURE, 0, "%s (hdu: %s): has %zu dimensions, but only %zu "
-          "value(s) given for the number of channels", filename, hdu,
-          input->ndim, i);
-
-
-  /* Allocate space for the channel sizes. */
-  out=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
-
-
-  /* Check if the channels are exactly divisible by the input's size along
-     each dimension and set the correct size. */
-  for(i=0;i<input->ndim;++i)
-    {
-      /* Check if the number of channels is not more than the size of the
-         image. Note that the reported dimension must be in FITS format.*/
-      if(input->dsize[i]<numchannels[i])
-        error(EXIT_FAILURE, 0, "the number of channels in dimension %zu "
-              "(%zu) is more than the size of the `%s' (hdu: %s) in that "
-              "dimension", input->ndim-i, numchannels[i], filename, hdu);
-
-      /* Also check the tile size. */
-      if(input->dsize[i]<tile[i])
-        error(EXIT_FAILURE, 0, "the tile size in dimension %zu (%zu) is "
-              "more than the size of the `%s' (hdu: %su) in that dimension",
-              input->ndim-i, tile[i], filename, hdu);
-
-      /* First check. */
-      d=(double)input->dsize[i]/(double)numchannels[i];
-      if(ceil(d)!=d)
-        error(EXIT_FAILURE, 0, "%zu (number of channels along dimension "
-              "%zu) is not exactly divisible by %zu (the length of `%s' "
-              "(hdu: %s) that dimension). The channels cover the input "
-              "dataset, hence, they must be identical", numchannels[i],
-              input->ndim-i, input->dsize[i], filename, hdu);
-
-      /* Put the channel size into the output. */
-      out[i]=d;
-    }
-
-  /* Return the output array (size of channel along each dimension). */
-  return out;
-}
-
-
-
-
-
 /* The user's specified tile size might not be an exact multiple of the
    parent's size. This function is useful in such cases. It will give the
    starting tile's size along each dimension. The line below can be the
@@ -525,9 +440,9 @@ gal_tile_all_sanity_check(char *filename, char *hdu, 
gal_data_t *input,
    parse all the tiles. We just have to make sure we don't go over the full
    input's length. */
 static void
-gal_tile_all_regular_first(gal_data_t *parent, size_t *regular,
-                           float significance, size_t *first, size_t *last,
-                           size_t *tsize)
+gal_tile_full_regular_first(gal_data_t *parent, size_t *regular,
+                            float significance, size_t *first, size_t *last,
+                            size_t *tsize)
 {
   size_t i, remainder, *dsize=parent->dsize;;
 
@@ -584,7 +499,7 @@ gal_tile_all_regular_first(gal_data_t *parent, size_t 
*regular,
 
      `remainderfrac' is the significant fraction of the remainder space if
         the width of the input isn't an exact multiple of the tile size
-        along a dimension, see `gal_tile_all_regular_first'.
+        along a dimension, see `gal_tile_full_regular_first'.
 
      `out' is the pointer to the array of data structures that is to keep
         the tile parameters. If `*out==NULL', then the necessary space will
@@ -596,8 +511,7 @@ gal_tile_all_regular_first(gal_data_t *parent, size_t 
*regular,
         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 `gal_tile_all_position_channel_tile'
-        below.
+        allocated space).  See the `gal_tile_full_two_layers' below.
 
    Output
    ------
@@ -621,8 +535,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,
-                      float remainderfrac, gal_data_t **out, size_t multiple)
+gal_tile_full(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);
@@ -635,7 +549,7 @@ gal_tile_all_position(gal_data_t *input, size_t *regular,
 
   /* 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, remainderfrac,
+  gal_tile_full_regular_first(input, regular, remainderfrac,
                              first, last, tsize);
   numtiles=gal_multidim_total_size(input->ndim, tsize);
 
@@ -668,7 +582,7 @@ gal_tile_all_position(gal_data_t *input, size_t *regular,
       for(d=0;d<input->ndim;++d)
         {
           /* Convert the tile coordinates to pixel coordinates within
-             `input'. See the comments above `gal_tile_all_regular_first':
+             `input'. See the comments above `gal_tile_full_regular_first':
              The first tile in every dimension can be different from the
              regular tile size. */
           coord[d] = tcoord[d] ? first[d] + (tcoord[d]-1)*regular[d] : 0;
@@ -693,6 +607,7 @@ gal_tile_all_position(gal_data_t *input, size_t *regular,
       /* Set the sizes of the tile. */
       tiles[i].size=1;
       tiles[i].ndim=input->ndim;
+      tiles[i].minmapsize=input->minmapsize;
       tiles[i].dsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T,input->ndim);
       for(d=0;d<input->ndim;++d)
         {
@@ -740,6 +655,91 @@ gal_tile_all_position(gal_data_t *input, size_t *regular,
 
 
 
+/* Make sure that the input parameters (in `tl', short for two-layer) fit
+   with the input dataset. The filename and HDU are only required for error
+   messages. Also, allocate and fill the `channelsize' array. */
+void
+gal_tile_full_sanity_check(char *filename, char *hdu, gal_data_t *input,
+                           struct gal_tile_two_layer_params *tl)
+{
+  double d;
+  size_t i, ndim=input->ndim;
+
+  /* Check the tile's dimensions. */
+  for(i=0;tl->tilesize[i]!=-1;++i)
+    {
+      /* Not equal to zero. */
+      if(tl->tilesize[i]==0)
+        error(EXIT_FAILURE, 0, "`--tilesize' must be larger than zero, "
+              "the given value for dimension %zu was zero", ndim-i);
+
+      /* If the tile size is larger than the dataset size in this
+         dimension, then quietly change the tile size to the dataset size
+         along that dimension. */
+      if( tl->tilesize[i] > input->dsize[i] )
+        tl->tilesize[i] = input->dsize[i];
+    }
+
+
+  /* Make sure the number of tile sizes (tile dimensions) are the same as
+     the dataset's dimensions). */
+  if(i!=ndim)
+    error(EXIT_FAILURE, 0, "%s (hdu: %s): has %zu dimensions, but only %zu "
+          "value(s) given for the tile size (`--tilesize' option).",
+          filename, hdu, ndim, i);
+
+
+  /* Check the channel's dimensions. */
+  for(i=0; tl->numchannels[i]!=-1; ++i)
+    if(tl->numchannels[i]==0)
+      error(EXIT_FAILURE, 0, "the number of channels in all dimensions must "
+            "be larger than zero. The number for dimension %zu was zero",
+            ndim);
+  if(i!=ndim)
+    error(EXIT_FAILURE, 0, "%s (hdu: %s): has %zu dimensions, but only %zu "
+          "value(s) given for the number of channels", filename, hdu, ndim,
+          i);
+
+
+  /* Allocate space for the channel sizes. */
+  tl->channelsize=gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, ndim);
+
+
+  /* Check if the channels are exactly divisible by the input's size along
+     each dimension and set the correct size. */
+  for(i=0;i<ndim;++i)
+    {
+      /* Check if the number of channels is not more than the size of the
+         image. Note that the reported dimension must be in FITS format.*/
+      if( input->dsize[i] < tl->numchannels[i] )
+        error(EXIT_FAILURE, 0, "the number of channels in dimension %zu "
+              "(%zu) is more than the size of the `%s' (hdu: %s) in that "
+              "dimension", ndim-i, tl->numchannels[i], filename, hdu);
+
+      /* Also check the tile size. */
+      if( input->dsize[i] < tl->tilesize[i] )
+        error(EXIT_FAILURE, 0, "the tile size in dimension %zu (%zu) is "
+              "more than the size of the `%s' (hdu: %su) in that dimension",
+              ndim-i, tl->tilesize[i], filename, hdu);
+
+      /* First check. */
+      d=(double)input->dsize[i]/(double)(tl->numchannels[i]);
+      if(ceil(d)!=d)
+        error(EXIT_FAILURE, 0, "%zu (number of channels along dimension "
+              "%zu) is not exactly divisible by %zu (the length of `%s' "
+              "(hdu: %s) that dimension). The channels cover the input "
+              "dataset, hence, they must be identical", tl->numchannels[i],
+              ndim-i, input->dsize[i], filename, hdu);
+
+      /* Put the channel size into the output. */
+      tl->channelsize[i]=d;
+    }
+}
+
+
+
+
+
 /* A dataset can be tiled with two layers that are related:
 
       Channels: A tesselation of larger tile sizes that all have the same
@@ -751,57 +751,80 @@ gal_tile_all_position(gal_data_t *input, size_t *regular,
 
       Tiles: A combined tesselation of each channel with smaller
            tiles. These tiles can be used to calculate things like
-           gradients over each channel and thus over the whole image.  */
-size_t *
-gal_tile_all_position_two_layers(gal_data_t *input, size_t *channel_size,
-                                 size_t *tile_size, float remainderfrac,
-                                 gal_data_t **channels, gal_data_t **tiles)
+           gradients over each channel and thus over the whole image. */
+void
+gal_tile_full_two_layers(gal_data_t *input,
+                         struct gal_tile_two_layer_params *tl)
 {
-  gal_data_t *ch, *t;
-  size_t i, nch=1, ntiles_in_ch;
-  size_t *chsize, *tsize, *ttsize;
-
-  /* First allocate the channels tessellation. */
-  *channels=NULL;
-  chsize=gal_tile_all_position(input, channel_size, remainderfrac,
-                               channels, 1);
-  for(i=0;i<input->ndim;++i) nch *= chsize[i];
-
-
-  /* Now, tile each channel. While tiling the first channel, we are also
-     going to allocate the space for the other channels. Then pass those
-     pointers. */
-  *tiles=NULL;
-  ch=*channels;
-  tsize = gal_tile_all_position(ch, tile_size, remainderfrac,
-                                tiles, nch);
-  ntiles_in_ch=gal_multidim_total_size(input->ndim, tsize);
-  for(i=1;i<nch;++i)
+  gal_data_t *t;
+  size_t i, *junk;
+
+  /* Initialize. Note that `numchannels might have already been
+     allocated. */
+  tl->channels=tl->tiles=NULL;
+  if(tl->numchannels) free(tl->numchannels);
+
+  /* Initialize necessary values and do the channels tessellation. */
+  tl->numchannels = gal_tile_full(input, tl->channelsize, tl->remainderfrac,
+                                &tl->channels, 1);
+  tl->totchannels = gal_multidim_total_size(input->ndim, tl->numchannels);
+
+
+  /* Tile each channel. While tiling the first channel, we are also going
+     to allocate the space for the other channels. Then pass those pointers
+     when we want to fill in each tile of the other channels. */
+  tl->numtilesinch = gal_tile_full(tl->channels, tl->tilesize,
+                                   tl->remainderfrac, &tl->tiles,
+                                   tl->totchannels);
+  tl->tottilesinch = gal_multidim_total_size(input->ndim, tl->numtilesinch);
+  for(i=1; i<tl->totchannels; ++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;
-      (*tiles)[ i * ntiles_in_ch - 1 ].next = t;
-
-      /* Fill in the information for all the tiles in this channel. */
-      ttsize=gal_tile_all_position(&ch[i], tile_size, remainderfrac, &t, 1);
-      free(ttsize);
+         pointer of the previous channel's tiles. Note that `gal_tile_full'
+         set this `next' element to NULL. */
+      t = tl->tiles + i * tl->tottilesinch;
+      tl->tiles[ i * tl->tottilesinch - 1 ].next = t;
+
+      /* Fill in the information for all the tiles in this channel. Note
+         that we already have the returned value, so it isn't important.*/
+      junk=gal_tile_full(&tl->channels[i], tl->tilesize, tl->remainderfrac,
+                         &t, 1);
+      free(junk);
     }
 
   /* Multiply the number of tiles along each dimension OF ONE CHANNEL by
-     the number of channels in each dimension for the output. */
+     the number of channels in each dimension to get the dimensionality of
+     the full tile structure. */
+  tl->numtiles = gal_data_malloc_array(GAL_DATA_TYPE_SIZE_T, input->ndim);
   for(i=0;i<input->ndim;++i)
-    tsize[i] *= chsize[i];
-
-  /* Return the total number of tiles along each dimension. */
-  return tsize;
+    tl->numtiles[i] = tl->numtilesinch[i] * tl->numchannels[i];
+  tl->tottiles = gal_multidim_total_size(input->ndim, tl->numtiles);
 }
 
 
 
 
 
+/* Clean up the allocated spaces in the parameters. */
+void
+gal_tile_full_free_contents(struct gal_tile_two_layer_params *tl)
+{
+  /* Free the simply allocated spaces. */
+  if(tl->tilesize)      free(tl->tilesize);
+  if(tl->numchannels)   free(tl->numchannels);
+  if(tl->channelsize)   free(tl->channelsize);
+  if(tl->numtiles)      free(tl->numtiles);
+  if(tl->numtilesinch)  free(tl->numtilesinch);
+  if(tl->tilecheckname) free(tl->tilecheckname);
+
+  /* Free the arrays of `gal_data_c' for each tile and channel. */
+  if(tl->tiles)    gal_data_array_free(tl->tiles,    tl->tottiles,    0);
+  if(tl->channels) gal_data_array_free(tl->channels, tl->totchannels, 0);
+}
+
+
+
+
 
 
 



reply via email to

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