[Top][All Lists]

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

[gnuastro-commits] master 6b7e5d7 1/4: Order of input and conditional in

From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 6b7e5d7 1/4: Order of input and conditional in -where- changed
Date: Wed, 7 Sep 2016 17:07:04 +0000 (UTC)

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

    Order of input and conditional in -where- changed
    Until now, Arithmetic's `where' operator would consider the third popped
    operand to be the condition, and the second to be the array whose values
    need to be changed. The problem with that initial ordering was that due to
    the nature of our current very basic (single stack with no variables)
    implementation of the reverse polish notation, it was very hard to do
    several checks/value-changes with one command.
    With this commit, the third popped operand is the input image and the
    second is the comparison image. So it is possible to read the input image
    once, and apply any number of `where' operators to it in one run of
 doc/gnuastro.texi           |   32 +++++++++++++++---------------
 src/arithmetic/arithmetic.c |   45 +++++++++++++++++++++----------------------
 tests/arithmetic/   |    2 +-
 3 files changed, 39 insertions(+), 40 deletions(-)

diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 2a50766..975bb5a 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -6999,26 +6999,26 @@ blank pixels. See the ``Blank pixels'' box below for 
more on Blank pixels
 in Arithmetic.
 @item where
-Change the pixel values `where' a certain condition holds. The conditional
-operators above can be used to define the condition. This operator requires
-three operands, for example, @command{a.fits b.fits c.fits where} will
-result in pixels from @file{b.fits}, where @file{a.fits} has true
-(@mymath{=1}) values, to be replaced by the respective pixels in
address@hidden The first popped operand (@file{c.fits} in this example, can
-also be a number, but the second and third have to be images.
-Commonly you won't be dealing with conditional images (that only have pixel
-values of 0 or 1) directly. You will mostly use them internally, for
+Change the input (pixel) value `where' a certain condition holds. The
+conditional operators above can be used to define the condition. Three
+operands are required for @command{where}, with the format of:
+astarithmetic in.fits condition.fits new.fits where
address@hidden example
+The first two operands above have to be images or all three operands have
+to be numbers. In the former case (when the first two are images), the
+third operand can be an image or a number. The value of any pixel in
address@hidden that corresponds to a non-zero pixel of
address@hidden will be changed to the value of the same pixel in
address@hidden Commonly you won't be dealing with an actual FITS file of
+a conditional image. You will probably actually define the condition in the
+same run or Arithmetic based on some other reference. For example the case
-$ astarithmetic a.fits 100 gt b.fits c.fits where
+$ astarithmetic in.fits reference.fits 100 gt new.fits where
 @end example
-will be read as: Make a conditional image where all the pixels of
address@hidden that have a value larger than 100 get values of 1, the rest
-0. Any pixel in @file{b.fits} with a corresponding conditional image pixel
-of 1, will be replaced by the corresponding pixel in @file{c.fits}.
 @end table
diff --git a/src/arithmetic/arithmetic.c b/src/arithmetic/arithmetic.c
index 8311db2..a5255fd 100644
--- a/src/arithmetic/arithmetic.c
+++ b/src/arithmetic/arithmetic.c
@@ -885,14 +885,14 @@ void
 where(struct imgarithparams *p)
   size_t size;
-  double *f, *s, *t, *ss;
-  double fnum, snum, tnum;      /* First, second, or third number.    */
-  double *farr, *sarr, *tarr;   /* First, second, or third array.     */
+  double *n, *c, *i, *ii;
+  double nnum, cnum, inum;      /* First, second, or third number.    */
+  double *narr, *carr, *iarr;   /* First, second, or third array.     */
-  /* Pop out the number of operands needed. */
-  pop_operand(p, &fnum, &farr, "where");
-  pop_operand(p, &snum, &sarr, "where");
-  pop_operand(p, &tnum, &tarr, "where");
+  /* ORDER IS VERY IMPORTANT HERE. Pop out the number of operands needed. */
+  pop_operand(p, &nnum, &narr, "where");              /* New value. */
+  pop_operand(p, &cnum, &carr, "where");              /* Condition. */
+  pop_operand(p, &inum, &iarr, "where");              /* Input.     */
   /* Set the total number of pixels, note that we can't do this in the
      definition of the variable because p->s0 and p->s1 will be set in
@@ -900,35 +900,34 @@ where(struct imgarithparams *p)
   /* Do the operation: */
-  if(sarr && tarr)              /* Both are arrays. */
+  if(iarr && carr)              /* Both are arrays. */
-      /* Do the operation, note that the output is stored in the first
-         input. Also note that since the linked list is
-         first-in-first-out, the second operand should be put first
-         here. */
-      t=tarr;
-      ss=(s=sarr)+size;
-      if(farr)
+      c=carr;
+      ii=(i=iarr)+size;
+      if(narr)                  /* `new' is an array, not number. */
-          f=farr;
+          n=narr;
           /* Note that we need to increment "f" after the check and
              replace. If the increment is inside the conditional replace,
              then when t==0, the increment won't work.*/
-          do {*s = *t++ ? *f : *s; ++f;} while(++s<ss);
+          do {*i = *c++ ? *n : *i; ++n;} while(++i<ii);
-      else
-        do *s = *t++ ? fnum : *s; while(++s<ss);
+      else                      /* `new' is a number, not array. */
+        do *i = *c++ ? nnum : *i; while(++i<ii);
       /* Push the output onto the stack. */
-      add_operand(p, NOOPTFILENAME, NOOPTNUMBER, sarr);
+      add_operand(p, NOOPTFILENAME, NOOPTNUMBER, iarr);
       /* Clean up. */
-      free(farr);
-      free(tarr);
+      free(carr);
+      free(narr);
+  else if ( iarr==NULL && carr==NULL && narr==NULL )
+    add_operand(p, NOOPTFILENAME, cnum ? nnum : inum, NOOPTARRAY);
     error(EXIT_FAILURE, 0, "the first and second arguments (second and "
-          "third popped elements) to `where' have to be arrays.");
+          "third popped elements) to `where' have to be arrays, or all have "
+          "to be numbers.");
diff --git a/tests/arithmetic/ b/tests/arithmetic/
index f4c371e..8e4ff84 100755
--- a/tests/arithmetic/
+++ b/tests/arithmetic/
@@ -48,4 +48,4 @@ if [ ! -f $execname ] || [ ! -f $img ]; then exit 77; fi
 # Actual test script
 # ==================
-$execname $img 0 eq $img nan where -h1 -h0 --output=where.fits
+$execname $img $img 0 eq nan where -h0 -h1 --output=where.fits

reply via email to

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