gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 40eb202: Arithmetic's where operator checks fo


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 40eb202: Arithmetic's where operator checks for blank values
Date: Mon, 23 Jul 2018 14:24:13 -0400 (EDT)

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

    Arithmetic's where operator checks for blank values
    
    When the condition operand of the `where' operator has blank values, this
    operator assumed they are true. With this commit, a check is done on the
    condition operand and only when it is not blank *and* non-zero will the
    value be modified.
    
    This bug was reported by Dmitry Oparin.
    
    This fixes bug #54358.
---
 NEWS              |  2 ++
 doc/gnuastro.texi | 12 ++++++------
 lib/arithmetic.c  | 40 +++++++++++++++++++++++-----------------
 3 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/NEWS b/NEWS
index a0c9680..d4edc7f 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,8 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
   bug #54298: Table not writing array when there are no rows.
   bug #54312: Crash when CFITSIO doesn't have fits_is_reentrant function.
   bug #54346: Non '-I' or non '-L' strings in CPPFLAGS or LDFLAGS cause crash.
+  bug #54358: Arithmetic's where, not ignoring blank values in condition.
+
 
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index aeaedaf..05f37d2 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -11681,12 +11681,12 @@ $ astarithmetic modify.fits binary.fits if-true.fits 
where
 @end example
 
 The value of any pixel in @file{modify.fits} that corresponds to a non-zero
-pixel of @file{binary.fits} will be changed to the value of the same pixel
-in @file{if-true.fits} (this may also be a number). The 3rd and 2nd popped
-operands (@file{modify.fits} and @file{binary.fits} respectively, see
address@hidden polish notation}) have to have the same
-dimensions/size. @file{if-true.fits} can be either a number, or have the
-same dimension/size as the other two.
address@hidden non-blank pixel of @file{binary.fits} will be changed to the
+value of the same pixel in @file{if-true.fits} (this may also be a
+number). The 3rd and 2nd popped operands (@file{modify.fits} and
address@hidden respectively, see @ref{Reverse polish notation}) have to
+have the same dimensions/size. @file{if-true.fits} can be either a number,
+or have the same dimension/size as the other two.
 
 The 2nd popped operand (@file{binary.fits}) has to have @code{uint8} (or
 @code{unsigned char} in standard C) type (see @ref{Numeric data types}). It
diff --git a/lib/arithmetic.c b/lib/arithmetic.c
index 3e84f95..d2b0f3b 100644
--- a/lib/arithmetic.c
+++ b/lib/arithmetic.c
@@ -494,25 +494,27 @@ arithmetic_from_statistics(int operator, int flags, 
gal_data_t *input)
 /***********************************************************************/
 /***************                  Where                   **************/
 /***********************************************************************/
-
 /* When the `iftrue' dataset only has one element and the element is blank,
    then it will be replaced with the blank value of the type of the output
    data. */
-#define DO_WHERE_OPERATION(ITT, OT) {                                \
-    ITT *it=iftrue->array;                                           \
-    OT b, *o=out->array, *of=o+out->size;                            \
-    if(iftrue->size==1)                                              \
-      {                                                              \
-        if( gal_blank_present(iftrue, 0) )                           \
-          {                                                          \
-            gal_blank_write(&b, out->type);                          \
-            do { *o = *c++ ? b : *o;        } while(++o<of);         \
-          }                                                          \
-        else                                                         \
-          do   { *o = *c++ ? *it : *o;       } while(++o<of);        \
-      }                                                              \
-    else                                                             \
-      do       { *o = *c++ ? *it : *o; ++it; } while(++o<of);        \
+#define DO_WHERE_OPERATION(ITT, OT) {                                   \
+    ITT *it=iftrue->array;                                              \
+    OT b, *o=out->array, *of=o+out->size;                               \
+    gal_blank_write(&b, out->type);                                     \
+    if(iftrue->size==1)                                                 \
+      {                                                                 \
+        if( gal_blank_is(it, iftrue->type) )                            \
+          {                                                             \
+            do{*o = (chb && *c==cb) ? *o : (*c ? b   : *o); ++c;      } \
+            while(++o<of);                                              \
+          }                                                             \
+        else                                                            \
+          do  {*o = (chb && *c==cb) ? *o : (*c ? *it : *o); ++c;      } \
+          while(++o<of);                                                \
+      }                                                                 \
+    else                                                                \
+      do      {*o = (chb && *c==cb) ? *o : (*c ? *it : *o); ++it; ++c;} \
+      while(++o<of);                                                    \
 }
 
 
@@ -545,7 +547,8 @@ static void
 arithmetic_where(int flags, gal_data_t *out, gal_data_t *cond,
                  gal_data_t *iftrue)
 {
-  unsigned char *c=cond->array;
+  int chb;    /* Read as: "Condition-Has-Blank" */
+  unsigned char *c=cond->array, cb=GAL_BLANK_UINT8;
 
   /* The condition operator has to be unsigned char. */
   if(cond->type!=GAL_TYPE_UINT8)
@@ -559,6 +562,9 @@ arithmetic_where(int flags, gal_data_t *out, gal_data_t 
*cond,
     error(EXIT_FAILURE, 0, "%s: the output and condition data sets of the "
           "must be the same size", __func__);
 
+  /* See if the condition array has blank values. */
+  chb=gal_blank_present(cond, 0);
+
   /* Do the operation. */
   switch(out->type)
     {



reply via email to

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