// compare two SFTs, return XLAL_SUCCESS if OK, error otherwise
int
XLALCompareSFTs ( const SFTtype *sft1, const SFTtype *sft2, const VectorComparison *tol )
{
  // check input sanity
  XLAL_CHECK ( sft1 != NULL, XLAL_EINVAL );
  XLAL_CHECK ( sft2 != NULL, XLAL_EINVAL );
  XLAL_CHECK ( tol  != NULL, XLAL_EINVAL );

  XLAL_CHECK ( XLALGPSCmp ( &(sft1->epoch), &(sft2->epoch) ) == 0, XLAL_ETOL );
  REAL8 tolFreq = 10 * LAL_REAL8_EPS;
  REAL8 err_f0 = sft1->f0 - sft2->f0;
  XLAL_CHECK ( err_f0 < tolFreq, XLAL_ETOL, "f0_1 = %.16g, f0_2 = %.16g, relErr_f0 = %g (tol = %g)\n", sft1->f0, sft2->f0, err_f0, tolFreq );
  REAL8 relErr_df = RELERR ( sft1->deltaF, sft2->deltaF );
  XLAL_CHECK ( relErr_df < tolFreq, XLAL_ETOL, "dFreq1 = %g, dFreq2 = %g, relErr_df = %g (tol = %g)", sft1->deltaF, sft2->deltaF, relErr_df, tolFreq );

  XLAL_CHECK ( XLALUnitCompare( &(sft1->sampleUnits), &(sft2->sampleUnits) ) == 0, XLAL_ETOL );

  XLAL_CHECK ( sft1->data->length == sft2->data->length, XLAL_ETOL, "sft1->length = %d, sft2->length = %d\n", sft1->data->length, sft2->data->length  );

  VectorComparison XLAL_INIT_DECL(cmp);
  XLAL_CHECK ( XLALCompareCOMPLEX8Vectors ( &cmp, sft1->data, sft2->data, tol ) == XLAL_SUCCESS, XLAL_EFUNC );

  return XLAL_SUCCESS;

} // XLALCompareSFTs()
///
/// Parse a string representing a range of LIGOTimeGPS values into a LIGOTimeGPSRange. Possible formats
/// are <tt>start</tt>, <tt>start,end</tt>, <tt>start/band</tt>, or <tt>start~plusminus</tt>.
/// Output range is always <tt>low,high</tt> with <tt>range[0] = low; range[1] = high</tt>.
///
int XLALParseStringValueAsEPOCHRange(
  LIGOTimeGPSRange *gpsRange,		///< [out] output range of LIGOTimeGPS values
  const char *valString			///< [in] input string
  )
{

  // Check input
  XLAL_CHECK(gpsRange != NULL, XLAL_EFAULT);
  XLAL_CHECK(valString != NULL, XLAL_EFAULT);

  // Parse range
  char part[2][256];
  int T[2][2];
  split_string_into_range(valString, part, T);
  LIGOTimeGPS val[2];
  XLAL_CHECK( XLALParseStringValueAsEPOCH(&val[0], part[0]) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsEPOCH(&val[1], part[1]) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALINT8NSToGPS( &(*gpsRange)[0], T[0][0] * XLALGPSToINT8NS(&val[0]) + T[0][1] * XLALGPSToINT8NS(&val[1]) );
  XLALINT8NSToGPS( &(*gpsRange)[1], T[1][0] * XLALGPSToINT8NS(&val[0]) + T[1][1] * XLALGPSToINT8NS(&val[1]) );

  // Check range ordering
  if (XLALGPSCmp(&(*gpsRange)[0], &(*gpsRange)[1]) > 0) {
    const LIGOTimeGPS tmp = (*gpsRange)[0];
    (*gpsRange)[0] = (*gpsRange)[1];
    (*gpsRange)[1] = tmp;
  }

  return XLAL_SUCCESS;

}
static int CompareDoppler( const PulsarDopplerParams *a, const PulsarDopplerParams *b )
{
  XLAL_CHECK( XLALGPSCmp( &a->refTime, &b->refTime ) == 0, XLAL_ETOL, "Reference time mismatch!" );
  CHECK_RELERR( cos( a->Alpha ), cos( b->Alpha ), 1e-10 );
  CHECK_RELERR( sin( a->Alpha ), sin( b->Alpha ), 1e-10 );
  CHECK_RELERR( a->Delta, b->Delta, 1e-10 );
  CHECK_RELERR( a->fkdot[0], b->fkdot[0], 1e-10 );
  CHECK_RELERR( a->fkdot[1], b->fkdot[1], 1e-10 );
  return XLAL_SUCCESS;
}
Exemple #4
0
/**
 * Restrict the EphemerisData 'edat' to the smallest number of entries
 * required to cover the GPS time range ['startGPS', 'endGPS']
 *
 * \ingroup LALBarycenter_h
 */
int XLALRestrictEphemerisData ( EphemerisData *edat, const LIGOTimeGPS *startGPS, const LIGOTimeGPS *endGPS ) {

  // Check input
  XLAL_CHECK(edat != NULL, XLAL_EFAULT);
  XLAL_CHECK(startGPS != NULL, XLAL_EFAULT);
  XLAL_CHECK(endGPS != NULL, XLAL_EFAULT);
  XLAL_CHECK(XLALGPSCmp(startGPS, endGPS) < 0, XLAL_EINVAL);

  // Convert 'startGPS' and 'endGPS' to REAL8s
  const REAL8 start = XLALGPSGetREAL8(startGPS), end = XLALGPSGetREAL8(endGPS);

  // Increase 'ephemE' and decrease 'nentriesE' to fit the range ['start', 'end']
  PosVelAcc *const old_ephemE = edat->ephemE;
  do {
    if (edat->nentriesE > 1 && edat->ephemE[0].gps < start && edat->ephemE[1].gps <= start) {
      ++edat->ephemE;
      --edat->nentriesE;
    } else if (edat->nentriesE > 1 && edat->ephemE[edat->nentriesE-1].gps > end && edat->ephemE[edat->nentriesE-2].gps >= end) {
      --edat->nentriesE;
    } else {
      break;
    }
  } while(1);

  // Reallocate 'ephemE' to new table size, and free old table
  PosVelAcc *const new_ephemE = XLALMalloc(edat->nentriesE * sizeof(*new_ephemE));
  XLAL_CHECK(new_ephemE != NULL, XLAL_ENOMEM);
  memcpy(new_ephemE, edat->ephemE, edat->nentriesE * sizeof(*new_ephemE));
  edat->ephemE = new_ephemE;
  XLALFree(old_ephemE);

  // Increase 'ephemS' and decrease 'nentriesS' to fit the range ['start', 'end']
  PosVelAcc *const old_ephemS = edat->ephemS;
  do {
    if (edat->nentriesS > 1 && edat->ephemS[0].gps < start && edat->ephemS[1].gps <= start) {
      ++edat->ephemS;
      --edat->nentriesS;
    } else if (edat->nentriesS > 1 && edat->ephemS[edat->nentriesS-1].gps > end && edat->ephemS[edat->nentriesS-2].gps >= end) {
      --edat->nentriesS;
    } else {
      break;
    }
  } while(1);

  // Reallocate 'ephemS' to new table size, and free old table
  PosVelAcc *const new_ephemS = XLALMalloc(edat->nentriesS * sizeof(*new_ephemS));
  XLAL_CHECK(new_ephemS != NULL, XLAL_ENOMEM);
  memcpy(new_ephemS, edat->ephemS, edat->nentriesS * sizeof(*new_ephemS));
  edat->ephemS = new_ephemS;
  XLALFree(old_ephemS);

  return XLAL_SUCCESS;

} /* XLALRestrictEphemerisData() */
Exemple #5
0
static PyObject *richcompare(PyObject *self, PyObject *other, int op_id)
{
	LIGOTimeGPS self_gps;
	LIGOTimeGPS other_gps;
	int d;
	PyObject *result;

	if(!pyobject_to_ligotimegps(self, &self_gps))
		return NULL;
	if(!pyobject_to_ligotimegps(other, &other_gps)) {
		PyErr_Clear();
		Py_INCREF(Py_NotImplemented);
		return Py_NotImplemented;
	}

	d = XLALGPSCmp(&self_gps, &other_gps);
	switch(op_id) {
	case Py_LT:
		result = (d < 0) ? Py_True : Py_False;
		break;

	case Py_LE:
		result = (d <= 0) ? Py_True : Py_False;
		break;

	case Py_EQ:
		result = (d == 0) ? Py_True : Py_False;
		break;

	case Py_NE:
		result = (d != 0) ? Py_True : Py_False;
		break;

	case Py_GT:
		result = (d > 0) ? Py_True : Py_False;
		break;

	case Py_GE:
		result = (d >= 0) ? Py_True : Py_False;
		break;

	default:
		PyErr_BadInternalCall();
		return NULL;
	}

	Py_INCREF(result);
	return result;
}
Exemple #6
0
static int runtest(const struct TESTCASE *testcase)
{
	int retval;
	LIGOTimeGPS gps;
	LIGOTimeGPS gpsCorrect;
	char *endptr;
	int failure = 0;

	XLALGPSSet(&gpsCorrect, testcase->sec, testcase->ns);

	XLALClearErrno();
	retval = XLALStrToGPS(&gps, testcase->string, &endptr);

	if(retval == 0 && testcase->xlal_errno == 0) {
		if(XLALGPSCmp(&gps, &gpsCorrect) || strcmp(endptr, testcase->remainder))
			failure = 1;
	} else if(XLALGetBaseErrno() != testcase->xlal_errno)
		failure = 1;

	if(lalDebugLevel || failure)
		fprintf(stdout, "Input = \"%s\"\n\tOutput =\t%" LAL_INT8_FORMAT " ns with \"%s\" remainder, errno %d\n\tCorrect =\t%" LAL_INT8_FORMAT " ns with \"%s\" remainder, errno %d\n\t\t===> %s\n", testcase->string, XLALGPSToINT8NS(&gps), endptr, XLALGetBaseErrno(), XLALGPSToINT8NS(&gpsCorrect), testcase->remainder, testcase->xlal_errno, failure ? "*** FAIL ***" : "Pass");

	return failure;
}
int main( int argc, char *argv[] )
{
  LALStatus             status = blank_status;
#if 0
  const INT4            S2StartTime = 729273613; /* Feb 14 2003 16:00:00 UTC */
  const INT4            S2StopTime  = 734367613; /* Apr 14 2003 15:00:00 UTC */
#endif
  /* command line options */
  LIGOTimeGPS   gpsStartTime = {S2StartTime, 0};
  LIGOTimeGPS   gpsEndTime   = {S2StopTime, 0};
  REAL8         meanTimeStep = 2630 / LAL_PI;
  REAL8         timeInterval = 0;
  UINT4         randSeed = 1;
  CHAR         *userTag = NULL;
  REAL4         minMass = 3.0;       /* minimum component mass */
  REAL4         maxMass = 20.0;      /* maximum component mass */
  REAL4         sumMaxMass = 0.0;    /* maximum total mass sum */
  UINT4         sumMaxMassUse=0;     /* flag indicating to use the sumMaxMass */
  REAL4         dmin = 1.0;          /* minimum distance from earth (kpc) */
  REAL4         dmax = 20000.0 ;     /* maximum distance from earth (kpc) */
  REAL4         fLower = 0;          /* default value for th lower cut off frequency */
/* REAL4         Rcore = 0.0; */
  UINT4         ddistr = 0, mdistr=0;

  /* program variables */
  RandomParams *randParams = NULL;
  REAL4  u, exponent, d2;
  REAL4  deltaM, mtotal;


  /* waveform */
  CHAR waveform[LIGOMETA_WAVEFORM_MAX];

#if 0
  int i, stat;

  double d, cosphi, sinphi;
#endif

/*  GalacticInspiralParamStruc galacticPar; */

  /* xml output data */
  CHAR                  fname[256];
  MetadataTable         proctable;
  MetadataTable         procparams;
  MetadataTable         injections;
  ProcessParamsTable   *this_proc_param;
  SimInspiralTable     *this_inj = NULL;
  LIGOLwXMLStream       xmlfp;
  UINT4                 outCompress = 0;

  /* getopt arguments */
  struct option long_options[] =
  {
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"write-compress",          no_argument,       &outCompress,      1 },
    {"version",                 no_argument,       0,                'V'},
    {"f-lower",                        required_argument, 0,                'f'},
    {"gps-start-time",          required_argument, 0,                'a'},
    {"gps-end-time",            required_argument, 0,                'b'},
    {"time-step",               required_argument, 0,                't'},
    {"time-interval",           required_argument, 0,                'i'},
    {"seed",                    required_argument, 0,                's'},
    {"min-mass",                required_argument, 0,                'A'},
    {"max-mass",                required_argument, 0,                'B'},
    {"max-total-mass",          required_argument, 0,                'x'},
    {"min-distance",            required_argument, 0,                'p'},
    {"max-distance",            required_argument, 0,                'r'},
    {"d-distr",                 required_argument, 0,                'd'},
    {"m-distr",                 required_argument, 0,                'm'},
    {"waveform",                required_argument, 0,                'w'},
    {"user-tag",                required_argument, 0,                'Z'},
    {"userTag",                 required_argument, 0,                'Z'},
    {0, 0, 0, 0}
  };
  int c;

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


  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) 
    calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  if (strcmp(CVS_REVISION,"$Revi" "sion$"))
    {
      XLALPopulateProcessTable(proctable.processTable,
          PROGRAM_NAME, CVS_REVISION, CVS_SOURCE, CVS_DATE, 0);
    }
  else
    {
      XLALPopulateProcessTable(proctable.processTable,
          PROGRAM_NAME, lalappsGitCommitID,
          lalappsGitGitStatus,
          lalappsGitCommitDate, 0);
    }
  snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, " " );
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
    calloc( 1, sizeof(ProcessParamsTable) );

  /* clear the waveform field */
  memset( waveform, 0, LIGOMETA_WAVEFORM_MAX * sizeof(CHAR) );
  

  /*
   *
   * parse command line arguments
   *
   */

     
  while ( 1 )
  {
    /* getopt_long stores long option here */
    int option_index = 0;
    long int gpsinput;
    size_t optarg_len;

    c = getopt_long_only( argc, argv, 
        "a:A:b:B:d:f:hi:m:p:q:r:s:t:vZ:w:", 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 'a':
        gpsinput = atol( optarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsStartTime.gpsSeconds = gpsinput;

        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'b':
        gpsinput = atol( optarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsEndTime.gpsSeconds = gpsinput;
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'f':
        fLower = atof( optarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%f", fLower );
        break;

      case 's':
        randSeed = atoi( optarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%d", randSeed );
        break;

      case 't':
        meanTimeStep = (REAL8) atof( optarg );
        if ( meanTimeStep <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time step must be > 0: (%e seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%e", meanTimeStep );
        break;

      case 'i':
        timeInterval = atof( optarg );
        if ( timeInterval < 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time interval must be >= 0: (%e seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", timeInterval );
        break;

      case 'A':
        /* minimum component mass */
        minMass = (REAL4) atof( optarg );
        if ( minMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "miniumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, minMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", minMass );
        break;

      case 'B':
        /* maximum component mass */
        maxMass = (REAL4) atof( optarg );
        if ( maxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maxiumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, maxMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", maxMass );
        break;

    case 'x':
      /* maximum sum of components */
      sumMaxMass = (REAL4) atof( optarg );
      if ( sumMaxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "sum of two component masses must be > 0: "
                   "(%f solar masses specified)\n",
                   long_options[option_index].name, sumMaxMass );
          exit( 1 );
        }
      sumMaxMassUse=1;
        this_proc_param = this_proc_param->next =
          next_process_param( long_options[option_index].name,
                              "float", "%e", sumMaxMass );
        break;

      case 'p':
        /* minimum distance from earth */
        dmin = (REAL4) atof( optarg );
        if ( dmin <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "minimum distance must be > 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, dmin );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", dmin );
        break;

      case 'r':
        /* max distance from earth */
        dmax = (REAL4) atof( optarg );
        if ( dmax <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maximum distance must be greater than 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, dmax );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", dmax );
        break;

      case 'd':
        ddistr = (UINT4) atoi( optarg );
        if ( ddistr != 0 && ddistr != 1 && ddistr != 2)
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "DDISTR must be either 0 or 1 or 2\n",
              long_options[option_index].name);
          exit(1);
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "int", "%d", ddistr );

        break;

      case 'm':
        mdistr = (UINT4) atoi( optarg );
        if ( mdistr != 0 && mdistr != 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "MDISTR must be either 0 or 1\n",
              long_options[option_index].name);
          exit(1);
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "int", "%d", mdistr );

  
        break;

      case 'Z':
        /* create storage for the usertag */
        optarg_len = strlen( optarg ) + 1;
        userTag = (CHAR *) calloc( optarg_len, sizeof(CHAR) );
        memcpy( userTag, optarg, optarg_len );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "string", "%s", optarg );
        break;

      case 'w':
        snprintf( waveform, LIGOMETA_WAVEFORM_MAX, "%s", optarg);
        this_proc_param = this_proc_param->next =
          next_process_param( long_options[option_index].name, "string",
              "%s", optarg);
        break;

      case 'V':
        /* print version information and exit */
        fprintf( stdout, "Binary Black Hole INJection generation routine\n" 
            "Duncan A Brown and Eirini Messaritaki\n"
            "CVS Version: " CVS_ID_STRING "\n"
            "CVS Tag: " CVS_NAME_STRING "\n" );
        fprintf( stdout, lalappsGitID );
        exit( 0 );
        break;
        
      case 'h':
      case '?':
        fprintf( stderr, USAGE );
        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 );
  }


  if ( !*waveform )
  {
    /* use EOBtwoPN as the default waveform */
    snprintf( waveform, LIGOMETA_WAVEFORM_MAX, "EOBtwoPN");
  }

  if ( !fLower )
  {
    fprintf( stderr, "--f-lower must be specified and non-zero\n" );
    exit( 1 );
  }

  /*
   *
   * initialization
   *
   */


  /* initialize the random number generator */
  LAL_CALL( LALCreateRandomParams( &status, &randParams, randSeed ), &status );

  /* mass range, per component */
  deltaM = maxMass - minMass;

  /* null out the head of the linked list */
  injections.simInspiralTable = NULL;

  /* create the output file name */
  if ( userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml.gz",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( userTag && !outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( !userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml.gz",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }


  /*
   *
   * loop over duration of desired output times
   *
   */


  while ( XLALGPSCmp( &gpsStartTime, &gpsEndTime ) < 0 )
  {

    /* rho, z and lGal are the galactocentric galactic axial coordinates */
    /* r and phi are the geocentric galactic spherical coordinates       */
#if 0
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.lGal = LAL_TWOPI * u;
    
    galacticPar.z = r * sinphi ;
    galacticPar.rho = 0.0 - Rcore * cos(galacticPar.lGal) +
      sqrt( r * r - galacticPar.z * galacticPar.z - 
      Rcore * Rcore * sin(galacticPar.lGal) * sin(galacticPar.lGal) );
#endif

#if 0
    if ( vrbflg ) fprintf( stdout, "%e %e %e %e %e\n", 
        galacticPar.m1, galacticPar.m2,
        galacticPar.rho * cos( galacticPar.lGal ),
        galacticPar.rho * sin( galacticPar.lGal ),
        galacticPar.z );
#endif

    /* create the sim_inspiral table */
    if ( injections.simInspiralTable )
    {
      this_inj = this_inj->next = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }
    else
    {
      injections.simInspiralTable = this_inj = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }

    /* set the geocentric end time of the injection */
    /* XXX CHECK XXX */
    this_inj->geocent_end_time = gpsStartTime;
    if ( timeInterval )
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      XLALGPSAdd( &(this_inj->geocent_end_time), u * timeInterval );
    }

    /* set gmst */
    this_inj->end_time_gmst = fmod(XLALGreenwichMeanSiderealTime(
        &this_inj->geocent_end_time), LAL_TWOPI) * 24.0 / LAL_TWOPI; /* hours */
    if( XLAL_IS_REAL8_FAIL_NAN(this_inj->end_time_gmst) )
    {
      fprintf(stderr, "XLALGreenwichMeanSiderealTime() failed\n");
      exit(1);
    }
    /* XXX END CHECK XXX */

    /* populate the sim_inspiral table */

    if (mdistr == 1)
    /* uniformly distributed mass1 and uniformly distributed mass2 */
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass1 = minMass + u * deltaM;
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass2 = minMass + u * deltaM;
      mtotal = this_inj->mass1 + this_inj->mass2 ;
      this_inj->eta = this_inj->mass1 * this_inj->mass2 / ( mtotal * mtotal );
      this_inj->mchirp = (this_inj->mass1 + this_inj->mass2) * 
        pow(this_inj->eta, 0.6);
    }
    else if (mdistr == 0)
    /*uniformly distributed total mass */
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status);
      mtotal = 2.0 * minMass + u * 2.0 *deltaM ;

      if (sumMaxMassUse==1) {
        while (mtotal > sumMaxMass) {
          LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status);
          mtotal = 2.0 * minMass + u * 2.0 *deltaM ;          
        }
      }

      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->mass1 = minMass + u * deltaM;
      this_inj->mass2 = mtotal - this_inj->mass1;

      while (this_inj->mass1 >= mtotal || 
          this_inj->mass2 >= maxMass || this_inj->mass2 <= minMass )
      {
        LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
        this_inj->mass1 = minMass + u * deltaM;
        this_inj->mass2 = mtotal - this_inj->mass1;
      }
      this_inj->eta = this_inj->mass1 * this_inj->mass2 / ( mtotal * mtotal );
      this_inj->mchirp = (this_inj->mass1 + this_inj->mass2) * 
        pow(this_inj->eta, 0.6);

    }

     /* spatial distribution */

#if 0
     LAL_CALL( LALUniformDeviate( &status, &u, randParams ),
            &status );
     sinphi = 2.0 * u - 1.0;
     cosphi = sqrt( 1.0 - sinphi*sinphi );
#endif

     if (ddistr == 0)
     /* uniform distribution in distance */
     {
       REAL4 deltaD = dmax - dmin ;
       LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
       this_inj->distance = dmin + deltaD * u ;
      }
      else if (ddistr == 1)
      /* uniform distribution in log(distance) */
      {
        REAL4 lmin = log10(dmin);
        REAL4 lmax = log10(dmax);
        REAL4 deltaL = lmax - lmin;
        LAL_CALL(  LALUniformDeviate(&status,&u,randParams),&status );
        exponent = lmin + deltaL * u;
        this_inj->distance = pow(10.0,(REAL4) exponent);
      }
     else if (ddistr == 2)
     /* uniform volume distribution */
     {
       REAL4 d2min = pow(dmin,3.0) ;
       REAL4 d2max = pow(dmax,3.0) ;
       REAL4 deltad2 = d2max - d2min ;
       LAL_CALL(  LALUniformDeviate(&status,&u,randParams),&status );
       d2 = d2min + u * deltad2 ;
       this_inj->distance = pow(d2,1.0/3.0);
     }

     this_inj->distance = this_inj->distance / 1000.0; /*convert to Mpc */
       

      /* compute random longitude and latitude */
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->latitude = asin( 2.0 * u - 1.0 ) ;
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      this_inj->longitude = LAL_TWOPI * u ;
     

#if 0
    LAL_CALL( LALGalacticInspiralParamsToSimInspiralTable( &status,
          this_inj, &galacticPar, randParams ), &status );
    if (vrbflg)
    { 
      fprintf( stdout, "%e\n",
      sqrt(galacticPar.z*galacticPar.z+galacticPar.rho*galacticPar.rho
          + Rcore*Rcore + 2.0*Rcore*galacticPar.rho*cos(galacticPar.lGal))-
      this_inj->distance*1000.0);
    }
#endif


    /* set the source and waveform fields */
    snprintf( this_inj->source, LIGOMETA_SOURCE_MAX, "???" );
    memcpy( this_inj->waveform, waveform, LIGOMETA_WAVEFORM_MAX *
        sizeof(CHAR));

    /* XXX CHECK XXX */
    /* compute random inclination, polarization and coalescence phase */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->inclination = acos( 2.0 * u - 1.0 );
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->polarization = LAL_TWOPI * u ;
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    this_inj->coa_phase = LAL_TWOPI * u ;
    
    /* populate the site specific information */
    LAL_CALL(LALPopulateSimInspiralSiteInfo( &status, this_inj ), 
        &status);
    
    /* increment the injection time */
    XLALGPSAdd( &gpsStartTime, meanTimeStep );

    /* finally populate the flower */
    if (fLower > 0)         
    {
        this_inj->f_lower = fLower;
    }
    else
    {
        this_inj->f_lower = 0;
    }
    /* XXX END CHECK XXX */

  } /* end loop over injection times */

  /* destroy random parameters */
  LAL_CALL( LALDestroyRandomParams( &status, &randParams ), &status );


  /*
   *
   * write output to LIGO_LW XML file
   *
   */


  /* open the xml file */
  memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlfp, fname ), &status );

  /* write the process table */
  snprintf( proctable.processTable->ifos, LIGOMETA_IFOS_MAX, "H1H2L1" );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_table ), 
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, proctable, 
        process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  free( proctable.processTable );

  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );

  /* write the process params table */
  if ( procparams.processParamsTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_params_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, procparams, 
          process_params_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
    while( procparams.processParamsTable )
    {
      this_proc_param = procparams.processParamsTable;
      procparams.processParamsTable = this_proc_param->next;
      free( this_proc_param );
    }
  }

  /* write the sim_inspiral table */
  if ( injections.simInspiralTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, sim_inspiral_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, injections, 
          sim_inspiral_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  }
  while ( injections.simInspiralTable )
  {
    this_inj = injections.simInspiralTable;
    injections.simInspiralTable = injections.simInspiralTable->next;
    LALFree( this_inj );
  }

  /* close the injection file */
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlfp ), &status );

  /* check for memory leaks and exit */
  LALCheckMemoryLeaks();
  return 0;
}
int STREAMGETSERIES(STYPE * series, LALFrStream * stream)
{
    const REAL8 fuzz = 0.1 / 16384.0;   /* smallest discernable time */
    const size_t size = sizeof(TYPE);
    size_t noff;
    size_t need;
    size_t ncpy;
    TYPE *dest;
    STYPE *buffer;
    LIGOTimeGPS tend;
    INT8 tnow;
    INT8 tbeg;
    int gap = 0;

    XLAL_CHECK(!(stream->state & LAL_FR_STREAM_END), XLAL_EIO);
    XLAL_CHECK(!(stream->state & LAL_FR_STREAM_ERR), XLAL_EIO);

    /* if series does not have allocation for data,
     * we are to return metadata only, so we don't
     * need to load data in the next call */
    if (series->data && series->data->length)
        buffer = READSERIES(stream->file, series->name, stream->pos);
    else
        buffer = READSERIESMETA(stream->file, series->name, stream->pos);
    if (!buffer)
        XLAL_ERROR(XLAL_EFUNC);

    tnow = XLALGPSToINT8NS(&stream->epoch);
    tbeg = XLALGPSToINT8NS(&buffer->epoch);

    /* Make sure that we aren't requesting data
     * that comes before the current frame.
     * Allow 1 millisecond padding to account
     * for double precision */
    if (tnow + 1000 < tbeg) {
        DESTROYSERIES(buffer);
        XLAL_ERROR(XLAL_ETIME);
    }

    /* compute number of points offset very carefully:
     * if current time is within fuzz of a sample, get
     * that sample; otherwise get the sample just after
     * the requested time */
    noff = ceil((1e-9 * (tnow - tbeg) - fuzz) / buffer->deltaT);

    /* adjust current time to be exactly the first sample
     * (rounded to nearest nanosecond) */
    tnow = tbeg + floor(1e9 * noff * buffer->deltaT + 0.5);
    XLALINT8NSToGPS(&series->epoch, tnow);
    series->deltaT = buffer->deltaT;
    series->sampleUnits = buffer->sampleUnits;

    /* end here if all you want is metadata */
    if (!series->data || !series->data->length) {
        DESTROYSERIES(buffer);
        return 0;
    }

    /* the rest of this function is to get the required
     * amount of data and copy it into the series */

    dest = series->data->data;  /* pointer to where to put the data */
    need = series->data->length;        /* number of points that are needed */

    if (noff > buffer->data->length) {
        /* invalid time offset */
        DESTROYSERIES(buffer);
        XLAL_ERROR(XLAL_ETIME);
    }

    /* copy as much of the buffer is needed */
    ncpy =
        (buffer->data->length - noff) <
        need ? buffer->data->length - noff : need;
    memcpy(dest, buffer->data->data + noff, ncpy * size);
    dest += ncpy;
    need -= ncpy;

    DESTROYSERIES(buffer);

    /* continue while data is required */
    while (need) {

        /* goto next frame */
        if (XLALFrStreamNext(stream) < 0)
            XLAL_ERROR(XLAL_EFUNC);
        if (stream->state & LAL_FR_STREAM_END)
            XLAL_ERROR(XLAL_EIO,
                "End of frame stream while %zd points remain to be read",
                need);

        /* load more data */
        buffer = READSERIES(stream->file, series->name, stream->pos);
        if (!buffer)
            XLAL_ERROR(XLAL_EFUNC);

        if (stream->state & LAL_FR_STREAM_GAP) {
            /* gap in data: reset dest and need and set epoch */
            dest = series->data->data;
            need = series->data->length;
            series->epoch = buffer->epoch;
            gap = 1;
        }

        /* copy data */
        ncpy = buffer->data->length < need ? buffer->data->length : need;
        memcpy(dest, buffer->data->data, ncpy * size);
        dest += ncpy;
        need -= ncpy;
        DESTROYSERIES(buffer);
    }

    /* update stream start time so that it corresponds to the
     * exact time of the next sample to be read */
    stream->epoch = series->epoch;
    XLALGPSAdd(&stream->epoch, series->data->length * series->deltaT);

    /* are we still within the current frame? */
    XLALFrFileQueryGTime(&tend, stream->file, stream->pos);
    XLALGPSAdd(&tend, XLALFrFileQueryDt(stream->file, stream->pos));
    if (XLALGPSCmp(&tend, &stream->epoch) <= 0) {
        /* advance a frame... note that failure here is
         * benign so we suppress gap warnings: these will
         * be triggered on the next read (if one is done) */
        int savemode = stream->mode;
        LIGOTimeGPS saveepoch = stream->epoch;
        stream->mode |= LAL_FR_STREAM_IGNOREGAP_MODE;   /* ignore gaps for now */
        if (XLALFrStreamNext(stream) < 0) {
            stream->mode = savemode;
            XLAL_ERROR(XLAL_EFUNC);
        }
        if (!(stream->state & LAL_FR_STREAM_GAP))       /* no gap: reset epoch */
            stream->epoch = saveepoch;
        stream->mode = savemode;
    }

    /* make sure to set the gap flag in the stream state
     * if a gap had been encountered during the reading */
    if (gap)
        stream->state |= LAL_FR_STREAM_GAP;
    /* FIXME:
     * does this need to cause a failure if mode is set to fail on gaps? */

    /* if the stream state is an error then fail */
    if (stream->state & LAL_FR_STREAM_ERR)
        XLAL_ERROR(XLAL_EIO);

    return 0;
}
/**
 * some basic consistency checks of the (XLAL) UserInput module, far from exhaustive,
 * but should be enough to catch big obvious malfunctions
 */
int
main(void)
{
  int i, my_argc = 8;
  char **my_argv;
  const char *argv_in[] = { "progname", "--argNum=1", "--argStr=xyz", "--argBool=true", "-a", "1", "-b", "@" TEST_DATA_DIR "ConfigFileSample.cfg" };
  UserInput_t XLAL_INIT_DECL(my_uvars);

  my_argv = XLALCalloc ( my_argc, sizeof(char*) );
  for (i=0; i < my_argc; i ++ )
    {
      my_argv[i] = XLALCalloc ( 1, strlen(argv_in[i])+1);
      strcpy ( my_argv[i], argv_in[i] );
    }

  /* ---------- Register all test user-variables ---------- */
  UserInput_t *uvar = &my_uvars;
  uvar->string2 = XLALStringDuplicate ( "this is the default value");

  XLAL_CHECK ( XLALRegisterUvarMember( argNum, REAL8, 0, REQUIRED, "Testing float argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( argStr, STRING, 0, REQUIRED, "Testing string argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( argBool, BOOLEAN, 0, REQUIRED, "Testing bool argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( argInt, INT4, 'a', REQUIRED, "Testing INT4 argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( dummy,  INT4, 'c', OPTIONAL, "Testing INT4 argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( argB2, BOOLEAN, 'b', REQUIRED, "Testing short-option bool argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( string2, STRING, 0, REQUIRED, "Testing another string argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( epochGPS, EPOCH, 0, REQUIRED, "Testing epoch given as GPS time") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( epochMJDTT, EPOCH, 0, REQUIRED, "Testing epoch given as MJD(TT) time") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( longHMS, RAJ, 0, REQUIRED, "Testing RAJ(HMS) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( longRad, RAJ, 0, REQUIRED, "Testing RAJ(rad) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( latDMS, DECJ, 0, REQUIRED, "Testing DECJ(DMS) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( latRad, DECJ, 0, REQUIRED, "Testing DECJ(rad) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( longInt, INT8, 0, REQUIRED, "Testing INT8 argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALRegisterUvarMember( long_help, BOOLEAN, 0, NODEFAULT,
                                       "This option is here to test the help page wrapping of long strings. "
                                       "This option is here to test the help page wrapping of long strings. "
                                       "This option is here to test the help page wrapping of long strings. "
                                       "This option is here to test the help page wrapping of long strings. "
                                       "This option is here to test the help page wrapping of long strings. "
                                       "\n"
                                       "This~option~is~here~to~test~the~help~page~wrapping~of~long~strings~without~spaces.~"
                                       "This~option~is~here~to~test~the~help~page~wrapping~of~long~strings~without~spaces.~"
                                       "This~option~is~here~to~test~the~help~page~wrapping~of~long~strings~without~spaces."
                 ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* ---------- now read all input from commandline and config-file ---------- */
  BOOLEAN should_exit = 0;
  XLAL_CHECK ( XLALUserVarReadAllInput ( &should_exit, my_argc, my_argv ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( should_exit == 0, XLAL_EFUNC );

  /* ---------- test print usage and help page */
  printf( "=== Begin usage string ===\n" );
  fflush( stdout );
  XLALUserVarPrintUsage( stdout );
  printf( "--- End usage string ---\n" );
  printf( "=== Begin help page ===\n" );
  fflush( stdout );
  XLALUserVarPrintHelp( stdout );
  printf( "--- End help page ---\n" );
  fflush( stdout );

  /* ---------- test log-generation */
  CHAR *logstr;
  XLAL_CHECK ( ( logstr = XLALUserVarGetLog (   UVAR_LOGFMT_CFGFILE )) != NULL, XLAL_EFUNC );
  XLALFree ( logstr );

  /* ---------- test values were read in correctly ---------- */
  XLAL_CHECK ( uvar->argNum == 1, XLAL_EFAILED, "Failed to read in argNum\n" );
  XLAL_CHECK ( strcmp ( uvar->argStr, "xyz" ) == 0, XLAL_EFAILED, "Failed to read in argStr\n" );
  XLAL_CHECK ( uvar->argBool, XLAL_EFAILED, "Failed to read in argBool\n" );
  XLAL_CHECK ( uvar->argInt == 1, XLAL_EFAILED, "Failed to read in argInt\n" );
  XLAL_CHECK ( uvar->argB2, XLAL_EFAILED, "Failed to read in argB2\n" );
  XLAL_CHECK ( strcmp ( uvar->string2, "this is also possible, and # here does nothing; and neither does semi-colon " ) == 0, XLAL_EFAILED, "Failed to read in string2\n" );

  char buf1[256], buf2[256];
  XLAL_CHECK ( XLALGPSCmp ( &uvar->epochGPS, &uvar->epochMJDTT ) == 0, XLAL_EFAILED, "GPS epoch %s differs from MJD(TT) epoch %s\n",
               XLALGPSToStr ( buf1, &uvar->epochGPS), XLALGPSToStr ( buf2, &uvar->epochMJDTT ) );

  REAL8 diff, tol = 3e-15;
  XLAL_CHECK ( (diff = fabs(uvar->longHMS - uvar->longRad)) < tol, XLAL_EFAILED, "longitude(HMS) = %.16g differs from longitude(rad) = %.16g by %g > %g\n", uvar->longHMS, uvar->longRad, diff, tol );
  XLAL_CHECK ( (diff = fabs(uvar->latDMS - uvar->latRad)) < tol, XLAL_EFAILED, "latitude(HMS) = %.16g differs from latitude(rad) = %.16g by %g > %g\n", uvar->latDMS, uvar->latRad, diff, tol );

  XLAL_CHECK ( uvar->longInt == 4294967294, XLAL_EFAILED, "Failed to read an INT8: longInt = %" LAL_INT8_FORMAT " != 4294967294", uvar->longInt );

  /* ----- cleanup ---------- */
  XLALDestroyUserVars();
  for (i=0; i < my_argc; i ++ ) {
    XLALFree ( my_argv[i] );
  }
  XLALFree ( my_argv );

  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} // main()
/**
 * Set up a full multi-dimensional grid-scan.
 * Currently this only emulates a 'factored' grid-scan with 'sky x Freq x f1dot ...' , but
 * keeps all details within the DopplerScan module for future extension to real multidimensional
 * grids.
 *
 * NOTE: Use 'XLALNextDopplerPos()' to step through this template grid.
 *
 */
DopplerFullScanState *
XLALInitDopplerFullScan ( const DopplerFullScanInit *init       /**< [in] initialization parameters */
                          )
{
  XLAL_CHECK_NULL ( init != NULL, XLAL_EINVAL );

  DopplerFullScanState *thisScan;
  XLAL_CHECK_NULL ( (thisScan = LALCalloc (1, sizeof(*thisScan) )) != NULL, XLAL_ENOMEM );

  thisScan->gridType = init->gridType;

  /* store the user-input spinRange (includes refTime) in DopplerFullScanState */
  thisScan->spinRange.refTime = init->searchRegion.refTime;
  memcpy ( thisScan->spinRange.fkdot, init->searchRegion.fkdot, sizeof(PulsarSpins) );
  memcpy ( thisScan->spinRange.fkdotBand, init->searchRegion.fkdotBand, sizeof(PulsarSpins) );

  // check that some old metric-codes aren't used with refTime!=startTime, which they don't handle correctly
  switch ( thisScan->gridType )
    {
    case GRID_METRIC:
    case GRID_METRIC_SKYFILE:
    case GRID_SPINDOWN_SQUARE: /* square parameter space */
    case GRID_SPINDOWN_AGEBRK: /* age-braking index parameter space */

      XLAL_CHECK_NULL ( XLALGPSDiff ( &init->startTime, &init->searchRegion.refTime ) == 0, XLAL_EINVAL,
                        "NOTE: gridType={metric,4,spin-square,spin-age-brk} only work for refTime (%f) == startTime (%f)!\n",
                        XLALGPSGetREAL8(&(init->searchRegion.refTime)), XLALGPSGetREAL8(&(init->startTime)) );;

      break;
    default:
      break;
    }

  /* which "class" of template grid to generate?: factored, or full-multidim ? */
  switch ( thisScan->gridType )
    {
      /* emulate old 'factored' grids 'sky x f0dot x f1dot x f2dot x f3dot': */
    case GRID_FLAT:
    case GRID_ISOTROPIC:
    case GRID_METRIC:
    case GRID_FILE_SKYGRID:
    case GRID_METRIC_SKYFILE:
      /* backwards-compatibility mode */
      XLAL_CHECK_NULL ( XLALInitFactoredGrid ( thisScan, init ) == XLAL_SUCCESS, XLAL_EFUNC );
      break;

      /* ----- multi-dimensional covering of full parameter space ----- */
    case GRID_FILE_FULLGRID:
      XLAL_CHECK_NULL ( XLALLoadFullGridFile ( thisScan, init ) == XLAL_SUCCESS, XLAL_EFUNC );
      break;

    case GRID_SPINDOWN_SQUARE: /* square parameter space */
    case GRID_SPINDOWN_AGEBRK: /* age-braking index parameter space */
      {
        const size_t n = 2 + PULSAR_MAX_SPINS;

        /* Check that the reference time is the same as the start time */
        XLAL_CHECK_NULL ( XLALGPSCmp ( &thisScan->spinRange.refTime, &init->startTime) == 0, XLAL_EINVAL,
                          "\nGRID_SPINDOWN_{SQUARE,AGEBRK}: This option currently restricts the reference time to be the same as the start time.\n");

        /* Create a vector to hold lattice tiling parameter-space points */
        XLAL_CHECK_NULL ( (thisScan->spindownTilingPoint = gsl_vector_alloc(n)) != NULL, XLAL_ENOMEM,
                          "\nGRID_SPINDOWN_{SQUARE,AGEBRK}: gsl_vector_alloc failed\n");

        /* Create a lattice tiling */
        XLAL_CHECK_NULL ( (thisScan->spindownTiling = XLALCreateLatticeTiling(n)) != NULL, XLAL_EFUNC );

        /* Parse the sky region string and check that it consists of only one point, and set bounds on it */
        SkyRegion XLAL_INIT_DECL(sky);
        XLAL_CHECK_NULL ( XLALParseSkyRegionString ( &sky, init->searchRegion.skyRegionString ) == XLAL_SUCCESS, XLAL_EFUNC );
        XLAL_CHECK_NULL ( sky.numVertices == 1, XLAL_EINVAL, "\nGRID_SPINDOWN_{SQUARE,AGEBRK}: This option can only handle a single sky position.\n");
        XLAL_CHECK_NULL ( sky.vertices[0].system == COORDINATESYSTEM_EQUATORIAL, XLAL_EINVAL, "\nGRID_SPINDOWN_{SQUARE,AGEBRK}: This option only understands COORDINATESYSTEM_EQUATORIAL\n");

        XLAL_CHECK_NULL ( XLALSetLatticeTilingConstantBound(thisScan->spindownTiling, 0, sky.vertices[0].longitude, sky.vertices[0].longitude) == XLAL_SUCCESS, XLAL_EFUNC );

        XLAL_CHECK_NULL ( XLALSetLatticeTilingConstantBound(thisScan->spindownTiling, 1, sky.vertices[0].latitude, sky.vertices[0].latitude) == XLAL_SUCCESS, XLAL_EFUNC );
        if (sky.vertices) {
          XLALFree (sky.vertices);
        }

        /* Set up parameter space */
        if (thisScan->gridType == GRID_SPINDOWN_SQUARE) { /* square parameter space */

          /* Set square bounds on the frequency and spindowns */
          for (size_t i = 0; i < PULSAR_MAX_SPINS; ++i) {
            XLAL_CHECK_NULL ( XLALSetLatticeTilingConstantBound(thisScan->spindownTiling, 2 + i, init->searchRegion.fkdot[i], init->searchRegion.fkdot[i] + init->searchRegion.fkdotBand[i]) == XLAL_SUCCESS, XLAL_EFUNC );
          }

        } else if (thisScan->gridType == GRID_SPINDOWN_AGEBRK) { /* age-braking index parameter space */

          /* Get age and braking index from extra arguments */
          const REAL8 spindownAge = init->extraArgs[0];
          const REAL8 minBraking = init->extraArgs[1];
          const REAL8 maxBraking = init->extraArgs[2];

          /* Set age-braking index parameter space */
          XLAL_CHECK_NULL ( XLAL_SUCCESS == XLALSetLatticeTilingConstantBound(thisScan->spindownTiling, 2, init->searchRegion.fkdot[0], init->searchRegion.fkdot[0] + init->searchRegion.fkdotBand[0]), XLAL_EFUNC );
          XLAL_CHECK_NULL ( XLAL_SUCCESS == XLALSetLatticeTilingF1DotAgeBrakingBound(thisScan->spindownTiling, 2, 3, spindownAge, minBraking, maxBraking), XLAL_EFUNC );
          XLAL_CHECK_NULL ( XLAL_SUCCESS == XLALSetLatticeTilingF2DotBrakingBound(thisScan->spindownTiling, 2, 3, 4, minBraking, maxBraking), XLAL_EFUNC );

          /* This current only goes up to second spindown, so bound higher dimensions */
          for (size_t i = 3; i < PULSAR_MAX_SPINS; ++i) {
            XLAL_CHECK_NULL ( XLAL_SUCCESS == XLALSetLatticeTilingConstantBound(thisScan->spindownTiling, 2 + i, init->searchRegion.fkdot[i], init->searchRegion.fkdot[i] + init->searchRegion.fkdotBand[i]), XLAL_EFUNC );
          }

        }

        /* Create a lattice tiling with Anstar lattice and spindown metric */
        gsl_matrix* metric;
        XLAL_CHECK_NULL ( (metric = gsl_matrix_alloc(n, n)) != NULL, XLAL_ENOMEM );
        gsl_matrix_set_identity(metric);
        gsl_matrix_view spin_metric = gsl_matrix_submatrix(metric, 2, 2, PULSAR_MAX_SPINS, PULSAR_MAX_SPINS);
        XLAL_CHECK_NULL ( XLALSpindownMetric(&spin_metric.matrix, init->Tspan) == XLAL_SUCCESS, XLAL_EFUNC );
        XLAL_CHECK_NULL ( XLALSetTilingLatticeAndMetric(thisScan->spindownTiling, "Ans", metric, init->metricMismatch) == XLAL_SUCCESS, XLAL_EFUNC );

        /* Create iterator over flat lattice tiling */
        XLAL_CHECK_NULL ( (thisScan->spindownTilingItr = XLALCreateLatticeTilingIterator(thisScan->spindownTiling, n)) != NULL, XLAL_EFUNC );

        /* Cleanup */
        gsl_matrix_free(metric);

      }

      break;

    default:
      XLAL_ERROR_NULL ( XLAL_EINVAL, "\nInvalid grid type '%d'\n\n", init->gridType );
      break;
    } /* switch gridType */

  /* we're ready */
  thisScan->state = STATE_READY;

  /* return result */
  return thisScan;

} // XLALInitDopplerFullScan()
Exemple #11
0
/**
 * some basic consistency checks of the (XLAL) UserInput module, far from exhaustive,
 * but should be enough to catch big obvious malfunctions
 */
int
main(int argc, char *argv[])
{
  int i, my_argc = 8;
  char **my_argv;
  const char *argv_in[] = { "progname", "--argNum=1", "--argStr=xyz", "--argBool=true", "-a", "1", "-b", "@" TEST_DATA_DIR "ConfigFileSample.cfg" };
  UserInput_t XLAL_INIT_DECL(my_uvars);

  XLAL_CHECK ( argc == 1, XLAL_EINVAL, "No input arguments allowed.\n");

  my_argv = XLALCalloc ( my_argc, sizeof(char*) );
  for (i=0; i < my_argc; i ++ )
    {
      my_argv[i] = XLALCalloc ( 1, strlen(argv_in[i])+1);
      strcpy ( my_argv[i], argv_in[i] );
    }

  /* ---------- Register all test user-variables ---------- */
  UserInput_t *uvar = &my_uvars;
  XLAL_CHECK ( XLALregREALUserStruct( argNum, 0, UVAR_REQUIRED, "Testing float argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregSTRINGUserStruct( argStr, 0, UVAR_REQUIRED, "Testing string argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregBOOLUserStruct( argBool, 0, UVAR_REQUIRED, "Testing bool argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregINTUserStruct( argInt, 'a', UVAR_REQUIRED, "Testing INT argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregINTUserStruct( dummy,  'c', UVAR_OPTIONAL, "Testing INT argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregBOOLUserStruct( argB2, 'b', UVAR_REQUIRED, "Testing short-option bool argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregSTRINGUserStruct( string2, 0, UVAR_REQUIRED, "Testing another string argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregEPOCHUserStruct( epochGPS, 0, UVAR_REQUIRED, "Testing epoch given as GPS time") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregEPOCHUserStruct( epochMJDTT, 0, UVAR_REQUIRED, "Testing epoch given as MJD(TT) time") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregRAJUserStruct( longHMS, 0, UVAR_REQUIRED, "Testing RAJ(HMS) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregRAJUserStruct( longRad, 0, UVAR_REQUIRED, "Testing RAJ(rad) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregDECJUserStruct( latDMS, 0, UVAR_REQUIRED, "Testing DECJ(DMS) argument") == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALregDECJUserStruct( latRad, 0, UVAR_REQUIRED, "Testing DECJ(rad) argument") == XLAL_SUCCESS, XLAL_EFUNC );

  /* ---------- now read all input from commandline and config-file ---------- */
  XLAL_CHECK ( XLALUserVarReadAllInput ( my_argc, my_argv ) == XLAL_SUCCESS, XLAL_EFUNC );

  /* ---------- test help-string generation */
  CHAR *helpstr;
  XLAL_CHECK ( (helpstr = XLALUserVarHelpString ( argv[0])) != NULL, XLAL_EFUNC );
  XLALFree ( helpstr );

  /* ---------- test log-generation */
  CHAR *logstr;
  XLAL_CHECK ( ( logstr = XLALUserVarGetLog (   UVAR_LOGFMT_CFGFILE )) != NULL, XLAL_EFUNC );
  XLALFree ( logstr );

  /* ---------- test values were read in correctly ---------- */
  XLAL_CHECK ( uvar->argNum == 1, XLAL_EFAILED, "Failed to read in argNum\n" );
  XLAL_CHECK ( strcmp ( uvar->argStr, "xyz" ) == 0, XLAL_EFAILED, "Failed to read in argStr\n" );
  XLAL_CHECK ( uvar->argBool, XLAL_EFAILED, "Failed to read in argBool\n" );
  XLAL_CHECK ( uvar->argInt == 1, XLAL_EFAILED, "Failed to read in argInt\n" );
  XLAL_CHECK ( uvar->argB2, XLAL_EFAILED, "Failed to read in argB2\n" );
  XLAL_CHECK ( strcmp ( uvar->string2, "this is also possible, and # here does nothing; and neither does semi-colon " ) == 0, XLAL_EFAILED, "Failed to read in string2\n" );

  char buf1[256], buf2[256];
  XLAL_CHECK ( XLALGPSCmp ( &uvar->epochGPS, &uvar->epochMJDTT ) == 0, XLAL_EFAILED, "GPS epoch %s differs from MJD(TT) epoch %s\n",
               XLALGPSToStr ( buf1, &uvar->epochGPS), XLALGPSToStr ( buf2, &uvar->epochMJDTT ) );

  REAL8 diff, tol = 3e-15;
  XLAL_CHECK ( (diff = fabs(uvar->longHMS - uvar->longRad)) < tol, XLAL_EFAILED, "longitude(HMS) = %.16g differs from longitude(rad) = %.16g by %g > tolerance\n", uvar->longHMS, uvar->longRad, diff, tol );
  XLAL_CHECK ( (diff = fabs(uvar->latDMS - uvar->latRad)) < tol, XLAL_EFAILED, "latitude(HMS) = %.16g differs from latitude(rad) = %.16g by %g > tolerance\n", uvar->latDMS, uvar->latRad, diff, tol );

  /* ----- cleanup ---------- */
  XLALDestroyUserVars();
  for (i=0; i < my_argc; i ++ ) {
    XLALFree ( my_argv[i] );
  }
  XLALFree ( my_argv );

  LALCheckMemoryLeaks();

  return XLAL_SUCCESS;

} // main()
Exemple #12
0
///
/// Compare two output results and return whether they are equal
///
int XLALWeaveOutputResultsCompare(
  BOOLEAN *equal,
  const WeaveSetupData *setup,
  const REAL8 param_tol_mism,
  const VectorComparison *result_tol,
  const WeaveOutputResults *out_1,
  const WeaveOutputResults *out_2
  )
{

  // Check input
  XLAL_CHECK( equal != NULL, XLAL_EFAULT );
  XLAL_CHECK( setup != NULL, XLAL_EFAULT );
  XLAL_CHECK( param_tol_mism >= 0, XLAL_EINVAL );
  XLAL_CHECK( result_tol != NULL, XLAL_EFAULT );
  XLAL_CHECK( out_1 != NULL, XLAL_EFAULT );
  XLAL_CHECK( out_2 != NULL, XLAL_EFAULT );

  // Output results are assumed equal until we find otherwise
  *equal = 1;

  // Compare reference times
  if ( XLALGPSCmp( &out_1->ref_time, &out_2->ref_time ) != 0 ) {
    *equal = 0;
    XLALPrintInfo( "%s: unequal reference times: %" LAL_GPS_FORMAT " != %" LAL_GPS_FORMAT "\n", __func__, LAL_GPS_PRINT( out_1->ref_time ), LAL_GPS_PRINT( out_2->ref_time ) );
    return XLAL_SUCCESS;
  }

  // Compare number of spindowns
  if ( out_1->nspins != out_2->nspins ) {
    *equal = 0;
    XLALPrintInfo( "%s: unequal number of spindowns: %zu != %zu\n", __func__, out_1->nspins, out_2->nspins );
    return XLAL_SUCCESS;
  }

  // Compare list of detectors
  {
    const BOOLEAN have_det_1 = ( out_1->statistics_params->detectors != NULL ), have_det_2 = ( out_2->statistics_params->detectors != NULL );
    if ( have_det_1 != have_det_2 ) {
      *equal = 0;
      XLALPrintInfo( "%s: unequal presence of detector lists: %i != %i\n", __func__, have_det_1, have_det_2 );
      return XLAL_SUCCESS;
    }
    if ( have_det_1 ) {
      if ( out_1->statistics_params->detectors->length != out_2->statistics_params->detectors->length ) {
        *equal = 0;
        XLALPrintInfo( "%s: unequal number of detectors: %u != %u\n", __func__, out_1->statistics_params->detectors->length, out_2->statistics_params->detectors->length );
        return XLAL_SUCCESS;
      }
      for ( size_t i = 0; i < out_1->statistics_params->detectors->length; ++i ) {
        if ( strcmp( out_1->statistics_params->detectors->data[i], out_2->statistics_params->detectors->data[i] ) != 0 ) {
          *equal = 0;
          XLALPrintInfo( "%s: unequal detectors: %s != %s\n", __func__, out_1->statistics_params->detectors->data[i], out_2->statistics_params->detectors->data[i] );
          return XLAL_SUCCESS;
        }
      }
    }
  }

  // Compare number of per-segment items
  if ( out_1->statistics_params->nsegments != out_2->statistics_params->nsegments ) {
    *equal = 0;
    XLALPrintInfo( "%s: unequal number of segments: %u != %u\n", __func__, out_1->statistics_params->nsegments, out_2->statistics_params->nsegments );
    return XLAL_SUCCESS;
  }

  // Compare toplist statistics
  if ( out_1->statistics_params->toplist_statistics != out_2->statistics_params->toplist_statistics ) {
    *equal = 0;
    char *toplists1, *toplists2;
    toplists1 = XLALPrintStringValueOfUserFlag( ( const int * )&( out_1->statistics_params->toplist_statistics ), &WeaveToplistChoices );
    XLAL_CHECK( toplists1 != NULL, XLAL_EFUNC );
    toplists2 = XLALPrintStringValueOfUserFlag( ( const int * )&( out_2->statistics_params->toplist_statistics ), &WeaveToplistChoices );
    XLAL_CHECK( toplists2 != NULL, XLAL_EFUNC );
    XLALPrintError( "%s: Inconsistent set of toplist statistics: {%s} != {%s}\n", __func__, toplists1, toplists2 );
    XLALFree( toplists1 );
    XLALFree( toplists2 );
    return XLAL_SUCCESS;
  }

  // Compare statistics_to_output
  for ( UINT4 istage = 0; istage < 2; ++ istage ) {
    if ( out_1->statistics_params->statistics_to_output[istage] != out_2->statistics_params->statistics_to_output[istage] ) {
      *equal = 0;
      char *outputs1, *outputs2;
      outputs1 = XLALPrintStringValueOfUserFlag( ( const int * )&( out_1->statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
      XLAL_CHECK( outputs1 != NULL, XLAL_EFUNC );
      outputs2 = XLALPrintStringValueOfUserFlag( ( const int * )&( out_2->statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
      XLAL_CHECK( outputs2 != NULL, XLAL_EFUNC );
      XLALPrintError( "%s: Inconsistent set of stage-%d ouput statistics: {%s} != {%s}\n", __func__, istage, outputs1, outputs2 );
      XLALFree( outputs1 );
      XLALFree( outputs2 );
      return XLAL_SUCCESS;
    }
  }

  // Compare toplists
  for ( size_t i = 0; i < out_1->ntoplists; ++i ) {
    XLAL_CHECK( XLALWeaveResultsToplistCompare( equal, setup, param_tol_mism, result_tol, out_1->toplists[i], out_2->toplists[i] ) == XLAL_SUCCESS, XLAL_EFUNC );
    if ( !*equal ) {
      return XLAL_SUCCESS;
    }
  }


  return XLAL_SUCCESS;

}
Exemple #13
0
///
/// Read results from a FITS file and append to new/existing output results
///
int XLALWeaveOutputResultsReadAppend(
  FITSFile *file,
  WeaveOutputResults **out,
  UINT4 toplist_limit
  )
{

  // Check input
  XLAL_CHECK( file != NULL, XLAL_EFAULT );
  XLAL_CHECK( out != NULL, XLAL_EFAULT );

  // Read reference time
  LIGOTimeGPS ref_time;
  XLAL_CHECK( XLALFITSHeaderReadGPSTime( file, "date-obs", &ref_time ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read number of spindowns
  UINT4 nspins = 0;
  XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "nspins", &nspins ) == XLAL_SUCCESS, XLAL_EFUNC );

  // ----- read elements for 'statistics_params' struct ----------
  WeaveStatisticsParams *statistics_params = XLALCalloc( 1, sizeof( *statistics_params ) );
  XLAL_CHECK( statistics_params != NULL, XLAL_ENOMEM );

  // Read list of detectors
  XLAL_CHECK( XLALFITSHeaderReadStringVector( file, "detect", &( statistics_params->detectors ) ) == XLAL_SUCCESS, XLAL_EFUNC );

  /// Number of segments
  XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "segments", &( statistics_params->nsegments ) ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read names of selected toplist statistics
  char *toplist_stats_names = NULL;
  int toplist_stats = 0;
  XLAL_CHECK( XLALFITSHeaderReadString( file, "toplists", &toplist_stats_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsUserFlag( &toplist_stats, &WeaveToplistChoices, toplist_stats_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALFree( toplist_stats_names );

  // Read names of selected extra output stats
  char *extras_names = NULL;
  int extra_stats = 0;
  XLAL_CHECK( XLALFITSHeaderReadString( file, "extras", &extras_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsUserFlag( &extra_stats, &WeaveStatisticChoices, extras_names ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLALFree( extras_names );

  // Read names of selected recalc stats
  int recalc_stats = 0;
  BOOLEAN exists = 0;
  XLAL_CHECK( XLALFITSHeaderQueryKeyExists( file, "recalc" , &exists ) == XLAL_SUCCESS, XLAL_EFUNC );
  if ( exists ) {
    char *recalc_names = NULL;
    XLAL_CHECK( XLALFITSHeaderReadString( file, "recalc", &recalc_names ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLAL_CHECK( XLALParseStringValueAsUserFlag( &recalc_stats, &WeaveStatisticChoices, recalc_names ) == XLAL_SUCCESS, XLAL_EFUNC );
    XLALFree( recalc_names );
  }

  // Compute and fill the full stats-dependency map
  XLAL_CHECK( XLALWeaveStatisticsParamsSetDependencyMap( statistics_params, toplist_stats, extra_stats, recalc_stats ) == XLAL_SUCCESS, XLAL_EFUNC );

  // Read maximum size of toplists, if not supplied
  if ( toplist_limit == 0 ) {
    XLAL_CHECK( XLALFITSHeaderReadUINT4( file, "toplimit", &toplist_limit ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  // Read whether to output semicoherent/coherent template indexes
  BOOLEAN toplist_tmpl_idx = 0;
  {
    exists = 0;
    XLAL_CHECK( XLALFITSHeaderQueryKeyExists( file, "toptmpli", &exists ) == XLAL_SUCCESS, XLAL_EFUNC );
    if ( exists ) {
      XLAL_CHECK( XLALFITSHeaderReadBOOLEAN( file, "toptmpli", &toplist_tmpl_idx ) == XLAL_SUCCESS, XLAL_EFUNC );
    }
  }

  if ( *out == NULL ) {

    // Create new output results
    *out = XLALWeaveOutputResultsCreate( &ref_time, nspins, statistics_params, toplist_limit, toplist_tmpl_idx );
    XLAL_CHECK( *out != NULL, XLAL_EFUNC );

  } else {

    // Check reference time
    XLAL_CHECK( XLALGPSCmp( &ref_time, &( *out )->ref_time ) == 0, XLAL_EIO, "Inconsistent reference time: %" LAL_GPS_FORMAT " != %" LAL_GPS_FORMAT, LAL_GPS_PRINT( ref_time ), LAL_GPS_PRINT( ( *out )->ref_time ) );

    // Check number of spindowns
    XLAL_CHECK( ( size_t ) nspins == ( *out )->nspins, XLAL_EIO, "Inconsistent number of spindowns: %i != %zu", nspins, ( *out )->nspins );

    // Check if list of detectors agrees
    if ( statistics_params->detectors != NULL ) {
      XLAL_CHECK( statistics_params->detectors->length == ( *out )->statistics_params->detectors->length, XLAL_EIO, "Inconsistent number of detectors: %u != %u", statistics_params->detectors->length, ( *out )->statistics_params->detectors->length );
      for ( size_t i = 0; i < statistics_params->detectors->length; ++i ) {
        XLAL_CHECK( strcmp( statistics_params->detectors->data[i], ( *out )->statistics_params->detectors->data[i] ) == 0, XLAL_EIO, "Inconsistent detectors: %s != %s", statistics_params->detectors->data[i], ( *out )->statistics_params->detectors->data[i] );
      }
    }

    // Check if number of segments agrees
    XLAL_CHECK( statistics_params->nsegments == ( *out )->statistics_params->nsegments, XLAL_EIO, "Inconsistent output per segment?: %i != %u", statistics_params->nsegments, ( *out )->statistics_params->nsegments );

    // Check list of selected toplist statistics
    if ( statistics_params->toplist_statistics != ( *out )->statistics_params->toplist_statistics ) {
      char *toplists1, *toplists2;
      toplists1 = XLALPrintStringValueOfUserFlag( ( const int * )&( statistics_params->toplist_statistics ), &WeaveToplistChoices );
      XLAL_CHECK( toplists1 != NULL, XLAL_EFUNC );
      toplists2 = XLALPrintStringValueOfUserFlag( ( const int * )&( ( *out )->statistics_params->toplist_statistics ), &WeaveToplistChoices );
      XLAL_CHECK( toplists2 != NULL, XLAL_EFUNC );
      XLALPrintError( "Inconsistent set of toplist statistics: %s != %s\n", toplists1, toplists2 );
      XLALFree( toplists1 );
      XLALFree( toplists2 );
      XLAL_ERROR( XLAL_EIO );
    }
    // Check list of selected output statistics
    for ( UINT4 istage = 0; istage < 2; ++ istage ) {
      if ( statistics_params->statistics_to_output[istage] != ( *out )->statistics_params->statistics_to_output[istage] ) {
        char *output1, *output2;
        output1 = XLALPrintStringValueOfUserFlag( ( const int * )&( statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
        XLAL_CHECK( output1 != NULL, XLAL_EFUNC );
        output2 = XLALPrintStringValueOfUserFlag( ( const int * )&( ( *out )->statistics_params->statistics_to_output[istage] ), &WeaveStatisticChoices );
        XLAL_CHECK( output2 != NULL, XLAL_EFUNC );
        XLALPrintError( "Inconsistent set of stage-%d output statistics: {%s} != {%s}\n", istage, output1, output2 );
        XLALFree( output1 );
        XLALFree( output2 );
        XLAL_ERROR( XLAL_EIO );
      }
    }

    XLALWeaveStatisticsParamsDestroy( statistics_params );  // Not creating a new output, so we need to free this

    // Check whether to output semicoherent/coherent template indexes
    XLAL_CHECK( !toplist_tmpl_idx == !( *out )->toplist_tmpl_idx, XLAL_EIO, "Inconsistent output template indexes? %i != %i", toplist_tmpl_idx, ( *out )->toplist_tmpl_idx );

  }

  // Read and append to toplists
  for ( size_t i = 0; i < ( *out )->ntoplists; ++i ) {
    XLAL_CHECK( XLALWeaveResultsToplistReadAppend( file, ( *out )->toplists[i] ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  return XLAL_SUCCESS;

}
///
/// test various string-value parser functions:
/// XLALParseStringValueAsINT8(), XLALParseStringValueAsINT4(), XLALParseStringValueAsREAL8(),
/// XLALParseStringValueAsINT4PlusFrac()
///
int
test_ParseStringValue ( void )
{
  const char *valString;

  // ---------- XLALParseStringValueAsINT8() ----------
  INT8 valINT8, valINT8Ref;
  valString = "9223372036854775807"; // LAL_INT8_MAX
  valINT8Ref = 9223372036854775807;
  XLAL_CHECK ( XLALParseStringValueAsINT8 ( &valINT8, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valINT8 == valINT8Ref, XLAL_ETOL, "XLALParseStringValueAsINT8(%s) failed, return = %" LAL_INT8_FORMAT "\n", valString, valINT8 );

  valString = "4294967294"; // 2 * LAL_INT4_MAX
  valINT8Ref = 4294967294;
  XLAL_CHECK ( XLALParseStringValueAsINT8 ( &valINT8, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valINT8 == valINT8Ref, XLAL_ETOL, "XLALParseStringValueAsINT8(%s) failed, return = %" LAL_INT8_FORMAT "\n", valString, valINT8 );

  valString = "-4294967294"; // -2 * LAL_INT4_MAX
  valINT8Ref = -4294967294;
  XLAL_CHECK ( XLALParseStringValueAsINT8 ( &valINT8, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valINT8 == valINT8Ref, XLAL_ETOL, "XLALParseStringValueAsINT8(%s) failed, return = %" LAL_INT8_FORMAT "\n", valString, valINT8 );

  // this one needs to fail!
  //valString = "18446744073709551616"; // 2 * LAL_INT8_MAX
  //XLAL_CHECK ( XLAL_SUCCESS != XLALParseStringValueAsINT8 ( &valINT8, valString ), XLAL_EFAILED, "XLALParseStringValueAsINT8() failed to catch out-of-range conversion\n" );
  //XLALPrintError ("---------- Not to worry, the above failure was on purpose: ----------\n\n");

  // ---------- XLALParseStringValueAsINT4() ----------
  INT4 valINT4, valINT4Ref;
  valString = "2147483647"; // LAL_INT4_MAX
  valINT4Ref = 2147483647;
  XLAL_CHECK ( XLALParseStringValueAsINT4 ( &valINT4, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valINT4 == valINT4Ref, XLAL_ETOL, "XLALParseStringValueAsINT4(%s) failed, return = %d\n", valString, valINT4 );

  valString = "-1000000";
  valINT4Ref = -1000000;
  XLAL_CHECK ( XLALParseStringValueAsINT4 ( &valINT4, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valINT4 == valINT4Ref, XLAL_ETOL, "XLALParseStringValueAsINT4(%s) failed, return = %d\n", valString, valINT4 );

  // this one needs to fail!
  //valString = "4294967294"; // 2 * LAL_INT4_MAX
  //XLAL_CHECK ( XLAL_SUCCESS != XLALParseStringValueAsINT4 ( &valINT4, valString ), XLAL_EFAILED, "XLALParseStringValueAsINT4() failed to catch out-of-range conversion\n" );
  //XLALPrintError ("---------- Not to worry, the above failure was on purpose: ----------\n\n");

  // ---------- XLALParseStringValueAsREAL8() ----------
  REAL8 valREAL8, valREAL8Ref;
  valString = "2147483647";
  valREAL8Ref = 2147483647;
  XLAL_CHECK ( XLALParseStringValueAsREAL8 ( &valREAL8, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valREAL8 == valREAL8Ref, XLAL_ETOL, "XLALParseStringValueAsREAL8(%s) failed, return = %.16g\n", valString, valREAL8 );

  valString = "-1.1234e10";
  valREAL8Ref = -1.1234e10;
  XLAL_CHECK ( XLALParseStringValueAsREAL8 ( &valREAL8, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( fabs ( (valREAL8 - valREAL8Ref) / valREAL8Ref ) <= LAL_REAL8_EPS, XLAL_ETOL, "XLALParseStringValueAsREAL8(%s) failed, return = %.16g\n", valString, valREAL8 );

  // ---------- XLALParseStringValueAsREAL4() ----------
  REAL4 valREAL4, valREAL4Ref;
  valString = "2147483647";
  valREAL4Ref = 2147483647;
  XLAL_CHECK ( XLALParseStringValueAsREAL4 ( &valREAL4, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( valREAL4 == valREAL4Ref, XLAL_ETOL, "XLALParseStringValueAsREAL4(%s) failed, return = %.16g\n", valString, valREAL4 );

  valString = "-1.1234e10";
  valREAL4Ref = -1.1234e10;
  XLAL_CHECK ( XLALParseStringValueAsREAL4 ( &valREAL4, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( fabs ( (valREAL4 - valREAL4Ref) / valREAL4Ref ) <= LAL_REAL4_EPS, XLAL_ETOL, "XLALParseStringValueAsREAL4(%s) failed, return = %.16g\n", valString, valREAL4 );


  // ---------- XLALParseStringValueAsINT4PlusFrac() ----------
  INT4 valINT, valINTRef;
  REAL8 valFrac, valFracRef;

  valString = "123456789.12345678912345";
  valINTRef = 123456789;
  valFracRef = 0.12345678912345;
  XLAL_CHECK ( XLALParseStringValueAsINT4PlusFrac ( &valINT, &valFrac, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( (valINT == valINTRef) && (fabs( (valFrac - valFracRef) / valFracRef ) <= LAL_REAL8_EPS), XLAL_ETOL,
               "XLALParseStringValueAsINT4PlusFrac(%s) failed, return = (%d, %.16g)\n", valString, valINT, valFrac );

  valString = "-123456789.12345678912345";
  valINTRef = -123456789;
  valFracRef = -0.12345678912345;
  XLAL_CHECK ( XLALParseStringValueAsINT4PlusFrac ( &valINT, &valFrac, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( (valINT == valINTRef) && (fabs( (valFrac - valFracRef) / valFracRef ) <= LAL_REAL8_EPS), XLAL_ETOL,
               "XLALParseStringValueAsINT4PlusFrac(%s) failed, return = (%d, %.16g)\n", valString, valINT, valFrac );

  // ---------- XLALParseStringValueAsGPS() ----------
  LIGOTimeGPS valGPS, valGPSRef = {987654321, 123456789 };

  valString = "987654321.123456789";
  XLAL_CHECK ( XLALParseStringValueAsGPS ( &valGPS, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALGPSCmp ( &valGPS, &valGPSRef ) == 0, XLAL_ETOL, "XLALParseStringValueAsGPS(%s) failed, return = {%d,%d}\n", valString, valGPS.gpsSeconds, valGPS.gpsNanoSeconds );

  // ---------- XLALParseStringValueAsEPOCH() ----------
  XLAL_CHECK ( XLALParseStringValueAsEPOCH ( &valGPS, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALGPSCmp ( &valGPS, &valGPSRef ) == 0, XLAL_ETOL, "XLALParseStringValueAsGPS(%s) failed, return = {%d,%d}\n", valString, valGPS.gpsSeconds, valGPS.gpsNanoSeconds );

  valString = "987654321.123456789GPS";
  XLAL_CHECK ( XLALParseStringValueAsEPOCH ( &valGPS, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALGPSCmp ( &valGPS, &valGPSRef ) == 0, XLAL_ETOL, "XLALParseStringValueAsGPS(%s) failed, return = {%d,%d}\n", valString, valGPS.gpsSeconds, valGPS.gpsNanoSeconds );

  valString = "55675.1848646696387616MJD";
  XLAL_CHECK ( XLALParseStringValueAsEPOCH ( &valGPS, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALGPSCmp ( &valGPS, &valGPSRef ) == 0, XLAL_ETOL, "XLALParseStringValueAsGPS(%s) failed, return = {%d,%d}\n", valString, valGPS.gpsSeconds, valGPS.gpsNanoSeconds );

  valString = "987654321.12345";
  valGPSRef.gpsNanoSeconds = 123450000;
  XLAL_CHECK ( XLALParseStringValueAsEPOCH ( &valGPS, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK ( XLALGPSCmp ( &valGPS, &valGPSRef ) == 0, XLAL_ETOL, "XLALParseStringValueAsGPS(%s) failed, return = {%d,%d}, correct = {%d,%d}\n",
               valString, valGPS.gpsSeconds, valGPS.gpsNanoSeconds, valGPSRef.gpsSeconds, valGPSRef.gpsNanoSeconds );

  // ---------- XLALParseStringValueAsREAL8Range() ----------
  REAL8Range real8Range, real8RangeRef;

  valString = "100";
  real8RangeRef[0] = 100; real8RangeRef[1] = 100;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "150/0.5";
  real8RangeRef[0] = 150; real8RangeRef[1] = 150.5;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "150/-0.5";
  real8RangeRef[0] = 149.5; real8RangeRef[1] = 150;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "200,201";
  real8RangeRef[0] = 200; real8RangeRef[1] = 201;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "203,202";
  real8RangeRef[0] = 202; real8RangeRef[1] = 203;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "-203,-202";
  real8RangeRef[0] = -203; real8RangeRef[1] = -202;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  valString = "250~5";
  real8RangeRef[0] = 245; real8RangeRef[1] = 255;
  XLAL_CHECK( XLALParseStringValueAsREAL8Range(&real8Range, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(real8Range[0] - real8RangeRef[0])/real8RangeRef[0] <= LAL_REAL8_EPS && fabs(real8Range[1] - real8RangeRef[1])/real8RangeRef[1] <= LAL_REAL8_EPS && real8Range[0] <= real8Range[1],
              XLAL_ETOL, "XLALParseStringValueAsREAL8Range(%s) failed, return = {%g,%g}\n", valString, real8Range[0], real8Range[1] );

  // ---------- XLALParseStringValueAsEPOCHRange() ----------
  LIGOTimeGPSRange gpsRange, gpsRangeRef;

  valString = "100200300.4";
  XLALGPSSet(&gpsRangeRef[0], 100200300, 400000000); XLALGPSSet(&gpsRangeRef[1], 100200300, 400000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  valString = "100200300.4/800600400.2";
  XLALGPSSet(&gpsRangeRef[0], 100200300, 400000000); XLALGPSSet(&gpsRangeRef[1], 900800700, 600000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  valString = "100200300.4/-800600400.2";
  XLALGPSSet(&gpsRangeRef[0], -700400099, -800000000); XLALGPSSet(&gpsRangeRef[1], 100200300, 400000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  valString = "200300400.5,600700800.9";
  XLALGPSSet(&gpsRangeRef[0], 200300400, 500000000); XLALGPSSet(&gpsRangeRef[1], 600700800, 900000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  valString = "600700800.9,200300400.5";
  XLALGPSSet(&gpsRangeRef[0], 200300400, 500000000); XLALGPSSet(&gpsRangeRef[1], 600700800, 900000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  valString = "123456789~123456.789";
  XLALGPSSet(&gpsRangeRef[0], 123333332, 211000000); XLALGPSSet(&gpsRangeRef[1], 123580245, 789000000);
  XLAL_CHECK( XLALParseStringValueAsEPOCHRange(&gpsRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALGPSCmp(&gpsRange[0], &gpsRangeRef[0]) == 0 && XLALGPSCmp(&gpsRange[1], &gpsRangeRef[1]) == 0 && XLALGPSCmp(&gpsRange[0], &gpsRange[1]) <= 0, XLAL_ETOL,
              "XLALParseStringValueAsEPOCHRange(%s) failed, return = {{%d,%d},{%d,%d}}\n", valString, gpsRange[0].gpsSeconds, gpsRange[0].gpsNanoSeconds, gpsRange[1].gpsSeconds, gpsRange[1].gpsNanoSeconds );

  // ---------- XLALParseStringValueAsRAJRange() ----------
  REAL8Range rajRange, rajRangeRef;

  valString = "0.1";
  rajRangeRef[0] = 0.1; rajRangeRef[1] = 0.1;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  valString = "10:20:30/0.5";
  rajRangeRef[0] = 2.7074420021562036; rajRangeRef[1] = rajRangeRef[0] + 0.5;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  valString = "10:20:30/-0.5";
  rajRangeRef[0] = 2.7074420021562036 - 0.5; rajRangeRef[1] = rajRangeRef[0] + 0.5;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  valString = "10:20:30,11:22:33";
  rajRangeRef[0] = 2.7074420021562036; rajRangeRef[1] = 2.9781862023718242;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  valString = "11:22:33,10:20:30";
  rajRangeRef[0] = 2.7074420021562036; rajRangeRef[1] = 2.9781862023718242;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  valString = "11:22:33~00:00:44.55";
  rajRangeRef[0] = 2.9749464349478099; rajRangeRef[1] = 2.9814259697958385;
  XLAL_CHECK( XLALParseStringValueAsRAJRange(&rajRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(rajRange[0] - rajRangeRef[0])/rajRangeRef[0] <= LAL_REAL8_EPS && fabs(rajRange[1] - rajRangeRef[1])/rajRangeRef[1] <= LAL_REAL8_EPS && rajRange[0] <= rajRange[1],
              XLAL_ETOL, "XLALParseStringValueAsRAJRange(%s) failed, return = {%g,%g}\n", valString, rajRange[0], rajRange[1] );

  // ---------- XLALParseStringValueAsDECJRange() ----------
  REAL8Range decjRange, decjRangeRef;

  valString = "0.1";
  decjRangeRef[0] = 0.1; decjRangeRef[1] = 0.1;
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  valString = "10:20:30/0.5";
  decjRangeRef[0] = (2.7074420021562036/15); decjRangeRef[1] = decjRangeRef[0] + 0.5;
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  valString = "10:20:30/-0.5";
  decjRangeRef[0] = (2.7074420021562036/15) - 0.5; decjRangeRef[1] = decjRangeRef[0] + 0.5;
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  valString = "10:20:30,11:22:33";
  decjRangeRef[0] = (2.7074420021562036/15); decjRangeRef[1] = (2.9781862023718242/15);
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  valString = "11:22:33,10:20:30";
  decjRangeRef[0] = (2.7074420021562036/15); decjRangeRef[1] = (2.9781862023718242/15);
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  valString = "11:22:33~00:00:44.55";
  decjRangeRef[0] = (2.9749464349478099/15); decjRangeRef[1] = (2.9814259697958385/15);
  XLAL_CHECK( XLALParseStringValueAsDECJRange(&decjRange, valString) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( fabs(decjRange[0] - decjRangeRef[0])/decjRangeRef[0] <= LAL_REAL8_EPS && fabs(decjRange[1] - decjRangeRef[1])/decjRangeRef[1] <= LAL_REAL8_EPS && decjRange[0] <= decjRange[1],
              XLAL_ETOL, "XLALParseStringValueAsDECJRange(%s) failed, return = {%g,%g}\n", valString, decjRange[0], decjRange[1] );

  return XLAL_SUCCESS;
} // test_ParseStringValue()
Exemple #15
0
int main( int argc, char *argv[] )
{
  LALStatus             status = blank_status;
  const INT4            S2StartTime = 729273613; /* Feb 14 2003 16:00:00 UTC */
  const INT4            S2StopTime  = 734367613; /* Apr 14 2003 15:00:00 UTC */

  /* command line options */
  LIGOTimeGPS   gpsStartTime = {S2StartTime, 0};
  LIGOTimeGPS   gpsEndTime   = {S2StopTime, 0};
  REAL8         meanTimeStep = 2630 / LAL_PI;
  REAL8         timeInterval = 0;
  UINT4         randSeed = 1;
  CHAR         *userTag = NULL;
  REAL4         minMass = 0.1;
  REAL4         maxMass = 1.0;
  REAL4         r_core = 5.0;     /* kpc core radius */
  REAL4         r_max = 50.0;     /* kpc halo radius */
  REAL4         q = 1.0;          /* flatten halo */

  /* program variables */
  RandomParams *randParams = NULL;
  REAL4  u;
  REAL4  deltaM;

  int i, stat;
  const int maxIter = 1000;
  const double tol = 1e-6;
  const gsl_root_fsolver_type *solver_type;
  gsl_root_fsolver *solver;
  gsl_function pdf;

  struct halo_pdf_params pdf_params;

  double r_lo, r_hi, r;
  double cosphi, sinphi;
  double pdf_norm;

  GalacticInspiralParamStruc galacticPar;

  /* xml output data */
  CHAR                  fname[256];
  MetadataTable         proctable;
  MetadataTable         procparams;
  MetadataTable         injections;
  ProcessParamsTable   *this_proc_param;
  SimInspiralTable     *this_inj = NULL;
  LIGOLwXMLStream       xmlfp;
  UINT4                 outCompress = 0;

  /* LALgetopt arguments */
  struct LALoption long_options[] =
  {
    {"help",                    no_argument,       0,                'h'},
    {"verbose",                 no_argument,       &vrbflg,           1 },
    {"write-compress",          no_argument,       &outCompress,      1 },
    {"gps-start-time",          required_argument, 0,                'a'},
    {"gps-end-time",            required_argument, 0,                'b'},
    {"time-step",               required_argument, 0,                't'},
    {"time-interval",                required_argument, 0,                     'i'},
    {"seed",                    required_argument, 0,                's'},
    {"minimum-mass",            required_argument, 0,                'A'},
    {"maximum-mass",            required_argument, 0,                'B'},
    {"core-radius",             required_argument, 0,                'p'},
    {"flatten-halo",            required_argument, 0,                'q'},
    {"halo-radius",             required_argument, 0,                'r'},
    {"user-tag",                required_argument, 0,                'Z'},
    {"userTag",                 required_argument, 0,                'Z'},
    {0, 0, 0, 0}
  };
  int c;

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

  /* create the process and process params tables */
  proctable.processTable = (ProcessTable *) 
    calloc( 1, sizeof(ProcessTable) );
  XLALGPSTimeNow(&(proctable.processTable->start_time));
  if (strcmp(CVS_REVISION,"$Revi" "sion$"))
    {
      XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME,
          CVS_REVISION, CVS_SOURCE, CVS_DATE, 0);
    }
  else
    {
      XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME,
          lalappsGitCommitID, lalappsGitGitStatus, lalappsGitCommitDate, 0);
    }
  snprintf( proctable.processTable->comment, LIGOMETA_COMMENT_MAX, " " );
  this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) 
    calloc( 1, sizeof(ProcessParamsTable) );
  

  /*
   *
   * parse command line arguments
   *
   */

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

    c = LALgetopt_long_only( argc, argv,
        "a:A:b:B:hi:p:q:r:s:t:vZ:", 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 'a':
        gpsinput = atol( LALoptarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsStartTime.gpsSeconds = gpsinput;

        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 'b':
        gpsinput = atol( LALoptarg );
        if ( gpsinput < 441417609 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "GPS start time is prior to " 
              "Jan 01, 1994  00:00:00 UTC:\n"
              "(%ld specified)\n",
              long_options[option_index].name, gpsinput );
          exit( 1 );
        }
        gpsEndTime.gpsSeconds = gpsinput;
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%ld", gpsinput );
        break;

      case 's':
        randSeed = atoi( LALoptarg );
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "int", 
              "%d", randSeed );
        break;

      case 't':
        meanTimeStep = (REAL8) atof( LALoptarg );
        if ( meanTimeStep <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time step must be > 0: (%le seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, "float", 
              "%le", meanTimeStep );
        break;

      case 'i':
        timeInterval = atof( LALoptarg );
        if ( timeInterval < 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "time interval must be >= 0: (%le seconds specified)\n",
              long_options[option_index].name, meanTimeStep );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%le", timeInterval );
        break;

      case 'A':
        minMass = (REAL4) atof( LALoptarg );
        if ( minMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "miniumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, minMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", minMass );
        break;

      case 'B':
        maxMass = (REAL4) atof( LALoptarg );
        if ( maxMass <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "maxiumum component mass must be > 0: "
              "(%f solar masses specified)\n",
              long_options[option_index].name, maxMass );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", maxMass );
        break;

      case 'p':
        /* core-radius */
        r_core = (REAL4) atof( LALoptarg );
        if ( r_core <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "galactic core radius must be > 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, r_core );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", r_core );
        break;

      case 'q':
        /* flatten-halo */
        q = (REAL4) atof( LALoptarg );
        if ( q <= 0 || q > 1 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "halo flattening parameter must be in range (0,1]: "
              "(%f specified)\n",
              long_options[option_index].name, q );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", q );
        break;

      case 'r':
        /* max halo radius */
        r_max = (REAL4) atof( LALoptarg );
        if ( r_max <= 0 )
        {
          fprintf( stderr, "invalid argument to --%s:\n"
              "halo radius must be greater than 0: "
              "(%f kpc specified)\n",
              long_options[option_index].name, r_max );
          exit( 1 );
        }
        this_proc_param = this_proc_param->next = 
          next_process_param( long_options[option_index].name, 
              "float", "%e", r_max );
        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 = 
          next_process_param( long_options[option_index].name, 
              "string", "%s", LALoptarg );
        break;

      case 'v':
        vrbflg = 1;
        break;

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

      case '?':
        fprintf( stderr, USAGE );
        exit( 1 );
        break;

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

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


  /*
   *
   * initialization
   *
   */


  /* initialize the random number generator */
  LAL_CALL( LALCreateRandomParams( &status, &randParams, randSeed ), &status );

  /* initialize the gsl solver with the spatial pdf */
  pdf.function = &halo_pdf;
  pdf.params   = &pdf_params;
  solver_type = gsl_root_fsolver_bisection;
  solver = gsl_root_fsolver_alloc( solver_type );
  pdf_params.a = r_core;

  /* normalization for the spatial pdf */
  pdf_norm = r_max - r_core * atan2( r_max, r_core );

  /* mass range */
  deltaM = maxMass - minMass;

  /* null out the head of the linked list */
  injections.simInspiralTable = NULL;

  /* create the output file name */
  if ( userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml.gz",
        randSeed, userTag, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( userTag && !outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d_%s-%d-%d.xml", 
        randSeed, userTag, gpsStartTime.gpsSeconds, 
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else if ( !userTag && outCompress )
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml.gz",
        randSeed, gpsStartTime.gpsSeconds,
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }
  else
  {
    snprintf( fname, sizeof(fname), "HL-INJECTIONS_%d-%d-%d.xml", 
        randSeed, gpsStartTime.gpsSeconds, 
        gpsEndTime.gpsSeconds - gpsStartTime.gpsSeconds );
  }


  /*
   *
   * loop over duration of desired output times
   *
   */


  while ( XLALGPSCmp( &gpsStartTime, &gpsEndTime ) < 0 )
  {
    /* uniformly distributed masses */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.m1 = minMass + u * deltaM;
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.m2 = minMass + u * deltaM;
    
    /* spatial distribution */
    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    pdf_params.u = u * pdf_norm;

    r_lo = 0.0;
    r_hi = r_max;
    gsl_root_fsolver_set( solver, &pdf, r_lo, r_hi );

    for ( i = 0; i < maxIter; ++i )
    {
      gsl_root_fsolver_iterate( solver );
      r = gsl_root_fsolver_root( solver );
      r_lo = gsl_root_fsolver_x_lower( solver );
      r_hi = gsl_root_fsolver_x_upper( solver );
      stat = gsl_root_test_interval( r_lo, r_hi, 0, tol );
      if ( stat == GSL_SUCCESS )
        break;
    }

    if ( stat != GSL_SUCCESS )
    {
      fprintf( stderr, "could not find root after %d iterations\n", maxIter );
      exit( 1 );
    }

    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    sinphi = 2.0 * u - 1.0;
    cosphi = sqrt( 1.0 - sinphi*sinphi );
    
    galacticPar.rho = r * cosphi;
    galacticPar.z   = q * r * sinphi;

    LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
    galacticPar.lGal = LAL_TWOPI * u;    

    if ( vrbflg ) fprintf( stdout, "%e %e %e %e %e\n", 
        galacticPar.m1, galacticPar.m2,
        galacticPar.rho * cos( galacticPar.lGal ),
        galacticPar.rho * sin( galacticPar.lGal ),
        galacticPar.z );

    /* create the sim_inspiral table */
    if ( injections.simInspiralTable )
    {
      this_inj = this_inj->next = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }
    else
    {
      injections.simInspiralTable = this_inj = (SimInspiralTable *)
        LALCalloc( 1, sizeof(SimInspiralTable) );
    }

    /* set the geocentric end time of the injection */
    galacticPar.geocentEndTime = gpsStartTime;
    if ( timeInterval )
    {
      LAL_CALL( LALUniformDeviate( &status, &u, randParams ), &status );
      XLALGPSAdd( &(galacticPar.geocentEndTime), u * timeInterval );
    }

    /* populate the sim_inspiral table */
    LAL_CALL( LALGalacticInspiralParamsToSimInspiralTable( &status,
          this_inj, &galacticPar, randParams ), &status );

    /* set the source and waveform fields */
    snprintf( this_inj->source, LIGOMETA_SOURCE_MAX, "MW" );
    snprintf( this_inj->waveform, LIGOMETA_WAVEFORM_MAX, 
        "GeneratePPNtwoPN" );

    /* increment the injection time */
    XLALGPSAdd( &gpsStartTime, meanTimeStep );
  } /* end loop over injection times */

  /* destroy random parameters */
  LAL_CALL( LALDestroyRandomParams( &status, &randParams ), &status );


  /*
   *
   * write output to LIGO_LW XML file
   *
   */


  /* open the xml file */
  memset( &xmlfp, 0, sizeof(LIGOLwXMLStream) );
  LAL_CALL( LALOpenLIGOLwXMLFile( &status, &xmlfp, fname ), &status );

  /* write the process table */
  snprintf( proctable.processTable->ifos, LIGOMETA_IFOS_MAX, "H1H2L1" );
  XLALGPSTimeNow(&(proctable.processTable->end_time));
  LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_table ), 
      &status );
  LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, proctable, 
        process_table ), &status );
  LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  free( proctable.processTable );

  /* free the unused process param entry */
  this_proc_param = procparams.processParamsTable;
  procparams.processParamsTable = procparams.processParamsTable->next;
  free( this_proc_param );

  /* write the process params table */
  if ( procparams.processParamsTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, process_params_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, procparams, 
          process_params_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
    while( procparams.processParamsTable )
    {
      this_proc_param = procparams.processParamsTable;
      procparams.processParamsTable = this_proc_param->next;
      free( this_proc_param );
    }
  }

  /* write the sim_inspiral table */
  if ( injections.simInspiralTable )
  {
    LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlfp, sim_inspiral_table ), 
        &status );
    LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlfp, injections, 
          sim_inspiral_table ), &status );
    LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlfp ), &status );
  }
  while ( injections.simInspiralTable )
  {
    this_inj = injections.simInspiralTable;
    injections.simInspiralTable = injections.simInspiralTable->next;
    LALFree( this_inj );
  }

  /* close the injection file */
  LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlfp ), &status );

  /* check for memory leaks and exit */
  LALCheckMemoryLeaks();
  return 0;
}
Exemple #16
0
/**
 * @brief Seeks a LALFrStream stream to data at a given time
 * @details
 * The position of a LALFrStream is set so that the net read will
 * be at the specified time.  #LAL_FR_STREAM_END and #LAL_FR_STREAM_GAP
 * bits are turned off in the #LALFrStreamState state.  If the time is before
 * the beginning of the stream, the stream position is set to the beginning of
 * the stream and the routine returns with code 1.  If the time is after the
 * end of the stream, the #LAL_FR_STREAM_END bit is set in the
 * #LALFrStreamState state, and the routine returns with code 2.  If the time
 * is in a gap in the data, the #LAL_FR_STREAM_GAP bit is set in the
 * #LALFrStreamState state, the position is advanced to the next data, and the
 * routine returns with code 3.  If, however, the
 * #LAL_FR_STREAM_IGNORETIME_MODE bit is not set in the LALFrStreamMode mode
 * then these conditions result in an error.
 * @param stream Pointer to a #LALFrStream structure.
 * @param epoch The LIGOTimeGPS time of the next data to read.
 * @retval 3 Time requested is in a gap in the data.
 * @retval 2 Time requested is after the end of the stream.
 * @retval 1 Time requested is before the beginning of the stream.
 * @retval 0 Normal success.
 * @retval <0 Failure.
 */
int XLALFrStreamSeek(LALFrStream * stream, const LIGOTimeGPS * epoch)
{
    double twant = XLALGPSGetREAL8(epoch);
    LALCacheEntry *entry;

    /* close file if one is open */
    XLALFrStreamFileClose(stream);

    /* clear EOF or GAP states; preserve ERR state */
    if (stream->state & LAL_FR_STREAM_ERR)
        stream->state = LAL_FR_STREAM_ERR;
    else
        stream->state = LAL_FR_STREAM_OK;

    /* is epoch before first file? */
    if (epoch->gpsSeconds < stream->cache->list->t0) {
        XLALFrStreamRewind(stream);
        stream->state |= LAL_FR_STREAM_GAP;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d before first frame",
                epoch->gpsSeconds);
        return 1;       /* before first file code */
    }

    /* seek for the time in the cache */
    entry = XLALCacheEntrySeek(stream->cache, twant);
    if (!entry) {       /* seek failed: only happens if time is past end of cache */
        stream->fnum = stream->cache->length;
        stream->epoch = *epoch;
        stream->state |= LAL_FR_STREAM_END;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d after last frame",
                epoch->gpsSeconds);
        return 2;       /* after last file code */
    }

    /* now we must find the position within the frame file */
    for (stream->fnum = entry - stream->cache->list;
        stream->fnum < stream->cache->length; ++stream->fnum) {
        /* check the file contents to determine the position that matches */
        size_t nFrame;
        if (XLALFrStreamFileOpen(stream, stream->fnum) < 0)
            XLAL_ERROR(XLAL_EFUNC);
        if (epoch->gpsSeconds < stream->cache->list[stream->fnum].t0) {
            /* detect a gap between files */
            stream->state |= LAL_FR_STREAM_GAP;
            break;
        }
        nFrame = XLALFrFileQueryNFrame(stream->file);
        for (stream->pos = 0; stream->pos < (int)nFrame; ++stream->pos) {
            LIGOTimeGPS start;
            int cmp;
            XLALFrFileQueryGTime(&start, stream->file, stream->pos);
            cmp = XLALGPSCmp(epoch, &start);
            if (cmp >= 0
                && XLALGPSDiff(epoch,
                    &start) < XLALFrFileQueryDt(stream->file, stream->pos))
                break;  /* this is the frame! */
            if (cmp < 0) {
                /* detect a gap between frames within a file */
                stream->state |= LAL_FR_STREAM_GAP;
                break;
            }
        }
        if (stream->pos < (int)nFrame)  /* we've found the frame */
            break;
        /* oops... not in this frame file, go on to the next one */
        /* probably the frame file was mis-named.... */
        XLALFrStreamFileClose(stream);
    }

    if (stream->fnum >= stream->cache->length) {
        /* we've gone right to the end without finding it! */
        stream->fnum = stream->cache->length;
        stream->epoch = *epoch;
        stream->state |= LAL_FR_STREAM_END;
        /* is this reported as an error? */
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) {
            /* FIXME:  if this is an error, should the stream state say so? */
            /* stream->state |= LAL_FR_STREAM_ERR; */
            XLAL_ERROR(XLAL_ETIME);
        }
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %d after last frame",
                epoch->gpsSeconds);
        return 2;       /* after last file code */
    }

    /* set the time of the stream */
    if (stream->state & LAL_FR_STREAM_GAP) {
        XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos);
        if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE)
            XLAL_PRINT_WARNING("Requested time %.6f in gap in frame data",
                twant);
        if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE))
            XLAL_ERROR(XLAL_ETIME);
        return 3;       /* in a gap code */
    }
    stream->epoch = *epoch;
    return 0;
}