[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 804eb22 2/5: Operator in Arithmetic to change
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] 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
first-in-first-out, 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
+ first-in-first-out, 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) during-dev.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 non-detected 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 as-is,
+# 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
- [gnuastro-commits] master updated (edc8c5e -> 21eef31), Mohammad Akhlaghi, 2016/08/26
- [gnuastro-commits] master 376edc9 1/5: Simple conditional operators added to Arithmetic, Mohammad Akhlaghi, 2016/08/26
- [gnuastro-commits] master ffd7f18 3/5: Output type print and checks moved to libraries, Mohammad Akhlaghi, 2016/08/26
- [gnuastro-commits] master 804eb22 2/5: Operator in Arithmetic to change pixel values,
Mohammad Akhlaghi <=
- [gnuastro-commits] master 21eef31 5/5: Letters, not symbols for Arithmetic's conditional operators, Mohammad Akhlaghi, 2016/08/26
- [gnuastro-commits] master 62c3bd2 4/5: Option for Arithmetic's output type, Mohammad Akhlaghi, 2016/08/26