/** * @brief Seeks a LALFrStream stream by a time offset * @details * The position of a LALFrStream is set so that the net read will * be at the specified time offset. The offset @p dt is a number of * seconds relative to the @p whence postion, which can be * @p SEEK_SET to seek relative to the beginning of the stream, * @p SEEK_CUR to seek relative to the current position of the stream, * or @p SEEK_END to seek relative to the end of the stream. * The return codes and conditions are the same as XLALFrStreamSeek(). * @param stream Pointer to a #LALFrStream structure. * @param dt The offset time in seconds. * @param whence The position whence to seek: one of @p SEEK_SET, @p SEEK_CUR, * or @p SEEK_END. * @retval 3 Time requested is in a gap in the data. * @retval 2 Time requested is after the end of the stream. * @retval 1 Time requested is before the beginning of the stream. * @retval 0 Normal success. * @retval <0 Failure. */ int XLALFrStreamSeekO(LALFrStream * stream, double dt, int whence) { LIGOTimeGPS epoch; switch (whence) { case SEEK_SET: if (XLALFrStreamRewind(stream) < 0) XLAL_ERROR(XLAL_EFUNC); /* FALL THROUGH */ case SEEK_CUR: epoch = stream->epoch; break; case SEEK_END: /* go to the last frame */ XLALFrStreamFileClose(stream); if (XLALFrStreamFileOpen(stream, stream->cache->length - 1) < 0) XLAL_ERROR(XLAL_EFUNC); if ((stream->pos = XLALFrFileQueryNFrame(stream->file) - 1) < 0) XLAL_ERROR(XLAL_EFUNC); if (XLALFrFileQueryGTime(&epoch, stream->file, stream->pos) == NULL) XLAL_ERROR(XLAL_EFUNC); /* add duration of last frame to dt */ dt += XLALFrFileQueryDt(stream->file, stream->pos); break; default: XLAL_ERROR(XLAL_EINVAL, "Invalid whence value: use SEEK_SET, SEEK_CUR, or SEEK_END"); } XLALGPSAdd(&epoch, dt); if (XLALFrStreamSeek(stream, &epoch) < 0) XLAL_ERROR(XLAL_EFUNC); return 0; }
int XLALAddNumRelStrainModesREAL8( REAL8TimeSeries **seriesPlus, /**< [out] h+, hx data */ REAL8TimeSeries **seriesCross, /**< [out] h+, hx data */ SimInspiralTable *thisinj /**< [in] injection data */ ) { INT4 modeL, modeM, modeLlo, modeLhi; INT4 len, lenPlus, lenCross, k; CHAR *channel_name_plus; CHAR *channel_name_cross; LALFrStream *frStream = NULL; LALCache frCache; LIGOTimeGPS epoch; REAL8TimeSeries *modePlus=NULL; REAL8TimeSeries *modeCross=NULL; REAL8 massMpc, timeStep; modeLlo = thisinj->numrel_mode_min; modeLhi = thisinj->numrel_mode_max; /* create a frame cache and open the frame stream */ frCache.length = 1; frCache.list = LALCalloc(1, sizeof(frCache.list[0])); frCache.list[0].url = thisinj->numrel_data; frStream = XLALFrStreamCacheOpen( &frCache ); /* the total mass of the binary in Mpc */ massMpc = (thisinj->mass1 + thisinj->mass2) * LAL_MRSUN_SI / ( LAL_PC_SI * 1.0e6); /* Time step in dimensionful units */ timeStep = (thisinj->mass1 + thisinj->mass2) * LAL_MTSUN_SI; /* start time of waveform -- set it to something */ epoch.gpsSeconds = thisinj->geocent_end_time.gpsSeconds; epoch.gpsNanoSeconds = thisinj->geocent_end_time.gpsNanoSeconds; /* loop over l values */ for ( modeL = modeLlo; modeL <= modeLhi; modeL++ ) { /* loop over m values */ for ( modeM = -modeL; modeM <= modeL; modeM++ ) { /* read numrel waveform */ /* first the plus polarization */ channel_name_plus = XLALGetNinjaChannelName("plus", modeL, modeM); /*get number of data points */ if (XLALCheckFrameHasChannel(channel_name_plus, frStream ) ) { lenPlus = XLALFrStreamGetVectorLength ( channel_name_plus, frStream ); } else { lenPlus = -1; } /* now the cross polarization */ channel_name_cross = XLALGetNinjaChannelName("cross", modeL, modeM); /*get number of data points */ if (XLALCheckFrameHasChannel(channel_name_cross, frStream ) ) { lenCross = XLALFrStreamGetVectorLength ( channel_name_cross, frStream ); } else { lenCross = -1; } /* skip on to next mode if mode doesn't exist */ if ( (lenPlus <= 0) || (lenCross <= 0) || (lenPlus != lenCross) ) { XLALClearErrno(); LALFree(channel_name_plus); LALFree(channel_name_cross); continue; } /* note: lenPlus and lenCross must be equal if we got this far*/ len = lenPlus; /* allocate and read the plus/cross time series */ modePlus = XLALCreateREAL8TimeSeries ( channel_name_plus, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(modePlus->data->data, 0, modePlus->data->length*sizeof(REAL8)); XLALFrStreamGetREAL8TimeSeries ( modePlus, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_plus); modeCross = XLALCreateREAL8TimeSeries ( channel_name_cross, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(modeCross->data->data, 0, modeCross->data->length*sizeof(REAL8)); XLALFrStreamGetREAL8TimeSeries ( modeCross, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_cross); /* scale and add */ if (*seriesPlus == NULL) { *seriesPlus = XLALCreateREAL8TimeSeries ( "hplus", &epoch, 0, 0, &lalDimensionlessUnit, len); memset((*seriesPlus)->data->data, 0, (*seriesPlus)->data->length*sizeof(REAL8)); (*seriesPlus)->deltaT = modePlus->deltaT; } if (*seriesCross == NULL) { *seriesCross = XLALCreateREAL8TimeSeries ( "hcross", &epoch, 0, 0, &lalDimensionlessUnit, len); memset((*seriesCross)->data->data, 0, (*seriesCross)->data->length*sizeof(REAL8)); (*seriesCross)->deltaT = modeCross->deltaT; } XLALOrientNRWaveTimeSeriesREAL8( modePlus, modeCross, modeL, modeM, thisinj->inclination, thisinj->coa_phase ); for (k = 0; k < len; k++) { (*seriesPlus)->data->data[k] += massMpc * modePlus->data->data[k]; (*seriesCross)->data->data[k] += massMpc * modeCross->data->data[k]; } /* we are done with seriesPlus and Cross for this iteration */ XLALDestroyREAL8TimeSeries (modePlus); XLALDestroyREAL8TimeSeries (modeCross); } /* end loop over modeM values */ } /* end loop over modeL values */ (*seriesPlus)->deltaT *= timeStep; (*seriesCross)->deltaT *= timeStep; XLALFrStreamClose( frStream ); LALFree(frCache.list); return XLAL_SUCCESS; }
void AddNumRelStrainModes( LALStatus *status, /**< pointer to LALStatus structure */ REAL4TimeVectorSeries **outStrain, /**< [out] h+, hx data */ SimInspiralTable *thisinj /**< [in] injection data */) { INT4 modeL, modeM, modeLlo, modeLhi; INT4 len, lenPlus, lenCross, k; CHAR *channel_name_plus; CHAR *channel_name_cross; LALFrStream *frStream = NULL; LALCache frCache; LIGOTimeGPS epoch; REAL4TimeSeries *seriesPlus=NULL; REAL4TimeSeries *seriesCross=NULL; REAL8 massMpc; REAL4TimeVectorSeries *sumStrain=NULL; REAL4TimeVectorSeries *tempStrain=NULL; /* NRWaveMetaData thisMetaData; */ INITSTATUS(status); ATTATCHSTATUSPTR (status); modeLlo = thisinj->numrel_mode_min; modeLhi = thisinj->numrel_mode_max; /* create a frame cache and open the frame stream */ frCache.length = 1; frCache.list = LALCalloc(1, sizeof(frCache.list[0])); frCache.list[0].url = thisinj->numrel_data; frStream = XLALFrStreamCacheOpen( &frCache ); /* the total mass of the binary in Mpc */ massMpc = (thisinj->mass1 + thisinj->mass2) * LAL_MRSUN_SI / ( LAL_PC_SI * 1.0e6); /* start time of waveform -- set it to something */ epoch.gpsSeconds = 0; epoch.gpsNanoSeconds = 0; /* loop over l values */ for ( modeL = modeLlo; modeL <= modeLhi; modeL++ ) { /* loop over m values */ for ( modeM = -modeL; modeM <= modeL; modeM++ ) { /* read numrel waveform */ /* first the plus polarization */ channel_name_plus = XLALGetNinjaChannelName("plus", modeL, modeM); /*get number of data points */ lenPlus = XLALFrStreamGetVectorLength ( channel_name_plus, frStream ); /* now the cross polarization */ channel_name_cross = XLALGetNinjaChannelName("cross", modeL, modeM); /*get number of data points */ lenCross = XLALFrStreamGetVectorLength ( channel_name_cross, frStream ); /* skip on to next mode if mode doesn't exist */ if ( (lenPlus <= 0) || (lenCross <= 0) || (lenPlus != lenCross) ) { XLALClearErrno(); LALFree(channel_name_plus); LALFree(channel_name_cross); continue; } /* note: lenPlus and lenCross must be equal if we got this far*/ /* len = lenPlus; */ len = lenPlus; /* allocate and read the plus/cross time series */ seriesPlus = XLALCreateREAL4TimeSeries ( channel_name_plus, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(seriesPlus->data->data, 0, seriesPlus->data->length*sizeof(REAL4)); XLALFrStreamGetREAL4TimeSeries ( seriesPlus, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_plus); seriesCross = XLALCreateREAL4TimeSeries ( channel_name_cross, &epoch, 0, 0, &lalDimensionlessUnit, len); memset(seriesCross->data->data, 0, seriesCross->data->length*sizeof(REAL4)); XLALFrStreamGetREAL4TimeSeries ( seriesCross, frStream ); XLALFrStreamRewind( frStream ); LALFree(channel_name_cross); /* allocate memory for tempStrain */ tempStrain = LALCalloc(1, sizeof(*tempStrain)); tempStrain->data = XLALCreateREAL4VectorSequence(2, len); tempStrain->deltaT = LAL_MTSUN_SI * (thisinj->mass1 + thisinj->mass2) * seriesPlus->deltaT ; tempStrain->f0 = seriesPlus->f0; tempStrain->sampleUnits = seriesPlus->sampleUnits; memset(tempStrain->data->data, 0, tempStrain->data->length * tempStrain->data->vectorLength*sizeof(REAL4)); /* now copy the data and scale amplitude corresponding to distance of 1Mpc*/ for (k = 0; k < len; k++) { tempStrain->data->data[k] = massMpc * seriesPlus->data->data[k]; tempStrain->data->data[len + k] = massMpc * seriesCross->data->data[k]; } /* we are done with seriesPlus and Cross for this iteration */ XLALDestroyREAL4TimeSeries (seriesPlus); XLALDestroyREAL4TimeSeries (seriesCross); seriesPlus = NULL; seriesCross = NULL; /* compute the h+ and hx for given inclination and coalescence phase*/ XLALOrientNRWave( tempStrain, modeL, modeM, thisinj->inclination, thisinj->coa_phase ); if (sumStrain == NULL) { sumStrain = LALCalloc(1, sizeof(*sumStrain)); sumStrain->data = XLALCreateREAL4VectorSequence(2, tempStrain->data->vectorLength); sumStrain->deltaT = tempStrain->deltaT; sumStrain->f0 = tempStrain->f0; sumStrain->sampleUnits = tempStrain->sampleUnits; memset(sumStrain->data->data,0.0,2*tempStrain->data->vectorLength*sizeof(REAL4)); sumStrain = XLALSumStrain( sumStrain, tempStrain ); } else { sumStrain = XLALSumStrain( sumStrain, tempStrain ); } /* clear memory for strain */ if (tempStrain->data != NULL) { XLALDestroyREAL4VectorSequence ( tempStrain->data ); LALFree( tempStrain ); tempStrain = NULL; } } /* end loop over modeM values */ } /* end loop over modeL values */ XLALFrStreamClose( frStream ); LALFree(frCache.list); *outStrain = sumStrain; DETATCHSTATUSPTR(status); RETURN(status); }
/** * @brief Seeks a LALFrStream stream to data at a given time * @details * The position of a LALFrStream is set so that the net read will * be at the specified time. #LAL_FR_STREAM_END and #LAL_FR_STREAM_GAP * bits are turned off in the #LALFrStreamState state. If the time is before * the beginning of the stream, the stream position is set to the beginning of * the stream and the routine returns with code 1. If the time is after the * end of the stream, the #LAL_FR_STREAM_END bit is set in the * #LALFrStreamState state, and the routine returns with code 2. If the time * is in a gap in the data, the #LAL_FR_STREAM_GAP bit is set in the * #LALFrStreamState state, the position is advanced to the next data, and the * routine returns with code 3. If, however, the * #LAL_FR_STREAM_IGNORETIME_MODE bit is not set in the LALFrStreamMode mode * then these conditions result in an error. * @param stream Pointer to a #LALFrStream structure. * @param epoch The LIGOTimeGPS time of the next data to read. * @retval 3 Time requested is in a gap in the data. * @retval 2 Time requested is after the end of the stream. * @retval 1 Time requested is before the beginning of the stream. * @retval 0 Normal success. * @retval <0 Failure. */ int XLALFrStreamSeek(LALFrStream * stream, const LIGOTimeGPS * epoch) { double twant = XLALGPSGetREAL8(epoch); LALCacheEntry *entry; /* close file if one is open */ XLALFrStreamFileClose(stream); /* clear EOF or GAP states; preserve ERR state */ if (stream->state & LAL_FR_STREAM_ERR) stream->state = LAL_FR_STREAM_ERR; else stream->state = LAL_FR_STREAM_OK; /* is epoch before first file? */ if (epoch->gpsSeconds < stream->cache->list->t0) { XLALFrStreamRewind(stream); stream->state |= LAL_FR_STREAM_GAP; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d before first frame", epoch->gpsSeconds); return 1; /* before first file code */ } /* seek for the time in the cache */ entry = XLALCacheEntrySeek(stream->cache, twant); if (!entry) { /* seek failed: only happens if time is past end of cache */ stream->fnum = stream->cache->length; stream->epoch = *epoch; stream->state |= LAL_FR_STREAM_END; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d after last frame", epoch->gpsSeconds); return 2; /* after last file code */ } /* now we must find the position within the frame file */ for (stream->fnum = entry - stream->cache->list; stream->fnum < stream->cache->length; ++stream->fnum) { /* check the file contents to determine the position that matches */ size_t nFrame; if (XLALFrStreamFileOpen(stream, stream->fnum) < 0) XLAL_ERROR(XLAL_EFUNC); if (epoch->gpsSeconds < stream->cache->list[stream->fnum].t0) { /* detect a gap between files */ stream->state |= LAL_FR_STREAM_GAP; break; } nFrame = XLALFrFileQueryNFrame(stream->file); for (stream->pos = 0; stream->pos < (int)nFrame; ++stream->pos) { LIGOTimeGPS start; int cmp; XLALFrFileQueryGTime(&start, stream->file, stream->pos); cmp = XLALGPSCmp(epoch, &start); if (cmp >= 0 && XLALGPSDiff(epoch, &start) < XLALFrFileQueryDt(stream->file, stream->pos)) break; /* this is the frame! */ if (cmp < 0) { /* detect a gap between frames within a file */ stream->state |= LAL_FR_STREAM_GAP; break; } } if (stream->pos < (int)nFrame) /* we've found the frame */ break; /* oops... not in this frame file, go on to the next one */ /* probably the frame file was mis-named.... */ XLALFrStreamFileClose(stream); } if (stream->fnum >= stream->cache->length) { /* we've gone right to the end without finding it! */ stream->fnum = stream->cache->length; stream->epoch = *epoch; stream->state |= LAL_FR_STREAM_END; /* is this reported as an error? */ if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) { /* FIXME: if this is an error, should the stream state say so? */ /* stream->state |= LAL_FR_STREAM_ERR; */ XLAL_ERROR(XLAL_ETIME); } if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %d after last frame", epoch->gpsSeconds); return 2; /* after last file code */ } /* set the time of the stream */ if (stream->state & LAL_FR_STREAM_GAP) { XLALFrFileQueryGTime(&stream->epoch, stream->file, stream->pos); if (stream->mode & LAL_FR_STREAM_TIMEWARN_MODE) XLAL_PRINT_WARNING("Requested time %.6f in gap in frame data", twant); if (!(stream->mode & LAL_FR_STREAM_IGNORETIME_MODE)) XLAL_ERROR(XLAL_ETIME); return 3; /* in a gap code */ } stream->epoch = *epoch; return 0; }