/** * Parse string-vectors (typically input by user) of N detector noise-floors \f$\sqrt{S_X}\f$ * for detectors \f$X=1\ldots N\f$, where here we assume equal number of SFTs per detector * such that \f$S^{-1} = \frac{1}{N}\sum_{X=0}^{N-1} S_X^{-1}\f$. * * The detectors corresponding to each noise-floor may be a subset of the input string-vectors, * e.g. if parsing noise-floors for a segment where SFTs from some detectors are missing. * The vector \p */ int XLALParseMultiNoiseFloorMapped ( MultiNoiseFloor *multiNoiseFloor, /**< [out] parsed multi-IFO noise floor info */ const LALStringVector *multiNoiseFloorDetNames, /**< [in] detector names for entries in \p multiNoiseFloor */ const LALStringVector *sqrtSX, /**< [in] string-list of \f$\sqrt{S_X}\f$ for detectors \f$X\f$ */ const LALStringVector *sqrtSXDetNames /**< [in] detector names for entries in \p sqrtSX */ ) { XLAL_CHECK ( multiNoiseFloor != NULL, XLAL_EINVAL ); XLAL_CHECK ( multiNoiseFloorDetNames != NULL, XLAL_EINVAL ); XLAL_CHECK ( sqrtSX != NULL, XLAL_EINVAL ); XLAL_CHECK ( sqrtSXDetNames != NULL, XLAL_EINVAL ); XLAL_CHECK ( multiNoiseFloorDetNames->length <= sqrtSXDetNames->length, XLAL_EINVAL ); XLAL_CHECK ( sqrtSX->length == sqrtSXDetNames->length, XLAL_EINVAL ); /* parse input strings */ REAL8 sqrtSn[PULSAR_MAX_DETECTORS]; for ( UINT4 Y = 0; Y < sqrtSX->length; Y ++ ) { XLAL_CHECK ( XLALParseStringValueAsREAL8 ( &sqrtSn[Y], sqrtSX->data[Y] ) == XLAL_SUCCESS, XLAL_EFUNC ); XLAL_CHECK ( sqrtSn[Y] >= 0, XLAL_EDOM ); } /* initialize empty return struct */ multiNoiseFloor->length = multiNoiseFloorDetNames->length; /* fill multiNoiseFloor with correctly mapped values */ for ( UINT4 X = 0; X < multiNoiseFloor->length; X ++ ) { const INT4 Y = XLALFindStringInVector( multiNoiseFloorDetNames->data[X], sqrtSXDetNames ); if ( Y < 0 ) { char *sqrtSXDet = XLALConcatStringVector( sqrtSXDetNames, "," ); XLAL_PRINT_ERROR ( "Noise-floor detector '%s' not found in list of sqrtSX detectors '%s'", multiNoiseFloorDetNames->data[X], sqrtSXDet ); XLALFree ( sqrtSXDet ); XLAL_ERROR ( XLAL_EINVAL ); } multiNoiseFloor->sqrtSn[X] = sqrtSn[Y]; } return XLAL_SUCCESS; } /* XLALParseMultiNoiseFloorMapped() */
/// /// 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; }