Table¶
- class igwn_ligolw.ligolw.Table(attrs=None)¶
Bases:
EmptyElement,listTable element that knows about its columns and a provides a list-like interface to its rows.
Customization¶
In some cases, applications will want to define custom sub-classes of the Table element tailored to their specific use case. The lsctables module provides many examples. The following is a quick summary of how to do this.
When defining a sub-class, a number of class attributes can be defined and used to convey metadata about the custom Table to other code in the library. All are optional, but in some cases failing to set them will defeat the purpose of creating a special sub-class. For example, typically you will want to specify the columns and their types, and indicate which column, if there is one, carries the IDs for rows in this table. The special class attributes are given below.
Special Attributes¶
.tableName: The name of the table. This is optional, but failing to set it makes the sub-class indistinguishable from the stock Table element to most of the code in this library.
.validcolumns: Dictionary of column name–>type mappings defining the set of columns that instances of this Table may have, and what their types are. When loading a document, if a column is encountered that is not in this dictionary or its type does not match what is specified an error will be reported. Column names must be lower case, and obey the normal rules for C or Python variables: no spaces, no hyphens, and they cannot start with a numeral. The recognized types can be found in the types module. NOTE: the names of columns that contain the IDs of rows in other tables must be named in the form “<table_name>:<column_name>”, i.e., the other table’s name, a colon, then the column in that other table containing that table’s IDs. For example, a column that contains process IDs referring to rows in the process table must be named “process:process_id”. Failure to ensure this will break the ligolw_add algorithm for reassigning IDs to prevent collisions.
.loadcolumns: Sequence of names of columns to be loaded. If not None, only names appearing in the list will be loaded, the rest will be skipped. Can be used to reduce memory use. Typically this is not initialized in the class itself, but is set by an application at runtime before loading a document.
.constraints: Text to be included as constraints in the SQL statement used to construct the Table.
.how_to_index: Dictionary mapping SQL index name to an interable of column names over which to construct that index.
.next_id: object giving the next ID to assign to a row in this Table, and carrying the ID column name as the .column_name attribute. Typically the Column.next_id metaclass is used to create a new custom class for this purpose, then the .next_id attribute is initialized to the 0 instance of that new class. NOTE: when doing this, the column_name used to initialize the new class must be set to the name of the column that will hold the IDs. Failing to ensure this will break the ligolw_add algorithm for merging documents and re-assigning IDs to prevent collisions.
.RowType: this attribute provides the class that will be used to store rows for this Table. A default implementation is provided which will initialize attributes from keyword arguments, and supports pickling, but if any special handling of the data stored in the Table’s columns is required then a custom class will be needed. Typically the class defined here will be sub-classed. The lsctables module provides helper code to implement a variety of properties, for example sets of instrument names or GPS times broken out into integer and nanosecond parts.
Document Parsing¶
Once a new Table class is defined, the .TableByName class attribute in this class should be updated. The .TableByName attribute is a mapping used to map table names to corresponding Python classes. This mapping is used when parsing XML documents, when extracting the contents of SQL databases and any other place the conversion from a name to a class definition is required. Once the mapping is updated, when reading XML documents, Table elements whose names match the custom definition will be converted to instances of that class. Tables whose names are not recognized are loaded as instances of this generic class.
Example:
>>> class MyCustomTable(Table): ... tableName = "my_custom_table" ... validcolumns = { ... "process:process_id": "int_8s", ... "snr": "real_8", ... "event_id": "int_8s" ... } ... next_id = Column.next_id.type("event_id")(0) ... class RowType(Table.RowType): ... pass ... >>> Table.TableByName[MyCustomTable.tableName] = MyCustomTable
Attributes Summary
The "Name" attribute.
The "Type" attribute.
The stripped (without table prefixes attached) Name attributes of the Column elements in this Table, in order.
The non-stripped (with table prefixes attached) Name attributes of the Column elements in this Table, in order.
The Python types corresponding to the Type attributes of the Column elements in this Table, in order.
The Type attributes of the Column elements in this Table, in order.
Methods Summary
CheckElement(elem)Return True if element is a Table element whose Name attribute matches the .tableName attribute of this class; return False otherwise.
CheckProperties(tagname, attrs)Return True if tagname and attrs are the XML tag name and element attributes, respectively, of a Table element whose Name attribute matches the .tableName attribute of this class; return False otherwise.
appendColumn(name)Append a Column element named "name" to the Table.
appendRow(*args, **kwargs)Create and append a new row to this Table, then return it
applyKeyMapping(mapping)Used as the second half of the key reassignment algorithm.
copy()Construct and return a new Table document subtree whose structure is the same as this Table, that is it has the same Columns etc.
Method invoked by document parser when it encounters the end-of-element event.
ensure_exists(xmldoc[, create_new, columns])A wrapper around .get_table() and .new() that adds the table to the element tree if one is not found.
getColumnByName(name)Retrieve and return the Column child element named name.
getTablesByName(elem, name)Return a list of Table elements named name under elem.
Returns the current value of the next_id class attribute, and increments the next_id class attribute by 1.
get_table(xmldoc[, name])Scan xmldoc for a Table element named name.
new([columns])Construct a pre-defined LSC table.
If the current value of the next_id class attribute is not None then set it to 0, otherwise it is left unmodified.
reset_next_ids([classes])Classes is a sequence of Table subclasses.
set_next_id(next_id)Sets the value of the next_id class attribute.
Determines the highest-numbered ID in this Table, and sets the Table's .next_id attribute to the next highest ID in sequence.
unlink()Break internal references within the document tree rooted on this element to promote garbage collection.
updateKeyMapping(mapping)Used as the first half of the row key reassignment algorithm.
Attributes Documentation
- Name¶
The “Name” attribute.
- TableByName = {'coinc_definer': <class 'igwn_ligolw.lsctables.CoincDefTable'>, 'coinc_event': <class 'igwn_ligolw.lsctables.CoincTable'>, 'coinc_event_map': <class 'igwn_ligolw.lsctables.CoincMapTable'>, 'coinc_inspiral': <class 'igwn_ligolw.lsctables.CoincInspiralTable'>, 'coinc_ringdown': <class 'igwn_ligolw.lsctables.CoincRingdownTable'>, 'dq_list': <class 'igwn_ligolw.lsctables.DQSpecListTable'>, 'process': <class 'igwn_ligolw.lsctables.ProcessTable'>, 'process_params': <class 'igwn_ligolw.lsctables.ProcessParamsTable'>, 'search_summary': <class 'igwn_ligolw.lsctables.SearchSummaryTable'>, 'search_summvars': <class 'igwn_ligolw.lsctables.SearchSummVarsTable'>, 'segment': <class 'igwn_ligolw.lsctables.SegmentTable'>, 'segment_definer': <class 'igwn_ligolw.lsctables.SegmentDefTable'>, 'segment_summary': <class 'igwn_ligolw.lsctables.SegmentSumTable'>, 'sim_burst': <class 'igwn_ligolw.lsctables.SimBurstTable'>, 'sim_cbc': <class 'igwn_ligolw.lsctables.SimCBCTable'>, 'sim_inspiral': <class 'igwn_ligolw.lsctables.SimInspiralTable'>, 'sim_ringdown': <class 'igwn_ligolw.lsctables.SimRingdownTable'>, 'sngl_burst': <class 'igwn_ligolw.lsctables.SnglBurstTable'>, 'sngl_inspiral': <class 'igwn_ligolw.lsctables.SnglInspiralTable'>, 'sngl_ringdown': <class 'igwn_ligolw.lsctables.SnglRingdownTable'>, 'summ_value': <class 'igwn_ligolw.lsctables.SummValueTable'>, 'time_slide': <class 'igwn_ligolw.lsctables.TimeSlideTable'>, 'veto_definer': <class 'igwn_ligolw.lsctables.VetoDefTable'>}¶
- Type¶
The “Type” attribute.
- columnnames¶
The stripped (without table prefixes attached) Name attributes of the Column elements in this Table, in order. These are the names of the attributes that row objects in this taable possess.
- columnnamesreal¶
The non-stripped (with table prefixes attached) Name attributes of the Column elements in this Table, in order. These are the Name attributes as they appear in the XML.
- columnpytypes¶
The Python types corresponding to the Type attributes of the Column elements in this Table, in order.
- columntypes¶
The Type attributes of the Column elements in this Table, in order.
- constraints = None¶
- how_to_index = None¶
- loadcolumns = None¶
- next_id = None¶
- tagName = 'Table'¶
- validchildren = frozenset({'Column', 'Comment', 'Stream'})¶
- validcolumns = None¶
Methods Documentation
- classmethod CheckElement(elem)¶
Return True if element is a Table element whose Name attribute matches the .tableName attribute of this class; return False otherwise. See also .CheckProperties().
- classmethod CheckProperties(tagname, attrs)¶
Return True if tagname and attrs are the XML tag name and element attributes, respectively, of a Table element whose Name attribute matches the .tableName attribute of this class; return False otherwise. The Table parent class does not provide a .tableName attribute, but sub-classes, especially those in lsctables.py, do provide a value for that attribute. See also .CheckElement()
Example:
>>> from igwn_ligolw import lsctables >>> lsctables.ProcessTable.CheckProperties("Table", {"Name": "process:table"}) True
- appendColumn(name)¶
Append a Column element named “name” to the Table. Returns the new child. Raises ValueError if the Table already has a Column by that name, and KeyError if the validcolumns attribute of this Table does not contain an entry for a Column by that name.
Example:
>>> from igwn_ligolw import lsctables >>> tbl = lsctables.ProcessParamsTable.new([]) >>> col = tbl.appendColumn("param") >>> print(col.getAttribute("Name")) param >>> print(col.Name) param >>> col = tbl.appendColumn("process:process_id") >>> print(col.getAttribute("Name")) process:process_id >>> print(col.Name) process_id
- appendRow(*args, **kwargs)¶
Create and append a new row to this Table, then return it
All positional and keyword arguments are passed to the RowType constructor for this Table.
- applyKeyMapping(mapping)¶
Used as the second half of the key reassignment algorithm. Loops over each row in the Table, replacing references to old row keys with the new values from the mapping.
- copy()¶
Construct and return a new Table document subtree whose structure is the same as this Table, that is it has the same Columns etc.. The rows are not copied. Note that a fair amount of metadata is shared between the original and new Tables. In particular, a copy of the Table object itself is created (but with no rows), and copies of the child nodes are created. All other object references are shared between the two instances, such as the RowType attribute on the Table object.
- endElement()¶
Method invoked by document parser when it encounters the end-of-element event.
- classmethod ensure_exists(xmldoc, create_new=True, columns=None)¶
A wrapper around .get_table() and .new() that adds the table to the element tree if one is not found. This only works with subclasses that provide the required metadata. Raises ValueError if not exactly 1 matching table is found, unless create_new is True (the default), in which case a new Table element is appended to the top-level LIGO_LW element, and that new Table object returned. When creating a new Table element, the names of the columns to include can be passed via the columns parameter, otherwise if columns is None the default columns will be created (all of them).
- getColumnByName(name)¶
Retrieve and return the Column child element named name. The comparison is done using the stripped names. Raises KeyError if this Table has no Column by that name.
Example:
>>> from igwn_ligolw import lsctables >>> tbl = lsctables.SnglInspiralTable.new() >>> col = tbl.getColumnByName("mass1")
- classmethod getTablesByName(elem, name)¶
Return a list of Table elements named name under elem. See also .get_table().
- classmethod get_next_id()¶
Returns the current value of the next_id class attribute, and increments the next_id class attribute by 1. Raises ValueError if the Table does not have an ID generator associated with it.
- classmethod get_table(xmldoc, name=None)¶
Scan xmldoc for a Table element named name. Raises ValueError if not exactly 1 such Table is found. If name is None (default), then the .tableName attribute of this class is used. The Table class does not provide a .tableName attribute, but sub-classes, for example those in lsctables.py, do provide a value for that attribute.
Example:
>>> from igwn_ligolw import ligolw >>> from igwn_ligolw import lsctables >>> xmldoc = ligolw.Document() >>> xmldoc.appendChild(ligolw.LIGO_LW()).appendChild(lsctables.SnglInspiralTable.new()) [] >>> # find Table >>> sngl_inspiral_table = lsctables.SnglInspiralTable.get_table(xmldoc)
See also .getTablesByName().
- classmethod new(columns=None, **kwargs)¶
Construct a pre-defined LSC table. The optional columns argument is a sequence of the names of the columns the table is to be constructed with. If columns = None, then the table is constructed with all valid columns (use columns = [] to create a table with no columns).
NOTE: this method can only be used with subclasses that provide the metadata required to create the Column elements.
NOTE: this method cannot be used with documents stored in databases.
Example:
>>> from igwn_ligolw import lsctables >>> import sys >>> tbl = lsctables.ProcessTable.new(["process_id", "start_time", "end_time", "comment"]) >>> tbl.write(sys.stdout) <Table Name="process:table"> <Column Name="process_id" Type="int_8s"/> <Column Name="start_time" Type="int_4s"/> <Column Name="end_time" Type="int_4s"/> <Column Name="comment" Type="lstring"/> <Stream Name="process:table" Delimiter="," Type="Local"> </Stream> </Table>
- classmethod reset_next_id()¶
If the current value of the next_id class attribute is not None then set it to 0, otherwise it is left unmodified.
Example:
>>> from igwn_ligolw import lsctables >>> for cls in Table.TableByName.values(): cls.reset_next_id()
- classmethod reset_next_ids(classes=None)¶
Classes is a sequence of Table subclasses. If None (the default) then values from the TableByName dictionary are used. For each class in the sequence, if the .next_id attribute is not None (meaning the table has an ID generator associated with it), set .next_id to 0. This has the effect of reseting the ID generators, and is useful in applications that process multiple documents and add new rows to tables in those documents. Calling this function between documents prevents new row IDs from growing continuously from document to document. There is no need to do this, it’s purpose is merely aesthetic, but it can be confusing to open a document and find process ID 300 in the process table and wonder what happened to the other 299 processes.
- classmethod set_next_id(next_id)¶
Sets the value of the next_id class attribute. This is a convenience function to help prevent accidentally assigning a value to an instance attribute instead of the class attribute.
- sync_next_id()¶
Determines the highest-numbered ID in this Table, and sets the Table’s .next_id attribute to the next highest ID in sequence. If the .next_id attribute is already set to a value greater than the highest value found, then it is left unmodified. The return value is the ID identified by this method. If the Table’s .next_id attribute is None, then this function is a no-op.
Note that Tables of the same name typically share a common .next_id attribute (it is a class attribute, not an attribute of each instance) so that IDs can be generated that are unique across all Tables in the document. Running sync_next_id() on all the Tables in a document that are of the same type will have the effect of setting the ID to the next ID higher than any ID in any of those Tables.
Example:
>>> from igwn_ligolw import lsctables >>> tbl = lsctables.ProcessTable.new() >>> print(tbl.sync_next_id()) 0
- unlink()¶
Break internal references within the document tree rooted on this element to promote garbage collection.
- updateKeyMapping(mapping)¶
Used as the first half of the row key reassignment algorithm. Accepts a dictionary mapping old key –> new key. Iterates over the rows in this Table, using the Table’s next_id attribute to assign a new ID to each row, recording the changes in the mapping. Returns the mapping. Raises ValueError if the Table’s next_id attribute is None.