LigolwSegments

class igwn_ligolw.utils.segments.LigolwSegments(xmldoc, process=None)

Bases: set

An interface shim between code that makes use of segments in ligo.segments form, and LIGO Light-Weight XML I/O code.

This class is “attached” to an XML document object, at which time it parses and extracts the segment lists from the document, and clears the document’s segment tables (preventing a second LigolwSegments object from being meaningfully attached to the same document). When the application is finished manipulating the segment lists, they can be inserted into the XML document at which time the contents of the LigolwSegments object are cleared (preventing any further manipulations).

This class is a subclass of the Python set builtin. Each element of the set is a LigolwSegmentList instance describing one of the segment lists in the original XML document.

This class may be used as a context manager to automate the replacement of segments back into the XML document, including in the event of an untrapped exception. When used as a context manager, the process parameter of the .__init__() method is not optional.

Example:

>>> import sys
>>> from igwn_segments import *
>>> from lal import LIGOTimeGPS
>>> from igwn_ligolw import ligolw, lsctables
>>> xmldoc = ligolw.Document()
>>> xmldoc.appendChild(ligolw.LIGO_LW())
<igwn_ligolw.ligolw.LIGO_LW object at ...>
>>> process = lsctables.Process(process_id = lsctables.ProcessTable.get_next_id())
>>> with LigolwSegments(xmldoc, process) as xmlsegments:
...     h1segs = segmentlist([segment(LIGOTimeGPS(0), LIGOTimeGPS(10))])
...     xmlsegments.insert_from_segmentlistdict(segmentlistdict({"H1": h1segs}), "test")
...     l1segs = h1segs.shift(5)
...     xmlsegments.add(LigolwSegmentList(active = l1segs, valid = segmentlist([segment(-infinity(), infinity())]), instruments = set(["L1"]), name = "test"))
...
>>> xmldoc.write(sys.stdout)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE LIGO_LW SYSTEM "http://ldas-sw.ligo.caltech.edu/doc/ligolwAPI/html/ligolw_dtd.txt">
<LIGO_LW>
        <Table Name="segment_definer:table">
                <Column Name="process:process_id" Type="int_8s"/>
                <Column Name="segment_def_id" Type="int_8s"/>
                <Column Name="ifos" Type="lstring"/>
                <Column Name="name" Type="lstring"/>
                <Column Name="version" Type="int_4s"/>
                <Column Name="comment" Type="lstring"/>
                <Stream Name="segment_definer:table" Delimiter="," Type="Local">
                        0,0,"H1","test",,,
                        0,1,"L1","test",,,
                </Stream>
        </Table>
        <Table Name="segment_summary:table">
                <Column Name="process:process_id" Type="int_8s"/>
                <Column Name="segment_sum_id" Type="int_8s"/>
                <Column Name="start_time" Type="int_4s"/>
                <Column Name="start_time_ns" Type="int_4s"/>
                <Column Name="end_time" Type="int_4s"/>
                <Column Name="end_time_ns" Type="int_4s"/>
                <Column Name="segment_definer:segment_def_id" Type="int_8s"/>
                <Column Name="comment" Type="lstring"/>
                <Stream Name="segment_summary:table" Delimiter="," Type="Local">
                        0,0,4294967295,4294967295,2147483647,4294967295,1,,
                        0,1,0,0,10,0,0,,
                </Stream>
        </Table>
        <Table Name="segment:table">
                <Column Name="process:process_id" Type="int_8s"/>
                <Column Name="segment_id" Type="int_8s"/>
                <Column Name="start_time" Type="int_4s"/>
                <Column Name="start_time_ns" Type="int_4s"/>
                <Column Name="end_time" Type="int_4s"/>
                <Column Name="end_time_ns" Type="int_4s"/>
                <Column Name="segment_definer:segment_def_id" Type="int_8s"/>
                <Stream Name="segment:table" Delimiter="," Type="Local">
                        0,0,0,0,10,0,0,
                        0,1,5,0,15,0,1
                </Stream>
        </Table>
</LIGO_LW>
>>> xmlsegments = LigolwSegments(xmldoc)
>>> segs = xmlsegments.get_by_name("test")
>>> segs["H1"]
[segment(LIGOTimeGPS(0, 0), LIGOTimeGPS(10, 0))]
>>> segs["L1"]
[segment(LIGOTimeGPS(5, 0), LIGOTimeGPS(15, 0))]
>>> xmlsegments.get_by_name("wrong name")
Traceback (most recent call last):
        ...
KeyError: "no segmentlists named 'wrong name'"

NOTE: the process of extracting and re-inserting the contents of the segment tables will, in general, randomize the IDs assigned to the rows of these tables. If there are references to segment, segment_summary, or segment_definer row IDs in other tables in the document, those references will be broken by this process.

Attributes Summary

instruments

The instruments for which the set contains at least one segment list.

names

The names of the segment lists contained in the set.

Methods Summary

coalesce()

Applies .coalesce() to all of the objects contained in the set, and then coalesces the LigolwSegmentList objects by applying the .update() operation to those that share instruments, name, version, and comment.

finalize([process_row])

Restore the LigolwSegmentList objects to the XML tables in preparation for output.

get_by_name(name[, clip_to_valid])

Retrieve the active segmentlists whose name equals name.

insert_from_segmentlistdict(seglists, name)

Insert the segment lists from the segmentlistdict object seglists as new LigolwSegmentList objects into this LigolwSegments object.

insert_from_segwizard(fileobj, instruments, name)

Parse the contents of the file object fileobj as a segwizard-format segment list, and insert the result as a new list of "active" segments into this LigolwSegments object.

optimize()

Identifies segment lists that differ only in their instruments --- they have the same valid and active segments, the same name, version and the same comment --- and then deletes all but one of them, leaving just a single list having the union of the instruments.

sort(*args, **kwargs)

Sort the segment lists.

Attributes Documentation

instruments

The instruments for which the set contains at least one segment list.

names

The names of the segment lists contained in the set.

Methods Documentation

coalesce()

Applies .coalesce() to all of the objects contained in the set, and then coalesces the LigolwSegmentList objects by applying the .update() operation to those that share instruments, name, version, and comment. This latter operation will fail if the segment lists are over-determined, meaning two or more of them describe inconsistent states for the same period of time.

Returns self.

NOTE: failure leaves the contents in an undefined state.

finalize(process_row=None)

Restore the LigolwSegmentList objects to the XML tables in preparation for output. All segments from all segment lists are inserted into the tables in time order, but this is NOT behaviour external applications should rely on. This is done simply in the belief that it might assist in constructing well balanced indexed databases from the resulting files. If that proves not to be the case, or for some reason this behaviour proves inconvenient to preserve, then it might be discontinued without notice. You’ve been warned.

get_by_name(name, clip_to_valid=False)

Retrieve the active segmentlists whose name equals name. The result is a segmentlistdict indexed by instrument. All segmentlist objects within it will be copies of the contents of this object, modifications will not affect the contents of this object. If clip_to_valid is True then the segmentlists will be intersected with their respective intervals of validity, otherwise they will be the verbatim active segments.

NOTE: the intersection operation required by clip_to_valid will yield undefined results unless the active and valid segmentlist objects are coalesced.

insert_from_segmentlistdict(seglists, name, version=None, comment=None)

Insert the segment lists from the segmentlistdict object seglists as new LigolwSegmentList objects into this LigolwSegments object. For each, the segments in the dictionary provide the “active” segments, and the “valid” segments are set to the .extent_all() of the segmentlistdict. The dictionary key for each segment list provides the instrument name. The name agument, and optional version and comment arguments provide the remaining metadata.

NOTE: the “valid” segments are set to the .extent_all() of the segmentlistdict, indicating that all segment lists define, exactly, their respective states from the earliest of any of their recorded times to the latest of any of their recorded times, with no gaps. If this is not correct, the calling code must do the insert itself.

insert_from_segwizard(fileobj, instruments, name, version=None, comment=None)

Parse the contents of the file object fileobj as a segwizard-format segment list, and insert the result as a new list of “active” segments into this LigolwSegments object. A new entry will be created in the segment_definer table for the segment list, and instruments, name and comment are used to populate the entry’s metadata.

Returns the newly created LigolwSegmentList object.

NOTE: the “valid” segments are set to the extent of the active segment list, indicating that the input segment list defines, exactly, the given state from the earliest recorded time to the latest recorded time, with no gaps. If this is not correct, the calling code must do the insert itself.

optimize()

Identifies segment lists that differ only in their instruments — they have the same valid and active segments, the same name, version and the same comment — and then deletes all but one of them, leaving just a single list having the union of the instruments.

sort(*args, **kwargs)

Sort the segment lists. The optional args are passed to the .sort() methods of the segment lists. This can be used to control the sort order by providing an alternate comparison function (the default is to sort all lists by segment start time with ties broken by end time).