gnuastro-commits
[Top][All Lists]
Advanced

[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



reply via email to

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