def read(source, channels, start=None, end=None, series_class=TimeSeries, scaled=None): """Read data from one or more GWF files using the LALFrame API """ # scaled must be provided to provide a consistent API with frameCPP if scaled is not None: warnings.warn( "the `scaled` keyword argument is not supported by lalframe, " "if you require ADC scaling, please install " "python-ldas-tools-framecpp", ) stream = open_data_source(source) # parse times and restrict to available data epoch = lal.LIGOTimeGPS(stream.epoch.gpsSeconds, stream.epoch.gpsNanoSeconds) streamdur = get_stream_duration(stream) if start is None: start = epoch start = max(epoch, lalutils.to_lal_ligotimegps(start)) if end is None: end = epoch + streamdur duration = float(end - start) # read data out = series_class.DictClass() for name in channels: out[name] = series_class.from_lal( _read_channel(stream, str(name), start=start, duration=duration), copy=False) lalframe.FrStreamSeek(stream, epoch) return out
def get_stream_duration(stream): """Find the duration of time stored in a frame stream Parameters ---------- stream : `lal.FrStream` stream of data to search Returns ------- duration : `float` the duration (seconds) of the data for this channel """ epoch = lal.LIGOTimeGPS(stream.epoch.gpsSeconds, stream.epoch.gpsNanoSeconds) # loop over each file in the stream cache and query its duration nfile = stream.cache.length duration = 0. for dummy_i in range(nfile): for dummy_j in range(lalframe.FrFileQueryNFrame(stream.file)): duration += lalframe.FrFileQueryDt(stream.file, 0) lalframe.FrStreamNext(stream) # rewind stream and return lalframe.FrStreamSeek(stream, epoch) return duration
def read(source, channels, start=None, end=None, series_class=TimeSeries): """Read data from one or more GWF files using the LALFrame API """ stream = open_data_source(source) # parse times and restrict to available data epoch = lal.LIGOTimeGPS(stream.epoch.gpsSeconds, stream.epoch.gpsNanoSeconds) streamdur = get_stream_duration(stream) if start is None: start = epoch else: start = max(epoch, lalutils.to_lal_ligotimegps(start)) if end is None: offset = float(start - epoch) duration = streamdur - offset else: end = min(epoch + streamdur, end) duration = float(end - start) # read data out = series_class.DictClass() for name in channels: out[name] = series_class.from_lal(_read_channel(stream, str(name), start=start, duration=duration), copy=False) lalframe.FrStreamSeek(stream, epoch) return out
def read_frame(location, channels, start_time=None, end_time=None, duration=None, check_integrity=True): """Read time series from frame data. Using the `location`, which can either be a frame file ".gwf" or a frame cache ".gwf", read in the data for the given channel(s) and output as a TimeSeries or list of TimeSeries. Parameters ---------- location : string A source of gravitational wave frames. Either a frame filename (can include pattern), a list of frame files, or frame cache file. channels : string or list of strings Either a string that contains the channel name or a list of channel name strings. start_time : {None, LIGOTimeGPS}, optional The gps start time of the time series. Defaults to reading from the beginning of the available frame(s). end_time : {None, LIGOTimeGPS}, optional The gps end time of the time series. Defaults to the end of the frame. Note, this argument is incompatible with `duration`. duration : {None, float}, optional The amount of data to read in seconds. Note, this argument is incompatible with `end`. check_integrity : {True, bool}, optional Test the frame files for internal integrity. Returns ------- Frame Data: TimeSeries or list of TimeSeries A TimeSeries or a list of TimeSeries, corresponding to the data from the frame file/cache for a given channel or channels. """ if end_time and duration: raise ValueError("end time and duration are mutually exclusive") if type(location) is list: locations = location else: locations = [location] cum_cache = locations_to_cache(locations) stream = lalframe.FrStreamCacheOpen(cum_cache) stream.mode = lalframe.FR_STREAM_VERBOSE_MODE if check_integrity: stream.mode = (stream.mode | lalframe.FR_STREAM_CHECKSUM_MODE) lalframe.FrSetMode(stream.mode, stream) # determine duration of data if type(channels) is list: first_channel = channels[0] else: first_channel = channels data_length = lalframe.FrStreamGetVectorLength(first_channel, stream) channel_type = lalframe.FrStreamGetTimeSeriesType(first_channel, stream) create_series_func = _fr_type_map[channel_type][2] get_series_metadata_func = _fr_type_map[channel_type][3] series = create_series_func(first_channel, stream.epoch, 0, 0, lal.ADCCountUnit, 0) get_series_metadata_func(series, stream) data_duration = data_length * series.deltaT if start_time is None: start_time = stream.epoch*1 if end_time is None: end_time = start_time + data_duration if type(start_time) is not lal.LIGOTimeGPS: start_time = lal.LIGOTimeGPS(start_time) if type(end_time) is not lal.LIGOTimeGPS: end_time = lal.LIGOTimeGPS(end_time) if duration is None: duration = float(end_time - start_time) else: duration = float(duration) # lalframe behaves dangerously with invalid duration so catch it here if duration <= 0: raise ValueError("Negative or null duration") #if duration > data_duration: # raise ValueError("Requested duration longer than available data") if type(channels) is list: all_data = [] for channel in channels: channel_data = _read_channel(channel, stream, start_time, duration) lalframe.FrStreamSeek(stream, start_time) all_data.append(channel_data) return all_data else: return _read_channel(channels, stream, start_time, duration)