gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master ab59071: Reusing a name in Arithmetic


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master ab59071: Reusing a name in Arithmetic
Date: Thu, 26 Jul 2018 06:01:59 -0400 (EDT)

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

    Reusing a name in Arithmetic
    
    Until now, if the `set-' operator was given the same name for two datasets,
    it would abort, complaining that the given name is already used. However,
    in some contexts, you don't know the total number of files to read into
    memory, in those cases, it is easier to use the same name many times (while
    freeing the dataset that the name previously pointed to).
    
    With this commit, this is done: if `set-' is given a name of an existing
    dataset, the old dataset will be freed and name will point to the new one.
    
    Also, the functions in `bin/arithmetic/operands.c' were re-organized to be
    easier to read: the operand name functions were separated from the popping
    and adding ones.
---
 bin/arithmetic/operands.c | 128 ++++++++++++++++++++++++++++++----------------
 doc/gnuastro.texi         |  46 +++++++++--------
 2 files changed, 111 insertions(+), 63 deletions(-)

diff --git a/bin/arithmetic/operands.c b/bin/arithmetic/operands.c
index a4914ae..92ebcc4 100644
--- a/bin/arithmetic/operands.c
+++ b/bin/arithmetic/operands.c
@@ -43,7 +43,9 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 
 
-
+/**********************************************************************/
+/************            General info on operands       ***************/
+/**********************************************************************/
 size_t
 operands_num(struct arithmeticparams *p)
 {
@@ -58,6 +60,24 @@ operands_num(struct arithmeticparams *p)
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/************                Named operands             ***************/
+/**********************************************************************/
 static int
 operands_name_is_used_later(struct arithmeticparams *p, char *name)
 {
@@ -77,18 +97,59 @@ operands_name_is_used_later(struct arithmeticparams *p, 
char *name)
 
 
 
+/* Remove a name from the list of names and return the dataset it points
+   to. */
+static gal_data_t *
+operands_remove_name(struct arithmeticparams *p, char *name)
+{
+  gal_data_t *tmp, *removed=NULL, *prev=NULL;
+
+  /* Go over all the given names. */
+  for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
+    {
+      if( !strcmp(tmp->name, name) )
+        {
+          removed=tmp;
+          if(prev) prev->next = tmp->next;
+          else     p->named   = tmp->next;
+        }
+
+      /* Set this node as the `prev' pointer. */
+      prev=tmp;
+    }
+
+  /* A small sanity check. */
+  if(removed==NULL)
+    error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
+          "problem. `removed' must not be NULL at this point", __func__,
+          PACKAGE_BUGREPORT);
+
+  /* Nothing in the list points to it now. So we can safely modify and
+     return it. */
+  free(removed->name);
+  removed->name=NULL;
+  return removed;
+}
+
+
+
+
+
 /* Pop a dataset and keep it in the `named' list for later use. */
 void
 operands_set_name(struct arithmeticparams *p, char *token)
 {
-  gal_data_t *tmp;
+  gal_data_t *tmp, *tofree;
   char *varname=&token[ SET_OPERATOR_PREFIX_LENGTH ];
 
-  /* Make sure the variable name hasn't been set before. */
+  /* If a dataset with this name already exists, it will be removed/deleted
+     so we can use the name for the newly designated dataset. */
   for(tmp=p->named; tmp!=NULL; tmp=tmp->next)
     if( !strcmp(varname, tmp->name) )
-      error(EXIT_FAILURE, 0, "`%s' was previously set as a name",
-            varname);
+      {
+        tofree=operands_remove_name(p, varname);
+        gal_data_free(tofree);
+      }
 
   /* Pop the top operand, then add it to the list of named datasets, but
      only if it is used in later tokens. If it isn't, free the popped
@@ -140,44 +201,6 @@ operands_is_name(struct arithmeticparams *p, char *token)
 
 
 
-/* Remove a name from the list of names and retrun the dataset it points
-   to. */
-static gal_data_t *
-operands_remove_name(struct arithmeticparams *p, char *name)
-{
-  gal_data_t *tmp, *removed=NULL, *prev=NULL;
-
-  /* Go over all the given names. */
-  for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
-    {
-      if( !strcmp(tmp->name, name) )
-        {
-          removed=tmp;
-          if(prev) prev->next = tmp->next;
-          else     p->named   = tmp->next;
-        }
-
-      /* Set this node as the `prev' pointer. */
-      prev=tmp;
-    }
-
-  /* A small sanity check. */
-  if(removed==NULL)
-    error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
-          "problem. `removed' must not be NULL at this point", __func__,
-          PACKAGE_BUGREPORT);
-
-  /* Nothing in the list points to it now. So we can safely modify and
-     return it. */
-  free(removed->name);
-  removed->name=NULL;
-  return removed;
-}
-
-
-
-
-
 /* Return a copy of the named dataset. */
 static gal_data_t *
 operands_copy_named(struct arithmeticparams *p, char *name)
@@ -214,6 +237,25 @@ operands_copy_named(struct arithmeticparams *p, char *name)
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**********************************************************************/
+/************      Adding to and popping from stack     ***************/
+/**********************************************************************/
 void
 operands_add(struct arithmeticparams *p, char *filename, gal_data_t *data)
 {
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 05f37d2..c3ab4fe 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -11814,20 +11814,25 @@ floating point (see @ref{Numeric data types}). The 
internal conversion of C
 will be used.
 
 @item set-AAA
-Set a name (all characters after the dash, @code{AAA} in the case shown
-here) for the first popped operand on the stack. The name can be any
-string, but avoid strings ending with standard filename suffixes (for
-example @file{.fits})@footnote{A dataset name like @file{a.fits} (which can
-be set with @command{set-a.fits}) will cause confusion in the the initial
-parser of Arithmetic. It will assume this name is a FITS file, and if it is
-used multiple times, Arithmetic will abort, complaining that you haven't
-provided enough HDUs.}. The named dataset will be freed from memory as soon
-as it is no longer needed in the rest of the command. This operator thus
+Set the characters after the dash (@code{AAA} in the case shown here) as a
+name for the first popped operand on the stack. The named dataset will be
+freed from memory as soon as it is no longer needed, or if the name is
+reset to refer to another dataset later in the command. This operator thus
 enables re-usability of a dataset without having to re-read it from a file
-everytime its necessary during a process.
+everytime it is necessary during a process. When a dataset is necessary
+more than once, this operator can thus help simplify reading/writing on the
+command-line (thus avoiding potential bugs), while also speeding up the
+processing.
+
+Like all operators, this operator pops the top operand off of the main
+processing stack, but unlike other operands, it won't add anything back to
+the stack immediately. It will keep the popped dataset in memory through a
+separate list of named datasets (not on the main stack). That list will be
+used to add/copy any requested dataset to the main processing stack when
+the name is called.
 
 The name to give the popped dataset is part of the operator's name. For
-example the @code{set-a} operator of the command below, gives the name of
+example the @code{set-a} operator of the command below, gives the name
 address@hidden'' to the contents of @file{image.fits}. This name is then used
 instead of the actual filename to multiply the dataset by two.
 
@@ -11835,30 +11840,31 @@ instead of the actual filename to multiply the 
dataset by two.
 $ astarithmetic image.fits set-a a 2 x
 @end example
 
-This is a unique operator, because it doesn't actually do anything to the
-contents of the popped dataset, it just assigns a name to the dataset. This
-makes it very easy to use a single dataset on the command-line multiple
-times and avoid extra attempts at reading it into memory.
+The name can be any string, but avoid strings ending with standard filename
+suffixes (for example @file{.fits})@footnote{A dataset name like
address@hidden (which can be set with @command{set-a.fits}) will cause
+confusion in the the initial parser of Arithmetic. It will assume this name
+is a FITS file, and if it is used multiple times, Arithmetic will abort,
+complaining that you haven't provided enough HDUs.}.
 
 One example of the usefulness of this operator is in the @code{where}
 operator. For example, let's assume you want to mask all pixels larger than
 @code{5} in @file{image.fits} (extension number 1) with a NaN
-value. Without using this operator, you have to run
+value. Without setting a name for the dataset, you have to read the file
+two times from memory in a command like this:
 
 @example
 $ astarithmetic image.fits image.fits 5 gt nan where -g1
 @end example
 
 But with this operator you can simply give @file{image.fits} the name
address@hidden and simplify the command above:
address@hidden and simplify the command above to the more readable one below
+(which greatly helps when the filename is long):
 
 @example
 $ astarithmetic image.fits set-i   i i 5 gt nan where
 @end example
 
-This operator can thus help simplify reading/writing on the command-line
-(avoid potential bugs), while also speeding up your processing.
-
 @end table
 
 @cartouche



reply via email to

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