BasicInjectTest.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Jolien Creighton, Teviet Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /****************************** <lalVerbatim file="BasicInjectTestCV">
00021 Author: Creighton, T. D.
00022 $Id: BasicInjectTest.c,v 1.12 2007/06/08 14:41:48 bema Exp $
00023 **************************************************** </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 
00027 \subsection{Program \texttt{BasicInjectTest.c}}
00028 \label{ss:BasicInjectTest.c}
00029 
00030 Injects inspiral signals into detector noise.
00031 
00032 \subsubsection*{Usage}
00033 \begin{verbatim}
00034 BasicInjectTest [-s sourcefile] [-r respfile] [-o outfile] [-e seed]
00035                 [-i infile | -n sec nsec npt dt sigma] [-d debuglevel]
00036 \end{verbatim}
00037 
00038 \subsubsection*{Description}
00039 
00040 This program generates inspiral waveforms with specified parameters,
00041 and injects them into ADC data.  The following option flags are
00042 accepted:
00043 \begin{itemize}
00044 \item[\texttt{-s}] Reads source information from the file
00045 \verb@sourcefile@.  If absent, it injects a single
00046 1.4$M_\odot$--1.4$M_\odot$ inspiral, optimally oriented, at a distance
00047 of $10^{-5}$ solar Schwarzschild radii ($0.00002GM_\odot/c^2$).
00048 \item[\texttt{-r}] Reads a detector response function from the file
00049 \verb@respfile@.  If absent, it generates raw dimensionless strain.
00050 \item[\texttt{-i}] Reads ADC input from the file \verb@infile@.  This
00051 takes precedence over the \verb@-n@ option, below.
00052 \item[\texttt{-n}] Generates random ADC input data starting from a GPS
00053 epoch of \verb@sec@ seconds plus \verb@nsec@ nanoseconds, with
00054 \verb@npt@ data sampled at \verb@dt@ second intervals, with white
00055 Gaussian noise having standard deviation \verb@sigma@.  If neither
00056 \verb@-i@ (above) nor \verb@-n@ are given, the program assumes
00057 \verb@-n 0 0 1048576 9.765625e-4 0.0@.
00058 \item[\texttt{-o}] Writes injected ADC data to the file
00059 \verb@outfile@.  If absent, the routines are exercised, but no output
00060 is written.
00061 \item[\texttt{-d}] Sets the debug level to \verb@debuglevel@.  If not
00062 specified, level 0 is assumed.
00063 \item[\texttt{-r}] Sets the random number seed to \verb@randomseed@.
00064 If not specified, the seed is gerenated from the current time.
00065 \end{itemize}
00066 
00067 \paragraph{Format for \texttt{sourcefile}:} The source file consists
00068 of any number of lines of data, each specifying a chirp waveform.
00069 Each line must begin with a character code (\verb@CHAR@ equal to one
00070 of \verb@'i'@, \verb@'f'@, or \verb@'c'@), followed by 6
00071 whitespace-delimited numerical fields: the GPS epoch of the chirp
00072 (\verb@INT8@ nanoseconds), the two binary masses (\verb@REAL4@
00073 $M_\odot$), the distance to the source (\verb@REAL4@ kpc), and the
00074 source's inclination and phase at coalescence (\verb@REAL4@ degrees).
00075 The character codes have the following meanings:
00076 \begin{itemize}
00077 \item[\texttt{'i'}] The epoch represents the GPS time of the start of
00078 the chirp waveform.
00079 \item[\texttt{'f'}] The epoch represents the GPS time of the end of
00080 the chirp waveform.
00081 \item[\texttt{'c'}] The epoch represents the GPS time when the
00082 binaries would coalesce in the point-mass approximation.
00083 \end{itemize}
00084 Thus a typical input line for two $1.4M_\odot$ objects at 11\,000\,kpc
00085 inclined $30^\circ$ with an initial phase of $45^\circ$, coalescing at
00086 315\,187\,245 GPS seconds, will have the following line in the input
00087 file:
00088 \begin{verbatim}
00089 c 315187245000000000 1.4 1.4 11000.0 30.0 45.0
00090 \end{verbatim}
00091 
00092 \paragraph{Format for \texttt{respfile}:} The response function $R(f)$
00093 gives the real and imaginary components of the transformation
00094 \emph{from} ADC output $o$ \emph{to} tidal strain $h$ via
00095 $\tilde{h}(f)=R(f)\tilde{o}(f)$.  It is inverted internally to give
00096 the detector \emph{transfer function} $T(f)=1/R(f)$.  The format
00097 \verb@respfile@ is a header specifying the GPS epoch $t_0$ at which
00098 the response was taken (\verb@INT8@ nanoseconds), the lowest frequency
00099 $f_0$ at which the response is given (\verb@REAL8@ Hz), and the
00100 frequency sampling interval $\Delta f$ (\verb@REAL8@ Hz):
00101 
00102 \medskip
00103 \begin{tabular}{l}
00104 \verb@# epoch = @$t_0$ \\
00105 \verb@# f0 = @$f_0$ \\
00106 \verb@# deltaF = @$\Delta f$
00107 \end{tabular}
00108 \medskip
00109 
00110 \noindent followed by two columns of \verb@REAL4@ data giving the real
00111 and imaginary components of $R(f_0+k\Delta f)$.
00112 
00113 \paragraph{Format for \texttt{infile}:} The input file consists of a
00114 header giving the GPS epoch $t_0$ of the first time sample
00115 (\verb@INT8@ nanoseconds) and the sampling interval $\Delta t$
00116 (\verb@REAL8@ seconds):
00117 
00118 \medskip
00119 \begin{tabular}{l}
00120 \verb@# epoch = @$t_0$ \\
00121 \verb@# deltaT = @$\Delta t$
00122 \end{tabular}
00123 \medskip
00124 
00125 \noindent followed by a single column of ADC data.  The ADC data
00126 should be integers in the range of an \verb@INT2@ (from $-32768$ to
00127 $32767$), but is assumed to be written in floating-point notation in
00128 accordance with frame format.
00129 
00130 The output file \verb@outfile@ containing injected data is written in
00131 the same format.
00132 
00133 \subsubsection*{Exit codes}
00134 ****************************************** </lalLaTeX><lalErrTable> */
00135 #define BASICINJECTTESTC_ENORM  0
00136 #define BASICINJECTTESTC_ESUB   1
00137 #define BASICINJECTTESTC_EARG   2
00138 #define BASICINJECTTESTC_EVAL   3
00139 #define BASICINJECTTESTC_EFILE  4
00140 #define BASICINJECTTESTC_EINPUT 5
00141 #define BASICINJECTTESTC_EMEM   6
00142 
00143 #define BASICINJECTTESTC_MSGENORM  "Normal exit"
00144 #define BASICINJECTTESTC_MSGESUB   "Subroutine failed"
00145 #define BASICINJECTTESTC_MSGEARG   "Error parsing arguments"
00146 #define BASICINJECTTESTC_MSGEVAL   "Input argument out of valid range"
00147 #define BASICINJECTTESTC_MSGEFILE  "Could not open file"
00148 #define BASICINJECTTESTC_MSGEINPUT "Error reading file"
00149 #define BASICINJECTTESTC_MSGEMEM   "Out of memory"
00150 /******************************************** </lalErrTable><lalLaTeX>
00151 
00152 \subsubsection*{Algorithm}
00153 
00154 \subsubsection*{Uses}
00155 \begin{verbatim}
00156 lalDebugLevel
00157 LALPrintError()                 LALCheckMemoryLeaks()
00158 LALMalloc()                     LALFree()
00159 LALCreateRandomParams()         LALDestroyRandomParams()
00160 LALI2CreateVector()             LALI2DestroyVector()
00161 LALSCreateVector()              LALSDestroyVector()
00162 LALCCreateVector()              LALCDestroyVector()
00163 LALSReadVectorSequence()        LALSDestroyVectorSequence()
00164 LALCCVectorDivide()             LALGeneratePPNInspiral()
00165 LALSimulateCoherentGW()         LALSI2InjectTimeSeries()
00166 LALNormalDeviates()
00167 \end{verbatim}
00168 
00169 \subsubsection*{Notes}
00170 
00171 \vfill{\footnotesize\input{BasicInjectTestCV}}
00172 
00173 ******************************************************* </lalLaTeX> */
00174 
00175 #include <math.h>
00176 #include <stdlib.h>
00177 #include <lal/LALStdio.h>
00178 #include <lal/LALStdlib.h>
00179 #include <lal/LALConstants.h>
00180 #include <lal/SeqFactories.h>
00181 #include <lal/Units.h>
00182 #include <lal/Random.h>
00183 #include <lal/VectorOps.h>
00184 #include <lal/Inject.h>
00185 #include <lal/SimulateCoherentGW.h>
00186 #include <lal/GeneratePPNInspiral.h>
00187 #include <lal/StreamInput.h>
00188 
00189 NRCSID( BASICINJECTTESTC, "$Id: BasicInjectTest.c,v 1.12 2007/06/08 14:41:48 bema Exp $" );
00190 
00191 /* Default parameter settings. */
00192 int lalDebugLevel = 0;
00193 #define EPOCH (0)
00194 #define DIST  (0.00002*LAL_MRSUN_SI )
00195 #define M1    (1.4)
00196 #define M2    (1.4)
00197 #define INC   (0.0)
00198 #define PHIC  (0.0)
00199 #define SEC   (0)
00200 #define NSEC  (0)
00201 #define NPT   (1048576)
00202 #define DT    (1.0/1024.0)
00203 #define SIGMA (0.0)
00204 
00205 /* Global constants. */
00206 #define MSGLEN (256)    /* maximum length of warning/info messages */
00207 #define FSTART (25.0)   /* initial frequency of waveform */
00208 #define FSTOP  (500.0) /* termination frequency of waveform */
00209 #define DELTAT (0.01)   /* sampling interval of amplitude and phase */
00210 
00211 /* Usage format string. */
00212 #define USAGE "Usage: %s [-s sourcefile] [-r respfile] [-o outfile] [-e seed]\n                [-i infile | -n sec nsec npt dt sigma] [-d debuglevel]\n"
00213 
00214 /* Macros for printing errors and testing subroutines. */
00215 #define ERROR( code, msg, statement )                                \
00216 do                                                                   \
00217 if ( lalDebugLevel & LALERROR )                                      \
00218 {                                                                    \
00219   LALPrintError( "Error[0] %d: program %s, file %s, line %d, %s\n"   \
00220                  "        %s %s\n", (code), *argv, __FILE__,         \
00221                  __LINE__, BASICINJECTTESTC, statement ? statement : \
00222                  "", (msg) );                                        \
00223 }                                                                    \
00224 while (0)
00225 
00226 #define INFO( statement )                                            \
00227 do                                                                   \
00228 if ( lalDebugLevel & LALINFO )                                       \
00229 {                                                                    \
00230   LALPrintError( "Info[0]: program %s, file %s, line %d, %s\n"       \
00231                  "        %s\n", *argv, __FILE__, __LINE__,          \
00232                  BASICINJECTTESTC, (statement) );                    \
00233 }                                                                    \
00234 while (0)
00235 
00236 #define WARNING( statement )                                         \
00237 do                                                                   \
00238 if ( lalDebugLevel & LALWARNING )                                    \
00239 {                                                                    \
00240   LALPrintError( "Warning[0]: program %s, file %s, line %d, %s\n"    \
00241                  "        %s\n", *argv, __FILE__, __LINE__,          \
00242                  BASICINJECTTESTC, (statement) );                    \
00243 }                                                                    \
00244 while (0)
00245 
00246 #define SUB( func, statusptr )                                       \
00247 do                                                                   \
00248 if ( (func), (statusptr)->statusCode )                               \
00249 {                                                                    \
00250   ERROR( BASICINJECTTESTC_ESUB, BASICINJECTTESTC_MSGESUB,            \
00251          "Function call \"" #func "\" failed:" );                    \
00252   return BASICINJECTTESTC_ESUB;                                      \
00253 }                                                                    \
00254 while (0)
00255 
00256 #define CHECKVAL( val, lower, upper )                                \
00257 do                                                                   \
00258 if ( ( (val) <= (lower) ) || ( (val) > (upper) ) )                   \
00259 {                                                                    \
00260   ERROR( BASICINJECTTESTC_EVAL, BASICINJECTTESTC_MSGEVAL,            \
00261          "Value of " #val " out of range:" );                        \
00262   LALPrintError( #val " = %f, range = (%f,%f]\n", (REAL8)(val),      \
00263                  (REAL8)(lower), (REAL8)(upper) );                   \
00264   return BASICINJECTTESTC_EVAL;                                      \
00265 }                                                                    \
00266 while (0)
00267 
00268 /* A global pointer for debugging. */
00269 #ifndef NDEBUG
00270 char *lalWatch;
00271 #endif
00272 
00273 /* A function to convert INT8 nanoseconds to LIGOTimeGPS. */
00274 void
00275 I8ToLIGOTimeGPS( LIGOTimeGPS *output, INT8 input );
00276 
00277 
00278 int
00279 main(int argc, char **argv)
00280 {
00281   /* Command-line parsing variables. */
00282   int arg;                   /* command-line argument counter */
00283   static LALStatus stat;     /* status structure */
00284   CHAR *sourcefile = NULL;   /* name of sourcefile */
00285   CHAR *respfile = NULL;     /* name of respfile */
00286   CHAR *infile = NULL;       /* name of infile */
00287   CHAR *outfile = NULL;      /* name of outfile */
00288   INT4 seed = 0;             /* random number seed */
00289   INT4 sec = SEC;            /* ouput epoch.gpsSeconds */
00290   INT4 nsec = NSEC;          /* ouput epoch.gpsNanoSeconds */
00291   INT4 npt = NPT;            /* number of output points */
00292   REAL8 dt = DT;             /* output sampling interval */
00293   REAL4 sigma = SIGMA;       /* noise amplitude */
00294 
00295   /* File reading variables. */
00296   FILE *fp = NULL; /* generic file pointer */
00297   BOOLEAN ok = 1;  /* whether input format is correct */
00298   UINT4 i;         /* generic index over file lines */
00299   INT8 epoch;      /* epoch stored as an INT8 */
00300 
00301   /* Other global variables. */
00302   RandomParams *params = NULL; /* parameters of pseudorandom sequence */
00303   DetectorResponse detector;   /* the detector in question */
00304   INT2TimeSeries output;       /* detector ACD output */
00305 
00306 
00307   /*******************************************************************
00308    * PARSE ARGUMENTS (arg stores the current position)               *
00309    *******************************************************************/
00310 
00311   /* Exit gracefully if no arguments were given.
00312   if ( argc <= 1 ) {
00313     INFO( "No testing done." );
00314     return 0;
00315   } */
00316 
00317   arg = 1;
00318   while ( arg < argc ) {
00319     /* Parse source file option. */
00320     if ( !strcmp( argv[arg], "-s" ) ) {
00321       if ( argc > arg + 1 ) {
00322         arg++;
00323         sourcefile = argv[arg++];
00324       }else{
00325         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00326         LALPrintError( USAGE, *argv );
00327         return BASICINJECTTESTC_EARG;
00328       }
00329     }
00330     /* Parse response file option. */
00331     else if ( !strcmp( argv[arg], "-r" ) ) {
00332       if ( argc > arg + 1 ) {
00333         arg++;
00334         respfile = argv[arg++];
00335       }else{
00336         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00337         LALPrintError( USAGE, *argv );
00338         return BASICINJECTTESTC_EARG;
00339       }
00340     }
00341     /* Parse input file option. */
00342     else if ( !strcmp( argv[arg], "-i" ) ) {
00343       if ( argc > arg + 1 ) {
00344         arg++;
00345         infile = argv[arg++];
00346       }else{
00347         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00348         LALPrintError( USAGE, *argv );
00349         return BASICINJECTTESTC_EARG;
00350       }
00351     }
00352     /* Parse noise output option. */
00353     else if ( !strcmp( argv[arg], "-n" ) ) {
00354       if ( argc > arg + 5 ) {
00355         arg++;
00356         sec = atoi( argv[arg++] );
00357         nsec = atoi( argv[arg++] );
00358         npt = atoi( argv[arg++] );
00359         dt = atof( argv[arg++] );
00360         sigma = atof( argv[arg++] );
00361       }else{
00362         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00363         LALPrintError( USAGE, *argv );
00364         return BASICINJECTTESTC_EARG;
00365       }
00366     }
00367     /* Parse output file option. */
00368     else if ( !strcmp( argv[arg], "-o" ) ) {
00369       if ( argc > arg + 1 ) {
00370         arg++;
00371         outfile = argv[arg++];
00372       }else{
00373         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00374         LALPrintError( USAGE, *argv );
00375         return BASICINJECTTESTC_EARG;
00376       }
00377     }
00378     /* Parse debug level option. */
00379     else if ( !strcmp( argv[arg], "-d" ) ) {
00380       if ( argc > arg + 1 ) {
00381         arg++;
00382         lalDebugLevel = atoi( argv[arg++] );
00383       }else{
00384         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00385         LALPrintError( USAGE, *argv );
00386         return BASICINJECTTESTC_EARG;
00387       }
00388     }
00389     /* Parse random seed option. */
00390     else if ( !strcmp( argv[arg], "-e" ) ) {
00391       if ( argc > arg + 1 ) {
00392         arg++;
00393         seed = atoi( argv[arg++] );
00394       }else{
00395         ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00396         LALPrintError( USAGE, *argv );
00397         return BASICINJECTTESTC_EARG;
00398       }
00399     }
00400     /* Check for unrecognized options. */
00401     else if ( argv[arg][0] == '-' ) {
00402       ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 );
00403       LALPrintError( USAGE, *argv );
00404       return BASICINJECTTESTC_EARG;
00405     }
00406   } /* End of argument parsing loop. */
00407 
00408   /* Check for redundant or bad argument values. */
00409   CHECKVAL( npt, 0, 2147483647 );
00410   CHECKVAL( dt, 0, LAL_REAL4_MAX );
00411 
00412 
00413   /*******************************************************************
00414    * SETUP                                                           *
00415    *******************************************************************/
00416 
00417   /* Set up output, detector, and random parameter structures. */
00418   output.data = NULL;
00419   detector.transfer = (COMPLEX8FrequencySeries *)
00420     LALMalloc( sizeof(COMPLEX8FrequencySeries) );
00421   if ( !(detector.transfer) ) {
00422     ERROR( BASICINJECTTESTC_EMEM, BASICINJECTTESTC_MSGEMEM, 0 );
00423     return BASICINJECTTESTC_EMEM;
00424   }
00425   detector.transfer->data = NULL;
00426   detector.site = NULL;
00427   SUB( LALCreateRandomParams( &stat, &params, seed ), &stat );
00428 
00429   /* Set up units. */
00430   {
00431     RAT4 negOne = { -1, 0 };
00432     LALUnit unit;
00433     LALUnitPair pair;
00434     output.sampleUnits = lalADCCountUnit;
00435     pair.unitOne = &lalADCCountUnit;
00436     pair.unitTwo = &lalStrainUnit;
00437     SUB( LALUnitRaise( &stat, &unit, pair.unitTwo,
00438                        &negOne ), &stat );
00439     pair.unitTwo = &unit;
00440     SUB( LALUnitMultiply( &stat, &(detector.transfer->sampleUnits),
00441                           &pair ), &stat );
00442   }
00443 
00444   /* Read response function. */
00445   if ( respfile ) {
00446     REAL4VectorSequence *resp = NULL; /* response as vector sequence */
00447     COMPLEX8Vector *response = NULL;  /* response as complex vector */
00448     COMPLEX8Vector *unity = NULL;     /* vector of complex 1's */
00449 
00450     if ( ( fp = fopen( respfile, "r" ) ) == NULL ) {
00451       ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
00452              respfile );
00453       return BASICINJECTTESTC_EFILE;
00454     }
00455 
00456     /* Read header. */
00457     ok &= ( fscanf( fp, "# epoch = %Li\n", &epoch ) == 1 );
00458     I8ToLIGOTimeGPS( &( detector.transfer->epoch ), epoch );
00459     ok &= ( fscanf( fp, "# f0 = %lf\n", &( detector.transfer->f0 ) )
00460             == 1 );
00461     ok &= ( fscanf( fp, "# deltaF = %lf\n",
00462                     &( detector.transfer->deltaF ) ) == 1 );
00463     if ( !ok ) {
00464       ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
00465              respfile );
00466       return BASICINJECTTESTC_EINPUT;
00467     }
00468 
00469     /* Read and convert body to a COMPLEX8Vector. */
00470     SUB( LALSReadVectorSequence( &stat, &resp, fp ), &stat );
00471     fclose( fp );
00472     if ( resp->vectorLength != 2 ) {
00473       ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
00474              respfile );
00475       return BASICINJECTTESTC_EINPUT;
00476     }
00477     SUB( LALCCreateVector( &stat, &response, resp->length ), &stat );
00478     memcpy( response->data, resp->data, 2*resp->length*sizeof(REAL4) );
00479     SUB( LALSDestroyVectorSequence( &stat, &resp ), &stat );
00480 
00481     /* Convert response function to a transfer function. */
00482     SUB( LALCCreateVector( &stat, &unity, response->length ), &stat );
00483     for ( i = 0; i < response->length; i++ ) {
00484       unity->data[i].re = 1.0;
00485       unity->data[i].im = 0.0;
00486     }
00487     SUB( LALCCreateVector( &stat, &( detector.transfer->data ),
00488                            response->length ), &stat );
00489     SUB( LALCCVectorDivide( &stat, detector.transfer->data, unity,
00490                             response ), &stat );
00491     SUB( LALCDestroyVector( &stat, &response ), &stat );
00492     SUB( LALCDestroyVector( &stat, &unity ), &stat );
00493   }
00494 
00495   /* No response file, so generate a unit response. */
00496   else {
00497     I8ToLIGOTimeGPS( &( detector.transfer->epoch ), EPOCH );
00498     detector.transfer->f0 = 0.0;
00499     detector.transfer->deltaF = 1.5*FSTOP;
00500     SUB( LALCCreateVector( &stat, &( detector.transfer->data ), 2 ),
00501          &stat );
00502     detector.transfer->data->data[0].re = 1.0;
00503     detector.transfer->data->data[1].re = 1.0;
00504     detector.transfer->data->data[0].im = 0.0;
00505     detector.transfer->data->data[1].im = 0.0;
00506   }
00507 
00508 
00509   /* Read input data. */
00510   if ( infile ) {
00511     REAL4VectorSequence *input = NULL; /* input as vector sequence */
00512     if ( ( fp = fopen( infile, "r" ) ) == NULL ) {
00513       ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
00514              infile );
00515       return BASICINJECTTESTC_EFILE;
00516     }
00517 
00518     /* Read header. */
00519     ok &= ( fscanf( fp, "# epoch = %Li\n", &epoch ) == 1 );
00520     I8ToLIGOTimeGPS( &( output.epoch ), epoch );
00521     ok &= ( fscanf( fp, "# deltaT = %lf\n", &( output.deltaT ) )
00522             == 1 );
00523     if ( !ok ) {
00524       ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
00525              infile );
00526       return BASICINJECTTESTC_EINPUT;
00527     }
00528 
00529     /* Read and convert body. */
00530     SUB( LALSReadVectorSequence( &stat, &input, fp ), &stat );
00531     fclose( fp );
00532     if ( input->vectorLength != 1 ) {
00533       ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT,
00534              infile );
00535       return BASICINJECTTESTC_EINPUT;
00536     }
00537     SUB( LALI2CreateVector( &stat, &( output.data ), input->length ),
00538          &stat );
00539     for ( i = 0; i < input->length; i++ )
00540       output.data->data[i] = (INT2)( input->data[i] );
00541     SUB( LALSDestroyVectorSequence( &stat, &input ), &stat );
00542   }
00543 
00544   /* No input file, so generate one randomly. */
00545   else {
00546     output.epoch.gpsSeconds = sec;
00547     output.epoch.gpsNanoSeconds = nsec;
00548     output.deltaT = dt;
00549     SUB( LALI2CreateVector( &stat, &( output.data ), npt ), &stat );
00550     if ( sigma == 0 ) {
00551       memset( output.data->data, 0, npt*sizeof(INT2) );
00552     } else {
00553       REAL4Vector *deviates = NULL; /* unit Gaussian deviates */
00554       SUB( LALSCreateVector( &stat, &deviates, npt ), &stat );
00555       SUB( LALNormalDeviates( &stat, deviates, params ), &stat );
00556       for ( i = 0; i < (UINT4)( npt ); i++ )
00557         output.data->data[i] = (INT2)
00558           floor( sigma*deviates->data[i] + 0.5 );
00559       SUB( LALSDestroyVector( &stat, &deviates ), &stat );
00560     }
00561   }
00562 
00563 
00564   /*******************************************************************
00565    * INJECTION                                                       *
00566    *******************************************************************/
00567 
00568   /* Open sourcefile. */
00569   if ( sourcefile ) {
00570     if ( ( fp = fopen( sourcefile, "r" ) ) == NULL ) {
00571       ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
00572              sourcefile );
00573       return BASICINJECTTESTC_EFILE;
00574     }
00575   }
00576 
00577   /* For each line in the sourcefile... */
00578   while ( ok ) {
00579     PPNParamStruc ppnParams;       /* wave generation parameters */
00580     REAL4 m1, m2, dist, inc, phic; /* unconverted parameters */
00581     CoherentGW waveform;           /* amplitude and phase structure */
00582     REAL4TimeSeries signal;        /* GW signal */
00583     REAL8 time;                    /* length of GW signal */
00584     CHAR timeCode;                 /* code for signal time alignment */
00585     CHAR message[MSGLEN];          /* warning/info messages */
00586 
00587     /* Read and convert input line. */
00588     if ( sourcefile ) {
00589       ok &= ( fscanf( fp, "%c %lli %f %f %f %f %f\n", &timeCode,
00590                       &epoch, &m1, &m2, &dist, &inc, &phic ) == 7 );
00591       ppnParams.mTot = m1 + m2;
00592       ppnParams.eta = m1*m2/( ppnParams.mTot*ppnParams.mTot );
00593       ppnParams.d = dist*LAL_PC_SI*1000.0;
00594       ppnParams.inc = inc*LAL_PI/180.0;
00595       ppnParams.phi = phic*LAL_PI/180.0;
00596     } else {
00597       timeCode = 'i';
00598       ppnParams.mTot = M1 + M2;
00599       ppnParams.eta = M1*M2/( ppnParams.mTot*ppnParams.mTot );
00600       ppnParams.d = DIST;
00601       ppnParams.inc = INC;
00602       ppnParams.phi = PHIC;
00603       epoch = EPOCH;
00604     }
00605 
00606     if ( ok ) {
00607       /* Set up other parameter structures. */
00608       ppnParams.epoch.gpsSeconds = ppnParams.epoch.gpsNanoSeconds = 0;
00609       ppnParams.position.latitude = ppnParams.position.longitude = 0.0;
00610       ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL;
00611       ppnParams.psi = 0.0;
00612       ppnParams.fStartIn = FSTART;
00613       ppnParams.fStopIn = FSTOP;
00614       ppnParams.lengthIn = 0;
00615       ppnParams.ppn = NULL;
00616       ppnParams.deltaT = DELTAT;
00617       memset( &waveform, 0, sizeof(CoherentGW) );
00618 
00619       /* Generate waveform at zero epoch. */
00620       SUB( LALGeneratePPNInspiral( &stat, &waveform, &ppnParams ),
00621            &stat );
00622       LALSnprintf( message, MSGLEN, "%d: %s", ppnParams.termCode,
00623                    ppnParams.termDescription );
00624       INFO( message );
00625       if ( ppnParams.dfdt > 2.0 ) {
00626         LALSnprintf( message, MSGLEN,
00627                      "Waveform sampling interval is too large:\n"
00628                      "\tmaximum df*dt = %f", ppnParams.dfdt );
00629         WARNING( message );
00630       }
00631 
00632       /* Compute epoch for waveform. */
00633       time = waveform.a->data->length*DELTAT;
00634       if ( timeCode == 'f' )
00635         epoch -= (INT8)( 1000000000.0*time );
00636       else if ( timeCode == 'c' )
00637         epoch -= (INT8)( 1000000000.0*ppnParams.tc );
00638       I8ToLIGOTimeGPS( &( waveform.a->epoch ), epoch );
00639       waveform.f->epoch = waveform.phi->epoch = waveform.a->epoch;
00640 
00641       /* Generate and inject signal. */
00642       signal.epoch = waveform.a->epoch;
00643       signal.epoch.gpsSeconds -= 1;
00644       signal.deltaT = output.deltaT/4.0;
00645       signal.f0 = 0;
00646       signal.data = NULL;
00647       time = ( time + 2.0 )/signal.deltaT;
00648       SUB( LALSCreateVector( &stat, &( signal.data ), (UINT4)time ),
00649            &stat );
00650       SUB( LALSimulateCoherentGW( &stat, &signal, &waveform,
00651                                   &detector ), &stat );
00652       SUB( LALSI2InjectTimeSeries( &stat, &output, &signal, params ),
00653            &stat );
00654       SUB( LALSDestroyVectorSequence( &stat, &( waveform.a->data ) ),
00655            &stat );
00656       SUB( LALSDestroyVector( &stat, &( waveform.f->data ) ), &stat );
00657       SUB( LALDDestroyVector( &stat, &( waveform.phi->data ) ), &stat );
00658       LALFree( waveform.a );
00659       LALFree( waveform.f );
00660       LALFree( waveform.phi );
00661       SUB( LALSDestroyVector( &stat, &( signal.data ) ), &stat );
00662     }
00663 
00664     /* If there is no source file, inject only one source. */
00665     if ( !sourcefile )
00666       ok = 0;
00667   }
00668 
00669   /* Input file is exhausted (or has a badly-formatted line ). */
00670   if ( sourcefile )
00671     fclose( fp );
00672 
00673 
00674   /*******************************************************************
00675    * CLEANUP                                                         *
00676    *******************************************************************/
00677 
00678   /* Print output file. */
00679   if ( outfile ) {
00680     if ( ( fp = fopen( outfile, "w" ) ) == NULL ) {
00681       ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE,
00682              outfile );
00683       return BASICINJECTTESTC_EFILE;
00684     }
00685     epoch = 1000000000LL*(INT8)( output.epoch.gpsSeconds );
00686     epoch += (INT8)( output.epoch.gpsNanoSeconds );
00687     fprintf( fp, "# epoch = %Li\n", epoch );
00688     fprintf( fp, "# deltaT = %23.16e\n", output.deltaT );
00689     for ( i = 0; i < output.data->length; i++ )
00690       fprintf( fp, "%8.1f\n", (REAL4)( output.data->data[i] ) );
00691     fclose( fp );
00692   }
00693 
00694   /* Destroy remaining memory. */
00695   SUB( LALDestroyRandomParams( &stat, &params ), &stat );
00696   SUB( LALI2DestroyVector( &stat, &( output.data ) ), &stat );
00697   SUB( LALCDestroyVector( &stat, &( detector.transfer->data ) ),
00698        &stat );
00699   LALFree( detector.transfer );
00700 
00701   /* Done! */
00702   LALCheckMemoryLeaks();
00703   INFO( BASICINJECTTESTC_MSGENORM );
00704   return BASICINJECTTESTC_ENORM;
00705 }
00706 
00707 
00708 /* A function to convert INT8 nanoseconds to LIGOTimeGPS. */
00709 void
00710 I8ToLIGOTimeGPS( LIGOTimeGPS *output, INT8 input )
00711 {
00712   INT8 s = input / 1000000000LL;
00713   output->gpsSeconds = (INT4)( s );
00714   output->gpsNanoSeconds = (INT4)( input - 1000000000LL*s );
00715   return;
00716 }

Generated on Sat Aug 30 03:12:13 2008 for LAL by  doxygen 1.5.2