def fromarray(array, name="", epoch=lal.LIGOTimeGPS(), f0=0, deltaT=1,\ sampleUnits=lal.DimensionlessUnit, frequencyseries=False): """ Convert numpy.array to REAL8TimeSeries. Use frequencyseries to return REAL8FrequencySeries. Arguments: array : numpy.array input data array Keyword arguments: name : str name of data source epoch : lal.LIGOTimeGPS GPS start time for array deltaT : float sampling time for data (or frequency spacing for FrequencySeries) f0 : float lower frequency limit for data sampleUnits : lal.Unit amplitude unit for array """ if frequencyseries: series = lal.CreateREAL8FrequencySeries(name, epoch, f0, deltaT,\ sampleUnits, array.size) else: series = lal.CreateREAL8TimeSeries(name, epoch, f0, deltaT,\ sampleUnits, array.size) series.data.data = array.astype(float) return series
def fromNDS(chname, start, duration, server="nds.ligo.caltech.edu",\ port=31200): """ Read data from NDS into a REAL?TimeSeries """ import nds connection = nds.daq(server, port) data = connection.fetch(start, start + duration, chname)[0] epoch = lal.LIGOTimeGPS(start) deltaT = duration / data.size return fromarray(data, name=chname, epoch=epoch, deltaT=deltaT)
def to_lal_ligotimegps(gps): """Convert the given GPS time to a `lal.LIGOTimeGPS` object Parameters ---------- gps : `~gwpy.time.LIGOTimeGPS`, `float`, `str` input GPS time, can be anything parsable by :meth:`~gwpy.time.to_gps` Returns ------- ligotimegps : `lal.LIGOTimeGPS` a SWIG-LAL `~lal.LIGOTimeGPS` representation of the given GPS time """ gps = to_gps(gps) return lal.LIGOTimeGPS(gps.seconds, gps.nanoseconds)
def ts_from_stream(stream, channels, start=None, duration=None, datatype=None, verbose=False): """Read a TimeSeries of channel data from an open FrStream @param stream XLALFrStream() of data from which to read @param channels string name of channel, e.g. 'L1:LDAS-STRAIN', or list of channel names @param start LIGOTimeGPS start time for output TimeSeries @param duration float duration (seconds) for output TimeSeries @param datatype datatype, either an integer from the LALTYPECODE, a string matchine the corresponding type, or a numpy dtype @param verbose print verbose output, default: False @returns a TimeSeries of the imported data """ # set verbosity lalframe.FrSetMode( verbose and lalframe.FR_STREAM_VERBOSE_MODE or lalframe.FR_STREAM_DEFAULT_MODE, stream) # determine default start time and duration epoch = lal.LIGOTimeGPS(stream.epoch) if start is None: start = epoch if not duration: startoffset = float(start - epoch) duration = float(get_stream_duration(stream)) - startoffset out = [] for channel in channels: out.append( read_channel_from_stream(stream, channel, start, duration, datatype=datatype)) lalframe.FrStreamSeek(stream, epoch) return out
def get_stream_duration(stream): """Find the duration of time stored in a frame stream @param stream XLALFrStream() of data to measure @returns the float 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 i in range(nfile): for 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 get_stream_length(stream, channel): """Find the number of samples represented in a frame stream @param stream XLALFrStream() of data to measure @param channel string name of channel to measure @returns the integer length 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 vector length nfile = stream.cache.length length = 0 for i in range(nfile): for j in range(lalframe.FrFileQueryNFrame(stream.file)): length += lalframe.FrFileQueryChanVectorLength( stream.file, channel, 0) lalframe.FrStreamNext(stream) # rewind the stream and return lalframe.FrStreamSeek(stream, epoch) return length
def lal_psd(timeseries, segmentlength, noverlap=None, method='welch', window=None, plan=None): """Generate a PSD `Spectrum` using XLAL. Parameters ---------- timeseries : :class:`~gwpy.timeseries.TimeSeries` input `TimeSeries` data. method : `str` average method. segmentlength : `int` number of samples in single average. noverlap : `int` number of samples to overlap between segments, defaults to 50%. window : `tuple`, `str`, optional window parameters to apply to timeseries prior to FFT plan : :lal:`REAL8FFTPlan`, optional LAL FFT plan to use when generating average spectrum Returns ------- Spectrum average power `Spectrum` """ # get LAL from ..utils.lal import LAL_TYPE_STR_FROM_NUMPY # default to 50% overlap if noverlap is None: noverlap = int(segmentlength // 2) stride = segmentlength - noverlap # get cached window if window is None: window = generate_lal_window(segmentlength, dtype=timeseries.dtype) elif isinstance(window, (tuple, str)): window = generate_lal_window(segmentlength, type_=window, dtype=timeseries.dtype) # get cached FFT plan if plan is None: plan = generate_lal_fft_plan(segmentlength, dtype=timeseries.dtype) method = method.lower() # check data length size = timeseries.size numsegs = 1 + int((size - segmentlength) / stride) if method == 'median-mean' and numsegs % 2: numsegs -= 1 if not numsegs: raise ValueError("Cannot calculate median-mean spectrum with " "this small a TimeSeries.") required = int((numsegs - 1) * stride + segmentlength) if size != required: warnings.warn("Data array is the wrong size for the correct number " "of averages given the input parameters. The trailing " "%d samples will not be used in this calculation." % (size - required)) timeseries = timeseries[:required] laltypestr = LAL_TYPE_STR_FROM_NUMPY[timeseries.dtype.type] # generate output spectrum try: unit = lal.lalStrainUnit except AttributeError: unit = lal.StrainUnit create = getattr(lal, 'Create%sFrequencySeries' % laltypestr) lalfs = create(timeseries.name, lal.LIGOTimeGPS(timeseries.epoch.gps), 0, 1 / segmentlength, unit, int(segmentlength // 2 + 1)) # calculate medianmean spectrum if re.match('median-mean\Z', method, re.I): average_spectrum = getattr(lal, "%sAverageSpectrumMedianMean" % laltypestr) elif re.match('median\Z', method, re.I): average_spectrum = getattr(lal, "%sAverageSpectrumMedian" % laltypestr) elif re.match('welch\Z', method, re.I): average_spectrum = getattr(lal, "%sAverageSpectrumWelch" % laltypestr) else: raise NotImplementedError("Sorry, only 'median' and 'median-mean' " "and 'welch' average methods are available.") average_spectrum(lalfs, timeseries.to_lal(), segmentlength, stride, window, plan) # format and return spec = Spectrum.from_lal(lalfs) spec.channel = timeseries.channel spec._unit = scale_timeseries_units(timeseries.unit, scaling='density') return spec
def fromFrStream(stream, chname, start=-1, duration=1, datatype=-1,\ verbose=False): """ Read data from the lalframe.LALFrStream object stream into a REAL?TimeSeries. Restrict data with the gpsstart and duration parameters. Arguments: stream : lalframe.FrStream frame stream to read chname : str name of channel to read Keyword arguments: start : lal.LIGOTimeGPS GPS start time of requested data duration : float length of requested data series in seconds datatype : int LAL enum for requested datatype, -1 == read from frame metadata verbose : [ True | False ] verbose output """ # set mode if verbose: mode = lalframe.FR_STREAM_VERBOSE_MODE else: mode = lalframe.FR_STREAM_DEFAULT_MODE lalframe.FrSetMode(mode, stream) # set time if int(start) == -1: start = stream.epoch else: start = lal.LIGOTimeGPS(float(start)) duration = float(duration) lalframe.FrSeek(start, stream) # get series type frdatatype = lalframe.FrStreamGetTimeSeriesType(chname, stream) if datatype == -1: datatype = frdatatype TYPESTR = _typestr[datatype] # get data if frdatatype == datatype: func = getattr(lalframe, 'FrStreamRead%sTimeSeries' % TYPESTR) series = func(stream, chname, start, duration, 0) else: dblseries = lalframe.FrStreamInputREAL8TimeSeries( stream, chname, start, duration, 0) func = getattr(lal, 'Create%sTimeSeries' % TYPESTR) series = func(dblseries.name, dblseries.epoch, dblseries.f0,\ dblseries.deltaT, dblseries.sampleUnits,\ dblseries.data.length) series.data.data = dblseries.data.data.astype(type( series.data.data[0])) del dblseries # return return series