Ejemplo n.º 1
0
/*----------------------------------------------------------------------
 * main function
 *----------------------------------------------------------------------*/
int
main(int argc, char *argv[])
{
  size_t len;
  ConfigVars_t XLAL_INIT_DECL(GV);
  UserVariables_t XLAL_INIT_DECL(uvar);

  /* ------------------------------
   * read user-input and set up shop
   *------------------------------*/
  XLAL_CHECK ( XLALInitUserVars ( &uvar, argc, argv ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLAL_CHECK ( XLALInitMakefakedata ( &GV, &uvar ) == XLAL_SUCCESS, XLAL_EFUNC );

  MultiSFTVector *mSFTs = NULL;
  MultiREAL8TimeSeries *mTseries = NULL;

  PulsarParamsVector *injectionSources = NULL;
  if ( uvar.injectionSources ) {
    XLAL_CHECK ( (injectionSources = XLALPulsarParamsFromUserInput ( uvar.injectionSources, NULL ) ) != NULL, XLAL_EFUNC );
  }

  CWMFDataParams XLAL_INIT_DECL(DataParams);
  DataParams.multiIFO           = GV.multiIFO;
  DataParams.multiNoiseFloor    = GV.multiNoiseFloor;
  DataParams.multiTimestamps 	= (*GV.multiTimestamps);
  DataParams.randSeed           = uvar.randSeed;
  DataParams.SFTWindowType      = uvar.SFTWindowType;
  DataParams.SFTWindowBeta      = uvar.SFTWindowBeta;
  if ( GV.inputMultiTS == NULL )
    {
      DataParams.fMin               = uvar.fmin;
      DataParams.Band               = uvar.Band;
      DataParams.inputMultiTS       = NULL;
    }
  else // current limitation: FIXME
    {
      DataParams.fMin               = 0;
      DataParams.Band               = 0;
      DataParams.inputMultiTS       = GV.inputMultiTS;
    }

  XLAL_CHECK ( XLALCWMakeFakeMultiData ( &mSFTs, &mTseries, injectionSources, &DataParams, GV.edat ) == XLAL_SUCCESS, XLAL_EFUNC );

  XLALDestroyPulsarParamsVector ( injectionSources );
  injectionSources = NULL;

  // if noiseSFTs specified, load them and add them to the resulting SFT-vector
  if ( GV.multiNoiseCatalogView )
    {
      SFTtype *sft0 = &(mSFTs->data[0]->data[0]);
      /* load effective frequency-band from noise-SFTs */
      UINT4 numBins = sft0->data->length;
      REAL8 dFreq   = sft0->deltaF;
      REAL8 fMin    = sft0->f0;
      REAL8 fMax    = fMin + ( numBins - 1 ) * dFreq;
      MultiSFTVector *mNoiseSFTs;
      XLAL_CHECK ( (mNoiseSFTs = XLALLoadMultiSFTsFromView ( GV.multiNoiseCatalogView, fMin, fMax )) != NULL, XLAL_EFUNC );
      XLAL_CHECK ( XLALMultiSFTVectorAdd ( mSFTs, mNoiseSFTs ) == XLAL_SUCCESS, XLAL_EFUNC );
      XLALDestroyMultiSFTVector ( mNoiseSFTs );
    }

  if (uvar.outSFTdir)
    {
      XLAL_CHECK ( is_directory ( uvar.outSFTdir ), XLAL_EINVAL );

      /* generate comment string */
      CHAR *logstr;
      XLAL_CHECK ( (logstr = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) != NULL, XLAL_EFUNC );
      char *comment = XLALCalloc ( 1, len = strlen ( logstr ) + strlen(GV.VCSInfoString) + 512 );
      XLAL_CHECK ( comment != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zu) failed.\n", len );
      sprintf ( comment, "Generated by:\n%s\n%s\n", logstr, GV.VCSInfoString );

      for ( UINT4 X=0; X < mSFTs->length; X ++ )
        {
          SFTVector *sfts = mSFTs->data[X];
          /* either write whole SFT-vector to single concatenated file */
          if ( uvar.outSingleSFT ) {
            XLAL_CHECK ( XLALWriteSFTVector2File( sfts, uvar.outSFTdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC );
          } else {	// or as individual SFT-files
            XLAL_CHECK ( XLALWriteSFTVector2Dir( sfts, uvar.outSFTdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC );
          }
        } // for X < numIFOs

      XLALFree ( logstr );
      XLALFree ( comment );

    } /* if outSFTdir */


   /* output ASCII time-series if requested */
  if ( uvar.TDDfile )
    {
      CHAR *fname = XLALCalloc (1, len = strlen(uvar.TDDfile) + 10 );
      XLAL_CHECK ( fname != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zu) failed\n", len );

      for ( UINT4 X=0; X < mTseries->length; X ++ )
        {
          const REAL8TimeSeries *TS = mTseries->data[X];
          sprintf (fname, "%c%c-%s", TS->name[0], TS->name[1], uvar.TDDfile );
          XLAL_CHECK ( XLALdumpREAL8TimeSeries ( fname, TS ) == XLAL_SUCCESS, XLAL_EFUNC );

        } // for X < numDet

      XLALFree (fname);
    } /* if outputting ASCII time-series */

  /* output time-series to frames if requested */
#ifdef HAVE_LIBLALFRAME
  if ( GV.outFrameDir != NULL )
    {
      XLAL_CHECK ( XLALCheckValidDescriptionField ( uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC );
      len = strlen(GV.outFrameDir) + strlen(uvar.outLabel) + 100;
      char *fname;

      char *hist = XLALUserVarGetLog (UVAR_LOGFMT_CMDLINE);
      if ( XLALUserVarWasSet ( &uvar.outFrChannels ) ) {
        XLAL_CHECK ( uvar.outFrChannels->length == mTseries->length, XLAL_EINVAL, "--outFrChannels: number of channel names (%d) must agree with number of IFOs (%d)\n",
                     uvar.outFrChannels->length, mTseries->length );
      }

      for ( UINT4 X=0; X < mTseries->length; X ++ )
        {
          REAL8TimeSeries *Tseries = mTseries->data[X];

          /* use standard frame output filename format */
          char IFO[2] = { Tseries->name[0], Tseries->name[1] };
          LIGOTimeGPS startTimeGPS = Tseries->epoch;
          REAL8 duration = Tseries->data->length * Tseries->deltaT;
          XLAL_CHECK ( (fname = LALCalloc (1, len )) != NULL, XLAL_ENOMEM );
          size_t written = snprintf ( fname, len, "%s/%c-%c%c_%s-%d-%d.gwf",
                                      GV.outFrameDir, IFO[0], IFO[0], IFO[1], uvar.outLabel, startTimeGPS.gpsSeconds, (int)duration );
          XLAL_CHECK ( written < len, XLAL_ESIZE, "Frame-filename exceeds expected maximal length (%zu): '%s'\n", len, fname );

          /* define the output frame */
          LALFrameH *outFrame;
          XLAL_CHECK ( (outFrame = XLALFrameNew ( &startTimeGPS, duration, uvar.outLabel, 1, 0, 0 )) != NULL, XLAL_EFUNC );

          /* add timeseries to the frame - make sure to change the timeseries name since this is used as the channel name */
          char buffer[LALNameLength];
          // if output frame channel names given, use those
          if ( XLALUserVarWasSet ( &uvar.outFrChannels ) ) {
            written = snprintf ( buffer, sizeof(buffer), "%s", uvar.outFrChannels->data[X] );
            if ( buffer[2] == ':' ) { // check we got correct IFO association
              XLAL_CHECK ( (buffer[0] == Tseries->name[0]) && (buffer[1] == Tseries->name[1]), XLAL_EINVAL,
                           "Possible IFO mismatch: outFrChannel[%d] = '%s', IFO = '%c%c': be careful about --outFrChannel ordering\n", X, buffer, Tseries->name[0], Tseries->name[1] );
            } // if buffer[2]==':'
          } else if ( XLALUserVarWasSet ( &uvar.inFrChannels ) ) { // otherwise: if input frame channel names given, use them for output, append "-<outLabel>"
            written = snprintf ( buffer, sizeof(buffer), "%s-%s", uvar.inFrChannels->data[X], uvar.outLabel );
          } else { // otherwise: fall back to <IFO>:<outLabel> channel name
            written = snprintf ( buffer, sizeof(buffer), "%c%c:%s", Tseries->name[0], Tseries->name[1], uvar.outLabel );
          }
          XLAL_CHECK ( written < LALNameLength, XLAL_ESIZE, "Output frame name exceeded max length (%d): '%s'\n", LALNameLength, buffer );
          strcpy ( Tseries->name, buffer );

          XLAL_CHECK ( (XLALFrameAddREAL8TimeSeriesProcData ( outFrame, Tseries ) == XLAL_SUCCESS ) , XLAL_EFUNC );

          /* Here's where we add extra information into the frame - first we add the command line args used to generate it */
          XLALFrameAddFrHistory ( outFrame, __FILE__, hist );

          /* then we add the version string */
          XLALFrameAddFrHistory ( outFrame, __FILE__, GV.VCSInfoString );

          /* output the frame to file - compression level 1 (higher values make no difference) */
          XLAL_CHECK ( XLALFrameWrite ( outFrame, fname ) == XLAL_SUCCESS , XLAL_EFUNC );

          /* free the frame, frame file name and history memory */
          XLALFrameFree ( outFrame );
          XLALFree ( fname );

        } // for X < numDetectors

      XLALFree ( hist );

    } /* if GV.outFrameDir: outputting time-series to frames */
#endif // HAVE_LIBLALFRAME

  /* ---------- free memory ---------- */
  XLALDestroyMultiREAL8TimeSeries ( mTseries );
  XLALDestroyMultiSFTVector ( mSFTs );

  XLALFreeMem ( &GV );	/* free the config-struct */

  LALCheckMemoryLeaks();

  return 0;
} /* main */
Ejemplo n.º 2
0
/** The main function of binary2sft.c
 *
 */
int main( int argc, char *argv[] )  {

  UserInput_t uvar = empty_UserInput;           /* user input variables */
  INT4 i,j;                                     /* counter */
  SFTVector *SFTvect = NULL;
  char *noisestr = XLALCalloc(1,sizeof(char));

  /**********************************************************************************/
  /* register and read all user-variables */
  if (XLALReadUserVars(argc,argv,&uvar)) {
    LogPrintf(LOG_CRITICAL,"%s : XLALReadUserVars() failed with error = %d\n",__func__,xlalErrno);
    return 1;
  }
  LogPrintf(LOG_DEBUG,"%s : read in uservars\n",__func__);

  /**********************************************************************************/
  /* read in the cache file */
  FILE *cachefp = NULL;
  if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) {
    LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile);
    return 1;
  }
  i = 0;
  while (fscanf(cachefp,"%*s %*d %*d")!=EOF) i++;
  INT4 Nfiles = i;
  fclose(cachefp);
  LogPrintf(LOG_DEBUG,"%s : counted %d files listed in the cache file.\n",__func__,Nfiles);

  /* allocate memory */
  char **filenames = LALCalloc(Nfiles,sizeof(char*));
  LIGOTimeGPSVector fileStart;
  fileStart.data = LALCalloc(Nfiles,sizeof(LIGOTimeGPS));
  for (i=0;i<Nfiles;i++) filenames[i] = LALCalloc(512,sizeof(char));

  if ((cachefp = fopen(uvar.cachefile,"r")) == NULL) {
    LogPrintf(LOG_CRITICAL,"%s : failed to open binary input file %s\n",__func__,uvar.cachefile);
    return 1;
  }

  for (i=0;i<Nfiles;i++) {
    fscanf(cachefp,"%s %d %d %*d",filenames[i],&(fileStart.data[i].gpsSeconds),&(fileStart.data[i].gpsNanoSeconds));
  }
  fclose(cachefp);

  /* initialise the random number generator */
  gsl_rng * r;
  if (XLALInitgslrand(&r,uvar.seed)) {
    LogPrintf(LOG_CRITICAL,"%s: XLALinitgslrand() failed with error = %d\n",__func__,xlalErrno);
    XLAL_ERROR(XLAL_EFAULT);
  }

  /* setup the binaryToSFT parameters */
  BinaryToSFTparams par;
  par.tsft = uvar.tsft;
  par.freq = uvar.freq;
  par.freqband = uvar.freqband;
  par.tsamp = uvar.tsamp;
  par.highpassf = uvar.highpassf;
  par.amp_inj = uvar.amp_inj;
  par.f_inj = uvar.f_inj;
  par.asini_inj = uvar.asini_inj;
  XLALGPSSetREAL8(&(par.tasc_inj),uvar.tasc_inj);
  par.tref = fileStart.data[0];
  par.P_inj = uvar.P_inj;
  par.phi_inj = uvar.phi_inj;
  par.r = r;

  /**********************************************************************************/
  /* loop over the input files */
  long int ntot = 0;
  for (j=0;j<Nfiles;j++) {

    UINT4 k = 0;
    INT8Vector *np = NULL;
    REAL8Vector *R = NULL;
    par.tstart = fileStart.data[j];
    REAL8 norm1 = par.tsamp/par.tsft;
    REAL8 norm2 = 1.0/(par.tsamp*par.tsft);
    UINT4 oldlen;
    if (SFTvect==NULL) oldlen = 0;
    else oldlen = SFTvect->length;
    LogPrintf(LOG_DEBUG,"%s : working on file %s\n",__func__,filenames[j]);

    if (XLALBinaryToSFTVector(&SFTvect,filenames[j],&(fileStart.data[j]),&par,&np,&R)) {
      LogPrintf(LOG_CRITICAL,"%s : failed to convert binary input file %s to sfts\n",__func__,filenames[j]);
      return 1;
    }
    if ((np!=NULL) && (R!=NULL)) {
      for (k=0;k<np->length;k++) {
        ntot += np->data[k];
        char temp[64];
        sprintf(temp,"%d %e %e\n",SFTvect->data[oldlen+k].epoch.gpsSeconds,(REAL8)np->data[k]*norm1,R->data[k]*norm2);
        noisestr = (char *)XLALRealloc(noisestr,sizeof(char)*(1+strlen(noisestr)+strlen(temp)));
        strcat(noisestr,temp);
      }
      XLALDestroyINT8Vector(np);
      XLALDestroyREAL8Vector(R);
    }

  }  /* end loop over input files */

  /**********************************************************************************/
  /* create a noise string */


  /**********************************************************************************/
  /* generate comment string */
  char *VCSInfoString = XLALGetVersionString(0);
  XLAL_CHECK ( VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" );
  CHAR *logstr;
  size_t len;
  XLAL_CHECK ( (logstr = XLALUserVarGetLog ( UVAR_LOGFMT_CMDLINE )) != NULL, XLAL_EFUNC );
  char *comment = XLALCalloc ( 1, len = strlen ( logstr ) + strlen(VCSInfoString) + strlen(noisestr) + 512 );
  XLAL_CHECK ( comment != NULL, XLAL_ENOMEM, "XLALCalloc(1,%zd) failed.\n", len );
  sprintf ( comment, "Generated by:\n%s\n%s\nTotal number of photons = %ld\n%s\n", logstr, VCSInfoString, ntot, noisestr );

  /**********************************************************************************/
  /* either write whole SFT-vector to single concatenated file */
  if ( uvar.outSingleSFT ) {
    XLAL_CHECK ( XLALWriteSFTVector2File( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC );
  } else {	/* or as individual SFT-files */
    XLAL_CHECK ( XLALWriteSFTVector2Dir( SFTvect, uvar.outputdir, comment, uvar.outLabel ) == XLAL_SUCCESS, XLAL_EFUNC );
  }

  /**********************************************************************************/
  /* free memory */
  XLALDestroySFTVector(SFTvect);
  XLALFree(logstr);
  XLALFree(comment);
  XLALFree(noisestr);

  LALCheckMemoryLeaks();

  return 0;

}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
  const char *fn = __func__;
  LALStatus status = empty_status;

  SFTCatalog *catalog = NULL;
  SFTConstraints constraints = empty_constraints;
  SFTVector *sft_vect = NULL;
  SFTVector *sft_vect2 = NULL;
  MultiSFTVector *multsft_vect = NULL;
  MultiSFTVector *multsft_vect2 = NULL;
  CHAR detector[2] = "H1";
  INT4 crc_check;

  /* band to read from infile.* SFTs */
  REAL8 fMin = 1008.5;
  REAL8 fMax = 1009.1;


  if ( argc == 1)	/* avoid warning */
    argc = 1;

  /* check that mal-formated SFTs are properly detected */
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad1", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad2", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad3", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad4", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad5", NULL ), &status);

  /* the following (SFT-bad6) has a wrong CRC64 checksum. However, this is
   * not checked in LALSFTdataFind, so it should succeed! */
  SHOULD_WORK( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad6", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );

  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad7", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad8", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad9", NULL ), &status);
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad10", NULL ), &status );
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad11", NULL ), &status );
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad12", NULL ), &status );
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad13", NULL ), &status );
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-bad14", NULL ), &status );

  /* now check some crc-checksums */
  SHOULD_WORK( LALCheckSFTs ( &status, &crc_check, TEST_DATA_DIR "SFT-test1", NULL ), &status );
  if ( crc_check != 0 )
    {
      XLALPrintError ("\nLALCheckSFTs(): SFT-test1 has correct checksum but LALCheckSFTs claimed it hasn't.\n\n");
      return crc_check;
    }
  SHOULD_WORK( LALCheckSFTs ( &status, &crc_check, TEST_DATA_DIR "SFT-bad6", NULL ), &status );
  if ( crc_check != SFTFILEIO_ECRC64 )
    {
      XLALPrintError ( "\nLALCheckSFTs() failed to catch invalid CRC checksum in SFT-bad6 \n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  /* check that proper v2-SFTs are read-in properly */
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test1", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test2", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test3", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test4", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test5", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test6", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test7", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );

  /* now completely read-in a v2 merged-SFT */
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test*", NULL ), &status );
  /* skip sft nr 4 with has Tsft=50 instead of Tsft=60 */
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test[123567]*", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  /* try the same with a ";" separated list of files and of patterns */
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog,
				 TEST_DATA_DIR "SFT-test1;"
				 TEST_DATA_DIR "SFT-test2;"
				 TEST_DATA_DIR "SFT-test3;"
				 TEST_DATA_DIR "SFT-test5;"
				 TEST_DATA_DIR "SFT-test6;"
				 TEST_DATA_DIR "SFT-test7", NULL ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );
  SHOULD_WORK ( LALSFTdataFind ( &status, &catalog, TEST_DATA_DIR "SFT-test[123]*;" TEST_DATA_DIR "SFT-test[5]*", NULL ), &status );

  /* load once as a single SFT-vector (mix of detectors) */
  SHOULD_WORK ( LALLoadSFTs ( &status, &sft_vect, catalog, -1, -1 ), &status );

  /* load once as a multi-SFT vector */
  SHOULD_WORK ( LALLoadMultiSFTs ( &status, &multsft_vect, catalog, -1, -1 ), &status );
  /* load again, using XLAL API */
  if ( ( multsft_vect2 = XLALLoadMultiSFTs ( catalog, -1, -1 )) == NULL ) {
    XLALPrintError ("%s: XLALLoadMultiSFTs (cat, -1, -1) failed with xlalErrno = %d\n", fn, xlalErrno );
    return SFTFILEIOTESTC_ESUB;
  }
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );

  /* 6 SFTs from 2 IFOs should have been read */
  if ( (sft_vect->length != 4) 	/* either as a single SFTVector */
       || (multsft_vect->length != 2) 	/* or separated by detector */
       || (multsft_vect->data[0]->length != 3) || ( multsft_vect->data[1]->length != 1 ) )
    {
      XLALPrintError ( "\nFailed to read in multi-SFT from 2 IFOs 'SFT-test*'!\n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  /* compare results from LALLoadMultiSFTs() and XLALLoadMultiSFTs() */
  {
    UINT4 numIFOs = multsft_vect->length;
    UINT4 X;
    for ( X=0; X < numIFOs; X ++ )
      {
        if( CompareSFTVectors ( multsft_vect->data[X], multsft_vect2->data[X] ) ) {
          XLALPrintError ("%s: comparing (X)LALLoadMultiSFTs(): sft-vectors differ for X=%d\n", fn, X );
          return SFTFILEIOTESTC_ESUB;
        }
      } /* for X < numIFOs */
  } /* ------ */

  /* ----- v2 SFT writing ----- */
  /* write v2-SFT to disk */
  SHOULD_WORK ( LALWriteSFT2file( &status, &(multsft_vect->data[0]->data[0]), "outputsftv2_v2.sft", "A v2-SFT file for testing!"), &status );

  SHOULD_WORK ( LALWriteSFTVector2Dir( &status, multsft_vect->data[0], ".", "A v2-SFT file for testing!", "test"), &status);

  /* write v2-SFT to single file */
  {
    const CHAR *currSingleSFT = NULL;
    UINT4 i = 0;
    FILE *fpConcat = NULL, *fpSingle = NULL;
    int concat = 0, single = 0;

    xlalErrno = 0;
    if (XLAL_SUCCESS != XLALWriteSFTVector2File ( multsft_vect->data[0], ".", "A v2-SFT file for testing!", "test_concat" )) {
      LALPrintError ( "\n XLALWriteSFTVector2File failed to write multi-SFT vector to file!\n\n");
      return SFTFILEIOTESTC_ESUB;
    }
    /* check that the single file SFT is the same as the single SFTs */
    const UINT4 numSingleSFTs = 3;
    const CHAR *singleSFTs[] = {
      "H-1_H1_60SFT_test-000012345-61.sft",
      "H-1_H1_60SFT_test-000012465-61.sft",
      "H-1_H1_60SFT_test-000012585-61.sft"
    };
    printf("*** Comparing single and concatenated SFTs ***\n");
    /* try to open concatenated SFT */
    const CHAR *concatSFT = "H-3_H1_60SFT_test_concat-000012345-302.sft";
    if ( ( fpConcat = fopen(concatSFT, "rb" ) ) == NULL ) {
      LALPrintError ( "\n Cound not open SFT '%s'!\n\n", concatSFT);
      return SFTFILEIOTESTC_ESUB;
    }
    /* do loop while concat. SFT has data */
    while (!feof(fpConcat)) {
      /* get character from concat. SFT */
      concat = fgetc(fpConcat);
      if ( ferror(fpConcat) ) {
	LALPrintError ( "\n IO error reading '%s'!\n\n", concatSFT);
	return SFTFILEIOTESTC_ESUB;
      }
      /* get character from single SFT */
      while (1) {
	/* need to open next single SFT file */
	if (fpSingle == NULL) {
	  /* break if we've run out of single SFTs */
	  if (i == numSingleSFTs)
	    break;
	  /* try to open single SFT */
	  if ( ( fpSingle = fopen(singleSFTs[i], "rb" ) ) == NULL ) {
	    LALPrintError ( "\n Cound not open SFT '%s'!\n\n", singleSFTs[i]);
	    return SFTFILEIOTESTC_ESUB;
	  }
	  currSingleSFT = singleSFTs[i];
	}
	/* get character from single SFT */
	single = fgetc(fpSingle);
	if ( ferror(fpSingle) ) {
	  LALPrintError ( "\n IO error reading '%s'!\n\n", singleSFTs[i]);
	  return SFTFILEIOTESTC_ESUB;
	}
	/* if single SFT is out of data, close it (open next one at beginning of loop) */
	if (feof(fpSingle)) {
	  fclose(fpSingle);
	  fpSingle = NULL;
	  ++i;
	}
	/* otherwise we have a valid character */
	else
	  break;
      }
      /* do character-by-character comparison */
      if ( concat != single ) {
	LALPrintError ( "\n Comparison failed between '%s'(last char = %i) and '%s'(last char = %i)!!\n\n",
			concatSFT, concat, currSingleSFT, single );
	return SFTFILEIOTESTC_ESFTDIFF;
      }
    }
    fclose(fpConcat);
    printf( "*** Comparing was successful!!! ***\n");
  }

  /* write v2-SFt as a v1-SFT to disk (correct normalization) */
  multsft_vect->data[0]->data[0].epoch.gpsSeconds += 60;	/* shift start-time so they don't look like segmented SFTs! */
  SHOULD_WORK ( LALWrite_v2SFT_to_v1file( &status, &(multsft_vect->data[0]->data[0]), "outputsftv2_v1.sft"), &status );

  SUB ( LALDestroySFTVector ( &status, &sft_vect ), &status );
  SUB ( LALDestroyMultiSFTVector (&status, &multsft_vect ), &status );
  SUB ( LALDestroyMultiSFTVector (&status, &multsft_vect2 ), &status );

  /* ----- read the previous two SFTs back */
  SHOULD_FAIL ( LALSFTdataFind ( &status, &catalog, "outputsftv2_*.sft", NULL ), &status );
  /* need to set proper detector! */
  constraints.detector = detector;
  SUB ( LALSFTdataFind ( &status, &catalog, "outputsftv2_*.sft", &constraints ), &status);
  SUB ( LALLoadSFTs ( &status, &sft_vect, catalog, -1, -1 ), &status );

  if ( sft_vect->length != 2 )
    {
      if ( lalDebugLevel ) XLALPrintError ("\nFailed to read back in 'outputsftv2_*.sft'\n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  sft_vect2 = XLALLoadSFTs ( catalog, -1, -1 );
  if (!sft_vect2)
    {
      XLALPrintError ( "\nXLALLoadSFTs() call failed (where it should have succeeded)!\n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  /* compare the SFT vectors just read */
  if(CompareSFTVectors(sft_vect, sft_vect2))
    return SFTFILEIOTESTC_ESUB;

  /* the data of 'outputsftv2_v2.sft' and 'outputsftv2_v1.sft' should agree, as the normalization
   * should be corrected again when reading-in
   */
  {
    UINT4 i;
    UINT4 numBins = sft_vect->data[0].data->length;
    for ( i=0; i < numBins; i++)
      {
	COMPLEX8 *data1 = &(sft_vect->data[0].data->data[i]);
	COMPLEX8 *data2 = &(sft_vect->data[1].data->data[i]);

	if ( (crealf(*data1) != crealf(*data2)) || (cimagf(*data1) != cimagf(*data2)) )
	  {
	    XLALPrintError ("\nv1- and v2- SFT differ after writing/reading\n\n");
	    return SFTFILEIOTESTC_ESFTDIFF;
	  }
      } /* for i < numBins */
  }
  SUB ( LALDestroySFTVector (&status, &sft_vect2 ), &status );
  SUB ( LALDestroySFTVector (&status, &sft_vect ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );

  /* `----- v1 SFT writing */

  /* read v1-SFTs: 'inputsft.0' and 'inputsft.1' (one is big-endian, the other little-endian!) */
  SUB ( LALSFTdataFind (&status, &catalog, TEST_DATA_DIR "inputsft.?", &constraints ), &status );
  SUB ( LALLoadSFTs ( &status, &sft_vect, catalog, fMin, fMax ), &status );
  if ( sft_vect->length != 2 )
    {
      if ( lalDebugLevel ) XLALPrintError ("\nFailed to read in v1-SFTs 'inputsft.0' and 'inputsft.1'\n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  /* read with XLALLoadSFTs() */
  sft_vect2 = XLALLoadSFTs ( catalog, fMin, fMax );
  if (!sft_vect2)
    {
      XLALPrintError ( "\nXLALLoadSFTs() call failed (where it should have succeeded)!\n\n");
      return SFTFILEIOTESTC_ESUB;
    }

  /* compare the SFT vectors just read */
  if(CompareSFTVectors(sft_vect, sft_vect2))
    return SFTFILEIOTESTC_ESUB;

  /* write v1-SFT to disk */
  SUB ( LALWriteSFTfile (&status, &(sft_vect->data[0]), "outputsft_v1.sft"), &status);

  /* try to write this v1-SFTs as v2: should fail without detector-info ! */
  strncpy( sft_vect->data[0].name, "??", 2 );
  SHOULD_FAIL (LALWriteSFT2file( &status, &(sft_vect->data[0]), "outputsft_v2.sft", "Another v2-SFT file for testing!"), &status );

  /* put detector there */
  strcpy ( sft_vect->data[0].name, "H1" );
  SHOULD_WORK (LALWriteSFT2file( &status, &(sft_vect->data[0]), "outputsft_v2.sft", "Another v2-SFT file for testing!"), &status );

  SUB ( LALDestroySFTVector (&status, &sft_vect2 ), &status );
  SUB ( LALDestroySFTVector (&status, &sft_vect ), &status );
  SUB ( LALDestroySFTCatalog( &status, &catalog), &status );

  /* ---------- test timestamps-reading functions by comparing LAL- and XLAL-versions against each other ---------- */
  {
#define TS_FNAME "testTimestamps.dat"
    LIGOTimeGPSVector *ts1 = NULL, *ts2 = NULL;

    /* ----- load timestamps with deprecated LAL function  */
    SUB ( LALReadTimestampsFile ( &status, &ts1, TEST_DATA_DIR TS_FNAME ), &status );
    /* ----- load timestamps w new XLAL function */
    if ( (ts2 = XLALReadTimestampsFile ( TEST_DATA_DIR TS_FNAME )) == NULL ) {
      XLALPrintError ("XLALReadTimestampsFile() failed to read timestamps from file '%s'. xlalErrno = %d\n", TS_FNAME );
      return SFTFILEIOTESTC_ESUB;
    }
    /* ----- compare the two */
    if ( ts1->length != ts2->length ) {
      XLALPrintError ("Read timestamps-lists differ in length %d != %d\n", ts1->length, ts2->length );
      return 1;
    }
    if ( ts1->deltaT != ts2->deltaT ) {
      XLALPrintError ("Read timestamps-lists differ in deltaT %g != %g\n", ts1->deltaT, ts2->deltaT );
      return 1;
    }
    UINT4 i, numTS = ts1->length;
    for ( i = 0; i < numTS; i ++ )
      {
        if ( XLALGPSDiff( &ts1->data[i], &ts2->data[i]) != 0 ) {
          XLALPrintError ("Read timestamps-lists differ in entry %d: { %d, %d } != { %d, %d }\n",
                          i + 1,
                          ts1->data[i].gpsSeconds, ts1->data[i].gpsNanoSeconds,
                          ts2->data[i].gpsSeconds, ts2->data[i].gpsNanoSeconds );
          return 1;
        }
      } /* for i < numTS */

    /* free mem */
    XLALDestroyTimestampVector ( ts1 );
    XLALDestroyTimestampVector ( ts2 );
  }

  /* ------------------------------ */
  LALCheckMemoryLeaks();

  XLALPrintError ("\n\n--------------------------------------------------------------------------------\n");
  XLALPrintError ("\n    OK. All tests passed correctly ! (error-messages above are OK!)\n");
  XLALPrintError ("\n--------------------------------------------------------------------------------\n");


  INFO( SFTFILEIOTESTC_MSGENORM );
  return SFTFILEIOTESTC_ENORM;
}