Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALFrame 3.0.7.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
frread.py
Go to the documentation of this file.
1# Copyright (C) 2013 Duncan Macleod
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with with program; see the file COPYING. If not, write to the
15# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16# MA 02110-1301 USA
17
18"""Wrappings of the LALFrame input methods for reading GWF files
19
20This module provides the read_timeseries function, the primary method
21by which users can load TimeSeries data from a variety of sources,
22including:
23 - a Gravitational-Wave Frame file (.gwf file extension)
24 - a LAL-format cache file (.lcf or .cache file extension)
25 - a LAL-format cache object (either XLALCache() or glue.lal.Cache [1]
26
27[1] https://www.lsc-group.phys.uwm.edu/daswg/projects/glue/doc/glue.lal.Cache-class.html
28"""
29
30import os
31import re
32
33import lal
34from lal import utils as lalutils
35
36try:
37 from glue import lal as gcache
38except ImportError:
39 _HAS_GLUE = False
40else:
41 _HAS_GLUE = True
42
43import lalframe
44from . import git_version
45__author__ = "Duncan Macleod <duncan.macleod@ligo.org>"
46__version__ = git_version.id
47__date__ = git_version.date
48
49__all__ = ['read_timeseries']
50
51
52def read_timeseries(source, channel, start=None, duration=None,
53 datatype=None, verbose=False):
54 r"""Read a TimeSeries of channel data from a source.
55
56 Acceptable sources are:
57 - a .gwf-format framefile (string ending in '.gwf')
58 - a LAL-format cache file (string ending in '.lcf' or '.cache')
59 - a lal.Cache object (either from SWIG-LAL or GLUE)
60
61 @param source
62 input source, see above for details
63 @param channel
64 string name of channel, e.g. 'L1:LDAS-STRAIN', or a list of channel
65 names
66 @param start
67 LIGOTimeGPS start time for output TimeSeries
68 @param duration
69 float duration (seconds) for output TimeSeries
70 @param datatype
71 datatype, either an integer from the LALTYPECODE, a string
72 matchine the corresponding type, or a numpy dtype
73 @param verbose
74 print verbose output, default: False
75
76 @returns a TimeSeries of the imported data
77
78 Example 1, reading from a frame file:
79
80 \code
81 >>> out = read_timeseries('L-R-1061499968-32.gwf', 'L1:PSL-ISS_PDB_OUT_DQ')
82 >>> print(type(out))
83 <type 'REAL4TimeSeries'>
84 >>> print(out.name, float(out.epoch), out.deltaT)
85 ('L1:PSL-ISS_PDB_OUT_DQ', 1061499968.0, 3.0517578125e-05)
86 \endcode
87
88 Example 2, reading from a cache:
89
90 \code
91 >>> import lal
92 >>> cache = lal.CacheGlob('/scratch/ER4/L0/L1/L-R-10614', 'L-R-1061499968*')
93 >>> out = frread.read_timeseries(cache, 'L1:PSL-ISS_PDB_OUT_DQ')
94 >>> print(out.name, float(out.epoch), out.deltaT)
95 ('L1:PSL-ISS_PDB_OUT_DQ', 1061499968.0, 3.0517578125e-05)
96 \endcode
97
98 Example 3, restricting data input:
99
100 \code
101 >>> out = read_timeseries('L-R-1061499968-32.gwf', 'L1:PSL-ISS_PDB_OUT_DQ',
102 start=1061499970, duration=10)
103 >>> print(out.name, float(out.epoch), out.data.length)
104 ('L1:PSL-ISS_PDB_OUT_DQ', 1061499970.0, 327680)
105 \endcode
106
107 Example 4, specifying data type:
108
109 \code
110 >>> out = read_timeseries('L-R-1061499968-32.gwf',
111 'L1:PSL-ODC_CHANNEL_OUT_DQ')
112 >>> print(type(out), out.data.data[:4])
113 (<type 'REAL4TimeSeries'>,
114 array([ 4259839., 4259839., 4259839., 4259839.], dtype=float32))
115 >>> out = read_timeseries('L-R-1061499968-32.gwf',
116 'L1:PSL-ODC_CHANNEL_OUT_DQ', datatype='int8')
117 >>> print(type(out), out.data.data[:4])
118 (<type 'INT8TimeSeries'>, array([4259839, 4259839, 4259839, 4259839]))
119 \endcode
121 """
122 # parse channels
123 if isinstance(channel, str):
124 channels = [channel]
125 else:
126 channels = list(channel)
127
128 # read cache file
129 if (isinstance(source, str) and
130 re.search(r'(.lcf|.cache)\Z', source)):
131 source = lal.CacheImport(os.path.expanduser(source))
132 # convert GLUE cache file
133 if _HAS_GLUE and isinstance(source, gcache.Cache):
134 source = lalutils.lalcache_from_gluecache(source)
135
136 # read from single frame
137 if isinstance(source, str) and source.endswith('.gwf'):
138 out = _ts_from_frame_file(source, channels, start=start,
139 duration=duration, datatype=datatype,
140 verbose=verbose)
141 # read from XLALCache
142 elif isinstance(source, lal.Cache):
143 out = _ts_from_cache(source, channels, start=start,
144 duration=duration, datatype=datatype,
145 verbose=verbose)
146 # otherwise barf
147 else:
148 raise ValueError("Cannot interpret source '%s'." % source)
149
150 # return
151 if isinstance(channel, str):
152 return out[0]
153 else:
154 return out
155
156
157def _ts_from_cache(cache, channels, start=None, duration=None, datatype=None,
158 verbose=False):
159 """Read a TimeSeries of channel data from a LAL Cache object
160
161 @param cache
162 XLALCache() containing list of GWF file paths
163 @param channels
164 list of channel names
165 @param start
166 LIGOTimeGPS start time for output TimeSeries
167 @param duration
168 float duration (seconds) for output TimeSeries
169 @param datatype
170 datatype, either an integer from the LALTYPECODE, a string
171 matchine the corresponding type, or a numpy dtype
172 @param verbose UNDOCUMENTED
173
174 @returns a TimeSeries of the imported data
175 """
176 # open the cache into a stream
177 stream = lalframe.FrStreamCacheOpen(cache)
178 # read the stream
179 return _ts_from_stream(stream, channels, start=start, duration=duration,
180 datatype=datatype, verbose=verbose)
181
182
183def _ts_from_frame_file(framefile, channels, start=None, duration=None,
184 datatype=None, verbose=False):
185 """Read a TimeSeries of channel data from a GWF-format framefile
186
187 @param framefile
188 path to GWF-format framefile to read
189 @param channels
190 list of channel names
191 @param start
192 LIGOTimeGPS start time for output TimeSeries
193 @param duration
194 float duration (seconds) for output TimeSeries
195 @param datatype
196 datatype, either an integer from the LALTYPECODE, a string
197 matchine the corresponding type, or a numpy dtype
198 @param verbose
199 print verbose output, default: False
200
201 @returns a TimeSeries of the imported data
202 """
203 # open the file into a stream
204 framefile = os.path.abspath(framefile)
205 stream = lalframe.FrStreamOpen('', framefile)
206 # read the stream
207 return _ts_from_stream(stream, channels, start=start, duration=duration,
208 datatype=datatype, verbose=verbose)
209
210
211def _ts_from_stream(stream, channels, start=None, duration=None, datatype=None,
212 verbose=False):
213 """Read a TimeSeries of channel data from an open FrStream
214
215 @param stream
216 XLALFrStream() of data from which to read
217 @param channels
218 list of channel names
219 @param start
220 LIGOTimeGPS start time for output TimeSeries
221 @param duration
222 float duration (seconds) for output TimeSeries
223 @param datatype
224 datatype, either an integer from the LALTYPECODE, a string
225 matchine the corresponding type, or a numpy dtype
226 @param verbose
227 print verbose output, default: False
228
229 @returns a TimeSeries of the imported data
230 """
231 # set verbosity
232 lalframe.FrStreamSetMode(
233 stream,
234 verbose and lalframe.FR_STREAM_VERBOSE_MODE
235 or lalframe.FR_STREAM_DEFAULT_MODE,
236 )
237 # determine default start time and duration
238 epoch = lal.LIGOTimeGPS(stream.epoch)
239 if start is None:
240 start = epoch
241 if not duration:
242 startoffset = float(start - epoch)
243 duration = float(get_stream_duration(stream)) - startoffset
244
245 out = []
246 for channel in channels:
247 out.append(read_channel_from_stream(stream, channel, start, duration,
248 datatype=datatype))
249 lalframe.FrStreamSeek(stream, epoch)
250 return out
251
252
253def read_channel_from_stream(stream, channel, start, duration, datatype=None):
254 """Read the TimeSeries of a single channel from an open stream
255 """
256 # get series type
257 frdatatype = lalframe.FrStreamGetTimeSeriesType(channel, stream)
258 if datatype is None:
259 datatype = frdatatype
260 else:
261 datatype = lalutils.get_lal_type(datatype)
262
263 # read original data
264 read = getattr(lalframe, 'FrStreamRead%sTimeSeries'
265 % lalutils.get_lal_type_str(frdatatype))
266 origin = read(stream, channel, start, duration, 0)
267 # format to output data-type if required
268 if datatype == frdatatype:
269 return origin
270 if datatype != frdatatype:
271 create = lalutils.func_factory(
272 'create', '%stimeseries' % lalutils.get_lal_type_str(datatype))
273 series = create(channel, start, origin.f0, origin.deltaT,
274 origin.sampleUnits, origin.data.length)
275 series.data.data = origin.data.data.astype(
276 lalutils.get_numpy_type(datatype))
277 return series
278
279
280def get_stream_length(stream, channel):
281 """Find the number of samples represented in a frame stream
282
283 @param stream
284 XLALFrStream() of data to measure
285 @param channel
286 string name of channel to measure
287
288 @returns the integer length of the data for this channel
289 """
290 epoch = lal.LIGOTimeGPS(stream.epoch.gpsSeconds,
291 stream.epoch.gpsNanoSeconds)
292 # loop over each file in the stream cache and query its vector length
293 nfile = stream.cache.length
294 length = 0
295 for i in range(nfile):
296 for j in range(lalframe.FrFileQueryNFrame(stream.file)):
297 length += lalframe.FrFileQueryChanVectorLength(stream.file,
298 channel,0)
299 lalframe.FrStreamNext(stream)
300 # rewind the stream and return
301 lalframe.FrStreamSeek(stream, epoch)
302 return length
303
304
305def get_stream_duration(stream):
306 """Find the duration of time stored in a frame stream
307
308 @param stream
309 XLALFrStream() of data to measure
310
311 @returns the float duration (seconds) of the data for this channel
312 """
313 epoch = lal.LIGOTimeGPS(stream.epoch.gpsSeconds,
314 stream.epoch.gpsNanoSeconds)
315 # loop over each file in the stream cache and query its duration
316 nfile = stream.cache.length
317 duration = 0
318 for i in range(nfile):
319 for j in range(lalframe.FrFileQueryNFrame(stream.file)):
320 duration += lalframe.FrFileQueryDt(stream.file, 0)
321 lalframe.FrStreamNext(stream)
322 # rewind stream and return
323 lalframe.FrStreamSeek(stream, epoch)
324 return duration
def get_stream_duration(stream)
Find the duration of time stored in a frame stream.
Definition: frread.py:312
def read_channel_from_stream(stream, channel, start, duration, datatype=None)
Read the TimeSeries of a single channel from an open stream.
Definition: frread.py:255
def get_stream_length(stream, channel)
Find the number of samples represented in a frame stream.
Definition: frread.py:289
def read_timeseries(source, channel, start=None, duration=None, datatype=None, verbose=False)
Read a TimeSeries of channel data from a source.
Definition: frread.py:121