gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 943d062 2/2: Table: new --head and --tail opti


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 943d062 2/2: Table: new --head and --tail options to only output certain rows
Date: Thu, 9 May 2019 18:24:49 -0400 (EDT)

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

    Table: new --head and --tail options to only output certain rows
    
    The top and bottom of a set of (possibly sorted/selected) columns usually
    has a lot of significance during an analysis, so these two options were
    added to Table to fascilitate this job.
---
 NEWS              |  4 ++++
 bin/table/args.h  | 26 ++++++++++++++++++++++++++
 bin/table/main.h  |  2 ++
 bin/table/table.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 bin/table/ui.c    | 21 +++++++++++++++++++++
 bin/table/ui.h    |  2 ++
 bootstrap.conf    |  1 +
 doc/gnuastro.texi | 19 +++++++++++++++++++
 8 files changed, 126 insertions(+)

diff --git a/NEWS b/NEWS
index 8f16b41..3e67c9a 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,10 @@ See the end of the file for license conditions.
      results hard. These options fix this issue. Please see the example in
      the book under `--sigclip-median' for a nice use case.
 
+  Table:
+   --head: Only output the given number of rows from the top of columns.
+   --tail: Only output the given number of rows from the botoom of columns.
+
 ** Removed features
 
 ** Changed features
diff --git a/bin/table/args.h b/bin/table/args.h
index 4c151d1..76e5478 100644
--- a/bin/table/args.h
+++ b/bin/table/args.h
@@ -116,6 +116,32 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
+    {
+      "head",
+      UI_KEY_HEAD,
+      "INT",
+      0,
+      "Only output given number of top rows.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->head,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+    {
+      "tail",
+      UI_KEY_TAIL,
+      "INT",
+      0,
+      "Only output given number of bottom rows.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->tail,
+      GAL_TYPE_SIZE_T,
+      GAL_OPTIONS_RANGE_GE_0,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
 
 
 
diff --git a/bin/table/main.h b/bin/table/main.h
index f3e4bb7..53d733e 100644
--- a/bin/table/main.h
+++ b/bin/table/main.h
@@ -59,6 +59,8 @@ struct tableparams
   gal_data_t           *range;  /* Range to limit output.               */
   char                  *sort;  /* Column name or number for sorting.   */
   uint8_t          descending;  /* Sort columns in descending order.    */
+  size_t                 head;  /* Output only the no. of top rows.     */
+  size_t                 tail;  /* Output only the no. of bottom rows.  */
 
   /* Internal. */
   gal_data_t           *table;  /* Linked list of output table columns. */
diff --git a/bin/table/table.c b/bin/table/table.c
index af5fd1d..2f4e5e7 100644
--- a/bin/table/table.c
+++ b/bin/table/table.c
@@ -34,6 +34,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <gnuastro/fits.h>
 #include <gnuastro/table.h>
 #include <gnuastro/qsort.h>
+#include <gnuastro/pointer.h>
 #include <gnuastro/arithmetic.h>
 #include <gnuastro/statistics.h>
 #include <gnuastro/permutation.h>
@@ -274,6 +275,52 @@ table_sort(struct tableparams *p)
 
 
 
+static void
+table_head_tail(struct tableparams *p)
+{
+  char **strarr;
+  gal_data_t *col;
+  size_t i, start, end;
+
+  /* Go over all the columns and make the necessary corrections. */
+  for(col=p->table;col!=NULL;col=col->next)
+    {
+      /* If we are dealing with strings, we'll need to free the strings
+         that the columns that will not be used point to (outside the
+         allocated array directly `gal_data_t'). We don't have to worry
+         about the space for the actual pointers (they will be free'd by
+         `free' in any case, since they are in the initially allocated
+         array).*/
+      if(col->type==GAL_TYPE_STRING)
+        {
+          /* Set the start and ending indexs. */
+          start = p->head!=GAL_BLANK_SIZE_T ? p->head        : 0;
+          end   = p->head!=GAL_BLANK_SIZE_T ? p->table->size : p->tail;
+
+          /* Free their allocated spaces. */
+          strarr=col->array;
+          for(i=start; i<end; ++i) { free(strarr[i]); strarr[i]=NULL; }
+        }
+
+      /* For `--tail', we'll need to bring the last columns to the
+         start. Note that we are using `memmove' because we want to be safe
+         with overlap. */
+      if(p->tail!=GAL_BLANK_SIZE_T)
+        memmove(col->array,
+                gal_pointer_increment(col->array, col->size - p->tail,
+                                      col->type),
+                p->tail*gal_type_sizeof(col->type));
+
+      /* In any case (head or tail), the new number of column elements is
+         the given value. */
+      col->size = col->dsize[0] = ( p->head!=GAL_BLANK_SIZE_T
+                                    ? p->head
+                                    : p->tail );
+    }
+}
+
+
+
 /**************************************************************/
 /***************       Top function         *******************/
 /**************************************************************/
@@ -286,6 +333,10 @@ table(struct tableparams *p)
   /* Sort it (if required). */
   if(p->sort) table_sort(p);
 
+  /* If the output number of rows is limited, apply them. */
+  if(p->head!=GAL_BLANK_SIZE_T || p->tail!=GAL_BLANK_SIZE_T)
+    table_head_tail(p);
+
   /* Write the output. */
   gal_table_write(p->table, NULL, p->cp.tableformat, p->cp.output,
                   "TABLE", p->colinfoinstdout);
diff --git a/bin/table/ui.c b/bin/table/ui.c
index 3431f76..8f7a032 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -115,6 +115,10 @@ ui_initialize_options(struct tableparams *p,
   cp->program_authors    = PROGRAM_AUTHORS;
   cp->coptions           = gal_commonopts_options;
 
+  /* Program-specific initialization. */
+  p->head                = GAL_BLANK_SIZE_T;
+  p->tail                = GAL_BLANK_SIZE_T;
+
   /* Modify common options. */
   for(i=0; !gal_options_is_last(&cp->coptions[i]); ++i)
     {
@@ -240,6 +244,11 @@ ui_read_check_only_options(struct tableparams *p)
           error(EXIT_FAILURE, 0, "first value (%g) given to `--range' must "
                 "be smaller than the second (%g)", darr[0], darr[1]);
       }
+
+  /* Make sure `--head' and `--tail' aren't given together. */
+  if(p->head!=GAL_BLANK_SIZE_T && p->tail!=GAL_BLANK_SIZE_T)
+    error(EXIT_FAILURE, 0, "`--head' and `--tail' options cannot be "
+          "called together");
 }
 
 
@@ -816,6 +825,18 @@ ui_preparations(struct tableparams *p)
   gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
 
 
+  /* If the head or tail values are given and are larger than the number of
+     rows, just set them to the number of rows (print the all the final
+     rows). This is how the `head' and `tail' programs of GNU Coreutils
+     operate. */
+  p->head = ( ((p->head!=GAL_BLANK_SIZE_T) && (p->head > p->table->size))
+              ? p->table->size
+              : p->head );
+  p->tail = ( ((p->tail!=GAL_BLANK_SIZE_T) && (p->tail > p->table->size))
+              ? p->table->size
+              : p->tail );
+
+
   /* Clean up. */
   if(rangeindout) free(rangeindout);
 }
diff --git a/bin/table/ui.h b/bin/table/ui.h
index da7fce7..6247fe7 100644
--- a/bin/table/ui.h
+++ b/bin/table/ui.h
@@ -44,6 +44,8 @@ enum option_keys_enum
   UI_KEY_RANGE           = 'r',
   UI_KEY_SORT            = 's',
   UI_KEY_DESCENDING      = 'd',
+  UI_KEY_HEAD            = 'H',
+  UI_KEY_TAIL            = 't',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
diff --git a/bootstrap.conf b/bootstrap.conf
index 8814be2..16a3739 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -223,6 +223,7 @@ gnulib_modules="
     stdint
     strtod
     mktime
+    memmove
     getline
     strcase
     gendocs
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 42812b3..287033a 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -11749,6 +11749,25 @@ column anymore afterwards.
 @itemx --descending
 When called with @option{--sort}, rows will be sorted in descending order.
 
address@hidden -H INT
address@hidden --head=INT
+Only print the given number of rows from the @emph{top} of the final
+table. Note that this option only affects the @emph{output} table. For
+example if you use @option{--sort}, or @option{--range}, the printed rows
+are the first @emph{after} applying the sort sorting, or selecting a range
+of the full input.
+
address@hidden GNU Coreutils
+If the given value to @option{--head} is 0, the output columns won't have
+any rows and if its larger than the number of rows in the input table, all
+the rows are printed (this option is effectively ignored). This behavior is
+taken from the @command{head} program in GNU Coreutils.
+
address@hidden -t INT
address@hidden --tail=INT
+Only print the given number of rows from the @emph{bottom} of the final
+table. See @option{--head} for more.
+
 @end table
 
 



reply via email to

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