The complete object linking for the data matrix. For each object linking to all other objects in the data hierarchy lineage is stored as a set of object indices by data level.
Attributes:
In the figure there is only a single lineage in the a) case as there is only one sub level for each data level. In the b) case the root level has two different sub levels and hence there are two lineages in the data hierarchy. The black nodes belong to the lineage 0 and the white nodes belong to the lineage 1. However, the root node is an exception to this rule as it belongs to both lineages 0 and 1 being the parent level for both.
>>> hierarchy = {0: {'ordinal':0, 'lineage':set([0, 1])},
... 1: {'ordinal':1, 'lineage':set([0])},
... 2: {'ordinal':1, 'lineage':set([1])},
... 3: {'ordinal':2, 'lineage':set([0])},
... 4: {'ordinal':2, 'lineage':set([1])}}
>>> from simo.matrix.linkage import Linkage
>>> l = Linkage()
Add linking information for a new object and all nodes connected to it. Test data here is for the b-case in the figure; i.e., five different data levels, level 0 being the root level having two child levels 1 and 2. Level 3 is the child of level 1 and level 4 the child of level 2. In the data structure the first key indicates the iteration and branch, and the second tuple the data level and object index, while the third is the data level and object index of the parent node:
>>> data = [(0, (0, 0), (None, None)), (0, (1, 0), (0, 0)),
... (0, (2, 0), (0, 0)), (0, (3, 0), (1, 0)),
... (0, (4, 1), (2, 0)), (0, (4, 2), (2, 0)),
... (0, (4, 0), (2, 0))]
>>> iteration = 0
>>> for node in data:
... branch, objkey, parentkey = node
... l.add_object(hierarchy, iteration, branch, objkey, parentkey)
>>> l.links[(0, 0)][(0, 0)]
{1: [0], 2: [0], 3: [0], 4: [0, 1, 2]}
>>> l.links[(0, 0)][(1, 0)]
{0: [0], 3: [0]}
>>> l.links[(0, 0)][(2, 0)]
{0: [0], 4: [0, 1, 2]}
>>> l.links[(0, 0)][(3, 0)]
{0: [0], 1: [0]}
>>> l.links[(0, 0)][(4, 0)]
{0: [0], 2: [0]}
>>> l.links[(0, 0)][(4, 1)]
{0: [0], 2: [0]}
>>> l.links[(0, 0)][(4, 2)]
{0: [0], 2: [0]}
Construct another linkage for testing adding object relations between existing objects.
>>> l2 = Linkage()
>>> data = [(0, (0, 0), (None, None)), (0, (2, 0), (0, 0)),
... (0, (2, 1), (0, 0)), (0, (2, 2), (0, 0)),
... (0, (1, 0), (0, 0)), (0, (1, 1), (0, 0)),]
>>> for node in data:
... branch, objkey, parentkey = node
... l2.add_object(hierarchy, 0, 0, objkey, parentkey)
>>> l2.links[(0, 0)][(0, 0)]
{1: [0, 1], 2: [0, 1, 2]}
>>> l2.links[(0, 0)][(2, 0)]
{0: [0]}
Add objects without updating existing linkage info. This is needed when adding object relations between existing objects instead of new objects (when for example creating new objects by grouping existing objects):
>>> l2.add_object(hierarchy, 0, 0, (2, 0), (1, 0), False)
>>> l2.add_object(hierarchy, 0, 0, (2, 1), (1, 0), False)
>>> l2.add_object(hierarchy, 0, 0, (2, 2), (1, 1), False)
>>> l2.links[(0, 0)][(0, 0)]
{1: [0, 1], 2: [0, 1, 2]}
>>> l2.links[(0, 0)][(1, 0)]
{0: [0], 2: [0, 1]}
>>> l2.links[(0, 0)][(1, 1)]
{0: [0], 2: [2]}
>>> l2.links[(0, 0)][(2, 0)]
{0: [0], 1: [0]}
>>> l2.links[(0, 0)][(2, 1)]
{0: [0], 1: [0]}
>>> l2.links[(0, 0)][(2, 2)]
{0: [0], 1: [1]}
Remove the references to the object from all the connected nodes, and the object from the links structure:
>>> l.links[(0, 0)][(1, 0)]
{0: [0], 3: [0]}
>>> l.links[(0, 0)][(2, 0)]
{0: [0], 4: [0, 1, 2]}
>>> l.links[(0, 0)][(3, 0)]
{0: [0], 1: [0]}
>>> l.links[(0, 0)][(4, 0)]
{0: [0], 2: [0]}
>>> l.remove_object(0, 0, (4, 0))
{4: [0]}
>>> l.links[(0, 0)][(2, 0)]
{0: [0], 4: [1, 2]}
Child removal can be forced with children-parameter:
>>> l.remove_object(0, 0, (2, 0), children=True)
{2: [0], 4: [1, 2]}
>>> l.links[(0, 0)][(0, 0)]
{1: [0], 3: [0]}