22Code to assist in reading and writing LAL time- and frequency series data
23encoded in LIGO Light-Weight XML format. The format recognized by the code
24in this module
is the same
as generated by the array-related functions
in
25LAL
's XML I/O code. The format is also very similar to the format used by
26the DMT to store time- and frequency-series data
in XML files,
30from igwn_ligolw import ligolw
35Attributes = ligolw.sax.xmlreader.AttributesImpl
39# =============================================================================
47def _build_series(series, dim_names, comment, delta_name, delta_unit, encoding="Text"):
48 elem = ligolw.LIGO_LW(
Attributes({
u"Name": str(series.__class__.__name__)}))
49 if comment
is not None:
50 elem.appendChild(ligolw.Comment()).pcdata = comment
51 elem.appendChild(ligolw.Time.from_gps(series.epoch,
u"epoch"))
52 elem.appendChild(ligolw.Param.from_pyvalue(
u"f0", series.f0, unit=
u"s^-1"))
53 delta = getattr(series, delta_name)
54 if np.iscomplexobj(series.data.data):
55 data = np.vstack((np.arange(len(series.data.data)) * delta, series.data.data.real, series.data.data.imag))
57 data = np.vstack((np.arange(len(series.data.data)) * delta, series.data.data))
58 a = ligolw.Array.build(series.name, data, dim_names=dim_names, encoding=encoding)
59 a.Unit = str(series.sampleUnits)
60 dim0 = a.getElementsByTagName(ligolw.Dim.tagName)[0]
61 dim0.Unit = delta_unit
62 dim0.Start = series.f0
68def _parse_series(elem, creatorfunc, delta_target_unit_string):
69 t, = elem.getElementsByTagName(ligolw.Time.tagName)
70 a, = elem.getElementsByTagName(ligolw.Array.tagName)
71 dims = a.getElementsByTagName(ligolw.Dim.tagName)
72 f0 = ligolw.Param.get_param(elem,
u"f0")
75 raise ValueError(
"epoch Type must be GPS")
79 inverse_seconds_unit = lal.Unit(
"s^-1")
81 delta_target_unit = lal.Unit(delta_target_unit_string)
84 f0_unit = lal.Unit(str(f0.Unit))
87 delta_unit = lal.Unit(str(dims[0].Unit))
90 sample_unit = lal.Unit(str(a.Unit))
96 f0.pcdata * float(f0_unit / inverse_seconds_unit),
97 dims[0].Scale * float(delta_unit / delta_target_unit),
103 if np.iscomplexobj(series.data.data):
104 series.data.data = a.array[1] + 1j * a.array[2]
106 series.data.data = a.array[1]
113 assert isinstance(series, lal.REAL4FrequencySeries)
114 return _build_series(series, (
u"Frequency,Real",
u"Frequency"), comment,
'deltaF',
's^-1', encoding=encoding)
118 return _parse_series(elem, lal.CreateREAL4FrequencySeries,
"s^-1")
122 assert isinstance(series, lal.REAL8FrequencySeries)
123 return _build_series(series, (
u"Frequency,Real",
u"Frequency"), comment,
'deltaF',
's^-1', encoding=encoding)
127 return _parse_series(elem, lal.CreateREAL8FrequencySeries,
"s^-1")
131 assert isinstance(series, lal.COMPLEX8FrequencySeries)
132 return _build_series(series, (
u"Frequency,Real,Imaginary",
u"Frequency"), comment,
'deltaF',
's^-1', encoding=encoding)
136 return _parse_series(elem, lal.CreateCOMPLEX8FrequencySeries,
"s^-1")
140 assert isinstance(series, lal.COMPLEX16FrequencySeries)
141 return _build_series(series, (
u"Frequency,Real,Imaginary",
u"Frequency"), comment,
'deltaF',
's^-1', encoding=encoding)
145 return _parse_series(elem, lal.CreateCOMPLEX16FrequencySeries,
"s^-1")
149 assert isinstance(series, lal.REAL4TimeSeries)
150 return _build_series(series, (
u"Time,Real",
u"Time"), comment,
'deltaT',
's', encoding=encoding)
154 return _parse_series(elem, lal.CreateREAL4TimeSeries,
"s")
158 assert isinstance(series, lal.REAL8TimeSeries)
159 return _build_series(series, (
u"Time,Real",
u"Time"), comment,
'deltaT',
's', encoding=encoding)
163 return _parse_series(elem, lal.CreateREAL8TimeSeries,
"s")
167 assert isinstance(series, lal.COMPLEX8TimeSeries)
168 return _build_series(series, (
u"Time,Real,Imaginary",
u"Time"), comment,
'deltaT',
's', encoding=encoding)
172 return _parse_series(elem, lal.CreateCOMPLEX8TimeSeries,
"s")
176 assert isinstance(series, lal.COMPLEX16TimeSeries)
177 return _build_series(series, (
u"Time,Real,Imaginary",
u"Time"), comment,
'deltaT',
's', encoding=encoding)
181 return _parse_series(elem, lal.CreateCOMPLEX16TimeSeries,
"s")
193def make_psd_xmldoc(psddict, xmldoc = None, root_name = u"psd", encoding="Text"):
195 Construct an XML document tree representation of a dictionary of
197 for a function to parse the resulting XML documents.
199 If xmldoc
is None (the default), then a new XML document
is created
and
200 the PSD dictionary added to it inside a LIGO_LW element. If xmldoc
is
201 not None then the PSD dictionary
is appended to the children of that
202 element inside a new LIGO_LW element. In both cases, the LIGO_LW
203 element
's Name attribute is set to root_name. This will be looked for
207 xmldoc = ligolw.Document()
208 lw = xmldoc.appendChild(ligolw.LIGO_LW(
Attributes({
u"Name": root_name})))
209 for instrument, psd
in psddict.items():
211 if instrument
is not None:
212 fs.appendChild(ligolw.Param.from_pyvalue(
u"instrument", instrument))
218 Parse a dictionary of PSD frequency series objects from an XML
220 documents
from a dictionary of PSDs. Interprets an empty frequency
221 series
for an instrument
as None.
223 The XML document tree
is searched
for a LIGO_LW element whose Name
224 attribute
is root_name (default
is "psd"). If root_name
is None all
225 REAL8Frequency series objects below xmldoc are included
in the
return
228 if root_name
is not None:
229 xmldoc, = (elem
for elem
in xmldoc.getElementsByTagName(ligolw.LIGO_LW.tagName)
if elem.hasAttribute(
u"Name")
and elem.Name == root_name)
230 result = dict((ligolw.Param.get_param(elem,
u"instrument").value,
parse_REAL8FrequencySeries(elem))
for elem
in xmldoc.getElementsByTagName(ligolw.LIGO_LW.tagName)
if elem.hasAttribute(
u"Name")
and elem.Name ==
u"REAL8FrequencySeries")
232 for instrument
in result:
233 if len(result[instrument].data.data) == 0:
234 result[instrument] =
None
238class PSDContentHandler(ligolw.LIGOLWContentHandler):
239 """A content handler suitable for reading PSD documents. Use like this:
241 >>> from igwn_ligolw.utils
import load_filename
242 >>> xmldoc = load_filename(
'psd.xml', contenthandler=PSDContentHandler)
def build_REAL4FrequencySeries(series, comment=None, encoding="Text")
def read_psd_xmldoc(xmldoc, root_name=u"psd")
Parse a dictionary of PSD frequency series objects from an XML document.
def parse_REAL4TimeSeries(elem)
def parse_COMPLEX16FrequencySeries(elem)
def build_COMPLEX16FrequencySeries(series, comment=None, encoding="Text")
def build_REAL8FrequencySeries(series, comment=None, encoding="Text")
def parse_COMPLEX16TimeSeries(elem)
def make_psd_xmldoc(psddict, xmldoc=None, root_name=u"psd", encoding="Text")
Construct an XML document tree representation of a dictionary of frequency series objects containing ...
def build_COMPLEX8TimeSeries(series, comment=None, encoding="Text")
def parse_REAL8FrequencySeries(elem)
def parse_COMPLEX8TimeSeries(elem)
def build_REAL4TimeSeries(series, comment=None, encoding="Text")
def parse_REAL4FrequencySeries(elem)
def build_COMPLEX16TimeSeries(series, comment=None, encoding="Text")
def build_COMPLEX8FrequencySeries(series, comment=None, encoding="Text")
def parse_COMPLEX8FrequencySeries(elem)
def parse_REAL8TimeSeries(elem)
def build_REAL8TimeSeries(series, comment=None, encoding="Text")