コード例 #1
0
ファイル: UserInput.c プロジェクト: SwethaPBhagwat/lalsuite
/**
 * Return a log-string representing the <em>complete</em> user-input.
 * <em>NOTE:</em> we only record user-variables that have been set
 * by the user.
 */
CHAR *
XLALUserVarGetLog ( UserVarLogFormat format 	/**< output format: return as config-file or command-line */
                    )
{
  XLAL_CHECK_NULL ( UVAR_vars.next != NULL, XLAL_EINVAL, "No UVAR memory allocated. Did you register any user-variables?" );
  XLAL_CHECK_NULL ( format < UVAR_LOGFMT_LAST, XLAL_EINVAL );

  CHAR *record = NULL;

  if ( format == UVAR_LOGFMT_CMDLINE ) {
    XLAL_CHECK_NULL ( (record = XLALStringAppend ( record, program_name)) != NULL, XLAL_EFUNC );
  }

  LALUserVariable *ptr = &UVAR_vars;
  while ( (ptr = ptr->next) )
    {
      if ( ! ptr->was_set ) { // skip unset variables
	continue;
      }

      CHAR *valstr;
      XLAL_CHECK_NULL ( (valstr = UserVarTypeMap [ ptr->type ].printer( ptr->varp )) != NULL, XLAL_EFUNC );

      char append[256];
      switch (format)
	{
	case UVAR_LOGFMT_CFGFILE:
	  snprintf (append, sizeof(append), "%s = %s;\n", ptr->name, valstr);
	  break;

	case UVAR_LOGFMT_CMDLINE:
	  snprintf (append, sizeof(append), " --%s=%s", ptr->name, valstr);
	  break;

	case UVAR_LOGFMT_PROCPARAMS:
	  snprintf (append, sizeof(append), "--%s = %s :%s;", ptr->name, valstr, UserVarTypeMap[ptr->type].name );
	  break;

	default:
          XLAL_ERROR_NULL ( XLAL_EINVAL, "Unknown format for recording user-input: '%i'\n", format );
	  break;
	} // switch (format)
      XLAL_LAST_ELEM(append) = 0;

      XLAL_CHECK_NULL ( (record = XLALStringAppend (record, append)) != NULL, XLAL_EFUNC );

      XLALFree (valstr);
    } // while ptr=ptr->next

  return record;

} // XLALUserVarGetLog()
コード例 #2
0
ファイル: ppe_utils.c プロジェクト: ahnitz/lalsuite
/**
 * \brief Chops and remerges data into stationary segments
 *
 * This function finds segments of data that appear to be stationary (have the same standard deviation).
 *
 * The function first attempts to chop up the data into as many stationary segments as possible. The splitting may not
 * be optimal, so it then tries remerging consecutive segments to see if the merged segments show more evidence of
 * stationarity. <b>[NOTE: Remerging is currently turned off and will make very little difference to the algorithm]</b>.
 * It then, if necessary, chops the segments again to make sure there are none greater than the required \c chunkMax.
 * The default \c chunkMax is 0, so this rechopping will not normally happen.
 *
 * This is all performed on data that has had a running median subtracted, to try and removed any underlying trends in
 * the data (e.g. those caused by a strong signal), which might affect the calculations (which assume the data is
 * Gaussian with zero mean).
 *
 * If the \c verbose flag is set then a list of the segments will be output to a file called \c data_segment_list.txt,
 * with a prefix of the detector name.
 *
 * \param data [in] A data structure
 * \param chunkMin [in] The minimum length of a segment
 * \param chunkMax [in] The maximum length of a segment
 *
 * \return A vector of segment/chunk lengths
 *
 * \sa subtract_running_median
 * \sa chop_data
 * \sa merge_data
 * \sa rechop_data
 */
UINT4Vector *chop_n_merge( LALInferenceIFOData *data, INT4 chunkMin, INT4 chunkMax ){
  UINT4 j = 0;

  UINT4Vector *chunkLengths = NULL;
  UINT4Vector *chunkIndex = NULL;

  COMPLEX16Vector *meddata = NULL;

  /* subtract a running median value from the data to remove any underlying trends (e.g. caused by a string signal) that
   * might affect the chunk calculations (which can assume the data is Gaussian with zero mean). */
  meddata = subtract_running_median( data->compTimeData->data );

  /* pass chop data a gsl_vector_view, so that internally it can use vector views rather than having to create new vectors */
  gsl_vector_complex_view meddatagsl = gsl_vector_complex_view_array((double*)meddata->data, meddata->length);
  chunkIndex = chop_data( &meddatagsl.vector, chunkMin );

  /* DON'T BOTHER WITH THE MERGING AS IT WILL MAKE VERY LITTLE DIFFERENCE */
  /* merge_data( meddata, chunkIndex ); */

  /* if a maximum chunk length is defined then rechop up the data, to segment any chunks longer than this value */
  if ( chunkMax > chunkMin ) { rechop_data( chunkIndex, chunkMax, chunkMin ); }

  chunkLengths = XLALCreateUINT4Vector( chunkIndex->length );

  /* go through segments and turn into vector of chunk lengths */
  for ( j = 0; j < chunkIndex->length; j++ ){
    if ( j == 0 ) { chunkLengths->data[j] = chunkIndex->data[j]; }
    else { chunkLengths->data[j] = chunkIndex->data[j] - chunkIndex->data[j-1]; }
  }

  /* if verbose print out the segment end indices to a file */
  if ( verbose_output ){
    FILE *fpsegs = NULL;

    CHAR *outfile = NULL;

    /* set detector name as prefix */
    outfile = XLALStringDuplicate( data->detector->frDetector.prefix );

    outfile = XLALStringAppend( outfile, "data_segment_list.txt" );

    if ( (fpsegs = fopen(outfile, "w")) == NULL ){
      fprintf(stderr, "Non-fatal error open file to output segment list.\n");
      return chunkLengths;
    }

    for ( j = 0; j < chunkIndex->length; j++ ) { fprintf(fpsegs, "%u\n", chunkIndex->data[j]); }

    /* add space at the end so that you can separate lists from different detector data streams */
    fprintf(fpsegs, "\n");

    fclose( fpsegs );
  }

  return chunkLengths;
}
コード例 #3
0
ファイル: ppe_utils.c プロジェクト: ahnitz/lalsuite
/**
 * \brief Remove a variable from the current parameters and remove it's scaling and prior values
 *
 * This function will clear out a variable from the \c currentParams and also remove it's scale
 * factors and prior ranges.
 *
 * \param runState [in] The analysis information structure
 * \param ifo [in] The IFO data structure
 * \param var [in] The variable to remove
 *
 */
void remove_variable_and_prior( LALInferenceRunState *runState, LALInferenceIFOModel *ifo, const CHAR *var ){
  /* remove variable from currentParams */
  if( LALInferenceCheckVariable( runState->currentParams, var ) ){
    LALInferenceRemoveVariable( runState->currentParams, var );
  }
  else{
    fprintf(stderr, "Error... variable %s cannot be removed as it does not exist!\n", var);
    exit(3);
  }

  /* remove variable scale parameters from data */
  LALInferenceIFOModel *ifotemp = ifo;
  while ( ifotemp ){
    CHAR *varscale = XLALStringDuplicate( var );
    varscale = XLALStringAppend( varscale, "_scale" );

    if( LALInferenceCheckVariable( ifotemp->params, varscale ) ){
      LALInferenceRemoveVariable( ifotemp->params, varscale );
    }
    else{
      fprintf(stderr, "Error... variable %s cannot be removed as it does not exist!\n", varscale);
      exit(3);
    }

    varscale = XLALStringAppend( varscale, "_min" );
    if( LALInferenceCheckVariable( ifotemp->params, varscale ) ){
      LALInferenceRemoveVariable( ifotemp->params, varscale );
    }
    else{
      fprintf(stderr, "Error... variable %s cannot be removed as it does not exist!\n", varscale);
      exit(3);
    }

    ifotemp = ifotemp->next;
  }

  /* remove prior */
  if ( LALInferenceCheckGaussianPrior( runState->priorArgs, var ) ){
    LALInferenceRemoveGaussianPrior( runState->priorArgs, var );
  }
  else { LALInferenceRemoveMinMaxPrior( runState->priorArgs, var ); }
}
コード例 #4
0
ファイル: ppe_utils.c プロジェクト: cpankow/lalsuite
/**
 * \brief Automatically set the solar system ephemeris file based on environment variables and data time span
 *
 * This function will attempt to construct the file name for Sun, Earth and time correction ephemeris files
 * based on the ephemeris used for the equivalent TEMPO(2) pulsar timing information. It assumes that the
 * ephemeris files are those constructed between 2000 and 2020. The path to the file is not required as this
 * will be found in \c XLALInitBarycenter.
 *
 * \param efile [in] a string that will return the Earth ephemeris file
 * \param sfile [in] a string that will return the Sun ephemeris file
 * \param tfile [in] a string that will return the time correction file
 * \param pulsar [in] the pulsar parameters read from a .par file
 * \param gpsstart [in] the GPS time of the start of the data
 * \param gpsend [in] the GPS time of the end of the data
 *
 * \return The TimeCorrectionType e.g. TDB or TCB
 */
TimeCorrectionType XLALAutoSetEphemerisFiles( CHAR **efile, CHAR **sfile, CHAR **tfile, PulsarParameters *pulsar,
                                              INT4 gpsstart, INT4 gpsend ){
  /* set the times that the ephemeris files span */
  INT4 ephemstart = 630720013; /* GPS time of Jan 1, 2000, 00:00:00 UTC */
  INT4 ephemend = 1261872015; /* GPS time of Jan 1, 2020, 00:00:00 UTC */
  TimeCorrectionType ttype = TIMECORRECTION_NONE;

  if( gpsstart < ephemstart || gpsend < ephemstart || gpsstart > ephemend || gpsend > ephemend ){
    XLAL_ERROR(XLAL_EFUNC, "Start and end times are outside the ephemeris file ranges!" );
  }

  *efile = XLALStringDuplicate("earth00-19-");
  *sfile = XLALStringDuplicate("sun00-19-");

  if( !PulsarCheckParam(pulsar, "EPHEM") ){
    /* default to use DE405 */
    *efile = XLALStringAppend(*efile, "DE405");
    *sfile = XLALStringAppend(*sfile, "DE405");
  }
  else{
    if( !strcmp(PulsarGetStringParam(pulsar, "EPHEM"), "DE405") || !strcmp(PulsarGetStringParam(pulsar, "EPHEM"), "DE200") ||
        !strcmp(PulsarGetStringParam(pulsar, "EPHEM"), "DE414") || !strcmp(PulsarGetStringParam(pulsar, "EPHEM"), "DE421") ){
      *efile = XLALStringAppend(*efile, PulsarGetStringParam(pulsar, "EPHEM"));
      *sfile = XLALStringAppend(*sfile, PulsarGetStringParam(pulsar, "EPHEM"));
    }
    else{
      XLAL_ERROR(XLAL_EFUNC, "Unknown ephemeris %s in par file.", PulsarGetStringParam(pulsar, "EPHEM") );
    }
  }

  /* add .dat.gz extension */
  *efile = XLALStringAppend(*efile, ".dat.gz");
  *sfile = XLALStringAppend(*sfile, ".dat.gz");

  if( !PulsarCheckParam( pulsar, "UNITS" ) ){
    /* default to using TCB units */
    *tfile = XLALStringDuplicate("te405_2000-2019.dat.gz");
    ttype = TIMECORRECTION_TCB;
  }
  else{
    if ( !strcmp( PulsarGetStringParam(pulsar, "UNITS"), "TDB" ) ){
      *tfile = XLALStringDuplicate("tdb_2000-2019.dat.gz");
      ttype = TIMECORRECTION_TDB;
    }
    else if ( !strcmp( PulsarGetStringParam(pulsar, "UNITS"), "TCB" ) ) {
      *tfile = XLALStringDuplicate("te405_2000-2019.dat.gz");
      ttype = TIMECORRECTION_TCB;
    }
    else{
      XLAL_ERROR(XLAL_EFUNC, "Error... unknown units %s in par file!", PulsarGetStringParam(pulsar, "UNITS"));
    }
  }

  return ttype;
}
コード例 #5
0
ファイル: ppe_utils.c プロジェクト: ahnitz/lalsuite
/**
 * \brief Automatically set the solar system ephemeris file based on environment variables and data time span
 *
 * This function will attempt to find Earth and Sun ephemeris files based on LAL environment variables (as set up by
 * <code> lalpulsar-user-env.(c)sh </code>) and a given start and end GPS time (presumably taken from the data that is
 * to be analysed). It requires \c LALPULSAR is installed and the \c LALPULSAR_PREFIX variable is set, which should mean
 * that ephemeris files are installed in the directory \c ${LALPULSAR_PREFIX}/share/lalpulsar/.
 *
 * \param efile [in] a string that will return the Earth ephemeris file
 * \param sfile [in] a string that will return the Sun ephemeris file
 * \param tfile [in] a string that will return the time correction file
 * \param pulsar [in] the pulsar parameters read from a .par file
 * \param gpsstart [in] the GPS time of the start of the data
 * \param gpsend [in] the GPS time of the end of the data
 *
 * \return The TimeCorrectionType e.g. TDB or TCB
 */
TimeCorrectionType XLALAutoSetEphemerisFiles( CHAR *efile, CHAR *sfile, CHAR *tfile, BinaryPulsarParams  pulsar,
                                              INT4 gpsstart, INT4 gpsend ){
  /* set the times that the ephemeris files span */
  INT4 ephemstart = 630720013; /* GPS time of Jan 1, 2000, 00:00:00 UTC */
  INT4 ephemend = 1261872015; /* GPS time of Jan 1, 2020, 00:00:00 UTC */
  CHAR *eftmp = NULL, *sftmp = NULL, *tftmp = NULL;
  TimeCorrectionType ttype = TIMECORRECTION_NONE;

  CHAR *lalpath = NULL, *lalpulsarpath = NULL;

  if( gpsstart < ephemstart || gpsend < ephemstart || gpsstart > ephemend || gpsend > ephemend ){
    XLALPrintError("Start and end times are outside the ephemeris file ranges!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  /* first check that the path to the Ephemeris files is available in the
     environment variables */
  if((lalpath = getenv("LALPULSAR_PREFIX")) == NULL){
    XLALPrintError("LALPULSAR_PREFIX environment variable not set. Cannot automatically generate ephemeris files!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  lalpulsarpath = XLALStringDuplicate( lalpath );

  if ( (lalpulsarpath = XLALStringAppend(lalpulsarpath, "/share/lalpulsar/")) == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  eftmp = XLALStringDuplicate(lalpulsarpath);
  sftmp = XLALStringDuplicate(lalpulsarpath);
  tftmp = XLALStringDuplicate(lalpulsarpath);

  eftmp = XLALStringAppend(eftmp, "earth00-19-");
  sftmp = XLALStringAppend(sftmp, "sun00-19-");

  if( pulsar.ephem == NULL ){
    /* default to use DE405 */
    eftmp = XLALStringAppend(eftmp, "DE405");
    sftmp = XLALStringAppend(sftmp, "DE405");
  }
  else{
    if( !strcmp(pulsar.ephem, "DE405") || !strcmp(pulsar.ephem, "DE200") ||
        !strcmp(pulsar.ephem, "DE414") ){
      eftmp = XLALStringAppend(eftmp, pulsar.ephem);
      sftmp = XLALStringAppend(sftmp, pulsar.ephem);
    }
    else{
      XLALPrintError("Unknown ephemeris %s in par file\n", pulsar.ephem);
      XLAL_ERROR(XLAL_EFUNC);
    }
  }

  /* add .dat extension */
  eftmp = XLALStringAppend(eftmp, ".dat.gz");
  sftmp = XLALStringAppend(sftmp, ".dat.gz");

  if ( eftmp == NULL || sftmp == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  XLALStringCopy( efile, eftmp, strlen(eftmp)+1 );
  XLALStringCopy( sfile, sftmp, strlen(sftmp)+1 );

  /* double check that the files exist */
  if( fopen(sfile, "r") == NULL || fopen(efile, "r") == NULL ){
    XLALPrintError("Error... ephemeris files not, or incorrectly, defined!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  if( pulsar.units == NULL ){
    /* default to using TCB units */
    tftmp = XLALStringAppend(tftmp, "te405_2000-2019.dat.gz");
    ttype = TIMECORRECTION_TCB;
  }
  else{
    if ( !strcmp( pulsar.units, "TDB" ) ){
      tftmp = XLALStringAppend(tftmp, "tdb_2000-2019.dat.gz");
      ttype = TIMECORRECTION_TDB;
    }
    else{
      XLALPrintError("Error... unknown units %s in par file!\n", pulsar.units);
      XLAL_ERROR(XLAL_EFUNC);
    }
  }

  if ( tftmp == NULL ) { XLAL_ERROR(XLAL_EFUNC); }

  XLALStringCopy( tfile, tftmp, strlen(tftmp)+1 );

  if( fopen(tfile, "r") == NULL ){
    XLALPrintError("Error... time ephemeris files not, or incorrectly, defined!\n");
    XLAL_ERROR(XLAL_EFUNC);
  }

  return ttype;
}
コード例 #6
0
ファイル: UserInput.c プロジェクト: SwethaPBhagwat/lalsuite
/**
 * Assemble all help-info from uvars into a help-string.
 */
CHAR *
XLALUserVarHelpString ( const CHAR *progname )
{
  XLAL_CHECK_NULL ( progname != NULL, XLAL_EINVAL );
  XLAL_CHECK_NULL ( UVAR_vars.next != NULL, XLAL_EINVAL, "No UVAR memory allocated. Did you register any user-variables?\n" );

  BOOLEAN showDeveloperOptions  = (lalDebugLevel >= LALWARNING);	// only output for lalDebugLevel >= warning
  BOOLEAN showDeprecatedOptions  = (lalDebugLevel >= LALINFO);		// only output for lalDebugLevel >= info

  // ---------- ZEROTH PASS: find longest long-option and type names, for proper output formatting
  LALUserVariable *ptr = &UVAR_vars;
  UINT4 nameFieldLen = 0;
  UINT4 typeFieldLen = 0;
  BOOLEAN haveDeveloperOptions = 0;
  BOOLEAN haveDeprecatedOptions = 0;

  while ( (ptr=ptr->next) != NULL )
    {
      if (ptr->category == UVAR_CATEGORY_DEVELOPER) {
        haveDeveloperOptions = 1;
      }
      if ( ptr->category == UVAR_CATEGORY_DEPRECATED ) {
        haveDeprecatedOptions = 1;
      }
      if ( (ptr->category == UVAR_CATEGORY_DEVELOPER) && !showDeveloperOptions ) {
	continue;	// skip developer options if not requested
      }
      if ( (ptr->category == UVAR_CATEGORY_DEPRECATED) && !showDeprecatedOptions ) {
	continue;	// skip deprecated options if not requested
      }
      if ( ptr->category == UVAR_CATEGORY_DEFUNCT ) {
	continue;	// always skip defunct options to hide them completely from help string
      }

      UINT4 len;
      // max variable name length
      if ( ptr->name != NULL )
        {
          len = strlen ( ptr->name );
          nameFieldLen = (len > nameFieldLen) ? len : nameFieldLen;
        }

      // max type name length
      len = strlen ( UserVarTypeMap[ptr->type].name );
      typeFieldLen = (len > typeFieldLen) ? len : typeFieldLen;

    } // while ptr=ptr->next

  CHAR fmtStr[256];		// for building a dynamic format-string
  snprintf ( fmtStr, sizeof(fmtStr), "  %%s --%%-%ds   %%-%ds  %%s [%%s]\n", nameFieldLen, typeFieldLen );
  XLAL_LAST_ELEM(fmtStr)=0;

  CHAR defaultstr[256]; 	// for display of default-value
  CHAR strbuf[512];

  CHAR *helpstr_regular    = NULL;
  CHAR *helpstr_developer  = NULL;
  CHAR *helpstr_deprecated = NULL;
  // ---------- provide header line: info about config-file reading

  snprintf (strbuf, sizeof(strbuf), "Usage: %s [@ConfigFile] [options], where options are:\n\n", progname);
  XLAL_LAST_ELEM(strbuf) = 0;
  XLAL_CHECK_NULL ( (helpstr_regular = XLALStringDuplicate ( strbuf )) != NULL, XLAL_EFUNC );

  // ---------- MAIN LOOP: step through all user variables and add entry to appropriate help string
  ptr = &UVAR_vars;
  while ( (ptr=ptr->next) != NULL )	// header always empty
    {
      if ( ptr->category == UVAR_CATEGORY_REQUIRED ) {
	strcpy (defaultstr, "REQUIRED");
      }
      else if ( ptr->category == UVAR_CATEGORY_HELP ) {
        strcpy ( defaultstr, "");
      }
      else // write the current default-value into a string
	{
	  CHAR *valstr;
	  XLAL_CHECK_NULL ( (valstr = UserVarTypeMap [ ptr->type ].printer( ptr->varp )) != NULL, XLAL_EFUNC );
	  strncpy ( defaultstr, valstr, sizeof(defaultstr) );	// cut short for default-entry
	  XLAL_LAST_ELEM(defaultstr) = 0;
	  XLALFree (valstr);
	}

      CHAR optstr[10];
      if (ptr->optchar != 0) {
	sprintf (optstr, "-%c,", ptr->optchar);
      } else {
	strcpy (optstr, "   ");
      }

      snprintf ( strbuf, sizeof(strbuf),  fmtStr,
                 optstr,
                 ptr->name ? ptr->name : "-NONE-",
                 UserVarTypeMap[ptr->type].name,
                 ptr->help ? ptr->help : "-NONE-",
                 defaultstr
                 );
      XLAL_LAST_ELEM(strbuf) = 0;

      // now append new line to the appropriate helpstring
      switch ( ptr->category )
        {
        case UVAR_CATEGORY_DEVELOPER:
          if ( showDeveloperOptions ) {
            helpstr_developer = XLALStringAppend ( helpstr_developer, strbuf );
          }
          break;

        case UVAR_CATEGORY_DEPRECATED:
          if ( showDeprecatedOptions ) {
            helpstr_deprecated = XLALStringAppend ( helpstr_deprecated, strbuf );
          }
          break;

        default:
          helpstr_regular = XLALStringAppend ( helpstr_regular, strbuf );
          break;
        } // switch category

    } // while ptr=ptr->next

  CHAR *helpstr = NULL;
  XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_regular )) != NULL, XLAL_EFUNC );
  XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC );

  // handle output of developer options, if requested
  if ( haveDeveloperOptions )
    {
      if ( !showDeveloperOptions )
        {
          const char *str = " ---------- Use help with lalDebugLevel >= warning to also see all 'developer' options ----------\n";
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC );
        }
      else
        {
          const char *str = " ---------- The following are 'developer'-options not useful for most users:----------\n\n";
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC );
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_developer )) != NULL, XLAL_EFUNC );
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC );
        }
    } // if haveDeveloperOptions

  // handle output of deprecated options, if requested
  if ( haveDeprecatedOptions )
    {
      if ( !showDeprecatedOptions )
        {
          const char *str = " ---------- Use help with lalDebugLevel >= info to also see deprecated options ----------\n";
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC );
        }
      else
        {
          const char *str = " ---------- The following are *DEPRECATED* options that shouldn't be used any more:----------\n\n";
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, str )) != NULL, XLAL_EFUNC );
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, helpstr_deprecated )) != NULL, XLAL_EFUNC );
          XLAL_CHECK_NULL ( (helpstr = XLALStringAppend ( helpstr, "\n" )) != NULL, XLAL_EFUNC );
        }
    } // if haveDeprecatedOptions

  XLALFree ( helpstr_regular );
  XLALFree ( helpstr_developer );
  XLALFree ( helpstr_deprecated );

  return helpstr;

} // XLALUserVarHelpString()