Ejemplo n.º 1
0
///
/// Parse a string representing a range of REAL8 values into a REAL8Range. 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 XLALParseStringValueAsREAL8Range(
  REAL8Range *real8Range,		///< [out] output range of REAL8 values
  const char *valString			///< [in] input string
  )
{

  // Check input
  XLAL_CHECK(real8Range != 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);
  REAL8 val[2];
  XLAL_CHECK( XLALParseStringValueAsREAL8(&val[0], part[0]) == XLAL_SUCCESS, XLAL_EFUNC );
  XLAL_CHECK( XLALParseStringValueAsREAL8(&val[1], part[1]) == XLAL_SUCCESS, XLAL_EFUNC );
  (*real8Range)[0] = T[0][0] * val[0] + T[0][1] * val[1];
  (*real8Range)[1] = T[1][0] * val[0] + T[1][1] * val[1];

  // Check range ordering
  if ((*real8Range)[0] > (*real8Range)[1]) {
    const REAL8 tmp = (*real8Range)[0];
    (*real8Range)[0] = (*real8Range)[1];
    (*real8Range)[1] = tmp;
  }

  return XLAL_SUCCESS;

}
Ejemplo n.º 2
0
/**
 * Parse string-vectors (typically input by user) of N detector noise-floors \f$\sqrt{S_X}\f$
 * for detectors \f$X=1\ldots N\f$, where here we assume equal number of SFTs per detector
 * such that \f$S^{-1} = \frac{1}{N}\sum_{X=0}^{N-1} S_X^{-1}\f$.
 *
 * \note input of length(sqrtSX)=1 < numDetectors is valid: use that single number for all detectors,
 *  otherwise we enforce length(sqrtSX) == numDetectors.
 *
 * returns result in MultiNoiseFloor struct 'multiNoiseFloor'.
 */
int
XLALParseMultiNoiseFloor ( MultiNoiseFloor *multiNoiseFloor,	/**< [out] parsed multi-IFO noise floor info */
                           const LALStringVector *sqrtSX,	/**< [in] string-list of \f$\sqrt{S_X}\f$ for detectors \f$X\f$ */
                           UINT4 numDetectors			/**< [in] number of detectors. NOTE: length[sqrtSX] must be EITHER =numDetectors OR =1 */
                           )
{
  XLAL_CHECK ( multiNoiseFloor != NULL, XLAL_EINVAL );
  XLAL_CHECK ( sqrtSX != NULL, XLAL_EINVAL );
  XLAL_CHECK ( (numDetectors > 0) && (numDetectors <= PULSAR_MAX_DETECTORS), XLAL_EINVAL );
  UINT4 numSqrtSX = sqrtSX->length;
  XLAL_CHECK ( (numSqrtSX == numDetectors) || (numSqrtSX == 1), XLAL_EINVAL );

  /* initialize empty return struct */
  multiNoiseFloor->length = numDetectors;

  /* parse input strings and fill multiNoiseFloor */
  for ( UINT4 X = 0; X < numDetectors; X ++ )
    {
      UINT4 X0 = X % numSqrtSX;		// always = 0 if (numSqrtSX == 1), otherwise = X if (numSqrtSX==numDetectors)
      const char *sqrtSnStr = sqrtSX->data[X0];
      REAL8 sqrtSn;
      XLAL_CHECK ( XLALParseStringValueAsREAL8 ( &sqrtSn, sqrtSnStr ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( sqrtSn >= 0, XLAL_EDOM );
      multiNoiseFloor->sqrtSn[X] = sqrtSn;
    } /* for X < numDetectors */

  return XLAL_SUCCESS;

} /* XLALParseMultiNoiseFloor() */
Ejemplo n.º 3
0
/**
 * Parse string-vectors (typically input by user) of N detector noise-floors \f$\sqrt{S_X}\f$
 * for detectors \f$X=1\ldots N\f$, where here we assume equal number of SFTs per detector
 * such that \f$S^{-1} = \frac{1}{N}\sum_{X=0}^{N-1} S_X^{-1}\f$.
 *
 * The detectors corresponding to each noise-floor may be a subset of the input string-vectors,
 * e.g. if parsing noise-floors for a segment where SFTs from some detectors are missing.
 * The vector \p
 */
int
XLALParseMultiNoiseFloorMapped ( MultiNoiseFloor *multiNoiseFloor,			/**< [out] parsed multi-IFO noise floor info */
                                 const LALStringVector *multiNoiseFloorDetNames,	/**< [in] detector names for entries in \p multiNoiseFloor */
                                 const LALStringVector *sqrtSX,				/**< [in] string-list of \f$\sqrt{S_X}\f$ for detectors \f$X\f$ */
                                 const LALStringVector *sqrtSXDetNames			/**< [in] detector names for entries in \p sqrtSX */
  )
{
  XLAL_CHECK ( multiNoiseFloor != NULL, XLAL_EINVAL );
  XLAL_CHECK ( multiNoiseFloorDetNames != NULL, XLAL_EINVAL );
  XLAL_CHECK ( sqrtSX != NULL, XLAL_EINVAL );
  XLAL_CHECK ( sqrtSXDetNames != NULL, XLAL_EINVAL );
  XLAL_CHECK ( multiNoiseFloorDetNames->length <= sqrtSXDetNames->length, XLAL_EINVAL );
  XLAL_CHECK ( sqrtSX->length == sqrtSXDetNames->length, XLAL_EINVAL );

  /* parse input strings */
  REAL8 sqrtSn[PULSAR_MAX_DETECTORS];
  for ( UINT4 Y = 0; Y < sqrtSX->length; Y ++ )
    {
      XLAL_CHECK ( XLALParseStringValueAsREAL8 ( &sqrtSn[Y], sqrtSX->data[Y] ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLAL_CHECK ( sqrtSn[Y] >= 0, XLAL_EDOM );
    }

  /* initialize empty return struct */
  multiNoiseFloor->length = multiNoiseFloorDetNames->length;

  /* fill multiNoiseFloor with correctly mapped values */
  for ( UINT4 X = 0; X < multiNoiseFloor->length; X ++ )
    {
      const INT4 Y = XLALFindStringInVector( multiNoiseFloorDetNames->data[X], sqrtSXDetNames );
      if ( Y < 0 )
        {
          char *sqrtSXDet = XLALConcatStringVector( sqrtSXDetNames, "," );
          XLAL_PRINT_ERROR ( "Noise-floor detector '%s' not found in list of sqrtSX detectors '%s'", multiNoiseFloorDetNames->data[X], sqrtSXDet );
          XLALFree ( sqrtSXDet );
          XLAL_ERROR ( XLAL_EINVAL );
        }
      multiNoiseFloor->sqrtSn[X] = sqrtSn[Y];
    }

  return XLAL_SUCCESS;

} /* XLALParseMultiNoiseFloorMapped() */
Ejemplo n.º 4
0
///
/// Parse a string representing an 'equatorial latitude' (aka declination or DEC) into REAL8 radians, allowing for both radians or "degrees:minutes:seconds" as input.
///
/// Note that "d:m:s" input is translated into radians using XLALTranslateDMStoRAD().
///
int
XLALParseStringValueAsDECJ ( REAL8 *valDECJ,   	///< [out] return latitude value in radians
                             const char *valString 	///< [in]  input string value
                             )
{
  XLAL_CHECK ( (valDECJ != NULL) && (valString != NULL ), XLAL_EINVAL );

  // ---------- first check if there's a colon ':' somewhere in the string, which indicates "D:M:S" format
  const char *colon;
  if ( (colon = strchr ( valString, ':' )) != NULL )
    {
      XLAL_CHECK ( XLALTranslateDMStoRAD ( valDECJ, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
    }
  else
    {
      XLAL_CHECK ( XLALParseStringValueAsREAL8 ( valDECJ, valString ) == XLAL_SUCCESS, XLAL_EFUNC );
    }

  return XLAL_SUCCESS;

} // XLALParseStringValueAsDECJ()
Ejemplo n.º 5
0
///
/// Parse a string containing a floating-point number into integer and fractional part, such that val = valINT + valFrac.
///
/// This is useful for parsing strings representing GPS or MJD times wihout loss of ns accuracy.
///
int
XLALParseStringValueAsINT4PlusFrac ( INT4 *valINT4,		///< [out] return INT4 integer part 'xxx'
                                     REAL8 *valFrac,      	///< [out] return fractional part '0.yyyy'
                                     const char *valString	///< [in]  input string value representing a floating-point number "xxx.yyyy"
                                     )
{
  XLAL_CHECK ( (valINT4 != NULL) && (valFrac != NULL) && (valString != NULL), XLAL_EINVAL );
  XLAL_CHECK ( !isspace(valString[0]), XLAL_EINVAL, "No initial whitespace allowed in input string '%s'\n", valString );

  char buf[256];
  strncpy ( buf, valString, sizeof(buf)-1 );
  XLAL_LAST_ELEM(buf) = 0;

  REAL8 sign = 1;
  if ( valString[0] == '-' ) {	 // that's why no initial whitespace is allowed in input string
    sign = -1;
  }
  char *point = strchr ( buf, '.' );
  // is there a fractional part at all? If yes, parse it, if no, set to 0
  if ( point != NULL )
    {
      (*point) = 0;
      char fracString[256] = "0.";
      strcat ( fracString+2, point+1);
      XLAL_CHECK ( XLALParseStringValueAsREAL8 ( valFrac, fracString ) == XLAL_SUCCESS, XLAL_EFUNC );
      (*valFrac) *= sign;	// correct sign: must agree with integer part
    }
  else
    {
      (*valFrac) = 0;
    }

  // now parse integer part
  XLAL_CHECK ( XLALParseStringValueAsINT4 ( valINT4, buf ) == XLAL_SUCCESS, XLAL_EFUNC );

  return XLAL_SUCCESS;
} // XLALParseStringValueAsINT4PlusFrac()
///
/// 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()