int main( int argc, char *argv[] )
{
  static LALStatus status;
  UINT4 loop = 0; /* loop counter */
  Math3DPointList *list = NULL;    /* structure for mathematica plot */
  Math3DPointList *first = NULL;
  SnglInspiralTable *bankHead = NULL;
  SnglInspiralTable *tmplt = NULL;
  InspiralCoarseBankIn coarseIn;
  INT4 ntiles = 0;                 /* number of tiles */
  INT2 Math3DPlot = 0;             /* option flag for Mathematica plot */
  INT4 opt = 0;                    /* returning value of LALgetopt() */
  INT4 optflag = -1;               /* Command Line option */
  REAL8Vector *psd = NULL;
  REAL8 df = 1.0;
  InspiralTemplate inspiralTemplate;
  REAL4 noiseMin = 1;
  BOOLEAN haveXML = 0;


  if( (list = (Math3DPointList *) LALCalloc( 1, sizeof( Math3DPointList )))
      == NULL )
  {
    LALError( &status, INSPIRALSPINBANKTESTC_MSGEMEM );
    printf( INSPIRALSPINBANKTESTC_MSGEMEM );
    return INSPIRALSPINBANKTESTC_EMEM;
  }

  first = list;

  /* Stuff for calculating the PSD and Noise Moments */
  coarseIn.fLower = inspiralTemplate.fLower = 30;
  coarseIn.fUpper = inspiralTemplate.fCutoff = 2000;
  coarseIn.iflso = 0;

 /* Parse options. */
  do
  {
    optflag++;
    switch (opt)
    {
      case 'b':
#if LAL_METAIO_ENABLED
	if( (ntiles = LALSnglInspiralTableFromLIGOLw( &bankHead, LALoptarg, 1,
            20000)) < 1 )
        {
          fprintf( stderr, INSPIRALSPINBANKTESTC_MSGEFILE );
          return INSPIRALSPINBANKTESTC_EFILE;
        }
        haveXML = 1;
#endif
        break;
      case 'm':
        coarseIn.mmCoarse = atof( LALoptarg );
        break;
      case 'n':
        coarseIn.mMin = atof( LALoptarg );
        break;
      case 'p':
        Math3DPlot = 1;
        break;
      case 's':
        break;
      case 'x':
        coarseIn.MMax = atof( LALoptarg );
        break;
      default:
        coarseIn.mmCoarse = 0.1;
        coarseIn.mMin = 1.0;
        coarseIn.MMax = 2*3.0;
        Math3DPlot = 0;
        break;
    }
  }
  while( (opt = LALgetopt( argc, argv, "b:n:m:x:ps" )) != -1 );

  /* Generate template bank from model noise if not given an XML file. */
  if( !haveXML )
  {
    coarseIn.shf.data = NULL;
    memset( &(coarseIn.shf), 0, sizeof( REAL8FrequencySeries ) );
    coarseIn.shf.f0 = 0;
    LALDCreateVector( &status, &psd, coarseIn.fUpper );
    df = 1.0;
    LALNoiseSpectralDensity( &status, psd, &LALLIGOIPsd, df );
    coarseIn.shf.data = psd;
    coarseIn.shf.deltaF = df;
    for( loop = 0; loop < psd->length; loop++ )
    {
      if( psd->data[loop] > 0 && psd->data[loop] < noiseMin )
      {
        noiseMin = psd->data[loop];
      }
    }
    LALInspiralSpinBank( &status, &bankHead, &ntiles, &coarseIn );
    if( status.statusCode )
    {
      LALError( &status, INSPIRALSPINBANKTESTC_MSGESUB );
      printf( INSPIRALSPINBANKTESTC_MSGESUB );
      return INSPIRALSPINBANKTESTC_ESUB;
    }
  }

  /* Convert template bank structure to plot input structure. */
  if( Math3DPlot )
  {
    for( tmplt = bankHead; tmplt != NULL; tmplt = tmplt->next )
    {
      list->x = tmplt->psi0;
      list->y = tmplt->psi3;
      list->z = tmplt->beta;
      list->grayLevel = 1.0*loop/ntiles;
      if( (list = list->next = (Math3DPointList *) LALCalloc( 1, sizeof(
          Math3DPointList ))) == NULL ) {
        LALError( &status, INSPIRALSPINBANKTESTC_MSGEMEM );
        printf( INSPIRALSPINBANKTESTC_MSGEMEM );
        return INSPIRALSPINBANKTESTC_EMEM;
      }
    }
    list->next = NULL;
    LALMath3DPlot( &status, first, &ntiles, NULL );
    if( status.statusCode )
    {
      LALError( &status, INSPIRALSPINBANKTESTC_MSGESUB );
      printf( INSPIRALSPINBANKTESTC_MSGESUB );
      return INSPIRALSPINBANKTESTC_ESUB;
    }

    /* Clean Up the memory from the MathPlot3D structure */
    list = first;
    while( list->next )
    {
      first = list->next;
      LALFree( list );
      list = first;
    }
  }

  /* free the last (first?) memory allocated for Math3DPlot. */
  LALFree( list );

  if (status.statusCode)
    return INSPIRALSPINBANKTESTC_ESUB;
  else
    return INSPIRALSPINBANKTESTC_ENORM;
}
Exemple #2
0
int main( int argc, char *argv[] )
{
  /* lal initialization variables */
  LALStatus stat = blank_status;

  /* Argument pointers */
  CHAR *inFile = NULL;
  CHAR *vetoFile = NULL;
  CHAR *outFile = NULL;

  /* Program operation variables */
  LALSegList vetoSegs;
  SnglInspiralTable *events = NULL;
  INT4 numEvents = 0;
  INT4 numEventsKept = 0;
  SnglInspiralTable    *eventHead = NULL;
  SnglInspiralTable    *thisEvent = NULL;
  SnglInspiralTable    *tmpEvent = NULL;
  SnglInspiralTable    *prevEvent = NULL;

  LIGOLwXMLStream       xmlStream;
  MetadataTable         outputTable;

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

  /*-- Check command-line arguments --*/
  if ( argc != 4 ) {
    printf( USAGE );
    exit( 0 );
  }
  inFile = argv[1];
  vetoFile = argv[2];
  outFile = argv[3];

  /* set up inital debugging values */
  lal_errhandler = LAL_ERR_EXIT;


  /*-- Initialize the veto segment list, and read the veto file --*/

  XLALSegListInit( &vetoSegs );
  LAL_CALL( LALSegListRead( &stat, &vetoSegs, vetoFile, "" ), &stat );
  /*-- Make sure the list of veto segments is coalesced for fast searching --*/
  XLALSegListCoalesce( &vetoSegs );


  /*-- Read the inspiral events from the file --*/

  numEvents = LALSnglInspiralTableFromLIGOLw( &events, inFile, 0, -1 );
  if ( numEvents < 0 ) {
    fprintf( stderr, "error: unable to read sngl_inspiral table from %s\n", 
             inFile );
    exit( 1 );
  }

  /*-- Report the number of events read in --*/
  printf( "Read %d events from input file\n", numEvents );


  /*-- Loop over inspiral triggers --*/

  thisEvent = events;
  while ( thisEvent ) {

    /*-- Check the time of this event against the veto segment list --*/

    if ( XLALSegListSearch( &vetoSegs, &(thisEvent->end_time) ) == NULL ) {
      /* This inspiral trigger does not fall within any veto segment */

      /* keep the trigger and increment the count of triggers */
      if ( ! eventHead ) eventHead = thisEvent;
      prevEvent = thisEvent;
      thisEvent = thisEvent->next;
      ++numEventsKept;

    } else {
      /*-- This event's end_time falls within one of the veto segments --*/

      /* discard the trigger and move to the next one */
      if ( prevEvent ) prevEvent->next = thisEvent->next;
      tmpEvent = thisEvent;
      thisEvent = thisEvent->next;
      LAL_CALL ( LALFreeSnglInspiral ( &stat, &tmpEvent ), &stat);

    }

  }

  /* make sure that the linked list is properly terminated */
  if ( prevEvent && prevEvent->next ) prevEvent->next->next = NULL;

  /*-- Report the number of events kept --*/
  printf( "Kept %d events\n", numEventsKept );


  /*-- Write out the surviving triggers --*/

  memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) );
  LAL_CALL( LALOpenLIGOLwXMLFile( &stat, &xmlStream, outFile ), &stat );

  if ( eventHead )
  {
    outputTable.snglInspiralTable = eventHead;
    LAL_CALL( LALBeginLIGOLwXMLTable( &stat, &xmlStream, 
          sngl_inspiral_table ), &stat );
    LAL_CALL( LALWriteLIGOLwXMLTable( &stat, &xmlStream, outputTable, 
          sngl_inspiral_table ), &stat );
    LAL_CALL( LALEndLIGOLwXMLTable( &stat, &xmlStream ), &stat);
  }

  /* close the output file */
  LAL_CALL( LALCloseLIGOLwXMLFile(&stat, &xmlStream), &stat);


  /*-- Free memory and exit --*/

  while ( eventHead )
  {
    thisEvent = eventHead;
    eventHead = eventHead->next;
    LAL_CALL ( LALFreeSnglInspiral ( &stat, &thisEvent ), &stat);
  }

  LALCheckMemoryLeaks();
  exit( 0 );
}
Exemple #3
0
int main ( int argc, char *argv[] )
{
  /* lal function variables */
  LALStatus             status = blank_status;

  /* template bank generation parameters */
  CHAR   *bankFileName = NULL;
  INT4    numOutBanks = 0;
  REAL4   minMatch = -1;

  /* output data */
  MetadataTable         inputBank;
  MetadataTable         outputBank;
  MetadataTable         proctable;
  MetadataTable         procparams;
  ProcessParamsTable   *this_proc_param = NULL;
  LIGOLwXMLStream       xmlStream;

  /* counters and other variables */
  INT4 i, j;
  INT4 numTmplts = 0;
  INT4 numTmpltsWritten = 0;
  INT4 numPerFile = 0;
  CHAR *gpsHyphen;
  char outBankFileName[FILENAME_MAX];
  CHAR bankFileNameHead[FILENAME_MAX];
  CHAR bankFileNameTail[FILENAME_MAX];
  CHAR comment[LIGOMETA_COMMENT_MAX];  
  CHAR *userTag = NULL;
  SnglInspiralTable *thisTmplt = NULL;
  SnglInspiralTable *tmpTmplt = NULL;

  /* LALgetopt arguments */
  struct LALoption long_options[] =
  {
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"version",                 no_argument,       0,                'V'},
    {"user-tag",                required_argument, 0,                'Z'},
    {"userTag",                 required_argument, 0,                'Z'},
    {"comment",                 required_argument, 0,                's'},    
    {"help",                    no_argument,       0,                'h'}, 
    {"bank-file",               required_argument, 0,                'v'},
    {"number-of-banks",         required_argument, 0,                'n'},
    {"minimal-match",           required_argument, 0,                'M'},
    {0, 0, 0, 0}
  };
  int c;


  /*
   * 
   * initialize things
   *
   */


  lal_errhandler = LAL_ERR_EXIT;
  setvbuf( stdout, NULL, _IONBF, 0 );

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentInfo.vcsId,
      lalAppsVCSIdentInfo.vcsStatus, lalAppsVCSIdentInfo.vcsDate, 0);
  this_proc_param = procparams.processParamsTable = 
    (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) );
  memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) );


  /*
   *
   * parse command line arguments
   *
   */


  while ( 1 )
  {
    /* LALgetopt_long stores long option here */
    int option_index = 0;
    size_t LALoptarg_len;

    c = LALgetopt_long_only( argc, argv,
        "i:n:VZ:hs:M:", 
        long_options, &option_index );

    /* detect the end of the options */
    if ( c == - 1 )
    {
      break;
    }

    switch ( c )
    {
      case 0:
        /* if this option set a flag, do nothing else now */
        if ( long_options[option_index].flag != 0 )
        {
          break;
        }
        else
        {
          fprintf( stderr, "error parsing option %s with argument %s\n",
              long_options[option_index].name, LALoptarg );
          exit( 1 );
        }
        break;

      case 'v':
        LALoptarg_len = strlen( LALoptarg ) + 1;
        bankFileName = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR));
        memcpy( bankFileName, LALoptarg, LALoptarg_len );
        snprintf( procparams.processParamsTable->program, 
            LIGOMETA_PROGRAM_MAX, "%s", PROGRAM_NAME );
        snprintf( procparams.processParamsTable->type, 
            LIGOMETA_TYPE_MAX, "string" );
        snprintf( procparams.processParamsTable->param, 
            LIGOMETA_PARAM_MAX, "--%s", long_options[option_index].name );
        snprintf( procparams.processParamsTable->value, 
            LIGOMETA_VALUE_MAX, "%s", LALoptarg );
        break;

      case 'n':
        numOutBanks = (INT4) atoi( LALoptarg );
        if ( numOutBanks < 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "Number of output banks must be greater than zero:" 
              "(%d specified)\n",
              long_options[option_index].name, numOutBanks );
          exit( 1 );
        }
        else if ( numOutBanks > 99 )
        {
          fprintf( stderr, 
              "Warning: generating more than 99 banks is not reccomended!\n" );
        }
        this_proc_param = this_proc_param->next = (ProcessParamsTable *)
          calloc( 1, sizeof(ProcessParamsTable) );
        snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, 
            "%s", PROGRAM_NAME );
        snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "int" );
        snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, 
            "--%s", long_options[option_index].name );
        snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%d", 
            numOutBanks );
        break;

      case 's':
        if ( strlen( LALoptarg ) > LIGOMETA_COMMENT_MAX - 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "comment must be less than %d characters\n",
              long_options[option_index].name, LIGOMETA_COMMENT_MAX );
          exit( 1 );
        }
        else
        {
          snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", LALoptarg );
        }
        break;

      case 'Z':
        /* create storage for the usertag */
        LALoptarg_len = strlen( LALoptarg ) + 1;
        userTag = (CHAR *) calloc( LALoptarg_len, sizeof(CHAR) );
        memcpy( userTag, LALoptarg, LALoptarg_len );

        this_proc_param = this_proc_param->next = (ProcessParamsTable *)
          calloc( 1, sizeof(ProcessParamsTable) );
        snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s", 
            PROGRAM_NAME );
        snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "string" );
        snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "-userTag" );
        snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%s",
            LALoptarg );
        break;

      case 'M':
        minMatch = (REAL4) atof( LALoptarg );
        if ( minMatch <= 0 )
        {
          fprintf( stdout, "invalid argument to --%s:\n"
              "minimal match of bank must be > 0: "
              "(%f specified)\n",
              long_options[option_index].name, minMatch );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = (ProcessParamsTable *)
          calloc( 1, sizeof(ProcessParamsTable) );
        snprintf( this_proc_param->program, LIGOMETA_PROGRAM_MAX, "%s", 
            PROGRAM_NAME );
        snprintf( this_proc_param->type, LIGOMETA_TYPE_MAX, "float" );
        snprintf( this_proc_param->param, LIGOMETA_PARAM_MAX, "--%s",
            long_options[option_index].name );
        snprintf( this_proc_param->value, LIGOMETA_VALUE_MAX, "%e",
            minMatch );
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "Inspiral Template Bank Splitter\n" 
            "Duncan Brown <*****@*****.**>\n");
        XLALOutputVersionString(stderr, 0);
        exit( 0 );
        break;

      case '?':
        fprintf( stderr, USAGE, argv[0] );
        exit( 1 );
        break;

      default:
        fprintf( stderr, "unknown error while parsing options\n" );
        fprintf( stderr, USAGE, argv[0] );
        exit( 1 );
    }
  }

  if ( LALoptind < argc )
  {
    fprintf( stderr, "extraneous command line arguments:\n" );
    while ( LALoptind < argc )
    {
      fprintf ( stderr, "%s\n", argv[LALoptind++] );
    }
    exit( 1 );
  }

  /* check the values of the arguments */
  if ( ! bankFileName )
  {
    fprintf( stderr, "Error: --bank-file must be specified\n" );
    exit( 1 );
  }

  if ( ! numOutBanks )
  {
    fprintf( stderr, "Error: --number-of-banks must be specified\n" );
    exit( 1 );
  }

  if ( minMatch < 0 )
  {
    fprintf( stderr, "Error: --minimal-match must be specified\n" );
    exit( 1 );
  }


  /*
   *
   * read in the template bank from the input file
   *
   */


  /* read in the template bank from a ligo lw xml file */
  inputBank.snglInspiralTable = NULL;
  numTmplts = LALSnglInspiralTableFromLIGOLw( &(inputBank.snglInspiralTable), 
      bankFileName, 0, -1 );
  if ( numTmplts < 0 )
  {
    fprintf( stderr, "error: unable to read templates from %s\n", 
        bankFileName );
    exit( 1 );
  }
  
  if ( vrbflg ) fprintf( stdout, "read %d templates from %s\n", 
      numTmplts, bankFileName );

  /* find the hypen just before the GPS start time of the bank */
  gpsHyphen = NULL;
  gpsHyphen = strstr( bankFileName, "-" );
  if ( ! gpsHyphen )
  {
    fprintf( stderr, "Error: could not find first hypen in file name %s\n",
        bankFileName );
    exit( 1 );
  }
  gpsHyphen = strstr( gpsHyphen + 1, "-" );
  if ( ! gpsHyphen )
  {
    fprintf( stderr, "Error: could not find second hypen in file name %s\n",
        bankFileName );
    exit( 1 );
  }

  /* store the name of the template bank file */
  memcpy( bankFileNameHead, bankFileName, 
      (size_t) gpsHyphen - (size_t) bankFileName < FILENAME_MAX ? 
      (gpsHyphen - bankFileName) * sizeof(CHAR) : FILENAME_MAX * sizeof(CHAR) );
  strncpy( bankFileNameTail, gpsHyphen + 1, FILENAME_MAX - 1 );

  if ( vrbflg )
  {
    fprintf( stdout, "head of bank file name is %s\n", bankFileNameHead );
    fprintf( stdout, "tail of bank file name is %s\n", bankFileNameTail );
  }

  
  /*
   *
   * write out the individual tempate bank files
   *
   */
  

  /* compute the number of templates per output file */
  numPerFile = floor( ( numTmplts - 0.5 )/ numOutBanks + 1 );
  thisTmplt = inputBank.snglInspiralTable;
  if ( vrbflg ) fprintf( stdout, "writing around %d templates per file\n", 
      numPerFile );

  for ( i = 0; i < numOutBanks; ++i )
  {
    /* open the output xml file */
    memset( outBankFileName, 0, FILENAME_MAX * sizeof(CHAR) );
    if(snprintf( outBankFileName, FILENAME_MAX, "%s_%02d-%s", 
        bankFileNameHead, i, bankFileNameTail ) >= FILENAME_MAX)
      abort();
    memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) );
    LAL_CALL( LALOpenLIGOLwXMLFile( &status , &xmlStream, outBankFileName), 
        &status );

    if ( vrbflg ) 
      fprintf( stdout, "writing templates to %s... ", outBankFileName );

    /* write process table */
    XLALGPSTimeNow(&(proctable.processTable->end_time));
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, proctable, 
          process_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );
    
    /* write process_params table */
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, 
          process_params_table ), &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, procparams, 
          process_params_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );

    /* write the templates to the file */
    outputBank.snglInspiralTable = thisTmplt;
    numTmpltsWritten = 0;

    if ( thisTmplt )
    {
      LAL_CALL( LALBeginLIGOLwXMLTable( &status ,&xmlStream, 
            sngl_inspiral_table), &status );

      for ( j = 0; j < numPerFile - 1 && thisTmplt->next; ++j )
      {
        thisTmplt = thisTmplt->next;
      }
      tmpTmplt = thisTmplt->next;
      thisTmplt->next = NULL;
      thisTmplt = tmpTmplt;

      LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputBank,
            sngl_inspiral_table), &status );
      LAL_CALL( LALEndLIGOLwXMLTable( &status, &xmlStream), &status );
    }

    while ( outputBank.snglInspiralTable )
    {
      ++numTmpltsWritten;
      tmpTmplt = outputBank.snglInspiralTable;
      outputBank.snglInspiralTable = outputBank.snglInspiralTable->next;
      LALFree( tmpTmplt );
    }

    LAL_CALL( LALCloseLIGOLwXMLFile( &status, &xmlStream), &status );

    if ( vrbflg ) fprintf( stdout, "%d templates\n", numTmpltsWritten );
  }

  LALCheckMemoryLeaks();
  exit( 0 );
}
int main( int argc, char *argv[] )
{
  LALStatus                     status = blank_status;

  UINT4                         k;
  UINT4                         kLow;
  UINT4                         kHi;
  INT4                          numPoints       = 524288;
  REAL4                         fSampling       = 2048.;
  REAL4                         fLow            = 70.;
  REAL4                         fLowInj         = 40.;
  REAL8                         deltaT          = 1./fSampling;
  REAL8                         deltaF          = fSampling / numPoints;

  REAL4                          statValue;
 
  /* vars required to make freq series */
  LIGOTimeGPS                   epoch = { 0, 0 };
  LIGOTimeGPS                   gpsStartTime = {0, 0}; 
  REAL8                         f0 = 0.;
  REAL8                         offset = 0.;
  INT8                          waveformStartTime = 0;

  /* files contain PSD info */
  CHAR                         *injectionFile = NULL;         
  CHAR                         *outputFile    = NULL;         
  CHAR                         *specFileH1    = NULL;         
  CHAR                         *specFileH2    = NULL;         
  CHAR                         *specFileL1    = NULL;         

  COMPLEX8Vector               *unity = NULL;
  const LALUnit strainPerCount = {0,{0,0,0,0,0,1,-1},{0,0,0,0,0,0,0}};

  int                           numInjections = 0;
  int                           numTriggers = 0;

  /* template bank simulation variables */
  INT4                         injSimCount = 0;
  SimInspiralTable            *injectionHead  = NULL;
  SimInspiralTable            *thisInjection  = NULL;
  SnglInspiralTable           *snglHead       = NULL;
  SearchSummaryTable          *searchSummHead = NULL;
  /*SummValueTable              *summValueHead  = NULL;    */

  /* raw input data storage */
  REAL8FrequencySeries          *specH1        = NULL;
  REAL8FrequencySeries          *specH2        = NULL;
  REAL8FrequencySeries          *specL1        = NULL;
  REAL8FrequencySeries          *thisSpec      = NULL;
  COMPLEX8FrequencySeries       *resp          = NULL;
  COMPLEX8FrequencySeries       *detTransDummy = NULL;
  REAL4TimeSeries               *chan          = NULL;
  RealFFTPlan                   *pfwd          = NULL;
  COMPLEX8FrequencySeries       *fftData       = NULL;
  REAL8                          thisSnrsq     = 0;
  REAL8                          thisSnr       = 0;
  REAL8                          thisCombSnr   = 0;
  REAL8                          snrVec[3];
  REAL8                          dynRange      = 1./(3.0e-23);

  /* needed for inj */
  CoherentGW                 waveform;
  PPNParamStruc              ppnParams;
  DetectorResponse           detector;
  InterferometerNumber       ifoNumber   = LAL_UNKNOWN_IFO;

  /* output data */
  LIGOLwXMLStream       xmlStream;
  MetadataTable         proctable;
  MetadataTable         outputTable;
  MetadataTable         procparams;
  CHAR                  fname[256];         
  CHAR                  comment[LIGOMETA_COMMENT_MAX];
  ProcessParamsTable   *this_proc_param = NULL;

  CHAR   chanfilename[FILENAME_MAX];

  REAL4 sum = 0;
  REAL4 bitten_H1 = 0;
  REAL4 bitten_H2 = 0;
  REAL4 thisCombSnr_H1H2 = 0;

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentId,
      lalAppsVCSIdentStatus, lalAppsVCSIdentDate, 0);
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
                                      calloc( 1, sizeof(ProcessParamsTable) );
  memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) );

  /* look at input args, write process params where required */
  while ( 1 )
  {

  /* getopt arguments */
  static struct option long_options[] =
  {
    /* these options set a flag */
    /* these options do not set a flag */
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"version",                 no_argument,       0,                'V'},
    {"spectrum-H1",             required_argument, 0,                'a'},
    {"spectrum-H2",             required_argument, 0,                'b'},
    {"spectrum-L1",             required_argument, 0,                'c'},
    {"inj-file",                required_argument, 0,                'd'},
    {"comment",                 required_argument, 0,                'e'},
    {"output-file",             required_argument, 0,                'f'},
    {"coire-flag",              no_argument,       &coireflg,         1 },
    {"ligo-srd",                no_argument,       &ligosrd,          1 },
    {"write-chan",              no_argument,       &writechan,        1 },
    {"inject-overhead",         no_argument,       &injoverhead,      1 },
    {"f-lower",                 required_argument, 0,                'g'},
    {0, 0, 0, 0}
  };
  int c;
  
  /*
   *
   * parse command line arguments
   *
   */

    /* getopt_long stores long option here */
    int option_index = 0;
    size_t optarg_len;

    c = getopt_long_only( argc, argv, "a:b:c:d:e:f:g:hV", long_options, &option_index );

    /* detect the end of the options */
    if ( c == - 1 )
    {
      break;
    }

    switch ( c )
    {
      case 0:
        /* if this option set a flag, do nothing else now */
        if ( long_options[option_index].flag != 0 )
        {
          break;
        }
        else
        {
          fprintf( stderr, "error parsing option %s with argument %s\n",
              long_options[option_index].name, optarg );
          exit( 1 );
        }
        break;

      case 'h':
        fprintf( stderr, USAGE );
        exit( 0 );
        break;

      case 'a':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileH1 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileH1, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'b':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileH2 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileH2, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'c':
        /* create storage for the spectrum file name */
        optarg_len = strlen( optarg ) + 1;
        specFileL1 = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( specFileL1, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'd':
        /* create storage for the injection file name */
        optarg_len = strlen( optarg ) + 1;
        injectionFile = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( injectionFile, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;

      case 'f':
        /* create storage for the output file name */
        optarg_len = strlen( optarg ) + 1;
        outputFile = (CHAR *) calloc( optarg_len, sizeof(CHAR));
        memcpy( outputFile, optarg, optarg_len );
        ADD_PROCESS_PARAM( "string", "%s", optarg );
        break;
    
      case 'g':
        fLow = (INT4) atof( optarg );
        if ( fLow < 40 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "f-lower must be > 40Hz (%e specified)\n",
              long_options[option_index].name, fLow );
          exit( 1 );
        }
        ADD_PROCESS_PARAM( "float", "%e", fLow );
        break;


     case 'e':
        if ( strlen( optarg ) > LIGOMETA_COMMENT_MAX - 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "comment must be less than %d characters\n",
              long_options[option_index].name, LIGOMETA_COMMENT_MAX );
          exit( 1 );
        }
        else
        {
          snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", optarg);
        }
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "calculation of expected SNR of injections\n"
            "Gareth Jones\n");
        XLALOutputVersionString(stderr, 0);
        exit( 0 );
        break;

     default:
        fprintf( stderr, "unknown error while parsing options\n" );
        fprintf( stderr, USAGE );
        exit( 1 );
    }
  }  

  if ( optind < argc )
  {
    fprintf( stderr, "extraneous command line arguments:\n" );
    while ( optind < argc )
    {
      fprintf ( stderr, "%s\n", argv[optind++] );
    }
    exit( 1 );
  }

  /* check the input arguments */
  if ( injectionFile == NULL )
  {
    fprintf( stderr, "Must specify the --injection-file\n" );
    exit( 1 );
  }

  if ( outputFile == NULL )
  {
    fprintf( stderr, "Must specify the --output-file\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileH1 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-H1\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileH2 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-H2\n" );
    exit( 1 );
  }

  if ( !ligosrd && specFileL1 == NULL )
  {
    fprintf( stderr, "Must specify the --spectrum-L1\n" );
    exit( 1 );
  }

  if ( ligosrd && (specFileH1 || specFileH2 || specFileL1 ))
  {
    fprintf( stdout, "WARNING: using LIGOI SRD power spectral density \n" );
  } 
 
  if ( vrbflg ){
    fprintf( stdout, "injection file is %s\n", injectionFile );
    fprintf( stdout, "output file is %s\n", outputFile );
    fprintf( stdout, "H1 spec file is   %s\n", specFileH1 );
    fprintf( stdout, "H2 spec file is   %s\n", specFileH2 );
    fprintf( stdout, "L1 spec file is   %s\n", specFileL1 );
  }

  /* create vector for H1, H2 and L1 spectrums */
  specH1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  specH2 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  specL1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) );
  if (!specH1 || !specH2 || !specL1){
    XLALDestroyREAL8FrequencySeries ( specH1 );
    XLALDestroyREAL8FrequencySeries ( specH2 );
    XLALDestroyREAL8FrequencySeries ( specL1 );
    XLALPrintError("failure allocating H1, H2 and L1 spectra");
    exit(1);
  }

  if (!ligosrd){
    /* read in H1 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specH1, specFileH1), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in H1 spec file\n" );
       fflush( stdout );
    } 

    /* read in H2 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specH2, specFileH2), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in H2 spec file\n" );
       fflush( stdout );
    }

    /* read in L1 spectrum */ 
    LAL_CALL( LALDReadFrequencySeries(&status, specL1, specFileL1), &status );
    if ( vrbflg ){
       fprintf( stdout, "read in L1 spec file\n" );
       fflush( stdout );
     }
  }

  chan = XLALCreateREAL4TimeSeries( "", &epoch, f0, deltaT, 
                                     &lalADCCountUnit, numPoints );
  if ( !chan ){
    XLALPrintError("failure allocating chan");
    exit(1);
  }

  /*
   *
   * set up the response function
   *
   */
  resp = XLALCreateCOMPLEX8FrequencySeries( chan->name, 
     &chan->epoch, f0, deltaF, &strainPerCount, (numPoints / 2 + 1) );
  if ( !resp ){
    XLALPrintError("failure allocating response function");
    exit(1);
  }

  /* create vector that will contain detector.transfer info, since this 
   * is constant I calculate it once outside of all the loops and pass it 
   * in to detector.transfer when required 
   */
  detTransDummy = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch,
                  f0, deltaF, &strainPerCount, (numPoints / 2 + 1) );
  if ( !detTransDummy ){
    XLALPrintError("failure allocating detector.transfer info");
    exit(1);
  }

  /* invert the response function to get the transfer function */
  unity = XLALCreateCOMPLEX8Vector( resp->data->length );
  for ( k = 0; k < unity->length; ++k )
     {
        unity->data[k] = 1.0;
     }

  /* set response */
  for ( k = 0; k < resp->data->length; ++k )
  {
      resp->data->data[k] = 1.0;
  }

  XLALCCVectorDivide( detTransDummy->data, unity, resp->data );
  XLALDestroyCOMPLEX8Vector( unity );

  /* read in injections from injection file */
  /* set endtime to 0 so that we read in all events */
  if ( vrbflg ) fprintf( stdout, "Reading sim_inspiral table of %s\n", injectionFile );
  LAL_CALL(numInjections = SimInspiralTableFromLIGOLw( &injectionHead, injectionFile, 0, 0), &status);
  if ( vrbflg ) fprintf( stdout, "Read %d injections from sim_inspiral table of %s\n", 
                                    numInjections, injectionFile );

  if (coireflg){
     if ( vrbflg ) fprintf( stdout, "Reading sngl_inspiral table of %s\n", injectionFile );
     LAL_CALL(numTriggers = LALSnglInspiralTableFromLIGOLw(&snglHead, injectionFile, 0, -1), &status);
     if ( vrbflg ) fprintf( stdout, "Read %d triggers from sngl_inspiral table of %s\n", 
                                    numTriggers, injectionFile );
     if ( vrbflg ) {
           fprintf( stdout, "Reading search_summary table of %s ...", injectionFile );
           fflush( stdout );
           }
     searchSummHead = XLALSearchSummaryTableFromLIGOLw (injectionFile);
     if ( vrbflg ) fprintf( stdout, " done\n");
  }

 /* make sure we start at head of linked list */
 thisInjection = injectionHead;

  /* setting fixed waveform injection parameters */
  memset( &ppnParams, 0, sizeof(PPNParamStruc) );
  ppnParams.deltaT   = deltaT;
  ppnParams.lengthIn = 0;
  ppnParams.ppn      = NULL;

  /* loop over injections */
  injSimCount = 0;
    
        
  do
  {
     fprintf( stdout, "injection %d/%d\n", injSimCount+1, numInjections );

     /* reset waveform structure */
     memset( &waveform, 0, sizeof(CoherentGW) );

     /* reset chan structure */
     memset( chan->data->data, 0, chan->data->length * sizeof(REAL4) );

     if (thisInjection->f_lower == 0){
        fprintf( stdout, "WARNING: f_lower in sim_inpiral = 0, ");
        fprintf( stdout, "changing this to %e\n ", fLowInj);
        thisInjection->f_lower = fLowInj;
     }

     /* create the waveform, amp, freq phase etc */
     LAL_CALL( LALGenerateInspiral(&status, &waveform, thisInjection, &ppnParams), &status);
     if (vrbflg) fprintf( stdout, "ppnParams.tc %e\n ", ppnParams.tc);

    statValue = 0.;
  
    /* calc lower index for integration */
    kLow = ceil(fLow / deltaF);
    if ( vrbflg ) {
        fprintf( stdout, "starting integration to find SNR at frequency %e ", fLow);
        fprintf( stdout, "at index %d \n", kLow);
    }
    /* calc upper index for integration */
    kHi = floor(fSampling / (2. * deltaF));
    if ( vrbflg ) {
        fprintf( stdout, "ending integration to find SNR at frequency %e ", fSampling / 2.);
        fprintf( stdout, "at index %d \n", kHi);
    }

    /* loop over ifo */
    for ( ifoNumber = 1; ifoNumber < 4; ifoNumber++ )
    {
        /* allocate memory and copy the parameters describing the freq series */
        memset( &detector, 0, sizeof( DetectorResponse ) );
        detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) );

        if (injoverhead){ 
           if ( vrbflg ) fprintf( stdout, "WARNING: perform overhead injections\n");
           /* setting detector.site to NULL causes SimulateCoherentGW to
            * perform overhead injections */  
           detector.site = NULL; 
        }
        else {
           /* if not overhead, set detector.site using ifonumber */  
           XLALReturnDetector( detector.site, ifoNumber );
        } 

        switch ( ifoNumber )
        {
        case 1:
           if ( vrbflg ) fprintf( stdout, "looking at H1 \n");
           thisSpec = specH1;
           break;
        case 2:
           if ( vrbflg ) fprintf( stdout, "looking at H2 \n");
           thisSpec = specH2;
           break;
        case 3:
           if ( vrbflg ) fprintf( stdout, "looking at L1 \n");
           thisSpec = specL1;
           break;
        default:
           fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber );
           exit( 1 );
        }

        /* get the gps start time of the signal to inject */
        waveformStartTime = XLALGPSToINT8NS( &(thisInjection->geocent_end_time) );
        waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc );

        offset = (chan->data->length / 2.0) * chan->deltaT;
        gpsStartTime.gpsSeconds     = thisInjection->geocent_end_time.gpsSeconds - offset;
        gpsStartTime.gpsNanoSeconds = thisInjection->geocent_end_time.gpsNanoSeconds;
        chan->epoch = gpsStartTime;


       if (vrbflg) fprintf(stdout, "offset start time of injection by %f seconds \n", offset ); 
       
       /* is this okay? copying in detector transfer which so far only contains response info  */
       detector.transfer = detTransDummy;

       XLALUnitInvert( &(detector.transfer->sampleUnits), &(resp->sampleUnits) );

       /* set the start times for injection */
       XLALINT8NSToGPS( &(waveform.a->epoch), waveformStartTime );
       memcpy(&(waveform.f->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) );
       memcpy(&(waveform.phi->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) );
 
       /* perform the injection */
       LAL_CALL( LALSimulateCoherentGW(&status, chan, &waveform, &detector ), &status); 

       if (writechan){ 
          /* write out channel data */
          if (vrbflg) fprintf(stdout, "writing channel data to file... \n" ); 
          switch ( ifoNumber )
          {
          case 1:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_H1_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing H1 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
          case 2:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_H2_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing H2 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
          case 3:
             snprintf( chanfilename, FILENAME_MAX, "chanTest_L1_inj%d.dat", injSimCount+1);
             if (vrbflg) fprintf( stdout, "writing L1 channel time series out to %s\n", chanfilename );
             LALSPrintTimeSeries(chan, chanfilename );
             break;
         default:
             fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber );
             exit( 1 );
         }  
      } 

      LAL_CALL( LALCreateForwardRealFFTPlan( &status, &pfwd, chan->data->length, 0), &status);

      fftData = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch, f0, deltaF, 
                                                   &lalDimensionlessUnit, (numPoints / 2 + 1) );
      if ( !fftData ){
        XLALPrintError("failure allocating fftData");
        exit(1);
      }
   
      LAL_CALL( LALTimeFreqRealFFT( &status, fftData, chan, pfwd ), &status);
   
      LAL_CALL( LALDestroyRealFFTPlan( &status, &pfwd ), &status);
      pfwd = NULL;

       /* compute the SNR */
       thisSnrsq = 0;
       /* avoid f=0 part of psd */  

       if (ligosrd){
          if (vrbflg) fprintf( stdout, "using LIGOI PSD \n");
          for ( k = kLow; k < kHi; k++ )
          {
           REAL8 freq;
           REAL8 sim_psd_value;
           freq = fftData->deltaF * k;
           LALLIGOIPsd( NULL, &sim_psd_value, freq ); 

           thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * 
                      (crealf(fftData->data->data[k]) * dynRange)) / sim_psd_value;
           thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * 
                      (cimagf(fftData->data->data[k]) * dynRange)) / sim_psd_value;
           }
       }
       else {
          if (vrbflg) fprintf( stdout, "using input spectra \n");
          for ( k = kLow; k < kHi; k++ )
          {
           thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * 
              (crealf(fftData->data->data[k]) * dynRange))  /
              (thisSpec->data->data[k] * dynRange * dynRange);
           thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * 
              (cimagf(fftData->data->data[k]) * dynRange)) /
              (thisSpec->data->data[k] * dynRange * dynRange);
        } 
      }

       thisSnrsq *= 4*fftData->deltaF;
       thisSnr    = pow(thisSnrsq, 0.5);
       /* Note indexing on snrVec, ifoNumber runs from 1..3 to get source correct,
        * we must index snrVec 0..2 
        */ 
       snrVec[ifoNumber-1] = thisSnr; 
       XLALDestroyCOMPLEX8FrequencySeries(fftData);

       if ( vrbflg ){
          fprintf( stdout, "thisSnrsq %e\n", thisSnrsq );
          fprintf( stdout, "snrVec    %e\n", snrVec[ifoNumber-1] );
          fflush( stdout );
       }

       /* sum thisSnrsq to eventually get combined snr*/
       statValue += thisSnrsq; 

       /* free some memory */
       if (detector.transfer) detector.transfer = NULL;
       if ( detector.site ) {LALFree( detector.site); detector.site = NULL;}
     }
     /* end loop over ifo */
  
    destroyCoherentGW( &waveform );

    /* store inverse eff snrs in eff_dist columns */
    thisInjection->eff_dist_h = 1./snrVec[0];
    thisInjection->eff_dist_g = 1./snrVec[1];
    thisInjection->eff_dist_l = 1./snrVec[2];

    /* store inverse sum of squares snr in eff_dist_t */
    thisCombSnr = pow(statValue, 0.5);
    if ( vrbflg ) fprintf( stdout, "thisCombSnr %e\n", thisCombSnr);
    thisInjection->eff_dist_t = 1./thisCombSnr;

    /* calc inverse bittenL snr for H1H2 and store in eff_dist_v */
    thisCombSnr_H1H2 = 0.;
    sum = snrVec[0] * snrVec[0] + snrVec[1] * snrVec[1];
    bitten_H1 = 3 * snrVec[0] -3;
    bitten_H2 = 3 * snrVec[1] -3;

    if (sum < bitten_H1){
       thisCombSnr_H1H2 = sum;
    }
    else
    {
       thisCombSnr_H1H2 = bitten_H1;
    }

    if (bitten_H2 < thisCombSnr_H1H2){
       thisCombSnr_H1H2 = bitten_H2;
    }
    thisInjection->eff_dist_v = 1./thisCombSnr_H1H2;


    /* increment the bank sim sim_inspiral table if necessary */
    if ( injectionHead )
    {
      thisInjection = thisInjection->next;
    }

  } while ( ++injSimCount < numInjections ); 
  /* end loop over injections */

  /* try opening, writing and closing an xml file */

  /* open the output xml file */
  memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) );
  snprintf( fname, sizeof(fname), "%s", outputFile);
  LAL_CALL( LALOpenLIGOLwXMLFile  ( &status, &xmlStream, fname), &status);

  /* write out the process and process params tables */
  if ( vrbflg ) fprintf( stdout, "process... " );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_table ), &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, proctable, process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );
  free( proctable.processTable );
  /* Just being pedantic here ... */
  proctable.processTable = NULL;
 
  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );
  this_proc_param = NULL;

  /* write the process params table */
  if ( vrbflg ) fprintf( stdout, "process_params... " );
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_params_table ), &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, procparams, process_params_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status );

  /* write the search summary table */
  if ( coireflg ){
     if ( vrbflg ) fprintf( stdout, "search_summary... " );
     outputTable.searchSummaryTable = searchSummHead;
     LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, search_summary_table), &status);
     LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, search_summary_table), &status);
     LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);
   }

  /* write the sim inspiral table */
  if ( vrbflg ) fprintf( stdout, "sim_inspiral... " );
  outputTable.simInspiralTable = injectionHead;
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sim_inspiral_table), &status);
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sim_inspiral_table), &status);
  LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);

  /* write the sngl inspiral table */
  if ( coireflg ){
     if ( vrbflg ) fprintf( stdout, "sngl_inspiral... " );
     outputTable.snglInspiralTable = snglHead;
     LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sngl_inspiral_table), &status);
     LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sngl_inspiral_table), &status);
     LAL_CALL( LALEndLIGOLwXMLTable  ( &status, &xmlStream), &status);
  } 

  /* close the xml file */ 
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlStream), &status);

  /* Freeing memory */
  XLALDestroyREAL4TimeSeries(chan);
  XLALDestroyCOMPLEX8FrequencySeries(resp);
  XLALDestroyCOMPLEX8FrequencySeries(detTransDummy);
  XLALDestroyREAL8FrequencySeries ( specH1 );
  XLALDestroyREAL8FrequencySeries ( specH2 );
  XLALDestroyREAL8FrequencySeries ( specL1 );


  free( specFileH1 );
  specFileH1 = NULL;
  free( specFileH2 );
  specFileH2 = NULL;
  free( specFileL1 );
  specFileL1 = NULL;
  free( injectionFile ); 
  injectionFile = NULL;

  /* free the process params */
  while( procparams.processParamsTable )
  {
    this_proc_param = procparams.processParamsTable;
    procparams.processParamsTable = this_proc_param->next;
    free( this_proc_param );
    this_proc_param = NULL;
  }

  /* free the sim inspiral tables */
  while ( injectionHead )
  {
    thisInjection = injectionHead;
    injectionHead = injectionHead->next;
    LALFree( thisInjection );
  }

  /*check for memory leaks */
  LALCheckMemoryLeaks(); 

  exit( 0 ); 
}
int
main (int argc, char **argv ) 
{
  UINT4 line=0, i;
UINT8  id=0;
  UINT4 start = 0;
  ResultIn trigger;
  REAL4 tau0, tau3, tau0I, tau3I, psi0, psi3, phaseI, coaTime;
  FILE *input1, *input2, *bank;
  FILE *output;      
  SnglInspiralTable     *inputData = NULL;
  INT4 numFileTriggers = 0;

  MetadataTable         templateBank;




  char sbuf[512];
  
  if (argc>1) {
    if (strcmp(argv[1], "--help")==0) {
      BEAscii2XmlHelp();
    }  
    if (strcmp(argv[1], "-h")==0) { 
      BEAscii2XmlHelp();
    }  
  }
  /* Main program starts here */
  /* First we open the file containing the ascii results */
  fprintf(stderr,"opening the xml output data file -- %s", BEASCII2XML_OUTPUT);
  output = fopen(BEASCII2XML_OUTPUT,"w");
  fprintf(stderr,"done\n");

  fprintf(stderr,"opening the xml input data file -- %s", BEASCII2XML_INPUT1);
  if  ( (input1  = fopen(BEASCII2XML_INPUT1,"r"))==NULL) {
    fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_INPUT1);
    exit(0);
  }
  fprintf(stderr,"done\n");

  fprintf(stderr,"opening the xml prototype (argument of BankEfficiency code) -- ");
  if  ( (input2  = fopen(BEASCII2XML_INPUT2,"r"))==NULL)
    {
      fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_INPUT2);
      fprintf(stderr,"the xml file will not contains parameters information\n");
      PRINT_LIGOLW_XML_HEADER(output);
      fprintf(stderr,"creating the header file -- done\n");
    }
  else 
    {
      /* read prototype and save in outputfile */
      fprintf(stderr,"parsing the prototype  -- ");
      while(fgets(sbuf,1024,input2) !=NULL)
	fputs(sbuf, output);
      fprintf(stderr," done\n");

      
    }
  

  /* insert the template bank here */
  if  ( (bank  = fopen(BEASCII2XML_BANK,"r"))==NULL)
    {
      fprintf(stderr,"error while opening input file %s\n",BEASCII2XML_BANK);
      fprintf(stderr,"the xml file will not contains the bank table\n");
    }
  else 
    {
      /* read prototype and save in outputfile */
      fprintf(stderr,"parsing the bank  -- ");
      fprintf( stdout, "reading triggers from file: %s\n", BEASCII2XML_BANK );
      numFileTriggers = 
        LALSnglInspiralTableFromLIGOLw( &inputData,BEASCII2XML_BANK , 0, -1 );
      fprintf(stderr," done %d\n", numFileTriggers);      
       myfprintf(output, LIGOLW_XML_SNGL_INSPIRAL );
       while(inputData)
	{
	  /*	  id = inputData->event_id->id;*/
	  
	  fprintf(output, SNGL_INSPIRAL_ROW, 
		  inputData->ifo,
		  inputData->search,
		  inputData->channel,
		  inputData->end_time.gpsSeconds,
		  inputData->end_time.gpsNanoSeconds,
		  inputData->end_time_gmst,
		  inputData->impulse_time.gpsSeconds,
		  inputData->impulse_time.gpsNanoSeconds,
		  inputData->template_duration,
		  inputData->event_duration,
		  inputData->amplitude,
		  inputData->eff_distance,
		  inputData->coa_phase,
		  inputData->mass1,
		  inputData->mass2,
		  inputData->mchirp,
		  inputData->mtotal,
		  inputData->eta,
		  inputData->tau0,
		  inputData->tau2,
		  inputData->tau3,
		  inputData->tau4,
		  inputData->tau5,
		  inputData->ttotal,
		  inputData->psi0,
		  inputData->psi3,
		  inputData->alpha,
		  inputData->alpha1,
		  inputData->alpha2,
		  inputData->alpha3,
		  inputData->alpha4,
		  inputData->alpha5,
		  inputData->alpha6,
		  inputData->beta,
		  inputData->f_final,
		  inputData->snr,
		  inputData->chisq,
		  inputData->chisq_dof,
		  inputData->sigmasq,
		  id);
	  inputData = inputData->next;
	  fprintf(output, "\n");

	}
       myfprintf(output, LIGOLW_XML_TABLE_FOOTER );

    }



  PRINT_LIGOLW_XML_BANKEFFICIENCY(output);
  fprintf(stderr,"done\n");
  /* read ascii input and save in xml format */
  fprintf(stderr,"reading the ascii file -- and saving xml file");
  do  
    {
      fscanf(input1,BANKEFFICIENCY_PARAMS_ROW_SPACE,
	     &trigger.psi0_triggerU,
	     &trigger.psi3_triggerU,
	     &trigger.psi0_trigger,
	     &trigger.psi3_trigger,
	     &psi0, 
	     &psi3,
	     &tau0, 
	     &tau3, 
	     &tau0I, 
	     &tau3I,
	     &trigger.fend_triggerU, 
	     &trigger.fend_trigger, 
	     &trigger.fend_inject,
	     &trigger.mass1_inject,
	     &trigger.mass2_inject,
	     &trigger.rho_finalU,
	     &trigger.phaseU,
	     &phaseI,
	     &trigger.alphaFU, 
	     &trigger.layerU,
	     &trigger.binU,
	     &trigger.rho_final,
	     &trigger.snrAtCoaTime, 
	     &phaseI,
	     &trigger.phase,
	     &trigger.alphaF, 
	     &trigger.layer,
	     &trigger.bin, 
	     &coaTime);

     if (start==0){
	      start+=1;
      }
      else 
      {
	      fprintf(output,",\n");
      }
      fprintf(output, BANKEFFICIENCY_PARAMS_ROW,
	      trigger.psi0_triggerU,
	      trigger.psi3_triggerU,
	      trigger.psi0_trigger,
	      trigger.psi3_trigger,
	      psi0, 
	      psi3,
	      tau0,
	      tau3,
	      tau0I,
	      tau3I,
	      trigger.fend_triggerU, 
	      trigger.fend_trigger, 
	      trigger.fend_inject,
	      trigger.mass1_inject,
	      trigger.mass2_inject,
	      trigger.rho_finalU,
	      phaseI,
	      trigger.phaseU,
	      trigger.alphaFU, 
	      trigger.layerU,
	      trigger.binU,
	      trigger.rho_final,
	      trigger.snrAtCoaTime,
	      phaseI,
	      trigger.phase,
	      trigger.alphaF, 
	      trigger.layer,
	      trigger.bin, 
	      coaTime);
         line++;
    }
   while(!feof(input1));

    fprintf(stderr,"read %d lines...done\n", line);
  PRINT_LIGOLW_XML_TABLE_FOOTER(output);
  PRINT_LIGOLW_XML_FOOTER(output);

  fclose(output);
    fprintf(stderr,"closing xml file\n");

  return 0;
}