Adding Topology Graphs

To add a new topology graph a new subclass of TopologyGraph must be added, which implements its virtual methods. Similarly, new subclasses of VertexData` and Vertex must also be made and their virtual methods implemented. When the new subclass of TopologyGraph is initialized, it must create instances of the VertexData subclass, together with EdgeData instances. Once your topology graph has the vertex and edge data it wants, simply run TopologyGraph.__init__() and you’re done.

When creating a VertexData subclass, get_vertex() needs to be implemented such that it returns an instance of your Vertex subclass. If you need to define a new __init__() method for either subclass, you will also need to implement clone() for it.

The TopologyGraph subclass can also create construction_stages if parallel construction needs to be broken down into separate stages. However, if this is not the case, then an empty tuple can simply be passed.

Why is both VertexData and Vertex needed?

At first, it may appear that having both VertexData and Vertex is an unnecssary inconvenience, as when you create a new TopologyGraph subclass you have to subclass both of these classes rather than just Vertex. The answer is related to how these two classes reference other objects in the TopologyGraph.

VertexData and EdgeData objects keep pointers to each other in the edges and vertices. This is extremely convenient for defining a TopologyGraph because its components can directly reference each other. However, it poses a significant issue for serialization. Topology graphs are usually highly-cyclic structures and are therefore often not possible to serialize with off-the-shelf serialization tools like pickle or dill. However, serialization is necessary and fundamental for allowing parallelization of TopologyGraph construction. The vertices and edges of the graph have to be serialized and sent to other cores so that they can place and connect building blocks in parallel. As a result, VertexData exists to allow a convenient definition of a TopologyGraph, while Vertex exists to provide a serializable representation of it. Verex and Edge do not reference other objects directly, instead they refer to them by their Vertex.id, which is used to get an index into TopologyGraph.vertices and TopologyGraph.edges.

VertexData.get_vertex() is used to convert VertexData into its Vertex counterpart.

class Edge(data)

Bases: object

Represents an edge in a topology graph.

Note that some methods of this class will behave differently before and after finalize() is called. Methods will switch from returning Vertex objects to returning int objects.

id

The id of the edge. Matches the index of the edge in TopologyGraph.edges.

Type

int

Methods

apply_scale(self, scale)

Scale the position by scale.

assign_func_group(self, func_group)

Assign func_group to be connected by this edge.

clone(self)

Return a clone.

get_func_groups(self)

Get the functional groups connected by this edge.

get_periodicity(self)

Get the periodicity of the edge.

get_position(self[, reference, vertices])

Return the position.

get_vertex_ids(self)

Get the connected vertices.

is_periodic(self)

Return True if periodic.

__init__(self, data)

Initialize an Edge.

Parameters

data (EdgeData) – The edge data.

apply_scale(self, scale)

Scale the position by scale.

Parameters

scale (float or list`of :class:`float) – The value by which the position of the Edge is scaled. Can be a single number if all axes are scaled by the same amount or a list of three numbers if each axis is scaled by a different value.

Returns

The edge is returned.

Return type

Edge

assign_func_group(self, func_group)

Assign func_group to be connected by this edge.

Parameters

func_group (FunctionalGroup) – The functional group to be assigned to the edge.

Returns

The edge is returned.

Return type

Edge

clone(self)

Return a clone.

Returns

The clone.

Return type

Edge

get_func_groups(self)

Get the functional groups connected by this edge.

Returns

The functional groups connected by the edge.

Return type

tuple of FunctionalGroup

get_periodicity(self)

Get the periodicity of the edge.

Returns

The periodicity of the edge. If [0, 0, 0] the edge is not periodic, if [1, 0, -1] the edge is periodic going in the postive direction along the x axis, is not periodic across the y axis and is periodic in the negative direction along the z axis.

Return type

numpy.ndarray

get_position(self, reference=None, vertices=None)

Return the position.

Parameters
  • reference (Vertex, optional) – If the edge is periodic, the position returned will depend on which vertex the edge position is calculated relative to.

  • vertices (tuple of Vertex, optional) – All the vertices in the topology graph. Index of each vertex must be equal to its id. Only needs to be supplied if reference is supplied.

Returns

The position of the Edge.

Return type

numpy.ndarray

get_vertex_ids(self)

Get the connected vertices.

Yields

int – The id of a connected vertex.

is_periodic(self)

Return True if periodic.

Returns

True if periodic.

Return type

bool

class EdgeData(*vertex_data, position=None, periodicity=None, lattice_constants=None)

Bases: object

Holds data used to initialize a Edge.

id

The id of the edge. This is equal the index of the edge in TopologyGraph.edges.

Type

int

vertices

The vertices connected to the edge.

Type

list of VertexData

periodicity

The periodicity of the edge. For example, if (0, 0, 0) then the edge is not periodic. If, (1, 0, -1) then the edge is periodic across the x axis in the positive direction, is not periodic across the y axis and is periodic across the z axis in the negative direction.

Type

numpy.ndarray

lattice_constants

The a, b and c lattice constants as vectors in Cartesian coordinates.

Type

tuple of numpy.ndarray

position

The position of the edge.

Type

numpy.ndarray

custom_position

True if the position of the edge was set manually. ``False``if the position of the edge is the centroid of the connected vertices.

Type

bool

Methods

clone(self[, vertex_map, …])

Return a clone.

get_edge(self)

Get an Edge from the data.

__init__(self, *vertex_data, position=None, periodicity=None, lattice_constants=None)

Initialize an EdgeData instance.

Parameters
  • *vertex_data (VertexData) – The vertices which the Edge connects.

  • position (numpy.ndarray, optional) – The position of the edge. If None, the centroid of vertex_data is used.

  • periodicity (tuple of int, optional) – The periodicity of the edge. For example, if (0, 0, 0) then the edge is not periodic. If, (1, 0, -1) then the edge is periodic across the x axis in the positive direction, is not periodic across the y axis and is periodic across the z axis in the negative direction. If None then the edge is not periodic.

  • lattice_constants (iterable, optional) – If the edge is periodic, the a, b and c lattice constants should be provided as vectors in Cartesian coordinates.

clone(self, vertex_map=None, recalculate_position=False, add_to_vertices=True)

Return a clone.

Parameters
  • vertex_map (dict) – If the clone should hold different VertexData instances, then a dict should be provided, which maps vertex data in the current EdgeData to the vertex data instances which should be used in the clone. Only vertex data instances which need to be changed need to be present in the vertex_map.

  • recalculate_position (bool, optional) – Toggle if the position of the clone should be recalculated from the vertices it connects or if it should inherit the position of the original edge.

  • add_to_vertices (bool, optional) – Toggles if the clone should be added to VertexData.edges.

Returns

The clone.

Return type

EdgeData

get_edge(self)

Get an Edge from the data.

Returns

The edge.

Return type

Edge

class PlacementResult(building_block, vertex, assignments)

Bases: tuple

Attributes
assignments

Alias for field number 2

building_block

Alias for field number 0

vertex

Alias for field number 1

Methods

count(self, value, /)

Return number of occurrences of value.

index(self, value[, start, stop])

Return first index of value.

__init__(self, /, *args, **kwargs)

Initialize self. See help(type(self)) for accurate signature.

property assignments

Alias for field number 2

property building_block

Alias for field number 0

count(self, value, /)

Return number of occurrences of value.

index(self, value, start=0, stop=9223372036854775807, /)

Return first index of value.

Raises ValueError if the value is not present.

property vertex

Alias for field number 1

class TopologyGraph(vertex_data, edge_data, construction_stages, num_processes)

Bases: object

Represents topology graphs of ConstructedMolecule.

The topology graph is an abstract representation of a constructed molecule. The vertices indicate where building blocks are placed and the edges indicate which building blocks have bonds formed between them by the construction process.

Vertices are responsible for placing the building block molecules. By initializing the vertices with different settings, they can position the building block molecules differently and therefore allow the user to easily specify a different structural isomer.

Once a building block is placed on a vertex, the functional groups on the building block must be assigned to the different edges connected to the vertex. The number of functional groups in the building block must match the number of edges connected to the vertex.

Once the functional groups are assigned to edges, each edge represents a reaction between the functional groups assigned to it. Note that an edge can be assigned more than two functional groups, in case you are dealing with something really exotic. The functional groups are then matched to an appropriate reaction, which generally creates bonds between the atoms of the functional groups. After this you will end up with a ConstructedMolecule.

vertices

The vertices which make up the topology graph.

Type

tuple of Vertex

edges

The edges which make up the topology graph.

Type

tuple of Edge

Methods

assign_building_blocks_to_vertices(self, …)

Assign building_blocks to vertices.

construct(self, mol)

Construct a ConstructedMolecule.

__init__(self, vertex_data, edge_data, construction_stages, num_processes)

Initialize an instance of TopologyGraph.

Parameters
  • vertices (tuple of VertexData) – The vertices which make up the graph.

  • edges (tuple of EdgeData) – The edges which make up the graph.

  • construction_stages (tuple of callable) –

    A collection of callables, each of which takes a Vertex and returns True or False. If the first callable is applied to a vertex in vertices, that vertex is is part of the first construction stage. The second callable is then applied to all vertices not in the first stage and those which return True belong to the second stage and so on.

    Vertices which belong to the same construction stage all place building blocks together in parallel, before placement is done by any vertices which are part of a later stage. This breaks down parallel construction into serial stages if synchronization between stages is needed.

    If the topology graph is performing construction serially, then all vertices which belong to an earlier stage will place their building block before those at a later stage.

  • num_processes (int) – The number of parallel processes to create during construct().

assign_building_blocks_to_vertices(self, building_blocks)

Assign building_blocks to vertices.

Parameters

building_blocks (list of Molecule) – The BuildingBlock and ConstructedMolecule instances which represent the building block molecules used for construction. Only one instance is present per building block molecule, even if multiples of that building block join up to form the ConstructedMolecule.

Returns

Maps the building_blocks, to the Vertex objects in vertices they are placed on during construction. The dict has the form

building_block_vertices = {
    BuildingBlock(...): [Vertex(...), Vertex(...)],
    BuildingBlock(...): [
        Vertex(...),
        Vertex(...),
        Vertex(...),
    ]
    ConstructedMolecule(...): [Vertex(...)]
}

Return type

dict

Raises

NotImplementedError – This is a virtual method which needs to be implemented in a subclass.

construct(self, mol)

Construct a ConstructedMolecule.

Parameters

mol (ConstructedMolecule) – The ConstructedMolecule instance which needs to be constructed.

Returns

None

Return type

NoneType

class Vertex(data)

Bases: object

Represents a vertex in a TopologyGraph.

id

The id of the vertex. This should be its index in TopologyGraph.vertices.

Type

int

Methods

after_assign_func_groups_to_edges(self, …)

Perform operations after functional groups have been assigned.

apply_scale(self, scale)

Scale the position by scale.

assign_func_groups_to_edges(self, …)

Assign functional groups to edges.

clone(self[, clear_edges])

Return a clone.

get_cell(self)

Get the cell of the lattice in which the vertex is found.

get_edge_ids(self)

Yield the ids of connected edges.

get_num_edges(self)

Return the number of connceted edge.

get_position(self)

Return the position.

place_building_block(self, building_block, …)

Place building_block on the Vertex.

set_contructed_molecule(self, mol)

Set the ConstructedMolecule being constructed.

__init__(self, data)

Initialize a Vertex.

Parameters

data (VertexData) – The vertex data.

after_assign_func_groups_to_edges(self, building_block, func_groups, vertices, edges)

Perform operations after functional groups have been assigned.

This method is always executed serially. It is often useful when data needs to be transferred between vertices, which have been processed independently, in parallel.

It does nothing by default, but should be overridden when necessary.

Parameters
  • building_block (Molecule) – The building block molecule which is needs to have functional groups assigned to edges.

  • func_groups (tuple of FunctionalGroup) – The functional group clones added to the constructed molecule.

  • vertices (tuple of Vertex) – All vertices in the topology graph. The index of each vertex must match its id.

  • edges (tuple of Edge) – All edges in the topology graph. The index of each edge must match its id.

Returns

None

Return type

NoneType

apply_scale(self, scale)

Scale the position by scale.

Parameters

scale (float or list`of :class:`float) – The value by which the position of the Vertex is scaled. Can be a single number if all axes are scaled by the same amount or a list of three numbers if each axis is scaled by a different value.

Returns

The vertex is returned.

Return type

Vertex

assign_func_groups_to_edges(self, building_block, vertices, edges)

Assign functional groups to edges.

Each FunctionalGroup of the building_block needs to be associated with one of the Edge instances in edges.

Parameters
  • building_block (Molecule) – The building block molecule which is needs to have functional groups assigned to edges.

  • vertices (tuple of Vertex) – All vertices in the topology graph. The index of each vertex must match its id.

  • edges (tuple of Edge) – All edges in the topology graph. The index of each edge must match its id.

Returns

A mapping from the id of a functional group in building_block to the id of the edge in edges it is assigned to.

Return type

dict

Raises

NotImplementedError – This is a virtual method, it needs to be implemented in a subclass.

clone(self, clear_edges=False)

Return a clone.

Parameters

clear_edges (bool, optional) – True if the clone should not be connected to any edges.

Returns

The clone.

Return type

Vertex

get_cell(self)

Get the cell of the lattice in which the vertex is found.

Returns

The cell of the lattice in which the vertex is found.

Return type

numpy.ndarray

get_edge_ids(self)

Yield the ids of connected edges.

Yields

int – The id of a connected edge.

get_num_edges(self)

Return the number of connceted edge.

Returns

The number of connected edges.

Return type

int

get_position(self)

Return the position.

Returns

The position of the Vertex.

Return type

numpy.ndarray

place_building_block(self, building_block, vertices, edges)

Place building_block on the Vertex.

Parameters
  • building_block (Molecule) – The building block molecule which is to be placed on the vertex.

  • vertices (tuple of Vertex) – All vertices in the topology graph. The index of each vertex must match its id.

  • edges (tuple of Edge) – All edges in the topology graph. The index of each edge must match its id.

Returns

The position matrix of building_block after being placed.

Return type

numpy.nadarray

Raises

NotImplementedError – This is a virtual method, it needs to be implemented in a subclass.

set_contructed_molecule(self, mol)

Set the ConstructedMolecule being constructed.

Parameters

mol (ConstructedMolecule) – The molecule being constructed.

Returns

The vertex.

Return type

Vertex

class VertexData(x, y, z)

Bases: object

Holds the data used to initialize a Vertex.

id

The id of the vertex. Must match the index in TopologyGraph.vertices.

Type

int

position

The position of the vertex.

Type

numpy.ndarray

edges

The edges connected to the vertex.

Type

list of EdgeData

cell

The unit cell in which the vertex is found.

Type

numpy.ndarray

Methods

clone(self[, clear_edges])

Return a clone.

get_vertex(self)

Get a vertex from the data.

init_at_center(\*vertex_data)

Initialize at the center of other vertices.

__init__(self, x, y, z)

Initialize a VertexData instance.

Parameters
  • x (float) – The x coordinate.

  • y (float) – The y coordinate.

  • z (float) – The z coordinate.

clone(self, clear_edges=False)

Return a clone.

Parameters

clear_edges (bool, optional) – True if the clone should not be connected to any edges.

Returns

The clone.

Return type

VertexData

get_vertex(self)

Get a vertex from the data.

Returns

A vertex initialized from the data.

Return type

Vertex

Raises

NotImplementedError – This is a virtual method which needs to be implemented in a subclass. The implementation should return an instance of the matching Vertex subclass.

classmethod init_at_center(*vertex_data)

Initialize at the center of other vertices.

Parameters

*vertex_data (VertexData) – Vertices at whose center this vertex should be initialized.

Returns

The vertex.

Return type

VertexData