[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastrocommits] master 6b7e5d7 1/4: Order of input and conditional in
From: 
Mohammad Akhlaghi 
Subject: 
[gnuastrocommits] 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/valuechanges 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
Arithmetic.

doc/gnuastro.texi  32 +++++++++++++++
src/arithmetic/arithmetic.c  45 +++++++++++++++++++++
tests/arithmetic/where.sh  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
example:
+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:
address@hidden
+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 nonzero 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
+below:
@example
$ 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)
size=p>s0*p>s1;
/* 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
 firstinfirstout, 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);
else
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/where.sh b/tests/arithmetic/where.sh
index f4c371e..8e4ff84 100755
 a/tests/arithmetic/where.sh
+++ b/tests/arithmetic/where.sh
@@ 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