GNU Astronomy Utilities


Previous: , Up: Library demo programs   [Contents][Index]


10.4.4 Library demo - reading and writing table columns

Tables are some of the most common inputs to, and outputs of programs. This section contains a small program for reading and writing tables using the constructs described in Table input output (table.h). For easy linking/compilation of this program, along with a first run, see Gnuastro’s BuildProgram. Before running, also set the following file and column names in the first two lines of main. The input and output names may be .txt and .fits tables, gal_table_read and gal_table_write will be able to write to both formats. For plain text tables see see Gnuastro text table format.

This example program reads three columns from a table. The first two columns are selected by their name (NAME1 and NAME2) and the third is selected by its number: column 10 (counting from 1). Gnuastro’s column selection is discussed in Selecting table columns. The first and second columns can be any type, but this program will convert them to int32_t and float for its internal usage respectively. However, the third column must be double for this program. So if it isn’t the program will abort with an error. Having the columns in memory, it will print them out along with their sum (just a simple application, you can do what ever you want at this stage). Reading the table finishes here.

The rest of the program is a demonstration of writing a table. While parsing the rows, this program will change the first column (to be counters) and multiply the second by 10 (to the output may be different). Then it will define the order of the output columns by setting the next element (to create a List of gal_data_t). Before writing, this function will also set names for the columns (units and comments can be defined in a similar manner). Writing the columns to a file is then done through a simple call to gal_table_write.

The operations that are shows in this example program are not necessary all the time. For example, in many cases, you know the numerical data type of the column before writing the program (see Numeric data types), so type checking and copying won’t be necessary.

#include <stdio.h>
#include <stdlib.h>

#include <gnuastro/table.h>

int
main(void)
{
  /* File names and column names (which may also be numbers). */
  char *c1_name="NAME1", *c2_name="NAME2", *c3_name="10";
  char *inname="input.fits", *hdu="1", *outname="out.fits";

  /* Internal parameters. */
  float *array2;
  double *array3;
  int32_t *array1;
  size_t i, counter=0;
  gal_data_t *c1, *c2;
  gal_data_t tmp, *col, *columns;
  gal_list_str_t *column_ids=NULL;

  /* Define the columns to read. */
  gal_list_str_add(&column_ids, c1_name, 0);
  gal_list_str_add(&column_ids, c2_name, 0);
  gal_list_str_add(&column_ids, c3_name, 0);

  /* The columns were added in reverse, so correct it. */
  gal_list_str_reverse(&column_ids);

  /* Read the desired columns. */
  columns = gal_table_read(inname, hdu, column_ids,
                           GAL_TABLE_SEARCH_NAME, 1, -1);

  /* Go over the columns, we'll assume that you don't know their type
   * a-priori, so we'll check  */
  counter=1;
  for(col=columns; col!=NULL; col=col->next)
    switch(counter++)
      {
      case 1:              /* First column: we want it as int32_t. */
        c1=gal_data_copy_to_new_type(col, GAL_TYPE_INT32);
        array1 = c1->array;
        break;

      case 2:              /* Second column: we want it as float.  */
        c2=gal_data_copy_to_new_type(col, GAL_TYPE_FLOAT32);
        array2 = c2->array;
        break;

      case 3:              /* Third column: it MUST be double.     */
        if(col->type!=GAL_TYPE_FLOAT64)
          {
            fprintf(stderr, "Column %s must be float64 type, it is "
                    "%s", c3_name, gal_type_name(col->type, 1));
            exit(EXIT_FAILURE);
          }
        array3 = col->array;
        break;
      }

  /* As an example application we'll just print them out. In the
   * meantime (just for a simple demonstration), change the first
   * array value to the counter and multiply the second by 10. */
  for(i=0;i<c1->size;++i)
    {
      printf("%zu: %d + %f + %f = %f\n", i+1, array1[i], array2[i],
             array3[i], array1[i]+array2[i]+array3[i]);
      array1[i]  = i+1;
      array2[i] *= 10;
    }

  /* Link the first two columns as a list. */
  c1->next = c2;
  c2->next = NULL;

  /* Set names for the columns and write them out. */
  c1->name = "COUNTER";
  c2->name = "VALUE";
  gal_table_write(c1, NULL, GAL_TABLE_FORMAT_BFITS, outname, 1);

  /* The names weren't allocated, so to avoid cleaning-up problems,
   * we'll set them to NULL. */
  c1->name = c2->name = NULL;

  /* Clean up and return.  */
  gal_data_free(c1);
  gal_data_free(c2);
  gal_list_data_free(columns);
  gal_list_str_free(column_ids, 0); /* strings weren't allocated. */
  return EXIT_SUCCESS;
}

Previous: , Up: Library demo programs   [Contents][Index]