[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastrocommits] master 804eb22 2/5: Operator in Arithmetic to change
From: 
Mohammad Akhlaghi 
Subject: 
[gnuastrocommits] master 804eb22 2/5: Operator in Arithmetic to change pixel values 
Date: 
Fri, 26 Aug 2016 17:37:28 +0000 (UTC) 
branch: master
commit 804eb22309d36ec1ff392e31508233432bd63f32
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
Operator in Arithmetic to change pixel values
Arithmetic now has a new `where' operator which will allow the users to
change specific pixels in an image, either to another image's values, or a
single number. A test has also been added and the book also contains an
explanation.

doc/gnuastro.texi  22 +++++++++++++
src/arithmetic/args.h  13 ++
src/arithmetic/arithmetic.c  72 ++++++++++++++++++++++++++++++++++
tests/Makefile.am  4 ++
tests/arithmetic/where.sh  51 ++++++++++++++++++++++++++++++
5 files changed, 135 insertions(+), 27 deletions()
diff git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 78ebd2d..17ce0cb 100644
 a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ 6983,6 +6983,28 @@ first.
Larger or equal: similar to the @code{<} (smaller than operator), but
returning 1 when the second popped operand is larger or equal to the first.
address@hidden 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:
+
address@hidden
+$ astarithmetic a.fits 100 > b.fits c.fits where
address@hidden 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
@cartouche
diff git a/src/arithmetic/args.h b/src/arithmetic/args.h
index bec5af0..efd87f1 100644
 a/src/arithmetic/args.h
+++ b/src/arithmetic/args.h
@@ 157,17 +157,8 @@ parse_opt(int key, char *arg, struct argp_state *state)
here: */
state>child_inputs[0]=&p>cp;
 /* In case the user incorrectly uses the equal sign (for example
 with a short format or with space in the long format, then `arg`
 start with (if the short version was called) or be (if the long
 version was called with a space) the equal sign. So, here we
 check if the first character of arg is the equal sign, then the
 user is warned and the program is stopped: */
 if(arg && arg[0]=='=')
 argp_error(state, "incorrect use of the equal sign (`=`). For short "
 "options, `=` should not be used and for long options, "
 "there should be no space between the option, equal sign "
 "and value");
+ /* There is no check for the equal character here because in
+ Arithmetic, the equal sign can be an argument. */
switch(key)
{
diff git a/src/arithmetic/arithmetic.c b/src/arithmetic/arithmetic.c
index 31e7bfc..6e5f589 100644
 a/src/arithmetic/arithmetic.c
+++ b/src/arithmetic/arithmetic.c
@@ 109,20 +109,6 @@ pop_operand(struct imgarithparams *p, double *number,
double **array,
operator);
 /* Do a sanity check. The basic idea behind this is that all the
 conditionals below will evaluate to 1 or 0. So if more than one
 of them are true, then the sum will be larger than 1 and if none
 of them are true then the sum will be 0. So if the sum (check) is
 not equal to 1, then there is a bug and the user should be
 warned. The parenthesis will help in avoiding compiler
 warnings.*/
 if( (strlen(operands>filename)>0) + !(isnan(operands>number))
 + (operands>array!=NOOPTARRAY) != 1)
 error(EXIT_FAILURE, 0, "a bug! Please contact us at %s so we can fix the "
 "problem. For some reason, one node in the operands linked list "
 "has more than one value", PACKAGE_BUGREPORT);


/* Set the array output. If filename is present then read the file
and fill in the array, if not then just set the array. */
if(strlen(operands>filename))
@@ 820,7 +806,7 @@ conditionals(struct imgarithparams *p, char *operator)
input. Also note that since the linked list is
firstinfirstout, the second operand should be put first
here. */
 ff=(f=farr)+size;
+ f=farr;
ss=(s=sarr)+size;
do *s = thisfunction(*s, *f++); while(++s<ss);
@@ 850,6 +836,61 @@ conditionals(struct imgarithparams *p, char *operator)
+/* Replace the pixels in the second popped element with the first. While
+ choosing the pixels that are selected from the third The third popped
+ element. The third is considered to be an array that can only be filled
+ with 0 or 1. */
+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. */
+
+ /* 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");
+
+ /* 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
+ pop_operand for the first image. */
+ size=p>s0*p>s1;
+
+ /* Do the operation: */
+ if(sarr && tarr) /* 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)
+ {
+ f=farr;
+ do *s = *t++ ? *f++ : *s; while(++s<ss);
+ }
+ else
+ do *s = *t++ ? fnum : *s; while(++s<ss);
+
+ /* Push the output onto the stack. */
+ add_operand(p, NOOPTFILENAME, NOOPTNUMBER, sarr);
+
+ /* Clean up. */
+ free(farr);
+ free(tarr);
+ }
+ else
+ error(EXIT_FAILURE, 0, "the first and second arguments (second and "
+ "third popped elements) to `where' have to be arrays.");
+}
+
+
+
+
+
@@ 917,6 +958,7 @@ reversepolish(struct imgarithparams *p)
 !strcmp(token>v, "==")
 !strcmp(token>v, "<=")
 !strcmp(token>v, ">=")) conditionals(p, token>v);
+ else if(!strcmp(token>v, "where")) where(p);
else
error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
"interpretted as an operator", token>v);
diff git a/tests/Makefile.am b/tests/Makefile.am
index 7008c4b..b7793c6 100644
 a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ 42,7 +42,8 @@ mkprof/ellipticalmasks.sh mkprof/inputascanvas.sh
header/write.sh \
header/print.sh header/update.sh header/delete.sh imgstat/basicstats.sh \
subtractsky/subtractsky.sh noisechisel/noisechisel.sh mkcatalog/simple.sh \
mkcatalog/aperturephot.sh arithmetic/snimage.sh arithmetic/onlynumbers.sh \
cosmiccal/simpletest.sh table/asciitobinary.sh table/binarytoascii.sh
+arithmetic/where.sh cosmiccal/simpletest.sh table/asciitobinary.sh \
+table/binarytoascii.sh
EXTRA_DIST = $(TESTS) duringdev.sh mkprof/mkprofcat1.txt \
mkprof/ellipticalmasks.txt mkprof/inputascanvas.txt mkprof/mkprofcat2.txt \
@@ 117,5 +118,6 @@ mkcatalog/simple.sh: noisechisel/noisechisel.sh.log
mkcatalog/aperturephot.sh: noisechisel/noisechisel.sh.log \
mkprof/inputascanvas.sh
arithmetic/snimage.sh: noisechisel/noisechisel.sh.log
+arithmetic/where.sh: noisechisel/noisechisel.sh.log
arithmetic/onlynumbers.sh: prepconf.sh.log
cosmiccal/simpletest.sh: prepconf.sh.log
diff git a/tests/arithmetic/where.sh b/tests/arithmetic/where.sh
new file mode 100755
index 0000000..93b3401
 /dev/null
+++ b/tests/arithmetic/where.sh
@@ 0,0 +1,51 @@
+# Mask nondetected pixels in the image with the `where' operator.
+#
+# See the Tests subsection of the manual for a complete explanation
+# (in the Installing gnuastro section).
+#
+# Original author:
+# Mohammad Akhlaghi <address@hidden>
+# Contributing author(s):
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved. This file is offered asis,
+# without any warranty.
+
+
+
+
+
+# Preliminaries
+# =============
+#
+# Set the variabels (The executable is in the build tree). Do the
+# basic checks to see if the executable is made or if the defaults
+# file exists (basicchecks.sh is in the source tree).
+prog=arithmetic
+execname=../src/$prog/ast$prog
+img=convolve_spatial_noised_labeled.fits
+
+
+
+
+
+# Skip?
+# =====
+#
+# If the dependencies of the test don't exist, then skip it. There are two
+# types of dependencies:
+#
+#  The executable was not made (for example due to a configure option),
+#
+#  The input data was not made (for example the test that created the
+# data file failed).
+if [ ! f $execname ]  [ ! f $img ]; then exit 77; fi
+
+
+
+
+
+# Actual test script
+# ==================
+$execname $img 0 == $img nan where h1 h0 output=where.fits
 [gnuastrocommits] master updated (edc8c5e > 21eef31), Mohammad Akhlaghi, 2016/08/26
 [gnuastrocommits] master 376edc9 1/5: Simple conditional operators added to Arithmetic, Mohammad Akhlaghi, 2016/08/26
 [gnuastrocommits] master ffd7f18 3/5: Output type print and checks moved to libraries, Mohammad Akhlaghi, 2016/08/26
 [gnuastrocommits] master 804eb22 2/5: Operator in Arithmetic to change pixel values,
Mohammad Akhlaghi <=
 [gnuastrocommits] master 21eef31 5/5: Letters, not symbols for Arithmetic's conditional operators, Mohammad Akhlaghi, 2016/08/26
 [gnuastrocommits] master 62c3bd2 4/5: Option for Arithmetic's output type, Mohammad Akhlaghi, 2016/08/26