Round-trip write/read GWF fails when timeseries name and channel differ
When writing a TimeSeries
to GWF when the name
and channel
attributes differ, reading the data from the new file raises an unusual error:
>>> import numpy
>>> from gwpy.timeseries import TimeSeries
>>> data = TimeSeries(
... numpy.random.random(10),
... channel="X1:TEST",
... name="test",
... )
>>> data.write("test.gwf", format="gwf.framecpp", type="proc")
>>> new = type(data).read("test.gwf", "X1:TEST")
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-5ff61904bd82> in <module>
----> 1 new = type(data).read("test.gwf", "X1:TEST")
~/git/gwpy-fork5/gwpy/timeseries/core.py in read(cls, source, *args, **kwargs)
312 -----"""
313 from .io.core import read as timeseries_reader
--> 314 return timeseries_reader(cls, source, *args, **kwargs)
315
316 def write(self, target, *args, **kwargs):
~/git/gwpy-fork5/gwpy/timeseries/io/core.py in read(cls, source, *args, **kwargs)
48 )
49 # read
---> 50 return io_read_multi(joiner, cls, source, *args, **kwargs)
51
52
~/git/gwpy-fork5/gwpy/io/mp.py in read_multi(flatten, cls, source, *args, **kwargs)
91 # read files
92 output = mp_utils.multiprocess_with_queues(
---> 93 nproc, _read_single_file, inputs, verbose=verbose, unit='files')
94
95 # raise exceptions (from multiprocessing, single process raises inline)
~/git/gwpy-fork5/gwpy/utils/mp.py in multiprocess_with_queues(nproc, func, inputs, verbose, **progress_kw)
121 pbar.update(1)
122
--> 123 return list(map(_inner, inputs))
124
125 # -------------------------------------------
~/git/gwpy-fork5/gwpy/utils/mp.py in _inner(x)
116 def _inner(x):
117 try:
--> 118 return func(x)
119 finally:
120 if pbar:
~/git/gwpy-fork5/gwpy/io/mp.py in _read_single_file(bundle)
119 fobj, cls, nproc, args, kwargs = bundle
120 try:
--> 121 return fobj, io_read(cls, fobj, *args, **kwargs)
122 # pylint: disable=broad-except,redefine-in-handler
123 except Exception as exc:
~/opt/miniconda3/envs/py37/lib/python3.7/site-packages/astropy/io/registry.py in read(cls, format, *args, **kwargs)
521
522 reader = get_reader(format, cls)
--> 523 data = reader(*args, **kwargs)
524
525 if not isinstance(data, cls):
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/__init__.py in read_(*args, **kwargs)
399 fmt = 'gwf.{}'.format(get_default_gwf_api())
400 reader = get_reader(fmt, container)
--> 401 return reader(*args, **kwargs)
402
403 def write_(*args, **kwargs):
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/__init__.py in read_timeseries(source, channel, *args, **kwargs)
285 """Read `TimeSeries` from GWF source
286 """
--> 287 return read_timeseriesdict(source, [channel], *args, **kwargs)[channel]
288
289 def read_statevector(source, channel, *args, **kwargs):
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/__init__.py in read_timeseriesdict(source, channels, start, end, dtype, resample, gap, pad, nproc, series_class, **kwargs)
269 out[name] = numpy.require(out[name], requirements=['O'])
270 out.append(libread_(src, channels, start=start, end=end,
--> 271 series_class=series_class, **kwargs),
272 gap=gap, pad=pad, copy=False)
273
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/framecpp.py in read(source, channels, start, end, scaled, type, series_class)
116 # read frame
117 out.append(read_gwf(file_, channels, start=start, end=end, ctype=ctype,
--> 118 scaled=scaled, series_class=series_class),
119 copy=False)
120 return out
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/framecpp.py in read_gwf(filename, channels, start, end, scaled, ctype, series_class)
207
208 # if we have all of the data we want, stop now
--> 209 if all(span in out[channel].span for channel in out):
210 break
211
~/git/gwpy-fork5/gwpy/timeseries/io/gwf/framecpp.py in <genexpr>(.0)
207
208 # if we have all of the data we want, stop now
--> 209 if all(span in out[channel].span for channel in out):
210 break
211
AttributeError: 'numpy.ndarray' object has no attribute 'span'
This is all because the FrProcData
structure is created using the channel
string, while the FrVect
structures are tagged using the name
string. We should just the name
for everything, I think.