void LALTfrWv (LALStatus *stat, REAL4Vector* sig, TimeFreqRep *tfr, TimeFreqParam *param) { INT4 nf; INT4 time; INT4 column, row; INT4 taumax, tau; REAL4Vector *lacf = NULL; /* local autocorrelation function */ COMPLEX8Vector *vtmp = NULL; RealFFTPlan *plan = NULL; INITSTATUS(stat); ATTATCHSTATUSPTR (stat); /* Make sure the arguments are not NULL: */ ASSERT (sig, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (param, stat, TFR_ENULL, TFR_MSGENULL); /* Make sure the data pointers are not NULL: */ ASSERT (sig->data, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->timeInstant, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->freqBin, stat, TFR_ENULL, TFR_MSGENULL); ASSERT (tfr->map, stat, TFR_ENULL, TFR_MSGENULL); /* Make sure the requested TFR type corresponds to what will be done */ ASSERT (tfr->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME); ASSERT (param->type == WignerVille , stat, TFR_ENAME, TFR_MSGENAME); /* Make sure the number of freq bins is a positive number: */ nf = tfr->fRow; ASSERT (nf > 0 , stat, TFR_EFROW, TFR_MSGEFROW); /* Make sure the number of freq bins is a power of 2: */ while(!(nf & 1)) nf = nf>>1; ASSERT (nf == 1, stat, TFR_EFROW, TFR_MSGEFROW); /* Make sure the timeInstant indicates existing time instants */ for (column=0 ; column<tfr->tCol ; column++) { if ((tfr->timeInstant[column] < 0) || (tfr->timeInstant[column] > (INT4)(sig->length-1))) { ASSERT (tfr->timeInstant[column] > 0, stat, TFR_EBADT, TFR_MSGEBADT); ASSERT (tfr->timeInstant[column] < (INT4)sig->length, stat, TFR_EBADT, TFR_MSGEBADT); } } TRY(LALCreateForwardRealFFTPlan(stat->statusPtr, &plan,(UINT4)tfr->fRow,0),stat); TRY(LALSCreateVector(stat->statusPtr, &lacf, tfr->fRow), stat); TRY(LALCCreateVector(stat->statusPtr, &vtmp, tfr->fRow/2+1), stat); for (column = 0; column < tfr->tCol; column++) { for (row = 0; row < tfr->fRow; row++) lacf->data[row] = 0.0; time = tfr->timeInstant[column]; taumax = MIN (time, (INT4)(sig->length -1 - time)); taumax = MIN (taumax, (tfr->fRow / 2 - 1)); for (tau = -taumax; tau <= taumax; tau++) { row = (tfr->fRow+tau)%tfr->fRow; lacf->data[row] = sig->data[time + tau]*sig->data[time - tau]; } tau=tfr->fRow/2; if ((time<=(INT4)sig->length-tau-1)&(time>=tau)) lacf->data[tau] = sig->data[time+tau]*sig->data[time-tau]; LALForwardRealFFT(stat->statusPtr, vtmp, lacf, plan); for (row = 0; row < (tfr->fRow/2+1); row++) tfr->map[column][row] = crealf(vtmp->data[row]); } /* Reflecting frequency halfing in WV distrob so multiply by 1/2 */ for (row = 0; row < (tfr->fRow/2+1) ; row++) tfr->freqBin[row] = (REAL4) row / (2 *tfr->fRow); TRY(LALSDestroyVector(stat->statusPtr, &lacf), stat); TRY(LALCDestroyVector(stat->statusPtr, &vtmp), stat); TRY(LALDestroyRealFFTPlan(stat->statusPtr, &plan), stat); DETATCHSTATUSPTR (stat); (void)param; /* normal exit */ RETURN (stat); }
/* Actually, we don't need it -- JTW struct tagRealFFTPlan { INT4 sign; UINT4 size; void* junk; }; */ int main( int argc, char *argv[] ) { static LALStatus status; UINT4 i; REAL8 f; const REAL4 testInputDataData[SZEROPADANDFFTTESTC_LENGTH] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; COMPLEX8 expectedOutputDataData[SZEROPADANDFFTTESTC_LENGTH] = {crectf(+3.600000000000000e+01, 0.0), crectf(-1.094039137097177e+01, -2.279368601990178e+01), crectf(+3.693524635113721e-01, +9.326003289238411e+00), crectf(-8.090169943749448e-01, -7.918722831227928e+00), crectf(+3.502214272222959e-01, +5.268737078678177e+00), crectf(+5.329070518200751e-15, -5.196152422706625e+00), crectf(+3.090169943749475e-01, +4.306254604896173e+00), crectf(+2.208174802380956e-01, -4.325962305777781e+00)}; REAL4TimeSeries goodInput; COMPLEX8FrequencySeries goodOutput; int result; LALUnit expectedUnit; CHAR unitString[LALUnitTextSize]; SZeroPadAndFFTParameters goodParams; goodParams.window = NULL; goodParams.fftPlan = NULL; goodParams.length = SZEROPADANDFFTTESTC_FULLLENGTH; /* build window */ goodParams.window = XLALCreateRectangularREAL4Window(SZEROPADANDFFTTESTC_LENGTH); #ifndef LAL_NDEBUG SZeroPadAndFFTParameters badParams = goodParams; #endif /* Fill in expected output */ for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { expectedOutputDataData[i] *= SZEROPADANDFFTTESTC_DELTAT; } ParseOptions( argc, argv ); /* TEST INVALID DATA HERE ------------------------------------------- */ /* define valid parameters */ goodInput.f0 = 0.0; goodInput.deltaT = SZEROPADANDFFTTESTC_DELTAT; goodInput.epoch.gpsSeconds = SZEROPADANDFFTTESTC_EPOCHSEC; goodInput.epoch.gpsNanoSeconds = SZEROPADANDFFTTESTC_EPOCHNS; goodInput.data = NULL; goodOutput.data = NULL; #ifndef LAL_NDEBUG REAL4TimeSeries badInput = goodInput; COMPLEX8FrequencySeries badOutput = goodOutput; #endif /* construct plan */ LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan), SZEROPADANDFFTTESTC_FULLLENGTH, SZEROPADANDFFTTESTC_FALSE); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } /* allocate input and output vectors */ LALSCreateVector(&status, &(goodInput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } LALCCreateVector(&status, &(goodOutput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS ) ) ) { return code; } #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* test behavior for null pointer to output series */ LALSZeroPadAndFFT(&status, NULL, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to input series */ LALSZeroPadAndFFT(&status, &goodOutput, NULL, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to parameter structure */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, NULL); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to parameter structure results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to FFT plan */ badParams.fftPlan = NULL; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &badParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to FFT plan results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badParams.fftPlan = goodParams.fftPlan; /* test behavior for null pointer to data member of output series */ LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to data member of input series */ LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to data member of data member of output series */ LALCCreateVector(&status, &(badOutput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } COMPLEX8 *cPtr; cPtr = badOutput.data->data; badOutput.data->data = NULL; LALSZeroPadAndFFT(&status, &badOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of data member of output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badOutput.data->data = cPtr; LALCDestroyVector(&status, &(badOutput.data)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* test behavior for null pointer to data member of data member of output series */ LALSCreateVector(&status, &(badInput.data), SZEROPADANDFFTTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } REAL4 *sPtr; sPtr = badInput.data->data; badInput.data->data = NULL; LALSZeroPadAndFFT(&status, &goodOutput, &badInput, &goodParams); if ( ( code = CheckStatus( &status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK ) ) ) { return code; } printf(" PASS: null pointer to data member of data member of input series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); badInput.data->data = sPtr; LALSDestroyVector(&status, &(badInput.data)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* test behavior for zero length */ goodInput.data->length = goodOutput.data->length = 0; /* plan->size = -1; */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EZEROLEN, STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero length results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN); /* reassign valid length */ goodInput.data->length = goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH; /* plan->size = SZEROPADANDFFTTESTC_FULLLENGTH; */ /* test behavior for negative time spacing */ goodInput.deltaT = -SZEROPADANDFFTTESTC_DELTAT; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative time spacing results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT); /* test behavior for zero time spacing */ goodInput.deltaT = 0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAT, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero time spacing results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAT); /* reassign valid time spacing */ goodInput.deltaT = SZEROPADANDFFTTESTC_DELTAT; } /* if ( ! lalNoDebug ) */ #endif /* NDEBUG */ /* test behavior for negative heterodyning frequency */ goodInput.f0 = -100.0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO, STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative heterodyning frequency results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO); /* test behavior for positive heterodyning frequency */ goodInput.f0 = 100.0; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONZEROHETERO, STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: positive heterodyning frequency results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONZEROHETERO); goodInput.f0 = 0.0; /* test behavior for length mismatch between input series and output series */ goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH + 1; LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EMMLEN, STOCHASTICCROSSCORRELATIONH_MSGEMMLEN, SZEROPADANDFFTTESTC_ECHK, SZEROPADANDFFTTESTC_MSGECHK) ) ) { return code; } printf(" PASS: length mismatch between input series and output series results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEMMLEN); goodOutput.data->length = SZEROPADANDFFTTESTC_LENGTH; /* TEST VALID DATA HERE --------------------------------------------- */ /* fill input time-series parameters */ strncpy(goodInput.name,"Dummy test data",LALNameLength); goodInput.sampleUnits = lalDimensionlessUnit; goodInput.sampleUnits.unitNumerator[LALUnitIndexADCCount] = 1; /* fill input time-series data */ for (i=0; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { goodInput.data->data[i] = testInputDataData[i]; } /* zero-pad and FFT */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* check output f0 */ if (optVerbose) { printf("f0=%g, should be 0\n", goodOutput.f0); } if (goodOutput.f0) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output deltaF */ if (optVerbose) { printf("deltaF=%g, should be %g\n", goodOutput.deltaF, SZEROPADANDFFTTESTC_DELTAF); } if ( fabs(goodOutput.deltaF-SZEROPADANDFFTTESTC_DELTAF) / SZEROPADANDFFTTESTC_DELTAF > SZEROPADANDFFTTESTC_TOL ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output epoch */ if (optVerbose) { printf("epoch=%d seconds, %d nanoseconds; should be %d seconds, %d nanoseconds\n", goodOutput.epoch.gpsSeconds, goodOutput.epoch.gpsNanoSeconds, SZEROPADANDFFTTESTC_EPOCHSEC, SZEROPADANDFFTTESTC_EPOCHNS); } if ( goodOutput.epoch.gpsSeconds != SZEROPADANDFFTTESTC_EPOCHSEC || goodOutput.epoch.gpsNanoSeconds != SZEROPADANDFFTTESTC_EPOCHNS ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output units */ expectedUnit = lalDimensionlessUnit; expectedUnit.unitNumerator[LALUnitIndexADCCount] = 1; expectedUnit.unitNumerator[LALUnitIndexSecond] = 1; result = XLALUnitCompare(&expectedUnit, &(goodOutput.sampleUnits)); if (optVerbose) { if ( XLALUnitAsString( unitString, LALUnitTextSize, &(goodOutput.sampleUnits)) == NULL ) { return SZEROPADANDFFTTESTC_EFLS; } printf( "Units are \"%s\", ", unitString ); if ( XLALUnitAsString( unitString, LALUnitTextSize, &expectedUnit) == NULL ) { return SZEROPADANDFFTTESTC_EFLS; } printf( "should be \"%s\"\n", unitString ); } if (result != 0) { printf(" FAIL: Valid data test #1\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } /* check output values */ if (optVerbose) { printf("hBarTilde(0)=%g + %g i, should be %g\n", crealf(goodOutput.data->data[0]), cimagf(goodOutput.data->data[0]), crealf(expectedOutputDataData[0])); } if ( fabsf(crealf(goodOutput.data->data[0]) - crealf(expectedOutputDataData[0])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL || fabsf(cimagf(goodOutput.data->data[0])) > SZEROPADANDFFTTESTC_TOL ) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } for (i=1; i<SZEROPADANDFFTTESTC_LENGTH; ++i) { f = i * SZEROPADANDFFTTESTC_DELTAF; if (optVerbose) { printf("hBarTilde(%f Hz)=%g + %g i, should be %g + %g i\n", f, crealf(goodOutput.data->data[i]), cimagf(goodOutput.data->data[i]), crealf(expectedOutputDataData[i]), cimagf(expectedOutputDataData[i])); } if (fabsf(crealf(goodOutput.data->data[i]) - crealf(expectedOutputDataData[i])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL || fabsf(cimagf(goodOutput.data->data[i]) - cimagf(expectedOutputDataData[i])) /* / expectedOutputDataData[0].re */> SZEROPADANDFFTTESTC_TOL) { printf(" FAIL: Valid data test\n"); if (optVerbose) { printf("Exiting with error: %s\n", SZEROPADANDFFTTESTC_MSGEFLS); } return SZEROPADANDFFTTESTC_EFLS; } } /* write results to output file LALSPrintTimeSeries(&input, "zeropadgoodInput.dat"); LALCPrintFrequencySeries(&output, "zeropadgoodOutput.dat");*/ /* clean up valid data */ LALSDestroyVector(&status, &goodInput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCDestroyVector(&status, &goodOutput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } XLALDestroyREAL4Window(goodParams.window); LALCheckMemoryLeaks(); printf("PASS: all tests\n"); /**************** Process User-Entered Data, If Any **************/ /* ::TODO:: Fix this with length and window type to be specified */ if (optInputFile[0] && optOutputFile[0]){ /* construct plan*/ LALCreateForwardRealFFTPlan(&status, &(goodParams.fftPlan), 2*optLength - 1, optMeasurePlan); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } goodInput.data = NULL; goodOutput.data = NULL; LALSCreateVector(&status, &goodInput.data, optLength); if ( ( code = CheckStatus( &status, 0 , "", SZEROPADANDFFTTESTC_EUSE, SZEROPADANDFFTTESTC_MSGEUSE) ) ) { return code; } LALCCreateVector(&status, &goodOutput.data, optLength); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* Read input file */ LALSReadTimeSeries(&status, &goodInput, optInputFile); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } /* calculate zero-pad and FFT */ LALSZeroPadAndFFT(&status, &goodOutput, &goodInput, &goodParams); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCPrintFrequencySeries(&goodOutput, optOutputFile); printf("===== FFT of Zero-Padded User-Specified Data Written to File %s =====\n", optOutputFile); /* clean up valid data */ LALSDestroyVector(&status, &goodInput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCDestroyVector(&status, &goodOutput.data); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALDestroyRealFFTPlan(&status, &(goodParams.fftPlan)); if ( ( code = CheckStatus(&status, 0 , "", SZEROPADANDFFTTESTC_EFLS, SZEROPADANDFFTTESTC_MSGEFLS) ) ) { return code; } LALCheckMemoryLeaks(); } return SZEROPADANDFFTTESTC_ENOM; }
int main( int argc, char *argv[] ) { LALStatus status = blank_status; UINT4 k; UINT4 kLow; UINT4 kHi; INT4 numPoints = 524288; REAL4 fSampling = 2048.; REAL4 fLow = 70.; REAL4 fLowInj = 40.; REAL8 deltaT = 1./fSampling; REAL8 deltaF = fSampling / numPoints; REAL4 statValue; /* vars required to make freq series */ LIGOTimeGPS epoch = { 0, 0 }; LIGOTimeGPS gpsStartTime = {0, 0}; REAL8 f0 = 0.; REAL8 offset = 0.; INT8 waveformStartTime = 0; /* files contain PSD info */ CHAR *injectionFile = NULL; CHAR *outputFile = NULL; CHAR *specFileH1 = NULL; CHAR *specFileH2 = NULL; CHAR *specFileL1 = NULL; COMPLEX8Vector *unity = NULL; const LALUnit strainPerCount = {0,{0,0,0,0,0,1,-1},{0,0,0,0,0,0,0}}; int numInjections = 0; int numTriggers = 0; /* template bank simulation variables */ INT4 injSimCount = 0; SimInspiralTable *injectionHead = NULL; SimInspiralTable *thisInjection = NULL; SnglInspiralTable *snglHead = NULL; SearchSummaryTable *searchSummHead = NULL; /*SummValueTable *summValueHead = NULL; */ /* raw input data storage */ REAL8FrequencySeries *specH1 = NULL; REAL8FrequencySeries *specH2 = NULL; REAL8FrequencySeries *specL1 = NULL; REAL8FrequencySeries *thisSpec = NULL; COMPLEX8FrequencySeries *resp = NULL; COMPLEX8FrequencySeries *detTransDummy = NULL; REAL4TimeSeries *chan = NULL; RealFFTPlan *pfwd = NULL; COMPLEX8FrequencySeries *fftData = NULL; REAL8 thisSnrsq = 0; REAL8 thisSnr = 0; REAL8 thisCombSnr = 0; REAL8 snrVec[3]; REAL8 dynRange = 1./(3.0e-23); /* needed for inj */ CoherentGW waveform; PPNParamStruc ppnParams; DetectorResponse detector; InterferometerNumber ifoNumber = LAL_UNKNOWN_IFO; /* output data */ LIGOLwXMLStream xmlStream; MetadataTable proctable; MetadataTable outputTable; MetadataTable procparams; CHAR fname[256]; CHAR comment[LIGOMETA_COMMENT_MAX]; ProcessParamsTable *this_proc_param = NULL; CHAR chanfilename[FILENAME_MAX]; REAL4 sum = 0; REAL4 bitten_H1 = 0; REAL4 bitten_H2 = 0; REAL4 thisCombSnr_H1H2 = 0; /* create the process and process params tables */ proctable.processTable = (ProcessTable *) calloc( 1, sizeof(ProcessTable) ); XLALGPSTimeNow(&(proctable.processTable->start_time)); XLALPopulateProcessTable(proctable.processTable, PROGRAM_NAME, lalAppsVCSIdentId, lalAppsVCSIdentStatus, lalAppsVCSIdentDate, 0); this_proc_param = procparams.processParamsTable = (ProcessParamsTable *) calloc( 1, sizeof(ProcessParamsTable) ); memset( comment, 0, LIGOMETA_COMMENT_MAX * sizeof(CHAR) ); /* look at input args, write process params where required */ while ( 1 ) { /* getopt arguments */ static struct option long_options[] = { /* these options set a flag */ /* these options do not set a flag */ {"help", no_argument, 0, 'h'}, {"verbose", no_argument, &vrbflg, 1 }, {"version", no_argument, 0, 'V'}, {"spectrum-H1", required_argument, 0, 'a'}, {"spectrum-H2", required_argument, 0, 'b'}, {"spectrum-L1", required_argument, 0, 'c'}, {"inj-file", required_argument, 0, 'd'}, {"comment", required_argument, 0, 'e'}, {"output-file", required_argument, 0, 'f'}, {"coire-flag", no_argument, &coireflg, 1 }, {"ligo-srd", no_argument, &ligosrd, 1 }, {"write-chan", no_argument, &writechan, 1 }, {"inject-overhead", no_argument, &injoverhead, 1 }, {"f-lower", required_argument, 0, 'g'}, {0, 0, 0, 0} }; int c; /* * * parse command line arguments * */ /* getopt_long stores long option here */ int option_index = 0; size_t optarg_len; c = getopt_long_only( argc, argv, "a:b:c:d:e:f:g:hV", long_options, &option_index ); /* detect the end of the options */ if ( c == - 1 ) { break; } switch ( c ) { case 0: /* if this option set a flag, do nothing else now */ if ( long_options[option_index].flag != 0 ) { break; } else { fprintf( stderr, "error parsing option %s with argument %s\n", long_options[option_index].name, optarg ); exit( 1 ); } break; case 'h': fprintf( stderr, USAGE ); exit( 0 ); break; case 'a': /* create storage for the spectrum file name */ optarg_len = strlen( optarg ) + 1; specFileH1 = (CHAR *) calloc( optarg_len, sizeof(CHAR)); memcpy( specFileH1, optarg, optarg_len ); ADD_PROCESS_PARAM( "string", "%s", optarg ); break; case 'b': /* create storage for the spectrum file name */ optarg_len = strlen( optarg ) + 1; specFileH2 = (CHAR *) calloc( optarg_len, sizeof(CHAR)); memcpy( specFileH2, optarg, optarg_len ); ADD_PROCESS_PARAM( "string", "%s", optarg ); break; case 'c': /* create storage for the spectrum file name */ optarg_len = strlen( optarg ) + 1; specFileL1 = (CHAR *) calloc( optarg_len, sizeof(CHAR)); memcpy( specFileL1, optarg, optarg_len ); ADD_PROCESS_PARAM( "string", "%s", optarg ); break; case 'd': /* create storage for the injection file name */ optarg_len = strlen( optarg ) + 1; injectionFile = (CHAR *) calloc( optarg_len, sizeof(CHAR)); memcpy( injectionFile, optarg, optarg_len ); ADD_PROCESS_PARAM( "string", "%s", optarg ); break; case 'f': /* create storage for the output file name */ optarg_len = strlen( optarg ) + 1; outputFile = (CHAR *) calloc( optarg_len, sizeof(CHAR)); memcpy( outputFile, optarg, optarg_len ); ADD_PROCESS_PARAM( "string", "%s", optarg ); break; case 'g': fLow = (INT4) atof( optarg ); if ( fLow < 40 ) { fprintf( stderr, "invalid argument to --%s:\n" "f-lower must be > 40Hz (%e specified)\n", long_options[option_index].name, fLow ); exit( 1 ); } ADD_PROCESS_PARAM( "float", "%e", fLow ); break; case 'e': if ( strlen( optarg ) > LIGOMETA_COMMENT_MAX - 1 ) { fprintf( stderr, "invalid argument to --%s:\n" "comment must be less than %d characters\n", long_options[option_index].name, LIGOMETA_COMMENT_MAX ); exit( 1 ); } else { snprintf( comment, LIGOMETA_COMMENT_MAX, "%s", optarg); } break; case 'V': /* print version information and exit */ fprintf( stdout, "calculation of expected SNR of injections\n" "Gareth Jones\n"); XLALOutputVersionString(stderr, 0); exit( 0 ); break; default: fprintf( stderr, "unknown error while parsing options\n" ); fprintf( stderr, USAGE ); exit( 1 ); } } if ( optind < argc ) { fprintf( stderr, "extraneous command line arguments:\n" ); while ( optind < argc ) { fprintf ( stderr, "%s\n", argv[optind++] ); } exit( 1 ); } /* check the input arguments */ if ( injectionFile == NULL ) { fprintf( stderr, "Must specify the --injection-file\n" ); exit( 1 ); } if ( outputFile == NULL ) { fprintf( stderr, "Must specify the --output-file\n" ); exit( 1 ); } if ( !ligosrd && specFileH1 == NULL ) { fprintf( stderr, "Must specify the --spectrum-H1\n" ); exit( 1 ); } if ( !ligosrd && specFileH2 == NULL ) { fprintf( stderr, "Must specify the --spectrum-H2\n" ); exit( 1 ); } if ( !ligosrd && specFileL1 == NULL ) { fprintf( stderr, "Must specify the --spectrum-L1\n" ); exit( 1 ); } if ( ligosrd && (specFileH1 || specFileH2 || specFileL1 )) { fprintf( stdout, "WARNING: using LIGOI SRD power spectral density \n" ); } if ( vrbflg ){ fprintf( stdout, "injection file is %s\n", injectionFile ); fprintf( stdout, "output file is %s\n", outputFile ); fprintf( stdout, "H1 spec file is %s\n", specFileH1 ); fprintf( stdout, "H2 spec file is %s\n", specFileH2 ); fprintf( stdout, "L1 spec file is %s\n", specFileL1 ); } /* create vector for H1, H2 and L1 spectrums */ specH1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) ); specH2 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) ); specL1 = XLALCreateREAL8FrequencySeries ( "",&epoch, f0, deltaF, &lalADCCountUnit, (numPoints / 2 + 1) ); if (!specH1 || !specH2 || !specL1){ XLALDestroyREAL8FrequencySeries ( specH1 ); XLALDestroyREAL8FrequencySeries ( specH2 ); XLALDestroyREAL8FrequencySeries ( specL1 ); XLALPrintError("failure allocating H1, H2 and L1 spectra"); exit(1); } if (!ligosrd){ /* read in H1 spectrum */ LAL_CALL( LALDReadFrequencySeries(&status, specH1, specFileH1), &status ); if ( vrbflg ){ fprintf( stdout, "read in H1 spec file\n" ); fflush( stdout ); } /* read in H2 spectrum */ LAL_CALL( LALDReadFrequencySeries(&status, specH2, specFileH2), &status ); if ( vrbflg ){ fprintf( stdout, "read in H2 spec file\n" ); fflush( stdout ); } /* read in L1 spectrum */ LAL_CALL( LALDReadFrequencySeries(&status, specL1, specFileL1), &status ); if ( vrbflg ){ fprintf( stdout, "read in L1 spec file\n" ); fflush( stdout ); } } chan = XLALCreateREAL4TimeSeries( "", &epoch, f0, deltaT, &lalADCCountUnit, numPoints ); if ( !chan ){ XLALPrintError("failure allocating chan"); exit(1); } /* * * set up the response function * */ resp = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch, f0, deltaF, &strainPerCount, (numPoints / 2 + 1) ); if ( !resp ){ XLALPrintError("failure allocating response function"); exit(1); } /* create vector that will contain detector.transfer info, since this * is constant I calculate it once outside of all the loops and pass it * in to detector.transfer when required */ detTransDummy = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch, f0, deltaF, &strainPerCount, (numPoints / 2 + 1) ); if ( !detTransDummy ){ XLALPrintError("failure allocating detector.transfer info"); exit(1); } /* invert the response function to get the transfer function */ unity = XLALCreateCOMPLEX8Vector( resp->data->length ); for ( k = 0; k < unity->length; ++k ) { unity->data[k] = 1.0; } /* set response */ for ( k = 0; k < resp->data->length; ++k ) { resp->data->data[k] = 1.0; } XLALCCVectorDivide( detTransDummy->data, unity, resp->data ); XLALDestroyCOMPLEX8Vector( unity ); /* read in injections from injection file */ /* set endtime to 0 so that we read in all events */ if ( vrbflg ) fprintf( stdout, "Reading sim_inspiral table of %s\n", injectionFile ); LAL_CALL(numInjections = SimInspiralTableFromLIGOLw( &injectionHead, injectionFile, 0, 0), &status); if ( vrbflg ) fprintf( stdout, "Read %d injections from sim_inspiral table of %s\n", numInjections, injectionFile ); if (coireflg){ if ( vrbflg ) fprintf( stdout, "Reading sngl_inspiral table of %s\n", injectionFile ); LAL_CALL(numTriggers = LALSnglInspiralTableFromLIGOLw(&snglHead, injectionFile, 0, -1), &status); if ( vrbflg ) fprintf( stdout, "Read %d triggers from sngl_inspiral table of %s\n", numTriggers, injectionFile ); if ( vrbflg ) { fprintf( stdout, "Reading search_summary table of %s ...", injectionFile ); fflush( stdout ); } searchSummHead = XLALSearchSummaryTableFromLIGOLw (injectionFile); if ( vrbflg ) fprintf( stdout, " done\n"); } /* make sure we start at head of linked list */ thisInjection = injectionHead; /* setting fixed waveform injection parameters */ memset( &ppnParams, 0, sizeof(PPNParamStruc) ); ppnParams.deltaT = deltaT; ppnParams.lengthIn = 0; ppnParams.ppn = NULL; /* loop over injections */ injSimCount = 0; do { fprintf( stdout, "injection %d/%d\n", injSimCount+1, numInjections ); /* reset waveform structure */ memset( &waveform, 0, sizeof(CoherentGW) ); /* reset chan structure */ memset( chan->data->data, 0, chan->data->length * sizeof(REAL4) ); if (thisInjection->f_lower == 0){ fprintf( stdout, "WARNING: f_lower in sim_inpiral = 0, "); fprintf( stdout, "changing this to %e\n ", fLowInj); thisInjection->f_lower = fLowInj; } /* create the waveform, amp, freq phase etc */ LAL_CALL( LALGenerateInspiral(&status, &waveform, thisInjection, &ppnParams), &status); if (vrbflg) fprintf( stdout, "ppnParams.tc %e\n ", ppnParams.tc); statValue = 0.; /* calc lower index for integration */ kLow = ceil(fLow / deltaF); if ( vrbflg ) { fprintf( stdout, "starting integration to find SNR at frequency %e ", fLow); fprintf( stdout, "at index %d \n", kLow); } /* calc upper index for integration */ kHi = floor(fSampling / (2. * deltaF)); if ( vrbflg ) { fprintf( stdout, "ending integration to find SNR at frequency %e ", fSampling / 2.); fprintf( stdout, "at index %d \n", kHi); } /* loop over ifo */ for ( ifoNumber = 1; ifoNumber < 4; ifoNumber++ ) { /* allocate memory and copy the parameters describing the freq series */ memset( &detector, 0, sizeof( DetectorResponse ) ); detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) ); if (injoverhead){ if ( vrbflg ) fprintf( stdout, "WARNING: perform overhead injections\n"); /* setting detector.site to NULL causes SimulateCoherentGW to * perform overhead injections */ detector.site = NULL; } else { /* if not overhead, set detector.site using ifonumber */ XLALReturnDetector( detector.site, ifoNumber ); } switch ( ifoNumber ) { case 1: if ( vrbflg ) fprintf( stdout, "looking at H1 \n"); thisSpec = specH1; break; case 2: if ( vrbflg ) fprintf( stdout, "looking at H2 \n"); thisSpec = specH2; break; case 3: if ( vrbflg ) fprintf( stdout, "looking at L1 \n"); thisSpec = specL1; break; default: fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber ); exit( 1 ); } /* get the gps start time of the signal to inject */ waveformStartTime = XLALGPSToINT8NS( &(thisInjection->geocent_end_time) ); waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc ); offset = (chan->data->length / 2.0) * chan->deltaT; gpsStartTime.gpsSeconds = thisInjection->geocent_end_time.gpsSeconds - offset; gpsStartTime.gpsNanoSeconds = thisInjection->geocent_end_time.gpsNanoSeconds; chan->epoch = gpsStartTime; if (vrbflg) fprintf(stdout, "offset start time of injection by %f seconds \n", offset ); /* is this okay? copying in detector transfer which so far only contains response info */ detector.transfer = detTransDummy; XLALUnitInvert( &(detector.transfer->sampleUnits), &(resp->sampleUnits) ); /* set the start times for injection */ XLALINT8NSToGPS( &(waveform.a->epoch), waveformStartTime ); memcpy(&(waveform.f->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) ); memcpy(&(waveform.phi->epoch), &(waveform.a->epoch), sizeof(LIGOTimeGPS) ); /* perform the injection */ LAL_CALL( LALSimulateCoherentGW(&status, chan, &waveform, &detector ), &status); if (writechan){ /* write out channel data */ if (vrbflg) fprintf(stdout, "writing channel data to file... \n" ); switch ( ifoNumber ) { case 1: snprintf( chanfilename, FILENAME_MAX, "chanTest_H1_inj%d.dat", injSimCount+1); if (vrbflg) fprintf( stdout, "writing H1 channel time series out to %s\n", chanfilename ); LALSPrintTimeSeries(chan, chanfilename ); break; case 2: snprintf( chanfilename, FILENAME_MAX, "chanTest_H2_inj%d.dat", injSimCount+1); if (vrbflg) fprintf( stdout, "writing H2 channel time series out to %s\n", chanfilename ); LALSPrintTimeSeries(chan, chanfilename ); break; case 3: snprintf( chanfilename, FILENAME_MAX, "chanTest_L1_inj%d.dat", injSimCount+1); if (vrbflg) fprintf( stdout, "writing L1 channel time series out to %s\n", chanfilename ); LALSPrintTimeSeries(chan, chanfilename ); break; default: fprintf( stderr, "Error: ifoNumber %d does not correspond to H1, H2 or L1: \n", ifoNumber ); exit( 1 ); } } LAL_CALL( LALCreateForwardRealFFTPlan( &status, &pfwd, chan->data->length, 0), &status); fftData = XLALCreateCOMPLEX8FrequencySeries( chan->name, &chan->epoch, f0, deltaF, &lalDimensionlessUnit, (numPoints / 2 + 1) ); if ( !fftData ){ XLALPrintError("failure allocating fftData"); exit(1); } LAL_CALL( LALTimeFreqRealFFT( &status, fftData, chan, pfwd ), &status); LAL_CALL( LALDestroyRealFFTPlan( &status, &pfwd ), &status); pfwd = NULL; /* compute the SNR */ thisSnrsq = 0; /* avoid f=0 part of psd */ if (ligosrd){ if (vrbflg) fprintf( stdout, "using LIGOI PSD \n"); for ( k = kLow; k < kHi; k++ ) { REAL8 freq; REAL8 sim_psd_value; freq = fftData->deltaF * k; LALLIGOIPsd( NULL, &sim_psd_value, freq ); thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * (crealf(fftData->data->data[k]) * dynRange)) / sim_psd_value; thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * (cimagf(fftData->data->data[k]) * dynRange)) / sim_psd_value; } } else { if (vrbflg) fprintf( stdout, "using input spectra \n"); for ( k = kLow; k < kHi; k++ ) { thisSnrsq += ((crealf(fftData->data->data[k]) * dynRange) * (crealf(fftData->data->data[k]) * dynRange)) / (thisSpec->data->data[k] * dynRange * dynRange); thisSnrsq += ((cimagf(fftData->data->data[k]) * dynRange) * (cimagf(fftData->data->data[k]) * dynRange)) / (thisSpec->data->data[k] * dynRange * dynRange); } } thisSnrsq *= 4*fftData->deltaF; thisSnr = pow(thisSnrsq, 0.5); /* Note indexing on snrVec, ifoNumber runs from 1..3 to get source correct, * we must index snrVec 0..2 */ snrVec[ifoNumber-1] = thisSnr; XLALDestroyCOMPLEX8FrequencySeries(fftData); if ( vrbflg ){ fprintf( stdout, "thisSnrsq %e\n", thisSnrsq ); fprintf( stdout, "snrVec %e\n", snrVec[ifoNumber-1] ); fflush( stdout ); } /* sum thisSnrsq to eventually get combined snr*/ statValue += thisSnrsq; /* free some memory */ if (detector.transfer) detector.transfer = NULL; if ( detector.site ) {LALFree( detector.site); detector.site = NULL;} } /* end loop over ifo */ destroyCoherentGW( &waveform ); /* store inverse eff snrs in eff_dist columns */ thisInjection->eff_dist_h = 1./snrVec[0]; thisInjection->eff_dist_g = 1./snrVec[1]; thisInjection->eff_dist_l = 1./snrVec[2]; /* store inverse sum of squares snr in eff_dist_t */ thisCombSnr = pow(statValue, 0.5); if ( vrbflg ) fprintf( stdout, "thisCombSnr %e\n", thisCombSnr); thisInjection->eff_dist_t = 1./thisCombSnr; /* calc inverse bittenL snr for H1H2 and store in eff_dist_v */ thisCombSnr_H1H2 = 0.; sum = snrVec[0] * snrVec[0] + snrVec[1] * snrVec[1]; bitten_H1 = 3 * snrVec[0] -3; bitten_H2 = 3 * snrVec[1] -3; if (sum < bitten_H1){ thisCombSnr_H1H2 = sum; } else { thisCombSnr_H1H2 = bitten_H1; } if (bitten_H2 < thisCombSnr_H1H2){ thisCombSnr_H1H2 = bitten_H2; } thisInjection->eff_dist_v = 1./thisCombSnr_H1H2; /* increment the bank sim sim_inspiral table if necessary */ if ( injectionHead ) { thisInjection = thisInjection->next; } } while ( ++injSimCount < numInjections ); /* end loop over injections */ /* try opening, writing and closing an xml file */ /* open the output xml file */ memset( &xmlStream, 0, sizeof(LIGOLwXMLStream) ); snprintf( fname, sizeof(fname), "%s", outputFile); LAL_CALL( LALOpenLIGOLwXMLFile ( &status, &xmlStream, fname), &status); /* write out the process and process params tables */ if ( vrbflg ) fprintf( stdout, "process... " ); XLALGPSTimeNow(&(proctable.processTable->end_time)); LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, proctable, process_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status ); free( proctable.processTable ); /* Just being pedantic here ... */ proctable.processTable = NULL; /* free the unused process param entry */ this_proc_param = procparams.processParamsTable; procparams.processParamsTable = procparams.processParamsTable->next; free( this_proc_param ); this_proc_param = NULL; /* write the process params table */ if ( vrbflg ) fprintf( stdout, "process_params... " ); LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, process_params_table ), &status ); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, procparams, process_params_table ), &status ); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream ), &status ); /* write the search summary table */ if ( coireflg ){ if ( vrbflg ) fprintf( stdout, "search_summary... " ); outputTable.searchSummaryTable = searchSummHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, search_summary_table), &status); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, search_summary_table), &status); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream), &status); } /* write the sim inspiral table */ if ( vrbflg ) fprintf( stdout, "sim_inspiral... " ); outputTable.simInspiralTable = injectionHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sim_inspiral_table), &status); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sim_inspiral_table), &status); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream), &status); /* write the sngl inspiral table */ if ( coireflg ){ if ( vrbflg ) fprintf( stdout, "sngl_inspiral... " ); outputTable.snglInspiralTable = snglHead; LAL_CALL( LALBeginLIGOLwXMLTable( &status, &xmlStream, sngl_inspiral_table), &status); LAL_CALL( LALWriteLIGOLwXMLTable( &status, &xmlStream, outputTable, sngl_inspiral_table), &status); LAL_CALL( LALEndLIGOLwXMLTable ( &status, &xmlStream), &status); } /* close the xml file */ LAL_CALL( LALCloseLIGOLwXMLFile ( &status, &xmlStream), &status); /* Freeing memory */ XLALDestroyREAL4TimeSeries(chan); XLALDestroyCOMPLEX8FrequencySeries(resp); XLALDestroyCOMPLEX8FrequencySeries(detTransDummy); XLALDestroyREAL8FrequencySeries ( specH1 ); XLALDestroyREAL8FrequencySeries ( specH2 ); XLALDestroyREAL8FrequencySeries ( specL1 ); free( specFileH1 ); specFileH1 = NULL; free( specFileH2 ); specFileH2 = NULL; free( specFileL1 ); specFileL1 = NULL; free( injectionFile ); injectionFile = NULL; /* free the process params */ while( procparams.processParamsTable ) { this_proc_param = procparams.processParamsTable; procparams.processParamsTable = this_proc_param->next; free( this_proc_param ); this_proc_param = NULL; } /* free the sim inspiral tables */ while ( injectionHead ) { thisInjection = injectionHead; injectionHead = injectionHead->next; LALFree( thisInjection ); } /*check for memory leaks */ LALCheckMemoryLeaks(); exit( 0 ); }
int main( void ) { const UINT4 n = 65536; const UINT4 m = 8; static AverageSpectrumParams specpar; static REAL4FrequencySeries fseries; static REAL4TimeSeries tseries; static LALStatus status; static RandomParams *randpar; REAL8 ave; UINT4 i; /* allocate memory for time and frequency series */ tseries.deltaT = 1; LALCreateVector( &status, &tseries.data, n * m ); TESTSTATUS( &status ); LALCreateVector( &status, &fseries.data, n / 2 + 1 ); TESTSTATUS( &status ); /* set time series data to be a unit impulse */ /* memset( tseries.data->data, 0, tseries.data->length * sizeof( *tseries.data->data ) ); tseries.data->data[0] = 1; */ randpar = XLALCreateRandomParams( 1 ); XLALNormalDeviates( tseries.data, randpar ); XLALDestroyRandomParams( randpar ); /* prepare average spectrum parameters */ specpar.method = useMedian; specpar.overlap = n / 2; /* specpar.overlap = 0; */ LALCreateForwardRealFFTPlan( &status, &specpar.plan, n, 0 ); TESTSTATUS( &status ); specpar.window = XLALCreateWelchREAL4Window(n); /* compute spectrum */ LALREAL4AverageSpectrum( &status, &fseries, &tseries, &specpar ); TESTSTATUS( &status ); /* output results -- omit DC & Nyquist */ /* for ( i = 1; i < fseries.data->length - 1; ++i ) fprintf( stdout, "%e\t%e\n", i * fseries.deltaF, fseries.data->data[i] ); */ /* average values of power spectrum (omit DC & Nyquist ) */ ave = 0; for ( i = 1; i < fseries.data->length - 1; ++i ) ave += fseries.data->data[i]; ave /= fseries.data->length - 2; fprintf( stdout, "median:\t%e\terror:\t%f%%\n", ave, fabs( ave - 2.0 ) / 0.02 ); /* now do the same for mean */ specpar.method = useMean; LALREAL4AverageSpectrum( &status, &fseries, &tseries, &specpar ); TESTSTATUS( &status ); /* average values of power spectrum (omit DC & Nyquist ) */ ave = 0; for ( i = 1; i < fseries.data->length - 1; ++i ) ave += fseries.data->data[i]; ave /= fseries.data->length - 2; fprintf( stdout, "mean:\t%e\terror:\t%f%%\n", ave, fabs( ave - 2.0 ) / 0.02 ); /* cleanup */ XLALDestroyREAL4Window( specpar.window ); LALDestroyRealFFTPlan( &status, &specpar.plan ); TESTSTATUS( &status ); LALDestroyVector( &status, &fseries.data ); TESTSTATUS( &status ); LALDestroyVector( &status, &tseries.data ); TESTSTATUS( &status ); /* exit */ LALCheckMemoryLeaks(); return 0; }
int main( int argc, char *argv[] ) { const UINT4 n = 65536; const REAL4 dt = 1.0 / 16384.0; static LALStatus status; static REAL4TimeSeries x; static COMPLEX8FrequencySeries X; static REAL4TimeSeries y; static REAL4FrequencySeries Y; static COMPLEX8TimeSeries z; static COMPLEX8FrequencySeries Z; RealFFTPlan *fwdRealPlan = NULL; RealFFTPlan *revRealPlan = NULL; ComplexFFTPlan *fwdComplexPlan = NULL; ComplexFFTPlan *revComplexPlan = NULL; RandomParams *randpar = NULL; AverageSpectrumParams avgSpecParams; UINT4 srate[] = { 4096, 9000 }; UINT4 npts[] = { 262144, 1048576 }; REAL4 var[] = { 5, 16 }; UINT4 j, sr, np, vr; /*CHAR fname[2048];*/ ParseOptions( argc, argv ); LALSCreateVector( &status, &x.data, n ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &X.data, n / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &z.data, n ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &Z.data, n ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateForwardRealFFTPlan( &status, &fwdRealPlan, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateReverseRealFFTPlan( &status, &revRealPlan, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateForwardComplexFFTPlan( &status, &fwdComplexPlan, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateReverseComplexFFTPlan( &status, &revComplexPlan, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); randpar = XLALCreateRandomParams( 100 ); /* * * Try the real transform. * */ x.f0 = 0; x.deltaT = dt; x.sampleUnits = lalMeterUnit; snprintf( x.name, sizeof( x.name ), "x" ); XLALNormalDeviates( x.data, randpar ); for ( j = 0; j < n; ++j ) /* add a 60 Hz line */ { REAL4 t = j * dt; x.data->data[j] += 0.1 * cos( LAL_TWOPI * 60.0 * t ); } LALSPrintTimeSeries( &x, "x.out" ); snprintf( X.name, sizeof( X.name ), "X" ); LALTimeFreqRealFFT( &status, &X, &x, fwdRealPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALCPrintFrequencySeries( &X, "X.out" ); LALFreqTimeRealFFT( &status, &x, &X, revRealPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALSPrintTimeSeries( &x, "xx.out" ); /* * * Try the average power spectum. * */ avgSpecParams.method = useMean; for ( np = 0; np < XLAL_NUM_ELEM(npts) ; ++np ) { /* length of time series for 7 segments, overlapped by 1/2 segment */ UINT4 tsLength = npts[np] * 7 - 6 * npts[np] / 2; LALCreateVector( &status, &y.data, tsLength ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateVector( &status, &Y.data, npts[np] / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); avgSpecParams.overlap = npts[np] / 2; /* create the window */ avgSpecParams.window = XLALCreateHannREAL4Window(npts[np]); avgSpecParams.plan = NULL; LALCreateForwardRealFFTPlan( &status, &avgSpecParams.plan, npts[np], 0 ); TestStatus( &status, CODES( 0 ), 1 ); for ( sr = 0; sr < XLAL_NUM_ELEM(srate) ; ++sr ) { /* set the sample rate of the time series */ y.deltaT = 1.0 / (REAL8) srate[sr]; for ( vr = 0; vr < XLAL_NUM_ELEM(var) ; ++vr ) { REAL4 eps = 1e-6; /* very conservative fp precision */ REAL4 Sfk = 2.0 * var[vr] * var[vr] * y.deltaT; REAL4 sfk = 0; REAL4 lbn; REAL4 sig; REAL4 ssq; REAL4 tol; /* create the data */ XLALNormalDeviates( y.data, randpar ); ssq = 0; for ( j = 0; j < y.data->length; ++j ) { y.data->data[j] *= var[vr]; ssq += y.data->data[j] * y.data->data[j]; } /* compute tolerance for comparison */ lbn = log( y.data->length ) / log( 2 ); sig = sqrt( 2.5 * lbn * eps * eps * ssq / y.data->length ); tol = 5 * sig; /* compute the psd and find the average */ LALREAL4AverageSpectrum( &status, &Y, &y, &avgSpecParams ); TestStatus( &status, CODES( 0 ), 1 ); LALSMoment( &status, &sfk, Y.data, 1 ); TestStatus( &status, CODES( 0 ), 1 ); /* check the result */ if ( fabs(Sfk-sfk) > tol ) { fprintf( stderr, "FAIL: PSD estimate appears incorrect\n"); fprintf( stderr, "expected %e, got %e ", Sfk, sfk ); fprintf( stderr, "(difference = %e, tolerance = %e)\n", fabs(Sfk-sfk), tol ); exit(2); } } } /* destroy structures that need to be resized */ LALDestroyRealFFTPlan( &status, &avgSpecParams.plan ); TestStatus( &status, CODES( 0 ), 1 ); XLALDestroyREAL4Window( avgSpecParams.window ); LALDestroyVector( &status, &y.data ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyVector( &status, &Y.data ); TestStatus( &status, CODES( 0 ), 1 ); } /* * * Try the complex transform. * */ z.f0 = 0; z.deltaT = dt; z.sampleUnits = lalVoltUnit; snprintf( z.name, sizeof( z.name ), "z" ); { /* dirty hack */ REAL4Vector tmp; tmp.length = 2 * z.data->length; tmp.data = (REAL4 *)z.data->data; XLALNormalDeviates( &tmp, randpar ); } for ( j = 0; j < n; ++j ) /* add a 50 Hz line and a 500 Hz ringdown */ { REAL4 t = j * dt; z.data->data[j] += 0.2 * cos( LAL_TWOPI * 50.0 * t ); z.data->data[j] += I * exp( -t ) * sin( LAL_TWOPI * 500.0 * t ); } LALCPrintTimeSeries( &z, "z.out" ); TestStatus( &status, CODES( 0 ), 1 ); snprintf( Z.name, sizeof( Z.name ), "Z" ); LALTimeFreqComplexFFT( &status, &Z, &z, fwdComplexPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALCPrintFrequencySeries( &Z, "Z.out" ); LALFreqTimeComplexFFT( &status, &z, &Z, revComplexPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALCPrintTimeSeries( &z, "zz.out" ); XLALDestroyRandomParams( randpar ); LALDestroyRealFFTPlan( &status, &fwdRealPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyRealFFTPlan( &status, &revRealPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyComplexFFTPlan( &status, &fwdComplexPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyComplexFFTPlan( &status, &revComplexPlan ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &Z.data ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &z.data ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &X.data ); TestStatus( &status, CODES( 0 ), 1 ); LALSDestroyVector( &status, &x.data ); TestStatus( &status, CODES( 0 ), 1 ); LALCheckMemoryLeaks(); return 0; }
int main( void ) { UINT4 resamplefac = 4; UINT4 seglen = 64 * 1024; /* after resampling */ UINT4 numovrlpseg = 10; /* after resampling */ UINT4 stride = seglen / 2; /* after resampling */ UINT4 reclen = numovrlpseg * stride + stride; /* after resampling */ /* UINT4 numovrlpseg = 8; */ /* after resampling */ /* UINT4 stride = seglen; */ /* after resampling */ /* UINT4 reclen = numovrlpseg * stride; */ /* after resampling */ static LALStatus status; static AverageSpectrumParams specpar; static REAL4FrequencySeries fseries; static REAL4TimeSeries tseries; static RandomParams *randpar; static ResampleTSParams resamplepar; static PassBandParamStruc highpasspar; REAL8 avg; UINT4 j; UINT4 k; FILE *fp; /* allocate memory for time and frequency series */ tseries.deltaT = 0.1; LALCreateVector( &status, &tseries.data, reclen * resamplefac ); TESTSTATUS( &status ); LALCreateVector( &status, &fseries.data, seglen / 2 + 1 ); TESTSTATUS( &status ); for ( j = 0; j < tseries.data->length; ++j ) tseries.data->data[j] = sin( 0.1 * j ); /* memset( tseries.data->data, 0, tseries.data->length * sizeof( *tseries.data->data ) ); tseries.data->data[seglen/2-1] = 1; tseries.data->data[seglen/2] = 1; tseries.data->data[seglen/2+1] = 1; */ /* create white Gaussian noise */ LALCreateRandomParams( &status, &randpar, 0 ); TESTSTATUS( &status ); LALNormalDeviates( &status, tseries.data, randpar ); TESTSTATUS( &status ); LALDestroyRandomParams( &status, &randpar ); TESTSTATUS( &status ); /* resample */ resamplepar.deltaT = resamplefac * tseries.deltaT; resamplepar.filterType = defaultButterworth; LALResampleREAL4TimeSeries( &status, &tseries, &resamplepar ); TESTSTATUS( &status ); /* do some simple colouring: high-pass filter */ highpasspar.nMax = 4; highpasspar.f1 = -1; highpasspar.a1 = -1; highpasspar.f2 = 0.1 / tseries.deltaT; /* ~20% of Nyquist */ highpasspar.a2 = 0.9; /* this means 10% attenuation at f2 */ LALDButterworthREAL4TimeSeries( &status, &tseries, &highpasspar ); TESTSTATUS( &status ); specpar.method = useMean; specpar.overlap = seglen - stride; LALCreateForwardRealFFTPlan( &status, &specpar.plan, seglen, 0 ); TESTSTATUS( &status ); specpar.window = XLALCreateRectangularREAL4Window(seglen); /* compute spectrum */ LALREAL4AverageSpectrum( &status, &fseries, &tseries, &specpar ); TESTSTATUS( &status ); /* output results */ fp = fopen( "out1.dat", "w" ); for ( k = 0; k < fseries.data->length; ++k ) fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] ); fclose( fp ); /* compute average */ avg = 0; for ( k = 1; k < fseries.data->length - 1; ++k ) avg += fseries.data->data[k]; avg /= ( fseries.data->length - 2 ); printf( "lal mean:\t%g\n", avg ); /* use the xlal function */ XLALREAL4AverageSpectrumWelch( &fseries, &tseries, seglen, stride, specpar.window, specpar.plan ); if ( xlalErrno ) { XLAL_PERROR(); exit( 1 ); } /* output results */ fp = fopen( "out2.dat", "w" ); for ( k = 0; k < fseries.data->length; ++k ) fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] ); fclose( fp ); /* compute average */ avg = 0; for ( k = 1; k < fseries.data->length - 1; ++k ) avg += fseries.data->data[k]; avg /= ( fseries.data->length - 2 ); printf( "xlal mean:\t%g\n", avg ); /* median-mean method */ XLALREAL4AverageSpectrumMedianMean( &fseries, &tseries, seglen, stride, specpar.window, specpar.plan ); if ( xlalErrno ) { XLAL_PERROR(); exit( 1 ); } /* output results */ fp = fopen( "out3.dat", "w" ); for ( k = 0; k < fseries.data->length; ++k ) fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] ); fclose( fp ); /* compute average */ avg = 0; for ( k = 1; k < fseries.data->length - 1; ++k ) avg += fseries.data->data[k]; avg /= ( fseries.data->length - 2 ); printf( "med mean:\t%g\n", avg ); /* median method */ XLALREAL4AverageSpectrumMedian( &fseries, &tseries, seglen, stride, specpar.window, specpar.plan ); if ( xlalErrno ) { XLAL_PERROR(); exit( 1 ); } /* output results */ fp = fopen( "out4.dat", "w" ); for ( k = 0; k < fseries.data->length; ++k ) fprintf( fp, "%e\t%e\n", k * fseries.deltaF, fseries.data->data[k] ); fclose( fp ); /* compute average */ avg = 0; for ( k = 1; k < fseries.data->length - 1; ++k ) avg += fseries.data->data[k]; avg /= ( fseries.data->length - 2 ); printf( "median:\t\t%g\n", avg ); /* cleanup */ XLALDestroyREAL4Window( specpar.window ); LALDestroyRealFFTPlan( &status, &specpar.plan ); TESTSTATUS( &status ); LALDestroyVector( &status, &fseries.data ); TESTSTATUS( &status ); LALDestroyVector( &status, &tseries.data ); TESTSTATUS( &status ); /* exit */ LALCheckMemoryLeaks(); return 0; }
int main( int argc, char *argv[] ) { static LALStatus status; RealFFTPlan *fwd = NULL; RealFFTPlan *rev = NULL; REAL4Vector *dat = NULL; REAL4Vector *rfft = NULL; REAL4Vector *ans = NULL; COMPLEX8Vector *dft = NULL; COMPLEX8Vector *fft = NULL; #if LAL_CUDA_ENABLED /* The test itself should pass at 1e-4, but it might fail at * some rare cases where accuracy is bad for some numbers. */ REAL8 eps = 3e-4; #else /* very conservative floating point precision */ REAL8 eps = 1e-6; #endif REAL8 lbn; REAL8 ssq; REAL8 var; REAL8 tol; UINT4 nmax; UINT4 m; UINT4 n; UINT4 i; UINT4 j; UINT4 k; UINT4 s = 0; FILE *fp; ParseOptions( argc, argv ); m = m_; n = n_; fp = verbose ? stdout : NULL ; if ( n == 0 ) { nmax = 65536; } else { nmax = n--; } while ( n < nmax ) { if ( n < 128 ) { ++n; } else { n *= 2; } LALSCreateVector( &status, &dat, n ); TestStatus( &status, CODES( 0 ), 1 ); LALSCreateVector( &status, &rfft, n ); TestStatus( &status, CODES( 0 ), 1 ); LALSCreateVector( &status, &ans, n ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &dft, n / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); LALCCreateVector( &status, &fft, n / 2 + 1 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateForwardRealFFTPlan( &status, &fwd, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); LALCreateReverseRealFFTPlan( &status, &rev, n, 0 ); TestStatus( &status, CODES( 0 ), 1 ); /* * * Do m trials of random data. * */ for ( i = 0; i < m; ++i ) { srand( s++ ); /* seed the random number generator */ /* * * Create data and compute error tolerance. * * Reference: Kaneko and Liu, * "Accumulation of round-off error in fast fourier tranforms" * J. Asssoc. Comp. Mach, Vol 17 (No 4) 637-654, October 1970. * */ srand( i ); /* seed the random number generator */ ssq = 0; for ( j = 0; j < n; ++j ) { dat->data[j] = 20.0 * rand() / (REAL4)( RAND_MAX + 1.0 ) - 10.0; ssq += dat->data[j] * dat->data[j]; fp ? fprintf( fp, "%e\n", dat->data[j] ) : 0; } lbn = log( n ) / log( 2 ); var = 2.5 * lbn * eps * eps * ssq / n; tol = 5 * sqrt( var ); /* up to 5 sigma excursions */ fp ? fprintf( fp, "\neps = %e \ntol = %e\n", eps, tol ) : 0; /* * * Perform forward FFT and DFT (only if n < 100). * */ LALForwardRealFFT( &status, fft, dat, fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALREAL4VectorFFT( &status, rfft, dat, fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALREAL4VectorFFT( &status, ans, rfft, rev ); TestStatus( &status, CODES( 0 ), 1 ); fp ? fprintf( fp, "rfft()\t\trfft(rfft())\trfft(rfft())\n\n" ) : 0; for ( j = 0; j < n; ++j ) { fp ? fprintf( fp, "%e\t%e\t%e\n", rfft->data[j], ans->data[j], ans->data[j] / n ) : 0; } if ( n < 128 ) { LALForwardRealDFT( &status, dft, dat ); TestStatus( &status, CODES( 0 ), 1 ); /* * * Check accuracy of FFT vs DFT. * */ fp ? fprintf( fp, "\nfftre\t\tfftim\t\t" ) : 0; fp ? fprintf( fp, "dtfre\t\tdftim\n" ) : 0; for ( k = 0; k <= n / 2; ++k ) { REAL8 fftre = creal(fft->data[k]); REAL8 fftim = cimag(fft->data[k]); REAL8 dftre = creal(dft->data[k]); REAL8 dftim = cimag(dft->data[k]); REAL8 errre = fabs( dftre - fftre ); REAL8 errim = fabs( dftim - fftim ); REAL8 avere = fabs( dftre + fftre ) / 2 + eps; REAL8 aveim = fabs( dftim + fftim ) / 2 + eps; REAL8 ferre = errre / avere; REAL8 ferim = errim / aveim; fp ? fprintf( fp, "%e\t%e\t", fftre, fftim ) : 0; fp ? fprintf( fp, "%e\t%e\n", dftre, dftim ) : 0; /* fp ? fprintf( fp, "%e\t%e\t", errre, errim ) : 0; */ /* fp ? fprintf( fp, "%e\t%e\n", ferre, ferim ) : 0; */ if ( ferre > eps && errre > tol ) { fputs( "FAIL: Incorrect result from forward transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", errre ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", ferre ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } if ( ferim > eps && errim > tol ) { fputs( "FAIL: Incorrect result from forward transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", errim ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", ferim ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } } } /* * * Perform reverse FFT and check accuracy vs original data. * */ LALReverseRealFFT( &status, ans, fft, rev ); TestStatus( &status, CODES( 0 ), 1 ); fp ? fprintf( fp, "\ndat->data[j]\tans->data[j] / n\n" ) : 0; for ( j = 0; j < n; ++j ) { REAL8 err = fabs( dat->data[j] - ans->data[j] / n ); REAL8 ave = fabs( dat->data[j] + ans->data[j] / n ) / 2 + eps; REAL8 fer = err / ave; fp ? fprintf( fp, "%e\t%e\n", dat->data[j], ans->data[j] / n ) : 0; /* fp ? fprintf( fp, "%e\t%e\n", err, fer ) : 0; */ if ( fer > eps && err > tol ) { fputs( "FAIL: Incorrect result after reverse transform\n", stderr ); fprintf( stderr, "\tdifference = %e\n", err ); fprintf( stderr, "\ttolerance = %e\n", tol ); fprintf( stderr, "\tfrac error = %e\n", fer ); fprintf( stderr, "\tprecision = %e\n", eps ); return 1; } } } LALSDestroyVector( &status, &dat ); TestStatus( &status, CODES( 0 ), 1 ); LALSDestroyVector( &status, &rfft ); TestStatus( &status, CODES( 0 ), 1 ); LALSDestroyVector( &status, &ans ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &dft ); TestStatus( &status, CODES( 0 ), 1 ); LALCDestroyVector( &status, &fft ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyRealFFTPlan( &status, &fwd ); TestStatus( &status, CODES( 0 ), 1 ); LALDestroyRealFFTPlan( &status, &rev ); TestStatus( &status, CODES( 0 ), 1 ); } LALCheckMemoryLeaks(); return 0; }