/// /// 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; }
/** * Handle user-input and set up shop accordingly, and do all * consistency-checks on user-input. */ int XLALInitMakefakedata ( ConfigVars_t *cfg, UserVariables_t *uvar ) { XLAL_CHECK ( cfg != NULL, XLAL_EINVAL, "Invalid NULL input 'cfg'\n" ); XLAL_CHECK ( uvar != NULL, XLAL_EINVAL, "Invalid NULL input 'uvar'\n"); cfg->VCSInfoString = XLALGetVersionString(0); XLAL_CHECK ( cfg->VCSInfoString != NULL, XLAL_EFUNC, "XLALGetVersionString(0) failed.\n" ); // version info was requested: output then exit if ( uvar->version ) { printf ("%s\n", cfg->VCSInfoString ); exit (0); } /* if requested, log all user-input and code-versions */ if ( uvar->logfile ) { XLAL_CHECK ( XLALWriteMFDlog ( uvar->logfile, cfg ) == XLAL_SUCCESS, XLAL_EFUNC, "XLALWriteMFDlog() failed with xlalErrno = %d\n", xlalErrno ); } /* Init ephemerides */ XLAL_CHECK ( (cfg->edat = XLALInitBarycenter ( uvar->ephemEarth, uvar->ephemSun )) != NULL, XLAL_EFUNC ); /* check for negative fMin and Band, which would break the fMin_eff, fBand_eff calculation below */ XLAL_CHECK ( uvar->fmin >= 0, XLAL_EDOM, "Invalid negative frequency fMin=%f!\n\n", uvar->fmin ); XLAL_CHECK ( uvar->Band > 0, XLAL_EDOM, "Invalid non-positive frequency band Band=%f!\n\n", uvar->Band ); // ---------- check user-input consistency ---------- // ----- check if frames + frame channels given BOOLEAN have_frames = (uvar->inFrames != NULL); BOOLEAN have_channels= (uvar->inFrChannels != NULL); XLAL_CHECK ( !(have_frames || have_channels) || (have_frames && have_channels), XLAL_EINVAL, "Need both --inFrames and --inFrChannels, or NONE\n"); // ----- IFOs : only from one of {--IFOs, --noiseSFTs, --inFrChannels}: mutually exclusive BOOLEAN have_IFOs = (uvar->IFOs != NULL); BOOLEAN have_noiseSFTs = (uvar->noiseSFTs != NULL); XLAL_CHECK ( have_frames || have_IFOs || have_noiseSFTs, XLAL_EINVAL, "Need one of --IFOs, --noiseSFTs or --inFrChannels to determine detectors\n"); if ( have_frames ) { XLAL_CHECK ( !have_IFOs && !have_noiseSFTs, XLAL_EINVAL, "If --inFrames given, cannot handle --IFOs or --noiseSFTs input\n"); XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->inFrChannels ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { // !have_frames XLAL_CHECK ( !(have_IFOs && have_noiseSFTs), XLAL_EINVAL, "Cannot handle both --IFOs and --noiseSFTs input\n"); } if ( have_IFOs ) { XLAL_CHECK ( XLALParseMultiLALDetector ( &(cfg->multiIFO), uvar->IFOs ) == XLAL_SUCCESS, XLAL_EFUNC ); } // ----- TIMESTAMPS: either from --timestampsFiles, --startTime+duration, or --noiseSFTs BOOLEAN have_startTime = XLALUserVarWasSet ( &uvar->startTime ); BOOLEAN have_duration = XLALUserVarWasSet ( &uvar->duration ); BOOLEAN have_timestampsFiles = ( uvar->timestampsFiles != NULL ); // need BOTH startTime+duration or none XLAL_CHECK ( ( have_duration && have_startTime) || !( have_duration || have_startTime ), XLAL_EINVAL, "Need BOTH {--startTime,--duration} or NONE\n"); // at least one of {startTime,timestamps,noiseSFTs,inFrames} required XLAL_CHECK ( have_timestampsFiles || have_startTime || have_noiseSFTs || have_frames, XLAL_EINVAL, "Need at least one of {--timestampsFiles, --startTime+duration, --noiseSFTs, --inFrames}\n" ); // don't allow timestamps + {startTime+duration OR noiseSFTs} XLAL_CHECK ( !have_timestampsFiles || !(have_startTime||have_noiseSFTs), XLAL_EINVAL, "--timestampsFiles incompatible with {--noiseSFTs or --startTime+duration}\n"); // note, however, that we DO allow --noiseSFTs and --startTime+duration, which will act as a constraint // on the noise-SFTs to load in // don't allow --SFToverlap with either --noiseSFTs OR --timestampsFiles XLAL_CHECK ( uvar->SFToverlap >= 0, XLAL_EDOM ); BOOLEAN haveOverlap = ( uvar->SFToverlap > 0 ); XLAL_CHECK ( !haveOverlap || !( have_noiseSFTs || have_timestampsFiles ), XLAL_EINVAL, "--SFToverlap incompatible with {--noiseSFTs or --timestampsFiles}\n" ); // now handle the 3 mutually-exclusive cases: have_noiseSFTs || have_timestampsFiles || have_startTime (only) if ( have_noiseSFTs ) { SFTConstraints XLAL_INIT_DECL(constraints); if ( have_startTime && have_duration ) // use optional (startTime+duration) as constraints, { LIGOTimeGPS minStartTime, maxStartTime; minStartTime = uvar->startTime; maxStartTime = uvar->startTime; XLALGPSAdd ( &maxStartTime, uvar->duration ); constraints.minStartTime = &minStartTime; constraints.maxStartTime = &maxStartTime; char bufGPS1[32], bufGPS2[32]; XLALPrintWarning ( "Only noise-SFTs between GPS [%s, %s] will be used!\n", XLALGPSToStr(bufGPS1, &minStartTime), XLALGPSToStr(bufGPS2, &maxStartTime) ); } /* if start+duration given */ XLAL_CHECK ( (cfg->noiseCatalog = XLALSFTdataFind ( uvar->noiseSFTs, &constraints )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( cfg->noiseCatalog->length > 0, XLAL_EINVAL, "No noise-SFTs matching (start+duration, timestamps) were found!\n" ); XLAL_CHECK ( (cfg->multiNoiseCatalogView = XLALGetMultiSFTCatalogView ( cfg->noiseCatalog )) != NULL, XLAL_EFUNC ); // extract multi-timestamps from the multi-SFT-catalog view XLAL_CHECK ( (cfg->multiTimestamps = XLALTimestampsFromMultiSFTCatalogView ( cfg->multiNoiseCatalogView )) != NULL, XLAL_EFUNC ); // extract IFOs from multi-SFT catalog XLAL_CHECK ( XLALMultiLALDetectorFromMultiSFTCatalogView ( &(cfg->multiIFO), cfg->multiNoiseCatalogView ) == XLAL_SUCCESS, XLAL_EFUNC ); } // endif have_noiseSFTs else if ( have_timestampsFiles ) { XLAL_CHECK ( (cfg->multiTimestamps = XLALReadMultiTimestampsFiles ( uvar->timestampsFiles )) != NULL, XLAL_EFUNC ); XLAL_CHECK ( (cfg->multiTimestamps->length > 0) && (cfg->multiTimestamps->data != NULL), XLAL_EINVAL, "Got empty timestamps-list from XLALReadMultiTimestampsFiles()\n" ); for ( UINT4 X=0; X < cfg->multiTimestamps->length; X ++ ) { cfg->multiTimestamps->data[X]->deltaT = uvar->Tsft; // Tsft information not given by timestamps-file } } // endif have_timestampsFiles else if ( have_startTime && have_duration ) { XLAL_CHECK ( ( cfg->multiTimestamps = XLALMakeMultiTimestamps ( uvar->startTime, uvar->duration, uvar->Tsft, uvar->SFToverlap, cfg->multiIFO.length )) != NULL, XLAL_EFUNC ); } // endif have_startTime // check if the user asked for Gaussian white noise to be produced (sqrtSn[X]!=0), otherwise leave noise-floors at 0 if ( uvar->sqrtSX != NULL ) { XLAL_CHECK ( XLALParseMultiNoiseFloor ( &(cfg->multiNoiseFloor), uvar->sqrtSX, cfg->multiIFO.length ) == XLAL_SUCCESS, XLAL_EFUNC ); } else { cfg->multiNoiseFloor.length = cfg->multiIFO.length; // values remain at their default sqrtSn[X] = 0; } #ifdef HAVE_LIBLALFRAME // if user requested time-series data from frames to be added: try to read the frames now if ( have_frames ) { UINT4 numDetectors = uvar->inFrChannels->length; XLAL_CHECK ( uvar->inFrames->length == numDetectors, XLAL_EINVAL, "Need equal number of channel names (%d) as frame specifications (%d)\n", uvar->inFrChannels->length, numDetectors ); XLAL_CHECK ( (cfg->inputMultiTS = XLALCalloc ( 1, sizeof(*cfg->inputMultiTS))) != NULL, XLAL_ENOMEM ); cfg->inputMultiTS->length = numDetectors; XLAL_CHECK ( (cfg->inputMultiTS->data = XLALCalloc ( numDetectors, sizeof(cfg->inputMultiTS->data[0]) )) != NULL, XLAL_ENOMEM ); if ( cfg->multiTimestamps == NULL ) { XLAL_CHECK ( (cfg->multiTimestamps = XLALCalloc ( 1, sizeof(*cfg->multiTimestamps) )) != NULL, XLAL_ENOMEM ); XLAL_CHECK ( (cfg->multiTimestamps->data = XLALCalloc ( numDetectors, sizeof(cfg->multiTimestamps->data[0]))) != NULL, XLAL_ENOMEM ); cfg->multiTimestamps->length = numDetectors; } for ( UINT4 X = 0; X < numDetectors; X ++ ) { LALCache *cache; XLAL_CHECK ( (cache = XLALCacheImport ( uvar->inFrames->data[X] )) != NULL, XLAL_EFUNC, "Failed to import cache file '%s'\n", uvar->inFrames->data[X] ); // this is a sorted cache, so extract its time-range: REAL8 cache_tStart = cache->list[0].t0; REAL8 cache_tEnd = cache->list[cache->length-1].t0 + cache->list[cache->length-1].dt; REAL8 cache_duration = (cache_tEnd - cache_tStart); LIGOTimeGPS ts_start; REAL8 ts_duration; // check that it's consistent with timestamps, if given, otherwise create timestamps from this if ( cfg->multiTimestamps->data[X] != NULL ) // FIXME: implicitly assumes timestamps are sorted, which is not guaranteed by timestamps-reading from file { const LIGOTimeGPSVector *timestampsX = cfg->multiTimestamps->data[X]; REAL8 tStart = XLALGPSGetREAL8( ×tampsX->data[0] ); REAL8 tEnd = XLALGPSGetREAL8( ×tampsX->data[timestampsX->length-1]) + timestampsX->deltaT; XLAL_CHECK ( tStart >= cache_tStart && tEnd <= cache_tEnd, XLAL_EINVAL, "Detector X=%d: Requested timestamps-range [%.0f, %.0f]s outside of cache range [%.0f,%.0f]s\n", X, tStart, tEnd, cache_tStart, cache_tEnd ); XLALGPSSetREAL8 ( &ts_start, tStart ); ts_duration = (tEnd - tStart); } else { XLALGPSSetREAL8 ( &ts_start, (REAL8)cache_tStart + 1); // cache times can apparently be by rounded up or down by 1s, so shift by 1s to be safe ts_duration = cache_duration - 1; XLAL_CHECK ( (cfg->multiTimestamps->data[X] = XLALMakeTimestamps ( ts_start, ts_duration, uvar->Tsft, uvar->SFToverlap ) ) != NULL, XLAL_EFUNC ); } // ----- now open frame stream and read *all* the data within this time-range [FIXME] ---------- LALFrStream *stream; XLAL_CHECK ( (stream = XLALFrStreamCacheOpen ( cache )) != NULL, XLAL_EFUNC, "Failed to open stream from cache file '%s'\n", uvar->inFrames->data[X] ); XLALDestroyCache ( cache ); const char *channel = uvar->inFrChannels->data[X]; size_t limit = 0; // unlimited read REAL8TimeSeries *ts; XLAL_CHECK ( (ts = XLALFrStreamInputREAL8TimeSeries ( stream, channel, &ts_start, ts_duration, limit )) != NULL, XLAL_EFUNC, "Frame reading failed for stream created for '%s': ts_start = {%d,%d}, duration=%.0f\n", uvar->inFrames->data[X], ts_start.gpsSeconds, ts_start.gpsNanoSeconds, ts_duration ); cfg->inputMultiTS->data[X] = ts; XLAL_CHECK ( XLALFrStreamClose ( stream ) == XLAL_SUCCESS, XLAL_EFUNC, "Stream closing failed for cache file '%s'\n", uvar->inFrames->data[X] ); } // for X < numDetectors } // if inFrames // if user requested timeseries *output* to frame files, handle deprecated options XLAL_CHECK ( !(uvar->TDDframedir && uvar->outFrameDir), XLAL_EINVAL, "Specify only ONE of {--TDDframedir or --outFrameDir} or NONE\n"); if ( uvar->TDDframedir ) { cfg->outFrameDir = uvar->TDDframedir; } else if ( uvar->outFrameDir ) { cfg->outFrameDir = uvar->outFrameDir; } #endif return XLAL_SUCCESS; } /* XLALInitMakefakedata() */