[Top][All Lists]

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

[gnuastro-commits] master ee40026f: Library (arithmetic): new isblanknot

From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master ee40026f: Library (arithmetic): new isblanknot operator
Date: Thu, 2 Mar 2023 12:18:19 -0500 (EST)

branch: master
commit ee40026f04e7b586bcc5135a8f7ee28232f9f2c9
Author: Mohammad Akhlaghi <>
Commit: Mohammad Akhlaghi <>

    Library (arithmetic): new isblanknot operator
    Until now, to select non-blank pixels, we would need to use these two
    operators 'isblank not' in sequence. This requires one intermediate array
    to be allocated and is also annoying to type.
    With this commit, the arithmetic library now has the 'isnotblank'
    operator. This will directly check for non-blank pixels without needing an
    intermediate block in memory and is also easier to see write and read in
    the command-line or a script.
    This was suggested by Sepideh Eskandarlou.
 NEWS                      |  2 ++
 doc/gnuastro.texi         | 16 ++++++++++++----
 lib/arithmetic.c          |  8 +++++++-
 lib/blank.c               | 32 ++++++++++++++++++++++++++------
 lib/gnuastro/arithmetic.h |  1 +
 lib/gnuastro/blank.h      |  3 +++
 6 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/NEWS b/NEWS
index 5dc63391..c0dcd2cd 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,8 @@ See the end of the file for license conditions.
    --writeall: Write all datasets on the stack as separate HDUs in the
      output; this is useful in debugging incomplete Arithmetic commands.
    - New operators (also available in Table).
+     - isnotblank: same as 'isblank not', but slightly more efficient.
+       This was suggested by Sepideh Eskandarlou.
      - swap: swap the top two datasets on the stack of operands.
      - index: return dataset of same size, with pixel values that are
        integers starting from 0 and incrementing one by one. This operator
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 5b44afba..60e19c3a 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -17453,7 +17453,7 @@ But you can use @option{--onedasimage} or 
@option{--onedonstdout} to respectivel
 For example, with the command below, the non-blank pixel values of 
@file{cropped.fits} are printed on the command-line (the @option{--quiet} 
option is used to remove the extra information that Arithmetic prints as it 
reads the inputs, its version and its running time).
-$ astarithmetic cropped.fits nonblank --onedonstdout --quiet
+$ astarithmetic cropped.fits noblank --onedonstdout --quiet
 @end example
 @end table
@@ -18009,15 +18009,16 @@ $ astarithmetic image.fits set-i i -100 lt i 200 ge or
 @item not
 Logical NOT: returns 1 when the operand is 0 and 0 when the operand is 
 The operand can be an image or number, for an image, it is applied to each 
pixel separately.
-For example, if you want to know which pixels are not blank, you can use not 
on the output of the @command{isblank} operator described below:
+For example, if you want to know which pixels are not blank (and assuming that 
we didn't have the @code{isnotblank} operator), you can use this @code{not} 
operator on the output of the @command{isblank} operator described below:
 $ astarithmetic image.fits isblank not
 @end example
 @cindex Blank pixel
 @item isblank
-Test for a blank value (see @ref{Blank pixels}).
-In essence, this is very similar to the conditional operators: the output is 
either 1 or 0 (see the `less than' operator above).
+Test each pixel for being a blank value (see @ref{Blank pixels}).
+This is a conditional operator: the output has the same size and dimensions as 
the input, but has an unsigned 8-bit integer type with two possible values: 
either 1 (for a pixel that was blank) or 0 (for a pixel that was not blank).
+See the description of @code{lt} operator above).
 The difference is that it only needs one operand.
 For example:
@@ -18026,6 +18027,13 @@ $ astarithmetic image.fits isblank
 Because of the definition of a blank pixel, a blank value is not even equal to 
itself, so you cannot use the equal operator above to select blank pixels.
 See the ``Blank pixels'' box below for more on Blank pixels in Arithmetic.
+In case you want to set non-blank pixels to an output pixel value of 1, it is 
better to use @code{isnotblank} instead of `@code{isblank not}' (for more, see 
the description of @code{isnotblank}).
+@item isnotblank
+The inverse of the @code{isblank} operator above (see that description for 
+Therefore, if a pixel has a blank value, the output of this operator will have 
a 0 value for it.
+This operator is therefore similar to running `@option{isblank not}', but 
slightly more efficient (won't need the intermediate product of two operators).
 @item where
 Change the input (pixel) value @emph{where}/if a certain condition holds.
 The conditional operators above can be used to define the condition.
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index e2bfb096..66fd9d45 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -3259,6 +3259,8 @@ gal_arithmetic_set_operator(char *string, size_t 
     { op=GAL_ARITHMETIC_OP_NOT;               *num_operands=1;  }
   else if (!strcmp(string, "isblank"))
     { op=GAL_ARITHMETIC_OP_ISBLANK;           *num_operands=1;  }
+  else if (!strcmp(string, "isnotblank"))
+    { op=GAL_ARITHMETIC_OP_ISNOTBLANK;        *num_operands=1;  }
   else if (!strcmp(string, "where"))
     { op=GAL_ARITHMETIC_OP_WHERE;             *num_operands=3;  }
@@ -3373,6 +3375,7 @@ gal_arithmetic_operator_string(int operator)
     case GAL_ARITHMETIC_OP_OR:              return "or";
     case GAL_ARITHMETIC_OP_NOT:             return "not";
     case GAL_ARITHMETIC_OP_ISBLANK:         return "isblank";
+    case GAL_ARITHMETIC_OP_ISNOTBLANK:      return "isnotblank";
     case GAL_ARITHMETIC_OP_WHERE:           return "where";
     case GAL_ARITHMETIC_OP_BITAND:          return "bitand";
@@ -3535,8 +3538,11 @@ gal_arithmetic(int operator, size_t numthreads, int 
flags, ...)
       d1 = va_arg(va, gal_data_t *);
-      out = gal_blank_flag(d1);
+      out = ( operator==GAL_ARITHMETIC_OP_ISBLANK
+              ? gal_blank_flag(d1)
+              : gal_blank_flag_not(d1) );
       if(flags & GAL_ARITHMETIC_FLAG_FREE) gal_data_free(d1);
diff --git a/lib/blank.c b/lib/blank.c
index 411eb767..85f1debe 100644
--- a/lib/blank.c
+++ b/lib/blank.c
@@ -557,13 +557,13 @@ gal_blank_number(gal_data_t *input, int updateflag)
 #define FLAG_BLANK(IT) {                                                \
     IT b, *a=input->array;                                              \
     gal_blank_write(&b, input->type);                                   \
-    if(b==b) /* Blank value can be checked with the equal comparison */ \
-      do { *o = *a==b;  ++a; } while(++o<of);                           \
-    else     /* Blank value will fail with the equal comparison */      \
-      do { *o = *a!=*a; ++a; } while(++o<of);                           \
+    if(b==b) /* Blank value can be checked with the equal. */           \
+      do {*o = blank1_not0 ? *a==b  : *a!=b;  ++a;} while(++o<of);      \
+    else     /* Blank value will fail with the equal comparison. */     \
+      do {*o = blank1_not0 ? *a!=*a : *a==*a; ++a;} while(++o<of);      \
-gal_data_t *
-gal_blank_flag(gal_data_t *input)
+static gal_data_t *
+blank_flag(gal_data_t *input, int blank1_not0)
   uint8_t *o, *of;
   gal_data_t *out;
@@ -639,6 +639,26 @@ gal_blank_flag(gal_data_t *input)
+gal_data_t *
+gal_blank_flag(gal_data_t *input)
+  return blank_flag(input, 1);
+gal_data_t *
+gal_blank_flag_not(gal_data_t *input)
+  return blank_flag(input, 0);
 /* Write a blank value in the input anywhere that the flag dataset is not
    zero or not blank. */
 #define BLANK_FLAG_APPLY(IT) {                                          \
diff --git a/lib/gnuastro/arithmetic.h b/lib/gnuastro/arithmetic.h
index c0122e67..94794131 100644
--- a/lib/gnuastro/arithmetic.h
+++ b/lib/gnuastro/arithmetic.h
@@ -102,6 +102,7 @@ enum gal_arithmetic_operators
   GAL_ARITHMETIC_OP_OR,           /*   ||    */
   GAL_ARITHMETIC_OP_NOT,          /*   !     */
   GAL_ARITHMETIC_OP_ISBLANK,      /* Similar to isnan() for floats. */
+  GAL_ARITHMETIC_OP_ISNOTBLANK,   /* Inverse of 'isblank'. */
   GAL_ARITHMETIC_OP_WHERE,        /*   ?:    */
   GAL_ARITHMETIC_OP_BITAND,       /*   &     */
diff --git a/lib/gnuastro/blank.h b/lib/gnuastro/blank.h
index 90299c6c..89207264 100644
--- a/lib/gnuastro/blank.h
+++ b/lib/gnuastro/blank.h
@@ -128,6 +128,9 @@ gal_blank_number(gal_data_t *input, int updateflag);
 gal_data_t *
 gal_blank_flag(gal_data_t *data);
+gal_data_t *
+gal_blank_flag_not(gal_data_t *input);
 gal_blank_flag_apply(gal_data_t *input, gal_data_t *flag);

reply via email to

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