makefakedata_v4.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2008 Chris Messenger, Karl Wette
00003 *  Copyright (C) 2007 Badri Krishnan, Reinhard Prix
00004 *
00005 *  This program is free software; you can redistribute it and/or modify
00006 *  it under the terms of the GNU General Public License as published by
00007 *  the Free Software Foundation; either version 2 of the License, or
00008 *  (at your option) any later version.
00009 *
00010 *  This program is distributed in the hope that it will be useful,
00011 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 *  GNU General Public License for more details.
00014 *
00015 *  You should have received a copy of the GNU General Public License
00016 *  along with with program; see the file COPYING. If not, write to the
00017 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00018 *  MA  02111-1307  USA
00019 */
00020 
00021 /*-----------------------------------------------------------------------
00022  *
00023  * File Name: makefakedata_v4.c
00024  *
00025  * Authors: R. Prix, M.A. Papa, X. Siemens, B. Allen, C. Messenger
00026  *
00027  * This code is a descendant of an earlier implementation 'makefakedata_v2.[ch]'
00028  * by Badri Krishnan, Bruce Allen, Maria Alessandra Papa, Reinhard Prix, Xavier Siemens, Yousuke Itoh
00029  *
00030  * Revision: $Id: makefakedata_v4.c,v 1.100 2008/10/01 16:38:49 reinhard Exp $
00031  *
00032  *
00033  *-----------------------------------------------------------------------
00034  */
00035 
00036 /* ---------- includes ---------- */
00037 #include <sys/stat.h>
00038 
00039 #include <lalapps.h>
00040 #include <lal/AVFactories.h>
00041 #include <lal/SeqFactories.h>
00042 #include <lal/LALInitBarycenter.h>
00043 #include <lal/Random.h>
00044 #include <gsl/gsl_math.h>
00045 
00046 #include <lal/UserInput.h>
00047 #include <lal/SFTfileIO.h>
00048 #include <lal/GeneratePulsarSignal.h>
00049 #include <lal/TimeSeries.h>
00050 #include <lal/BinaryPulsarTiming.h>
00051 #include <lal/Window.h>
00052 
00053 #include <lal/lalGitID.h>
00054 #include <lalappsGitID.h>
00055 
00056 
00057 RCSID ("$Id: makefakedata_v4.c,v 1.100 2008/10/01 16:38:49 reinhard Exp $");
00058 
00059 /* Error codes and messages */
00060 /* <lalErrTable file="MAKEFAKEDATACErrorTable"> */
00061 #define MAKEFAKEDATAC_ENORM     0
00062 #define MAKEFAKEDATAC_ESUB      1
00063 #define MAKEFAKEDATAC_EARG      2
00064 #define MAKEFAKEDATAC_EBAD      3
00065 #define MAKEFAKEDATAC_EFILE     4
00066 #define MAKEFAKEDATAC_ENOARG    5
00067 #define MAKEFAKEDATAC_EMEM      6
00068 #define MAKEFAKEDATAC_EBINARYOUT 7
00069 #define MAKEFAKEDATAC_EREADFILE 8
00070 
00071 #define MAKEFAKEDATAC_MSGENORM "Normal exit"
00072 #define MAKEFAKEDATAC_MSGESUB  "Subroutine failed"
00073 #define MAKEFAKEDATAC_MSGEARG  "Error parsing arguments"
00074 #define MAKEFAKEDATAC_MSGEBAD  "Bad argument values"
00075 #define MAKEFAKEDATAC_MSGEFILE "File IO error"
00076 #define MAKEFAKEDATAC_MSGENOARG "Missing argument"
00077 #define MAKEFAKEDATAC_MSGEMEM   "Out of memory..."
00078 #define MAKEFAKEDATAC_MSGEBINARYOUT "Error in writing binary-data to stdout"
00079 #define MAKEFAKEDATAC_MSGEREADFILE "Error reading in file"
00080 /* </lalErrTable> */
00081 
00082 /***************************************************/
00083 #define TRUE (1==1)
00084 #define FALSE (1==0)
00085 
00086 #define myMax(x,y) ( (x) > (y) ? (x) : (y) )
00087 #define SQ(x) ( (x) * (x) )
00088 #define GPS2REAL(gps) (gps.gpsSeconds + 1e-9 * gps.gpsNanoSeconds )
00089 
00090 /*----------------------------------------------------------------------*/
00091 /** configuration-variables derived from user-variables */
00092 typedef struct
00093 {
00094   PulsarParams pulsar;          /**< pulsar signal-parameters (amplitude + doppler */
00095   EphemerisData edat;           /**< ephemeris-data */
00096   LALDetector site;             /**< detector-site info */
00097 
00098   LIGOTimeGPS startTimeGPS;     /**< start-time of observation */
00099   UINT4 duration;               /**< total duration of observation in seconds */
00100 
00101   LIGOTimeGPSVector *timestamps;/**< a vector of timestamps to generate time-series/SFTs for */
00102 
00103   REAL8 fmin_eff;               /**< 'effective' fmin: round down such that fmin*Tsft = integer! */
00104   REAL8 fBand_eff;              /**< 'effective' frequency-band such that samples/SFT is integer */
00105   REAL8Vector *spindown;        /**< vector of frequency-derivatives of GW signal */
00106 
00107   SFTVector *noiseSFTs;         /**< vector of noise-SFTs to be added to signal */
00108   REAL8 noiseSigma;             /**< sigma for Gaussian noise to be added */
00109 
00110   REAL4Window *window;          /**< window function for the time series */
00111 
00112   COMPLEX8FrequencySeries *transfer;  /**< detector's transfer function for use in hardware-injection */
00113 
00114   INT4 randSeed;                /**< random-number seed: either taken from user or /dev/urandom */
00115 } ConfigVars_t;
00116 
00117 /** Default year-span of ephemeris-files to be used */
00118 #define EPHEM_YEARS  "00-04"
00119 
00120 /* ---------- local prototypes ---------- */
00121 void FreeMem (LALStatus *, ConfigVars_t *cfg);
00122 void InitUserVars (LALStatus *);
00123 void InitMakefakedata (LALStatus *, ConfigVars_t *cfg, int argc, char *argv[]);
00124 void AddGaussianNoise (LALStatus *, REAL4TimeSeries *outSeries, REAL4TimeSeries *inSeries, REAL4 sigma, INT4 seed);
00125 /* void GetOrbitalParams (LALStatus *, BinaryOrbitParams *orbit); */
00126 void WriteMFDlog (LALStatus *, char *argv[], const char *logfile);
00127 
00128 
00129 void LoadTransferFunctionFromActuation(LALStatus *,
00130                                        COMPLEX8FrequencySeries **transfer,
00131                                        REAL8 actuationScale,
00132                                        const CHAR *fname);
00133 
00134 void LALExtractSFTBand ( LALStatus *, SFTVector **outSFTs, const SFTVector *inSFTs, REAL8 fmin, REAL8 Band );
00135 
00136 void LALGenerateLineFeature ( LALStatus *status, REAL4TimeSeries **Tseries, const PulsarSignalParams *params );
00137 
00138 extern void write_timeSeriesR4 (FILE *fp, const REAL4TimeSeries *series);
00139 extern void write_timeSeriesR8 (FILE *fp, const REAL8TimeSeries *series);
00140 BOOLEAN is_directory ( const CHAR *fname );
00141 void OutputVersion ( void );
00142 
00143 /*----------------------------------------------------------------------*/
00144 static const ConfigVars_t empty_GV;
00145 static const LALUnit empty_LALUnit;
00146 /*----------------------------------------------------------------------*/
00147 /* User variables */
00148 /*----------------------------------------------------------------------*/
00149 BOOLEAN uvar_help;              /**< Print this help/usage message */
00150 
00151 /* output */
00152 CHAR *uvar_outSFTbname;         /**< Path and basefilename of output SFT files */
00153 BOOLEAN uvar_outSFTv1;          /**< use v1-spec for output-SFTs */
00154 
00155 CHAR *uvar_TDDfile;             /**< Filename for ASCII output time-series */
00156 BOOLEAN uvar_hardwareTDD;       /**< Binary output timeseries in chunks of Tsft for hardware injections. */
00157 
00158 CHAR *uvar_logfile;             /**< name of logfile */
00159 
00160 /* specify start + duration */
00161 CHAR *uvar_timestampsFile;      /**< Timestamps file */
00162 INT4 uvar_startTime;            /**< Start-time of requested signal in detector-frame (GPS seconds) */
00163 INT4 uvar_duration;             /**< Duration of requested signal in seconds */
00164 
00165 /* generation mode of timer-series: all-at-once or per-sft */
00166 INT4 uvar_generationMode;       /**< How to generate the timeseries: all-at-once or per-sft */
00167 typedef enum
00168   {
00169     GENERATE_ALL_AT_ONCE = 0,   /**< generate whole time-series at once before turning into SFTs */
00170     GENERATE_PER_SFT,           /**< generate timeseries individually for each SFT */
00171     GENERATE_LAST               /**< end-marker */
00172   } GenerationMode;
00173 
00174 /* time-series sampling + heterodyning frequencies */
00175 REAL8 uvar_fmin;                /**< Lowest frequency in output SFT (= heterodyning frequency) */
00176 REAL8 uvar_Band;                /**< bandwidth of output SFT in Hz (= 1/2 sampling frequency) */
00177 
00178 /* SFT params */
00179 REAL8 uvar_Tsft;                /**< SFT time baseline Tsft */
00180 REAL8 uvar_SFToverlap;          /**< overlap SFTs by this many seconds */
00181 
00182 /* noise to add [OPTIONAL] */
00183 CHAR *uvar_noiseSFTs;           /**< Glob-like pattern specifying noise-SFTs to be added to signal */
00184 REAL8 uvar_noiseSigma;          /**< Gaussian noise with standard-deviation sigma */
00185 REAL8 uvar_noiseSqrtSh;         /**< ALTERNATIVE: single-sided sqrt(Sh) for Gaussian noise */
00186 
00187 /* Window function [OPTIONAL] */
00188 CHAR *uvar_window;              /**< Windowing function for the time series */
00189 
00190 /* Detector and ephemeris */
00191 CHAR *uvar_IFO;                 /**< Detector: H1, L1, H2, V1, ... */
00192 CHAR *uvar_detector;            /**< [DEPRECATED] Detector: LHO, LLO, VIRGO, GEO, TAMA, CIT, ROME */
00193 
00194 CHAR *uvar_actuation;           /**< filename containg detector actuation function */
00195 REAL8 uvar_actuationScale;      /**< Scale-factor to be applied to actuation-function */
00196 CHAR *uvar_ephemDir;            /**< Directory path for ephemeris files (optional), use LAL_DATA_PATH if unset. */
00197 CHAR *uvar_ephemYear;           /**< Year (or range of years) of ephemeris files to be used */
00198 
00199 /* pulsar parameters [REQUIRED] */
00200 REAL8 uvar_refTime;             /**< Pulsar reference time tRef in SSB ('0' means: use startTime converted to SSB) */
00201 REAL8 uvar_refTimeMJD;          /**< Pulsar reference time tRef in MJD ('0' means: use startTime converted to SSB) */
00202 
00203 REAL8 uvar_h0;                  /**< overall signal amplitude h0 */
00204 REAL8 uvar_cosi;                /**< cos(iota) of inclination angle iota */
00205 REAL8 uvar_aPlus;               /**< ALTERNATIVE to {h0,cosi}: Plus polarization amplitude aPlus */
00206 REAL8 uvar_aCross;              /**< ALTERNATIVE to {h0,cosi}: Cross polarization amplitude aCross */
00207 REAL8 uvar_psi;                 /**< Polarization angle psi */
00208 REAL8 uvar_phi0;                /**< Initial phase phi */
00209 
00210 REAL8 uvar_Alpha;               /**< Right ascension [radians] alpha of pulsar */
00211 REAL8 uvar_Delta;               /**< Declination [radians] delta of pulsar */
00212 CHAR *uvar_RA;                  /**< Right ascension [hh:mm:ss.ssss] alpha of pulsar */
00213 CHAR *uvar_Dec;                 /**< Declination [dd:mm:ss.ssss] delta of pulsar */
00214 REAL8 uvar_longitude;           /**< [DEPRECATED] Right ascension [radians] alpha of pulsar */
00215 REAL8 uvar_latitude;            /**< [DEPRECATED] Declination [radians] delta of pulsar */
00216 
00217 REAL8 uvar_Freq;
00218 REAL8 uvar_f0;                  /**< [DEPRECATED] Gravitational wave-frequency f0 at refTime */
00219 
00220 REAL8 uvar_f1dot;               /**< First spindown parameter f' */
00221 REAL8 uvar_f2dot;               /**< Second spindown parameter f'' */
00222 REAL8 uvar_f3dot;               /**< Third spindown parameter f''' */
00223 
00224 /* orbital parameters [OPTIONAL] */
00225 
00226 REAL8 uvar_orbitasini;          /**< Projected orbital semi-major axis in seconds (a/c) */
00227 REAL8 uvar_orbitEcc;            /**< Orbital eccentricity */
00228 INT4  uvar_orbitTpSSBsec;       /**< 'observed' (SSB) time of periapsis passage. Seconds. */
00229 INT4  uvar_orbitTpSSBnan;       /**< 'observed' (SSB) time of periapsis passage. Nanoseconds. */
00230 REAL8 uvar_orbitTpSSBMJD;       /**< 'observed' (SSB) time of periapsis passage. MJD. */
00231 REAL8 uvar_orbitPeriod;         /**< Orbital period (seconds) */
00232 REAL8 uvar_orbitArgp;           /**< Argument of periapsis (radians) */
00233 
00234 /* precision-level of signal-generation */
00235 BOOLEAN uvar_exactSignal;       /**< generate signal timeseries as exactly as possible (slow) */
00236 BOOLEAN uvar_lineFeature;       /**< generate a monochromatic line instead of a pulsar-signal */
00237 
00238 BOOLEAN uvar_version;           /**< output version information */
00239 
00240 INT4 uvar_randSeed;             /**< allow user to specify random-number seed for reproducible noise-realizations */
00241 
00242 /*----------------------------------------------------------------------*/
00243 
00244 extern int vrbflg;
00245 
00246 /*----------------------------------------------------------------------
00247  * main function
00248  *----------------------------------------------------------------------*/
00249 int
00250 main(int argc, char *argv[])
00251 {
00252   LALStatus status = blank_status;      /* initialize status */
00253   ConfigVars_t GV = empty_GV;
00254   PulsarSignalParams params = empty_PulsarSignalParams;
00255   SFTVector *SFTs = NULL;
00256   REAL4TimeSeries *Tseries = NULL;
00257   UINT4 i_chunk, numchunks;
00258 
00259   UINT4 i;
00260 
00261   lalDebugLevel = 0;    /* default value */
00262   vrbflg = 1;           /* verbose error-messages */
00263 
00264   /* set LAL error-handler */
00265   lal_errhandler = LAL_ERR_EXIT;        /* exit with returned status-code on error */
00266 
00267   /* ------------------------------
00268    * read user-input and set up shop
00269    *------------------------------*/
00270   LAL_CALL (LALGetDebugLevel(&status, argc, argv, 'v'), &status);
00271 
00272   LAL_CALL (InitMakefakedata(&status, &GV, argc, argv), &status);
00273 
00274   /*----------------------------------------
00275    * fill the PulsarSignalParams struct
00276    *----------------------------------------*/
00277   /* pulsar params */
00278   params.pulsar.refTime            = GV.pulsar.Doppler.refTime;
00279   params.pulsar.position.system    = COORDINATESYSTEM_EQUATORIAL;
00280   params.pulsar.position.longitude = GV.pulsar.Doppler.Alpha;
00281   params.pulsar.position.latitude  = GV.pulsar.Doppler.Delta;
00282   {
00283     REAL8 h0   = GV.pulsar.Amp.h0;
00284     REAL8 cosi = GV.pulsar.Amp.cosi;
00285     params.pulsar.aPlus            = 0.5 * h0 * ( 1.0 + SQ(cosi) );
00286     params.pulsar.aCross           = h0 * cosi;
00287   }
00288   params.pulsar.phi0               = GV.pulsar.Amp.phi0;
00289   params.pulsar.psi                = GV.pulsar.Amp.psi;
00290 
00291   params.pulsar.f0                 = GV.pulsar.Doppler.fkdot[0];
00292   params.pulsar.spindown           = GV.spindown;
00293   params.orbit                     = GV.pulsar.Doppler.orbit;
00294 
00295   /* detector params */
00296   params.transfer = GV.transfer;        /* detector transfer function (NULL if not used) */
00297   params.site = &(GV.site);
00298   params.ephemerides = &(GV.edat);
00299 
00300   /* characterize the output time-series */
00301   if ( ! uvar_exactSignal )     /* GeneratePulsarSignal() uses 'idealized heterodyning' */
00302     {
00303       params.samplingRate       = 2.0 * GV.fBand_eff;   /* sampling rate of time-series (=2*frequency-Band) */
00304       params.fHeterodyne        = GV.fmin_eff;          /* heterodyning frequency for output time-series */
00305     }
00306   else  /* in the exact-signal case: don't do heterodyning, sample at least twice highest frequency */
00307     {
00308       params.samplingRate       = myMax( 2.0 * (params.pulsar.f0 + 2 ), 2*(GV.fmin_eff + GV.fBand_eff ) );
00309       params.fHeterodyne        = 0;
00310     }
00311 
00312   /* set-up main-loop according to 'generation-mode' (all-at-once' or 'per-sft') */
00313   switch ( uvar_generationMode )
00314     {
00315     case GENERATE_ALL_AT_ONCE:
00316       params.duration     = GV.duration;
00317       numchunks = 1;
00318       break;
00319     case GENERATE_PER_SFT:
00320       params.duration = (UINT4) ceil(uvar_Tsft);
00321       numchunks = GV.timestamps->length;
00322       break;
00323     default:
00324       printf ("\nIllegal value for generationMode %d\n\n", uvar_generationMode);
00325       return MAKEFAKEDATAC_EARG;
00326       break;
00327     } /* switch generationMode */
00328 
00329   /* ----------
00330    * Main loop: produce time-series and turn it into SFTs,
00331    * either all-at-once or per-sft
00332    * ----------*/
00333   for ( i_chunk = 0; i_chunk < numchunks; i_chunk++ )
00334     {
00335       params.startTimeGPS = GV.timestamps->data[i_chunk];
00336 
00337       /*----------------------------------------
00338        * generate the signal time-series
00339        *----------------------------------------*/
00340       if ( uvar_exactSignal )
00341         {
00342           LAL_CALL ( LALSimulateExactPulsarSignal (&status, &Tseries, &params), &status );
00343         }
00344       else if ( uvar_lineFeature )
00345         {
00346           LAL_CALL ( LALGenerateLineFeature ( &status, &Tseries, &params ), &status );
00347         }
00348       else
00349         {
00350           LAL_CALL ( LALGeneratePulsarSignal(&status, &Tseries, &params), &status );
00351         }
00352 
00353       /* for HARDWARE-INJECTION:
00354        * before the first chunk we send magic number and chunk-length to stdout
00355        */
00356       if ( uvar_hardwareTDD && (i_chunk == 0) )
00357         {
00358           REAL4 magic = 1234.5;
00359           UINT4 length = Tseries->data->length;
00360           if ( (1 != fwrite ( &magic, sizeof(magic), 1, stdout ))
00361                || (1 != fwrite(&length, sizeof(INT4), 1, stdout)) )
00362             {
00363               perror ("Failed to write to stdout");
00364               exit (MAKEFAKEDATAC_EFILE);
00365             }
00366         } /* if hardware-injection and doing first chunk */
00367 
00368 
00369       /* add Gaussian noise if requested */
00370       if ( GV.noiseSigma > 0) {
00371         LAL_CALL ( AddGaussianNoise(&status, Tseries, Tseries, (REAL4)(GV.noiseSigma), GV.randSeed ), &status);
00372       }
00373 
00374       /* output ASCII time-series if requested */
00375       if ( uvar_TDDfile )
00376         {
00377           FILE *fp;
00378           CHAR *fname = LALCalloc (1, strlen(uvar_TDDfile) + 10 );
00379           sprintf (fname, "%s.%02d", uvar_TDDfile, i_chunk);
00380 
00381           if ( (fp = fopen (fname, "w")) == NULL)
00382             {
00383               perror ("Error opening outTDDfile for writing");
00384               printf ("TDDfile = %s\n", fname );
00385               exit ( MAKEFAKEDATAC_EFILE );
00386             }
00387 
00388           write_timeSeriesR4(fp, Tseries);
00389           fclose(fp);
00390           LALFree (fname);
00391         } /* if outputting ASCII time-series */
00392 
00393 
00394       /* if hardware injection: send timeseries in binary-format to stdout */
00395       if ( uvar_hardwareTDD )
00396         {
00397           UINT4  length = Tseries->data->length;
00398           REAL4 *datap = Tseries->data->data;
00399 
00400           if ( length != fwrite (datap, sizeof(datap[0]), length, stdout) )
00401             {
00402               perror( "Fatal error in writing binary data to stdout\n");
00403               exit (MAKEFAKEDATAC_EBINARYOUT);
00404             }
00405           fflush (stdout);
00406 
00407         } /* if hardware injections */
00408 
00409       /*----------------------------------------
00410        * last step: turn this timeseries into SFTs
00411        * and output them to disk
00412        *----------------------------------------*/
00413       if (uvar_outSFTbname)
00414         {
00415           SFTParams sftParams = empty_SFTParams;
00416           LIGOTimeGPSVector ts;
00417           SFTVector noise;
00418 
00419           sftParams.Tsft = uvar_Tsft;
00420           sftParams.make_v2SFTs = 1;
00421 
00422           switch (uvar_generationMode)
00423             {
00424             case GENERATE_ALL_AT_ONCE:
00425               sftParams.timestamps = GV.timestamps;
00426               sftParams.noiseSFTs = GV.noiseSFTs;
00427               break;
00428             case GENERATE_PER_SFT:
00429               ts.length = 1;
00430               ts.data = &(GV.timestamps->data[i_chunk]);
00431               sftParams.timestamps = &(ts);
00432               sftParams.noiseSFTs = NULL;
00433 
00434               if ( GV.noiseSFTs )
00435                 {
00436                   noise.length = 1;
00437                   noise.data = &(GV.noiseSFTs->data[i_chunk]);
00438                   sftParams.noiseSFTs = &(noise);
00439                 }
00440 
00441               break;
00442 
00443             default:
00444               printf ("\ninvalid Value for --generationMode\n\n");
00445               return MAKEFAKEDATAC_EBAD;
00446               break;
00447             }
00448 
00449           /* Enter the window function into the SFTparams struct */
00450           sftParams.window = GV.window;
00451 
00452           /* get SFTs from timeseries */
00453           LAL_CALL ( LALSignalToSFTs(&status, &SFTs, Tseries, &sftParams), &status);
00454 
00455           /* extract requested band if necessary (eg in the exact-signal case) */
00456           if ( uvar_exactSignal )
00457             {
00458               SFTVector *outSFTs = NULL;
00459               LAL_CALL ( LALExtractSFTBand ( &status, &outSFTs, SFTs, GV.fmin_eff, GV.fBand_eff ), &status );
00460               LAL_CALL ( LALDestroySFTVector ( &status, &SFTs ), &status );
00461               SFTs = outSFTs;
00462             }
00463 
00464           if ( uvar_outSFTv1 )          /* write output-SFTs using the SFT-v1 format */
00465             {
00466               CHAR *fname = LALCalloc (1, strlen (uvar_outSFTbname) + 10);
00467 
00468               for (i=0; i < SFTs->length; i++)
00469                 {
00470                   sprintf (fname, "%s.%05d", uvar_outSFTbname, i_chunk*SFTs->length + i);
00471                   LAL_CALL ( LALWrite_v2SFT_to_v1file ( &status, &(SFTs->data[i]), fname ), &status );
00472                 }
00473               LALFree (fname);
00474             } /* if outSFTv1 */
00475           else
00476             {   /* write standard v2-SFTs */
00477               CHAR *comment = NULL;
00478               CHAR *logstr = NULL;
00479 
00480               /* check that user didn't follow v1-habits and tried to give us a base filename */
00481               if ( ! is_directory ( uvar_outSFTbname ) )
00482                 {
00483                   fprintf (stderr, "\nERROR: the --outSFTbname '%s' is not a directory!\n", uvar_outSFTbname);
00484                   fprintf (stderr, "------------------------------------------------------------\n");
00485                   fprintf (stderr, "NOTE: v2-SFTs are written using the SFTv2 filename-convention!\n");
00486                   fprintf (stderr, "==> therefore, only an (existing) directory-name may be given to --outSFTbname, but no basename!\n");
00487                   fprintf (stderr, "------------------------------------------------------------\n\n");
00488                   return MAKEFAKEDATAC_EBAD;
00489                 }
00490               LAL_CALL ( LALUserVarGetLog ( &status, &logstr,  UVAR_LOGFMT_CMDLINE ), &status );
00491               comment = LALCalloc ( 1, strlen ( logstr ) + strlen(lalGitID) + strlen(lalappsGitID) + 512 );
00492               sprintf ( comment, "Generated by $Id: makefakedata_v4.c,v 1.100 2008/10/01 16:38:49 reinhard Exp $:\n%s\n%s\n%s", logstr, lalGitID, lalappsGitID );
00493               LAL_CALL ( LALWriteSFTVector2Dir (&status, SFTs, uvar_outSFTbname, comment, "mfdv4" ), &status );
00494               LALFree ( logstr );
00495               LALFree ( comment );
00496             }
00497         } /* if outSFTbname */
00498 
00499       /* free memory */
00500       if (Tseries)
00501         {
00502           LAL_CALL (LALDestroyVector(&status, &(Tseries->data)), &status);
00503           LALFree (Tseries);
00504           Tseries = NULL;
00505         }
00506 
00507       if (SFTs)
00508         {
00509           LAL_CALL (LALDestroySFTVector(&status, &SFTs), &status);
00510           SFTs = NULL;
00511         }
00512 
00513     } /* for i_chunk < numchunks */
00514 
00515   LAL_CALL (FreeMem(&status, &GV), &status);    /* free the rest */
00516 
00517   LALCheckMemoryLeaks();
00518 
00519   return 0;
00520 } /* main */
00521 
00522 /**
00523  *  Handle user-input and set up shop accordingly, and do all
00524  * consistency-checks on user-input.
00525  */
00526 void
00527 InitMakefakedata (LALStatus *status, ConfigVars_t *cfg, int argc, char *argv[])
00528 {
00529   CHAR *channelName = NULL;
00530 
00531   INITSTATUS( status, "InitMakefakedata", rcsid );
00532   ATTATCHSTATUSPTR (status);
00533 
00534   /* register all user-variables */
00535   TRY (InitUserVars(status->statusPtr), status);
00536 
00537   /* read cmdline & cfgfile  */
00538   TRY (LALUserVarReadAllInput(status->statusPtr, argc,argv), status);
00539 
00540   if (uvar_help)        /* if help was requested, we're done */
00541     exit (0);
00542 
00543   if ( uvar_version )
00544     {
00545       OutputVersion();
00546       exit (0);
00547     }
00548 
00549   /* if requested, log all user-input and code-versions */
00550   if ( uvar_logfile ) {
00551     TRY ( WriteMFDlog(status->statusPtr, argv, uvar_logfile), status);
00552   }
00553 
00554   { /* ========== translate user-input into 'PulsarParams' struct ========== */
00555     BOOLEAN have_h0     = LALUserVarWasSet ( &uvar_h0 );
00556     BOOLEAN have_cosi   = LALUserVarWasSet ( &uvar_cosi );
00557     BOOLEAN have_aPlus  = LALUserVarWasSet ( &uvar_aPlus );
00558     BOOLEAN have_aCross = LALUserVarWasSet ( &uvar_aCross );
00559     BOOLEAN have_Freq   = LALUserVarWasSet ( &uvar_Freq );
00560     BOOLEAN have_f0     = LALUserVarWasSet ( &uvar_f0 );
00561     BOOLEAN have_longitude = LALUserVarWasSet ( &uvar_longitude );
00562     BOOLEAN have_latitude  = LALUserVarWasSet ( &uvar_latitude );
00563     BOOLEAN have_Alpha  = LALUserVarWasSet ( &uvar_Alpha );
00564     BOOLEAN have_Delta  = LALUserVarWasSet ( &uvar_Delta );
00565     BOOLEAN have_RA = LALUserVarWasSet ( &uvar_RA );
00566     BOOLEAN have_Dec = LALUserVarWasSet ( &uvar_Dec );
00567 
00568     /* ----- {h0,cosi} or {aPlus,aCross} ----- */
00569     if ( (have_aPlus || have_aCross) && ( have_h0 || have_cosi ) ) {
00570       printf ( "\nSpecify EITHER {h0,cosi} OR {aPlus, aCross}!\n\n");
00571       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00572     }
00573     if ( (have_h0 ^ have_cosi) ) {
00574       printf ( "\nNeed both --h0 and --cosi!\n\n");
00575       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00576     }
00577     if ( (have_aPlus ^ have_aCross) ) {
00578       printf ( "\nNeed both --aPlus and --aCross !\n\n");
00579       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00580     }
00581     if ( have_h0 && have_cosi )
00582       {
00583         cfg->pulsar.Amp.h0 = uvar_h0;
00584         cfg->pulsar.Amp.cosi = uvar_cosi;
00585       }
00586     else if ( have_aPlus && have_aCross )
00587       {  /* translate A_{+,x} into {h_0, cosi} */
00588         REAL8 disc;
00589         if ( fabs(uvar_aCross) > uvar_aPlus )
00590           {
00591             printf ( "\nInvalid input parameters: aCross must smaller or equal aPlus !\n\n");
00592             ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00593           }
00594         disc = sqrt ( SQ(uvar_aPlus) - SQ(uvar_aCross) );
00595         cfg->pulsar.Amp.h0   = uvar_aPlus + disc;
00596         cfg->pulsar.Amp.cosi = uvar_aCross / cfg->pulsar.Amp.h0;
00597       }
00598     else {
00599       cfg->pulsar.Amp.h0 = 0.0;
00600       cfg->pulsar.Amp.cosi = 0.0;
00601     }
00602     cfg->pulsar.Amp.phi0 = uvar_phi0;
00603     cfg->pulsar.Amp.psi  = uvar_psi;
00604     /* ----- signal Frequency ----- */
00605     if ( have_f0 && have_Freq ) {
00606       printf ( "\nSpecify signal-frequency using EITHER --Freq [preferred] OR --f0 [deprecated]!\n\n");
00607       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00608     }
00609     if ( have_Freq )
00610       cfg->pulsar.Doppler.fkdot[0] = uvar_Freq;
00611     else if ( have_f0 )
00612       cfg->pulsar.Doppler.fkdot[0] = uvar_f0;
00613     else
00614       cfg->pulsar.Doppler.fkdot[0] = 0.0;
00615 
00616     /* ----- skypos ----- */
00617     if ( (have_Alpha || have_Delta) && ( have_longitude || have_latitude ) && (have_RA || have_Dec) ) {
00618       printf ( "\nUse EITHER {Alpha, Delta} [preferred] OR {RA, Dec} [preferred] OR {longitude,latitude} [deprecated]\n\n");
00619       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00620     }
00621     if ( (have_Alpha && !have_Delta) || ( !have_Alpha && have_Delta ) ) {
00622       printf ( "\nSpecify skyposition: need BOTH --Alpha and --Delta!\n\n");
00623       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00624     }
00625     if ( (have_longitude && !have_latitude) || ( !have_longitude && have_latitude ) ) {
00626       printf ( "\nSpecify skyposition: need BOTH --longitude and --latitude!\n\n");
00627       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00628     }
00629     if ( (have_RA && !have_Dec) || ( !have_RA && have_Dec ) ) {
00630       printf ( "\nSpecify skyposition: need BOTH --RA and --Dec!\n\n");
00631       ABORT (status,  MAKEFAKEDATAC_EBAD,  MAKEFAKEDATAC_MSGEBAD);
00632     }
00633     if