00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <math.h>
00063
00064 #ifdef HAVE_UNISTD_H
00065 #include <unistd.h>
00066 #endif
00067
00068 #include <lal/LALStdlib.h>
00069 #include <lal/LALConstants.h>
00070 #include <lal/LALStdio.h>
00071 #include <lal/AVFactories.h>
00072 #include <lal/Units.h>
00073 #include <lal/Random.h>
00074 #include <lal/PrintFTSeries.h>
00075 #include <lal/TimeFreqFFT.h>
00076 #include <lal/LALMoment.h>
00077
00078 #include <lal/LALRCSID.h>
00079 NRCSID (TIMEFREQFFTTESTC,"$Id: TimeFreqFFTTest.c,v 1.9 2008/07/08 22:13:24 kipp Exp $");
00080
00081 #define CODES_(x) #x
00082 #define CODES(x) CODES_(x)
00083
00084 extern char *optarg;
00085 extern int optind;
00086
00087 int lalDebugLevel = 0;
00088 int verbose = 0;
00089
00090 static void
00091 Usage( const char *program, int exitflag );
00092
00093 static void
00094 ParseOptions( int argc, char *argv[] );
00095
00096 static void
00097 TestStatus( LALStatus *status, const char *expectedCodes, int exitCode );
00098
00099 static void
00100 ClearStatus( LALStatus *status );
00101
00102
00103 int main( int argc, char *argv[] )
00104 {
00105 const UINT4 n = 65536;
00106 const REAL4 dt = 1.0 / 16384.0;
00107 static LALStatus status;
00108
00109 static REAL4TimeSeries x;
00110 static COMPLEX8FrequencySeries X;
00111
00112 static REAL4TimeSeries y;
00113 static REAL4FrequencySeries Y;
00114
00115 static COMPLEX8TimeSeries z;
00116 static COMPLEX8FrequencySeries Z;
00117
00118 RealFFTPlan *fwdRealPlan = NULL;
00119 RealFFTPlan *revRealPlan = NULL;
00120 ComplexFFTPlan *fwdComplexPlan = NULL;
00121 ComplexFFTPlan *revComplexPlan = NULL;
00122 RandomParams *randpar = NULL;
00123
00124 AverageSpectrumParams avgSpecParams;
00125
00126 UINT4 srate[] = { 4096, 9000 };
00127 UINT4 npts[] = { 262144, 1048576 };
00128 REAL4 var[] = { 5, 16 };
00129
00130 UINT4 j, sr, np, vr;
00131
00132 CHAR fname[2048];
00133
00134 ParseOptions( argc, argv );
00135
00136 LALSCreateVector( &status, &x.data, n );
00137 TestStatus( &status, CODES( 0 ), 1 );
00138 LALCCreateVector( &status, &X.data, n / 2 + 1 );
00139 TestStatus( &status, CODES( 0 ), 1 );
00140
00141 LALCCreateVector( &status, &z.data, n );
00142 TestStatus( &status, CODES( 0 ), 1 );
00143 LALCCreateVector( &status, &Z.data, n );
00144 TestStatus( &status, CODES( 0 ), 1 );
00145
00146 LALCreateForwardRealFFTPlan( &status, &fwdRealPlan, n, 0 );
00147 TestStatus( &status, CODES( 0 ), 1 );
00148 LALCreateReverseRealFFTPlan( &status, &revRealPlan, n, 0 );
00149 TestStatus( &status, CODES( 0 ), 1 );
00150 LALCreateForwardComplexFFTPlan( &status, &fwdComplexPlan, n, 0 );
00151 TestStatus( &status, CODES( 0 ), 1 );
00152 LALCreateReverseComplexFFTPlan( &status, &revComplexPlan, n, 0 );
00153 TestStatus( &status, CODES( 0 ), 1 );
00154
00155 LALCreateRandomParams( &status, &randpar, 100 );
00156 TestStatus( &status, CODES( 0 ), 1 );
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 x.f0 = 0;
00167 x.deltaT = dt;
00168 x.sampleUnits = lalMeterUnit;
00169 LALSnprintf( x.name, sizeof( x.name ), "x" );
00170 LALNormalDeviates( &status, x.data, randpar );
00171 TestStatus( &status, CODES( 0 ), 1 );
00172 for ( j = 0; j < n; ++j )
00173 {
00174 REAL4 t = j * dt;
00175 x.data->data[j] += 0.1 * cos( LAL_TWOPI * 60.0 * t );
00176 }
00177 LALSPrintTimeSeries( &x, "x.out" );
00178
00179 LALSnprintf( X.name, sizeof( X.name ), "X" );
00180 LALTimeFreqRealFFT( &status, &X, &x, fwdRealPlan );
00181 TestStatus( &status, CODES( 0 ), 1 );
00182 LALCPrintFrequencySeries( &X, "X.out" );
00183
00184 LALFreqTimeRealFFT( &status, &x, &X, revRealPlan );
00185 TestStatus( &status, CODES( 0 ), 1 );
00186 LALSPrintTimeSeries( &x, "xx.out" );
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 avgSpecParams.method = useMean;
00197
00198 for ( np = 0; np < sizeof(npts)/sizeof(*npts) ; ++np )
00199 {
00200
00201 UINT4 tsLength = npts[np] * 7 - 6 * npts[np] / 2;
00202 LALCreateVector( &status, &y.data, tsLength );
00203 TestStatus( &status, CODES( 0 ), 1 );
00204 LALCreateVector( &status, &Y.data, npts[np] / 2 + 1 );
00205 TestStatus( &status, CODES( 0 ), 1 );
00206 avgSpecParams.overlap = npts[np] / 2;
00207
00208
00209 avgSpecParams.window = XLALCreateHannREAL4Window(npts[np]);
00210 avgSpecParams.plan = NULL;
00211 LALCreateForwardRealFFTPlan( &status, &avgSpecParams.plan, npts[np], 0 );
00212 TestStatus( &status, CODES( 0 ), 1 );
00213
00214 for ( sr = 0; sr < sizeof(srate)/sizeof(*srate) ; ++sr )
00215 {
00216
00217 y.deltaT = 1.0 / (REAL8) srate[sr];
00218 for ( vr = 0; vr < sizeof(var)/sizeof(*var) ; ++vr )
00219 {
00220 REAL4 eps = 1e-6;
00221 REAL4 Sfk = 2.0 * var[vr] * var[vr] * y.deltaT;
00222 REAL4 sfk = 0;
00223 REAL4 lbn;
00224 REAL4 sig;
00225 REAL4 ssq;
00226 REAL4 tol;
00227
00228
00229 LALNormalDeviates( &status, y.data, randpar );
00230 TestStatus( &status, CODES( 0 ), 1 );
00231 ssq = 0;
00232 for ( j = 0; j < y.data->length; ++j )
00233 {
00234 y.data->data[j] *= var[vr];
00235 ssq += y.data->data[j] * y.data->data[j];
00236 }
00237
00238
00239 lbn = log( y.data->length ) / log( 2 );
00240 sig = sqrt( 2.5 * lbn * eps * eps * ssq / y.data->length );
00241 tol = 5 * sig;
00242
00243
00244 LALREAL4AverageSpectrum( &status, &Y, &y, &avgSpecParams );
00245 TestStatus( &status, CODES( 0 ), 1 );
00246 LALSMoment( &status, &sfk, Y.data, 1 );
00247 TestStatus( &status, CODES( 0 ), 1 );
00248
00249
00250 if ( fabs(Sfk-sfk) > tol )
00251 {
00252 fprintf( stderr, "FAIL: PSD estimate appears incorrect\n");
00253 fprintf( stderr, "expected %e, got %e ", Sfk, sfk );
00254 fprintf( stderr, "(difference = %e, tolerance = %e)\n",
00255 fabs(Sfk-sfk), tol );
00256 exit(2);
00257 }
00258
00259 }
00260 }
00261
00262
00263 LALDestroyRealFFTPlan( &status, &avgSpecParams.plan );
00264 TestStatus( &status, CODES( 0 ), 1 );
00265 XLALDestroyREAL4Window( avgSpecParams.window );
00266 LALDestroyVector( &status, &y.data );
00267 TestStatus( &status, CODES( 0 ), 1 );
00268 LALDestroyVector( &status, &Y.data );
00269 TestStatus( &status, CODES( 0 ), 1 );
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 z.f0 = 0;
00281 z.deltaT = dt;
00282 z.sampleUnits = lalVoltUnit;
00283 LALSnprintf( z.name, sizeof( z.name ), "z" );
00284 {
00285 REAL4Vector tmp;
00286 tmp.length = 2 * z.data->length;
00287 tmp.data = (REAL4 *)z.data->data;
00288 LALNormalDeviates( &status, &tmp, randpar );
00289 }
00290 for ( j = 0; j < n; ++j )
00291 {
00292 REAL4 t = j * dt;
00293 z.data->data[j].re += 0.2 * cos( LAL_TWOPI * 50.0 * t );
00294 z.data->data[j].im += exp( -t ) * sin( LAL_TWOPI * 500.0 * t );
00295 }
00296 LALCPrintTimeSeries( &z, "z.out" );
00297 TestStatus( &status, CODES( 0 ), 1 );
00298
00299 LALSnprintf( Z.name, sizeof( Z.name ), "Z" );
00300 LALTimeFreqComplexFFT( &status, &Z, &z, fwdComplexPlan );
00301 TestStatus( &status, CODES( 0 ), 1 );
00302 LALCPrintFrequencySeries( &Z, "Z.out" );
00303
00304 LALFreqTimeComplexFFT( &status, &z, &Z, revComplexPlan );
00305 TestStatus( &status, CODES( 0 ), 1 );
00306 LALCPrintTimeSeries( &z, "zz.out" );
00307
00308 LALDestroyRandomParams( &status, &randpar );
00309 TestStatus( &status, CODES( 0 ), 1 );
00310
00311 LALDestroyRealFFTPlan( &status, &fwdRealPlan );
00312 TestStatus( &status, CODES( 0 ), 1 );
00313 LALDestroyRealFFTPlan( &status, &revRealPlan );
00314 TestStatus( &status, CODES( 0 ), 1 );
00315 LALDestroyComplexFFTPlan( &status, &fwdComplexPlan );
00316 TestStatus( &status, CODES( 0 ), 1 );
00317 LALDestroyComplexFFTPlan( &status, &revComplexPlan );
00318 TestStatus( &status, CODES( 0 ), 1 );
00319
00320 LALCDestroyVector( &status, &Z.data );
00321 TestStatus( &status, CODES( 0 ), 1 );
00322 LALCDestroyVector( &status, &z.data );
00323 TestStatus( &status, CODES( 0 ), 1 );
00324
00325 LALCDestroyVector( &status, &X.data );
00326 TestStatus( &status, CODES( 0 ), 1 );
00327 LALSDestroyVector( &status, &x.data );
00328 TestStatus( &status, CODES( 0 ), 1 );
00329
00330 LALCheckMemoryLeaks();
00331 return 0;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 static void
00344 TestStatus( LALStatus *status, const char *ignored, int exitcode )
00345 {
00346 char str[64];
00347 char *tok;
00348
00349 if ( verbose )
00350 {
00351 REPORTSTATUS( status );
00352 }
00353
00354 if ( strncpy( str, ignored, sizeof( str ) ) )
00355 {
00356 if ( (tok = strtok( str, " " ) ) )
00357 {
00358 do
00359 {
00360 if ( status->statusCode == atoi( tok ) )
00361 {
00362 return;
00363 }
00364 }
00365 while ( ( tok = strtok( NULL, " " ) ) );
00366 }
00367 else
00368 {
00369 if ( status->statusCode == atoi( tok ) )
00370 {
00371 return;
00372 }
00373 }
00374 }
00375
00376 fprintf( stderr, "\nExiting to system with code %d\n", exitcode );
00377 exit( exitcode );
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 void
00390 ClearStatus( LALStatus *status )
00391 {
00392 if ( status->statusPtr )
00393 {
00394 ClearStatus( status->statusPtr );
00395 DETATCHSTATUSPTR( status );
00396 }
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 static void
00408 Usage( const char *program, int exitcode )
00409 {
00410 fprintf( stderr, "Usage: %s [options]\n", program );
00411 fprintf( stderr, "Options:\n" );
00412 fprintf( stderr, " -h print this message\n" );
00413 fprintf( stderr, " -q quiet: run silently\n" );
00414 fprintf( stderr, " -v verbose: print extra information\n" );
00415 fprintf( stderr, " -d level set lalDebugLevel to level\n" );
00416 exit( exitcode );
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426 static void
00427 ParseOptions( int argc, char *argv[] )
00428 {
00429 while ( 1 )
00430 {
00431 int c = -1;
00432
00433 c = getopt( argc, argv, "hqvd:" );
00434 if ( c == -1 )
00435 {
00436 break;
00437 }
00438
00439 switch ( c )
00440 {
00441 case 'd':
00442 lalDebugLevel = atoi( optarg );
00443 break;
00444
00445 case 'v':
00446 ++verbose;
00447 break;
00448
00449 case 'q':
00450 freopen( "/dev/null", "w", stderr );
00451 freopen( "/dev/null", "w", stdout );
00452 break;
00453
00454 case 'h':
00455 Usage( argv[0], 0 );
00456 break;
00457
00458 default:
00459 Usage( argv[0], 1 );
00460 }
00461
00462 }
00463
00464 if ( optind < argc )
00465 {
00466 Usage( argv[0], 1 );
00467 }
00468
00469 return;
00470 }