gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master e6d7c9a 1/2: gal_label_oversegment now checks


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master e6d7c9a 1/2: gal_label_oversegment now checks for blank values
Date: Sun, 29 Apr 2018 10:25:43 -0400 (EDT)

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

    gal_label_oversegment now checks for blank values
    
    Until now, `gal_label_oversegment' wouldn't check for blank values,
    therefore, if the user hadn't already set the blank value flag, it wouldn't
    put rivers on pixels touching blank values. So a call to
    `gal_blank_present' was added to this function and a single variable is now
    set to see if blank values are present or not (making it easier to read
    than bit-flag checking deep into the loop).
    
    Also, the description in the bit flag `GAL_DATA_FLAG_BLANK_CH' was edited
    to be more clear.
---
 doc/gnuastro.texi | 38 ++++++++++++++++++++++++++++++++------
 lib/label.c       | 51 ++++++++++++++++++++++++++++-----------------------
 2 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index fac52c5..cf67d25 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -21051,11 +21051,18 @@ these flags. The currently recognized bits are stored 
in these macros:
 
 @cindex Blank data
 @item GAL_DATA_FLAG_BLANK_CH
-Marking that the dataset has been checked for blank values. Therefore, the
-value of the bit in @code{GAL_DATA_FLAG_HASBLANK} is reliable. Without
-this bit, when a dataset doesn't have any blank values (and this has been
-checked), the @code{GAL_DATA_FLAG_HASBLANK} bit will be zero so a checker
-has no way to know if this zero is real or if no check has been done yet.
+Marking that the dataset has been checked for blank values or not. When a
+dataset doesn't have any blank values, the @code{GAL_DATA_FLAG_HASBLANK}
+bit will be zero. But upon initialization, all bits also get a value of
+zero. Therefore, a checker needs this flag to see if the value in
address@hidden is reliable (dataset has actually been parsed
+for a blank value) or not.
+
+Also, if it is necessary to re-check the presence of flags, you just have
+to set this flag to zero and call @code{gal_blank_present} for example to
+parse the dataset and check for blank values. Note that for improved
+efficiency, when this flag is set, @code{gal_blank_present} will not
+actually parse the dataset, it will just use @code{GAL_DATA_FLAG_HASBLANK}.
 
 @item GAL_DATA_FLAG_HASBLANK
 This bit has a value of @code{1} when the given dataset has blank
@@ -21066,7 +21073,8 @@ values, so there is no more need for further checks.
 @item GAL_DATA_FLAG_SORT_CH
 Marking that the dataset is already checked for being sorted or not and
 thus that the possible @code{0} values in @code{GAL_DATA_FLAG_SORTED_I} and
address@hidden are meaningful.
address@hidden are meaningful. The logic behind this is
+similar to that in @code{GAL_DATA_FLAG_BLANK_CH}.
 
 @item GAL_DATA_FLAG_SORTED_I
 This bit has a value of @code{1} when the given dataset is sorted in an
@@ -25466,6 +25474,24 @@ must have a @code{GAL_TYPE_INT32} type and be the same 
size as
 @code{values}. All local minima (maxima), when @code{min0_max1} is @code{1}
 (@code{0}), are considered rivers (watersheds) and given a label of
 @code{GAL_LABEL_RIVER} (see above).
+
+Note that rivers/watersheds will also be formed on the edges of the labeled
+regions or when the labeled pixels touch a blank pixel. Therefore this
+function will need to check for the presence of blank values. To be most
+efficient, it is thus recommended to use @code{gal_blank_present} (with
address@hidden) prior to calling this function (see @ref{Library blank
+values}. Once the flag has been set, no other function (including this one)
+that needs special behavior for blank pixels will have to parse the dataset
+any more.
+
+If you are sure your dataset doesn't have blank values (by the design of
+your software), to avoid an extra parsing of the dataset and improve
+performance, you can set the two bits manually (see the description of
address@hidden in @ref{Generic data container}):
address@hidden
+input->flags |=  GAL_DATA_FLAG_BLANK_CH; /* Set bit to 1. */
+input->flags &= ~GAL_DATA_FLAG_HASBLANK; /* Set bit to 0. */
address@hidden example
 @end deftypefun
 
 @deftypefun void gal_label_grow_indexs (gal_data_t @code{*labels}, gal_data_t 
@code{*indexs}, int @code{withrivers}, int @code{connectivity})
diff --git a/lib/label.c b/lib/label.c
index 6e719cb..44f7b54 100644
--- a/lib/label.c
+++ b/lib/label.c
@@ -181,13 +181,13 @@ gal_label_oversegment(gal_data_t *values, gal_data_t 
*indexs,
 {
   size_t ndim=values->ndim;
 
+  int hasblank;
   float *arr=values->array;
   gal_list_sizet_t *Q=NULL, *cleanup=NULL;
   size_t *a, *af, ind, *dsize=values->dsize;
   size_t *dinc=gal_dimension_increment(ndim, dsize);
   int32_t n1, nlab, rlab, curlab=1, *labs=labels->array;
 
-
   /* Sanity checks */
   label_check_type(values, GAL_TYPE_FLOAT32, "values", __func__);
   label_check_type(indexs, GAL_TYPE_SIZE_T,  "indexs", __func__);
@@ -200,6 +200,10 @@ gal_label_oversegment(gal_data_t *values, gal_data_t 
*indexs,
           "%zuD", __func__, indexs->ndim);
 
 
+  /* See if there are blank values in the input dataset. */
+  hasblank=gal_blank_present(values, 0);
+
+
   /*********************************************
    For checks and debugging:*
   gal_data_t *crop;
@@ -328,18 +332,18 @@ gal_label_oversegment(gal_data_t *values, gal_data_t 
*indexs,
                                         ? (n1==nlab ? n1 : GAL_LABEL_RIVER)
                                         : nlab )
 
-                                    /* If the data has blank pixels (recall
-                                       that blank in int32 is negative),
-                                       see if the neighbor is blank and if
-                                       so, set the label to a river. Since
-                                       the flag checking can be done
-                                       outside this loop, for datasets with
-                                       no blank element this last step will
-                                       be completley ignored. */
-                                    : ( ( (values->flag
-                                           & GAL_DATA_FLAG_HASBLANK)
-                                          && nlab==GAL_BLANK_INT32 )
-                                        ? GAL_LABEL_RIVER : n1 ) );
+                                    /* If the data has blank pixels, see if
+                                       the neighbor is blank. If so, set
+                                       the label to a river. Checking for
+                                       the presence of blank values in the
+                                       dataset can be done outside this
+                                       loop (or even outside this function
+                                       if flags are set). So to help the
+                                       compiler optimize the program, we'll
+                                       first use the pre-checked value. */
+                                    : ( ( hasblank && isnan(arr[nind]) )
+                                        ? GAL_LABEL_RIVER
+                                        : n1 ) );
                            }
 
                          /* If this neigbour has a label of zero, then we
@@ -419,16 +423,17 @@ gal_label_oversegment(gal_data_t *values, gal_data_t 
*indexs,
                                     ? ( nlab==n1 ? n1 : GAL_LABEL_RIVER )
                                     : nlab )
 
-                                /* If the dataset has blank values and this
-                                   neighbor is blank, then the pixel should
-                                   be a river. Note that the blank checking
-                                   can be optimized out, so if the input
-                                   doesn't have blank values,
-                                   `nlab==GAL_BLANK_INT32' will never be
-                                   checked. */
-                                : ( (values->flag & GAL_DATA_FLAG_HASBLANK)
-                                    && nlab==GAL_BLANK_INT32
-                                    ? GAL_LABEL_RIVER : n1 ) )
+                                /* If the data has blank pixels, see if the
+                                   neighbor is blank. If so, set the label
+                                   to a river. Checking for the presence of
+                                   blank values in the dataset can be done
+                                   outside this loop (or even outside this
+                                   function if flags are set). So to help
+                                   the compiler optimize the program, we'll
+                                   first use the pre-checked value. */
+                                : ( ( hasblank && isnan(arr[nind]) )
+                                    ? GAL_LABEL_RIVER
+                                    : n1 ) )
 
                             /* `nlab==0' (the neighbor lies in the other
                                domain (sky or detections). To avoid the



reply via email to

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