How to read a file of database entries into a C program

Peter Shawhan
February 25, 2002

Philip Charlton wrote a library of C functions, collectively called "metaio", to parse the contents of a LIGO_LW file containing a table of entries from the LDAS database. This code is included in the libdataflow.a library, which is part of the LIGOtools dataflow package. A program linked to this library typically can parse several thousand table rows per second. There is no comprehensive documentation for the metaio functions, but a few sample programs should be sufficient to demonstrate how to use the software.

A simple example program

/*------------------------------------
 "max_snr.c" -- Scans a LIGO_LW file containing entries from the sngl_inspiral
     table, and reports which entry has the largest signal-to-noise ratio
 Written by Peter Shawhan, 25 Feb 2002
 -------------------------------------*/

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

/*===========================================================================*/
int main( int argc, char **argv )
{
  char *file=NULL;
  int status;
  int snr_col, search_col;
  int nrows, max_snr_row;
  char max_snr_search[256];
  float snr, max_snr;

  /*-- The following lines create the "parsing environment" as well as
    a pointer to it (for convenience) --*/
  struct MetaioParseEnvironment parseEnv;
  const MetaioParseEnv env = &parseEnv;

  /*------ Beginning of code ------*/

  /*-- Make sure there is exactly one argument, the filename --*/
  if ( argc != 2 ) {
    printf( "Usage:  max_snr <file>\n" );
    return 1;
  }

  /*-- Open the file --*/
  file = argv[1];
  status = MetaioOpen( env, file );
  if ( status != 0 ) {
    printf( "Error opening file %s\n", file );
    MetaioClose( env );  return 2;
  }

  /*-- Figure out the column indexes of the "snr" and "search" columns --*/
  /*-- Note: column names are NOT case-sensitive --*/
  snr_col = MetaioFindColumn( env, "snr" );
  search_col = MetaioFindColumn( env, "search" );
  if ( snr_col < 0 || search_col < 0 ) {
    printf( "'snr' and/or 'search' column does not exist\n" );
    MetaioClose(env);  return 1;
  }

  /*------ Loop over rows in the file ------*/

  nrows = 0;
  max_snr = 0.0;
  while ( (status=MetaioGetRow(env)) == 1 ) {
    nrows++;

    /*-- Copy the snr value into a local variable --*/
    snr = env->ligo_lw.table.elt[snr_col].data.real_4;

          /*-- The last component in the line above ("real_4") would be
	    replaced by "int_4s", "real_8", or "lstring.data" for an
	    integer value, a double-precision real value, or a pointer
	    to a null-terminated char array, respectively --*/

    /*-- See if this is the new maximum --*/
    if ( snr > max_snr ) {
      max_snr = snr;
      max_snr_row = nrows;
      /*-- Store the search name --*/
      strcpy( max_snr_search,
	      env->ligo_lw.table.elt[search_col].data.lstring.data );
    }
  }

  if ( status == -1 ) {
    printf( "Parsing error after row %d\n", nrows );
    printf( "%s", env->errmsg.data );
  }

  MetaioClose(env);

  /*------ Print out the result ------*/
  if ( nrows > 1 ) {
    printf( "Processed %d rows\n", nrows );
    printf( "Maximum snr was %f, at row %d (search: %s)\n",
	    max_snr, max_snr_row, max_snr_search );
  }

  return 0;
}

How to compile the example program

gcc max_snr.c $LIGOTOOLS/lib/libdataflow.a -I$LIGOTOOLS/include -o max_snr

Output from the example program

When the file inspiral_events.xml is passed to this program, the output is:
Processed 1000 rows
Maximum snr was 23.543287, at row 387 (search: template)

Other example programs