[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