gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 4d2508f 028/113: Fixed NoiseChisel opening and


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 4d2508f 028/113: Fixed NoiseChisel opening and dilation and merged with master
Date: Fri, 16 Apr 2021 10:33:36 -0400 (EDT)

branch: master
commit 4d2508fb91a23d35d8c5677a8aa79b0ad41e558c
Merge: 6cc3d25 eadb72c
Author: Mohammad Akhlaghi <akhlaghi@gnu.org>
Commit: Mohammad Akhlaghi <akhlaghi@gnu.org>

    Fixed NoiseChisel opening and dilation and merged with master
    
    While merging the recent changes from master into this branch, I noticed
    that NoiseChisel wasn't passing the connectivity values to the opening and
    final dilation operations properly: it was based on 2D, so when the ngb
    value was 4, it would pass a connectivity of 1 and otherwise 2. So in 3D
    (where the ngb is never 4), it would always only pass a connectivity of 2.
---
 NEWS                                   | 17 ++++---
 bin/arithmetic/arithmetic.c            |  2 +-
 bin/convertt/convertt.c                |  2 +-
 bin/convolve/convolve.c                | 14 +++---
 bin/crop/crop.c                        |  4 +-
 bin/crop/onecrop.c                     | 30 +++++++++---
 bin/mknoise/mknoise.c                  |  2 +-
 bin/mkprof/mkprof.c                    |  6 +--
 bin/noisechisel/args.h                 | 13 +++++
 bin/noisechisel/astnoisechisel-3d.conf |  3 +-
 bin/noisechisel/astnoisechisel.conf    |  1 +
 bin/noisechisel/clumps.c               | 12 +++--
 bin/noisechisel/detection.c            | 90 +++++++++++++++++++++-------------
 bin/noisechisel/main.h                 |  1 +
 bin/noisechisel/noisechisel.c          | 12 ++---
 bin/noisechisel/segmentation.c         |  8 +--
 bin/noisechisel/sky.c                  |  6 +--
 bin/noisechisel/threshold.c            | 16 +++---
 bin/noisechisel/ui.c                   | 28 ++++++-----
 bin/noisechisel/ui.h                   |  1 +
 bin/statistics/sky.c                   | 20 ++++----
 bin/statistics/statistics.c            |  6 +--
 bin/warp/warp.c                        |  2 +-
 doc/announce-acknowledge.txt           | 15 ++++++
 doc/gnuastro.texi                      | 72 +++++++++++++++------------
 doc/release-checklist.txt              | 90 ++++++++++++++++++++++++----------
 lib/fits.c                             |  8 ++-
 lib/gnuastro/fits.h                    |  2 +-
 28 files changed, 306 insertions(+), 177 deletions(-)

diff --git a/NEWS b/NEWS
index e8cf3e7..ec9901a 100644
--- a/NEWS
+++ b/NEWS
@@ -4,8 +4,11 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
 ** New features
 
-  `.fit' suffix is now also recognized as a FITS file extension in all
-  programs and libraries.
+  All programs: `.fit' is now a recognized FITS file suffix.
+
+  All programs: ASCII text files (tables) created with CRLF line
+  terminators (for example text files created in MS Windows) are now also
+  readable as input when necessary.
 
   Arithmetic: now has a new `--globalhdu' (`-g') option which can be used
   once for all the input images.
@@ -44,10 +47,12 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
   option, the `--mcol' values of the catalog will be interpretted as total
   brightness (sum of pixel values), not magnitude.
 
+  NoiseChisel: with the new `--dilatengb' option, it is now possible to
+  identify the connectivity of the final dilation.
+
   Library: Functions that read data from an ASCII text file
   (`gal_txt_table_info', `gal_txt_table_read', `gal_txt_image_read') now
-  also operate on files with CRLF line terminators (for example text files
-  created in MS Windows).
+  also operate on files with CRLF line terminators.
 
 ** Removed features
 
@@ -118,7 +123,7 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
   `GAL_TILE_PARSE_OPERATE' (only when `OTHER' is given) can now parse and
   operate on different datasets independent of the size of allocated block
-  of memory (the tile sizes of `IN' and `OTHER' have to be idential, but
+  of memory (the tile sizes of `IN' and `OTHER' have to be identical, but
   not their allocated blocks of memory). Until now, it was necessary for
   the two blocks to have the same size and this is no longer the case.
 
@@ -137,7 +142,7 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
 
   Crashes on 32-bit and big-endian systems (bug #51476).
 
-  Warp's align matrix when second dimention must be reversed (bug #51536).
+  Warp's align matrix when second dimension must be reversed (bug #51536).
 
   Reading BZERO for unsigned 64-bit integers (bug #51555).
 
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index a82e256..622af73 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -377,7 +377,7 @@ reversepolish(struct arithmeticparams *p)
       /* Put a copy of the WCS structure from the reference image, it
          will be freed while freeing d1. */
       d1->wcs=p->refdata.wcs;
-      gal_fits_img_write(d1, p->cp.output, NULL, PROGRAM_STRING);
+      gal_fits_img_write(d1, p->cp.output, NULL, PROGRAM_NAME);
       if(!p->cp.quiet)
         printf(" - Output written to %s\n", p->cp.output);
     }
diff --git a/bin/convertt/convertt.c b/bin/convertt/convertt.c
index 8f057ad..729811a 100644
--- a/bin/convertt/convertt.c
+++ b/bin/convertt/convertt.c
@@ -179,7 +179,7 @@ save_with_gnuastro_lib(struct converttparams *p)
     /* FITS: a FITS file can have many extensions (channels). */
     case OUT_FORMAT_FITS:
       for(channel=p->chll; channel!=NULL; channel=channel->next)
-        gal_fits_img_write(channel, p->cp.output, NULL, PROGRAM_STRING);
+        gal_fits_img_write(channel, p->cp.output, NULL, PROGRAM_NAME);
       break;
 
     /* Plain text: only one channel is acceptable. */
diff --git a/bin/convolve/convolve.c b/bin/convolve/convolve.c
index 323a725..f99fa7f 100644
--- a/bin/convolve/convolve.c
+++ b/bin/convolve/convolve.c
@@ -647,13 +647,13 @@ convolve_frequency(struct convolveparams *p)
       /* Save the padded input image. */
       complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_REAL, &tmp);
       data->array=tmp; data->name="input padded";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       free(tmp); data->name=NULL;
 
       /* Save the padded kernel image. */
       complextoreal(p->pker, p->ps0*p->ps1, COMPLEX_TO_REAL_REAL, &tmp);
       data->array=tmp; data->name="kernel padded";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       free(tmp); data->name=NULL;
     }
 
@@ -671,12 +671,12 @@ convolve_frequency(struct convolveparams *p)
     {
       complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
       data->array=tmp; data->name="input transformed";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       free(tmp); data->name=NULL;
 
       complextoreal(p->pker, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
       data->array=tmp; data->name="kernel transformed";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       free(tmp); data->name=NULL;
     }
 
@@ -698,7 +698,7 @@ convolve_frequency(struct convolveparams *p)
     {
       complextoreal(p->pimg, p->ps0*p->ps1, COMPLEX_TO_REAL_SPEC, &tmp);
       data->array=tmp; data->name=p->makekernel ? "Divided" : "Multiplied";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       free(tmp); data->name=NULL;
     }
 
@@ -714,7 +714,7 @@ convolve_frequency(struct convolveparams *p)
   if(p->checkfreqsteps)
     {
       data->array=p->rpad; data->name="padded output";
-      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(data, p->freqstepsname, NULL, PROGRAM_NAME);
       data->name=NULL; data->array=NULL;
     }
 
@@ -794,6 +794,6 @@ convolve(struct convolveparams *p)
     convolve_frequency(p);
 
   /* Save the output (which is in p->input) array. */
-  gal_fits_img_write_to_type(p->input, cp->output, NULL, PROGRAM_STRING,
+  gal_fits_img_write_to_type(p->input, cp->output, NULL, PROGRAM_NAME,
                              cp->type);
 }
diff --git a/bin/crop/crop.c b/bin/crop/crop.c
index 8173051..2a9b423 100644
--- a/bin/crop/crop.c
+++ b/bin/crop/crop.c
@@ -222,7 +222,7 @@ crop_mode_img(void *inparam)
           crp->centerfilled=onecrop_center_filled(crp);
 
           /* Add the final headers and close output FITS image: */
-          gal_fits_key_write_version(crp->outfits, NULL, PROGRAM_STRING);
+          gal_fits_key_write_version(crp->outfits, NULL, PROGRAM_NAME);
           status=0;
           if( fits_close_file(crp->outfits, &status) )
             gal_fits_io_error(status, "CFITSIO could not close "
@@ -325,7 +325,7 @@ crop_mode_wcs(void *inparam)
           crp->centerfilled=onecrop_center_filled(crp);
 
           /* Write all the dependency versions and close the file. */
-          gal_fits_key_write_version(crp->outfits, NULL, PROGRAM_STRING);
+          gal_fits_key_write_version(crp->outfits, NULL, PROGRAM_NAME);
           status=0;
           if( fits_close_file(crp->outfits, &status) )
             gal_fits_io_error(status, "CFITSIO could not close the "
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index 97ec264..80a2257 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -575,11 +575,11 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
   fitsfile *ofp;
   long naxes[MAXDIM];
   char *outname=crp->name;
-  char cpname[FLEN_KEYWORD];
   int status=0, type=crp->p->type;
+  char **strarr, cpname[FLEN_KEYWORD];
+  gal_data_t *rkey=gal_data_array_calloc(1);
   size_t i, ndim=crp->p->imgs->ndim, totsize;
   char *cp, *cpf, blankrec[80], titlerec[80];
-  char startblank[]="                      / ";
   struct inputimgs *img=&crp->p->imgs[crp->in_ind];
 
 
@@ -595,11 +595,11 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
     for(i=0;i<ndim;++i)
       {
         fpixel_c[i] = 1;
-        lpixel_c[i]=naxes[i]=lpixel_i[i]-fpixel_i[i]+1;
+        lpixel_c[i] = naxes[i] = lpixel_i[i]-fpixel_i[i]+1;
       }
   else
     for(i=0;i<ndim;++i)
-      naxes[i]=crp->lpixel[i]-crp->fpixel[i]+1;
+      naxes[i] = crp->lpixel[i]-crp->fpixel[i]+1;
 
 
   /* Create the FITS file with a blank first extension, then close it, so
@@ -633,6 +633,22 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
   status=0;
 
 
+  /* Read the units of the input dataset and store them in the output. */
+  rkey->next=NULL;
+  rkey->name="BUNIT";
+  rkey->type=GAL_TYPE_STRING;
+  gal_fits_key_read_from_ptr(crp->infits, rkey, 1, 1);
+  if(rkey->status==0)           /* The BUNIT keyword was read. */
+    {
+      strarr=rkey->array;
+      fits_update_key(ofp, TSTRING, "BUNIT", strarr[0], "physical units",
+                      &status);
+      gal_fits_io_error(status, "writing BUNIT");
+    }
+  rkey->name=NULL;              /* `name' wasn't allocated. */
+  gal_data_free(rkey);
+
+
   /* Write the blank value as a FITS keyword if necessary. */
   if( type!=GAL_TYPE_FLOAT32 && type!=GAL_TYPE_FLOAT64 )
     if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
@@ -650,7 +666,7 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
       /* Write the WCS title and common WCS information. */
       if(fits_write_record(ofp, blankrec, &status))
         gal_fits_io_error(status, NULL);
-      sprintf(titlerec, "%sWCS information", startblank);
+      sprintf(titlerec, "%sWCS information", GAL_FITS_KEY_TITLE_START);
       for(i=strlen(titlerec);i<79;++i)
         titlerec[i]=' ';
       fits_write_record(ofp, titlerec, &status);
@@ -670,9 +686,7 @@ onecrop_make_array(struct onecropparams *crp, long 
*fpixel_i,
 
 
   /* Add the Crop information. */
-  if(fits_write_record(ofp, blankrec, &status))
-    gal_fits_io_error(status, NULL);
-  sprintf(titlerec, "%sCrop information", startblank);
+  sprintf(titlerec, "%sCrop information", GAL_FITS_KEY_TITLE_START);
   for(i=strlen(titlerec);i<79;++i)
     titlerec[i]=' ';
   if(fits_write_record(ofp, titlerec, &status))
diff --git a/bin/mknoise/mknoise.c b/bin/mknoise/mknoise.c
index f91c265..82505ae 100644
--- a/bin/mknoise/mknoise.c
+++ b/bin/mknoise/mknoise.c
@@ -97,7 +97,7 @@ convertsaveoutput(struct mknoiseparams *p)
 
   /* Save the output: */
   p->input=gal_data_copy_to_new_type_free(p->input, p->cp.type);
-  gal_fits_img_write(p->input, p->cp.output, headers, PROGRAM_STRING);
+  gal_fits_img_write(p->input, p->cp.output, headers, PROGRAM_NAME);
 }
 
 
diff --git a/bin/mkprof/mkprof.c b/bin/mkprof/mkprof.c
index 209b5d3..3bc4e5e 100644
--- a/bin/mkprof/mkprof.c
+++ b/bin/mkprof/mkprof.c
@@ -146,7 +146,7 @@ saveindividual(struct mkonthread *mkp)
   /* Write the array to file (a separately built PSF doesn't need WCS
      coordinates). */
   if(ibq->ispsf && p->psfinimg==0)
-    gal_fits_img_write(ibq->image, filename, NULL, PROGRAM_STRING);
+    gal_fits_img_write(ibq->image, filename, NULL, PROGRAM_NAME);
   else
     {
       /* Allocate space for the corrected crpix and fill it in. Both
@@ -158,7 +158,7 @@ saveindividual(struct mkonthread *mkp)
       /* Write the image. */
       gal_fits_img_write_corr_wcs_str(ibq->image, filename, p->wcsheader,
                                       p->wcsnkeyrec, crpix, NULL,
-                                      PROGRAM_STRING);
+                                      PROGRAM_NAME);
     }
   ibq->indivcreated=1;
 
@@ -588,7 +588,7 @@ mkprof_write(struct mkprofparams *p)
          on, will put it in `out' to also free it while freeing `out'. */
       out->wcs=p->wcs;
       gal_fits_img_write_to_type(out, p->mergedimgname, NULL,
-                                 PROGRAM_STRING, p->cp.type);
+                                 PROGRAM_NAME, p->cp.type);
       p->wcs=NULL;
 
       /* Clean up */
diff --git a/bin/noisechisel/args.h b/bin/noisechisel/args.h
index 46f4dbf..772b09a 100644
--- a/bin/noisechisel/args.h
+++ b/bin/noisechisel/args.h
@@ -378,6 +378,19 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_SET
     },
     {
+      "dilatengb",
+      UI_KEY_DILATENGB,
+      "INT",
+      0,
+      "4 or 8 connectivity in final dilation.",
+      ARGS_GROUP_DETECTION,
+      &p->dilatengb,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+    {
       "cleandilated",
       UI_KEY_CLEANDILATED,
       0,
diff --git a/bin/noisechisel/astnoisechisel-3d.conf 
b/bin/noisechisel/astnoisechisel-3d.conf
index 58026c6..73fe65d 100644
--- a/bin/noisechisel/astnoisechisel-3d.conf
+++ b/bin/noisechisel/astnoisechisel-3d.conf
@@ -24,4 +24,5 @@
 
 # Detection
  erodengb       6
- openingngb     18
\ No newline at end of file
+ openingngb     18
+ dilatengb      18
\ No newline at end of file
diff --git a/bin/noisechisel/astnoisechisel.conf 
b/bin/noisechisel/astnoisechisel.conf
index b0e4f9b..6217e43 100644
--- a/bin/noisechisel/astnoisechisel.conf
+++ b/bin/noisechisel/astnoisechisel.conf
@@ -40,6 +40,7 @@
  detsnminarea       10
  detquant         0.95
  dilate              3
+ dilatengb           8
 
 # Segmentation
  segsnminarea       15
diff --git a/bin/noisechisel/clumps.c b/bin/noisechisel/clumps.c
index dd560f7..4c891fb 100644
--- a/bin/noisechisel/clumps.c
+++ b/bin/noisechisel/clumps.c
@@ -96,7 +96,7 @@ clumps_oversegment(struct clumps_thread_params *cltprm)
     error(EXIT_FAILURE, 0, "in the debugging mode of `clumps_oversegment' "
           "only one thread must be used");
   crop=gal_data_copy(tile);
-  gal_fits_img_write(crop, filename, NULL, PROGRAM_STRING);
+  gal_fits_img_write(crop, filename, NULL, PROGRAM_NAME);
   gal_data_free(crop);
   printf("blank: %u\nriver: %u\ntmpcheck: %u\ninit: %u\nmaxlab: %u\n",
          (int32_t)GAL_BLANK_INT32, (int32_t)CLUMPS_RIVER,
@@ -348,7 +348,7 @@ clumps_oversegment(struct clumps_thread_params *cltprm)
             crop=gal_data_copy(tile);
             crf=(cr=crop->array)+crop->size;
             do if(*cr==CLUMPS_RIVER) *cr=0; while(++cr<crf);
-            gal_fits_img_write(crop, filename, NULL, PROGRAM_STRING);
+            gal_fits_img_write(crop, filename, NULL, PROGRAM_NAME);
             gal_data_free(crop);
           }
         **********************************************/
@@ -1271,7 +1271,7 @@ clumps_true_find_sn_thresh(struct noisechiselparams *p)
              demo, set all Sky regions to blank and all clump macro values
              to zero. */
           gal_fits_img_write(p->clabel, p->segmentationname, NULL,
-                             PROGRAM_STRING);
+                             PROGRAM_NAME);
 
           /* Increment the step counter. */
           ++clprm.step;
@@ -1298,6 +1298,12 @@ clumps_true_find_sn_thresh(struct noisechiselparams *p)
   for(i=0;i<p->ltl.tottiles;++i)
     if(clprm.sn[i].ndim)  /* Only on tiles were an S/N was calculated. */
       numsn+=clprm.sn[i].size;
+  if( numsn < p->minnumfalse )
+    error(EXIT_FAILURE, 0, "only %zu clumps could be identified in the "
+          "undetected regions. This is less than %zu (value to "
+          "`--minnumfalse' option). Please either decrease this value or "
+          "other options to change prior processing steps", numsn,
+          p->minnumfalse);
 
 
   /* Allocate the space to keep all the S/N values. */
diff --git a/bin/noisechisel/detection.c b/bin/noisechisel/detection.c
index 8ba126b..3c82a74 100644
--- a/bin/noisechisel/detection.c
+++ b/bin/noisechisel/detection.c
@@ -49,12 +49,38 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /****************************************************************
  ************           Initial detection            ************
  ****************************************************************/
+/* The user gives connectivity values in terms of the number of neighbors
+   to use, so with this function, we convert that number to the
+   connectivity that is defined in `gnuastro/dimension.h'. */
+static int
+detection_ngb_to_connectivity(size_t ndim, size_t ngb)
+{
+  int connectivity=0;
+  switch(ndim)
+    {
+    case 2:
+      connectivity = ngb==4 ? 1 : 2;
+      break;
+    case 3:
+      connectivity = ngb==6 ? 1 : (ngb==18 ? 2 : 3);
+      break;
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to address "
+            "the problem. %zu not a valid value to `ndim'",
+            __func__, PACKAGE_BUGREPORT, ndim);
+    }
+  return connectivity;
+}
+
+
+
+
+
 void
 detection_initial(struct noisechiselparams *p)
 {
   char *msg;
   uint8_t *b, *bf;
-  int connectivity=0;
   struct timeval t0, t1;
 
 
@@ -71,30 +97,16 @@ detection_initial(struct noisechiselparams *p)
   if(p->detectionname)
     {
       p->binary->name="THRESHOLDED";
-      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_NAME);
       p->binary->name=NULL;
     }
 
 
-  /* Set the connectivity of the erosion. */
-  switch(p->binary->ndim)
-    {
-    case 2:
-      connectivity = p->erodengb==4 ? 1 : 2;
-      break;
-    case 3:
-      connectivity = p->erodengb==6 ? 1 : (p->erodengb==18 ? 2 : 3);
-      break;
-    default:
-      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to address "
-            "the problem. %zu not a valid value to p->binary->ndim",
-            __func__, PACKAGE_BUGREPORT, p->binary->ndim);
-    }
-
-
   /* Erode the image. */
   if(!p->cp.quiet) gettimeofday(&t1, NULL);
-  gal_binary_erode(p->binary, p->erode, connectivity, 1);
+  gal_binary_erode(p->binary, p->erode,
+                   detection_ngb_to_connectivity(p->input->ndim, p->erodengb),
+                   1);
   if(!p->cp.quiet)
     {
       asprintf(&msg, "Eroded %zu time%s (%zu-connectivity).", p->erode,
@@ -105,7 +117,7 @@ detection_initial(struct noisechiselparams *p)
   if(p->detectionname)
     {
       p->binary->name="ERODED";
-      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->binary, p->detectionname, NULL, PROGRAM_NAME);
       p->binary->name=NULL;
     }
 
@@ -117,7 +129,9 @@ detection_initial(struct noisechiselparams *p)
 
   /* Do the opening. */
   if(!p->cp.quiet) gettimeofday(&t1, NULL);
-  gal_binary_open(p->binary, p->opening, p->openingngb==4 ? 1 : 2, 1);
+  gal_binary_open(p->binary, p->opening,
+                  detection_ngb_to_connectivity(p->input->ndim, p->openingngb),
+                  1);
   if(!p->cp.quiet)
     {
       asprintf(&msg, "Opened (depth: %zu, %s connectivity).",
@@ -132,7 +146,7 @@ detection_initial(struct noisechiselparams *p)
   if(p->detectionname)
     {
       p->olabel->name="OPENED-AND-LABELED";
-      gal_fits_img_write(p->olabel, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->olabel, p->detectionname, NULL, PROGRAM_NAME);
       p->olabel->name=NULL;
     }
 
@@ -308,7 +322,7 @@ detection_pseudo_find(struct noisechiselparams *p, 
gal_data_t *workbin,
   if(p->detectionname)
     {
       workbin->name = s0d1 ? "DTHRESH-ON-DET" : "DTHRESH-ON-SKY";
-      gal_fits_img_write(workbin, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(workbin, p->detectionname, NULL, PROGRAM_NAME);
       workbin->name=NULL;
     }
 
@@ -363,7 +377,7 @@ detection_pseudo_find(struct noisechiselparams *p, 
gal_data_t *workbin,
             }
 
           /* Write the temporary array into the check image. */
-          gal_fits_img_write(bin, p->detectionname, NULL, PROGRAM_STRING);
+          gal_fits_img_write(bin, p->detectionname, NULL, PROGRAM_NAME);
 
           /* Increment the step counter. */
           ++fho_prm.step;
@@ -574,7 +588,7 @@ detection_sn(struct noisechiselparams *p, gal_data_t 
*worklab, size_t num,
           while(++plab<plabend);
         }
       worklab->name=extname;
-      gal_fits_img_write(worklab, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(worklab, p->detectionname, NULL, PROGRAM_NAME);
       worklab->name=NULL;
     }
 
@@ -688,7 +702,7 @@ detection_pseudo_remove_low_sn(struct noisechiselparams *p,
     {
       workbin->name="TRUE-PSEUDOS";
       gal_fits_img_write(workbin, p->detectionname, NULL,
-                         PROGRAM_STRING);
+                         PROGRAM_NAME);
       workbin->name=NULL;
     }
 
@@ -725,12 +739,14 @@ detection_pseudo_real(struct noisechiselparams *p)
 
 
   /* A small sanity check */
-  if(sn->size==0)
-    error(EXIT_FAILURE, 0, "no pseudo-detections could be found over the "
-          "sky region to estimate an S/N. Please adjust parameters like "
+  if( sn->size < p->minnumfalse)
+    error(EXIT_FAILURE, 0, "only %zu pseudo-detections could be found over "
+          "the sky region to estimate an S/N. This is less than %zu (value "
+          "to `--minnumfalse' option). Please adjust parameters like "
           "`--dthresh', `--detsnminarea', or make sure that there actually "
           "is sufficient sky area after initial detection. You can use "
-          "`--checkdetection' to see every step until this point");
+          "`--checkdetection' to see every step until this point", sn->size,
+          p->minnumfalse);
 
 
   /* Get the S/N quantile and report it if we are in non-quiet mode. */
@@ -839,7 +855,7 @@ detection_final_remove_small_sn(struct noisechiselparams 
*p, size_t num)
     {
       p->olabel->name="DETECTION-FINAL";
       gal_fits_img_write(p->olabel, p->detectionname, NULL,
-                         PROGRAM_STRING);
+                         PROGRAM_NAME);
       p->olabel->name=NULL;
     }
 
@@ -1001,14 +1017,18 @@ detection(struct noisechiselparams *p)
   /* If the user asked for dilation, then apply it. */
   if(p->dilate)
     {
-      gal_binary_dilate(workbin, p->dilate, p->input->ndim, 1);
+      gal_binary_dilate(workbin, p->dilate,
+                        detection_ngb_to_connectivity(p->input->ndim,
+                                                      p->dilatengb),
+                        1);
       num_true_initial = gal_binary_connected_components(workbin, &p->olabel,
                                                          8);
     }
   if(!p->cp.quiet)
     {
-      asprintf(&msg, "%zu detections after %zu dilation%s",
-              num_true_initial, p->dilate, p->dilate>1 ? "s." : ".");
+      asprintf(&msg, "%zu detections after %zu dilation%s (%zu-connected)",
+               num_true_initial, p->dilate, p->dilate>1 ? "s." : ".",
+               p->dilatengb);
       gal_timing_report(&t0, msg, 2);
       free(msg);
     }
@@ -1029,7 +1049,7 @@ detection(struct noisechiselparams *p)
         {
           p->olabel->name="DETECTION-FINAL";
           gal_fits_img_write(p->olabel, p->detectionname, NULL,
-                             PROGRAM_STRING);
+                             PROGRAM_NAME);
           p->olabel->name=NULL;
         }
     }
diff --git a/bin/noisechisel/main.h b/bin/noisechisel/main.h
index 25dff0d..bdd7396 100644
--- a/bin/noisechisel/main.h
+++ b/bin/noisechisel/main.h
@@ -73,6 +73,7 @@ struct noisechiselparams
   uint8_t          checkdetsn;  /* Save pseudo-detection S/N values.      */
   float              detquant;  /* True detection quantile.               */
   size_t               dilate;  /* Number of times to dilate true dets.   */
+  size_t            dilatengb;  /* Connectivity for final dilation.       */
   uint8_t        cleandilated;  /* Remove dilated objects with small S/N. */
   uint8_t      checkdetection;  /* Save all detection steps to a file.    */
   uint8_t            checksky;  /* Check the Sky value estimation.        */
diff --git a/bin/noisechisel/noisechisel.c b/bin/noisechisel/noisechisel.c
index cf0f94b..f5d4fc8 100644
--- a/bin/noisechisel/noisechisel.c
+++ b/bin/noisechisel/noisechisel.c
@@ -68,8 +68,8 @@ noisechisel_convolve(struct noisechiselparams *p)
   if(!p->cp.quiet) gal_timing_report(&t1, "Convolved with kernel.", 1);
   if(p->detectionname)
     {
-      gal_fits_img_write(p->input, p->detectionname, NULL, PROGRAM_STRING);
-      gal_fits_img_write(p->conv, p->detectionname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->input, p->detectionname, NULL, PROGRAM_NAME);
+      gal_fits_img_write(p->conv, p->detectionname, NULL, PROGRAM_NAME);
     }
 }
 
@@ -205,7 +205,7 @@ noisechisel_output(struct noisechiselparams *p)
                         0, "Minimum S/N of true pseudo-detections", 0,
                         "ratio");
   p->olabel->name = p->onlydetection ? "DETECTIONS" : "OBJECTS";
-  gal_fits_img_write(p->olabel, p->cp.output, keys, PROGRAM_STRING);
+  gal_fits_img_write(p->olabel, p->cp.output, keys, PROGRAM_NAME);
   p->olabel->name=NULL;
   keys=NULL;
 
@@ -223,7 +223,7 @@ noisechisel_output(struct noisechiselparams *p)
       gal_fits_key_list_add(&keys, GAL_TYPE_FLOAT32, "CLUMPSN", 0,
                             &p->clumpsnthresh, 0, "Minimum S/N of true clumps",
                             0, "ratio");
-      gal_fits_img_write(p->clabel, p->cp.output, keys, PROGRAM_STRING);
+      gal_fits_img_write(p->clabel, p->cp.output, keys, PROGRAM_NAME);
       p->clabel->name=NULL;
       keys=NULL;
     }
@@ -233,7 +233,7 @@ noisechisel_output(struct noisechiselparams *p)
   if(p->sky->name) free(p->sky->name);
   p->sky->name="SKY";
   gal_tile_full_values_write(p->sky, &p->cp.tl, p->cp.output,
-                             NULL, PROGRAM_STRING);
+                             NULL, PROGRAM_NAME);
   p->sky->name=NULL;
 
 
@@ -249,7 +249,7 @@ noisechisel_output(struct noisechiselparams *p)
                         "Median raw tile standard deviation", 0,
                         p->input->unit);
   gal_tile_full_values_write(p->std, &p->cp.tl, p->cp.output, keys,
-                             PROGRAM_STRING);
+                             PROGRAM_NAME);
   p->std->name=NULL;
 }
 
diff --git a/bin/noisechisel/segmentation.c b/bin/noisechisel/segmentation.c
index 6c25980..eb3e706 100644
--- a/bin/noisechisel/segmentation.c
+++ b/bin/noisechisel/segmentation.c
@@ -767,7 +767,7 @@ segmentation_detections(struct noisechiselparams *p)
              default values are hard to view, so we'll make a copy of the
              demo, set all Sky regions to blank and all clump macro values
              to zero. */
-          gal_fits_img_write(demo, p->segmentationname, NULL, PROGRAM_STRING);
+          gal_fits_img_write(demo, p->segmentationname, NULL, PROGRAM_NAME);
 
           /* If the user wanted to check the clump S/N values, then break
              out of the loop, we don't need the rest of the process any
@@ -847,11 +847,11 @@ segmentation(struct noisechiselparams *p)
      inputs. */
   if(p->segmentationname)
     {
-      gal_fits_img_write(p->input, p->segmentationname, NULL, PROGRAM_STRING);
-      gal_fits_img_write(p->conv, p->segmentationname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->input, p->segmentationname, NULL, PROGRAM_NAME);
+      gal_fits_img_write(p->conv, p->segmentationname, NULL, PROGRAM_NAME);
       p->olabel->name="DETECTION_LABELS";
       gal_fits_img_write(p->olabel, p->segmentationname, NULL,
-                         PROGRAM_STRING);
+                         PROGRAM_NAME);
       p->olabel->name=NULL;
     }
 
diff --git a/bin/noisechisel/sky.c b/bin/noisechisel/sky.c
index efb5961..5cc9340 100644
--- a/bin/noisechisel/sky.c
+++ b/bin/noisechisel/sky.c
@@ -157,7 +157,7 @@ sky_and_std(struct noisechiselparams *p, char *checkname)
   if(checkname && !tl->oneelempertile)
     {
       p->binary->name="DETECTED";
-      gal_fits_img_write(p->binary, checkname, NULL, PROGRAM_STRING);
+      gal_fits_img_write(p->binary, checkname, NULL, PROGRAM_NAME);
       p->binary->name=NULL;
     }
 
@@ -174,8 +174,8 @@ sky_and_std(struct noisechiselparams *p, char *checkname)
                        cp->numthreads);
   if(checkname)
     {
-      gal_tile_full_values_write(p->sky, tl, checkname, NULL, PROGRAM_STRING);
-      gal_tile_full_values_write(p->std, tl, checkname, NULL, PROGRAM_STRING);
+      gal_tile_full_values_write(p->sky, tl, checkname, NULL, PROGRAM_NAME);
+      gal_tile_full_values_write(p->std, tl, checkname, NULL, PROGRAM_NAME);
     }
 
   /* Get the basic information about the standard deviation
diff --git a/bin/noisechisel/threshold.c b/bin/noisechisel/threshold.c
index f58eedc..6584d38 100644
--- a/bin/noisechisel/threshold.c
+++ b/bin/noisechisel/threshold.c
@@ -273,8 +273,8 @@ threshold_interp_smooth(struct noisechiselparams *p, 
gal_data_t **first,
     {
       (*first)->name="THRESH1_INTERP";
       (*second)->name="THRESH2_INTERP";
-      gal_tile_full_values_write(*first, tl, filename, NULL, PROGRAM_STRING);
-      gal_tile_full_values_write(*second, tl, filename, NULL, PROGRAM_STRING);
+      gal_tile_full_values_write(*first, tl, filename, NULL, PROGRAM_NAME);
+      gal_tile_full_values_write(*second, tl, filename, NULL, PROGRAM_NAME);
       (*first)->name = (*second)->name = NULL;
     }
 
@@ -299,9 +299,9 @@ threshold_interp_smooth(struct noisechiselparams *p, 
gal_data_t **first,
           (*first)->name="THRESH1_SMOOTH";
           (*second)->name="THRESH2_SMOOTH";
           gal_tile_full_values_write(*first, tl, filename, NULL,
-                                     PROGRAM_STRING);
+                                     PROGRAM_NAME);
           gal_tile_full_values_write(*second, tl, filename, NULL,
-                                     PROGRAM_STRING);
+                                     PROGRAM_NAME);
           (*first)->name = (*second)->name = NULL;
         }
     }
@@ -458,7 +458,7 @@ threshold_quantile_find_apply(struct noisechiselparams *p)
      the full input when `oneelempertile' isn't requested. */
   if(p->qthreshname && !tl->oneelempertile)
     gal_fits_img_write(p->conv ? p->conv : p->input, p->qthreshname, NULL,
-                       PROGRAM_STRING);
+                       PROGRAM_NAME);
 
 
   /* Allocate space for the quantile threshold values. */
@@ -491,9 +491,9 @@ threshold_quantile_find_apply(struct noisechiselparams *p)
       qprm.erode_th->name="QTHRESH_ERODE";
       qprm.noerode_th->name="QTHRESH_NOERODE";
       gal_tile_full_values_write(qprm.erode_th, tl, p->qthreshname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
       gal_tile_full_values_write(qprm.noerode_th, tl, p->qthreshname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
       qprm.erode_th->name = qprm.noerode_th->name = NULL;
     }
 
@@ -510,7 +510,7 @@ threshold_quantile_find_apply(struct noisechiselparams *p)
 
   /* Write the binary image if check is requested. */
   if(p->qthreshname && !tl->oneelempertile)
-    gal_fits_img_write(p->binary, p->qthreshname, NULL, PROGRAM_STRING);
+    gal_fits_img_write(p->binary, p->qthreshname, NULL, PROGRAM_NAME);
 
 
   /* Clean up and report duration if necessary. */
diff --git a/bin/noisechisel/ui.c b/bin/noisechisel/ui.c
index d8d9a62..69a7c88 100644
--- a/bin/noisechisel/ui.c
+++ b/bin/noisechisel/ui.c
@@ -216,22 +216,28 @@ parse_opt(int key, char *arg, struct argp_state *state)
 /**************************************************************/
 /***************       Sanity Check         *******************/
 /**************************************************************/
+static void
+ui_ngb_check(size_t value, char *optionname)
+{
+  if(value!=4 && value!=8 && value!=6 && value!=18 && value!=26)
+    error(EXIT_FAILURE, 0, "%zu is not an acceptable value for "
+          "`--%s'. Acceptable values are 4 or 8 (for 2D inputs) and "
+          "6, 18, or 26 (for 3D inputs)", value, optionname);
+}
+
+
+
+
+
 /* Read and check ONLY the options. When arguments are involved, do the
    check in `ui_check_options_and_arguments'. */
 static void
 ui_read_check_only_options(struct noisechiselparams *p)
 {
   /* A general check on the neighbor connectivity values. */
-  if(p->erodengb!=4 && p->erodengb!=8 && p->erodengb!=6 && p->erodengb!=18
-     && p->erodengb!=26)
-    error(EXIT_FAILURE, 0, "%zu is not an acceptable value for "
-          "`--erodengb'. Acceptable values are 4 or 8 (for 2D inputs) and "
-          "6, 18, or 26 (for 3D inputs)", p->erodengb);
-  if(p->openingngb!=4 && p->openingngb!=8 && p->openingngb!=6
-     && p->openingngb!=18 && p->openingngb!=26)
-    error(EXIT_FAILURE, 0, "%zu is not an acceptable value for "
-          "`--openingngb'. Acceptable values are 4 or 8 (for 2D inputs) and "
-          "6, 18, or 26 (for 3D inputs)", p->openingngb);
+  ui_ngb_check(p->erodengb,   "erodengb");
+  ui_ngb_check(p->dilatengb,  "dilatengb");
+  ui_ngb_check(p->openingngb, "openingngb");
 
   /* Make sure that the no-erode-quantile is not smaller or equal to
      qthresh. */
@@ -241,7 +247,7 @@ ui_read_check_only_options(struct noisechiselparams *p)
           "or `-t'). You have provided %.4f and %.4f for the former and "
           "latter, respectively", p->noerodequant, p->qthresh);
 
-  /* For the options that make tables, the table formation option is
+  /* For the options that make tables, the table format option is
      mandatory. */
   if( (p->checkdetsn || p->checkclumpsn) && p->cp.tableformat==0 )
     error(EXIT_FAILURE, 0, "`--tableformat' is necessary with the "
diff --git a/bin/noisechisel/ui.h b/bin/noisechisel/ui.h
index 8c0d3d6..416cd76 100644
--- a/bin/noisechisel/ui.h
+++ b/bin/noisechisel/ui.h
@@ -71,6 +71,7 @@ enum option_keys_enum
   UI_KEY_OPENINGNGB,
   UI_KEY_CHECKDETSKY,
   UI_KEY_CHECKDETSN,
+  UI_KEY_DILATENGB,
   UI_KEY_CLEANDILATED,
   UI_KEY_CHECKDETECTION,
   UI_KEY_CHECKSKY,
diff --git a/bin/statistics/sky.c b/bin/statistics/sky.c
index fc20a17..f68678c 100644
--- a/bin/statistics/sky.c
+++ b/bin/statistics/sky.c
@@ -151,7 +151,7 @@ sky(struct statisticsparams *p)
 
   /* When checking steps, the input image is the first extension. */
   if(p->checksky)
-    gal_fits_img_write(p->input, p->checkskyname, NULL, PROGRAM_STRING);
+    gal_fits_img_write(p->input, p->checkskyname, NULL, PROGRAM_NAME);
 
 
   /* Convolve the image (if desired). */
@@ -162,7 +162,7 @@ sky(struct statisticsparams *p)
                                         cp->numthreads, 1, tl->workoverch);
       if(p->checksky)
         gal_fits_img_write(p->convolved, p->checkskyname, NULL,
-                           PROGRAM_STRING);
+                           PROGRAM_NAME);
       if(!cp->quiet)
         gal_timing_report(&t1, "Input convolved with kernel.", 1);
     }
@@ -193,9 +193,9 @@ sky(struct statisticsparams *p)
   if(p->checksky)
     {
       gal_tile_full_values_write(p->sky_t, tl, p->checkskyname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
       gal_tile_full_values_write(p->std_t, tl, p->checkskyname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
     }
 
 
@@ -214,9 +214,9 @@ sky(struct statisticsparams *p)
   if(p->checksky)
     {
       gal_tile_full_values_write(p->sky_t, tl, p->checkskyname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
       gal_tile_full_values_write(p->std_t, tl, p->checkskyname, NULL,
-                                 PROGRAM_STRING);
+                                 PROGRAM_NAME);
     }
 
 
@@ -238,9 +238,9 @@ sky(struct statisticsparams *p)
       if(p->checksky)
         {
           gal_tile_full_values_write(p->sky_t, tl, p->checkskyname, NULL,
-                                     PROGRAM_STRING);
+                                     PROGRAM_NAME);
           gal_tile_full_values_write(p->std_t, tl, p->checkskyname, NULL,
-                                     PROGRAM_STRING);
+                                     PROGRAM_NAME);
         }
     }
 
@@ -250,8 +250,8 @@ sky(struct statisticsparams *p)
                                         ( p->cp.output
                                           ? p->cp.output
                                           : p->inputname ), "_sky.fits");
-  gal_tile_full_values_write(p->sky_t, tl, outname, NULL, PROGRAM_STRING);
-  gal_tile_full_values_write(p->std_t, tl, outname, NULL, PROGRAM_STRING);
+  gal_tile_full_values_write(p->sky_t, tl, outname, NULL, PROGRAM_NAME);
+  gal_tile_full_values_write(p->std_t, tl, outname, NULL, PROGRAM_NAME);
   if(!cp->quiet)
     printf("  - Written to `%s'.\n", outname);
 
diff --git a/bin/statistics/statistics.c b/bin/statistics/statistics.c
index 9333fe8..7b27985 100644
--- a/bin/statistics/statistics.c
+++ b/bin/statistics/statistics.c
@@ -254,7 +254,7 @@ statistics_interpolate_and_write(struct statisticsparams *p,
     }
 
   /* Write the values. */
-  gal_tile_full_values_write(values, &cp->tl, output, NULL, PROGRAM_STRING);
+  gal_tile_full_values_write(values, &cp->tl, output, NULL, PROGRAM_NAME);
 }
 
 
@@ -557,7 +557,7 @@ write_output_table(struct statisticsparams *p, gal_data_t 
*table,
   gal_list_str_add(&comments, tmp, 0);
 
   if(strcmp(fix, "fits"))  /* The intro info will be in FITS files anyway.*/
-    gal_table_comments_add_intro(&comments, PROGRAM_STRING, &p->rawtime);
+    gal_table_comments_add_intro(&comments, PROGRAM_NAME, &p->rawtime);
 
 
   /* Write the table. */
@@ -704,7 +704,7 @@ print_input_info(struct statisticsparams *p)
   char *str, *name, *col=NULL;
 
   /* Print the program name and version. */
-  printf("%s\n", PROGRAM_STRING);
+  printf("%s\n", PROGRAM_NAME);
 
   /* Print the input information, if the input was a table, we also need to
      give the column information. When the column has a name, it will be
diff --git a/bin/warp/warp.c b/bin/warp/warp.c
index 23fa4ee..b22e63f 100644
--- a/bin/warp/warp.c
+++ b/bin/warp/warp.c
@@ -469,7 +469,7 @@ correct_wcs_save_output(struct warpparams *p)
   /* Save the output into the proper type and write it. */
   if(p->cp.type!=p->output->type)
     p->output=gal_data_copy_to_new_type_free(p->output, p->cp.type);
-  gal_fits_img_write(p->output, p->cp.output, headers, PROGRAM_STRING);
+  gal_fits_img_write(p->output, p->cp.output, headers, PROGRAM_NAME);
 }
 
 
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
new file mode 100644
index 0000000..b4c0c94
--- /dev/null
+++ b/doc/announce-acknowledge.txt
@@ -0,0 +1,15 @@
+This file is meant to keep the names of the people who's help must be
+acknowledged in the next release.
+
+Marjan Akbari
+Adrian Bunk
+Antonio Diaz Diaz
+Mosè Giordano
+Raúl Infante Sainz
+Aurélien Jarno
+Alan Lefor
+Guillaume Mahler
+William Pence
+Ole Streicher
+Ignacio Trujillo
+David Valls-Gabaud
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index ddb4224..54dec63 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -1543,17 +1543,19 @@ management of its version controlled source server 
there.
 
 @c To the developers: please keep this in the same order as the THANKS file
 @c (alphabetical, except for the names in the paragraph above).
-We would also like to gratefully thank (in alphabetical order) Roland
-Bacon, Nicolas Bouché, Adrian Bunk, Rosa Calvi, Antonio Diaz Diaz, Raúl
-Infante Sainz, Lee Kelvin, Mohammad-Reza Khellat, Alan Lefor, Guillaume
-Mahler, Francesco Montanari, William Pence, Yahya Sefidbakht, Ole
-Streicher, Ignacio Trujillo, David Valls-Gabaud and Christopher Willmer for
-their useful and constructive comments and suggestions. Finally we should
-thank all the (sometimes anonymous) people in various online forums which
-patiently answered all our small (but important) technical questions. All
-work on Gnuastro has been voluntary, but we are most grateful to the
-following institutions (in chronological order) for hosting us in our
-research:
+We would also like to gratefully thank (in alphabetical order by family
+name) Marjan Akbari, Roland Bacon, Nicolas Bouch@'e, Adrian Bunk, Rosa
+Calvi, Antonio Diaz Diaz, Raúl Infante Sainz, Lee Kelvin, Mohammad-Reza
+Khellat, Alan Lefor, Guillaume Mahler, Francesco Montanari, William Pence,
+Yahya Sefidbakht, Ole Streicher, Ignacio Trujillo, David Valls-Gabaud and
+Christopher Willmer for their useful and constructive comments and
+suggestions. Finally we should thank all the (sometimes anonymous) people
+in various online forums which patiently answered all our small (but
+important) technical questions.
+
+All work on Gnuastro has been voluntary, but the authors are most grateful
+to the following institutions (in chronological order) for hosting us in
+our research:
 
 @quotation
 Ministry of education, culture, sports, science and technology (MEXT), Japan.@*
@@ -2851,21 +2853,17 @@ activities, please clone the version controlled source 
as described in
 
 @cindex Gzip
 @cindex Lzip
-Gnuastro's official tarball is released with two formats: Gzip (with suffix
-@file{.tar.gz}) and Lzip (with suffix @file{.tar.lz}). The former is a very
-well-known and widely used compression program created by GNU and available
-in most systems. The latter provides a better compression ratio and more
-robust archival capacity. For example Gnuastro 0.2's tarball was 2.8MB and
-4.2MB with Lzip and Gzip respectively. From the
-@url{http://www.nongnu.org/lzip/lzip.html, Lzip webpage}: ``Lzip is a
-lossless data compressor with a user interface similar to the one of gzip
-or bzip2. Lzip can compress about as fast as gzip (@command{lzip -0}), or
-compress most files more than bzip2 (@command{lzip -9}). Decompression
-speed is intermediate between gzip and bzip2. Lzip is better than gzip and
-bzip2 from a data recovery perspective.'' However, Lzip is currently not
-too common, so it might not be pre-installed in your operating
-system. Installing it from your operating system's package manager or from
-source is very easy.
+Gnuastro's official/stable tarball is released with two formats: Gzip (with
+suffix @file{.tar.gz}) and Lzip (with suffix @file{.tar.lz}). The
+pre-release tarballs (after version 0.3) are released only as an Lzip
+tarball. Gzip is a very well-known and widely used compression program
+created by GNU and available in most systems. However, Lzip provides a
+better compression ratio and more robust archival capacity. For example
+Gnuastro 0.3's tarball was 2.9MB and 4.3MB with Lzip and Gzip respectively,
+see the @url{http://www.nongnu.org/lzip/lzip.html, Lzip webpage} for
+more. Lzip might not be pre-installed in your operating system, if so,
+installing it from your operating system's package manager or from source
+is very easy and fast (it is a very small program).
 
 The GNU FTP server is mirrored (has backups) in various locations on the
 globe (@url{http://www.gnu.org/order/ftp.html}). You can use the closest
@@ -12160,6 +12158,11 @@ give this option a value of 1 (only the largest valued 
pixel in the input
 will not be eroded).
 
 @item
+@option{--dilatengb}: to specify the final dilation connectivity. Prior to
+Gnuastro 0.4, it was assumed to be 8 (maximum connectivity in a 2D image
+where each pixel has 8 neighbors).
+
+@item
 @option{--cleandilated}: After dilation, if the signal-to-noise ratio of a
 detection is less than the derived pseudo-detection S/N limit, that
 detection will be discarded. In an ideal/clean noise, a true detection's
@@ -12694,6 +12697,10 @@ neighborhood. This is because astronomical objects, 
except cosmic rays,
 never have a clear cutoff, so all the 8-pixels connected to the border
 pixels of a detection might harbor data.
 
+@item --dilatengb=INT
+The connectivity used for the final dilation, see @option{--erodengb} for
+more information about connectivity or a structuring element.
+
 @item --checkdetection
 Every step of the detection process will be added as an extension to a file
 with the suffix @file{_det.fits}. Going through each would just be a repeat
@@ -12901,12 +12908,13 @@ pixel.
 
 @end enumerate
 
-To inspect NoiseChisel's 2D output (when input is 2D), you can configure
-SAO DS9 in your Graphic User Interface (GUI) to open NoiseChisel's output
-as a multi-extension data cube. This will allow you to flip through the
-different extensions and visually inspect the results. This process has
-been described for the GNOME GUI (most common GUI in GNU/Linux operating
-systems) in @ref{Viewing multiextension FITS images}.
+When the input is a 2D image, to inspect NoiseChisel's output you can
+configure SAO DS9 in your Graphic User Interface (GUI) to open
+NoiseChisel's output as a multi-extension data cube. This will allow you to
+flip through the different extensions and visually inspect the
+results. This process has been described for the GNOME GUI (most common GUI
+in GNU/Linux operating systems) in @ref{Viewing multiextension FITS
+images}.
 
 For a 3D datacube, things become a little more complicated because
 projecting a 3D dataset to a 2D surface (your monitor) is always bound to
diff --git a/doc/release-checklist.txt b/doc/release-checklist.txt
index 8239932..3b25ac0 100644
--- a/doc/release-checklist.txt
+++ b/doc/release-checklist.txt
@@ -6,12 +6,14 @@ set of operations to do for making each release. This should 
be done after
 all the commits needed for this release have been completed.
 
 
- - Only in an alpha release (In the next main release they will remain
-   unchanged): update the library version (the values starting with `GAL_'
-   in `configure.ac'). See the `Updating library version information'
-   section of the GNU Libtool manual as a guide.
+ - [ALPHA] Only in the first alpha release after a stable release: update
+   the library version (the values starting with `GAL_' in
+   `configure.ac'). See the `Updating library version information' section
+   of the GNU Libtool manual as a guide.
+
+
+ - [ALPHA] Run a spell-check (in emacs with `M-x ispell') on the whole book.
 
- - Run a spell-check (in emacs with `M-x ispell') on the whole book.
 
  - Update the NEWS file (use `git log --reverse gnuastro_vA.B..HEAD').
 
@@ -25,7 +27,11 @@ all the commits needed for this release have been completed.
    people/institutions.
 
 
- - Update the webpage (`doc/gnuastro-top.html') and correct the links.
+ - Make sure THANKS corresponds to the acknowledgements in the book.
+
+
+ - [STABLE] Update the webpage (`doc/gnuastro-top.html') and correct the
+   links.
 
 
  - Commit all these changes and tag the commit:
@@ -45,13 +51,21 @@ all the commits needed for this release have been completed.
      $ make distcheck -j8
 
 
+ - [ALPHA] For alpha, we will only be distributing lzip tarballs. So first
+   remove the `tar.gz' file that was produced by `make distcheck', then
+   make the `tar.lz' that will be distributed.
+
+     $ rm *.tar.gz
+     $ make dist-lzip
+
+
  - [STABLE]: After the `make distcheck' is safely finished, tag the release:
 
      $ git tag -a gnuastro_vX.X
 
 
- - The tag will cause a change in the tarball version. So clean the build
-   directory, and repeat the steps for the final release:
+ - [STABLE] The tag will cause a change in the tarball version. So clean
+   the build directory, and repeat the steps for the final release:
 
      $ rm -rf ./build/*
      $ autoreconf -f
@@ -60,6 +74,7 @@ all the commits needed for this release have been completed.
      $ make distcheck -j8
      $ make dist-lzip
 
+
  - Upload the tarball with the command below: Note that `gnupload'
    uses `ncftpput' which comes with the `ncftp' package. The replaces
    are necessary for the symbolic links.
@@ -68,7 +83,7 @@ all the commits needed for this release have been completed.
 
        $  /path/to/gnulib/build-aux/gnupload --to alpha.gnu.org:gnuastro   \
                --replace --symlink-regex="s/X.X.XXX-XXXX/alpha-latest/"    \
-               gnuastro-X.X.XXX-XXXX.tar.gz
+               gnuastro-X.X.XXX-XXXX.tar.lz
 
    - For a stable release:
 
@@ -76,40 +91,45 @@ all the commits needed for this release have been completed.
                --replace --symlink-regex                                   \
                gnuastro-X.X.tar.gz gnuastro-X.X.tar.lz
 
- - [ALPHA]: Now that you have the release number, update the link on the
-   main HTML on the webpage (`gnuastro-top.html').
 
- - Build the manual in all the formats and upload everything. Note that you
-   will need to configure Gnuastro in the main source directory to build
-   the full webpage with this script.
+ - [STABLE] Build the manual in all the formats and upload everything. Note
+   that you will need to configure Gnuastro in the main source directory to
+   build the full webpage with this script.
 
        $ ./configure
        $ cd doc
        $ ./forwebpage /path/to/local/copy/of/webpage
 
+
  - Push all the changes and tag to the main repo:
 
     $ git push --follow-tags
 
+
  - Prepare the announcement, this command will calculate the checksums and
    also make the links ready. You just have to add a starting and ending
    similar to previous announcements in a text editor. In the `XXXX', put
-   `ftp' for a stable, and `alpha' for an alpha release.
+   `stable' or `alpha' and in YYYY, put `ftp' for a stable, and `alpha' for
+   an alpha release.
 
-     $ /path/to/gnulib/build-aux/announce-gen --release-type=stable        \
+     $ /path/to/gnulib/build-aux/announce-gen --release-type=XXXX        \
               --package-name=gnuastro --previous-version=0.1               \
               --current-version=0.2 --gpg-key-id=16A8A4B2AEC42AFF          \
-              --url-directory=http://XXXX.gnu.org/gnu/gnuastro             \
+              --url-directory=http://YYYY.gnu.org/gnu/gnuastro             \
               --archive-suffix=tar.lz > announcement.txt
 
+
  - After finishing the announcement (adding an intro and NEWS file), run a
    spell-check on it.
 
- - IMPORTANT: double check the changes in the list of authors and the list
-   in THANKS and make sure everyone's contribution is correctly included.
 
- - Announce the release on `info-gnuastro@gnu.org', `info-gnu@gnu.org' and
-   Savannah news.
+ - IMPORTANT: In the announcements, double check the changes in the list of
+   authors and the list in THANKS and make sure everyone's contribution is
+   correctly included.
+
+
+ - Announce the release on `info-gnuastro@gnu.org', `info-gnu@gnu.org'
+   (only for STABLE) and Savannah news (only for STABLE).
 
 
 
@@ -131,6 +151,7 @@ Steps necessary to Package Gnuastro for Debian.
 
      $ git clone git://anonscm.debian.org/debian-astro/packages/gnuastro.git
 
+
  - If a Git directory exists, then pull any possible changes that already
    exist:
 
@@ -138,17 +159,20 @@ Steps necessary to Package Gnuastro for Debian.
      $ git pull
      $ cd ..
 
+
  - Clean any existing files (if this process was already done for an
    earlier version):
 
      $ rm -f gnuastro_* gnuastro-*
 
+
  - To keep things clean, define Gnuastro's version as a variable (if this
    isn't a major release, we won't use the last four or five characters
    that are the first commit hash characters):
 
      $ export ver=A.B.CCC
 
+
  - Put a copy of the tarball to be packaged in this directory and make a
    standard symbolic link to it (IMPORTANT: the `dash' is changed to an
    `underscore' and an `orig' is added), then go into the cloned directory.
@@ -156,6 +180,7 @@ Steps necessary to Package Gnuastro for Debian.
      $ ln -s gnuastro-$ver-XXXX.tar.gz gnuastro_$ver.orig.tar.gz
      $ cd gnuastro
 
+
  - You need to checkout to the `upstream' branch, clean everything that was
    in it and unpack this release's raw package source files into it as
    shown below.
@@ -166,6 +191,7 @@ Steps necessary to Package Gnuastro for Debian.
      $ mv ../gnuastro-tmp-git .git         # Bring back the `.git' directory.
      $ tar xf ../gnuastro_$ver.orig.tar.gz --strip-components=1
 
+
  - We now need to commit these into the `upstream' branch of the Git
    history, tag it and run `pristine-tar' on it.
 
@@ -174,11 +200,13 @@ Steps necessary to Package Gnuastro for Debian.
      $ git tag upstream/$ver
      $ pristine-tar commit ../gnuastro_$ver.orig.tar.gz
 
+
  - We are done with the `upstream' and `pristine-tar' branches and can
    checkout `master':
 
      $ git checkout master
 
+
  - Again, we need to clean everything that already exists here, except
    `.git' and `debian':
 
@@ -188,10 +216,12 @@ Steps necessary to Package Gnuastro for Debian.
      $ mv ../gnuastro-tmp-git .git         # Bring back the `.git' directory.
      $ mv ../gnuastro-tmp-debian debian    # Bring back the `debian' directory.
 
+
  - Unpack the distribution tarball into the master branch too:
 
      $ tar xf ../gnuastro_$ver.orig.tar.gz --strip-components=1
 
+
  - Update the ChangeLog. But first get all the changes in this version from
    the NEWS file.
 
@@ -202,11 +232,13 @@ Steps necessary to Package Gnuastro for Debian.
      $ git diff NEWS
      $ emacs debian/changelog
 
+
  - Check the current Debian policy version at
    https://www.debian.org/doc/debian-policy/ and update debian/control:
 
      $ emacs debian/control
 
+
  - If the soname of the shared libraries has changed:
 
      - Rename the file `debain/libgnuastroX.install' (set `X' to the new
@@ -214,28 +246,36 @@ Steps necessary to Package Gnuastro for Debian.
 
      - In `debian control, change all the old sonames to the new value.
 
+
  - Update your version of `pbuilder':
 
      $ sudo pbuilder update
 
+
  - Run `pdebuild' to build the package (needs sudo).
 
      $ sudo pdebuild
 
+
  - Run Lintian to check the build.
 
      $ lintian -E -I --pedantic                                         \
                /var/cache/pbuilder/result/gnuastro_$ver-1_amd64.changes
 
+
  - Commit the contents of the new release, make sure everything except the
    `debian' directory is commited (with `git status'):
 
-     $ git add -f bin/ bootstrapped/ doc/ lib/ tests/
-     $ git status                         # Add anything that remains.
+     $ git add --all
+     $ git status                         # For a visual check
      $ git commit -m "Gnuastro $ver"
 
- - Push all the changes to the repository:
 
-     $ git push --all origin
+ - Push all the changes to the repository (you can't call `--all' and
+   `--tags' together):
+
+     $ git push --all
+     $ git push --tags
+
 
  - Inform Debian Astro.
diff --git a/lib/fits.c b/lib/fits.c
index d172a6c..9350c2f 100644
--- a/lib/fits.c
+++ b/lib/fits.c
@@ -1123,7 +1123,6 @@ gal_fits_key_write_wcsstr(fitsfile *fptr, char *wcsstr, 
int nkeyrec)
 {
   size_t i;
   int h, status=0;
-  char startblank[]="                      / ";
   char *cp, *cpf, blankrec[80], titlerec[80];
 
   /* Set the last element of the blank array. */
@@ -1135,7 +1134,7 @@ gal_fits_key_write_wcsstr(fitsfile *fptr, char *wcsstr, 
int nkeyrec)
   /* Print the first two lines before the WCS header information. */
   if(fits_write_record(fptr, blankrec, &status))
     gal_fits_io_error(status, NULL);
-  sprintf(titlerec, "%sWCS information", startblank);
+  sprintf(titlerec, "%sWCS information", GAL_FITS_KEY_TITLE_START);
   for(i=strlen(titlerec);i<79;++i)
     titlerec[i]=' ';
   if(fits_write_record(fptr, titlerec, &status))
@@ -1210,7 +1209,6 @@ gal_fits_key_write_version(fitsfile *fptr, 
gal_fits_list_key_t *headers,
   int status=0;
   char *gitdescribe;
   char cfitsioversion[20];
-  char startblank[]="              / ";
   char *cp, *cpf, blankrec[80], titlerec[80];
 
   /* Before WCSLIB 5.0, the wcslib_version function was not
@@ -1233,7 +1231,7 @@ gal_fits_key_write_version(fitsfile *fptr, 
gal_fits_list_key_t *headers,
   if(headers)
     {
       fits_write_record(fptr, blankrec, &status);
-      sprintf(titlerec, "%s%s", startblank,
+      sprintf(titlerec, "%s%s", GAL_FITS_KEY_TITLE_START,
               program_name ? program_name : PACKAGE_NAME);
       for(i=strlen(titlerec);i<79;++i) titlerec[i]=' ';
       fits_write_record(fptr, titlerec, &status);
@@ -1243,7 +1241,7 @@ gal_fits_key_write_version(fitsfile *fptr, 
gal_fits_list_key_t *headers,
 
   /* Start printing the version information */
   fits_write_record(fptr, blankrec, &status);
-  sprintf(titlerec, "%sVersions and date", startblank);
+  sprintf(titlerec, "%sVersions and date", GAL_FITS_KEY_TITLE_START);
   for(i=strlen(titlerec);i<79;++i) titlerec[i]=' ';
   fits_write_record(fptr, titlerec, &status);
   gal_fits_io_error(status, NULL);
diff --git a/lib/gnuastro/fits.h b/lib/gnuastro/fits.h
index b7b67c8..a44a3d5 100644
--- a/lib/gnuastro/fits.h
+++ b/lib/gnuastro/fits.h
@@ -68,7 +68,7 @@ __BEGIN_C_DECLS  /* From C++ preparations */
 
 /* Macros. */
 #define GAL_FITS_MAX_NDIM 999
-
+#define GAL_FITS_KEY_TITLE_START "                      / "
 
 
 



reply via email to

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