/// /// Create coherent input data /// WeaveCohInput *XLALWeaveCohInputCreate( const LALStringVector *setup_detectors, const WeaveSimulationLevel simulation_level, const SFTCatalog *sft_catalog, const UINT4 segment_index, const LALSeg *segment, const PulsarDopplerParams *min_phys, const PulsarDopplerParams *max_phys, const double dfreq, const EphemerisData *ephemerides, const LALStringVector *sft_noise_sqrtSX, const LALStringVector *Fstat_assume_sqrtSX, FstatOptionalArgs *Fstat_opt_args, const WeaveStatisticsParams *statistics_params, BOOLEAN recalc_stage ) { // Check input XLAL_CHECK_NULL( setup_detectors != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( ( simulation_level & WEAVE_SIMULATE_MIN_MEM ) || ( sft_catalog != NULL ), XLAL_EFAULT ); XLAL_CHECK_NULL( segment != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( min_phys != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( max_phys != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( dfreq >= 0, XLAL_EINVAL ); XLAL_CHECK_NULL( ephemerides != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( Fstat_opt_args != NULL, XLAL_EFAULT ); XLAL_CHECK_NULL( statistics_params != NULL, XLAL_EFAULT ); // Allocate memory WeaveCohInput *coh_input = XLALCalloc( 1, sizeof( *coh_input ) ); XLAL_CHECK_NULL( coh_input != NULL, XLAL_ENOMEM ); // Set fields coh_input->setup_detectors = setup_detectors; coh_input->simulation_level = simulation_level; coh_input->seg_info_have_sft_info = ( sft_catalog != NULL ); coh_input->Fstat_collect_timing = Fstat_opt_args->collectTiming; // Record information from segment coh_input->seg_info.segment_start = segment->start; coh_input->seg_info.segment_end = segment->end; // Decide what F-statistic quantities to compute WeaveStatisticType requested_stats = ( recalc_stage ) ? statistics_params->completionloop_statistics[1] : statistics_params->mainloop_statistics; if ( requested_stats & WEAVE_STATISTIC_COH2F ) { coh_input->Fstat_what_to_compute |= FSTATQ_2F; } if ( requested_stats & WEAVE_STATISTIC_COH2F_DET ) { coh_input->Fstat_what_to_compute |= FSTATQ_2F_PER_DET; } // Return now if simulating search with minimal memory allocation if ( coh_input->simulation_level & WEAVE_SIMULATE_MIN_MEM ) { return coh_input; } // Get a timeslice of SFT catalog restricted to the given segment SFTCatalog XLAL_INIT_DECL( sft_catalog_seg ); XLAL_CHECK_NULL( XLALSFTCatalogTimeslice( &sft_catalog_seg, sft_catalog, &segment->start, &segment->end ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK_NULL( sft_catalog_seg.length > 0, XLAL_EINVAL, "No SFTs found in segment %u", segment_index ); // Check that the number of SFTs in each segment matches the number provided by the segment list in the setup file, if nonzero const UINT4 sft_count = ( UINT4 ) segment->id; XLAL_CHECK_NULL( sft_count == 0 || sft_catalog_seg.length == sft_count, XLAL_EFAILED, "Number of SFTs found for segment %u (%u) is inconsistent with expected number of SFTs given by segment list (%u)", segment_index, sft_catalog_seg.length, sft_count ); // Get list of detectors of SFT catalog in this segment LALStringVector *sft_catalog_seg_detectors = XLALListIFOsInCatalog( &sft_catalog_seg ); XLAL_CHECK_NULL( sft_catalog_seg_detectors != NULL, XLAL_EFUNC ); // Compute frequency range covered by spindown range over in the given segment LIGOTimeGPS sft_start = sft_catalog_seg.data[0].header.epoch; LIGOTimeGPS sft_end = sft_catalog_seg.data[sft_catalog_seg.length - 1].header.epoch; const double sft_end_timebase = 1.0 / sft_catalog_seg.data[sft_catalog_seg.length - 1].header.deltaF; XLALGPSAdd( &sft_end, sft_end_timebase ); PulsarSpinRange XLAL_INIT_DECL( spin_range ); XLAL_CHECK_NULL( XLALInitPulsarSpinRangeFromSpins( &spin_range, &min_phys->refTime, min_phys->fkdot, max_phys->fkdot ) == XLAL_SUCCESS, XLAL_EFUNC ); double sft_min_cover_freq = 0, sft_max_cover_freq = 0; XLAL_CHECK_NULL( XLALCWSignalCoveringBand( &sft_min_cover_freq, &sft_max_cover_freq, &sft_start, &sft_end, &spin_range, 0, 0, 0 ) == XLAL_SUCCESS, XLAL_EFUNC ); // Parse SFT noise sqrt(Sh) string vector for detectors in this segment // - This is important when segments contain data from a subset of detectors MultiNoiseFloor Fstat_injectSqrtSX; if ( sft_noise_sqrtSX != NULL ) { XLAL_CHECK_NULL( XLALParseMultiNoiseFloorMapped( &Fstat_injectSqrtSX, sft_catalog_seg_detectors, sft_noise_sqrtSX, setup_detectors ) == XLAL_SUCCESS, XLAL_EFUNC ); Fstat_opt_args->injectSqrtSX = &Fstat_injectSqrtSX; } // Parse F-statistic assumed sqrt(Sh) string vector for detectors in this segment // - This is important when segments contain data from a subset of detectors MultiNoiseFloor Fstat_assumeSqrtSX; if ( Fstat_assume_sqrtSX != NULL ) { XLAL_CHECK_NULL( XLALParseMultiNoiseFloorMapped( &Fstat_assumeSqrtSX, sft_catalog_seg_detectors, Fstat_assume_sqrtSX, setup_detectors ) == XLAL_SUCCESS, XLAL_EFUNC ); Fstat_opt_args->assumeSqrtSX = &Fstat_assumeSqrtSX; } // Load F-statistic input data coh_input->Fstat_input = XLALCreateFstatInput( &sft_catalog_seg, sft_min_cover_freq, sft_max_cover_freq, dfreq, ephemerides, Fstat_opt_args ); XLAL_CHECK_NULL( coh_input->Fstat_input != NULL, XLAL_EFUNC ); Fstat_opt_args->prevInput = coh_input->Fstat_input; // Map detectors in F-statistic data in the given segment to their index in the coherent results // - This is important when segments contain data from a subset of detectors // - Map entry 'i' in 'Fstat_detector_info' (F-statistic data) to entry 'idx' in 'detectors' (coherent results) if ( coh_input->Fstat_what_to_compute & FSTATQ_2F_PER_DET ) { const MultiLALDetector *Fstat_detector_info = XLALGetFstatInputDetectors( coh_input->Fstat_input ); coh_input->Fstat_ndetectors = Fstat_detector_info->length; char *statistics_detectors_string = XLALConcatStringVector( statistics_params->detectors, "," ); for ( size_t i = 0; i < coh_input->Fstat_ndetectors; ++i ) { const char *prefix = Fstat_detector_info->sites[i].frDetector.prefix; const int idx = XLALFindStringInVector( prefix, statistics_params->detectors ); XLAL_CHECK_NULL( idx >= 0, XLAL_EFAILED, "Detector '%s' from F-statistic data not found in list of detectors '%s'", prefix, statistics_detectors_string ); coh_input->Fstat_res_idx[i] = idx; } XLALFree( statistics_detectors_string ); } // Record information from SFTs in the given segment { MultiSFTCatalogView *sft_catalog_seg_view = XLALGetMultiSFTCatalogView( &sft_catalog_seg ); XLAL_CHECK_NULL( sft_catalog_seg_view != NULL, XLAL_EINVAL ); for ( size_t j = 0; j < sft_catalog_seg_view->length; ++j ) { XLAL_CHECK_NULL( sft_catalog_seg_view->data[j].length > 0, XLAL_EINVAL ); char *detector_name = XLALGetChannelPrefix( sft_catalog_seg_view->data[j].data[0].header.name ); XLAL_CHECK_NULL( detector_name != NULL, XLAL_EFUNC ); const int k = XLALFindStringInVector( detector_name, sft_catalog_seg_detectors ); if ( k >= 0 ) { const UINT4 length = sft_catalog_seg_view->data[j].length; coh_input->seg_info.sft_first[k] = sft_catalog_seg_view->data[j].data[0].header.epoch; coh_input->seg_info.sft_last[k] = sft_catalog_seg_view->data[j].data[length - 1].header.epoch; coh_input->seg_info.sft_count[k] = length; } XLALFree( detector_name ); } XLALDestroyMultiSFTCatalogView( sft_catalog_seg_view ); } XLAL_CHECK_NULL( XLALGetFstatInputSFTBand( coh_input->Fstat_input, &coh_input->seg_info.sft_min_freq, &coh_input->seg_info.sft_max_freq ) == XLAL_SUCCESS, XLAL_EFUNC ); // Cleanup XLALDestroyStringVector( sft_catalog_seg_detectors ); return coh_input; }
// ---------- main ---------- int main ( int argc, char *argv[] ) { // ---------- handle user input ---------- UserInput_t XLAL_INIT_DECL(uvar_s); UserInput_t *uvar = &uvar_s; uvar->FstatMethod = XLALStringDuplicate("ResampBest"); uvar->Freq = 100; uvar->f1dot = -3e-9; uvar->FreqResolution = XLALCreateREAL8Vector ( 2 ); uvar->FreqResolution->data[0] = 1; uvar->FreqResolution->data[1] = 10; uvar->numFreqBins = XLALCreateINT4Vector ( 2 ); uvar->numFreqBins->data[0] = 1000; uvar->numFreqBins->data[1] = 100000; uvar->Tseg = 60 * 3600; uvar->numSegments = 90; uvar->numTrials = 1; uvar->Tsft = 1800; uvar->runBuffered = 0; XLAL_CHECK ( (uvar->IFOs = XLALCreateStringVector ( "H1", NULL )) != NULL, XLAL_EFUNC ); uvar->outputInfo = NULL; XLAL_CHECK ( XLALRegisterUvarMember ( help, BOOLEAN, 'h', HELP, "Print help message" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( FstatMethod, STRING, 0, OPTIONAL, XLALFstatMethodHelpString() ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( Freq, REAL8, 0, OPTIONAL, "Search frequency in Hz" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( f1dot, REAL8, 0, OPTIONAL, "Search spindown f1dot in Hz/s" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( FreqResolution, REAL8Vector, 0, OPTIONAL, "Range of frequency resolution factor 'r' (st dFreq = 1/(r*T)) [2-number range input]" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( Tseg, REAL8, 0, OPTIONAL, "Coherent segment length" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( numSegments, INT4, 0, OPTIONAL, "Number of semi-coherent segment" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( numFreqBins, INT4Vector, 0, OPTIONAL, "Range of number of frequency bins to search [2-number range input]" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( IFOs, STRINGVector, 0, OPTIONAL, "IFOs to use" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( numTrials, INT4, 0, OPTIONAL, "Number of repeated trials to run (with potentially randomized parameters)" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( outputInfo, STRING, 0, OPTIONAL, "Append Resampling internal info into this file") == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( Tsft, REAL8, 0, DEVELOPER, "SFT length" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALRegisterUvarMember ( runBuffered, BOOLEAN, 0, DEVELOPER, "Explicitly time buffered Fstat call (only useful for double-checking and Demod timing)" ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( XLALUserVarReadAllInput(argc, argv) == XLAL_SUCCESS, XLAL_EFUNC ); if (uvar->help) { // if help was requested, we're done here return XLAL_SUCCESS; } // check user input XLAL_CHECK ( uvar->numSegments >= 1, XLAL_EINVAL ); XLAL_CHECK ( (uvar->FreqResolution->length == 1) || (uvar->FreqResolution->length == 2), XLAL_EINVAL ); XLAL_CHECK ( uvar->FreqResolution->data[0] > 0, XLAL_EINVAL ); REAL8 FreqResolutionMin, FreqResolutionMax; FreqResolutionMin = FreqResolutionMax = uvar->FreqResolution->data[0]; if ( uvar->FreqResolution->length == 2 ) { XLAL_CHECK ( uvar->FreqResolution->data[1] > 0, XLAL_EINVAL ); XLAL_CHECK ( uvar->FreqResolution->data[1] > uvar->FreqResolution->data[0], XLAL_EINVAL ); FreqResolutionMax = uvar->FreqResolution->data[1]; } XLAL_CHECK ( uvar->Freq > 0, XLAL_EINVAL ); XLAL_CHECK ( uvar->Tseg > uvar->Tsft, XLAL_EINVAL ); XLAL_CHECK ( uvar->Tsft > 1, XLAL_EINVAL ); XLAL_CHECK ( (uvar->numFreqBins->length == 1) || (uvar->numFreqBins->length == 2), XLAL_EINVAL ); XLAL_CHECK ( uvar->numFreqBins->data[0] > 0, XLAL_EINVAL ); UINT4 numFreqBinsMax, numFreqBinsMin; numFreqBinsMin = numFreqBinsMax = uvar->numFreqBins->data[0]; if ( uvar->numFreqBins->length == 2 ) { XLAL_CHECK ( uvar->numFreqBins->data[1] > 0, XLAL_EINVAL ); XLAL_CHECK ( uvar->numFreqBins->data[1] > uvar->numFreqBins->data[0], XLAL_EINVAL ); numFreqBinsMax = uvar->numFreqBins->data[1]; } XLAL_CHECK ( uvar->numTrials >= 1, XLAL_EINVAL ); // ---------- end: handle user input ---------- // common setup over repeated trials FstatMethodType FstatMethod; XLAL_CHECK ( XLALParseFstatMethodString ( &FstatMethod, uvar->FstatMethod ) == XLAL_SUCCESS, XLAL_EFUNC ); EphemerisData *ephem; XLAL_CHECK ( (ephem = XLALInitBarycenter ( TEST_DATA_DIR "earth00-19-DE405.dat.gz", TEST_DATA_DIR "sun00-19-DE405.dat.gz" )) != NULL, XLAL_EFUNC ); REAL8 memBase = XLALGetPeakHeapUsageMB(); UINT4 numDetectors = uvar->IFOs->length; // ----- setup injection and data parameters LIGOTimeGPS startTime = {711595934, 0}; LIGOTimeGPS startTime_l = startTime; LIGOTimeGPS endTime_l; SFTCatalog **catalogs; XLAL_CHECK ( (catalogs = XLALCalloc ( uvar->numSegments, sizeof( catalogs[0] ))) != NULL, XLAL_ENOMEM ); for ( INT4 l = 0; l < uvar->numSegments; l ++ ) { endTime_l = startTime_l; XLALGPSAdd( &endTime_l, uvar->Tseg ); MultiLIGOTimeGPSVector *multiTimestamps; XLAL_CHECK ( (multiTimestamps = XLALMakeMultiTimestamps ( startTime_l, uvar->Tseg, uvar->Tsft, 0, numDetectors )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (catalogs[l] = XLALMultiAddToFakeSFTCatalog ( NULL, uvar->IFOs, multiTimestamps )) != NULL, XLAL_EFUNC ); XLALDestroyMultiTimestamps ( multiTimestamps ); startTime_l = endTime_l; } // for l < numSegments LIGOTimeGPS endTime = endTime_l; UINT4 numSFTsPerSeg = catalogs[0]->length; FILE *fpInfo = NULL; if ( (uvar->outputInfo != NULL) && (FstatMethod == FMETHOD_RESAMP_GENERIC) ) { XLAL_CHECK ( (fpInfo = fopen (uvar->outputInfo, "ab")) != NULL, XLAL_ESYS, "Failed to open '%s' for appending\n", uvar->outputInfo ); XLALAppendResampInfo2File ( fpInfo, NULL ); // create header comment line } PulsarSpinRange XLAL_INIT_DECL(spinRange); LIGOTimeGPS refTime = { startTime.gpsSeconds - 2.3 * uvar->Tseg, 0 }; spinRange.refTime = refTime; spinRange.fkdot[0] = uvar->Freq; spinRange.fkdot[1] = uvar->f1dot; spinRange.fkdotBand[1] = 0; REAL8 asini = 0, Period = 0, ecc = 0; REAL8 minCoverFreq, maxCoverFreq; PulsarDopplerParams XLAL_INIT_DECL(Doppler); Doppler.refTime = refTime; Doppler.Alpha = 0.5; Doppler.Delta = 0.5; memcpy ( &Doppler.fkdot, &spinRange.fkdot, sizeof(Doppler.fkdot) );; Doppler.period = Period; Doppler.ecc = ecc; Doppler.asini = asini; // ----- setup optional Fstat arguments FstatOptionalArgs optionalArgs = FstatOptionalArgsDefaults; MultiNoiseFloor XLAL_INIT_DECL(injectSqrtSX); injectSqrtSX.length = numDetectors; for ( UINT4 X=0; X < numDetectors; X ++ ) { injectSqrtSX.sqrtSn[X] = 1; } optionalArgs.injectSqrtSX = &injectSqrtSX; optionalArgs.FstatMethod = FstatMethod; FstatWorkspace *sharedWorkspace = NULL; FstatInputVector *inputs; FstatQuantities whatToCompute = (FSTATQ_2F | FSTATQ_2F_PER_DET); FstatResults *results = NULL; REAL8 tauF1NoBuf = 0; REAL8 tauF1Buf = 0; // ---------- main loop over repeated trials ---------- for ( INT4 i = 0; i < uvar->numTrials; i ++ ) { // randomize numFreqBins UINT4 numFreqBins_i = numFreqBinsMin + (UINT4)round ( 1.0 * (numFreqBinsMax - numFreqBinsMin) * rand() / RAND_MAX ); // randomize FreqResolution REAL8 FreqResolution_i = FreqResolutionMin + 1.0 * ( FreqResolutionMax - FreqResolutionMin ) * rand() / RAND_MAX; XLAL_CHECK ( (inputs = XLALCreateFstatInputVector ( uvar->numSegments )) != NULL, XLAL_EFUNC ); REAL8 dFreq = 1.0 / ( FreqResolution_i * uvar->Tseg ); REAL8 FreqBand = numFreqBins_i * dFreq; fprintf ( stderr, "trial %d/%d: Tseg = %.1f d, numSegments = %d, Freq = %.1f Hz, f1dot = %.1e Hz/s, FreqResolution r = %f, numFreqBins = %d [dFreq = %.2e Hz, FreqBand = %.2e Hz]\n", i+1, uvar->numTrials, uvar->Tseg / 86400.0, uvar->numSegments, uvar->Freq, uvar->f1dot, FreqResolution_i, numFreqBins_i, dFreq, FreqBand ); spinRange.fkdotBand[0] = FreqBand; XLAL_CHECK ( XLALCWSignalCoveringBand ( &minCoverFreq, &maxCoverFreq, &startTime, &endTime, &spinRange, asini, Period, ecc ) == XLAL_SUCCESS, XLAL_EFUNC ); UINT4 numBinsSFT = ceil ( (maxCoverFreq - minCoverFreq) * uvar->Tsft + 2 * 8 ); REAL8 memSFTs = uvar->numSegments * numSFTsPerSeg * ( sizeof(SFTtype) + numBinsSFT * sizeof(COMPLEX8)) / 1e6; // create per-segment input structs for ( INT4 l = 0; l < uvar->numSegments; l ++ ) { XLAL_CHECK ( (inputs->data[l] = XLALCreateFstatInput ( catalogs[l], minCoverFreq, maxCoverFreq, dFreq, ephem, &optionalArgs )) != NULL, XLAL_EFUNC ); if ( l == 0 ) { sharedWorkspace = XLALGetSharedFstatWorkspace ( inputs->data[0] ); } optionalArgs.sharedWorkspace = sharedWorkspace; } // ----- compute Fstatistics over segments REAL8 tauF1NoBuf_i = 0; REAL8 tauF1Buf_i = 0; for ( INT4 l = 0; l < uvar->numSegments; l ++ ) { XLAL_CHECK ( XLALComputeFstat ( &results, inputs->data[l], &Doppler, numFreqBins_i, whatToCompute ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- output timing details if requested if ( (fpInfo != NULL) ) { XLALAppendResampInfo2File ( fpInfo, inputs->data[l] ); } REAL8 tauF1NoBuf_il, tauF1Buf_il; XLAL_CHECK ( XLALGetResampTimingInfo ( &tauF1NoBuf_il, &tauF1Buf_il, inputs->data[l] ) == XLAL_SUCCESS, XLAL_EFUNC ); tauF1NoBuf_i += tauF1NoBuf_il; tauF1Buf_i += tauF1Buf_il; } // for l < numSegments tauF1NoBuf_i /= uvar->numSegments; tauF1Buf_i /= uvar->numSegments; REAL8 memMaxCompute = XLALGetPeakHeapUsageMB() - memBase; tauF1Buf += tauF1Buf_i; tauF1NoBuf += tauF1NoBuf_i; fprintf (stderr, "%-15s: tauF1Buf = %.2g s, tauF1NoBuf = %.2g s, memSFTs = %.1f MB, memMaxCompute = %.1f MB\n", XLALGetFstatMethodName ( FstatMethod ), tauF1Buf_i, tauF1NoBuf_i, memSFTs, memMaxCompute ); XLALDestroyFstatInputVector ( inputs ); XLALDestroyFstatWorkspace ( sharedWorkspace ); optionalArgs.sharedWorkspace = NULL; } // for i < numTrials tauF1Buf /= uvar->numTrials; tauF1NoBuf /= uvar->numTrials; fprintf (stderr, "\nAveraged timings: <tauF1Buf> = %.2g s, <tauF1NoBuf> = %.2g s\n", tauF1Buf, tauF1NoBuf ); // ----- free memory ---------- if ( fpInfo != NULL ) { fclose ( fpInfo ); } for ( INT4 l = 0; l < uvar->numSegments; l ++ ) { XLALDestroySFTCatalog ( catalogs[l] ); } XLALFree ( catalogs ); XLALDestroyFstatResults ( results ); XLALDestroyUserVars(); XLALDestroyEphemerisData ( ephem ); LALCheckMemoryLeaks(); return XLAL_SUCCESS; } // main()
// ---------- main ---------- int main ( int argc, char *argv[] ) { XLAL_CHECK ( argc == 1, XLAL_EINVAL, "No input arguments allowed.\n" ); XLAL_CHECK ( argv != NULL, XLAL_EINVAL ); // ----- load ephemeris EphemerisData *ephem; XLAL_CHECK ( (ephem = XLALInitBarycenter ( TEST_DATA_DIR "earth00-19-DE405.dat.gz", TEST_DATA_DIR "sun00-19-DE405.dat.gz" )) != NULL, XLAL_EFUNC ); // ----- setup injection and data parameters LALStringVector *detNames = NULL; XLAL_CHECK ( (detNames = XLALCreateStringVector ( "H1", "L1", NULL )) != NULL, XLAL_EFUNC ); UINT4 numDetectors = detNames->length; // generate and assume some gaussian noise floors MultiNoiseFloor XLAL_INIT_DECL(injectSqrtSX); MultiNoiseFloor XLAL_INIT_DECL(assumeSqrtSX); injectSqrtSX.length = numDetectors; assumeSqrtSX.length = numDetectors; for ( UINT4 X = 0; X < numDetectors; X ++ ) { injectSqrtSX.sqrtSn[X] = 0; // don't inject random noise to keep errors deterministic and informative (resampling differs much more on noise) assumeSqrtSX.sqrtSn[X] = 1.0 + 2.0*X; } LIGOTimeGPS startTime = {711595934, 0}; REAL8 Tspan = 20 * 3600; LIGOTimeGPS endTime = startTime; XLALGPSAdd( &endTime, Tspan ); REAL8 Tsft = 1800; LIGOTimeGPS refTime = { startTime.gpsSeconds - 2.3 * Tspan, 0 }; MultiLIGOTimeGPSVector *multiTimestamps; XLAL_CHECK ( ( multiTimestamps = XLALCalloc ( 1, sizeof(*multiTimestamps))) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( ( multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(multiTimestamps->data[0]) )) != NULL, XLAL_ENOMEM ); multiTimestamps->length = numDetectors; LIGOTimeGPS startTimeX = startTime; for ( UINT4 X=0; X < numDetectors; X ++ ) { XLAL_CHECK ( (multiTimestamps->data[X] = XLALMakeTimestamps ( startTimeX, Tspan, Tsft, 0 ) ) != NULL, XLAL_EFUNC ); XLALGPSAdd ( &startTimeX, 0.5 * Tspan ); // shift start-times by 1/2 Tspan for each detector Tspan *= 2.0; } // for X < numDetectors // shift a few timestamps around to create gaps UINT4 numSFTsPerDet = multiTimestamps->data[0]->length; multiTimestamps->data[0]->data[numSFTsPerDet-1].gpsSeconds += 10000; multiTimestamps->data[0]->data[numSFTsPerDet-2].gpsSeconds += 5000; multiTimestamps->data[1]->data[0].gpsSeconds -= 10000; multiTimestamps->data[1]->data[1].gpsSeconds -= 5000; SFTCatalog *catalog; XLAL_CHECK ( (catalog = XLALMultiAddToFakeSFTCatalog ( NULL, detNames, multiTimestamps )) != NULL, XLAL_EFUNC ); // ----- CW sources to injet ---------- REAL8 Freq = 100.0; PulsarParamsVector *injectSources; XLAL_CHECK ( (injectSources = XLALCreatePulsarParamsVector(1)) != NULL, XLAL_EFUNC ); injectSources->data[0].Amp.h0 = 1; injectSources->data[0].Amp.cosi = 0.5; injectSources->data[0].Amp.psi = 0.1; injectSources->data[0].Amp.phi0 = 1.2; REAL8 asini = 0; // 1.4; // sco-X1 like REAL8 Period = 0; // 19 * 3600;// sco-X1 like REAL8 ecc = 0; // 0.1; // much larger than ScoX1 PulsarDopplerParams XLAL_INIT_DECL(Doppler); Doppler.Alpha = 0.5; Doppler.Delta = -0.5; Doppler.fkdot[0] = Freq; Doppler.fkdot[1] = -1e-9; Doppler.refTime = refTime; Doppler.asini = asini; Doppler.ecc = ecc; Doppler.tp = startTime; Doppler.period = Period; Doppler.argp = 0.5; injectSources->data[0].Doppler = Doppler; REAL8 dFreq = 0.1 / Tspan; // 10x finer than native FFT resolution REAL8 mis = 0.5; REAL8 df1dot = sqrt( 720.0 * mis ) / (LAL_PI * Tspan * Tspan); // metric (f-projected) stepsize for given mismatch mis REAL8 dSky = 1e4 / (Freq * Tspan); // rough estimate of a 'metric' sky step, eg. Eq.(118) in \cite Prix07 REAL8 dPeriod = 3600; UINT4 numFreqBins = 1000; UINT4 numf1dotPoints = 2; UINT4 numSkyPoints = 2; UINT4 numPeriodPoints = 2; PulsarSpinRange XLAL_INIT_DECL(spinRange); spinRange.refTime = refTime; memcpy ( &spinRange.fkdot, &injectSources->data[0].Doppler.fkdot, sizeof(spinRange.fkdot) ); spinRange.fkdotBand[0] = (numFreqBins - 1)*dFreq - 10*LAL_REAL8_EPS; spinRange.fkdotBand[1] = (numf1dotPoints - 1)*df1dot - 10*LAL_REAL8_EPS; Doppler.fkdot[0] -= 0.4 * spinRange.fkdotBand[0]; REAL8 minCoverFreq, maxCoverFreq; XLAL_CHECK ( XLALCWSignalCoveringBand ( &minCoverFreq, &maxCoverFreq, &startTime, &endTime, &spinRange, asini, Period, ecc ) == XLAL_SUCCESS, XLAL_EFUNC ); // ----- setup optional Fstat arguments FstatOptionalArgs optionalArgs = FstatOptionalArgsDefaults; optionalArgs.injectSources = injectSources; optionalArgs.injectSqrtSX = &injectSqrtSX; optionalArgs.assumeSqrtSX = &assumeSqrtSX; // ----- prepare input data with injection for all available methods FstatInput *input[FMETHOD_END]; FstatResults *results[FMETHOD_END]; for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { results[iMethod] = NULL; if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } optionalArgs.FstatMethod = iMethod; XLAL_CHECK ( (input[iMethod] = XLALCreateFstatInput ( catalog, minCoverFreq, maxCoverFreq, dFreq, ephem, &optionalArgs )) != NULL, XLAL_EFUNC ); } FstatQuantities whatToCompute = (FSTATQ_2F | FSTATQ_FAFB); // ----- loop over all templates {sky, f1dot, period} for ( UINT4 iSky = 0; iSky < numSkyPoints; iSky ++ ) { for ( UINT4 if1dot = 0; if1dot < numf1dotPoints; if1dot ++ ) { for ( UINT4 iPeriod = 0; iPeriod < numPeriodPoints; iPeriod ++ ) { // ----- loop over all available methods and compare Fstat results FstatMethodType firstMethod = FMETHOD_START; for ( UINT4 iMethod = FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } if ( firstMethod == FMETHOD_START ) { // keep track of first available method found firstMethod = iMethod; } XLAL_CHECK ( XLALComputeFstat ( &results[iMethod], input[iMethod], &Doppler, numFreqBins, whatToCompute ) == XLAL_SUCCESS, XLAL_EFUNC ); if ( lalDebugLevel & LALINFOBIT ) { FILE *fp; char fname[1024]; XLAL_INIT_MEM ( fname ); snprintf ( fname, sizeof(fname)-1, "twoF%s-iSky%02d-if1dot%02d-iPeriod%02d.dat", XLALGetFstatMethodName(iMethod), iSky, if1dot, iPeriod ); XLAL_CHECK ( (fp = fopen ( fname, "wb" )) != NULL, XLAL_EFUNC ); for ( UINT4 k = 0; k < results[iMethod]->numFreqBins; k ++ ) { REAL8 Freq0 = results[iMethod]->doppler.fkdot[0]; REAL8 Freq_k = Freq0 + k * results[iMethod]->dFreq; if ( whatToCompute & FSTATQ_FAFB ) { fprintf ( fp, "%20.16g %10.4g %10.4g %10.4g %10.4g %10.4g\n", Freq_k, results[iMethod]->twoF[k], crealf(results[iMethod]->Fa[k]), cimagf(results[iMethod]->Fa[k]), crealf(results[iMethod]->Fb[k]), cimagf(results[iMethod]->Fb[k]) ); } else { fprintf ( fp, "%20.16g %10.4g\n", Freq_k, results[iMethod]->twoF[k] ); } } // for k < numFreqBins fclose(fp); } // if info // compare to first result if ( iMethod != firstMethod ) { XLALPrintInfo ("Comparing results between method '%s' and '%s'\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) ); if ( compareFstatResults ( results[firstMethod], results[iMethod] ) != XLAL_SUCCESS ) { XLALPrintError ("Comparison between method '%s' and '%s' failed\n", XLALGetFstatMethodName(firstMethod), XLALGetFstatMethodName(iMethod) ); XLAL_ERROR ( XLAL_EFUNC ); } } } // for i < FMETHOD_END Doppler.period += dPeriod; } // for iPeriod < numPeriodPoints Doppler.fkdot[1] += df1dot; } // for if1dot < numf1dotPoints Doppler.Alpha += dSky; } // for iSky < numSkyPoints // free remaining memory for ( UINT4 iMethod=FMETHOD_START; iMethod < FMETHOD_END; iMethod ++ ) { if ( !XLALFstatMethodIsAvailable(iMethod) ) { continue; } XLALDestroyFstatInput ( input[iMethod] ); XLALDestroyFstatResults ( results[iMethod] ); } // for i < FMETHOD_END XLALDestroyPulsarParamsVector ( injectSources ); XLALDestroySFTCatalog ( catalog ); XLALDestroyMultiTimestamps ( multiTimestamps ); XLALDestroyStringVector ( detNames ); XLALDestroyEphemerisData ( ephem ); LALCheckMemoryLeaks(); return XLAL_SUCCESS; } // main()