gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master b26545f4: Table: --equal can be called on same


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master b26545f4: Table: --equal can be called on same col with diff values separately
Date: Mon, 9 Jun 2025 15:38:52 -0400 (EDT)

branch: master
commit b26545f444a0c3d56f48cdb7932d6c88ed53e399
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Table: --equal can be called on same col with diff values separately
    
    Until now, when Table's '--equal' operator was called multiple times on the
    same column with different values the output will be an empty table (the
    first '--equal' will only keep a certain set of rows that do not match the
    second '--equal'!). This would not happen when the values were given in one
    call to '--equal'. This is contrary to the description of the '--equal' (or
    '--notequal') in the book (which explicitly says that both modes are fine).
    
    With this commit, the problem was solved by redefining an alternative to
    the default parser of '--equal' or '--notequal'. An internal appending
    function also became necessary in 'data.h'.
---
 NEWS                            |  7 ++++++
 bin/table/args.h                |  4 ++--
 doc/gnuastro.texi               | 18 ++++++++++-----
 lib/data.c                      | 49 +++++++++++++++++++++++++++++++++++++++++
 lib/gnuastro-internal/options.h |  5 +++++
 lib/gnuastro/data.h             |  3 +++
 lib/options.c                   | 38 +++++++++++++++++++++++++++-----
 7 files changed, 111 insertions(+), 13 deletions(-)

diff --git a/NEWS b/NEWS
index 57ee20d6..88a66e51 100644
--- a/NEWS
+++ b/NEWS
@@ -106,6 +106,10 @@ See the end of the file for license conditions.
 
 *** Library
 
+  - gal_data_append_second_array_to_first_free: for easily appending
+    (adding the contents of the second array into the first) in
+    single-dimensional datasets.
+
   - gal_statistics_range_double: return the difference between the minimum
     and maximum as a double-precision floating point of a dataset (with any
     type).
@@ -248,6 +252,9 @@ See the end of the file for license conditions.
     command-line and complains with an invalid '-i' option! Reported by
     Sepideh Eskandarlou.
 
+  - bug #67204: Table's --equal operator cannot be called multiple times on
+    same column with different values.
+
 
 
 
diff --git a/bin/table/args.h b/bin/table/args.h
index 22f8510f..b9080052 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -452,7 +452,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      gal_options_parse_name_and_strings
+      gal_options_parse_name_and_strings_append
     },
     {
       "notequal",
@@ -466,7 +466,7 @@ struct argp_option program_options[] =
       GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
-      gal_options_parse_name_and_strings
+      gal_options_parse_name_and_strings_append
     },
     {
       "sort",
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 874be58a..30dd13ea 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -19594,10 +19594,10 @@ This option is very similar to the 
@option{--inpolygon} option, so see the descr
 The polygon to use for the @code{--inpolygon} and @option{--outpolygon} 
options.
 This option is parsed in an identical way to the same option in the Crop 
program, so for more information on how to use it, see @ref{Crop options}.
 
-@item -e STR,INT/FLT,...
-@itemx --equal=STR,INT/FLT,...
-Only output rows that are equal to the given number(s) in the given column.
-The first argument is the column identifier (name or number, see 
@ref{Selecting table columns}), after that you can specify any number of values.
+@item -e STR,INT/FLT/STR,...
+@itemx --equal=STR,INT/FLT/STR,...
+Only output rows that are equal to the given string(s)/number(s) in the given 
column.
+The first value is the column identifier (name or number, see @ref{Selecting 
table columns}), after that you can specify any number of values.
 For the precedence of this operation in relation to others, see @ref{Operation 
precedence in Table}.
 
 For example, @option{--equal=ID,5,6,8} will only print the rows that have a 
value of 5, 6, or 8 in the @code{ID} column.
@@ -21762,14 +21762,16 @@ $ astarithmetic image.fits set-i i i minvalue - sqrt
 Natural logarithm of first operand, so ``@command{4 log}'' is equivalent to 
@mymath{ln(4)}.
 Negative pixels will become NaN, and the output type is determined from the 
input, see the explanation under @command{sqrt} for more on these features.
 For example, the command below will take the natural logarithm of every pixel 
in the input.
+
 @example
 $ astarithmetic image.fits log --output=log.fits
 @end example
 
 @item log10
-Base-10 logarithm of first popped operand, so ``@command{4 log}'' is 
equivalent to @mymath{log_{10}(4)}.
+Base-10 logarithm of first popped operand, so ``@command{4 log10}'' is 
equivalent to @mymath{log_{10}(4)}.
 Negative pixels will become NaN, and the output type is determined from the 
input, see the explanation under @command{sqrt} for more on these features.
 For example, the command below will take the base-10 logarithm of every pixel 
in the input.
+
 @example
 $ astarithmetic image.fits log10
 @end example
@@ -39168,6 +39170,12 @@ Read @code{string} into the smallest type that can 
store the value (see @ref{Num
 This function is just a wrapper for the @code{gal_type_string_to_number}, but 
will put the value into a single-element dataset.
 @end deftypefun
 
+@deftypefun {void} gal_data_append_second_array_to_first_free (gal_data_t 
@code{*a}, gal_data_t @code{*b})
+Append the contents of @code{a->array} and @code{b->array} into an internal 
array, and replace it with @code{a->array}.
+Finally, free @code{b}.
+Both inputs have to have the same type and have to have a single dimension.
+@end deftypefun
+
 
 @node Dimensions, Linked lists, Library data container, Gnuastro library
 @subsection Dimensions (@file{dimension.h})
diff --git a/lib/data.c b/lib/data.c
index d9892c8d..5580aee3 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -949,6 +949,55 @@ gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out)
 
 
 
+/* Append the array of the second input dataset to the first one. */
+void
+gal_data_append_second_array_to_first_free(gal_data_t *a, gal_data_t *b)
+{
+  void *new;
+  size_t i, len;
+  char **strarr;
+
+  /* In case 'b' doesn't have any elements, return (nothing to do!). */
+  if(b && b->size==0) return;
+
+  /* Make sure the two arrays have the same type. */
+  if(a->type!=b->type)
+    error(EXIT_FAILURE, 0, "%s: the two input datasets must have "
+          "the same type. The first has a type of '%s' and the "
+          "second a type of '%s'", __func__,
+          gal_type_name(a->type, 1), gal_type_name(b->type, 1));
+
+  /* Make sure both arrays are one-dimensional (the only supported format
+     here). */
+  if(a->ndim!=1 || b->ndim!=1)
+    error(EXIT_FAILURE, 0, "%s: the two input datasets should only have "
+          "a single dimension. The first and second inputs respectively "
+          "have %zu and %zu dimensions", __func__, a->ndim, b->ndim);
+
+  /* Allocate the new array and copy the contents of the two inputs into
+     it. */
+  len=a->size+b->size;
+  new=gal_pointer_allocate(a->type, len, 0, __func__, "new");
+  memcpy(new, a->array, a->size*gal_type_sizeof(a->type));
+  memcpy(gal_pointer_increment(new, a->size, a->type),
+         b->array, b->size*gal_type_sizeof(b->type));
+
+  /* In case the second input had a string type, set all the contents to
+     'NULL' (so the actual strings are not freed), then free it. */
+  if(b->type==GAL_TYPE_STRING)
+    { strarr=b->array; for(i=0;i<b->size;++i) strarr[i]=NULL; }
+  gal_data_free(b);
+
+  /* Free the first input's array, and replace it with the new one. */
+  a->size=a->dsize[0]=len;
+  free(a->array);
+  a->array=new;
+}
+
+
+
+
+
 /* Just a wrapper around 'gal_type_from_string_auto', to return a
    'gal_data_t' dataset hosting the allocated number. */
 gal_data_t *
diff --git a/lib/gnuastro-internal/options.h b/lib/gnuastro-internal/options.h
index 220b0368..25d95c3e 100644
--- a/lib/gnuastro-internal/options.h
+++ b/lib/gnuastro-internal/options.h
@@ -347,6 +347,11 @@ gal_options_parse_name_and_strings(struct argp_option 
*option, char *arg,
                                    char *filename, size_t lineno,
                                    void *junk);
 
+void *
+gal_options_parse_name_and_strings_append(struct argp_option *option,
+                                          char *arg, char *filename,
+                                          size_t lineno, void *junk);
+
 void *
 gal_options_parse_name_and_float64s(struct argp_option *option, char *arg,
                                     char *filename, size_t lineno,
diff --git a/lib/gnuastro/data.h b/lib/gnuastro/data.h
index a9eeb7c9..dedcf529 100644
--- a/lib/gnuastro/data.h
+++ b/lib/gnuastro/data.h
@@ -293,6 +293,9 @@ gal_data_copy_to_allocated(gal_data_t *in, gal_data_t *out);
 gal_data_t *
 gal_data_copy_string_to_number(char *string);
 
+void
+gal_data_append_second_array_to_first_free(gal_data_t *a, gal_data_t *b);
+
 
 __END_C_DECLS    /* From C++ preparations */
 
diff --git a/lib/options.c b/lib/options.c
index 35567665..ef341a48 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -1650,7 +1650,7 @@ gal_options_read_sigma_clip(struct argp_option *option, 
char *arg,
 static void *
 gal_options_parse_name_and_values(struct argp_option *option, char *arg,
                                   char *filename, size_t lineno, void *junk,
-                                  int str0_f641_sz2)
+                                  int str0_f641_sz2, int append)
 {
   double *darray=NULL;
   size_t i, nc, *sizarr=NULL;
@@ -1745,7 +1745,7 @@ gal_options_parse_name_and_values(struct argp_option 
*option, char *arg,
                 str0_f641_sz2);
         }
 
-      /* If there actually was a string of numbers, add the dataset to the
+      /* If there actually was a string of values, add the dataset to the
          rest. */
       if(dataset)
         {
@@ -1755,8 +1755,21 @@ gal_options_parse_name_and_values(struct argp_option 
*option, char *arg,
           existing = *(gal_data_t **)(option->value);
           if(existing)
             {
+              /* Parse over the existing name/values. */
               for(tmp=existing;tmp!=NULL;tmp=tmp->next)
-                if(tmp->next==NULL) { tmp->next=dataset; break; }
+                {
+                  /* Check if an existing name has already been given. */
+                  if( append && !strcmp(tmp->name, dataset->name) )
+                    {
+                      gal_data_append_second_array_to_first_free(tmp,
+                                                                 dataset);
+                      break;
+                    }
+
+                  /* This is the first time that this name is being
+                     called, add it to the end. */
+                  if(tmp->next==NULL) { tmp->next=dataset; break; }
+                }
             }
           else
             *(gal_data_t **)(option->value) = dataset;
@@ -1792,7 +1805,20 @@ gal_options_parse_name_and_strings(struct argp_option 
*option, char *arg,
                                    void *junk)
 {
   return gal_options_parse_name_and_values(option, arg, filename, lineno,
-                                           junk, 0);
+                                           junk, 0, 0);
+}
+
+
+
+
+
+void *
+gal_options_parse_name_and_strings_append(struct argp_option *option,
+                                          char *arg, char *filename,
+                                          size_t lineno, void *junk)
+{
+  return gal_options_parse_name_and_values(option, arg, filename, lineno,
+                                           junk, 0, 1);
 }
 
 
@@ -1805,7 +1831,7 @@ gal_options_parse_name_and_float64s(struct argp_option 
*option, char *arg,
                                     void *junk)
 {
   return gal_options_parse_name_and_values(option, arg, filename, lineno,
-                                           junk, 1);
+                                           junk, 1, 0);
 }
 
 
@@ -1818,7 +1844,7 @@ gal_options_parse_name_and_sizets(struct argp_option 
*option, char *arg,
                                   void *junk)
 {
   return gal_options_parse_name_and_values(option, arg, filename, lineno,
-                                           junk, 2);
+                                           junk, 2, 0);
 }
 
 



reply via email to

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