/** * \brief Provides an interface between code build from \ref lalinspiral_findchirp and * various simulation packages for injecting chirps into data. * \author Brown, D. A. and Creighton, T. D * * Injects the signals described * in the linked list of \c SimInspiralTable structures \c events * into the data \c chan. The response function \c resp should * contain the response function to use when injecting the signals into the data. */ void LALFindChirpInjectIMR ( LALStatus *status, REAL4TimeSeries *chan, SimInspiralTable *events, SimRingdownTable *ringdownevents, COMPLEX8FrequencySeries *resp, INT4 injectSignalType ) { UINT4 k; DetectorResponse detector; SimInspiralTable *thisEvent = NULL; SimRingdownTable *thisRingdownEvent = NULL; PPNParamStruc ppnParams; CoherentGW waveform, *wfm; INT8 waveformStartTime; REAL4TimeSeries signalvec; COMPLEX8Vector *unity = NULL; CHAR warnMsg[512]; #if 0 UINT4 n; UINT4 i; #endif INITSTATUS(status); ATTATCHSTATUSPTR( status ); ASSERT( chan, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( chan->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( chan->data->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( events, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); ASSERT( resp->data->data, status, FINDCHIRPH_ENULL, FINDCHIRPH_MSGENULL ); /* * * set up structures and parameters needed * */ /* fixed waveform injection parameters */ memset( &ppnParams, 0, sizeof(PPNParamStruc) ); ppnParams.deltaT = chan->deltaT; ppnParams.lengthIn = 0; ppnParams.ppn = NULL; /* * * compute the transfer function from the given response function * */ /* allocate memory and copy the parameters describing the freq series */ memset( &detector, 0, sizeof( DetectorResponse ) ); detector.transfer = (COMPLEX8FrequencySeries *) LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) ); if ( ! detector.transfer ) { ABORT( status, FINDCHIRPH_EALOC, FINDCHIRPH_MSGEALOC ); } memcpy( &(detector.transfer->epoch), &(resp->epoch), sizeof(LIGOTimeGPS) ); detector.transfer->f0 = resp->f0; detector.transfer->deltaF = resp->deltaF; detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) ); /* set the detector site */ switch ( chan->name[0] ) { case 'H': *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF]; LALWarning( status, "computing waveform for Hanford." ); break; case 'L': *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF]; LALWarning( status, "computing waveform for Livingston." ); break; case 'G': *(detector.site) = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; LALWarning( status, "computing waveform for GEO600." ); break; case 'T': *(detector.site) = lalCachedDetectors[LALDetectorIndexTAMA300DIFF]; LALWarning( status, "computing waveform for TAMA300." ); break; case 'V': *(detector.site) = lalCachedDetectors[LALDetectorIndexVIRGODIFF]; LALWarning( status, "computing waveform for Virgo." ); break; default: LALFree( detector.site ); detector.site = NULL; LALWarning( status, "Unknown detector site, computing plus mode " "waveform with no time delay" ); break; } /* set up units for the transfer function */ if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { ABORTXLAL(status); } /* invert the response function to get the transfer function */ LALCCreateVector( status->statusPtr, &( detector.transfer->data ), resp->data->length ); CHECKSTATUSPTR( status ); LALCCreateVector( status->statusPtr, &unity, resp->data->length ); CHECKSTATUSPTR( status ); for ( k = 0; k < resp->data->length; ++k ) { unity->data[k] = 1.0; } LALCCVectorDivide( status->statusPtr, detector.transfer->data, unity, resp->data ); CHECKSTATUSPTR( status ); LALCDestroyVector( status->statusPtr, &unity ); CHECKSTATUSPTR( status ); thisRingdownEvent = ringdownevents; /* * * loop over the signals and inject them into the time series * */ for ( thisEvent = events; thisEvent; thisEvent = thisEvent->next) { /* * * generate waveform and inject it into the data * */ /* clear the waveform structure */ memset( &waveform, 0, sizeof(CoherentGW) ); LALGenerateInspiral(status->statusPtr, &waveform, thisEvent, &ppnParams); CHECKSTATUSPTR( status ); /* add the ringdown */ wfm = XLALGenerateInspRing( &waveform, thisEvent, thisRingdownEvent, injectSignalType ); if ( !wfm ) { fprintf( stderr, "Failed to generate the waveform \n" ); if (xlalErrno == XLAL_EFAILED) { fprintf( stderr, "Too much merger\n"); XLALDestroyREAL4TimeSeries( chan ); xlalErrno = XLAL_SUCCESS; return; } else exit ( 1 ); } waveform = *wfm; LALInfo( status, ppnParams.termDescription ); if ( thisEvent->geocent_end_time.gpsSeconds ) { /* get the gps start time of the signal to inject */ waveformStartTime = XLALGPSToINT8NS( &(thisEvent->geocent_end_time) ); waveformStartTime -= (INT8) ( 1000000000.0 * ppnParams.tc ); } else { LALInfo( status, "Waveform start time is zero: injecting waveform " "into center of data segment" ); /* center the waveform in the data segment */ waveformStartTime = XLALGPSToINT8NS( &(chan->epoch) ); waveformStartTime += (INT8) ( 1000000000.0 * ((REAL8) (chan->data->length - ppnParams.length) / 2.0) * chan->deltaT ); } snprintf( warnMsg, sizeof(warnMsg)/sizeof(*warnMsg), "Injected waveform timing:\n" "thisEvent->geocent_end_time.gpsSeconds = %d\n" "thisEvent->geocent_end_time.gpsNanoSeconds = %d\n" "ppnParams.tc = %e\n" "waveformStartTime = %" LAL_INT8_FORMAT "\n", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, ppnParams.tc, waveformStartTime ); LALInfo( status, warnMsg ); /* clear the signal structure */ memset( &signalvec, 0, sizeof(REAL4TimeSeries) ); /* 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) ); /* set the start time of the signal vector to the start time of the chan */ signalvec.epoch = chan->epoch; /* set the parameters for the signal time series */ signalvec.deltaT = chan->deltaT; if ( ( signalvec.f0 = chan->f0 ) != 0 ) { ABORT( status, FINDCHIRPH_EHETR, FINDCHIRPH_MSGEHETR ); } signalvec.sampleUnits = lalADCCountUnit; /* simulate the detectors response to the inspiral */ LALSCreateVector( status->statusPtr, &(signalvec.data), chan->data->length ); CHECKSTATUSPTR( status ); LALSimulateCoherentGW( status->statusPtr, &signalvec, &waveform, &detector ); CHECKSTATUSPTR( status ); /* *****************************************************************************/ #if 0 FILE *fp; char fname[512]; UINT4 jj, kplus, kcross; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, thisEvent->waveform ); fp = fopen( fname, "w" ); for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length; ++jj, kplus += 2, kcross +=2 ) { fprintf(fp, "%d %e %e %le %e\n", jj, waveform.a->data->data[kplus], waveform.a->data->data[kcross], waveform.phi->data->data[jj], waveform.f->data->data[jj]); } fclose( fp ); #endif /* ********************************************************************************/ #if 0 FILE *fp; char fname[512]; UINT4 jj; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", thisEvent->geocent_end_time.gpsSeconds, thisEvent->geocent_end_time.gpsNanoSeconds, thisEvent->waveform ); fp = fopen( fname, "w" ); for( jj = 0; jj < signalvec.data->length; ++jj ) { fprintf(fp, "%d %e %e \n", jj, signalvec.data->data[jj]); } fclose( fp ); #endif /* ********************************************************************************/ /* inject the signal into the data channel */ LALSSInjectTimeSeries( status->statusPtr, chan, &signalvec ); CHECKSTATUSPTR( status ); /* allocate and go to next SimRingdownTable */ if( thisEvent->next ) thisRingdownEvent = thisRingdownEvent->next = (SimRingdownTable *) calloc( 1, sizeof(SimRingdownTable) ); else thisRingdownEvent->next = NULL; /* destroy the signal */ LALSDestroyVector( status->statusPtr, &(signalvec.data) ); CHECKSTATUSPTR( status ); LALSDestroyVectorSequence( status->statusPtr, &(waveform.a->data) ); CHECKSTATUSPTR( status ); LALSDestroyVector( status->statusPtr, &(waveform.f->data) ); CHECKSTATUSPTR( status ); LALDDestroyVector( status->statusPtr, &(waveform.phi->data) ); CHECKSTATUSPTR( status ); if ( waveform.shift ) { LALSDestroyVector( status->statusPtr, &(waveform.shift->data) ); CHECKSTATUSPTR( status ); } LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); if ( waveform.shift ) { LALFree( waveform.shift ); } } LALCDestroyVector( status->statusPtr, &( detector.transfer->data ) ); CHECKSTATUSPTR( status ); if ( detector.site ) LALFree( detector.site ); LALFree( detector.transfer ); DETATCHSTATUSPTR( status ); RETURN( status ); }
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; }
int main ( int argc, char *argv[] ) { const int size = 8; COMPLEX8Vector *z1 = NULL; COMPLEX8Vector *z2 = NULL; COMPLEX8Vector *z3 = NULL; REAL4Vector *x1 = NULL; REAL4Vector *x2 = NULL; REAL4Vector *x3 = NULL; REAL4Vector *y_1 = NULL; REAL4Vector *y2 = NULL; REAL4Vector *y3 = NULL; static LALStatus status; INT4 i; ParseOptions( argc, argv ); LALCCreateVector(&status, &z1, size); TestStatus( &status, CODES(0), 1 ); LALCCreateVector(&status, &z2, size); TestStatus( &status, CODES(0), 1 ); LALCCreateVector(&status, &z3, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x1, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x2, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x3, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &y_1, size/2); TestStatus( &status, CODES(0), 1 ); y2 = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector)); y2->data = NULL; y2->length = size; y3 = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector)); y3->data = (REAL4 *)LALMalloc(size*sizeof(REAL4)); y3->length = 0; for (i = 0; i < size; ++i) { z1->data[i] = 1 + i; z1->data[i] += I * (2 + i*i); z2->data[i] = 3 + i + i*i*i; z2->data[i] += I * (4 + i*i + i*i*i); x1->data[i] = 5 + i + i*i; x2->data[i] = 6 + i + i*i + i*i*i; } if (verbose) printf("\n"); LALCCVectorMultiply(&status, z3, z1, z2); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf("(% 6.0f,% 6.0f) x (% 6.0f,% 6.0f) = (% 6.0f,% 6.0f)\n", crealf(z1->data[i]), cimagf(z1->data[i]), crealf(z2->data[i]), cimagf(z2->data[i]), crealf(z3->data[i]), cimagf(z3->data[i])); if (verbose) printf("\n"); LALCCVectorMultiplyConjugate(&status, z3, z1, z2); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf("(% 6.0f,% 6.0f) x (% 6.0f,% 6.0f)* = (% 6.0f,% 6.0f)\n", crealf(z1->data[i]), cimagf(z1->data[i]), crealf(z2->data[i]), cimagf(z2->data[i]), crealf(z3->data[i]), cimagf(z3->data[i])); if (verbose) printf("\n"); LALCCVectorDivide(&status, z3, z1, z2); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf("(% 6.0f,% 6.0f) / (% 6.0f,% 6.0f) = (% 9.6f,% 9.6f)\n", crealf(z1->data[i]), cimagf(z1->data[i]), crealf(z2->data[i]), cimagf(z2->data[i]), crealf(z3->data[i]), cimagf(z3->data[i])); if (verbose) printf("\n"); LALSCVectorMultiply(&status, z3, x1, z1); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf("% 6.0f x (% 6.0f,% 6.0f) = (% 6.0f,% 6.0f)\n", crealf(x1->data[i]), crealf(z1->data[i]), cimagf(z1->data[i]), crealf(z3->data[i]), cimagf(z3->data[i])); if (verbose) printf("\n"); LALSSVectorMultiply(&status, x3, x1, x2); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf("% 6.0f x % 6.0f = % 6.0f\n", x1->data[i], x2->data[i], x3->data[i]); if (verbose) printf("\n"); #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { LALSSVectorMultiply(&status, x3, x1, NULL); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALSSVectorMultiply(&status, x3, y2, x2); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALSSVectorMultiply(&status, y3, x1, x2); TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 ); LALSSVectorMultiply(&status, x3, x1, y_1); TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 ); } #endif LALCDestroyVector(&status, &z1); TestStatus( &status, CODES(0), 1 ); LALCDestroyVector(&status, &z2); TestStatus( &status, CODES(0), 1 ); LALCDestroyVector(&status, &z3); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x1); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x2); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x3); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &y_1); TestStatus( &status, CODES(0), 1 ); LALFree(y2); LALFree(y3->data); LALFree(y3); x1 = x2 = x3 = y_1 = y2 = y3 = NULL; z1 = z2 = z3 = NULL; LALCCreateVector(&status, &z1, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x1, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x2, size); TestStatus( &status, CODES(0), 1 ); LALSCreateVector(&status, &x3, size); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) { z1->data[i] = (12.0 + i) *cos(LAL_PI/3.0*i); z1->data[i] += I * (12.0 + i )*sin(LAL_PI/3.0*i); } if (verbose) printf("\n"); LALCVectorAbs(&status, x1, z1); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf(" Abs(% f,%f) = %f \n", crealf(z1->data[i]), cimagf(z1->data[i]), x1->data[i]); LALCVectorAngle(&status, x2, z1); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf(" Angle(%f,%f) = %f \n", crealf(z1->data[i]), cimagf(z1->data[i]), x2->data[i]); LALUnwrapREAL4Angle(&status, x3, x2); TestStatus( &status, CODES(0), 1 ); for (i = 0; i < size; ++i) if (verbose) printf(" Unwrap Phase Angle ( %f ) = %f \n", x2->data[i], x3->data[i]); LALSCreateVector(&status, &y_1, size/2); TestStatus( &status, CODES(0), 1 ); y2 = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector)); y2->data = NULL; y2->length = size; y3 = (REAL4Vector *)LALMalloc(sizeof(REAL4Vector)); y3->data = (REAL4 *)LALMalloc(size*sizeof(REAL4)); y3->length = 0; if (verbose) printf("\n"); #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { LALCVectorAbs(&status, x1, NULL); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAbs(&status, NULL, z1); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAbs(&status, y_1, z1); TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 ); LALCVectorAbs(&status, y2, z1); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAbs(&status, y3, z1); TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 ); LALCVectorAngle(&status, x2, NULL); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAngle(&status, NULL, z1); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAngle(&status, y_1, z1); TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 ); LALCVectorAngle(&status, y2, z1); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALCVectorAngle(&status, y3, z1); TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 ); LALUnwrapREAL4Angle(&status, x3, NULL); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALUnwrapREAL4Angle(&status, NULL, x2); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALUnwrapREAL4Angle(&status, y_1, x2); TestStatus( &status, CODES(VECTOROPSH_ESZMM), 1 ); LALUnwrapREAL4Angle(&status, y2, x2); TestStatus( &status, CODES(VECTOROPSH_ENULL), 1 ); LALUnwrapREAL4Angle(&status, y3, x2); TestStatus( &status, CODES(VECTOROPSH_ESIZE), 1 ); LALUnwrapREAL4Angle(&status, x2, x2); TestStatus( &status, CODES(VECTOROPSH_ESAME), 1 ); } #endif LALCDestroyVector(&status, &z1); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x1); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x2); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &x3); TestStatus( &status, CODES(0), 1 ); LALSDestroyVector(&status, &y_1); TestStatus( &status, CODES(0), 1 ); LALFree(y2); LALFree(y3->data); LALFree(y3); LALCheckMemoryLeaks(); return 0; }
/** * \author Creighton, T. D. * * \brief Computes a continuous waveform with frequency drift and Doppler * modulation from a parabolic orbital trajectory. * * This function computes a quaiperiodic waveform using the spindown and * orbital parameters in <tt>*params</tt>, storing the result in * <tt>*output</tt>. * * In the <tt>*params</tt> structure, the routine uses all the "input" * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the * "output" fields. If <tt>params-\>f</tt>=\c NULL, no spindown * modulation is performed. If <tt>params-\>oneMinusEcc</tt>\f$\neq0\f$, or if * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$ * (faster-than-light speed at periapsis), an error is returned. * * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is * ignored, but all other pointer fields must be set to \c NULL. The * function will create and allocate space for <tt>output-\>a</tt>, * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary. The * <tt>output-\>shift</tt> field will remain set to \c NULL. * * ### Algorithm ### * * For parabolic orbits, we combine \eqref{eq_spinorbit-tr}, * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$ * directly as a function of \f$E\f$: * \f{equation}{ * \label{eq_cubic-e} * t_r = t_p + \frac{r_p\sin i}{c} \left[ \cos\omega + * \left(\frac{1}{v_p} + \cos\omega\right)E - * \frac{\sin\omega}{4}E^2 + \frac{1}{12v_p}E^3\right] \;, * \f} * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at * periapsis. Following the prescription for the general analytic * solution to the real cubic equation, we substitute * \f$E=x+3v_p\sin\omega\f$ to obtain: * \f{equation}{ * \label{eq_cubic-x} * x^3 + px = q \;, * \f} * where: * \f{eqnarray}{ * \label{eq_cubic-p} * p & = & 12 + 12v_p\cos\omega - 3v_p^2\sin^2\omega \;, \\ * \label{eq_cubic-q} * q & = & 12v_p^2\sin\omega\cos\omega - 24v_p\sin\omega + * 2v_p^3\sin^3\omega + 12\dot{\upsilon}_p(t_r-t_p) \;. * \f} * We note that \f$p>0\f$ is guaranteed as long as \f$v_p<1\f$, so the right-hand * side of \eqref{eq_cubic-x} is monotonic in \f$x\f$ and has exactly one * root. However, \f$p\rightarrow0\f$ in the limit \f$v_p\rightarrow1\f$ and * \f$\omega=\pi\f$. This may cause some loss of precision in subsequent * calculations. But \f$v_p\sim1\f$ means that our solution will be * inaccurate anyway because we ignore significant relativistic effects. * * Since \f$p>0\f$, we can substitute \f$x=y\sqrt{3/4p}\f$ to obtain: * \f{equation}{ * 4y^3 + 3y = \frac{q}{2}\left(\frac{3}{p}\right)^{3/2} \equiv C \;. * \f} * Using the triple-angle hyperbolic identity * \f$\sinh(3\theta)=4\sinh^3\theta+3\sinh\theta\f$, we have * \f$y=\sinh\left(\frac{1}{3}\sinh^{-1}C\right)\f$. The solution to the * original cubic equation is then: * \f{equation}{ * E = 3v_p\sin\omega + 2\sqrt{\frac{p}{3}} * \sinh\left(\frac{1}{3}\sinh^{-1}C\right) \;. * \f} * To ease the calculation of \f$E\f$, we precompute the constant part * \f$E_0=3v_p\sin\omega\f$ and the coefficient \f$\Delta E=2\sqrt{p/3}\f$. * Similarly for \f$C\f$, we precompute a constant piece \f$C_0\f$ evaluated at * the epoch of the output time series, and a stepsize coefficient * \f$\Delta C=6(p/3)^{3/2}\dot{\upsilon}_p\Delta t\f$, where \f$\Delta t\f$ is * the step size in the (output) time series in \f$t_r\f$. Thus at any * timestep \f$i\f$, we obtain \f$C\f$ and hence \f$E\f$ via: * \f{eqnarray}{ * C & = & C_0 + i\Delta C \;,\\ * E & = & E_0 + \Delta E\times\left\{\begin{array}{l@{\qquad}c} * \sinh\left[\frac{1}{3}\ln\left( * C + \sqrt{C^2+1} \right) \right]\;, & C\geq0 \;,\\ \\ * \sinh\left[-\frac{1}{3}\ln\left( * -C + \sqrt{C^2+1} \right) \right]\;, & C\leq0 \;,\\ * \end{array}\right. * \f} * where we have explicitly written \f$\sinh^{-1}\f$ in terms of functions in * \c math.h. Once \f$E\f$ is found, we can compute * \f$t=E(12+E^2)/(12\dot{\upsilon}_p)\f$ (where again \f$1/12\dot{\upsilon}_p\f$ * can be precomputed), and hence \f$f\f$ and \f$\phi\f$ via * \eqref{eq_taylorcw-freq} and \eqref{eq_taylorcw-phi}. The * frequency \f$f\f$ must then be divided by the Doppler factor: * \f[ * 1 + \frac{\dot{R}}{c} = 1 + \frac{v_p}{4+E^2}\left( * 4\cos\omega - 2E\sin\omega \right) * \f] * (where once again \f$4\cos\omega\f$ and \f$2\sin\omega\f$ can be precomputed). * * This routine does not account for relativistic timing variations, and * issues warnings or errors based on the criterea of * \eqref{eq_relativistic-orbit} in GenerateEllipticSpinOrbitCW(). * The routine will also warn if * it seems likely that \c REAL8 precision may not be sufficient to * track the orbit accurately. We estimate that numerical errors could * cause the number of computed wave cycles to vary by * \f[ * \Delta N \lesssim f_0 T\epsilon\left[ * \sim6+\ln\left(|C|+\sqrt{|C|^2+1}\right)\right] \;, * \f] * where \f$|C|\f$ is the maximum magnitude of the variable \f$C\f$ over the * course of the computation, \f$f_0T\f$ is the approximate total number of * wave cycles over the computation, and \f$\epsilon\approx2\times10^{-16}\f$ * is the fractional precision of \c REAL8 arithmetic. If this * estimate exceeds 0.01 cycles, a warning is issued. */ void LALGenerateParabolicSpinOrbitCW( LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params ) { UINT4 n, i; /* number of and index over samples */ UINT4 nSpin = 0, j; /* number of and index over spindown terms */ REAL8 t, dt, tPow; /* time, interval, and t raised to a power */ REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */ REAL8 f, fPrev; /* current and previous values of frequency */ REAL4 df = 0.0; /* maximum difference between f and fPrev */ REAL8 phi; /* current value of phase */ REAL8 vp; /* projected speed at periapsis */ REAL8 argument; /* argument of periapsis */ REAL8 fourCosOmega; /* four times the cosine of argument */ REAL8 twoSinOmega; /* two times the sine of argument */ REAL8 vpCosOmega; /* vp times cosine of argument */ REAL8 vpSinOmega; /* vp times sine of argument */ REAL8 vpSinOmega2; /* vpSinOmega squared */ REAL8 vDot6; /* 6 times angular speed at periapsis */ REAL8 oneBy12vDot; /* one over (12 times angular speed) */ REAL8 pBy3; /* constant sqrt(p/3) in cubic equation */ REAL8 p32; /* constant (p/3)^1.5 in cubic equation */ REAL8 c, c0, dc; /* C variable, offset, and step increment */ REAL8 e, e2, e0; /* E variable, E^2, and constant piece of E */ REAL8 de; /* coefficient of sinh() piece of E */ REAL8 tpOff; /* orbit epoch - time series epoch (s) */ REAL8 spinOff; /* spin epoch - orbit epoch (s) */ REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); ASSERT( output, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); /* If Taylor coeficients are specified, make sure they exist. */ if ( params->f ) { ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); nSpin = params->f->length; fSpin = params->f->data; } /* Set up some constants (to avoid repeated calculation or dereferencing), and make sure they have acceptable values. */ vp = params->rPeriNorm*params->angularSpeed; vDot6 = 6.0*params->angularSpeed; n = params->length; dt = params->deltaT; f0 = fPrev = params->f0; if ( params->oneMinusEcc != 0.0 ) { ABORT( stat, GENERATESPINORBITCWH_EECC, GENERATESPINORBITCWH_MSGEECC ); } if ( vp >= 1.0 ) { ABORT( stat, GENERATESPINORBITCWH_EFTL, GENERATESPINORBITCWH_MSGEFTL ); } if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDot6 <= 0.0 || n == 0 ) { ABORT( stat, GENERATESPINORBITCWH_ESGN, GENERATESPINORBITCWH_MSGESGN ); } #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { if ( f0*n*dt*vp*vp > 0.5 ) LALWarning( stat, "Orbit may have significant relativistic" " effects that are not included" ); } #endif /* Compute offset between time series epoch and periapsis, and betweem periapsis and spindown reference epoch. */ tpOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->epoch.gpsSeconds ); tpOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->epoch.gpsNanoSeconds ); spinOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->spinEpoch.gpsSeconds ); spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->spinEpoch.gpsNanoSeconds ); /* Set up some other constants. */ twopif0 = f0*LAL_TWOPI; phi0 = params->phi0; argument = params->omega; oneBy12vDot = 0.5/vDot6; fourCosOmega = 4.0*cos( argument ); twoSinOmega = 2.0*sin( argument ); vpCosOmega = 0.25*vp*fourCosOmega; vpSinOmega = 0.5*vp*twoSinOmega; vpSinOmega2 = vpSinOmega*vpSinOmega; pBy3 = sqrt( 4.0*( 1.0 + vpCosOmega ) - vpSinOmega2 ); p32 = 1.0/( pBy3*pBy3*pBy3 ); c0 = p32*( vpSinOmega*( 6.0*vpCosOmega - 12.0 + vpSinOmega2 ) - tpOff*vDot6 ); dc = p32*vDot6*dt; e0 = 3.0*vpSinOmega; de = 2.0*pBy3; /* Check whether REAL8 precision is good enough. */ #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { REAL8 x = fabs( c0 + n*dc ); /* a temporary computation variable */ if ( x < fabs( c0 ) ) x = fabs( c0 ); x = 6.0 + log( x + sqrt( x*x + 1.0 ) ); if ( LAL_REAL8_EPS*f0*dt*n*x > 0.01 ) LALWarning( stat, "REAL8 arithmetic may not have sufficient" " precision for this orbit" ); } #endif /* Allocate output structures. */ if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position = params->position; output->psi = params->psi; output->a->epoch = output->f->epoch = output->phi->epoch = params->epoch; output->a->deltaT = n*params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "CW amplitudes" ); snprintf( output->f->name, LALNameLength, "CW frequency" ); snprintf( output->phi->name, LALNameLength, "CW phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), n ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), n ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate and fill amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = 2; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); output->a->data->data[0] = output->a->data->data[2] = params->aPlus; output->a->data->data[1] = output->a->data->data[3] = params->aCross; } /* Fill frequency and phase arrays. */ fData = output->f->data->data; phiData = output->phi->data->data; for ( i = 0; i < n; i++ ) { /* Compute emission time. */ c = c0 + dc*i; if ( c > 0 ) e = e0 + de*sinh( log( c + sqrt( c*c + 1.0 ) )/3.0 ); else e = e0 + de*sinh( -log( -c + sqrt( c*c + 1.0 ) )/3.0 ); e2 = e*e; phi = t = tPow = oneBy12vDot*e*( 12.0 + e2 ); /* Compute source emission phase and frequency. */ f = 1.0; for ( j = 0; j < nSpin; j++ ) { f += fSpin[j]*tPow; phi += fSpin[j]*( tPow*=t )/( j + 2.0 ); } /* Appy frequency Doppler shift. */ f *= f0 / ( 1.0 + vp*( fourCosOmega - e*twoSinOmega ) /( 4.0 + e2 ) ); phi *= twopif0; if ( fabs( f - fPrev ) > df ) df = fabs( f - fPrev ); *(fData++) = fPrev = f; *(phiData++) = phi + phi0; } /* Set output field and return. */ params->dfdt = df*dt; DETATCHSTATUSPTR( stat ); RETURN( stat ); }
int main(int argc, char **argv) { static LALStatus stat; /* LALStatus pointer */ CHAR *infile = NULL; /* The input filename */ CHAR *outfile = NULL; /* The output filename */ INT4 arg; /* Argument counter */ UINT4 npts = NPTS; /* Number of points in time series */ UINT4 offset = OFFSET; /* Position of delta function */ REAL8 dt = DT; /* Sampling interval. */ static REAL4TimeSeries series; /* Time series */ static PassBandParamStruc params; /* Filter parameters */ XLALSetErrorHandler( XLALAbortErrorHandler ); /* Set up the default filter parameters. */ params.f1 = F1; params.f2 = F2; params.a1 = A1; params.a2 = A2; params.nMax = ORDER; /* Parse argument list. i stores the current position. */ arg = 1; while ( arg < argc ) { /* Parse debuglevel option. */ if ( !strcmp( argv[arg], "-d" ) ) { if ( argc > arg + 1 ) { arg++; } else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* Parse input file option. */ else if ( !strcmp( argv[arg], "-i" ) ) { if ( argc > arg + 1 ) { arg++; infile = argv[arg++]; } else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* Parse output file option. */ else if ( !strcmp( argv[arg], "-o" ) ) { if ( argc > arg + 1 ) { arg++; outfile = argv[arg++]; } else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* Parse filter options. */ else if ( !strcmp( argv[arg], "-f" ) ) { if ( argc > arg + 5 ) { arg++; params.f1=atof(argv[arg++]); params.f2=atof(argv[arg++]); params.a1=atof(argv[arg++]); params.a2=atof(argv[arg++]); params.nMax=atoi(argv[arg++]); } else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* Parse time series options. */ else if ( !strcmp( argv[arg], "-n" ) ) { if ( argc > arg + 3 ) { arg++; npts=atoi(argv[arg++]); dt=atof(argv[arg++]); offset=atoi(argv[arg++]); } else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* Unrecognized option. */ else { ERROR( BANDPASSTESTC_EARG, BANDPASSTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BANDPASSTESTC_EARG; } } /* End of argument parsing loop. */ /* Check input values. */ if ( !infile ) { if ( offset >= npts ) { ERROR( BANDPASSTESTC_EBAD, BANDPASSTESTC_MSGEBAD, 0 ); LALPrintError( "\toffset=%i must be less than npts=%i\n", offset, npts ); return BANDPASSTESTC_EBAD; } } /* Create the time series. */ if ( infile ) { FILE *fp = fopen( infile, "r" ); if ( !fp ) { ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, infile ); return BANDPASSTESTC_EFILE; } SUB( LALSReadTSeries( &stat, &series, fp ), &stat ); fclose( fp ); } else { snprintf( series.name, LALNameLength, "%s", "Impulse" ); series.deltaT = dt; SUB( LALSCreateVector( &stat, &(series.data), npts ), &stat ); memset( series.data->data, 0, npts*sizeof(REAL4) ); series.data->data[offset] = 1.0; } /* Filter the time series. */ SUB( LALDButterworthREAL4TimeSeries( &stat, &series, ¶ms ), &stat ); /* Print the output, if the -o option was given. */ if ( outfile ) { FILE *fp = fopen( outfile, "w" ); if ( !fp ){ ERROR( BANDPASSTESTC_EFILE, BANDPASSTESTC_MSGEFILE, outfile ); return BANDPASSTESTC_EFILE; } SUB( LALSWriteTSeries( &stat, fp, &series ), &stat ); fclose( fp ); } /* Free memory and exit. */ SUB( LALSDestroyVector( &stat, &(series.data) ), &stat ); LALCheckMemoryLeaks(); INFO( BANDPASSTESTC_MSGENORM ); return BANDPASSTESTC_ENORM; }
void LALGenerateRing( LALStatus *stat, CoherentGW *output, REAL4TimeSeries UNUSED *series, SimRingdownTable *simRingdown, RingParamStruc *params ) { UINT4 i; /* number of and index over samples */ REAL8 t, dt; /* time, interval */ REAL8 gtime ; /* central time, decay time */ REAL8 f0, quality; /* frequency and quality factor */ REAL8 twopif0; /* 2*pi*f0 */ REAL4 h0; /* peak strain for ringdown */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ REAL8 init_phase; /*initial phase of injection */ REAL4 *aData; /* pointer to frequency data */ UINT4 nPointInj; /* number of data points in a block */ #if 0 UINT4 n; REAL8 t0; REAL4TimeSeries signalvec; /* start time of block that injection is injected into */ LALTimeInterval interval; INT8 geoc_tns; /* geocentric_start_time of the injection in ns */ INT8 block_tns; /* start time of block in ns */ REAL8 deltaTns; INT8 inj_diff; /* time between start of segment and injection */ LALTimeInterval dummyInterval; #endif INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATERINGH_ENUL, GENERATERINGH_MSGENUL ); ASSERT( output, stat, GENERATERINGH_ENUL, GENERATERINGH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATERINGH_EOUT, GENERATERINGH_MSGEOUT ); /* Set up some other constants, to avoid repeated dereferencing. */ dt = params->deltaT; /* N_point = 2 * floor(0.5+ 1/ dt); */ nPointInj = 163840; /* Generic ring parameters */ h0 = simRingdown->amplitude; quality = (REAL8)simRingdown->quality; f0 = (REAL8)simRingdown->frequency; twopif0 = f0*LAL_TWOPI; init_phase = simRingdown->phase; if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position.longitude = simRingdown->longitude; output->position.latitude = simRingdown->latitude; output->position.system = params->system; output->psi = simRingdown->polarization; /* set epoch of output time series to that of the block */ output->a->epoch = output->f->epoch = output->phi->epoch = simRingdown->geocent_start_time; output->a->deltaT = params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "Ring amplitudes" ); snprintf( output->f->name, LALNameLength, "Ring frequency" ); snprintf( output->phi->name, LALNameLength, "Ring phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), nPointInj ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), nPointInj ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = nPointInj; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); } /* set arrays to zero */ memset( output->f->data->data, 0, sizeof( REAL4 ) * output->f->data->length ); memset( output->phi->data->data, 0, sizeof( REAL8 ) * output->phi->data->length ); memset( output->a->data->data, 0, sizeof( REAL4 ) * output->a->data->length * output->a->data->vectorLength ); /* Fill frequency and phase arrays starting at time of injection NOT start */ fData = output->f->data->data; phiData = output->phi->data->data; aData = output->a->data->data; if ( !( strcmp( simRingdown->waveform, "Ringdown" ) ) ) { for ( i = 0; i < nPointInj; i++ ) { t = i * dt; gtime = twopif0 / 2 / quality * t ; *(fData++) = f0; *(phiData++) = twopif0 * t+init_phase; *(aData++) = h0 * ( 1.0 + pow( cos( simRingdown->inclination ), 2 ) ) * exp( - gtime ); *(aData++) = h0* 2.0 * cos( simRingdown->inclination ) * exp( - gtime ); } } else { ABORT( stat, GENERATERINGH_ETYP, GENERATERINGH_MSGETYP ); } /* Set output field and return. */ DETATCHSTATUSPTR( stat ); RETURN( stat ); }
void LALFitToPulsarStudentT ( LALStatus *status, CoarseFitOutput *output, FitInputStudentT *input, CoarseFitParams *params ) { /******* DECLARE VARIABLES ************/ UINT4 n,i,j,k; REAL8 psi; REAL8 h0; REAL8 cosIota; REAL8 phase; REAL8 chiSquare; LALDetector detector; LALSource pulsar; LALDetAndSource detAndSource; LALDetAMResponse computedResponse; REAL4Vector *Fp, *Fc; /* pointers to amplitude responses of the detector */ REAL8 cos2phase,sin2phase; COMPLEX16 Xp, Xc; REAL8 Y, cosIota2; COMPLEX16 A,B; REAL8 sumAA, sumBB, sumAB; REAL8 h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0; REAL8 minChiSquare; UINT4 iH0, iCosIota, iPhase, iPsi, arg; LALGPSandAcc pGPSandAcc; INT4Vector *kVec=NULL; UINT4 count=0; REAL8 meanSegLength=0.0; INITSTATUS(status); ATTATCHSTATUSPTR(status); /******* CHECK VALIDITY OF ARGUMENTS ************/ ASSERT(params != (CoarseFitParams *)NULL, status, FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); ASSERT(input != (FitInputStudentT *)NULL, status, FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); /******* EXTRACT INPUTS AND PARAMETERS ************/ n = input->B->length; detector = params->detector; detAndSource.pDetector = &detector; pulsar = params->pulsarSrc; /******* ALLOCATE MEMORY TO VECTORS **************/ Fp = NULL; LALSCreateVector(status->statusPtr, &Fp, n); Fp->length = n; Fc = NULL; LALSCreateVector(status->statusPtr, &Fc, n); Fc->length = n; /******* INITIALIZE VARIABLES *******************/ for (i=0;i<params->meshH0[2]*params->meshCosIota[2]*params->meshPhase[2]*params->meshPsi[2];i++) output->mChiSquare->data[i] = 0.0; /* create kVec of chunk lengths within lock stretches */ LALI4CreateVector(status->statusPtr, &kVec, n); j=i=0; while(1){ count++; if((input->t[i+1].gpsSeconds - input->t[i].gpsSeconds)>180.0 || count==input->N){ kVec->data[j] = count; count = 0; /* check if last segment is found this loop */ if(i+1 > n-1) break; j++; } i++; /* break clause */ if(i>n-1){ /* set final value of kVec */ kVec->data[j] = count; break; } } kVec->length = j+1; for(i=0;i<kVec->length;i++){ meanSegLength += kVec->data[i]; } fprintf(stderr, "Mean segment length = %f.\n", meanSegLength/(double)kVec->length); j=i=count=0; minChiSquare = INICHISQU; /******* DO ANALYSIS ************/ for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++) { fprintf(stderr,"%d out of %f iPsi\n", iPsi+1, params->meshPsi[2]); fflush(stderr); psi = params->meshPsi[0] + (REAL8)iPsi*params->meshPsi[1]; pulsar.orientation = psi; detAndSource.pSource = &pulsar; /* create vectors containing amplitude response of detector for specified times */ for (i=0;i<n;i++){ pGPSandAcc.gps.gpsNanoSeconds = input->t[i].gpsNanoSeconds; pGPSandAcc.gps.gpsSeconds = input->t[i].gpsSeconds; pGPSandAcc.accuracy = 1.0; LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &pGPSandAcc); Fp->data[i] = (REAL8)computedResponse.plus; Fc->data[i] = (REAL8)computedResponse.cross; } for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++){ phase = params->meshPhase[0] + (REAL8)iPhase*params->meshPhase[1]; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++){ INT4 tempLength; cosIota = params->meshCosIota[0] + (REAL8)iCosIota*params->meshCosIota[1]; cosIota2 = 1.0 + cosIota*cosIota; Xp.re = 0.25*cosIota2 * cos2phase; Xp.im = 0.25*cosIota2 * sin2phase; Y = 0.5*cosIota; Xc.re = Y*sin2phase; Xc.im = -Y*cos2phase; sumAB = 0.0; sumAA = 0.0; sumBB = 0.0; /*k = input->N;*/ count=0; for (i = 0; i < n-kVec->data[kVec->length-1]; i+=tempLength){ tempLength = kVec->data[count]; /* don't include data segments under 5 mins long */ if(kVec->data[count] < 5){ count++; continue; } sumBB = 0.0; sumAA = 0.0; sumAB = 0.0; for (j=i;j<i+kVec->data[count];j++){ B.re = input->B->data[j].re; B.im = input->B->data[j].im; A.re = Fp->data[j]*Xp.re + Fc->data[j]*Xc.re; A.im = Fp->data[j]*Xp.im + Fc->data[j]*Xc.im; sumBB += B.re*B.re + B.im*B.im; sumAA += A.re*A.re + A.im*A.im; sumAB += B.re*A.re + B.im*A.im; } for (iH0 = 0; iH0 < params->meshH0[2]; iH0++){ h0 = params->meshH0[0] + (float)iH0*params->meshH0[1]; chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA; arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); output->mChiSquare->data[arg] += 2.0*((REAL8)kVec->data[count])*log(chiSquare); } /* iH0 */ count++; } /* n*/ /* find best fit */ for (iH0 = 0; iH0 < params->meshH0[2]; iH0++){ arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); if ((output->mChiSquare->data[arg])<minChiSquare){ minChiSquare = output->mChiSquare->data[arg]; h0 = params->meshH0[0] + (float)iH0*params->meshH0[1]; h0BestFit = h0; cosIotaBestFit = cosIota; psiBestFit = psi; phaseBestFit = phase; } } /* end find best fit */ } /* iCosIota */ } /* iPhase */ } /* iPsi */ /******* CONSTRUCT OUTPUT ************/ output->h0 = h0BestFit; output->cosIota = cosIotaBestFit; output->phase = phaseBestFit; output->psi = psiBestFit; output->chiSquare = minChiSquare; ASSERT(minChiSquare < INICHISQU, status, FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); LALI4DestroyVector(status->statusPtr, &kVec); LALSDestroyVector(status->statusPtr, &Fp); LALSDestroyVector(status->statusPtr, &Fc); DETATCHSTATUSPTR(status); RETURN(status); }
/* 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; }
/** * Computes REAL4TimeSeries containing time series of response amplitudes. * \deprecated Use XLALComputeDetAMResponseSeries() instead. */ void LALComputeDetAMResponseSeries(LALStatus * status, LALDetAMResponseSeries * pResponseSeries, const LALDetAndSource * pDetAndSource, const LALTimeIntervalAndNSample * pTimeInfo) { /* Want to loop over the time and call LALComputeDetAMResponse() */ LALDetAMResponse instResponse; unsigned i; INITSTATUS(status); ATTATCHSTATUSPTR(status); /* * Error-checking assertions */ ASSERT(pResponseSeries != (LALDetAMResponseSeries *) NULL, status, DETRESPONSEH_ENULLOUTPUT, DETRESPONSEH_MSGENULLOUTPUT); ASSERT(pDetAndSource != (LALDetAndSource *) NULL, status, DETRESPONSEH_ENULLINPUT, DETRESPONSEH_MSGENULLINPUT); ASSERT(pTimeInfo != (LALTimeIntervalAndNSample *) NULL, status, DETRESPONSEH_ENULLINPUT, DETRESPONSEH_MSGENULLINPUT); /* * Set names */ pResponseSeries->pPlus->name[0] = '\0'; pResponseSeries->pCross->name[0] = '\0'; pResponseSeries->pScalar->name[0] = '\0'; strncpy(pResponseSeries->pPlus->name, "plus", LALNameLength); strncpy(pResponseSeries->pCross->name, "cross", LALNameLength); strncpy(pResponseSeries->pScalar->name, "scalar", LALNameLength); /* * Set sampling parameters */ pResponseSeries->pPlus->epoch = pTimeInfo->epoch; pResponseSeries->pPlus->deltaT = pTimeInfo->deltaT; pResponseSeries->pPlus->f0 = 0.; pResponseSeries->pPlus->sampleUnits = lalDimensionlessUnit; pResponseSeries->pCross->epoch = pTimeInfo->epoch; pResponseSeries->pCross->deltaT = pTimeInfo->deltaT; pResponseSeries->pCross->f0 = 0.; pResponseSeries->pCross->sampleUnits = lalDimensionlessUnit; pResponseSeries->pScalar->epoch = pTimeInfo->epoch; pResponseSeries->pScalar->deltaT = pTimeInfo->deltaT; pResponseSeries->pScalar->f0 = 0.; pResponseSeries->pScalar->sampleUnits = lalDimensionlessUnit; /* * Ensure enough memory for requested vectors */ if(pResponseSeries->pPlus->data->length < pTimeInfo->nSample) { if(lalDebugLevel >= 8) LALInfo(status, "plus sequence too short -- reallocating"); TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pPlus->data)), status); TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pPlus->data), pTimeInfo->nSample), status); if(lalDebugLevel > 0) printf("pResponseSeries->pPlus->data->length = %d\n", pResponseSeries->pPlus->data->length); } if(pResponseSeries->pCross->data->length < pTimeInfo->nSample) { if(lalDebugLevel >= 8) LALInfo(status, "cross sequence too short -- reallocating"); TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pCross->data)), status); TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pCross->data), pTimeInfo->nSample), status); } if(pResponseSeries->pScalar->data->length < pTimeInfo->nSample) { if(lalDebugLevel & 0x08) LALInfo(status, "scalar sequence too short -- reallocating"); TRY(LALSDestroyVector(status->statusPtr, &(pResponseSeries->pScalar->data)), status); TRY(LALSCreateVector(status->statusPtr, &(pResponseSeries->pScalar->data), pTimeInfo->nSample), status); } /* * Loop to compute each element in time series. */ for(i = 0; i < pTimeInfo->nSample; ++i) { LIGOTimeGPS gps = pTimeInfo->epoch; XLALGPSAdd(&gps, i * pTimeInfo->deltaT); TRY(LALComputeDetAMResponse(status->statusPtr, &instResponse, pDetAndSource, &gps), status); pResponseSeries->pPlus->data->data[i] = instResponse.plus; pResponseSeries->pCross->data->data[i] = instResponse.cross; pResponseSeries->pScalar->data->data[i] = instResponse.scalar; } DETATCHSTATUSPTR(status); RETURN(status); }
int main(void) { static LALStatus status; LALDetector detector; LALSource pulsar; CoarseFitOutput output; CoarseFitInput input; CoarseFitParams params; LIGOTimeGPS tgps[FITTOPULSARTEST_LENGTH]; REAL4 cosIota; REAL4 phase; REAL4 psi; REAL4 h0; REAL4 cos2phase, sin2phase; static RandomParams *randomParams; static REAL4Vector *noise; INT4 seed = 0; LALDetAndSource detAndSource; LALDetAMResponseSeries pResponseSeries = {NULL,NULL,NULL}; REAL4TimeSeries Fp, Fc, Fs; LALTimeIntervalAndNSample time_info; UINT4 i; /* Allocate memory */ input.B = NULL; input.var = NULL; LALZCreateVector( &status, &input.B, FITTOPULSARTEST_LENGTH); LALZCreateVector( &status, &input.var, FITTOPULSARTEST_LENGTH); noise = NULL; LALCreateVector( &status, &noise, FITTOPULSARTEST_LENGTH); LALCreateRandomParams( &status, &randomParams, seed); Fp.data = NULL; Fc.data = NULL; Fs.data = NULL; pResponseSeries.pPlus = &(Fp); pResponseSeries.pCross = &(Fc); pResponseSeries.pScalar = &(Fs); LALSCreateVector(&status, &(pResponseSeries.pPlus->data), 1); LALSCreateVector(&status, &(pResponseSeries.pCross->data), 1); LALSCreateVector(&status, &(pResponseSeries.pScalar->data), 1); input.t = tgps; /******** GENERATE FAKE INPUT **********/ time_info.epoch.gpsSeconds = FITTOPULSARTEST_T0; time_info.epoch.gpsNanoSeconds = 0; time_info.deltaT = 60; time_info.nSample = FITTOPULSARTEST_LENGTH; cosIota = 0.5; psi = 0.1; phase = 0.4; h0 = 5.0; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); detector = lalCachedDetectors[LALDetectorIndexGEO600DIFF]; /* use GEO 600 detector for tests */ pulsar.equatorialCoords.longitude = 1.4653; /* right ascention of pulsar */ pulsar.equatorialCoords.latitude = -1.2095; /* declination of pulsar */ pulsar.equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; /* coordinate system */ pulsar.orientation = psi; /* polarization angle */ strcpy(pulsar.name, "fakepulsar"); /* name of pulsar */ detAndSource.pDetector = &detector; detAndSource.pSource = &pulsar; LALNormalDeviates( &status, noise, randomParams ); LALComputeDetAMResponseSeries(&status, &pResponseSeries, &detAndSource, &time_info); for (i = 0;i < FITTOPULSARTEST_LENGTH; i++) { input.t[i].gpsSeconds = FITTOPULSARTEST_T0 + 60*i; input.t[i].gpsNanoSeconds = 0; input.B->data[i] = crect( pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*cos2phase + 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*sin2phase, pResponseSeries.pPlus->data->data[i]*h0*(1.0 + cosIota*cosIota)*sin2phase - 2.0*pResponseSeries.pCross->data->data[i]*h0*cosIota*cos2phase ); input.var->data[i] = crect( noise->data[FITTOPULSARTEST_LENGTH-i-1]*noise->data[FITTOPULSARTEST_LENGTH-i-1], noise->data[i]*noise->data[i] ); } input.B->length = FITTOPULSARTEST_LENGTH; input.var->length = FITTOPULSARTEST_LENGTH; /******* TEST RESPONSE TO VALID DATA ************/ /* Test that valid data generate the correct answers */ params.detector = detector; params.pulsarSrc = pulsar; params.meshH0[0] = 4.0; params.meshH0[1] = 0.2; params.meshH0[2] = 10; params.meshCosIota[0] = 0.0; params.meshCosIota[1] = 0.1; params.meshCosIota[2] = 10; params.meshPhase[0] = 0.0; params.meshPhase[1] = 0.1; params.meshPhase[2] = 10; params.meshPsi[0] = 0.0; params.meshPsi[1] = 0.1; params.meshPsi[2] = 10; output.mChiSquare = NULL; LALDCreateVector( &status, &output.mChiSquare,params.meshH0[2]*params.meshCosIota[2]*params.meshPhase[2]*params.meshPsi[2]); LALCoarseFitToPulsar(&status,&output, &input, ¶ms); if(status.statusCode) { printf("Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription); return FITTOPULSARTESTC_EFLS; } if(output.phase > phase + params.meshPhase[2] || output.phase < phase - params.meshPhase[2]) { printf("Got incorrect phase %f when expecting %f \n", output.phase, phase); return FITTOPULSARTESTC_EFLS; } if(output.cosIota > cosIota + params.meshCosIota[2] || output.cosIota < cosIota - params.meshCosIota[2]) { printf("Got incorrect cosIota %f when expecting %f \n", output.cosIota, cosIota); return FITTOPULSARTESTC_EFLS; } if(output.psi > psi + params.meshPsi[2] || output.psi < psi - params.meshPsi[2]) { printf("Got incorrect psi %f when expecting %f \n", output.psi, psi); return FITTOPULSARTESTC_EFLS; } /******* TEST RESPONSE OF LALCoarseFitToPulsar TO INVALID DATA ************/ #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* Test that all the error conditions are correctly detected by the function */ LALCoarseFitToPulsar(&status, NULL, &input, ¶ms); if (status.statusCode != FITTOPULSARH_ENULLOUTPUT || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLOUTPUT)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); return FITTOPULSARTESTC_ECHK; } LALCoarseFitToPulsar(&status, &output, NULL, ¶ms); if (status.statusCode != FITTOPULSARH_ENULLINPUT || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLINPUT)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); return FITTOPULSARTESTC_ECHK; } LALCoarseFitToPulsar(&status, &output, &input, NULL); if (status.statusCode != FITTOPULSARH_ENULLPARAMS || strcmp(status.statusDescription, FITTOPULSARH_MSGENULLPARAMS)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); return FITTOPULSARTESTC_ECHK; } /* try having two input vectors of different length */ input.var->length = 1; LALCoarseFitToPulsar(&status, &output, &input, ¶ms); if (status.statusCode != FITTOPULSARH_EVECSIZE || strcmp(status.statusDescription, FITTOPULSARH_MSGEVECSIZE)) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription); printf( "Expected error code %d and message %s\n", FITTOPULSARH_EVECSIZE, FITTOPULSARH_MSGEVECSIZE); return FITTOPULSARTESTC_ECHK; } input.var->length = FITTOPULSARTEST_LENGTH; } /* if ( ! lalNoDebug ) */ #endif /* LAL_NDEBUG */ /******* CLEAN UP ************/ LALZDestroyVector(&status, &input.B); LALZDestroyVector(&status, &input.var); LALDestroyVector(&status, &noise); LALDDestroyVector(&status, &output.mChiSquare); LALDestroyRandomParams(&status, &randomParams); LALSDestroyVector(&status, &(pResponseSeries.pPlus->data)); LALSDestroyVector(&status, &(pResponseSeries.pCross->data)); LALSDestroyVector(&status, &(pResponseSeries.pScalar->data)); LALCheckMemoryLeaks(); return FITTOPULSARTESTC_ENOM; }
int main( void ) { /* Declare inputs of LAL function */ static LALStatus status; REAL4Vector *output; FoldAmplitudesInput input; FoldAmplitudesInput badinput; FoldAmplitudesParams param; /* Declare other variables */ REAL4 f = FOLDAMPLITUDESTESTC_FREQ; /* A frequency for producing test amplitudes */ REAL4 fDot = FOLDAMPLITUDESTESTC_FREQDOT; /* A frequency for producing test phases */ REAL4 delT = FOLDAMPLITUDESTESTC_TIMESTEP; /* A time step for producing test data */ REAL4 twoPi = (REAL4) LAL_TWOPI; /* For phase bins between 0 an 2*pi */ REAL4 binRange; /* binMax - binMin */ INT4 lengthAmpVec = FOLDAMPLITUDESTESTC_LENGTH; /* length of the vector of amplitudes */ INT4 i; /* generic integer index */ INT4 j; /* generic integer index */ INT4 k; /* generic integer index */ INT2 gotError = 0; /* Set nonzero if error condition occurs */ /* Allocate memory */ input.phaseVec = NULL; input.amplitudeVec = NULL; badinput.phaseVec = NULL; badinput.amplitudeVec = NULL; output = NULL; LALSCreateVector( &status, &input.phaseVec, FOLDAMPLITUDESTESTC_LENGTH ); LALSCreateVector( &status, &input.amplitudeVec, FOLDAMPLITUDESTESTC_LENGTH ); LALSCreateVector( &status, &badinput.phaseVec, FOLDAMPLITUDESTESTC_BADLENGTH ); LALSCreateVector( &status, &badinput.amplitudeVec, FOLDAMPLITUDESTESTC_LENGTH ); LALSCreateVector( &status, &output, FOLDAMPLITUDESTESTC_NUMBINS ); /* ****** TEST RESPONSE TO INVALID DATA ************/ /* Test that all the error conditions are correctly detected by the function */ #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* Test NULL output */ param.numBins = FOLDAMPLITUDESTESTC_NUMBINS; param.binMin = 0.0; param.binMax = twoPi; LALFoldAmplitudes( &status, NULL, &input, ¶m ); if ( status.statusCode != FOLDAMPLITUDESH_ENULLP || strcmp(status.statusDescription, FOLDAMPLITUDESH_MSGENULLP) ) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription ); printf( "Expected error code %d and message %s\n", FOLDAMPLITUDESH_ENULLP, FOLDAMPLITUDESH_MSGENULLP ); return FOLDAMPLITUDESTESTC_ECHK; } /* Test input vectors of different length */ param.numBins = FOLDAMPLITUDESTESTC_NUMBINS; param.binMin = 0.0; param.binMax = twoPi; LALFoldAmplitudes( &status, output, &badinput, ¶m ); if ( status.statusCode != FOLDAMPLITUDESH_EVECSIZE || strcmp(status.statusDescription, FOLDAMPLITUDESH_MSGEVECSIZE) ) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription ); printf( "Expected error code %d and message %s\n", FOLDAMPLITUDESH_EVECSIZE, FOLDAMPLITUDESH_MSGEVECSIZE ); return FOLDAMPLITUDESTESTC_ECHK; } /* Test number of bins < 1 */ param.numBins = 0; param.binMin = 0.0; param.binMax = twoPi; LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode != FOLDAMPLITUDESH_ENUMBINS || strcmp(status.statusDescription, FOLDAMPLITUDESH_MSGENUMBINS) ) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription ); printf( "Expected error code %d and message %s\n", FOLDAMPLITUDESH_ENUMBINS, FOLDAMPLITUDESH_MSGENUMBINS ); return FOLDAMPLITUDESTESTC_ECHK; } /* Test bin max <= bin min */ param.numBins = FOLDAMPLITUDESTESTC_NUMBINS; param.binMin = 0.0; param.binMax = 0.0; LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode != FOLDAMPLITUDESH_EBINSIZE || strcmp(status.statusDescription, FOLDAMPLITUDESH_MSGEBINSIZE) ) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription ); printf( "Expected error code %d and message %s\n", FOLDAMPLITUDESH_EBINSIZE, FOLDAMPLITUDESH_MSGEBINSIZE ); return FOLDAMPLITUDESTESTC_ECHK; } /* Test bin min != 0 */ param.numBins = FOLDAMPLITUDESTESTC_NUMBINS; param.binMin = -0.5; param.binMax = 0.5; LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode != FOLDAMPLITUDESH_EBINMIN || strcmp(status.statusDescription, FOLDAMPLITUDESH_MSGEBINMIN) ) { printf( "Got error code %d and message %s\n", status.statusCode, status.statusDescription ); printf( "Expected error code %d and message %s\n", FOLDAMPLITUDESH_EBINMIN, FOLDAMPLITUDESH_MSGEBINMIN ); return FOLDAMPLITUDESTESTC_ECHK; } } #endif /* LAL_NDEBUG */ /* ****** TEST RESPONSE TO VALID DATA ************/ /* Test that valid data generate the correct answers */ /* Test 1: Simple test with constant amplitudes and constant phases */ /* All the amplitudes should end up in one bin; specifically the (j + 8)/2 % param.numBins bin. */ for (k = 0; k < 2; ++k) { param.numBins = 4; param.binMin = 0.0; if (k == 0) { param.binMax = 1.0; /* test phase measured in cycles */ } else { param.binMax = twoPi; /* test phase measured in radians */ } binRange = param.binMax - param.binMin; for (j = -8; j <= 8; ++j) { for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { input.amplitudeVec->data[i] = 1.0; /* Set the phase: Add in a multiple of twoPi to check that values bin correctly */ input.phaseVec->data[i] = j*(binRange/8.0) + j*j*j*binRange + .001; } /* Initialize the output vector */ for ( i = 0 ; i < (INT4)output->length ; ++i ) { output->data[i] = 0.0; } /* printf("\n"); for ( i = 0 ; i < input.amplitudeVec->length ; ++i ) { printf("Index %i Input Amplitude %f \n",i, input.amplitudeVec->data[i]); } printf("\n"); for ( i = 0 ; i < input.phaseVec->length ; ++i ) { printf("Index %i Input Phase %f \n",i, input.phaseVec->data[i]); } */ LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode ) { printf( "Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription ); return FOLDAMPLITUDESTESTC_EFLS; } printf("\n"); for ( i = 0 ; i < param.numBins ; ++i ) { printf("Constant phase test binRange %g, index %i, Bin %i, Output Amplitude %f \n",binRange,j,i,output->data[i]); if (i == (j + 8)/2 % param.numBins) { if (output->data[i] != lengthAmpVec*1.0) { printf ("For binRange %g expected all the amplitudes to fold into bin %i but instead got %g in this bin. \n",binRange, i,output->data[i]); gotError = 1; } } else { if (output->data[i] != 0.0) { printf ("For binRange %g expected no amplitudes to fold into bin %i but instead got %g in this bin. \n",binRange, i,output->data[i]); gotError = 1; } } } } /* end for (j = -8; j < 8; ++j) */ } /* end for (k = 0; k < 1; ++k) */ printf("\n"); if (gotError > 0) { printf("Test 1 in FoldAmplitudesTest.c Failed. \n"); return FOLDAMPLITUDESTESTC_EFLS; } else { printf("Test 1 in FoldAmplitudesTest.c Passed. \n"); } /* Test 2: Constant amplitudes, simple phases */ /* One should end up in each bin. */ param.numBins = 10; param.binMin = 0.0; param.binMax = twoPi; /* test phase measured in radians */ binRange = param.binMax - param.binMin; for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { input.amplitudeVec->data[i] = 1; input.phaseVec->data[i] = twoPi*i/10.0 + .0001; } /* Initialize the output vector */ for ( i = 0 ; i < (INT4)output->length ; ++i ) { output->data[i] = 0.0; } /* printf("\n"); for ( i = 0 ; i < input.amplitudeVec->length ; ++i ) { printf("Index %i Input Amplitude %f \n",i, input.amplitudeVec->data[i]); } printf("\n"); for ( i = 0 ; i < input.phaseVec->length ; ++i ) { printf("Index %i Input Phase %f \n",i, input.phaseVec->data[i]); } */ LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode ) { printf( "Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription ); return FOLDAMPLITUDESTESTC_EFLS; } printf("\n"); for ( i = 0 ; i < param.numBins ; ++i ) { printf("Bin %i Output Amplitude %f \n",i,output->data[i]); if (output->data[i] != 1.0) { printf ("In bin %i expected 1 but instead got %g in this bin. \n",i,output->data[i]); gotError = 1; } } printf("\n"); if (gotError > 0) { printf("Test 2 in FoldAmplitudesTest.c Failed. \n"); return FOLDAMPLITUDESTESTC_EFLS; } else { printf("Test 2 in FoldAmplitudesTest.c Passed. \n"); } /* Test 3: One amplitude goes into each bin, so that sin(\PHI) should return sin(\PHI) */ param.numBins = 10; param.binMin = 0.0; param.binMax = twoPi; /* test phase measured in radians */ binRange = param.binMax - param.binMin; for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { input.amplitudeVec->data[i] = sin(twoPi*i/10.0 + .0001); input.phaseVec->data[i] = twoPi*i/10.0 + .0001; } /* Initialize the output vector */ for ( i = 0 ; i < (INT4)output->length ; ++i ) { output->data[i] = 0.0; } /* printf("\n"); for ( i = 0 ; i < input.amplitudeVec->length ; ++i ) { printf("Index %i Input Amplitude %f \n",i, input.amplitudeVec->data[i]); } printf("\n"); for ( i = 0 ; i < input.phaseVec->length ; ++i ) { printf("Index %i Input Phase %f \n",i, input.phaseVec->data[i]); } */ LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode ) { printf( "Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription ); return FOLDAMPLITUDESTESTC_EFLS; } printf("\n"); for ( i = 0 ; i < param.numBins ; ++i ) { printf("Bin %i Output Amplitude %f \n",i,output->data[i]); if (fabs(output->data[i] - sin(twoPi*i/10.0 + .0001)) > fabs(output->data[i]*FOLDAMPLITUDESTESTC_TOL)) { printf ("In bin %i expected %g but instead got %g in this bin. \n",i,sin(twoPi*i/10.0 + .0001),output->data[i]); gotError = 1; } } printf("\n"); if (gotError > 0) { printf("Test 3 in FoldAmplitudesTest.c Failed. \n"); return FOLDAMPLITUDESTESTC_EFLS; } else { printf("Test 3 in FoldAmplitudesTest.c Passed. \n"); } /* Test 4: Two amplitudes go into each bin, such that sin(2*\PHI) should return 2*sin(\PHI) */ /* Also, phases are input as cycles. */ param.numBins = 5; param.binMin = 0.0; param.binMax = 1.0; /* test phase measured in radians */ binRange = param.binMax - param.binMin; for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { input.amplitudeVec->data[i] = sin(2.0*twoPi*i/5.0 + .001); input.phaseVec->data[i] = i/5.0 + .001; } /* Initialize the output vector */ for ( i = 0 ; i < (INT4)output->length ; ++i ) { output->data[i] = 0.0; } printf("\n"); for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { printf("Index %i Input Amplitude %f \n",i, input.amplitudeVec->data[i]); } printf("\n"); for ( i = 0 ; i < (INT4)input.phaseVec->length ; ++i ) { printf("Index %i Input Phase in Cycles %f \n",i, input.phaseVec->data[i]); } LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode ) { printf( "Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription ); return FOLDAMPLITUDESTESTC_EFLS; } printf("\n"); for ( i = 0 ; i < param.numBins ; ++i ) { printf("Bin %i Output Amplitude %f \n",i,output->data[i]); if (fabs(output->data[i] - 2.0*sin(2.0*twoPi*i/5.0 + .001)) > fabs(output->data[i]*FOLDAMPLITUDESTESTC_TOL)) { printf ("In bin %i expected %g but instead got %g in this bin. \n",i,2.0*sin(2.0*twoPi*i/5.0 + .001),output->data[i]); gotError = 1; } } printf("\n"); if (gotError > 0) { printf("Test 4 in FoldAmplitudesTest.c Failed. \n"); return FOLDAMPLITUDESTESTC_EFLS; } else { printf("Test 4 in FoldAmplitudesTest.c Passed. \n"); } /* Test 5: More realistic data; check output by hand */ param.numBins = FOLDAMPLITUDESTESTC_NUMBINS; param.binMin = 0.0; param.binMax = twoPi; printf("\n"); printf("Test 5 check by hand: numBins, binMax = %i, %g \n",param.numBins,param.binMax); for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { input.amplitudeVec->data[i] = sin(twoPi*f*i*delT + 0.5*fDot*i*delT*i*delT - 10.001); input.phaseVec->data[i] = twoPi*f*i*delT + 0.5*fDot*i*delT*i*delT - 10.001; } for ( i = 0 ; i < (INT4)output->length ; ++i ) { output->data[i] = 0.0; } printf("\n"); for ( i = 0 ; i < (INT4)input.amplitudeVec->length ; ++i ) { printf("Index %i Input Amplitude %f \n",i, input.amplitudeVec->data[i]); } printf("\n"); for ( i = 0 ; i < (INT4)input.phaseVec->length ; ++i ) { printf("Index %i Input Phase %f \n",i, input.phaseVec->data[i]); } LALFoldAmplitudes( &status, output, &input, ¶m ); if ( status.statusCode ) { printf( "Unexpectedly got error code %d and message %s\n", status.statusCode, status.statusDescription ); return FOLDAMPLITUDESTESTC_EFLS; } printf("\n"); for ( i = 0 ; i < param.numBins ; ++i ) { printf("Bin %i Output Amplitude %f \n",i,output->data[i]); } printf("\n"); if (gotError > 0) { printf("Test 5in FoldAmplitudesTest.c Failed. \n"); return FOLDAMPLITUDESTESTC_EFLS; } else { printf("Test 5 in FoldAmplitudesTest.c Passed. \n"); } /* some check on the contents of output */ /* ****** CLEAN UP ************/ LALSDestroyVector( &status, &input.phaseVec ); LALSDestroyVector( &status, &input.amplitudeVec ); LALSDestroyVector( &status, &badinput.phaseVec ); LALSDestroyVector( &status, &badinput.amplitudeVec ); LALSDestroyVector( &status, &output ); LALCheckMemoryLeaks(); printf("\n"); printf("PASS: All tests \n"); printf("\n"); return FOLDAMPLITUDESTESTC_ENOM; }
/** * \author Creighton, T. D. * * \brief Computes a continuous waveform with frequency drift and Doppler * modulation from a hyperbolic orbital trajectory. * * This function computes a quaiperiodic waveform using the spindown and * orbital parameters in <tt>*params</tt>, storing the result in * <tt>*output</tt>. * * In the <tt>*params</tt> structure, the routine uses all the "input" * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the * "output" fields. If <tt>params-\>f</tt>=\c NULL, no spindown * modulation is performed. If <tt>params-\>oneMinusEcc</tt>\f$\not<0\f$ (a * non-hyperbolic orbit), or if * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$ * (faster-than-light speed at periapsis), an error is returned. * * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is * ignored, but all other pointer fields must be set to \c NULL. The * function will create and allocate space for <tt>output-\>a</tt>, * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary. The * <tt>output-\>shift</tt> field will remain set to \c NULL. * * ### Algorithm ### * * For hyperbolic orbits, we combine \eqref{eq_spinorbit-tr}, * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$ * directly as a function of \f$E\f$: * \f{eqnarray}{ * \label{eq_tr-e3} * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\ * & + & \frac{1}{n} \left( -E + * \left[v_p(e-1)\cos\omega + e\right]\sinh E * - \left[v_p\sqrt{\frac{e-1}{e+1}}\sin\omega\right] * [\cosh E - 1]\right) \;, * \f} * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at * periapsis and \f$n=\dot{\upsilon}_p\sqrt{(1-e)^3/(1+e)}\f$ is a normalized * angular speed for the orbit (the hyperbolic analogue of the mean * angular speed for closed orbits). For simplicity we write this as: * \f{equation}{ * \label{eq_tr-e4} * t_r = T_p + \frac{1}{n}\left( E + A\sinh E + B[\cosh E - 1] \right) \;, * \f} * * \figure{inject_hanomaly,eps,0.23,Function to be inverted to find eccentric anomaly} * * where \f$T_p\f$ is the \e observed time of periapsis passage. Thus * the key numerical procedure in this routine is to invert the * expression \f$x=E+A\sinh E+B(\cosh E - 1)\f$ to get \f$E(x)\f$. This function * is sketched to the right (solid line), along with an approximation * used for making an initial guess (dotted line), as described later. * * We note that \f$A^2-B^2<1\f$, although it approaches 1 when * \f$e\rightarrow1\f$, or when \f$v_p\rightarrow1\f$ and either \f$e=0\f$ or * \f$\omega=\pi\f$. Except in this limit, Newton-Raphson methods will * converge rapidly for any initial guess. In this limit, though, the * slope \f$dx/dE\f$ approaches zero at \f$E=0\f$, and an initial guess or * iteration landing near this point will send the next iteration off to * unacceptably large or small values. A hybrid root-finding strategy is * used to deal with this, and with the exponential behaviour of \f$x\f$ at * large \f$E\f$. * * First, we compute \f$x=x_{\pm1}\f$ at \f$E=\pm1\f$. If the desired \f$x\f$ lies * in this range, we use a straightforward Newton-Raphson root finder, * with the constraint that all guesses of \f$E\f$ are restricted to the * domain \f$[-1,1]\f$. This guarantees that the scheme will eventually find * itself on a uniformly-convergent trajectory. * * Second, for \f$E\f$ outside of this range, \f$x\f$ is dominated by the * exponential terms: \f$x\approx\frac{1}{2}(A+B)\exp(E)\f$ for \f$E\gg1\f$, and * \f$x\approx-\frac{1}{2}(A-B)\exp(-E)\f$ for \f$E\ll-1\f$. We therefore do an * \e approximate Newton-Raphson iteration on the function \f$\ln|x|\f$, * where the approximation is that we take \f$d\ln|x|/d|E|\approx1\f$. This * involves computing an extra logarithm inside the loop, but gives very * rapid convergence to high precision, since \f$\ln|x|\f$ is very nearly * linear in these regions. * * At the start of the algorithm, we use an initial guess of * \f$E=-\ln[-2(x-x_{-1})/(A-B)-\exp(1)]\f$ for \f$x<x_{-1}\f$, \f$E=x/x_{-1}\f$ for * \f$x_{-1}\leq x\leq0\f$, \f$E=x/x_{+1}\f$ for \f$0\leq x\leq x_{+1}\f$, or * \f$E=\ln[2(x-x_{+1})/(A+B)-\exp(1)]\f$ for \f$x>x_{+1}\f$. We refine this * guess until we get agreement to within 0.01 parts in part in * \f$N_\mathrm{cyc}\f$ (where \f$N_\mathrm{cyc}\f$ is the larger of the number * of wave cycles in a time \f$2\pi/n\f$, or the number of wave cycles in the * entire waveform being generated), or one part in \f$10^{15}\f$ (an order * of magnitude off the best precision possible with \c REAL8 * numbers). The latter case indicates that \c REAL8 precision may * fail to give accurate phasing, and one should consider modeling the * orbit as a set of Taylor frequency coefficients \'{a} la * <tt>LALGenerateTaylorCW()</tt>. On subsequent timesteps, we use the * previous timestep as an initial guess, which is good so long as the * timesteps are much smaller than \f$1/n\f$. * * Once a value of \f$E\f$ is found for a given timestep in the output * series, we compute the system time \f$t\f$ via \eqref{eq_spinorbit-t}, * and use it to determine the wave phase and (non-Doppler-shifted) * frequency via \eqref{eq_taylorcw-freq} * and \eqref{eq_taylorcw-phi}. The Doppler shift on the frequency is * then computed using \eqref{eq_spinorbit-upsilon} * and \eqref{eq_orbit-rdot}. We use \f$\upsilon\f$ as an intermediate in * the Doppler shift calculations, since expressing \f$\dot{R}\f$ directly in * terms of \f$E\f$ results in expression of the form \f$(e-1)/(e\cosh E-1)\f$, * which are difficult to simplify and face precision losses when * \f$E\sim0\f$ and \f$e\rightarrow1\f$. By contrast, solving for \f$\upsilon\f$ is * numerically stable provided that the system <tt>atan2()</tt> function is * well-designed. * * This routine does not account for relativistic timing variations, and * issues warnings or errors based on the criterea of * \eqref{eq_relativistic-orbit} in \ref LALGenerateEllipticSpinOrbitCW(). */ void LALGenerateHyperbolicSpinOrbitCW( LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params ) { UINT4 n, i; /* number of and index over samples */ UINT4 nSpin = 0, j; /* number of and index over spindown terms */ REAL8 t, dt, tPow; /* time, interval, and t raised to a power */ REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */ REAL8 f, fPrev; /* current and previous values of frequency */ REAL4 df = 0.0; /* maximum difference between f and fPrev */ REAL8 phi; /* current value of phase */ REAL8 vDotAvg; /* nomalized orbital angular speed */ REAL8 vp; /* projected speed at periapsis */ REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */ REAL8 eCosOmega; /* eccentricity * cosine of argument */ REAL8 tPeriObs; /* time of observed periapsis */ REAL8 spinOff; /* spin epoch - orbit epoch */ REAL8 x; /* observed ``mean anomaly'' */ REAL8 xPlus, xMinus; /* limits where exponentials dominate */ REAL8 dx, dxMax; /* current and target errors in x */ REAL8 a, b; /* constants in equation for x */ REAL8 ecc; /* orbital eccentricity */ REAL8 eccMinusOne, eccPlusOne; /* ecc - 1 and ecc + 1 */ REAL8 e; /* hyperbolic anomaly */ REAL8 sinhe, coshe; /* sinh of e, and cosh of e minus 1 */ REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); ASSERT( output, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); /* If Taylor coeficients are specified, make sure they exist. */ if ( params->f ) { ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); nSpin = params->f->length; fSpin = params->f->data; } /* Set up some constants (to avoid repeated calculation or dereferencing), and make sure they have acceptable values. */ eccMinusOne = -params->oneMinusEcc; ecc = 1.0 + eccMinusOne; eccPlusOne = 2.0 + eccMinusOne; if ( eccMinusOne <= 0.0 ) { ABORT( stat, GENERATESPINORBITCWH_EECC, GENERATESPINORBITCWH_MSGEECC ); } vp = params->rPeriNorm*params->angularSpeed; vDotAvg = params->angularSpeed *sqrt( eccMinusOne*eccMinusOne*eccMinusOne/eccPlusOne ); n = params->length; dt = params->deltaT; f0 = fPrev = params->f0; if ( vp >= 1.0 ) { ABORT( stat, GENERATESPINORBITCWH_EFTL, GENERATESPINORBITCWH_MSGEFTL ); } if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 || n == 0 ) { ABORT( stat, GENERATESPINORBITCWH_ESGN, GENERATESPINORBITCWH_MSGESGN ); } /* Set up some other constants. */ twopif0 = f0*LAL_TWOPI; phi0 = params->phi0; argument = params->omega; a = vp*eccMinusOne*cos( argument ) + ecc; b = -vp*sqrt( eccMinusOne/eccPlusOne )*sin( argument ); eCosOmega = ecc*cos( argument ); if ( n*dt*vDotAvg > LAL_TWOPI ) dxMax = 0.01/( f0*n*dt ); else dxMax = 0.01/( f0*LAL_TWOPI/vDotAvg ); if ( dxMax < 1.0e-15 ) { dxMax = 1.0e-15; #ifndef NDEBUG LALWarning( stat, "REAL8 arithmetic may not have sufficient" " precision for this orbit" ); #endif } #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { REAL8 tau = n*dt; if ( tau > LAL_TWOPI/vDotAvg ) tau = LAL_TWOPI/vDotAvg; if ( f0*tau*vp*vp*ecc/eccPlusOne > 0.25 ) LALWarning( stat, "Orbit may have significant relativistic" " effects that are not included" ); } #endif /* Compute offset between time series epoch and observed periapsis, and betweem true periapsis and spindown reference epoch. */ tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds - params->epoch.gpsSeconds ); tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->epoch.gpsNanoSeconds ); tPeriObs += params->rPeriNorm*sin( params->omega ); spinOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->spinEpoch.gpsSeconds ); spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->spinEpoch.gpsNanoSeconds ); /* Determine bounds of hybrid root-finding algorithm, and initial guess for e. */ xMinus = 1.0 + a*sinh( -1.0 ) + b*cosh( -1.0 ) - b; xPlus = -1.0 + a*sinh( 1.0 ) + b*cosh( 1.0 ) - b; x = -vDotAvg*tPeriObs; if ( x < xMinus ) e = -log( -2.0*( x - xMinus )/( a - b ) - exp( 1.0 ) ); else if ( x <= 0 ) e = x/xMinus; else if ( x <= xPlus ) e = x/xPlus; else e = log( 2.0*( x - xPlus )/( a + b ) - exp( 1.0 ) ); sinhe = sinh( e ); coshe = cosh( e ) - 1.0; /* Allocate output structures. */ if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position = params->position; output->psi = params->psi; output->a->epoch = output->f->epoch = output->phi->epoch = params->epoch; output->a->deltaT = n*params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "CW amplitudes" ); snprintf( output->f->name, LALNameLength, "CW frequency" ); snprintf( output->phi->name, LALNameLength, "CW phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), n ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), n ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate and fill amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = 2; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); output->a->data->data[0] = output->a->data->data[2] = params->aPlus; output->a->data->data[1] = output->a->data->data[3] = params->aCross; } /* Fill frequency and phase arrays. */ fData = output->f->data->data; phiData = output->phi->data->data; for ( i = 0; i < n; i++ ) { x = vDotAvg*( i*dt - tPeriObs ); /* Use approximate Newton-Raphson method on ln|x| if |x| > 1. */ if ( x < xMinus ) { x = log( -x ); while ( fabs( dx = log( e - a*sinhe - b*coshe ) - x ) > dxMax ) { e += dx; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } else if ( x > xPlus ) { x = log( x ); while ( fabs( dx = log( -e + a*sinhe + b*coshe ) - x ) > dxMax ) { e -= dx; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } /* Use ordinary Newton-Raphson method on x if |x| <= 1. */ else { while ( fabs( dx = -e + a*sinhe + b*coshe - x ) > dxMax ) { e -= dx/( -1.0 + a*coshe + a + b*sinhe ); if ( e < -1.0 ) e = -1.0; else if ( e > 1.0 ) e = 1.0; sinhe = sinh( e ); coshe = cosh( e ) - 1.0; } } /* Compute source emission time, phase, and frequency. */ phi = t = tPow = ( ecc*sinhe - e )/vDotAvg + spinOff; f = 1.0; for ( j = 0; j < nSpin; j++ ) { f += fSpin[j]*tPow; phi += fSpin[j]*( tPow*=t )/( j + 2.0 ); } /* Appy frequency Doppler shift. */ upsilon = 2.0*atan2( sqrt( eccPlusOne*coshe ), sqrt( eccMinusOne*( coshe + 2.0 ) ) ); f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega ) /eccPlusOne ); phi *= twopif0; if ( fabs( f - fPrev ) > df ) df = fabs( f - fPrev ); *(fData++) = fPrev = f; *(phiData++) = phi + phi0; } /* Set output field and return. */ params->dfdt = df*dt; DETATCHSTATUSPTR( stat ); RETURN( stat ); }
/** * \ingroup LALInspiralBank_h * \author Hanna, C. R. and Owen, B. J. * \brief This function creates a bank of BCVSpin templates to search for precessing binaries. * * ### Algorithm ### * * The code checks <tt>coarseIn-\>mMin</tt> to determine whether the limits on * the target region are in terms of masses or phenomenological parameters. * A positive value indicates that mass limits are being used. * * If mass limits are used, the target region of parameter space is a * distorted box in the coordinates \f$(x=\psi_0, y=\psi_3, z=\beta)\f$. The * metric at high values of \f$\beta\f$ is constant. It is convenient to rotate * to coordinates \f$(x',y',z')\f$ which lie along eigenvectors of the metric. * * The algorithm first draws a rectilinear box in the primed coordinates * which includes the target region, then steps through along the * directions of the primed coordinates. At each point it tests if the * point lies within the target region. If the point is inside the target * region, the algorithm adds a template to the linked list. If not, it * continues through the box containing the target region. * * The tiling is done with a body-centered cubic lattice. People usually * solve the non-overlapping bcc problem rather than the overlapping one * here, so it's worth mentioning how we do it. I don't have time to stick * in the 3D figures you need to show it properly, but you can figure out * the spacing by finding the smallest sphere that contains the * Wigner-Seitz cell. When you do that you find that the lattice constant * (spacing between templates in the plane, in proper distance) is * \f$(4/3)\sqrt{2\mu}\f$. So the coordinate spacing is that divided by the * square root of the corresponding eigenvalue of the metric. (The vertical * spacing in the bcc lattice is multiplied by a further 1/2.) * * If \f$(\psi_0, \psi_3, \beta)\f$ limits are used, the tiling is done in the * given box with a bcc lattice. * * ### Notes ### * * Currently we use a static function for the metric based on an * approximation that is good only for large \f$\beta\f$. We should update it * and put it out in the LAL namespace. * * The metric relies on approximations that make it valid only for a binary * system with a total mass \f$<15M\odot\f$ where the larger body's minimum mass * is at least twice the smaller body's maximum mass. If the parameter * range is specified with physical parameters rather than the * phenomenological parameters \f$(\psi_0, \psi_3, \beta)\f$ then using mass * values that violate these conditions will result in an error message. * */ void LALInspiralSpinBank( LALStatus *status, SnglInspiralTable **tiles, INT4 *ntiles, InspiralCoarseBankIn *coarseIn ) { SnglInspiralTable *tmplt = NULL; /* loop counter */ REAL4Array *metric = NULL; /* parameter-space metric */ UINT4Vector *metricDimensions = NULL; /* contains the dimension of metric */ REAL4Vector *eigenval = NULL; /* eigenvalues of metric */ InspiralMomentsEtc moments; /* Added for LALGetInspiralMoments() */ InspiralTemplate inspiralTemplate; /* Added for LALGetInspiralMoments() */ REAL4 x, y, z; /* psi0, psi3, beta coordinates */ REAL4 x0, myy0, z0; /* minimum values of x, y, z */ REAL4 x1, myy1, z1; /* maximum values of x, y, z */ REAL4 xp, yp, zp; /* metric eigenvector coordinates */ REAL4 xp0, yp0, UNUSED zp0; /* minimum values of xp, yp, zp */ REAL4 xp1, yp1, zp1; /* maximum values of xp, yp, zp */ REAL4 dxp, dyp, dzp; /* step sizes in xp, yp, zp */ REAL4 theta; /* angle of rotation for xp and yp */ REAL4 m1Min=0, m1Max=0; /* range of m1 to search */ REAL4 m2Min=0, m2Max=0; /* range of m2 to search */ REAL4 f0 = -1; /* frequency of minimum of noise curve */ INT2 bccFlag = 0; /* determines offset for bcc tiling */ INT4 cnt = 0; /* loop counter set to value of ntiles */ REAL4 shf0 = 1; /* used to find minimum of shf */ BOOLEAN havePsi; /* are we using phenom parameters? */ /* Set up status pointer. */ INITSTATUS(status); ATTATCHSTATUSPTR( status ); ASSERT( coarseIn, status, LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL ); /* Check that minimal match is OK. */ ASSERT( coarseIn->mmCoarse > 0, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); /* Sanity check parameter bounds. */ if( coarseIn->mMin > 0 ) { ASSERT( coarseIn->MMax > 0, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); ASSERT( coarseIn->MMax > 2*coarseIn->mMin, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); havePsi = 0; } /* Sanity check phenomenological parameter bounds. */ else { ASSERT( coarseIn->psi0Min > 0, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); ASSERT( coarseIn->psi0Max > coarseIn->psi0Min, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); ASSERT( coarseIn->psi3Min < 0, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); ASSERT( coarseIn->psi3Max > coarseIn->psi3Min, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); ASSERT( coarseIn->betaMax > coarseIn->betaMin, status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE ); havePsi = 1; } /* Check that noise curve exists. */ ASSERT( coarseIn->shf.data, status, LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL ); ASSERT( coarseIn->shf.data->data, status, LALINSPIRALBANKH_ENULL, LALINSPIRALBANKH_MSGENULL ); /* Allocate memory for 3x3 parameter-space metric & eigenvalues. */ LALU4CreateVector( status->statusPtr, &metricDimensions, (UINT4) 2 ); BEGINFAIL(status) cleanup(status->statusPtr, &metric, &metricDimensions, &eigenval, *tiles, tmplt, ntiles); ENDFAIL(status); metricDimensions->data[0] = 3; metricDimensions->data[1] = 3; LALSCreateArray( status->statusPtr, &metric, metricDimensions ); BEGINFAIL(status) cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles); ENDFAIL(status); eigenval = NULL; LALSCreateVector( status->statusPtr, &eigenval, 3 ); BEGINFAIL(status) cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles); ENDFAIL(status); /* Set f0 to frequency of minimum of noise curve. */ for( cnt = 0; cnt < (INT4) coarseIn->shf.data->length; cnt++ ) { if( coarseIn->shf.data->data[cnt] > 0 && coarseIn->shf.data->data[cnt] < shf0 ) { f0 = (REAL4) coarseIn->shf.deltaF * cnt; shf0 = coarseIn->shf.data->data[cnt]; } } /* Compute noise moments. */ inspiralTemplate.fLower = coarseIn->fLower; inspiralTemplate.fCutoff = coarseIn->fUpper; LALGetInspiralMoments( status->statusPtr, &moments, &(coarseIn->shf), &inspiralTemplate ); BEGINFAIL(status) cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ENDFAIL(status); /* Find the metric. */ LALInspiralSpinBankMetric(status->statusPtr, metric, &moments, &inspiralTemplate, &f0); BEGINFAIL(status) cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt, ntiles); ENDFAIL(status); /* Find eigenvalues and eigenvectors. */ LALSSymmetricEigenVectors( status->statusPtr, eigenval, metric ); BEGINFAIL(status) cleanup(status->statusPtr,&metric, &metricDimensions,&eigenval,*tiles,tmplt, ntiles); ENDFAIL(status); /* Allocate first template, which will remain blank. */ *tiles = tmplt = (SnglInspiralTable *) LALCalloc( 1, sizeof( SnglInspiralTable ) ); if ( *tiles == NULL ) { cleanup( status->statusPtr, &metric, &metricDimensions, &eigenval, *tiles, tmplt, ntiles); ABORT( status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM ); } *ntiles = 0; /* Set stepsizes from eigenvalues and angle from eigenvectors. */ if( eigenval->data[0] <= 0 || eigenval->data[1] <=0 || eigenval->data[2] <= 0 ) { ABORT(status, LALINSPIRALBANKH_ECHOICE, LALINSPIRALBANKH_MSGECHOICE); } dxp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[0]); dyp = 1.333333*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[1]); dzp = 0.6666667*sqrt(2*(1-coarseIn->mmCoarse)/eigenval->data[2]); theta = atan2( -metric->data[3], -metric->data[0] ); printf( "theta is %e\n", theta ); /* If target region is given in terms of masses... */ if ( ! havePsi ) { /* Hardcode mass range on higher mass for the moment. */ m2Min = coarseIn->mMin*LAL_MTSUN_SI; m2Max = coarseIn->MMax*LAL_MTSUN_SI/2; m1Min = 2.0*m2Max; m1Max = 15.0*LAL_MTSUN_SI - m2Max; /* Set box on unprimed phenom coordinates including region. */ x0 = 0.9*(3.0/128) / (pow(LAL_PI*f0*(m1Max+m2Max),1.666667) *(m1Max*m2Max/pow(m1Max+m2Max,2))); myy0 = 1.1*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Max+m2Min),0.6666667)*(m1Max*m2Min/pow(m1Max+m2Min,2))); z0 = 0; x1 = 1.1*(3.0/128) / (pow(LAL_PI*f0*(m1Min+m2Min),1.666667)*(m1Min*m2Min/pow(m1Min+m2Min,2))); myy1 = .9*(-.375*LAL_PI) / (pow(LAL_PI*f0*(m1Min+m2Max),0.6666667)*(m1Min*m2Max/pow(m1Min+m2Max,2))); z1 = 3.8* LAL_PI/29.961432 * (1+0.75*m2Max/m1Min) * (m1Max/m2Min) * pow(LAL_MTSUN_SI*100.0/(m1Min+m2Min), 0.6666667); } /* Target region is given in terms of psi etc (unprimed). */ else { /* Rescale to dimensionless parameters used internally. */ x0 = coarseIn->psi0Min / pow( f0, 5./3 ); x1 = coarseIn->psi0Max / pow( f0, 5./3 ); myy0 = coarseIn->psi3Min / pow( f0, 2./3 ); myy1 = coarseIn->psi3Max / pow( f0, 2./3 ); z0 = coarseIn->betaMin / pow( f0, 2./3 ); z1 = coarseIn->betaMax / pow( f0, 2./3 ); } /* Set boundaries of bigger box in primed (eigen) coordinates. */ xp0 = x0 + sin(theta)*sin(theta) * (x1 - x0); yp0 = myy0 - cos(theta)*sin(theta) * (x1 - x0); yp1 = sin(theta) * (x1 - x0) + cos(theta) * (myy1 - myy0); xp1 = sin(theta) * (myy1 - myy0) + cos(theta) * (x1 - x0); zp0 = z0; zp1 = z1; /* This loop generates the template bank. */ for (zp = 0; zp <= zp1; zp += dzp) { bccFlag++; for (yp = 0; yp<= yp1; yp += dyp) { for (xp = 0; xp <= xp1; xp += dxp) { /* If the point is in the target region, allocate a template. */ x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta); y = calculateY(0, yp0, xp, dxp, yp, dyp, bccFlag, theta); z = calculateZ(0, zp, dzp); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if( tmplt == NULL ) { cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } /* If dx behind is not in region, try dx/2 behind. */ x = calculateX(-1, xp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { x = calculateX(-0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if( tmplt == NULL ) { cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } /* If dy behind is not in region, try dy/2 behind. */ x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta); y = calculateY(-1, yp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { y = calculateY(-0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if (!tmplt){ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } /* If dz behind is not in region, try dz/2 behind. */ y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta); z = calculateZ(-1, zp, dzp); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { z = calculateZ(-0.5, zp, dzp); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if (!tmplt){ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } /* If dx ahead is not in region, try dx/2 ahead. */ x = calculateX(1, xp0, xp, dxp, yp, dyp, bccFlag, theta); y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta); z = calculateZ(0, zp, dzp); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { x = calculateX(0.5, xp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if (!tmplt){ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } /* If dy ahead is not in region, try dy/2 ahead. */ x = calculateX(0, xp0, xp, dxp, yp, dyp, bccFlag, theta); y = calculateY(1, yp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { y = calculateY(0.5, yp0, xp, dxp, yp, dyp, bccFlag, theta); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if (!tmplt){ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } /* If dz ahead is not in region, try dz/2 ahead. */ y = calculateY(0, yp0, xp, dxp, yp, dyp, (bccFlag+1), theta); z = calculateZ(1, zp, dzp); if( ( havePsi && ! inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && ! test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { z = calculateZ(0.5, zp, dzp); if( ( havePsi && inPsiRegion( x, y, z, coarseIn, f0 ) ) || ( ! havePsi && test(x,y,z,m1Min,m1Max,m2Min,m2Max,f0) ) ) { allocate( x, y, z, f0, &tmplt, ntiles, havePsi ); if (!tmplt){ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, LALINSPIRALBANKH_EMEM, LALINSPIRALBANKH_MSGEMEM); } } } } /* for (zp...) */ } /* for (yp...) */ } /* for (zp...) */ /* Trim the first template, which was left blank. */ tmplt = (*tiles)->next; LALFree( *tiles ); *tiles = tmplt; /* What if no templates were allocated? ABORT */ if (*tiles == NULL) { cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,*tiles,tmplt,ntiles); ABORT(status, INSPIRALSPINBANKC_ENOTILES, INSPIRALSPINBANKC_MSGENOTILES); } /* free memory allocated for the vectors and arrays */ cleanup(status->statusPtr,&metric,&metricDimensions,&eigenval,NULL,NULL,&cnt); DETATCHSTATUSPTR( status ); RETURN( status ); } /* LALInspiralSpinBank() */
int main(int argc, char *argv[]) { long i; double window_sum; LALStatus status={level:0, statusPtr: NULL}; PassBandParamStruc filterpar; REAL4TimeSeries chan; /* must zero the f0 field */ fprintf(stderr,"make_sft_op version %s\n", MAKE_SFT_VERSION); fprintf(stderr,"Using frame library %s\n", FrLibVersionF()); fprintf(stderr,"Using LAL version %s\n", LAL_VERSION); yylex(); if(freq_start<0)freq_start=0; if(freq_stop<0)freq_stop=total_samples; /* post_init various subsystems */ post_init_response_files(); post_init_alpha_beta(); /* print settings */ print_settings(stderr); /* start processing data */ print_data_stats(); print_data(file_debug1, "debug 1"); verify_loaded_data(); generate_fake_data(); linear_interpolate_gaps(); print_data(file_debug2, "debug 2"); /* this is a hack, but it significantly reduces memory footprint */ td_data=do_alloc(1,sizeof(*td_data)); td_data->length=total_samples; td_data->data=data; /* setup structure to hold input for Butterworth filter */ chan.data=NULL; strncpy(chan.name,channel,LALNameLength); chan.f0=0; chan.name[LALNameLength-1]=0; /* make sure it is null-terminated */ chan.deltaT=1.0/samples_per_second; chan.epoch.gpsSeconds=gps_start; /* no need */ chan.epoch.gpsNanoSeconds=0; if(trace_power){ fprintf(stderr, "Input data total power=%.*g\n", precision, sum_r4_squares(data, total_samples)/samples_per_second); } if(!bypass_highpass_filter && (highpass_filter_f>0) && (highpass_filter_a>0)){ fprintf(stderr,"Applying high pass filter, f=%g a=%g order=%d\n", highpass_filter_f, highpass_filter_a, highpass_filter_order); /* Setup Butterworth filter */ filterpar.name="Butterworth High Pass"; filterpar.nMax=highpass_filter_order; filterpar.f2=highpass_filter_f; filterpar.a2=highpass_filter_a; /* values that are 'not given' = out of range */ filterpar.f1=-1.0; filterpar.a1=-1.0; /* REAL4Sequence is the same as REAL4Vector - according to lal/Datatypes.h */ chan.data=(REAL4Sequence *)td_data; LALDButterworthREAL4TimeSeries(&status, &chan, &filterpar); TESTSTATUS(&status); if(trace_power){ fprintf(stderr, "After highpass filter total power=%.*g\n", precision, sum_r4_squares(data, total_samples)/samples_per_second); } } if(!bypass_lowpass_filter && (lowpass_filter_f>0) && (lowpass_filter_a > 0)){ fprintf(stderr,"Applying low pass filter, f=%g a=%g order=%d\n", lowpass_filter_f, lowpass_filter_a, lowpass_filter_order); /* Setup Butterworth filter */ filterpar.name="Butterworth Low Pass"; filterpar.nMax=lowpass_filter_order; filterpar.f1=lowpass_filter_f; filterpar.a1=lowpass_filter_a; /* values that are 'not given' = out of range */ /* why 2*nsamples ? LAL used to have a bug in it where the pairs were sorted before deciding whether the filter is lowpass or highpass. Therefore, we need to specify a large, out of range, frequency f so that we get a low-pass filter. The maximum frequency is Nyquist, hence 2*nsamples is definitely out of range */ filterpar.f2=2*total_samples; filterpar.a2=-1.0; /* REAL4Sequence is the same as REAL4Vector - according to lal/Datatypes.h */ chan.data=(REAL4Sequence *)td_data; LALDButterworthREAL4TimeSeries(&status, &chan, &filterpar); TESTSTATUS(&status); if(trace_power){ fprintf(stderr, "After lowpass filter total power=%.*g\n", precision, sum_r4_squares(data, total_samples)/samples_per_second); } } if(!bypass_first_window){ fprintf(stderr,"Applying Hann window to input data\n"); for(i=0;i<total_samples;i++)data[i]*=0.5*(1.0-cos((2.0*M_PI*i)/total_samples)); window_sum=0.5; } else { window_sum=1.0; } if(trace_power){ fprintf(stderr, "After windowing total power=%.*g\n", precision, sum_r4_squares(data, total_samples)/samples_per_second); } for(i=0;i<3;i++){ fprintf(stderr,"Allocating phi[%ld]\n", i); LALCCreateVector(&status, &(phi[i]), freq_stop-freq_start); TESTSTATUS(&status); } compute_test_fft(td_data, phi, 3, freq_start, freq_stop); /* now free td_data to conserve space */ free(td_data->data); data=NULL; free(td_data); td_data=NULL; LALCCreateVector(&status, &pgram, freq_stop-freq_start); TESTSTATUS(&status); compute_calibrated_periodogram3(phi, freq_start, freq_stop, pgram, window_sum); print_COMPLEX8Vector(pgram, output_sft, "CALIBRATED FREQUENCY DOMAIN DATA", output_mode, 0, freq_stop-freq_start); if(output_power!=NULL){ /* we need more space */ for(i=0;i<3;i++){ LALCDestroyVector(&status, &(phi[i])); TESTSTATUS(&status); } LALSCreateVector(&status, &power, freq_stop-freq_start); TESTSTATUS(&status); for(i=0;i<freq_stop-freq_start;i++) power->data[i]=(pgram->data[i].re*pgram->data[i].re+pgram->data[i].im*pgram->data[i].im); print_REAL4Vector(power, output_power, "CALIBRATED POWER", output_mode, 0, freq_stop-freq_start); } /* we do not destroy large vectors when we are done unless we need to allocate a lot of space again. This reduces run time of the program */ return 0; }
void LALCoarseFitToPulsar ( LALStatus *status, CoarseFitOutput *output, CoarseFitInput *input, CoarseFitParams *params ) { /******* DECLARE VARIABLES ************/ UINT4 n,i,j; /* integer indices */ REAL8 psi; REAL8 h0; REAL8 cosIota; REAL8 phase; REAL8 chiSquare; LALDetector detector; LALSource pulsar; LALDetAndSource detAndSource; LALDetAMResponse computedResponse; REAL4Vector *Fp, *Fc; /* pointers to amplitude responses of the detector */ REAL8Vector *var; REAL8 cos2phase,sin2phase; COMPLEX16 Xp, Xc; REAL8 Y, cosIota2; COMPLEX16 A,B; REAL8 sumAA, sumBB, sumAB; REAL8 h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0; REAL8 minChiSquare; UINT4 iH0, iCosIota, iPhase, iPsi, arg; LALGPSandAcc pGPSandAcc; INITSTATUS(status); ATTATCHSTATUSPTR(status); /******* CHECK VALIDITY OF ARGUMENTS ************/ ASSERT(output != (CoarseFitOutput *)NULL, status, FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); ASSERT(params != (CoarseFitParams *)NULL, status, FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); ASSERT(input != (CoarseFitInput *)NULL, status, FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); ASSERT(input->B->length == input->var->length, status, FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE ); /******* EXTRACT INPUTS AND PARAMETERS ************/ n = input->B->length; for (i = 0; i < n; i++) ASSERT(input->var->data[i].re > 0.0 && input->var->data[i].im > 0.0, status, FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR); detector = params->detector; detAndSource.pDetector = &detector; pulsar = params->pulsarSrc; /******* ALLOCATE MEMORY TO VECTORS **************/ Fp = NULL; LALSCreateVector(status->statusPtr, &Fp, n); Fp->length = n; Fc = NULL; LALSCreateVector(status->statusPtr, &Fc, n); Fc->length = n; var = NULL; LALDCreateVector(status->statusPtr, &var, n); var->length = n; /******* INITIALIZE VARIABLES *******************/ minChiSquare = INICHISQU; /******* DO ANALYSIS ************/ for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++) { fprintf(stderr,"%d out of %f iPsi\n", iPsi+1, params->meshPsi[2]); fflush(stderr); psi = params->meshPsi[0] + (REAL8)iPsi*params->meshPsi[1]; pulsar.orientation = psi; detAndSource.pSource = &pulsar; for (i=0;i<n;i++) { Fp->data[i] = 0.0; Fc->data[i] = 0.0; for(j=0;j<input->N;j++) { pGPSandAcc.gps.gpsNanoSeconds = input->t[i].gpsNanoSeconds; pGPSandAcc.gps.gpsSeconds = input->t[i].gpsSeconds + (double)j*60.0; pGPSandAcc.accuracy = 1.0; LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &pGPSandAcc); Fp->data[i] += (REAL8)computedResponse.plus; Fc->data[i] += (REAL8)computedResponse.cross; } Fp->data[i] /= (double)input->N; Fc->data[i] /= (double)input->N; } for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++) { phase = params->meshPhase[0] + (REAL8)iPhase*params->meshPhase[1]; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++) { cosIota = params->meshCosIota[0] + (REAL8)iCosIota*params->meshCosIota[1]; cosIota2 = 1.0 + cosIota*cosIota; Xp.re = 0.25*cosIota2 * cos2phase; Xp.im = 0.25*cosIota2 * sin2phase; Y = 0.5*cosIota; Xc.re = Y*sin2phase; Xc.im = -Y*cos2phase; sumAB = 0.0; sumAA = 0.0; sumBB = 0.0; for (i = 0; i < n; i++) { B.re = input->B->data[i].re; B.im = input->B->data[i].im; A.re = Fp->data[i]*Xp.re + Fc->data[i]*Xc.re; A.im = Fp->data[i]*Xp.im + Fc->data[i]*Xc.im; sumBB += B.re*B.re/input->var->data[i].re + B.im*B.im/input->var->data[i].im; sumAA += A.re*A.re/input->var->data[i].re + A.im*A.im/input->var->data[i].im; sumAB += B.re*A.re/input->var->data[i].re + B.im*A.im/input->var->data[i].im; } for (iH0 = 0; iH0 < params->meshH0[2]; iH0++) { h0 = params->meshH0[0] + (float)iH0*params->meshH0[1]; chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA; if (chiSquare<minChiSquare) { minChiSquare = chiSquare; h0BestFit = h0; cosIotaBestFit = cosIota; psiBestFit = psi; phaseBestFit = phase; } arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); output->mChiSquare->data[arg] = chiSquare; } } } } /******* CONSTRUCT OUTPUT ************/ output->h0 = h0BestFit; output->cosIota = cosIotaBestFit; output->phase = phaseBestFit; output->psi = psiBestFit; output->chiSquare = minChiSquare; ASSERT(minChiSquare < INICHISQU, status, FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); LALSDestroyVector(status->statusPtr, &Fp); LALSDestroyVector(status->statusPtr, &Fc); LALDDestroyVector(status->statusPtr, &var); DETATCHSTATUSPTR(status); RETURN(status); }
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); }
/** * Handle user-input and check its validity. * Load ephemeris and calculate AM-coefficients (stored globally) */ void Initialize (LALStatus *status, struct CommandLineArgsTag *CLA) { EphemerisData *edat=NULL; /* Stores earth/sun ephemeris data for barycentering */ BarycenterInput baryinput; /* Stores detector location and other barycentering data */ EarthState earth; AMCoeffsParams *amParams; LIGOTimeGPS *midTS=NULL; /* Time stamps for amplitude modulation coefficients */ LALDetector *Detector; /* Our detector*/ INT4 k; INITSTATUS(status); ATTATCHSTATUSPTR (status); if ( XLALUserVarWasSet ( &(CLA->nTsft) ) ) CLA->duration = 1.0 * CLA->nTsft * CLA->Tsft; /* read or generate SFT timestamps */ if ( XLALUserVarWasSet(&(CLA->timestamps)) ) { XLAL_CHECK_LAL ( status, ( timestamps = XLALReadTimestampsFile ( CLA->timestamps ) ) != NULL, XLAL_EFUNC ); if ( (CLA->nTsft > 0) && ( (UINT4)CLA->nTsft < timestamps->length ) ) /* truncate if required */ timestamps->length = CLA->nTsft; CLA->nTsft = timestamps->length; } /* if have_timestamps */ else { LIGOTimeGPS tStart; tStart.gpsSeconds = CLA->gpsStart; tStart.gpsNanoSeconds = 0; XLAL_CHECK_LAL ( status, ( timestamps = XLALMakeTimestamps( tStart, CLA->duration, CLA->Tsft, 0 ) ) != NULL, XLAL_EFUNC ); CLA->nTsft = timestamps->length; } /* no timestamps */ /*---------- initialize detector ---------- */ { BOOLEAN have_IFO = XLALUserVarWasSet ( &CLA->IFO ); BOOLEAN have_detector = XLALUserVarWasSet ( &CLA->detector ); CHAR *IFO; if ( !have_IFO && !have_detector ) { fprintf (stderr, "\nNeed to specify the detector (--IFO) !\n\n"); ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } if ( have_IFO ) IFO = CLA->IFO; else IFO = CLA->detector; if ( ( Detector = XLALGetSiteInfo ( IFO ) ) == NULL ) { ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } } /* ---------- load ephemeris-files ---------- */ { edat = XLALInitBarycenter( CLA->ephemEarth, CLA->ephemSun ); if ( !edat ) { XLALPrintError("XLALInitBarycenter failed: could not load Earth ephemeris '%s' and Sun ephemeris '%s'\n", CLA->ephemEarth, CLA->ephemSun); ABORT (status, SEMIANALYTIC_EINPUT, SEMIANALYTIC_MSGEINPUT); } } /* ephemeris-reading */ /* ---------- calculate AM-coefficients ---------- */ /* prepare call to barycentering routing */ baryinput.site.location[0] = Detector->location[0]/LAL_C_SI; baryinput.site.location[1] = Detector->location[1]/LAL_C_SI; baryinput.site.location[2] = Detector->location[2]/LAL_C_SI; baryinput.alpha = CLA->Alpha; baryinput.delta = CLA->Delta; baryinput.dInv = 0.e0; /* amParams structure to compute a(t) and b(t) */ /* Allocate space for amParams stucture */ /* Here, amParams->das is the Detector and Source info */ amParams = (AMCoeffsParams *)LALMalloc(sizeof(AMCoeffsParams)); amParams->das = (LALDetAndSource *)LALMalloc(sizeof(LALDetAndSource)); amParams->das->pSource = (LALSource *)LALMalloc(sizeof(LALSource)); /* Fill up AMCoeffsParams structure */ amParams->baryinput = &baryinput; amParams->earth = &earth; amParams->edat = edat; amParams->das->pDetector = Detector; amParams->das->pSource->equatorialCoords.system = COORDINATESYSTEM_EQUATORIAL; amParams->das->pSource->equatorialCoords.longitude = CLA->Alpha; amParams->das->pSource->equatorialCoords.latitude = CLA->Delta; amParams->das->pSource->orientation = 0.0; amParams->polAngle = amParams->das->pSource->orientation ; /* These two have to be the same!!!!!!!!!*/ /* Allocate space for AMCoeffs */ XLAL_INIT_MEM(amc); TRY ( LALSCreateVector(status->statusPtr, &(amc.a), (UINT4) CLA->nTsft), status); TRY ( LALSCreateVector(status->statusPtr, &(amc.b), (UINT4) CLA->nTsft), status); /* Mid point of each SFT */ midTS = (LIGOTimeGPS *)LALCalloc(CLA->nTsft,sizeof(LIGOTimeGPS)); for(k=0; k < CLA->nTsft; k++) { /* FIXME: loss of precision; consider midTS[k] = timestamps->data[k]; XLALGPSAdd(&midTS[k], 0.5*CLA->Tsft); */ REAL8 teemp=0.0; teemp = XLALGPSGetREAL8(&(timestamps->data[k])); teemp += 0.5*CLA->Tsft; XLALGPSSetREAL8(&(midTS[k]), teemp); } TRY ( LALComputeAM(status->statusPtr, &amc, midTS, amParams), status); /* Free memory */ XLALDestroyTimestampVector ( timestamps); LALFree(midTS); LALFree(Detector); XLALDestroyEphemerisData(edat); LALFree(amParams->das->pSource); LALFree(amParams->das); LALFree(amParams); DETATCHSTATUSPTR (status); RETURN(status); } /* ParseUserInput() */
/** * \author Creighton, T. D. * * \brief Computes the response of a detector to a coherent gravitational wave. * * This function takes a quasiperiodic gravitational waveform given in * <tt>*signal</tt>, and estimates the corresponding response of the * detector whose position, orientation, and transfer function are * specified in <tt>*detector</tt>. The result is stored in * <tt>*output</tt>. * * The fields <tt>output-\>epoch</tt>, <tt>output->deltaT</tt>, and * <tt>output-\>data</tt> must already be set, in order to specify the time * period and sampling rate for which the response is required. If * <tt>output-\>f0</tt> is nonzero, idealized heterodyning is performed (an * amount \f$2\pi f_0(t-t_0)\f$ is subtracted from the phase before computing * the sinusoid, where \f$t_0\f$ is the heterodyning epoch defined in * \c detector). For the input signal, <tt>signal-\>h</tt> is ignored, * and the signal is treated as zero at any time for which either * <tt>signal-\>a</tt> or <tt>signal-\>phi</tt> is not defined. * * This routine will convert <tt>signal-\>position</tt> to equatorial * coordinates, if necessary. * * ### Algorithm ### * * The routine first accounts for the time delay between the detector and * the solar system barycentre, based on the detector position * information stored in <tt>*detector</tt> and the propagation direction * specified in <tt>*signal</tt>. Values of the propagation delay are * precomuted at fixed intervals and stored in a table, with the * intervals \f$\Delta T_\mathrm{delay}\f$ chosen such that the value * interpolated from adjacent table entries will never differ from the * true value by more than some timing error \f$\sigma_T\f$. This implies * that: * \f[ * \Delta T_\mathrm{delay} \leq \sqrt{ * \frac{8\sigma_T}{\max\{a/c\}} } \; , * \f] * where \f$\max\{a/c\}=1.32\times10^{-10}\mathrm{s}^{-1}\f$ is the maximum * acceleration of an Earth-based detector in the barycentric frame. The * total propagation delay also includes Einstein and Shapiro delay, but * these are more slowly varying and thus do not constrain the table * spacing. At present, a 400s table spacing is hardwired into the code, * implying \f$\sigma_T\approx3\mu\f$s, comparable to the stated accuracy of * <tt>LALBarycenter()</tt>. * * Next, the polarization response functions of the detector * \f$F_{+,\times}(\alpha,\delta)\f$ are computed for every 10 minutes of the * signal's duration, using the position of the source in <tt>*signal</tt>, * the detector information in <tt>*detector</tt>, and the function * <tt>LALComputeDetAMResponseSeries()</tt>. Subsequently, the * polarization functions are estimated for each output sample by * interpolating these precomputed values. This guarantees that the * interpolated value is accurate to \f$\sim0.1\%\f$. * * Next, the frequency response of the detector is estimated in the * quasiperiodic limit as follows: * <ul> * <li> At each sample point in <tt>*output</tt>, the propagation delay is * computed and added to the sample time, and the instantaneous * amplitudes \f$A_1\f$, \f$A_2\f$, frequency \f$f\f$, phase \f$\phi\f$, and polarization * shift \f$\Phi\f$ are found by interpolating the nearest values in * <tt>signal-\>a</tt>, <tt>signal-\>f</tt>, <tt>signal-\>phi</tt>, and * <tt>signal-\>shift</tt>, respectively. If <tt>signal-\>f</tt> is not * defined at that point in time, then \f$f\f$ is estimated by differencing * the two nearest values of \f$\phi\f$, as \f$f\approx\Delta\phi/2\pi\Delta * t\f$. If <tt>signal-\>shift</tt> is not defined, then \f$\Phi\f$ is treated as * zero.</li> * <li> The complex transfer function of the detector the frequency \f$f\f$ * is found by interpolating <tt>detector-\>transfer</tt>. The amplitude of * the transfer function is multiplied with \f$A_1\f$ and \f$A_2\f$, and the * phase of the transfer function is added to \f$\phi\f$,</li> * <li> The plus and cross contributions \f$o_+\f$, \f$o_\times\f$ to the * detector output are computed as in \eqref{eq_quasiperiodic_hpluscross} * of \ref PulsarSimulateCoherentGW_h, but * using the response-adjusted amplitudes and phase.</li> * <li> The final detector response \f$o\f$ is computed as * \f$o=(o_+F_+)+(o_\times F_\times)\f$.</li> * </ul> * * ### A note on interpolation: ### * * Much of the computational work in this routine involves interpolating * various time series to find their values at specific output times. * The algorithm is summarized below. * * Let \f$A_j = A( t_A + j\Delta t_A )\f$ be a sampled time series, which we * want to resample at new (output) time intervals \f$t_k = t_0 + k\Delta * t\f$. We first precompute the following quantities: * \f{eqnarray}{ * t_\mathrm{off} & = & \frac{t_0-t_A}{\Delta t_A} \; , \\ * dt & = & \frac{\Delta t}{\Delta t_A} \; . * \f} * Then, for each output sample time \f$t_k\f$, we compute: * \f{eqnarray}{ * t & = & t_\mathrm{off} + k \times dt \; , \\ * j & = & \lfloor t \rfloor \; , \\ * f & = & t - j \; , * \f} * where \f$\lfloor x\rfloor\f$ is the "floor" function; i.e.\ the largest * integer \f$\leq x\f$. The time series sampled at the new time is then: * \f[ * A(t_k) = f \times A_{j+1} + (1-f) \times A_j \; . * \f] * * ### Notes ### * * The major computational hit in this routine comes from computing the * sine and cosine of the phase angle in * \eqref{eq_quasiperiodic_hpluscross} of * \ref PulsarSimulateCoherentGW_h. For better online performance, these can * be replaced by other (approximate) trig functions. Presently the code * uses the native \c libm functions by default, or the function * <tt>sincosp()</tt> in \c libsunmath \e if this function is * available \e and the constant \c ONLINE is defined. * Differences at the level of 0.01 begin to appear only for phase * arguments greater than \f$10^{14}\f$ or so (corresponding to over 500 * years between phase epoch and observation time for frequencies of * around 1kHz). * * To activate this feature, be sure that <tt>sunmath.h</tt> and * \c libsunmath are on your system, and add <tt>-DONLINE</tt> to the * <tt>--with-extra-cppflags</tt> configuration argument. In future this * flag may be used to turn on other efficient trig algorithms on other * (non-Solaris) platforms. * */ void LALPulsarSimulateCoherentGW( LALStatus *stat, REAL4TimeSeries *output, PulsarCoherentGW *CWsignal, PulsarDetectorResponse *detector ) { INT4 i, n; /* index over output->data, and its final value */ INT4 nMax; /* used to store limits on index ranges */ INT4 fInit, fFinal; /* index range for which CWsignal->f is defined */ INT4 shiftInit, shiftFinal; /* ditto for CWsignal->shift */ UINT4 dtDelayBy2; /* delay table half-interval (s) */ UINT4 dtPolBy2; /* polarization table half-interval (s) */ REAL4 *outData; /* pointer to output data */ REAL8 delayMin, delayMax; /* min and max values of time delay */ SkyPosition source; /* source sky position */ BOOLEAN transfer; /* 1 if transfer function is specified */ BOOLEAN fFlag = 0; /* 1 if frequency left detector->transfer range */ BOOLEAN pFlag = 0; /* 1 if frequency was estimated from phase */ /* get delay table and polaristion tables half intervals if defined (>0) in the PulsarCoherentGW structure otherwise default to 400s for dtDelatBy2 and 300s for dtPolBy2 */ dtDelayBy2 = CWsignal->dtDelayBy2 > 0 ? CWsignal->dtDelayBy2 : 400; dtPolBy2 = CWsignal->dtPolBy2 > 0 ? CWsignal->dtPolBy2 : 300; /* The amplitude, frequency, phase, polarization shift, polarization response, and propagation delay are stored in arrays that must be interpolated. For a quantity x, we define a pointer xData to the data array. At some time t measured in units of output->deltaT, the interpolation point in xData is given by ( xOff + t*xDt ), where xOff is an offset and xDt is a relative sampling rate. */ LALDetAMResponseSeries polResponse; REAL8Vector *delay = NULL; REAL4 *aData, *fData, *shiftData, *plusData, *crossData; REAL8 *phiData, *delayData; REAL8 aOff, fOff, phiOff, shiftOff, polOff, delayOff; REAL8 aDt, fDt, phiDt, shiftDt, polDt, delayDt; /* Frequencies in the detector transfer function are interpolated similarly, except everything is normalized with respect to detector->transfer->deltaF. */ REAL4Vector *aTransfer = NULL; REAL4Vector *phiTransfer = NULL; REAL4Vector *phiTemp = NULL; REAL4 *aTransData = NULL, *phiTransData = NULL; REAL8 f0 = 1.0; REAL8 phiFac = 1.0, fFac = 1.0; /* Heterodyning phase factor LAL_TWOPI*output->f0*output->deltaT, and phase offset at the start of the series LAL_TWOPI*output->f0*(time offset). */ REAL8 heteroFac, phi0; /* Variables required by the TCENTRE() macro, above. */ REAL8 realIndex; INT4 intIndex; REAL8 indexFrac; INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter structures and their fields exist. */ ASSERT( CWsignal, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( !( CWsignal->a ) ) { ABORT( stat, SIMULATECOHERENTGWH_ESIG, SIMULATECOHERENTGWH_MSGESIG ); } ASSERT( CWsignal->a->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->a->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( !( CWsignal->phi ) ) { ABORT( stat, SIMULATECOHERENTGWH_ESIG, SIMULATECOHERENTGWH_MSGESIG ); } ASSERT( CWsignal->phi->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->phi->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( CWsignal->f ) { ASSERT( CWsignal->f->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->f->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } if ( CWsignal->shift ) { ASSERT( CWsignal->shift->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( CWsignal->shift->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } ASSERT( detector, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); if ( ( transfer = ( detector->transfer != NULL ) ) ) { ASSERT( detector->transfer->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( detector->transfer->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); } ASSERT( output, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( output->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); ASSERT( output->data->data, stat, SIMULATECOHERENTGWH_ENUL, SIMULATECOHERENTGWH_MSGENUL ); /* Check dimensions of amplitude array. */ ASSERT( CWsignal->a->data->vectorLength == 2, stat, SIMULATECOHERENTGWH_EDIM, SIMULATECOHERENTGWH_MSGEDIM ); /* Make sure we never divide by zero. */ ASSERT( CWsignal->a->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); ASSERT( CWsignal->phi->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); aDt = output->deltaT / CWsignal->a->deltaT; phiDt = output->deltaT / CWsignal->phi->deltaT; ASSERT( aDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); ASSERT( phiDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); if ( CWsignal->f ) { ASSERT( CWsignal->f->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); fDt = output->deltaT / CWsignal->f->deltaT; ASSERT( fDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } else fDt = 0.0; if ( CWsignal->shift ) { ASSERT( CWsignal->shift->deltaT != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); shiftDt = output->deltaT / CWsignal->shift->deltaT; ASSERT( shiftDt != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } else shiftDt = 0.0; if ( transfer ) { ASSERT( detector->transfer->deltaF != 0.0, stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); fFac = 1.0 / detector->transfer->deltaF; phiFac = fFac / ( LAL_TWOPI*CWsignal->phi->deltaT ); f0 = detector->transfer->f0/detector->transfer->deltaF; } heteroFac = LAL_TWOPI*output->f0*output->deltaT; phi0 = (REAL8)( output->epoch.gpsSeconds - detector->heterodyneEpoch.gpsSeconds ); phi0 += 0.000000001*(REAL8)( output->epoch.gpsNanoSeconds - detector->heterodyneEpoch.gpsNanoSeconds ); phi0 *= LAL_TWOPI*output->f0; if ( phi0 > 1.0/LAL_REAL8_EPS ) { LALWarning( stat, "REAL8 arithmetic is not sufficient to maintain" " heterodyne phase to within a radian." ); } /* Check units on input, and set units on output. */ { ASSERT( XLALUnitCompare( &(CWsignal->f->sampleUnits), &lalHertzUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); ASSERT( XLALUnitCompare( &(CWsignal->phi->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); if( CWsignal->shift ) { ASSERT( XLALUnitCompare( &(CWsignal->shift->sampleUnits), &lalDimensionlessUnit ) == 0, stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); } if ( transfer ) { if ( XLALUnitMultiply( &(output->sampleUnits), &(CWsignal->a->sampleUnits), &(detector->transfer->sampleUnits) ) == NULL ) { ABORT( stat, SIMULATECOHERENTGWH_EUNIT, SIMULATECOHERENTGWH_MSGEUNIT ); } } else { output->sampleUnits = CWsignal->a->sampleUnits; } snprintf( output->name, LALNameLength, "response to %s", CWsignal->a->name ); } /* Define temporary variables to access the data of CWsignal->a, CWsignal->f, and CWsignal->phi. */ aData = CWsignal->a->data->data; INT4 aLen = CWsignal->a->data->length * CWsignal->a->data->vectorLength; phiData = CWsignal->phi->data->data; INT4 phiLen = CWsignal->phi->data->length; outData = output->data->data; INT4 fLen=0, shiftLen=0; if ( CWsignal->f ) { fData = CWsignal->f->data->data; fLen = CWsignal->f->data->length; } else { fData = NULL; } if ( CWsignal->shift ) { shiftData = CWsignal->shift->data->data; shiftLen = CWsignal->shift->data->length; } else { shiftData = NULL; } /* Convert source position to equatorial coordinates, if required. */ if ( detector->site ) { source = CWsignal->position; if ( source.system != COORDINATESYSTEM_EQUATORIAL ) { ConvertSkyParams params; /* parameters for conversion */ EarthPosition location; /* location of detector */ params.gpsTime = &( output->epoch ); params.system = COORDINATESYSTEM_EQUATORIAL; if ( source.system == COORDINATESYSTEM_HORIZON ) { params.zenith = &( location.geodetic ); location.x = detector->site->location[0]; location.y = detector->site->location[1]; location.z = detector->site->location[2]; TRY( LALGeocentricToGeodetic( stat->statusPtr, &location ), stat ); } TRY( LALConvertSkyCoordinates( stat->statusPtr, &source, &source, ¶ms ), stat ); } } /* Generate the table of propagation delays. dtDelayBy2 = (UINT4)( 38924.9/sqrt( output->f0 + 1.0/output->deltaT ) ); */ delayDt = output->deltaT/( 2.0*dtDelayBy2 ); nMax = (UINT4)( output->data->length*delayDt ) + 3; TRY( LALDCreateVector( stat->statusPtr, &delay, nMax ), stat ); delayData = delay->data; /* Compute delay from solar system barycentre. */ if ( detector->site && detector->ephemerides ) { LIGOTimeGPS gpsTime; /* detector time when we compute delay */ EarthState state; /* Earth position info at that time */ BarycenterInput input; /* input structure to LALBarycenter() */ EmissionTime emit; /* output structure from LALBarycenter() */ /* Arrange nested pointers, and set initial values. */ gpsTime = input.tgps = output->epoch; gpsTime.gpsSeconds -= dtDelayBy2; input.tgps.gpsSeconds -= dtDelayBy2; input.site = *(detector->site); for ( i = 0; i < 3; i++ ) input.site.location[i] /= LAL_C_SI; input.alpha = source.longitude; input.delta = source.latitude; input.dInv = 0.0; delayMin = delayMax = 1.1*LAL_AU_SI/( LAL_C_SI*output->deltaT ); delayMax *= -1; /* Compute table. */ for ( i = 0; i < nMax; i++ ) { REAL8 tDelay; /* propagation time */ LALBarycenterEarth( stat->statusPtr, &state, &gpsTime, detector->ephemerides ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ENDFAIL( stat ); LALBarycenter( stat->statusPtr, &emit, &input, &state ); BEGINFAIL( stat ) TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ENDFAIL( stat ); delayData[i] = tDelay = emit.deltaT/output->deltaT; if ( tDelay < delayMin ) delayMin = tDelay; if ( tDelay > delayMax ) delayMax = tDelay; gpsTime.gpsSeconds += 2*dtDelayBy2; input.tgps.gpsSeconds += 2*dtDelayBy2; } } /* No information from which to compute delays. */ else { LALInfo( stat, "Detector site and ephemerides absent; simulating hplus with no" " propagation delays" ); memset( delayData, 0, nMax*sizeof(REAL8) ); delayMin = delayMax = 0.0; } /* Generate the table of polarization response functions. */ polDt = output->deltaT/( 2.0*dtPolBy2 ); nMax = (UINT4)( output->data->length*polDt ) + 3; memset( &polResponse, 0, sizeof( LALDetAMResponseSeries ) ); polResponse.pPlus = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); polResponse.pCross = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); polResponse.pScalar = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ); if ( !polResponse.pPlus || !polResponse.pCross || !polResponse.pScalar ) { if ( polResponse.pPlus ) LALFree( polResponse.pPlus ); if ( polResponse.pCross ) LALFree( polResponse.pCross ); if ( polResponse.pScalar ) LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); ABORT( stat, SIMULATECOHERENTGWH_EMEM, SIMULATECOHERENTGWH_MSGEMEM ); } memset( polResponse.pPlus, 0, sizeof(REAL4TimeSeries) ); memset( polResponse.pCross, 0, sizeof(REAL4TimeSeries) ); memset( polResponse.pScalar, 0, sizeof(REAL4TimeSeries) ); LALSCreateVector( stat->statusPtr, &( polResponse.pPlus->data ), nMax ); BEGINFAIL( stat ) { LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); LALSCreateVector( stat->statusPtr, &( polResponse.pCross->data ), nMax ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); LALSCreateVector( stat->statusPtr, &( polResponse.pScalar->data ), nMax ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pCross->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); plusData = polResponse.pPlus->data->data; crossData = polResponse.pCross->data->data; INT4 plusLen = polResponse.pPlus->data->length; INT4 crossLen = polResponse.pCross->data->length; if ( plusLen != crossLen ) { XLALPrintError ("plusLen = %d != crossLen = %d\n", plusLen, crossLen ); ABORT ( stat, SIMULATECOHERENTGWH_EBAD, SIMULATECOHERENTGWH_MSGEBAD ); } if ( detector->site ) { LALSource polSource; /* position and polarization angle */ LALDetAndSource input; /* response input structure */ LALTimeIntervalAndNSample params; /* response parameter structure */ /* Arrange nested pointers, and set initial values. */ polSource.equatorialCoords = source; polSource.orientation = (REAL8)( CWsignal->psi ); input.pSource = &polSource; input.pDetector = detector->site; params.epoch = output->epoch; params.epoch.gpsSeconds -= dtPolBy2; params.deltaT = 2.0*dtPolBy2; params.nSample = nMax; /* Compute table of responses. */ LALComputeDetAMResponseSeries( stat->statusPtr, &polResponse, &input, ¶ms ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pPlus->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pCross->data ) ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &( polResponse.pScalar->data ) ), stat ); LALFree( polResponse.pPlus ); LALFree( polResponse.pCross ); LALFree( polResponse.pScalar ); TRY( LALDDestroyVector( stat->statusPtr, &delay ), stat ); } ENDFAIL( stat ); } else {
int main( int argc, char *argv[] ) { static LALStatus status; StochasticOmegaGWParameters parameters; REAL4FrequencySeries omegaGW; UINT4 i; REAL4 omega, f; INT4 code; /* define valid parameters */ parameters.alpha = STOCHASTICOMEGAGWTESTC_ALPHA; parameters.fRef = STOCHASTICOMEGAGWTESTC_FREF; parameters.omegaRef = STOCHASTICOMEGAGWTESTC_OMEGAREF; parameters.length = STOCHASTICOMEGAGWTESTC_LENGTH; parameters.f0 = STOCHASTICOMEGAGWTESTC_F0; parameters.deltaF = STOCHASTICOMEGAGWTESTC_DELTAF; omegaGW.data = NULL; #ifndef LAL_NDEBUG REAL4FrequencySeries dummyOutput; dummyOutput.data = NULL; #endif ParseOptions( argc, argv ); LALSCreateVector(&status, &(omegaGW.data), STOCHASTICOMEGAGWTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } /* TEST INVALID DATA HERE ------------------------------------------ */ #ifndef LAL_NDEBUG if ( ! lalNoDebug ) { /* test behavior for null pointer to real frequency series for output */ LALStochasticOmegaGW(&status, NULL, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: null pointer to output series results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to parameter structure */ LALStochasticOmegaGW(&status, &omegaGW, NULL); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: null pointer to parameter structure results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* test behavior for null pointer to data member of real frequency series for output */ LALStochasticOmegaGW(&status, &dummyOutput, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: null pointer to data member of output series results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* Create a vector for testing null data-data pointer */ LALSCreateVector(&status, &(dummyOutput.data), STOCHASTICOMEGAGWTESTC_LENGTH); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } REAL4 *tempPtr; tempPtr = dummyOutput.data->data; dummyOutput.data->data = NULL; /* test behavior for null pointer to data member of data member of real frequency series for output */ LALStochasticOmegaGW(&status, &dummyOutput, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENULLPTR, STOCHASTICCROSSCORRELATIONH_MSGENULLPTR, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: null pointer to data member of data member of output series results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENULLPTR); /* clean up */ dummyOutput.data->data = tempPtr; LALSDestroyVector(&status, &(dummyOutput.data)); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } /* test behavior for length parameter equal to zero */ parameters.length = 0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EZEROLEN, STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero length parameter results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEZEROLEN); /* assign valid length parameter */ parameters.length = STOCHASTICOMEGAGWTESTC_LENGTH; /* test behavior for frequency spacing less than or equal to zero */ parameters.deltaF = -1; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative frequency spacing results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF); parameters.deltaF = 0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSDELTAF, STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero frequency spacing results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSDELTAF); /* assign valid frequency spacing */ parameters.deltaF = STOCHASTICOMEGAGWTESTC_DELTAF; } #endif /* LAL_NDEBUG */ /* test behavior for negative start frequency */ parameters.f0 = -20.0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENEGFMIN, STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative start frequency results in error:\n \"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENEGFMIN); /* reassign valid start frequency */ parameters.f0 = STOCHASTICOMEGAGWTESTC_F0; /* test behavior for length of data member of real frequency series for output not equal to length specified in input parameters */ parameters.length += 1; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EMMLEN, STOCHASTICCROSSCORRELATIONH_MSGEMMLEN, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: mismatch between length of output series and length parameter results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEMMLEN); /* reassign valid length to data member of dummy output */ parameters.length -= 1; /* test behavior for fRef < deltaf */ parameters.fRef = 0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_EOORFREF, STOCHASTICCROSSCORRELATIONH_MSGEOORFREF, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero reference frequency results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGEOORFREF); parameters.fRef = STOCHASTICOMEGAGWTESTC_FREF; /* test behavior for omegaRef <=0 */ parameters.omegaRef = -1.0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSOMEGA, STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: negative amplitude parameter results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA); parameters.omegaRef = 0.0; LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status, STOCHASTICCROSSCORRELATIONH_ENONPOSOMEGA, STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA, STOCHASTICOMEGAGWTESTC_ECHK, STOCHASTICOMEGAGWTESTC_MSGECHK) ) ) { return code; } printf(" PASS: zero amplitude parameter results in error: \n\"%s\"\n", STOCHASTICCROSSCORRELATIONH_MSGENONPOSOMEGA); parameters.omegaRef = STOCHASTICOMEGAGWTESTC_OMEGAREF; /* TEST VALID DATA HERE -------------------------------------------- */ /* generate omegaGW */ LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status,0, "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } /* test values */ for (i=0; i<STOCHASTICOMEGAGWTESTC_LENGTH; ++i) { f = i * STOCHASTICOMEGAGWTESTC_DELTAF; omega = STOCHASTICOMEGAGWTESTC_OMEGAREF * pow(f/STOCHASTICOMEGAGWTESTC_FREF,STOCHASTICOMEGAGWTESTC_ALPHA); if (optVerbose) { printf("Omega(%f Hz)=%g, should be %g\n", f, omegaGW.data->data[i], omega); } if ( (omegaGW.data->data[i] - omega) && abs((omegaGW.data->data[i] - omega)/omega) > STOCHASTICOMEGAGWTESTC_TOL ) { printf(" FAIL: Valid data test #1 (alpha=%f)\n",STOCHASTICOMEGAGWTESTC_ALPHA); return STOCHASTICOMEGAGWTESTC_EFLS; } } printf(" PASS: Valid data test #1 (alpha=%f)\n",STOCHASTICOMEGAGWTESTC_ALPHA); /* change parameters */ parameters.alpha = 0.0; /* generate omegaGW */ LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status,0, "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } /* test values */ for (i=0; i<STOCHASTICOMEGAGWTESTC_LENGTH; ++i) { f = i * STOCHASTICOMEGAGWTESTC_DELTAF; if (optVerbose) { printf("Omega(%f Hz)=%g, should be %g\n", f, omegaGW.data->data[i], STOCHASTICOMEGAGWTESTC_OMEGAREF); } if ( abs(omegaGW.data->data[i] - STOCHASTICOMEGAGWTESTC_OMEGAREF) / STOCHASTICOMEGAGWTESTC_OMEGAREF > STOCHASTICOMEGAGWTESTC_TOL ) { printf(" FAIL: Valid data test #2 (alpha=0)\n"); return STOCHASTICOMEGAGWTESTC_EFLS; } } printf(" PASS: Valid data test #2 (alpha=0)\n"); /* clean up valid data */ LALSDestroyVector(&status, &(omegaGW.data)); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EFLS, STOCHASTICOMEGAGWTESTC_MSGEFLS) ) ) { return code; } LALCheckMemoryLeaks(); printf("PASS: all tests\n"); if (optFile[0]) { parameters.alpha = optAlpha; parameters.length = optLength; parameters.deltaF = optDeltaF; parameters.f0 = optF0; parameters.omegaRef = optOmegaR; parameters.fRef = optFR; LALSCreateVector(&status, &(omegaGW.data), optLength); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EUSE, STOCHASTICOMEGAGWTESTC_MSGEUSE) ) ) { return code; } LALStochasticOmegaGW(&status, &omegaGW, ¶meters); if ( ( code = CheckStatus(&status,0, "", STOCHASTICOMEGAGWTESTC_EUSE, STOCHASTICOMEGAGWTESTC_MSGEUSE) ) ) { return code; } LALSPrintFrequencySeries( &omegaGW, optFile ); printf("=== Stochastic Gravitational-wave Spectrum Written to File %s ===\n", optFile); LALSDestroyVector(&status, &(omegaGW.data)); if ( ( code = CheckStatus(&status, 0 , "", STOCHASTICOMEGAGWTESTC_EUSE, STOCHASTICOMEGAGWTESTC_MSGEUSE) ) ) { return code; } LALCheckMemoryLeaks(); } return STOCHASTICOMEGAGWTESTC_ENOM; }
void LALRingInjectSignals( LALStatus *stat, REAL4TimeSeries *series, SimRingdownTable *injections, COMPLEX8FrequencySeries *resp, INT4 calType ) { UINT4 k; INT4 injStartTime; INT4 injStopTime; DetectorResponse detector; COMPLEX8Vector *unity = NULL; CoherentGW waveform; RingParamStruc ringParam; REAL4TimeSeries signalvec; SimRingdownTable *simRingdown=NULL; LALDetector *tmpDetector=NULL /*,*nullDetector=NULL*/; COMPLEX8FrequencySeries *transfer = NULL; INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* set up start and end of injection zone TODO: fix this hardwired 10 */ injStartTime = series->epoch.gpsSeconds - 10; injStopTime = series->epoch.gpsSeconds + 10 + (INT4)(series->data->length * series->deltaT); /* *compute the transfer function */ /* allocate memory and copy the parameters describing the freq series */ memset( &detector, 0, sizeof( DetectorResponse ) ); transfer = (COMPLEX8FrequencySeries *) LALCalloc( 1, sizeof(COMPLEX8FrequencySeries) ); if ( ! transfer ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } memcpy( &(transfer->epoch), &(resp->epoch), sizeof(LIGOTimeGPS) ); transfer->f0 = resp->f0; transfer->deltaF = resp->deltaF; tmpDetector = detector.site = (LALDetector *) LALMalloc( sizeof(LALDetector) ); /* set the detector site */ switch ( series->name[0] ) { case 'H': *(detector.site) = lalCachedDetectors[LALDetectorIndexLHODIFF]; LALWarning( stat, "computing waveform for Hanford." ); break; case 'L': *(detector.site) = lalCachedDetectors[LALDetectorIndexLLODIFF]; LALWarning( stat, "computing waveform for Livingston." ); break; default: LALFree( detector.site ); detector.site = NULL; tmpDetector = NULL; LALWarning( stat, "Unknown detector site, computing plus mode " "waveform with no time delay" ); break; } /* set up units for the transfer function */ if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { ABORTXLAL(stat); } /* invert the response function to get the transfer function */ LALCCreateVector( stat->statusPtr, &( transfer->data ), resp->data->length ); CHECKSTATUSPTR( stat ); LALCCreateVector( stat->statusPtr, &unity, resp->data->length ); CHECKSTATUSPTR( stat ); for ( k = 0; k < resp->data->length; ++k ) { unity->data[k] = 1.0; } LALCCVectorDivide( stat->statusPtr, transfer->data, unity, resp->data ); CHECKSTATUSPTR( stat ); LALCDestroyVector( stat->statusPtr, &unity ); CHECKSTATUSPTR( stat ); /* Set up a time series to hold signal in ADC counts */ signalvec.deltaT = series->deltaT; if ( ( signalvec.f0 = series->f0 ) != 0 ) { ABORT( stat, GENERATERINGH_EMEM, GENERATERINGH_MSGEMEM ); } signalvec.sampleUnits = lalADCCountUnit; signalvec.data=NULL; LALSCreateVector( stat->statusPtr, &(signalvec.data), series->data->length ); CHECKSTATUSPTR( stat ); /* loop over list of waveforms and inject into data stream */ simRingdown = injections; while ( simRingdown ) { /* only do the work if the ring is in injection zone */ if( (injStartTime - simRingdown->geocent_start_time.gpsSeconds) * (injStopTime - simRingdown->geocent_start_time.gpsSeconds) > 0 ) { simRingdown = simRingdown->next; continue; } /* set the ring params */ ringParam.deltaT = series->deltaT; if( !( strcmp( simRingdown->coordinates, "HORIZON" ) ) ) { ringParam.system = COORDINATESYSTEM_HORIZON; } else if ( !( strcmp( simRingdown->coordinates, "ZENITH" ) ) ) { /* set coordinate system for completeness */ ringParam.system = COORDINATESYSTEM_EQUATORIAL; detector.site = NULL; } else if ( !( strcmp( simRingdown->coordinates, "GEOGRAPHIC" ) ) ) { ringParam.system = COORDINATESYSTEM_GEOGRAPHIC; } else if ( !( strcmp( simRingdown->coordinates, "EQUATORIAL" ) ) ) { ringParam.system = COORDINATESYSTEM_EQUATORIAL; } else if ( !( strcmp( simRingdown->coordinates, "ECLIPTIC" ) ) ) { ringParam.system = COORDINATESYSTEM_ECLIPTIC; } else if ( !( strcmp( simRingdown->coordinates, "GALACTIC" ) ) ) { ringParam.system = COORDINATESYSTEM_GALACTIC; } else ringParam.system = COORDINATESYSTEM_EQUATORIAL; /* generate the ring */ memset( &waveform, 0, sizeof(CoherentGW) ); LALGenerateRing( stat->statusPtr, &waveform, series, simRingdown, &ringParam ); CHECKSTATUSPTR( stat ); /* print the waveform to a file */ if ( 0 ) { FILE *fp; char fname[512]; UINT4 jj, kplus, kcross; snprintf( fname, sizeof(fname) / sizeof(*fname), "waveform-%d-%d-%s.txt", simRingdown->geocent_start_time.gpsSeconds, simRingdown->geocent_start_time.gpsNanoSeconds, simRingdown->waveform ); fp = fopen( fname, "w" ); for( jj = 0, kplus = 0, kcross = 1; jj < waveform.phi->data->length; ++jj, kplus += 2, kcross +=2 ) { fprintf(fp, "%d %e %e %le %e\n", jj, waveform.a->data->data[kplus], waveform.a->data->data[kcross], waveform.phi->data->data[jj], waveform.f->data->data[jj]); } fclose( fp ); } /* end */ #if 0 fprintf( stderr, "a->epoch->gpsSeconds = %d\na->epoch->gpsNanoSeconds = %d\n", waveform.a->epoch.gpsSeconds, waveform.a->epoch.gpsNanoSeconds ); fprintf( stderr, "phi->epoch->gpsSeconds = %d\nphi->epoch->gpsNanoSeconds = %d\n", waveform.phi->epoch.gpsSeconds, waveform.phi->epoch.gpsNanoSeconds ); fprintf( stderr, "f->epoch->gpsSeconds = %d\nf->epoch->gpsNanoSeconds = %d\n", waveform.f->epoch.gpsSeconds, waveform.f->epoch.gpsNanoSeconds ); #endif /* must set the epoch of signal since it's used by coherent GW */ signalvec.epoch = series->epoch; memset( signalvec.data->data, 0, signalvec.data->length * sizeof(REAL4) ); /* decide which way to calibrate the data; defaul to old way */ if( calType ) detector.transfer=NULL; else detector.transfer=transfer; /* convert this into an ADC signal */ LALSimulateCoherentGW( stat->statusPtr, &signalvec, &waveform, &detector ); CHECKSTATUSPTR( stat ); /* print the waveform to a file */ if ( 0 ) { FILE *fp; char fname[512]; UINT4 jj; snprintf( fname, sizeof(fname) / sizeof(*fname), "signal-%d-%d-%s.txt", simRingdown->geocent_start_time.gpsSeconds, simRingdown->geocent_start_time.gpsNanoSeconds, simRingdown->waveform ); fp = fopen( fname, "w" ); for( jj = 0; jj < signalvec.data->length; ++jj ) { fprintf( fp, "%d %le\n", jj, signalvec.data->data[jj] ); } fclose( fp ); } /* end */ #if 0 fprintf( stderr, "series.epoch->gpsSeconds = %d\nseries.epoch->gpsNanoSeconds = %d\n", series->epoch.gpsSeconds, series->epoch.gpsNanoSeconds ); fprintf( stderr, "signalvec->epoch->gpsSeconds = %d\nsignalvec->epoch->gpsNanoSeconds = %d\n", signalvec.epoch.gpsSeconds, signalvec.epoch.gpsNanoSeconds ); #endif /* if calibration using RespFilt */ if( calType == 1 ) XLALRespFilt(&signalvec, transfer); /* inject the signal into the data channel */ LALSSInjectTimeSeries( stat->statusPtr, series, &signalvec ); CHECKSTATUSPTR( stat ); /* free memory in coherent GW structure. TODO: fix this */ LALSDestroyVectorSequence( stat->statusPtr, &( waveform.a->data ) ); CHECKSTATUSPTR( stat ); LALSDestroyVector( stat->statusPtr, &( waveform.f->data ) ); CHECKSTATUSPTR( stat ); LALDDestroyVector( stat->statusPtr, &( waveform.phi->data ) ); CHECKSTATUSPTR( stat ); LALFree( waveform.a ); waveform.a = NULL; LALFree( waveform.f ); waveform.f = NULL; LALFree( waveform.phi ); waveform.phi = NULL; /* reset the detector site information in case it changed */ detector.site = tmpDetector; /* move on to next one */ simRingdown = simRingdown->next; } /* destroy the signal */ LALSDestroyVector( stat->statusPtr, &(signalvec.data) ); CHECKSTATUSPTR( stat ); LALCDestroyVector( stat->statusPtr, &( transfer->data ) ); CHECKSTATUSPTR( stat ); if ( detector.site ) LALFree( detector.site ); LALFree( transfer ); DETATCHSTATUSPTR( stat ); RETURN( stat ); }
void LALInspiralEccentricityForInjection( LALStatus *status, CoherentGW *waveform, InspiralTemplate *params, PPNParamStruc *ppnParams ) { INT4 count, i; REAL8 p, phiC; REAL4Vector a; /* pointers to generated amplitude data */ REAL4Vector ff; /* pointers to generated frequency data */ REAL8Vector phi; /* generated phase data */ CreateVectorSequenceIn in; CHAR message[256]; InspiralInit paramsInit; INITSTATUS(status); ATTATCHSTATUSPTR(status); /* Make sure parameter and waveform structures exist. */ ASSERT( params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT(waveform, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL); ASSERT( !( waveform->a ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT( !( waveform->f ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); ASSERT( !( waveform->phi ), status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL ); /* Compute some parameters*/ LALInspiralInit(status->statusPtr, params, ¶msInit); CHECKSTATUSPTR(status); if (paramsInit.nbins == 0){ DETATCHSTATUSPTR(status); RETURN (status); } /* Now we can allocate memory and vector for coherentGW structure*/ ff.length = paramsInit.nbins; a.length = 2* paramsInit.nbins; phi.length = paramsInit.nbins; ff.data = (REAL4 *) LALCalloc(paramsInit.nbins, sizeof(REAL4)); a.data = (REAL4 *) LALCalloc(2 * paramsInit.nbins, sizeof(REAL4)); phi.data= (REAL8 *) LALCalloc(paramsInit.nbins, sizeof(REAL8)); /* Check momory allocation is okay */ if (!(ff.data) || !(a.data) || !(phi.data)) { if (ff.data) LALFree(ff.data); if (a.data) LALFree(a.data); if (phi.data) LALFree(phi.data); ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } count = 0; /* Call the engine function */ LALInspiralEccentricityEngine(status->statusPtr, NULL, NULL, &a, &ff, &phi, &count, params); BEGINFAIL( status ) { LALFree(ff.data); LALFree(a.data); LALFree(phi.data); } ENDFAIL( status ); p = phi.data[count-1]; params->fFinal = ff.data[count-1]; sprintf(message, "cycles = %f", p/(double)LAL_TWOPI); LALInfo(status, message); if ( (INT4)(p/LAL_TWOPI) < 2 ){ sprintf(message, "The waveform has only %f cycles; we don't keep waveform with less than 2 cycles.", p/(double)LAL_TWOPI ); XLALPrintError("%s", message); LALWarning(status, message); } /*wrap the phase vector*/ phiC = phi.data[count-1] ; for (i = 0; i < count; i++) { phi.data[i] = phi.data[i] - phiC + ppnParams->phi; } /* Allocate the waveform structures. */ if ( ( waveform->a = (REAL4TimeVectorSeries *) LALCalloc(1, sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } if ( ( waveform->f = (REAL4TimeSeries *) LALCalloc(1, sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( waveform->a ); waveform->a = NULL; ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } if ( ( waveform->phi = (REAL8TimeSeries *) LALCalloc(1, sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( waveform->a ); waveform->a = NULL; LALFree( waveform->f ); waveform->f = NULL; ABORT( status, LALINSPIRALH_EMEM, LALINSPIRALH_MSGEMEM ); } in.length = (UINT4)(count); in.vectorLength = 2; LALSCreateVectorSequence( status->statusPtr, &( waveform->a->data ), &in ); CHECKSTATUSPTR(status); LALSCreateVector( status->statusPtr, &( waveform->f->data ), count); CHECKSTATUSPTR(status); LALDCreateVector( status->statusPtr, &( waveform->phi->data ), count ); CHECKSTATUSPTR(status); memcpy(waveform->f->data->data , ff.data, count*(sizeof(REAL4))); memcpy(waveform->a->data->data , a.data, 2*count*(sizeof(REAL4))); memcpy(waveform->phi->data->data ,phi.data, count*(sizeof(REAL8))); waveform->a->deltaT = waveform->f->deltaT = waveform->phi->deltaT = ppnParams->deltaT; waveform->a->sampleUnits = lalStrainUnit; waveform->f->sampleUnits = lalHertzUnit; waveform->phi->sampleUnits = lalDimensionlessUnit; waveform->position = ppnParams->position; waveform->psi = ppnParams->psi; snprintf( waveform->a->name, LALNameLength, "T1 inspiral amplitude" ); snprintf( waveform->f->name, LALNameLength, "T1 inspiral frequency" ); snprintf( waveform->phi->name, LALNameLength, "T1 inspiral phase" ); /* --- fill some output ---*/ ppnParams->tc = (double)(count-1) / params->tSampling ; ppnParams->length = count; ppnParams->dfdt = ((REAL4)(waveform->f->data->data[count-1] - waveform->f->data->data[count-2])) * ppnParams->deltaT; ppnParams->fStop = params->fFinal; ppnParams->termCode = GENERATEPPNINSPIRALH_EFSTOP; ppnParams->termDescription = GENERATEPPNINSPIRALH_MSGEFSTOP; ppnParams->fStart = ppnParams->fStartIn; /* --- free memory --- */ LALFree(ff.data); LALFree(a.data); LALFree(phi.data); DETATCHSTATUSPTR(status); RETURN (status); }
int main(void) { const INT4 Nsignal=16; const INT4 Nwindow=5; const INT4 Nfft=8; static LALStatus status; REAL4Vector *signalvec = NULL; CreateTimeFreqIn tfrIn; TimeFreqRep *tfr = NULL; TimeFreqParam *param = NULL; INT4 column; INT4 row; /*--------------------------------------------------------------------*/ LALSCreateVector(&status, &signalvec, Nsignal); for (column = 0; column < (INT4)signalvec->length; column++) signalvec->data[column]=(rand() % 10) / 2.0; /*--------------------------------------------------------------------*/ tfrIn.type=Spectrogram; tfrIn.fRow=Nfft; tfrIn.tCol=Nsignal; tfrIn.wlengthT=Nwindow; tfrIn.wlengthF=0; /*--------------------------------------------------------------------*/ LALCreateTimeFreqRep(&status, &tfr, &tfrIn); for (column = 0; column < tfr->tCol; column++) tfr->timeInstant[column]=column; LALCreateTimeFreqParam(&status, ¶m, &tfrIn); for (column = 0; column < (INT4)param->windowT->length; column++) param->windowT->data[column]=1.0; /*--------------------------------------------------------------------*/ LALTfrSp(&status,signalvec,tfr,param); REPORTSTATUS(&status); /*--------------------------------------------------------------------*/ printf("Signal:\n"); for (column= 0; column < (INT4)signalvec->length; column++) printf("%1.1f ",signalvec->data[column]); printf("\n\n"); printf("TFR:\n"); for (row= 0; row < (tfr->fRow/2+1); row++) { for (column= 0; column < tfr->tCol; column++) printf("%2.2f ",tfr->map[column][row]); printf("\n"); } /*--------------------------------------------------------------------*/ LALSDestroyVector(&status,&signalvec); LALDestroyTimeFreqRep(&status,&tfr); LALDestroyTimeFreqParam(&status,¶m); 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(int argc, char **argv) { /* Command-line parsing variables. */ int arg; /* command-line argument counter */ static LALStatus stat; /* status structure */ CHAR *sourcefile = NULL; /* name of sourcefile */ CHAR *respfile = NULL; /* name of respfile */ CHAR *infile = NULL; /* name of infile */ CHAR *outfile = NULL; /* name of outfile */ INT4 seed = 0; /* random number seed */ INT4 sec = SEC; /* ouput epoch.gpsSeconds */ INT4 nsec = NSEC; /* ouput epoch.gpsNanoSeconds */ INT4 npt = NPT; /* number of output points */ REAL8 dt = DT; /* output sampling interval */ REAL4 sigma = SIGMA; /* noise amplitude */ /* File reading variables. */ FILE *fp = NULL; /* generic file pointer */ BOOLEAN ok = 1; /* whether input format is correct */ UINT4 i; /* generic index over file lines */ INT8 epoch; /* epoch stored as an INT8 */ /* Other global variables. */ RandomParams *params = NULL; /* parameters of pseudorandom sequence */ DetectorResponse detector; /* the detector in question */ INT2TimeSeries output; /* detector ACD output */ /******************************************************************* * PARSE ARGUMENTS (arg stores the current position) * *******************************************************************/ /* Exit gracefully if no arguments were given. if ( argc <= 1 ) { INFO( "No testing done." ); return 0; } */ arg = 1; while ( arg < argc ) { /* Parse source file option. */ if ( !strcmp( argv[arg], "-s" ) ) { if ( argc > arg + 1 ) { arg++; sourcefile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse response file option. */ else if ( !strcmp( argv[arg], "-r" ) ) { if ( argc > arg + 1 ) { arg++; respfile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse input file option. */ else if ( !strcmp( argv[arg], "-i" ) ) { if ( argc > arg + 1 ) { arg++; infile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse noise output option. */ else if ( !strcmp( argv[arg], "-n" ) ) { if ( argc > arg + 5 ) { arg++; sec = atoi( argv[arg++] ); nsec = atoi( argv[arg++] ); npt = atoi( argv[arg++] ); dt = atof( argv[arg++] ); sigma = atof( argv[arg++] ); }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse output file option. */ else if ( !strcmp( argv[arg], "-o" ) ) { if ( argc > arg + 1 ) { arg++; outfile = argv[arg++]; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse debug level option. */ else if ( !strcmp( argv[arg], "-d" ) ) { if ( argc > arg + 1 ) { arg++; }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Parse random seed option. */ else if ( !strcmp( argv[arg], "-e" ) ) { if ( argc > arg + 1 ) { arg++; seed = atoi( argv[arg++] ); }else{ ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* Check for unrecognized options. */ else if ( argv[arg][0] == '-' ) { ERROR( BASICINJECTTESTC_EARG, BASICINJECTTESTC_MSGEARG, 0 ); LALPrintError( USAGE, *argv ); return BASICINJECTTESTC_EARG; } } /* End of argument parsing loop. */ /* Check for redundant or bad argument values. */ CHECKVAL( npt, 0, 2147483647 ); CHECKVAL( dt, 0, LAL_REAL4_MAX ); /******************************************************************* * SETUP * *******************************************************************/ /* Set up output, detector, and random parameter structures. */ output.data = NULL; detector.transfer = (COMPLEX8FrequencySeries *) LALMalloc( sizeof(COMPLEX8FrequencySeries) ); if ( !(detector.transfer) ) { ERROR( BASICINJECTTESTC_EMEM, BASICINJECTTESTC_MSGEMEM, 0 ); return BASICINJECTTESTC_EMEM; } detector.transfer->data = NULL; detector.site = NULL; SUB( LALCreateRandomParams( &stat, ¶ms, seed ), &stat ); /* Set up units. */ output.sampleUnits = lalADCCountUnit; if (XLALUnitDivide( &(detector.transfer->sampleUnits), &lalADCCountUnit, &lalStrainUnit ) == NULL) { return LAL_EXLAL; } /* Read response function. */ if ( respfile ) { REAL4VectorSequence *resp = NULL; /* response as vector sequence */ COMPLEX8Vector *response = NULL; /* response as complex vector */ COMPLEX8Vector *unity = NULL; /* vector of complex 1's */ if ( ( fp = fopen( respfile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, respfile ); return BASICINJECTTESTC_EFILE; } /* Read header. */ ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 ); I8ToLIGOTimeGPS( &( detector.transfer->epoch ), epoch ); ok &= ( fscanf( fp, "# f0 = %lf\n", &( detector.transfer->f0 ) ) == 1 ); ok &= ( fscanf( fp, "# deltaF = %lf\n", &( detector.transfer->deltaF ) ) == 1 ); if ( !ok ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, respfile ); return BASICINJECTTESTC_EINPUT; } /* Read and convert body to a COMPLEX8Vector. */ SUB( LALSReadVectorSequence( &stat, &resp, fp ), &stat ); fclose( fp ); if ( resp->vectorLength != 2 ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, respfile ); return BASICINJECTTESTC_EINPUT; } SUB( LALCCreateVector( &stat, &response, resp->length ), &stat ); memcpy( response->data, resp->data, 2*resp->length*sizeof(REAL4) ); SUB( LALSDestroyVectorSequence( &stat, &resp ), &stat ); /* Convert response function to a transfer function. */ SUB( LALCCreateVector( &stat, &unity, response->length ), &stat ); for ( i = 0; i < response->length; i++ ) { unity->data[i] = 1.0; } SUB( LALCCreateVector( &stat, &( detector.transfer->data ), response->length ), &stat ); SUB( LALCCVectorDivide( &stat, detector.transfer->data, unity, response ), &stat ); SUB( LALCDestroyVector( &stat, &response ), &stat ); SUB( LALCDestroyVector( &stat, &unity ), &stat ); } /* No response file, so generate a unit response. */ else { I8ToLIGOTimeGPS( &( detector.transfer->epoch ), EPOCH ); detector.transfer->f0 = 0.0; detector.transfer->deltaF = 1.5*FSTOP; SUB( LALCCreateVector( &stat, &( detector.transfer->data ), 2 ), &stat ); detector.transfer->data->data[0] = 1.0; detector.transfer->data->data[1] = 1.0; } /* Read input data. */ if ( infile ) { REAL4VectorSequence *input = NULL; /* input as vector sequence */ if ( ( fp = fopen( infile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, infile ); return BASICINJECTTESTC_EFILE; } /* Read header. */ ok &= ( fscanf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", &epoch ) == 1 ); I8ToLIGOTimeGPS( &( output.epoch ), epoch ); ok &= ( fscanf( fp, "# deltaT = %lf\n", &( output.deltaT ) ) == 1 ); if ( !ok ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, infile ); return BASICINJECTTESTC_EINPUT; } /* Read and convert body. */ SUB( LALSReadVectorSequence( &stat, &input, fp ), &stat ); fclose( fp ); if ( input->vectorLength != 1 ) { ERROR( BASICINJECTTESTC_EINPUT, BASICINJECTTESTC_MSGEINPUT, infile ); return BASICINJECTTESTC_EINPUT; } SUB( LALI2CreateVector( &stat, &( output.data ), input->length ), &stat ); for ( i = 0; i < input->length; i++ ) output.data->data[i] = (INT2)( input->data[i] ); SUB( LALSDestroyVectorSequence( &stat, &input ), &stat ); } /* No input file, so generate one randomly. */ else { output.epoch.gpsSeconds = sec; output.epoch.gpsNanoSeconds = nsec; output.deltaT = dt; SUB( LALI2CreateVector( &stat, &( output.data ), npt ), &stat ); if ( sigma == 0 ) { memset( output.data->data, 0, npt*sizeof(INT2) ); } else { REAL4Vector *deviates = NULL; /* unit Gaussian deviates */ SUB( LALSCreateVector( &stat, &deviates, npt ), &stat ); SUB( LALNormalDeviates( &stat, deviates, params ), &stat ); for ( i = 0; i < (UINT4)( npt ); i++ ) output.data->data[i] = (INT2) floor( sigma*deviates->data[i] + 0.5 ); SUB( LALSDestroyVector( &stat, &deviates ), &stat ); } } /******************************************************************* * INJECTION * *******************************************************************/ /* Open sourcefile. */ if ( sourcefile ) { if ( ( fp = fopen( sourcefile, "r" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, sourcefile ); return BASICINJECTTESTC_EFILE; } } /* For each line in the sourcefile... */ while ( ok ) { PPNParamStruc ppnParams; /* wave generation parameters */ REAL4 m1, m2, dist, inc, phic; /* unconverted parameters */ CoherentGW waveform; /* amplitude and phase structure */ REAL4TimeSeries signalvec; /* GW signal */ REAL8 time; /* length of GW signal */ CHAR timeCode; /* code for signal time alignment */ CHAR message[MSGLEN]; /* warning/info messages */ /* Read and convert input line. */ if ( sourcefile ) { ok &= ( fscanf( fp, "%c %" LAL_INT8_FORMAT " %f %f %f %f %f\n", &timeCode, &epoch, &m1, &m2, &dist, &inc, &phic ) == 7 ); ppnParams.mTot = m1 + m2; ppnParams.eta = m1*m2/( ppnParams.mTot*ppnParams.mTot ); ppnParams.d = dist*LAL_PC_SI*1000.0; ppnParams.inc = inc*LAL_PI/180.0; ppnParams.phi = phic*LAL_PI/180.0; } else { timeCode = 'i'; ppnParams.mTot = M1 + M2; ppnParams.eta = M1*M2/( ppnParams.mTot*ppnParams.mTot ); ppnParams.d = DIST; ppnParams.inc = INC; ppnParams.phi = PHIC; epoch = EPOCH; } if ( ok ) { /* Set up other parameter structures. */ ppnParams.epoch.gpsSeconds = ppnParams.epoch.gpsNanoSeconds = 0; ppnParams.position.latitude = ppnParams.position.longitude = 0.0; ppnParams.position.system = COORDINATESYSTEM_EQUATORIAL; ppnParams.psi = 0.0; ppnParams.fStartIn = FSTART; ppnParams.fStopIn = FSTOP; ppnParams.lengthIn = 0; ppnParams.ppn = NULL; ppnParams.deltaT = DELTAT; memset( &waveform, 0, sizeof(CoherentGW) ); /* Generate waveform at zero epoch. */ SUB( LALGeneratePPNInspiral( &stat, &waveform, &ppnParams ), &stat ); snprintf( message, MSGLEN, "%d: %s", ppnParams.termCode, ppnParams.termDescription ); INFO( message ); if ( ppnParams.dfdt > 2.0 ) { snprintf( message, MSGLEN, "Waveform sampling interval is too large:\n" "\tmaximum df*dt = %f", ppnParams.dfdt ); WARNING( message ); } /* Compute epoch for waveform. */ time = waveform.a->data->length*DELTAT; if ( timeCode == 'f' ) epoch -= (INT8)( 1000000000.0*time ); else if ( timeCode == 'c' ) epoch -= (INT8)( 1000000000.0*ppnParams.tc ); I8ToLIGOTimeGPS( &( waveform.a->epoch ), epoch ); waveform.f->epoch = waveform.phi->epoch = waveform.a->epoch; /* Generate and inject signal. */ signalvec.epoch = waveform.a->epoch; signalvec.epoch.gpsSeconds -= 1; signalvec.deltaT = output.deltaT/4.0; signalvec.f0 = 0; signalvec.data = NULL; time = ( time + 2.0 )/signalvec.deltaT; SUB( LALSCreateVector( &stat, &( signalvec.data ), (UINT4)time ), &stat ); SUB( LALSimulateCoherentGW( &stat, &signalvec, &waveform, &detector ), &stat ); SUB( LALSI2InjectTimeSeries( &stat, &output, &signalvec, params ), &stat ); SUB( LALSDestroyVectorSequence( &stat, &( waveform.a->data ) ), &stat ); SUB( LALSDestroyVector( &stat, &( waveform.f->data ) ), &stat ); SUB( LALDDestroyVector( &stat, &( waveform.phi->data ) ), &stat ); LALFree( waveform.a ); LALFree( waveform.f ); LALFree( waveform.phi ); SUB( LALSDestroyVector( &stat, &( signalvec.data ) ), &stat ); } /* If there is no source file, inject only one source. */ if ( !sourcefile ) ok = 0; } /* Input file is exhausted (or has a badly-formatted line ). */ if ( sourcefile ) fclose( fp ); /******************************************************************* * CLEANUP * *******************************************************************/ /* Print output file. */ if ( outfile ) { if ( ( fp = fopen( outfile, "w" ) ) == NULL ) { ERROR( BASICINJECTTESTC_EFILE, BASICINJECTTESTC_MSGEFILE, outfile ); return BASICINJECTTESTC_EFILE; } epoch = 1000000000LL*(INT8)( output.epoch.gpsSeconds ); epoch += (INT8)( output.epoch.gpsNanoSeconds ); fprintf( fp, "# epoch = %" LAL_INT8_FORMAT "\n", epoch ); fprintf( fp, "# deltaT = %23.16e\n", output.deltaT ); for ( i = 0; i < output.data->length; i++ ) fprintf( fp, "%8.1f\n", (REAL4)( output.data->data[i] ) ); fclose( fp ); } /* Destroy remaining memory. */ SUB( LALDestroyRandomParams( &stat, ¶ms ), &stat ); SUB( LALI2DestroyVector( &stat, &( output.data ) ), &stat ); SUB( LALCDestroyVector( &stat, &( detector.transfer->data ) ), &stat ); LALFree( detector.transfer ); /* Done! */ LALCheckMemoryLeaks(); INFO( BASICINJECTTESTC_MSGENORM ); return BASICINJECTTESTC_ENORM; }
void LALCoarseFitToPulsar ( LALStatus *status, CoarseFitOutput *output, CoarseFitInput *input, CoarseFitParams *params ) { /******* DECLARE VARIABLES ************/ UINT4 n,i; /* integer indices */ REAL8 psi; REAL8 h0/*,h*/; REAL8 cosIota; REAL8 phase; REAL8 chiSquare; LALDetector detector; LALSource pulsar; LALDetAndSource detAndSource; LALDetAMResponse computedResponse; REAL4Vector *Fp, *Fc; /* pointers to amplitude responses of the detector */ REAL8Vector *var; REAL8 cos2phase,sin2phase; COMPLEX16 Xp, Xc; REAL8 Y, cosIota2; COMPLEX16 A,B; REAL8 sumAA, sumBB, sumAB; REAL8 h0BestFit=0,phaseBestFit=0, psiBestFit=0, cosIotaBestFit=0; REAL8 minChiSquare; COMPLEX16 eh0; REAL8 oldMinEh0, oldMaxEh0, weh0; UINT4 iH0, iCosIota, iPhase, iPsi, arg; INITSTATUS(status); ATTATCHSTATUSPTR(status); /******* CHECK VALIDITY OF ARGUMENTS ************/ ASSERT(output != (CoarseFitOutput *)NULL, status, FITTOPULSARH_ENULLOUTPUT, FITTOPULSARH_MSGENULLOUTPUT); ASSERT(params != (CoarseFitParams *)NULL, status, FITTOPULSARH_ENULLPARAMS, FITTOPULSARH_MSGENULLPARAMS); ASSERT(input != (CoarseFitInput *)NULL, status, FITTOPULSARH_ENULLINPUT, FITTOPULSARH_MSGENULLINPUT); ASSERT(input->B->length == input->var->length, status, FITTOPULSARH_EVECSIZE , FITTOPULSARH_MSGEVECSIZE ); /******* EXTRACT INPUTS AND PARAMETERS ************/ n = input->B->length; for (i = 0; i < n; i++) ASSERT(creal(input->var->data[i]) > 0.0 && cimag(input->var->data[i]) > 0.0, status, FITTOPULSARH_EVAR, FITTOPULSARH_MSGEVAR); detector = params->detector; detAndSource.pDetector = &detector; pulsar = params->pulsarSrc; /******* ALLOCATE MEMORY TO VECTORS **************/ Fp = NULL; LALSCreateVector(status->statusPtr, &Fp, n); Fp->length = n; Fc = NULL; LALSCreateVector(status->statusPtr, &Fc, n); Fc->length = n; var = NULL; LALDCreateVector(status->statusPtr, &var, n); var->length = n; /******* INITIALIZE VARIABLES *******************/ minChiSquare = INICHISQU; oldMaxEh0 = INIMAXEH; oldMinEh0 = INIMINEH; for (i=0;i<n;i++) { var->data[i] = creal(input->var->data[i]) + cimag(input->var->data[i]); } /******* DO ANALYSIS ************/ for (iPsi = 0; iPsi < params->meshPsi[2]; iPsi++) { psi = params->meshPsi[0] + iPsi*params->meshPsi[1]; pulsar.orientation = psi; detAndSource.pSource = &pulsar; /* create vectors containing amplitude response of detector for specified times */ for (i=0;i<n;i++) { LALComputeDetAMResponse(status->statusPtr, &computedResponse,&detAndSource, &input->t[i]); Fp->data[i] = (REAL8)computedResponse.plus; Fc->data[i] = (REAL8)computedResponse.cross; } for (iPhase = 0; iPhase < params->meshPhase[2]; iPhase++) { phase = params->meshPhase[0] + iPhase*params->meshPhase[1]; cos2phase = cos(2.0*phase); sin2phase = sin(2.0*phase); for (iCosIota = 0; iCosIota < params->meshCosIota[2]; iCosIota++) { cosIota = params->meshCosIota[0] + iCosIota*params->meshCosIota[1]; cosIota2 = 1.0 + cosIota*cosIota; Xp = crect( cosIota2 * cos2phase, cosIota2 * sin2phase ); Y = 2.0*cosIota; Xc = crect( Y*sin2phase, -Y*cos2phase ); sumAB = 0.0; sumAA = 0.0; sumBB = 0.0; eh0 = 0.0; for (i = 0; i < n; i++) { B = input->B->data[i]; A = crect( Fp->data[i]*creal(Xp) + Fc->data[i]*creal(Xc), Fp->data[i]*cimag(Xp) + Fc->data[i]*cimag(Xc) ); sumBB += (creal(B)*creal(B) + cimag(B)*cimag(B)) / var->data[i]; sumAA += (creal(A)*creal(A) + cimag(A)*cimag(A)) / var->data[i]; sumAB += (creal(B)*creal(A) + cimag(B)*cimag(A)) / var->data[i]; /**** calculate error on h0 **********/ eh0 += crect( (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) * (Fp->data[i]*cosIota2*cos2phase + 2.0*Fc->data[i]*cosIota*sin2phase) / creal(input->var->data[i]), (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) * (Fp->data[i]*cosIota2*sin2phase - 2.0*Fc->data[i]*cosIota*cos2phase) / cimag(input->var->data[i]) ); } for (iH0 = 0; iH0 < params->meshH0[2]; iH0++) { h0 = params->meshH0[0] + iH0*params->meshH0[1]; chiSquare = sumBB - 2.0*h0*sumAB + h0*h0*sumAA; if (chiSquare<minChiSquare) { minChiSquare = chiSquare; h0BestFit = h0; cosIotaBestFit = cosIota; psiBestFit = psi; phaseBestFit = phase; output->eh0[0] = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0))); } weh0 = 1.0 /sqrt(sqrt(creal(eh0)*creal(eh0) + cimag(eh0)*cimag(eh0))); if (weh0>oldMaxEh0) { output->eh0[2] = weh0; oldMaxEh0 = weh0; } if (weh0<oldMinEh0) { output->eh0[1] = weh0; oldMinEh0 = weh0; } arg = iH0 + params->meshH0[2]*(iCosIota + params->meshCosIota[2]*(iPhase + params->meshPhase[2]*iPsi)); output->mChiSquare->data[arg] = chiSquare; } } } } /******* CONSTRUCT OUTPUT ************/ output->h0 = h0BestFit; output->cosIota = cosIotaBestFit; output->phase = phaseBestFit; output->psi = psiBestFit; output->chiSquare = minChiSquare; ASSERT(minChiSquare < INICHISQU, status, FITTOPULSARH_EMAXCHI , FITTOPULSARH_MSGEMAXCHI); LALSDestroyVector(status->statusPtr, &Fp); LALSDestroyVector(status->statusPtr, &Fc); LALDDestroyVector(status->statusPtr, &var); DETATCHSTATUSPTR(status); RETURN(status); }
void LALCreateTimeFreqParam (LALStatus *status, TimeFreqParam **param, CreateTimeFreqIn *in) { /* Initialize status */ INITSTATUS(status); /* Check input structure: report if NULL */ ASSERT (in != NULL, status, CREATETFP_ENULL, CREATETFP_MSGENULL); /* Check return structure */ ASSERT (param != NULL, status, CREATETFP_ENULL, CREATETFP_MSGENULL); ASSERT (*param == NULL, status, CREATETFP_ENNUL, CREATETFP_MSGENNUL); *param = (TimeFreqParam *) LALMalloc(sizeof(TimeFreqParam)); /* Check Allocation */ ASSERT (*param != NULL, status, CREATETFP_EMALL, CREATETFP_MSGEMALL); (*param)->type=Undefined; /* Undefined until storage allocated */ (*param)->windowT = NULL; /* NULL data until allocated */ (*param)->windowF = NULL; /* NULL data until allocated */ switch (in->type) { case Spectrogram : /* Make sure the window length is a odd number */ ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ); LALSCreateVector(status,&(*param)->windowT,in->wlengthT); (*param)->type = Spectrogram; break; case WignerVille : (*param)->type = WignerVille; break; case PSWignerVille : /* Make sure the window length is a odd number */ ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ); /* Make sure the window length is a odd number */ ASSERT (in->wlengthF%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ); LALSCreateVector(status,&(*param)->windowT,in->wlengthT); LALSCreateVector(status,&(*param)->windowF,in->wlengthF); (*param)->type = PSWignerVille; break; case RSpectrogram : /* Make sure the window length is a odd number */ ASSERT (in->wlengthT%2 != 0, status, CREATETFP_EWSIZ, CREATETFP_MSGEWSIZ); LALSCreateVector(status,&(*param)->windowT,in->wlengthT); (*param)->type = RSpectrogram; break; default : ABORT(status,CREATETFP_ETYPE, CREATETFP_MSGETYPE); } /* We be done: Normal exit */ RETURN (status); }
/** \see See \ref DetInverse_c for documentation */ void LALSMatrixInverse( LALStatus *stat, REAL4 *det, REAL4Array *matrix, REAL4Array *inverse ) { INT2 sgn; /* sign of permutation. */ UINT4 n, i, j, ij; /* array dimension and indecies */ UINT4Vector *indx = NULL; /* permutation storage vector */ REAL4Vector *col = NULL; /* columns of inverse matrix */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Check dimension length. Other argument testing is done by the subroutines. */ ASSERT( matrix, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( matrix->dimLength, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( matrix->dimLength->data, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength->data, stat, MATRIXUTILSH_ENUL, MATRIXUTILSH_MSGENUL ); ASSERT( inverse->dimLength->length == 2, stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); n = inverse->dimLength->data[0]; ASSERT( n, stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); ASSERT( n == inverse->dimLength->data[1], stat, MATRIXUTILSH_EDIM, MATRIXUTILSH_MSGEDIM ); /* Allocate vectors to store the matrix permutation and column vectors. */ TRY( LALU4CreateVector( stat->statusPtr, &indx, n ), stat ); LALSCreateVector( stat->statusPtr, &col, n ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); } ENDFAIL( stat ); /* Decompose the matrix. */ sgn = 0; /* silence -Werror=maybe-uninitialized. note: there is no check here that LALSLUDecomp() is successful and the compiler knows this. *that's* the real problem, but I'm not fixing (Kipp) */ LALSLUDecomp( stat->statusPtr, &sgn, matrix, indx ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &col ), stat ); } ENDFAIL( stat ); /* Compute the determinant, if available. */ if ( det ) { *det = sgn; for ( i = 0; i < n; i++ ) *det *= matrix->data[i*(n+1)]; } /* Compute each column of inverse matrix. */ for ( j = 0; j < n; j++ ) { memset( col->data, 0, n*sizeof(REAL4) ); col->data[j] = 1.0; LALSLUBackSub( stat->statusPtr, col, matrix, indx ); BEGINFAIL( stat ) { TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &col ), stat ); } ENDFAIL( stat ); for ( i = 0, ij = j; i < n; i++, ij += n ) inverse->data[ij] = col->data[i]; } /* Clean up. */ TRY( LALU4DestroyVector( stat->statusPtr, &indx ), stat ); TRY( LALSDestroyVector( stat->statusPtr, &col ), stat ); DETATCHSTATUSPTR( stat ); RETURN( stat ); }
int main( void ) { static LALStatus status; REAL4Sequence *sSequenceIn; REAL4Sequence *sSequenceOut; REAL8Sequence *dSequenceIn; REAL8Sequence *dSequenceOut; COMPLEX8Sequence *cSequenceIn; COMPLEX8Sequence *cSequenceOut; COMPLEX16Sequence *zSequenceIn; COMPLEX16Sequence *zSequenceOut; REAL4FrequencySeries sFrequencySeries; REAL8FrequencySeries dFrequencySeries; COMPLEX8FrequencySeries cFrequencySeries; COMPLEX16FrequencySeries zFrequencySeries; REAL4FrequencySeries sFrequencySeries2; REAL8FrequencySeries dFrequencySeries2; COMPLEX8FrequencySeries cFrequencySeries2; COMPLEX16FrequencySeries zFrequencySeries2; REAL4TimeSeries sTimeSeries; REAL8TimeSeries dTimeSeries; COMPLEX8TimeSeries cTimeSeries; COMPLEX16TimeSeries zTimeSeries; REAL4TimeSeries sTimeSeries2; REAL8TimeSeries dTimeSeries2; COMPLEX8TimeSeries cTimeSeries2; COMPLEX16TimeSeries zTimeSeries2; REAL4 *sData; REAL8 *dData; COMPLEX8 *cData; COMPLEX16 *zData; /* Boolean Vars */ BOOLEAN unitComp; /* variables for units */ RAT4 raise; LALUnit strainToMinus2; LALUnit adcToMinus2; LALUnit adcStrain; /* This routine should generate a file with data */ /* to be read by ReadFTSeries.c*/ LIGOTimeGPS t; UINT4 i; /* Data Test Variable */ UINT4 j; fprintf(stderr,"Testing value of LALUnitTextSize ... "); if ( (int)LALSupportUnitTextSize != (int)LALUnitTextSize ) { fprintf(stderr,"UnitTextSize mismatch: [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } fprintf(stderr,"PASS\n"); t.gpsSeconds = 0; t.gpsNanoSeconds = 0; fprintf(stderr,"Testing Print/Read COMPLEX8FrequencySeries ... "); cSequenceIn = NULL; LALCCreateVector(&status, &cSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ ) { *(cData) = crectf( i, i+1 ); } strncpy(cFrequencySeries.name,"Complex frequency series",LALNameLength); cFrequencySeries.sampleUnits = lalHertzUnit; cFrequencySeries.deltaF = 1; cFrequencySeries.epoch = t; cFrequencySeries.f0 = 5; cFrequencySeries.data = cSequenceIn; LALCPrintFrequencySeries(&cFrequencySeries, "cFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cSequenceOut = NULL; LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cFrequencySeries2.data = cSequenceOut; LALCReadFrequencySeries(&status, &cFrequencySeries2, "./cFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(cFrequencySeries.deltaF - cFrequencySeries.deltaF)/ cFrequencySeries.deltaF > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaF MisMatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(cFrequencySeries.name,cFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.epoch.gpsSeconds) != (cFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.epoch.gpsNanoSeconds) != (cFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanosecondMismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cFrequencySeries.f0) ? (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0)/cFrequencySeries.f0) : (fabs(cFrequencySeries.f0 - cFrequencySeries2.f0) > READFTSERIESTEST_TOL)) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&cFrequencySeries.sampleUnits,&cFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < cSequenceIn->length;j++) { if ((crealf(cSequenceIn->data[j]) ? fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j])) /crealf(cSequenceIn->data[j])) :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimagf(cSequenceIn->data[j]) ? fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j])) /cimagf(cSequenceIn->data[j])) :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX16FrequencySeries ... "); /* Test case 2 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; zSequenceIn = NULL; LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ ) { *(zData) = crect( i/4.0, (i+1)/5.0 ); } zFrequencySeries.sampleUnits = lalDimensionlessUnit; strncpy(zFrequencySeries.name,"Complex frequency series",LALNameLength); zFrequencySeries.deltaF = 1.3; zFrequencySeries.epoch = t; zFrequencySeries.f0 = 0; zFrequencySeries.data = zSequenceIn; LALZPrintFrequencySeries(&zFrequencySeries, "zFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zSequenceOut = NULL; LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zFrequencySeries2.data = zSequenceOut; LALZReadFrequencySeries(&status, &zFrequencySeries2, "./zFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if ((zFrequencySeries.deltaF) != (zFrequencySeries2.deltaF)) { fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(zFrequencySeries.name,zFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zFrequencySeries.epoch.gpsSeconds) != (zFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zFrequencySeries.epoch.gpsNanoSeconds) != (zFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (zFrequencySeries.f0 ? (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)/zFrequencySeries.f0) : (fabs(zFrequencySeries.f0 - zFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&zFrequencySeries.sampleUnits,&zFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < zSequenceIn->length;j++) { if ((creal(zSequenceIn->data[j]) ? fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j])) /creal(zSequenceIn->data[j])) : fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimag(zSequenceIn->data[j]) ? fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j])) /cimag(zSequenceIn->data[j])) : fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL8FrequencySeries ... "); /* Test case 3 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; dSequenceIn = NULL; LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ ) { *(dData) = 0.005; } strncpy(dFrequencySeries.name,"Complex frequency series",LALNameLength); /* set units */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&dFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dFrequencySeries.deltaF = 1.3; dFrequencySeries.epoch = t; dFrequencySeries.f0 = 0; dFrequencySeries.data = dSequenceIn; LALDPrintFrequencySeries(&dFrequencySeries, "dFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dSequenceOut = NULL; LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dFrequencySeries2.data = dSequenceOut; LALDReadFrequencySeries(&status, &dFrequencySeries2, "./dFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if ((dFrequencySeries.deltaF) != (dFrequencySeries.deltaF)) { fprintf(stderr,"DeltaF Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(dFrequencySeries.name,dFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dFrequencySeries.epoch.gpsSeconds) != (dFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dFrequencySeries.epoch.gpsSeconds) != (dFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (dFrequencySeries.f0 ? (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)/dFrequencySeries.f0) : (fabs(dFrequencySeries.f0 - dFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&dFrequencySeries.sampleUnits,&dFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < dSequenceIn->length;j++) { if ((dSequenceIn->data[j] ? fabs((dSequenceIn->data[j] - dSequenceOut->data[j]) /dSequenceIn->data[j]) :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL4FrequencySeries ... "); /* Test case 4 */ t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; sSequenceIn = NULL; LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ ) { *(sData) = 0.005; } strncpy(sFrequencySeries.name,"Complex frequency series",LALNameLength); /* set units */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sFrequencySeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sFrequencySeries.deltaF = 1.3; sFrequencySeries.epoch = t; sFrequencySeries.f0 = 5; sFrequencySeries.data = sSequenceIn; sSequenceOut = NULL; LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sFrequencySeries2.data = sSequenceOut; LALSPrintFrequencySeries(&sFrequencySeries, "sFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSReadFrequencySeries(&status, &sFrequencySeries2, "./sFSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(sFrequencySeries.deltaF - sFrequencySeries2.deltaF) /sFrequencySeries.deltaF > READFTSERIESTEST_TOL) { fprintf(stderr,"Deltaf Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(sFrequencySeries.name,sFrequencySeries2.name)!=0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sFrequencySeries.epoch.gpsSeconds) != (sFrequencySeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sFrequencySeries.epoch.gpsNanoSeconds) != (sFrequencySeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (sFrequencySeries.f0 ? (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)/sFrequencySeries.f0) : (fabs(sFrequencySeries.f0 - sFrequencySeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&sFrequencySeries.sampleUnits,&sFrequencySeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < sSequenceIn->length;j++) { if ((sSequenceIn->data[j] ? fabs((sSequenceIn->data[j] - sSequenceOut->data[j]) /sSequenceIn->data[j]) :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } LALCDestroyVector(&status, &cSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCDestroyVector(&status, &cSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL4TimeSeries ... "); /* Here is where testing for ReadTimeSeries is done */ /* S Case ReadTimeSeries */ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; sSequenceIn = NULL; LALSCreateVector( &status, &sSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, sData=sSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, sData++ ) { *(sData) = 0.005; } strncpy(sTimeSeries.name,"Real4 Time series",LALNameLength); sTimeSeries.deltaT = 1.3; sTimeSeries.epoch = t; sTimeSeries.data = sSequenceIn; sTimeSeries.f0 = 5; LALSPrintTimeSeries(&sTimeSeries, "sTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sSequenceOut = NULL; LALSCreateVector( &status, &sSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } sTimeSeries2.data = sSequenceOut; LALSReadTimeSeries(&status, &sTimeSeries2, "./sTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(sTimeSeries.deltaT-sTimeSeries2.deltaT) / sTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(sFrequencySeries.name,sFrequencySeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sTimeSeries.epoch.gpsSeconds) != (sTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((sTimeSeries.epoch.gpsNanoSeconds) != (sTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch NanoSeconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } /* printf("%f ... %f f0 value\n",sTimeSeries.f0,sTimeSeries2.f0);*/ if (sTimeSeries.f0 ? (fabs(sTimeSeries.f0 - sTimeSeries2.f0)/sTimeSeries.f0) : (fabs(sTimeSeries.f0 - sTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&sTimeSeries.sampleUnits,&sTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < sSequenceIn->length;j++) { if ((sSequenceIn->data[j] ? fabs((sSequenceIn->data[j] - sSequenceOut->data[j]) /sSequenceIn->data[j]) :fabs(sSequenceIn->data[j] - sSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX16TimeSeries ... "); /* Z case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&zTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; zSequenceIn = NULL; LALZCreateVector( &status, &zSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, zData=zSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, zData++ ) { *(zData) = crect( 0.005, 1 ); } strncpy(zTimeSeries.name,"Complex16 Time series",LALNameLength); zTimeSeries.deltaT = 1.3; zTimeSeries.epoch = t; zTimeSeries.data = zSequenceIn; zTimeSeries.f0 = 0; LALZPrintTimeSeries(&zTimeSeries, "zTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zSequenceOut = NULL; LALZCreateVector( &status, &zSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } zTimeSeries2.data = zSequenceOut; LALZReadTimeSeries(&status, &zTimeSeries2, "./zTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(zTimeSeries.deltaT) - (zTimeSeries2.deltaT)/zTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"Mismatch DeltaT [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(zTimeSeries.name,zTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((zTimeSeries.epoch.gpsSeconds) != (zTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Second Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ( (zTimeSeries.epoch.gpsNanoSeconds) != (zTimeSeries2.epoch.gpsNanoSeconds) ) { fprintf(stderr,"Epoch Nanosecond Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (zTimeSeries.f0 ? (fabs(zTimeSeries.f0 - zTimeSeries2.f0)/zTimeSeries.f0) : (fabs(zTimeSeries.f0 - zTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&zTimeSeries.sampleUnits,&zTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFUN; } for (j = 0; j < zSequenceIn->length;j++) { if ((creal(zSequenceIn->data[j]) ? fabs((creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j])) /creal(zSequenceIn->data[j])) :fabs(creal(zSequenceIn->data[j]) - creal(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimag(zSequenceIn->data[j]) ? fabs((cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j])) /cimag(zSequenceIn->data[j])) :fabs(cimag(zSequenceIn->data[j]) - cimag(zSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read REAL8TimeSeries ... "); /* D case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&sTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } strncpy(dTimeSeries.name,"REAL8 Time series",LALNameLength); dTimeSeries.sampleUnits = lalHertzUnit; t.gpsSeconds = 4578; t.gpsNanoSeconds = 890634; dSequenceIn = NULL; LALDCreateVector( &status, &dSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, dData=dSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, dData++ ) { *(dData) = 0.005; } dTimeSeries.deltaT = 1.3; dTimeSeries.epoch = t; dTimeSeries.data = dSequenceIn; dTimeSeries.f0 = 0; LALDPrintTimeSeries(&dTimeSeries, "dTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dSequenceOut = NULL; LALDCreateVector( &status, &dSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } dTimeSeries2.data = dSequenceOut; LALDReadTimeSeries(&status, &dTimeSeries2, "./dTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(dTimeSeries.deltaT) - (dTimeSeries2.deltaT)/dTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode, status.statusDescription ); return READFTSERIESTESTC_EFLS; } if (strcmp(dTimeSeries.name,dTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%d,%s]\n",status.statusCode, status.statusDescription ); return READFTSERIESTESTC_EFLS; } if ((dTimeSeries.epoch.gpsSeconds) != (dTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((dTimeSeries.epoch.gpsNanoSeconds) != (dTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (dTimeSeries.f0 ? (fabs(dTimeSeries.f0 - dTimeSeries2.f0)/dTimeSeries.f0) : (fabs(dTimeSeries.f0 - dTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&dTimeSeries.sampleUnits,&dTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Unit Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < dSequenceIn->length;j++) { if ((dSequenceIn->data[j] ? fabs((dSequenceIn->data[j] - dSequenceOut->data[j]) /dSequenceIn->data[j]) :fabs(dSequenceIn->data[j] - dSequenceOut->data[j])) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); fprintf(stderr,"Testing Print/Read COMPLEX8TimeSeries ... "); /* C case ReadTimeSeries*/ raise.numerator = -2; raise.denominatorMinusOne = 0; if (XLALUnitRaiseRAT4(&strainToMinus2, &lalStrainUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitRaiseRAT4(&adcToMinus2, &lalADCCountUnit, &raise) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&(adcStrain), &strainToMinus2, &adcToMinus2) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (XLALUnitMultiply(&cTimeSeries.sampleUnits, &adcStrain, &lalHertzUnit) == NULL) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } t.gpsSeconds = 45678; t.gpsNanoSeconds = 89065834; cSequenceIn = NULL; LALCCreateVector( &status, &cSequenceIn, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } for ( i=1, cData=cSequenceIn->data; i<=READFTSERIESTEST_LEN ; i++, cData++ ) { *(cData) = crectf( 0.005, 1 ); } strncpy(cTimeSeries.name,"Complex8 Time series",LALNameLength); cTimeSeries.deltaT = 1.3; cTimeSeries.epoch = t; cTimeSeries.data = cSequenceIn; cTimeSeries.f0 = 0; cSequenceOut = NULL; LALCPrintTimeSeries(&cTimeSeries, "cTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCCreateVector( &status, &cSequenceOut, READFTSERIESTEST_LEN); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } cTimeSeries2.data = cSequenceOut; LALCReadTimeSeries(&status, &cTimeSeries2, "./cTSInput.dat"); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } if (fabs(cTimeSeries.deltaT - cTimeSeries2.deltaT)/cTimeSeries.deltaT > READFTSERIESTEST_TOL) { fprintf(stderr,"DeltaT Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (strcmp(cTimeSeries.name,cTimeSeries2.name) != 0) { fprintf(stderr,"Name Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cTimeSeries.epoch.gpsSeconds) != (cTimeSeries2.epoch.gpsSeconds)) { fprintf(stderr,"Epoch Seconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cTimeSeries.epoch.gpsNanoSeconds)!=(cTimeSeries2.epoch.gpsNanoSeconds)) { fprintf(stderr,"Epoch Nanoseconds Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if (cTimeSeries.f0 ? (fabs(cTimeSeries.f0 - cTimeSeries2.f0)/cTimeSeries.f0) : (fabs(cTimeSeries.f0 - cTimeSeries2.f0)) > READFTSERIESTEST_TOL) { fprintf(stderr,"f0 Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } unitComp = XLALUnitCompare(&cTimeSeries.sampleUnits,&cTimeSeries2.sampleUnits); if (unitComp != 0) { fprintf(stderr,"Units Mismatch [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } for (j = 0; j < cSequenceIn->length;j++) { if ((crealf(cSequenceIn->data[j]) ? fabs((crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j])) /crealf(cSequenceIn->data[j])) :fabs(crealf(cSequenceIn->data[j]) - crealf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } if ((cimagf(cSequenceIn->data[j]) ? fabs((cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j])) /cimagf(cSequenceIn->data[j])) :fabs(cimagf(cSequenceIn->data[j]) - cimagf(cSequenceOut->data[j]))) > READFTSERIESTEST_TOL) { fprintf(stderr,"Data Tolerance Exceeded [ReadFTSeriesTest:%s]\n", READFTSERIESTESTC_MSGEFLS); return READFTSERIESTESTC_EFLS; } } fprintf(stderr,"PASS\n"); /* *******************Deallocate all memory****************** */ LALCDestroyVector(&status, &cSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCDestroyVector(&status, &cSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALZDestroyVector(&status, &zSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALDDestroyVector(&status, &dSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceIn); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALSDestroyVector(&status, &sSequenceOut); if (status.statusCode != 0) { fprintf(stderr,"[%i]: %s [ReadFTSeriesTest:%s]\n",status.statusCode, status.statusDescription, READFTSERIESTESTC_MSGEFUN); return READFTSERIESTESTC_EFUN; } LALCheckMemoryLeaks(); fprintf(stderr,"ReadFTSeries passed all tests.\n"); return READFTSERIESTESTC_ENOM; }
/** * \author Creighton, T. D. * * \brief Computes a continuous waveform with frequency drift and Doppler * modulation from an elliptical orbital trajectory. * * This function computes a quaiperiodic waveform using the spindown and * orbital parameters in <tt>*params</tt>, storing the result in * <tt>*output</tt>. * * In the <tt>*params</tt> structure, the routine uses all the "input" * fields specified in \ref GenerateSpinOrbitCW_h, and sets all of the * "output" fields. If <tt>params-\>f</tt>=\c NULL, no spindown * modulation is performed. If <tt>params-\>oneMinusEcc</tt>\f$\notin(0,1]\f$ * (an open orbit), or if * <tt>params-\>rPeriNorm</tt>\f$\times\f$<tt>params-\>angularSpeed</tt>\f$\geq1\f$ * (faster-than-light speed at periapsis), an error is returned. * * In the <tt>*output</tt> structure, the field <tt>output-\>h</tt> is * ignored, but all other pointer fields must be set to \c NULL. The * function will create and allocate space for <tt>output-\>a</tt>, * <tt>output-\>f</tt>, and <tt>output-\>phi</tt> as necessary. The * <tt>output-\>shift</tt> field will remain set to \c NULL. * * ### Algorithm ### * * For elliptical orbits, we combine \eqref{eq_spinorbit-tr}, * \eqref{eq_spinorbit-t}, and \eqref{eq_spinorbit-upsilon} to get \f$t_r\f$ * directly as a function of the eccentric anomaly \f$E\f$: * \f{eqnarray}{ * \label{eq_tr-e1} * t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega\\ * & + & \left(\frac{P}{2\pi}\right) \left( E + * \left[v_p(1-e)\cos\omega - e\right]\sin E * + \left[v_p\sqrt{\frac{1-e}{1+e}}\sin\omega\right] * [\cos E - 1]\right) \;, * \f} * where \f$v_p=r_p\dot{\upsilon}_p\sin i/c\f$ is a normalized velocity at * periapsis and \f$P=2\pi\sqrt{(1+e)/(1-e)^3}/\dot{\upsilon}_p\f$ is the * period of the orbit. For simplicity we write this as: * \f{equation}{ * \label{eq_tr-e2} * t_r = T_p + \frac{1}{n}\left( E + A\sin E + B[\cos E - 1] \right) \;, * \f} * * \figure{inject_eanomaly,eps,0.23,Function to be inverted to find eccentric anomaly} * * where \f$T_p\f$ is the \e observed time of periapsis passage and * \f$n=2\pi/P\f$ is the mean angular speed around the orbit. Thus the key * numerical procedure in this routine is to invert the expression * \f$x=E+A\sin E+B(\cos E - 1)\f$ to get \f$E(x)\f$. We note that * \f$E(x+2n\pi)=E(x)+2n\pi\f$, so we only need to solve this expression in * the interval \f$[0,2\pi)\f$, sketched to the right. * * We further note that \f$A^2+B^2<1\f$, although it approaches 1 when * \f$e\rightarrow1\f$, or when \f$v_p\rightarrow1\f$ and either \f$e=0\f$ or * \f$\omega=\pi\f$. Except in this limit, Newton-Raphson methods will * converge rapidly for any initial guess. In this limit, though, the * slope \f$dx/dE\f$ approaches zero at the point of inflection, and an * initial guess or iteration landing near this point will send the next * iteration off to unacceptably large or small values. However, by * restricting all initial guesses and iterations to the domain * \f$E\in[0,2\pi)\f$, one will always end up on a trajectory branch that * will converge uniformly. This should converge faster than the more * generically robust technique of bisection. (Note: the danger with Newton's method * has been found to be unstable for certain binary orbital parameters. So if * Newton's method fails to converge, a bisection algorithm is employed.) * * In this algorithm, we start the computation with an arbitrary initial * guess of \f$E=0\f$, and refine it until the we get agreement to within * 0.01 parts in part in \f$N_\mathrm{cyc}\f$ (where \f$N_\mathrm{cyc}\f$ is the * larger of the number of wave cycles in an orbital period, or the * number of wave cycles in the entire waveform being generated), or one * part in \f$10^{15}\f$ (an order of magnitude off the best precision * possible with \c REAL8 numbers). The latter case indicates that * \c REAL8 precision may fail to give accurate phasing, and one * should consider modeling the orbit as a set of Taylor frequency * coefficients \'{a} la <tt>LALGenerateTaylorCW()</tt>. On subsequent * timesteps, we use the previous timestep as an initial guess, which is * good so long as the timesteps are much smaller than an orbital period. * This sequence of guesses will have to readjust itself once every orbit * (as \f$E\f$ jumps from \f$2\pi\f$ down to 0), but this is relatively * infrequent; we don't bother trying to smooth this out because the * additional tests would probably slow down the algorithm overall. * * Once a value of \f$E\f$ is found for a given timestep in the output * series, we compute the system time \f$t\f$ via \eqref{eq_spinorbit-t}, * and use it to determine the wave phase and (non-Doppler-shifted) * frequency via \eqref{eq_taylorcw-freq} * and \eqref{eq_taylorcw-phi}. The Doppler shift on the frequency is * then computed using \eqref{eq_spinorbit-upsilon} * and \eqref{eq_orbit-rdot}. We use \f$\upsilon\f$ as an intermediate in * the Doppler shift calculations, since expressing \f$\dot{R}\f$ directly in * terms of \f$E\f$ results in expression of the form \f$(1-e)/(1-e\cos E)\f$, * which are difficult to simplify and face precision losses when * \f$E\sim0\f$ and \f$e\rightarrow1\f$. By contrast, solving for \f$\upsilon\f$ is * numerically stable provided that the system <tt>atan2()</tt> function is * well-designed. * * The routine does not account for variations in special relativistic or * gravitational time dilation due to the elliptical orbit, nor does it * deal with other gravitational effects such as Shapiro delay. To a * very rough approximation, the amount of phase error induced by * gravitational redshift goes something like \f$\Delta\phi\sim * fT(v/c)^2\Delta(r_p/r)\f$, where \f$f\f$ is the typical wave frequency, \f$T\f$ * is either the length of data or the orbital period (whichever is * \e smaller), \f$v\f$ is the \e true (unprojected) speed at * periapsis, and \f$\Delta(r_p/r)\f$ is the total range swept out by the * quantity \f$r_p/r\f$ over the course of the observation. Other * relativistic effects such as special relativistic time dilation are * comparable in magnitude. We make a crude estimate of when this is * significant by noting that \f$v/c\gtrsim v_p\f$ but * \f$\Delta(r_p/r)\lesssim 2e/(1+e)\f$; we take these approximations as * equalities and require that \f$\Delta\phi\lesssim\pi\f$, giving: * \f{equation}{ * \label{eq_relativistic-orbit} * f_0Tv_p^2\frac{4e}{1+e}\lesssim1 \;. * \f} * When this critereon is violated, a warning is generated. Furthermore, * as noted earlier, when \f$v_p\geq1\f$ the routine will return an error, as * faster-than-light speeds can cause the emission and reception times to * be non-monotonic functions of one another. */ void LALGenerateEllipticSpinOrbitCW( LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params ) { UINT4 n, i; /* number of and index over samples */ UINT4 nSpin = 0, j; /* number of and index over spindown terms */ REAL8 t, dt, tPow; /* time, interval, and t raised to a power */ REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */ REAL8 f, fPrev; /* current and previous values of frequency */ REAL4 df = 0.0; /* maximum difference between f and fPrev */ REAL8 phi; /* current value of phase */ REAL8 p, vDotAvg; /* orbital period, and 2*pi/(period) */ REAL8 vp; /* projected speed at periapsis */ REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */ REAL8 eCosOmega; /* eccentricity * cosine of argument */ REAL8 tPeriObs; /* time of observed periapsis */ REAL8 spinOff; /* spin epoch - orbit epoch */ REAL8 x; /* observed mean anomaly */ REAL8 dx, dxMax; /* current and target errors in x */ REAL8 a, b; /* constants in equation for x */ REAL8 ecc; /* orbital eccentricity */ REAL8 oneMinusEcc, onePlusEcc; /* 1 - ecc and 1 + ecc */ REAL8 e = 0.0; /* eccentric anomaly */ REAL8 de = 0.0; /* eccentric anomaly step */ REAL8 sine = 0.0, cose = 0.0; /* sine of e, and cosine of e minus 1 */ REAL8 *fSpin = NULL; /* pointer to Taylor coefficients */ REAL4 *fData; /* pointer to frequency data */ REAL8 *phiData; /* pointer to phase data */ INITSTATUS(stat); ATTATCHSTATUSPTR( stat ); /* Make sure parameter and output structures exist. */ ASSERT( params, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); ASSERT( output, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); /* Make sure output fields don't exist. */ ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT, GENERATESPINORBITCWH_MSGEOUT ); /* If Taylor coeficients are specified, make sure they exist. */ if ( params->f ) { ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL, GENERATESPINORBITCWH_MSGENUL ); nSpin = params->f->length; fSpin = params->f->data; } /* Set up some constants (to avoid repeated calculation or dereferencing), and make sure they have acceptable values. */ oneMinusEcc = params->oneMinusEcc; ecc = 1.0 - oneMinusEcc; onePlusEcc = 1.0 + ecc; if ( ecc < 0.0 || oneMinusEcc <= 0.0 ) { ABORT( stat, GENERATESPINORBITCWH_EECC, GENERATESPINORBITCWH_MSGEECC ); } vp = params->rPeriNorm*params->angularSpeed; n = params->length; dt = params->deltaT; f0 = fPrev = params->f0; vDotAvg = params->angularSpeed *sqrt( oneMinusEcc*oneMinusEcc*oneMinusEcc/onePlusEcc ); if ( vp >= 1.0 ) { ABORT( stat, GENERATESPINORBITCWH_EFTL, GENERATESPINORBITCWH_MSGEFTL ); } if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 || n == 0 ) { ABORT( stat, GENERATESPINORBITCWH_ESGN, GENERATESPINORBITCWH_MSGESGN ); } /* Set up some other constants. */ twopif0 = f0*LAL_TWOPI; phi0 = params->phi0; argument = params->omega; p = LAL_TWOPI/vDotAvg; a = vp*oneMinusEcc*cos( argument ) + oneMinusEcc - 1.0; b = vp*sqrt( oneMinusEcc/( onePlusEcc ) )*sin( argument ); eCosOmega = ecc*cos( argument ); if ( n*dt > p ) dxMax = 0.01/( f0*n*dt ); else dxMax = 0.01/( f0*p ); if ( dxMax < 1.0e-15 ) { dxMax = 1.0e-15; #ifndef NDEBUG LALWarning( stat, "REAL8 arithmetic may not have sufficient" " precision for this orbit" ); #endif } #ifndef NDEBUG if ( lalDebugLevel & LALWARNING ) { REAL8 tau = n*dt; if ( tau > p ) tau = p; if ( f0*tau*vp*vp*ecc/onePlusEcc > 0.25 ) LALWarning( stat, "Orbit may have significant relativistic" " effects that are not included" ); } #endif /* Compute offset between time series epoch and observed periapsis, and betweem true periapsis and spindown reference epoch. */ tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds - params->epoch.gpsSeconds ); tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->epoch.gpsNanoSeconds ); tPeriObs += params->rPeriNorm*sin( params->omega ); spinOff = (REAL8)( params->orbitEpoch.gpsSeconds - params->spinEpoch.gpsSeconds ); spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds - params->spinEpoch.gpsNanoSeconds ); /* Allocate output structures. */ if ( ( output->a = (REAL4TimeVectorSeries *) LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) { ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->a, 0, sizeof(REAL4TimeVectorSeries) ); if ( ( output->f = (REAL4TimeSeries *) LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->f, 0, sizeof(REAL4TimeSeries) ); if ( ( output->phi = (REAL8TimeSeries *) LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; ABORT( stat, GENERATESPINORBITCWH_EMEM, GENERATESPINORBITCWH_MSGEMEM ); } memset( output->phi, 0, sizeof(REAL8TimeSeries) ); /* Set output structure metadata fields. */ output->position = params->position; output->psi = params->psi; output->a->epoch = output->f->epoch = output->phi->epoch = params->epoch; output->a->deltaT = n*params->deltaT; output->f->deltaT = output->phi->deltaT = params->deltaT; output->a->sampleUnits = lalStrainUnit; output->f->sampleUnits = lalHertzUnit; output->phi->sampleUnits = lalDimensionlessUnit; snprintf( output->a->name, LALNameLength, "CW amplitudes" ); snprintf( output->f->name, LALNameLength, "CW frequency" ); snprintf( output->phi->name, LALNameLength, "CW phase" ); /* Allocate phase and frequency arrays. */ LALSCreateVector( stat->statusPtr, &( output->f->data ), n ); BEGINFAIL( stat ) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); LALDCreateVector( stat->statusPtr, &( output->phi->data ), n ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); /* Allocate and fill amplitude array. */ { CreateVectorSequenceIn in; /* input to create output->a */ in.length = 2; in.vectorLength = 2; LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in ); BEGINFAIL( stat ) { TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ), stat ); TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ), stat ); LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; } ENDFAIL( stat ); output->a->data->data[0] = output->a->data->data[2] = params->aPlus; output->a->data->data[1] = output->a->data->data[3] = params->aCross; } /* Fill frequency and phase arrays. */ fData = output->f->data->data; phiData = output->phi->data->data; for ( i = 0; i < n; i++ ) { INT4 nOrb; /* number of orbits since the specified orbit epoch */ /* First, find x in the range [0,2*pi]. */ x = vDotAvg*( i*dt - tPeriObs ); nOrb = (INT4)( x/LAL_TWOPI ); if ( x < 0.0 ) nOrb -= 1; x -= LAL_TWOPI*nOrb; /* Newton-Raphson iteration to find E(x). Maximum of 100 iterations. */ INT4 maxiter = 100, iter = 0; while ( iter<maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) { iter++; //Make a check on the step-size so we don't step too far de = dx/( 1.0 + a*cose + a - b*sine ); if ( de > LAL_PI ) de = LAL_PI; else if ( de < -LAL_PI ) de = -LAL_PI; e -= de; if ( e < 0.0 ) e = 0.0; else if ( e > LAL_TWOPI ) e = LAL_TWOPI; sine = sin( e ); cose = cos( e ) - 1.0; } /* Bisection algorithm from GSL if Newton's method (above) fails to converge. */ if (iter==maxiter && fabs( dx = e + a*sine + b*cose - x ) > dxMax ) { //Initialize solver const gsl_root_fsolver_type *T = gsl_root_fsolver_bisection; gsl_root_fsolver *s = gsl_root_fsolver_alloc(T); REAL8 e_lo = 0.0, e_hi = LAL_TWOPI; gsl_function F; struct E_solver_params pars = {a, b, x}; F.function = &gsl_E_solver; F.params = &pars; if (gsl_root_fsolver_set(s, &F, e_lo, e_hi) != 0) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; ABORT( stat, -1, "GSL failed to set initial points" ); } INT4 keepgoing = 1; INT4 success = 0; INT4 root_status = keepgoing; e = 0.0; iter = 0; while (root_status==keepgoing && iter<maxiter) { iter++; root_status = gsl_root_fsolver_iterate(s); if (root_status!=keepgoing && root_status!=success) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; ABORT( stat, -1, "gsl_root_fsolver_iterate() failed" ); } e = gsl_root_fsolver_root(s); sine = sin(e); cose = cos(e) - 1.0; if (fabs( dx = e + a*sine + b*cose - x ) > dxMax) root_status = keepgoing; else root_status = success; } if (root_status!=success) { LALFree( output->a ); output->a = NULL; LALFree( output->f ); output->f = NULL; LALFree( output->phi ); output->phi = NULL; gsl_root_fsolver_free(s); ABORT( stat, -1, "Could not converge using bisection algorithm" ); } gsl_root_fsolver_free(s); } /* Compute source emission time, phase, and frequency. */ phi = t = tPow = ( e + LAL_TWOPI*nOrb - ecc*sine )/vDotAvg + spinOff; f = 1.0; for ( j = 0; j < nSpin; j++ ) { f += fSpin[j]*tPow; phi += fSpin[j]*( tPow*=t )/( j + 2.0 ); } /* Appy frequency Doppler shift. */ upsilon = 2.0 * atan2 ( sqrt(onePlusEcc/oneMinusEcc) * sin(0.5*e), cos(0.5*e) ); f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega ) /onePlusEcc ); phi *= twopif0; if ( (i > 0) && (fabs( f - fPrev ) > df) ) df = fabs( f - fPrev ); *(fData++) = fPrev = f; *(phiData++) = phi + phi0; } /* for i < n */ /* Set output field and return. */ params->dfdt = df*dt; DETATCHSTATUSPTR( stat ); RETURN( stat ); }