API Reference

MOF Structure

class mofstructure.structure.MOFstructure(ase_atoms=None, filename=None)[source]

Bases: object

get_ligands(wrap_system=True, cheminfo=True, add_dummy=False)[source]

Extract the metal and linker secondary building units from the guest free system.

parameter:

wrap_system (bool): If True, removes the effects of periodicity by merging the system. cheminfo (bool): If True, computes cheminformatic identifiers such as SMILES, InChI, and InChIKey. add_dummy (bool): If True, adds dummy atoms at the points of extension.

return:

metal_clusters (list): A list of unique metal atoms or clusters. organic_ligands (list): A list of unique organic ligands.

get_oms()[source]

Function to compute open metal sites

get_porosity(probe_radius=1.86, number_of_steps=10000, rad_file=None, high_accuracy=True)[source]

A function to compute porosity data for a system.

parameters

probe_radius (float): Radius of the probe (default: 1.86). number_of_steps (int): Number of GCMC simulation cycles (default: 10000). high_accuracy (bool): If True, perform high-accuracy computations. rad_file: Optional file containing user defined atom radii. Must have the .rad extension

return:
pore (dict): A dictionary containing:
  • AV_Volume_fraction: Accessible volume void fraction.

  • AV_A^3: Accessible volume in A^2.

  • AV_cm^3/g: Accessible volume in cm³/g. This value is often infinite because it divides the computed

    volume by Avogadro’s number.

  • ASA_A^2: Accessible surface area in A^2.

  • ASA_m^2/cm^3: Accessible surface area in m2/cm3.

  • Number_of_channels: Number of channels (i.e., pores) present in the system.

  • LCD_A: The largest cavity diameter, defined as the diameter of the largest sphere that can be

    inserted into the porous system without overlapping any atoms.

  • lfpd_A: The largest included sphere along the free sphere path, i.e., the largest sphere that can be

    inserted into the pore.

  • PLD_A: The pore limiting diameter, defined as the largest sphere that can freely diffuse through the

    porous network without overlapping any atoms.

get_sbu(wrap_system=True, cheminfo=True, add_dummy=False)[source]

Extract the metal and linker secondary building units from the guest free system.

parameter

wrap_system (bool): If True, removes the effects of periodicity by merging the system. cheminfo (bool): If True, computes cheminformatic identifiers such as SMILES, InChI, and InChIKey. add_dummy (bool): If True, adds dummy atoms at the points of extension.

return:

metal_sbu (list): A list of unique metal secondary building units linker_sbu (list): A list of unique organic secondary building units

get_topology(method='all_node', *, decimals=8, include_edge_centers=True, fallback_to_input_cgd=False)[source]

Compute topology information for the guest-free system.

parameters:
method: str

Topology extraction method passed to SystreTopology.

decimals: int

Number of decimal places used when hashing the relaxed topology payload.

include_edge_centers: bool

If True, include edge-center comments in the CRYSTAL2 text.

fallback_to_input_cgd: bool

If True, return a CRYSTAL2 wrapper from the input CGD when no relaxed component can be parsed from Systre output.

return:
python dictionary
Mapping containing:
  • topology

  • dimension

  • td10

  • topology_hash

  • cgd_crystal2text

remove_guest()[source]

Simple function to remove guest molecules in porous system. Note that this can work for any periodic system.

return:

ase_atoms (ase.Atoms): atom object with guest removed.

mofstructure.structure.get_coordination_environment(coordination_spheres, metal_element, coordination_number)[source]

Returns the coordination environment (neighbors) of a specified metal element only if the number of neighbors equals the given coordination number.

parameters:

coordination_spheres (list): A list of metal coordination spheres (MetalSite objects). metal_element (str): The metal element symbol (e.g., ‘Ag’). coordination_number (int): The desired number of neighbors (coordination number).

Returns:

A list of species symbols (neighbors) bonded to the metal center.

Returns an empty list if no matching environment is found.

Return type:

List[str]

MOF Deconstructions

mofstructure.mofdeconstructor.all_ferrocene_metals(ase_atom, graph)[source]

A function to find metals corresponding to ferrocene. These metals should not be considered during mof-constructions

parameters:

ase_atom: ASE atom graph : dictionary containing neigbour lists

returns:

list_of_metals: list of indices of ferrocene metals

mofstructure.mofdeconstructor.angle_tolerance_to_rad(angle, tolerance=5)[source]

Convert angle from degrees to radians with tolerance.

parameters:
angle: float

Angle in degrees.

tolerance: float

Tolerance in degrees, default is 5.

returns:

bond_angle_rad: float Adjusted angle in radians.

mofstructure.mofdeconstructor.ase_2_pybel(atoms)[source]

As simple script to convert from ase atom object to pybel. There are many functionalities like atom typing, bond typing and autmatic addition of hydrogen that can be performed on a pybel molecule object, which can not be directly performed on an ase atom object. E.g

add_hygrogen = pybel.addh()

remove_hydrogen = pybel.removeh()

https://openbabel.org/docs/dev/UseTheLibrary/Python_Pybel.html

parameters:

atoms : ASE atoms object

returns:

pybel: pybel molecular object.

mofstructure.mofdeconstructor.ase_2_xyz(atoms)[source]

Create an xyz string from an ase atom object to be compatible with pybel in order to perfom some cheminformatics.

parameters:

atoms : ASE atoms object

returns:

a_str : string block of the atom object in xyz format

mofstructure.mofdeconstructor.check_planarity(p1, p2, p3, p4)[source]

A simple procedure to check whether a point is planar to three other points. Important to distinguish porphyrin type metals

parameters:

p1, p2, p3, p4 : ndarray containing x,y,z values

returns:

Boolean True: planar False: noneplanar

mofstructure.mofdeconstructor.compute_ase_neighbour(ase_atom)[source]

Create a connectivity graph using ASE neigbour list.

parameters:

ASE atoms

returns:
  1. atom_neighbors: A python dictionary, wherein each atom index is key and the value are the indices of it neigbours. e.g. atom_neighbors ={0:[1,2,3,4], 1:[3,4,5]…}

  2. matrix: An adjacency matrix that wherein each row correspond to to an atom index and the colums correspond to the interaction between that atom to the other atoms. The entries in the matrix are 1 or 0. 1 implies bonded and 0 implies not bonded.

mofstructure.mofdeconstructor.compute_ase_neighbour_with_offsets(ase_atom)[source]

Create a connectivity graph using ASE neigbour list.

parameters:

ASE atoms

return:

atom_neighbors: dict[int, list[int]] matrix: adjacency matrix bond_offsets: dict[(i, j)] -> list[(sx, sy, sz)]

mofstructure.mofdeconstructor.compute_cheminformatic_from_rdkit(ase_atom)[source]

A function that converts and ase atom into rkdit mol to extract some cheminformatic information.The script begins by taking an ase atom an creating an xyz string of the molecule, which is stored to memory. The xyz string is then read using the MolFromXYZBlock function in rdkit, which reads an xyz string of the molecule. However, this does not include any of the bonding information. To do this the following commands are parsed to the rdkit mol,bond_moll = Chem.Mol(rdmol) rdDetermineBonds.DetermineBonds(bond_moll,charge=0) https://github.com/rdkit/UGM_2022/blob/main/Notebooks/Landrum_WhatsNew.ipynb

parameters:

ASE atoms

returns:

smile string, inchi, inchikey

mofstructure.mofdeconstructor.compute_inchis(obmol)[source]

A function to compute the cheminformatic inchi and inchikey using openbabel. The inchi and inchikey are IUPAC cheminformatic identifiers of molecules. They are important to easily search for molecules in databases. For MOFs, this is quite important to search for different secondary building units (sbu) and ligands found in the MOF. More about inchi can be found in the following link

https://iupac.org/who-we-are/divisions/division-details/inchi

parameters:

obmol: openbabel molecule object

returns:

inChi, inChiKey: iupac inchi and inchikeys for thesame molecule.

mofstructure.mofdeconstructor.compute_openbabel_cheminformatic(ase_atom)[source]

A function the returns all smiles, inchi and inchikeys from an ase_atom object. The function starts by wrapping the system, which is important for systems in which minimum image convertion has made atoms appear to be uncoordinated at random positions. The wrap functions coordinates all the atoms together.

parameters:

atoms : ASE atoms object

returns:

smi, inChi, inChiKey

mofstructure.mofdeconstructor.compute_smi(obmol)[source]

A function to compute the SMILES (Simplified molecular-input line-entry system) notation of a molecule using openbabel. The SMILES is a line notation method that uses ASCII strings to represent molecules. More about SMILES can be found in the following link https://en.wikipedia.org/wiki/Simplified_molecular-input_line-entry_system

parameters:

obmol : openbabel molecule object

returns:

smi: SMILES notatation of the molecule.

mofstructure.mofdeconstructor.connected_components(graph)[source]

Selects the appropriate connected components algorithm based on the size of the system. Generally, the recursive method is faster but may exceed the recursion depth limit when the system is too large, while the iterative approach is slower but prevents the code from crashing in such cases. This function chooses the connected components method based on the size of the graph.

parameters:

graph: A dictionary representing a graph, where keys are nodes and values are lists of adjacent nodes.

returns:

A list of lists, where each sublist represents a connected component in the graph.

mofstructure.mofdeconstructor.connected_components_iterative(graph)[source]

Find the connected fragments in a graph. Should work for any graph defined as a dictionary.

parameters:

graph: a python dictionary representing the graph where keys are nodes and values are lists of adjacent nodes.

returns:

A python list of lists containing the connected components. Each sublist corresponds to an individual connected component (i.e., a set of nodes that are all connected).

mofstructure.mofdeconstructor.connected_components_recursive(graph)[source]

Find the connected fragments in a graph. Should work for any graph defined as a dictionary

parameters:

A graph in the form of dictionary e.g.:: graph = {1:[0,1,3], 2:[2,4,5]}

returns:

returns a python list of list of connected components These correspond to individual molecular fragments. list_of_connected_components = [[1,2],[1,3,4]]

mofstructure.mofdeconstructor.covalent_radius(element)[source]

A function that returns the covalent radius from the chemical symbol of an element.

parameters:

element: chemical symbol of an atom type.string

returns:

covalent_radii: covalent radius of the elements. type.float

mofstructure.mofdeconstructor.dfs_iterative(graph, start, visited)[source]

Depth-first search (DFS) iterative graph algorithm for traversing graph data structures. It starts at the root node ‘start’ and explores as far as possible along each branch before backtracking. This function is used as a utility for identifying connected components in the MOF graph.

parameters:

graph: a python dictionary where keys represent nodes and values are lists of neighboring nodes. start: a key in the python dictionary (graph), which is used as the starting or root node for the DFS. visited: a dictionary containing nodes that have been visited (True if visited, False otherwise).

returns:

A python list containing the nodes in the connected component starting from ‘start’.

mofstructure.mofdeconstructor.dfsutil_graph_method(graph, temp, node, visited)[source]

Depth-first search graph algorithm for traversing graph data structures. I starts at the root ‘node’ and explores as far as possible along each branch before backtracking. It is used here a a util for searching connected components in the MOF graph

parameters:

graph: any python dictionary temp: a python list to hold nodes that have been visited node: a key in the python dictionary (graph), which is used as the starting or root node visited: python list containing nodes that have been traversed.

returns:

python dictionary

mofstructure.mofdeconstructor.find_COS(ase_atom, graph)[source]

A simple aglorimth to search for COS.

O
|
-C
|
S
parameters:

ase_atom: ASE atom

returns:

dictionary of key = carbon index and values = sulphur index

mofstructure.mofdeconstructor.find_carbonyl_sulphate(ase_atom, graph)[source]

A simple aglorimth to search for Carbonyl sulphate found in the system.

   O
   |
-C-S
   |
   O
parameters:

ase_atom: ASE atom

returns:

dictionary of key = carbon index and values = oxygen index

mofstructure.mofdeconstructor.find_carboxylates(ase_atom, graph)[source]

A simple aglorimth to search for carboxylates found in the system.

parameters:
  • ase_atom: ASE atom

returns:
  • dictionary of key = carbon index and values = oxygen index

mofstructure.mofdeconstructor.find_key_or_value(key_or_value, list_of_list)[source]

Search for a key or value in a list of lists. If the key or value is found, returns the corresponding value or key.

parameters:

key_or_value : int or str list_of_list : list of lists

returns:

The corresponding value or key if found, otherwise None.

mofstructure.mofdeconstructor.find_phosphate(ase_atom, graph)[source]

A simple algorithm to search for Carbonyl sulphate found in the system.

 O
 |
-P-o
 |
 O
parameters:

ase_atom: ASE atom

returns

dictionary of key = carbon index and values = oxygen index

mofstructure.mofdeconstructor.find_phosphite(ase_atom, graph)[source]

A simple aglorimth to search for sulfides.

 P
 |
-C
 |
 P
parameters:

ase_atom: ASE atom

returns:

dictionary of key = carbon index and values = phosphorous index

mofstructure.mofdeconstructor.find_sulfides(ase_atom, graph)[source]

A simple aglorimth to search for sulfides.

 S
 |
-C
 |
 S
parameters:

ase_atom: ASE atom

returns:

dictionary of key = carbon index and values = sulphur index

mofstructure.mofdeconstructor.find_unique_building_units(list_of_connected_components, bonds_to_break, ase_atom, porphyrin_checker, all_regions, wrap_system=True, cheminfo=False, add_dummy=False)[source]

A function that identifies and processes unique building units within a MOF. This function deconstructs a MOF into its constituent building unit and identifies unique building units. It can also 1. wrap the system into the unit cell, 2. add dummy atoms to neutralize the building units, 3. compute cheminformatics data using Open Babel.

parameters:

list_of_connected_components : list of connected components bonds_to_break : list of lists of atom indices at breaking point ase_atom : ASE atoms object porphyrin_checker : list of indices of porphyrins all_regions : dictionary of regions wrap_system : boolean, default True cheminfo : boolean, default False add_dummy: boolean, default False add_dummy keyword enables the addition of dumnmy atoms which can then be replaced by hydrogen to neutralize the building blocks.

returns:

mof_metal: list of metal indices mof_linker: list of linker indices concentration: dictionary of concentration of building units

mofstructure.mofdeconstructor.get_bond_shift(i, j, bond_offsets)[source]
mofstructure.mofdeconstructor.get_neighbour_bond_matrix(sbu, skin=0.3, bo_step=0.1, aromatic=True)[source]

Create a bond-order connectivity graph using covalent radii and ASE NeighborList, with optional aromatic ring correction.

The algorithm:
  1. Uses covalent radii + tolerance to determine bonded atoms.

  2. Uses progressively shorter cutoffs to heuristically assign single, double, and triple bonds.

  3. Applies MOF-specific rules for metals, alkali metals, and hydrogen atoms.

  4. Optionally detects planar 5–10 membered rings and assigns aromatic bond order (1.5).

parameters:

sbu : ASE atoms object skin : float

Additional tolerance added to covalent radii (Å). Important for capturing slightly elongated coordination bonds.

bo_stepfloat

Distance reduction step used to define higher bond orders.

aromaticbool

If True, perform aromatic ring detection and correction.

returns:
  1. atom_neighbors:

    A python dictionary where each atom index is a key and the value is a list of bonded atom indices. e.g. atom_neighbors = {0:[1,2,3], 1:[0,4], …}

  2. bonds:

    Bond order matrix (NxN ndarray). Values:

    0.0 -> no bond 1.0 -> single bond 2.0 -> double bond (heuristic) 3.0 -> triple bond (heuristic) 1.5 -> aromatic bond 0.5 -> metal–organic coordination-like bond 0.25 -> metal–metal weak bond

mofstructure.mofdeconstructor.inter_atomic_distance_check(ase_atom)[source]

A function that checks whether any pair of atoms (except those with exactly one hydrogen) has a distance below 0.90 Å. Only unique pairs are checked to avoid redundancy.

Parameters ase_atom : ase.Atoms

An ASE Atoms object containing atomic positions and chemical symbols.

Returns bool

Returns False if any applicable atom pair has a distance below 0.90 Å. Otherwise, returns True.

mofstructure.mofdeconstructor.inter_atomic_distance_check2(ase_atom)[source]

Checks whether any non-hydrogen atom in the ASE atoms object has a neighbor within 0.90 Å (ignoring self-distances). This is used to detect overly close contacts, while ignoring R–H bonds (i.e., cases where the central atom is hydrogen).

parameters:

ase_atom : ASE atoms object

returns:

bool: False if any non-hydrogen atom has a neighbor (other than itself) within 0.90 Å; True otherwise.

mofstructure.mofdeconstructor.inter_atomic_distance_iterative(ase_atom)[source]

A function that checks whether two atoms are within a distance 1.0 Amstrong unless it is an R-H bond

parameters:

ase_atom : ASE atoms object

returns

boolean :

mofstructure.mofdeconstructor.is_alkali(symbols)[source]

Check wether symbols in a list are alkali

mofstructure.mofdeconstructor.is_atom_in_ring(atom_index, atom_in_ring_lookup)[source]

O(1) check.

mofstructure.mofdeconstructor.is_ferrocene(metal_sbu, graph)[source]

A simple script to check whether a metal_sbu is ferrocene

parameter:

metal_sbu : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is ferrocene, False otherwise

mofstructure.mofdeconstructor.is_irmof(ase_atom, graph)[source]

returns True if the atom is part of a IRMOF motif

parameter:

ase_atom : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is part of a IRMOF motif, False otherwise

mofstructure.mofdeconstructor.is_metal(symbols)[source]

Check wether symbols in a list are metals

mofstructure.mofdeconstructor.is_mof32(ase_atom, graph)[source]

returns True if the atom is part of a MOF32 motif

parameter:

ase_atom : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is part of a MOF32 motif, False otherwise

mofstructure.mofdeconstructor.is_paddlewheel(metal_sbu, graph)[source]

returns True if the atom is part of a paddlewheel motif

parameter:

metal_sbu : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is part of a paddlewheel motif, False otherwise

mofstructure.mofdeconstructor.is_paddlewheel_with_water(ase_atom, graph)[source]

returns True if the atom is part of a paddle wheel with water motif

parameter:

ase_atom : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is part of a paddle wheel with water motif, False otherwise

mofstructure.mofdeconstructor.is_rodlike(metal_sbu)[source]

Simple test to check whether a metal sbu is a rodlike MOF

parameter:

metal_sbu : ase_atom

returns:

bool : True if the metal sbu is a rodlike MOF, False otherwise

mofstructure.mofdeconstructor.is_uio66(ase_atom, graph)[source]

returns True if the atom is part of a UIO66 motif

parameter:

ase_atom : ase_atom graph : dictionary containing neigbour lists

returns:

bool : True if the metal_sbu is part of a UIO66 motif, False otherwise

mofstructure.mofdeconstructor.ligands_and_metal_clusters(ase_atom)[source]

Start by checking whether there are more than 2 layers if yes, select one Here we select the largest connected component

parameters:

ase_atom: ASE atom

returns:

list_of_connected_components: list of connected components, in which each list contains atom indices bonds_to_break: List of lists of atom indices at breaking points Porpyrin_checker: Boolean showing whether the metal is in the centre of a porpherin Regions: Dictionary of regions.

mofstructure.mofdeconstructor.longest_list(lst)[source]

return longest list in list of list

mofstructure.mofdeconstructor.matrix2dict(bond_matrix)[source]

A simple procedure to convert an adjacency matrix into a python dictionary.

parameters:

bond matrix : adjacency matrix, type: nxn ndarray

returns:

graph: python dictionary

mofstructure.mofdeconstructor.max_index(lists)[source]

Extract index of list with the maximum element

mofstructure.mofdeconstructor.metal_coordination_enviroment(ase_atom)[source]

Find the enviroment of a metal

paramters:

ase_atom : ASE atoms object

returns:

metal_elt : list of metal elements metal_enviroment : dict where key is metal element and value is list of neighboring elements

mofstructure.mofdeconstructor.metal_coordination_number(ase_atom)[source]

Extract coordination number of central metal

paramters:

ase_atom : ASE atoms object

returns:

metal_elt : list of metal elements

mofstructure.mofdeconstructor.metal_in_porphyrin(ase_atom, graph)[source]

A funtion to check whether a metal is found at the centre of a phorphirin. The function specifically identifies metal atoms that are coordinated with four nitrogen atoms, as typically seen in porphyrin complexes. These atoms must also satisfy the planarity condition of the porphyrin structure.

https://en.wikipedia.org/wiki/Transition_metal_porphyrin_complexes

parameters:

ase_atom: ASE atom graph: python dictionary containing neigbours

returns:

list of indices consisting of index of metal atoms found in the ASE atom

mofstructure.mofdeconstructor.metal_in_porphyrin2(ase_atom, graph)[source]

https://en.wikipedia.org/wiki/Transition_metal_porphyrin_complexes Check whether a metal is found at the centre of a phorphirin

parameters:

ase_atom: ASE atom graph: python dictionary containing neigbours

returns:

list of indices consisting of index of metal atoms found in the ASE atom

mofstructure.mofdeconstructor.mof_regions(ase_atom, list_of_connected_components, bonds_to_break)[source]

A function to map all atom indices to exact position in which the find themselves in the MOF. This function is used to partition a MOF into regions that correspond to unique unique building units.

parameters:

ase_atom: ASE atom list_of_connected_components : list of list, wherein each list correspond to atom indices of a specific building unit bonds_to_break : list of lists of atom indices at breaking point

returns:

Move an index from any position in the list to the front The function is important to set the cell of a rodmof to point in the a-axis. Such that the system can be grow along this axis

mofstructure.mofdeconstructor.move2front(index_value, coords)[source]

Move an index from any position in the list to the front The function is important to set the cell of a rodmof to point in thea-axis. Such that the system can be grow along this axis

parameters:
  • index_value: index of item to move to the from

  • coords: list of coords

returns:

list of coords

mofstructure.mofdeconstructor.obmol_2_rdkit(obmol)[source]

A simple function to convert openbabel mol to RDkit mol A function that takes an openbabel molecule object and converts it to an RDkit molecule object. The importance of this function lies in the fact that there is no direct were to convert from an ase atom type to an rdkit molecule object. Consequently, the easiest approach it is firt convert the system to an openbabel molecule object using the function ase_2_pybel to convert to the pybel molecule object. Then using the following code obmol = pybel_mol.OBMol to obtain the openbabel molecule object that can then be used to convert to the rdkit molecule object.

parameters:

obmol : openbabel molecule object

returns:

rdmol : rdkit molecule object.

mofstructure.mofdeconstructor.remove_unbound_guest(ase_atom)[source]

A simple script to remove guest from a metal organic framework. 1) It begins by computing a connected graph component of all the fragments in the system using ASE neighbour list. 2) Secondly it selects indices of connected components which contain a metal 3) if the there are two or more components, we create a pytmagen graph for each components and filter out all components that are not polymeric 4) If there are two or more polymeric components, we check whether these systems there are identical or different and select all polymeric components

parameters:

ASE atoms

returns:

mof_indices: indices of the guest-free system. The guest-free ase_atom object can be obtained as follows; E.g. guest_free_system = ase_atom[mof_indices]

mofstructure.mofdeconstructor.remove_unbound_guest_and_return_unique(ase_atom)[source]

A simple script to remove guest from a metal organic framework. 1)It begins by computing a connected graph component of all the fragments in the system using ASE neighbour list. 2) Secondly it selects indicies of connected components which contain a metal 3)if the there are two or more components, we create a pytmagen graph for each components and filter out all components that are not polymeric 4) If there are two or more polymeric components, we check wether these systems there are identical or different and select only unique polymeric components

parameters:

ASE atoms

returns:

mof_indices : indinces of the guest free system. The guest free ase_atom object can be obtain as follows; E.g. guest_free_system = ase_atom[mof_indices]

mofstructure.mofdeconstructor.rings_and_atom_ring_lookup(graph, use_mcb=True)[source]

Build rings and fast per-atom ring membership lookup.

Parameters:
  • graph (dict[int, list[int]]) – Undirected adjacency list (atom -> neighbors).

  • use_mcb (bool) – If True: use nx.minimum_cycle_basis (SSSR-like). If False: use nx.cycle_basis (fundamental cycles; faster, less “SSSR”).

Returns:

  • rings (list[list[int]]) – List of cycles (each cycle is a list of atom indices).

  • atom_in_ring (dict[int, bool]) – Quick membership: atom_in_ring[i] == True if i is in any ring.

  • atom_to_rings (dict[int, list[int]]) – atom_to_rings[i] gives list of ring indices that contain atom i.

mofstructure.mofdeconstructor.rod_manipulation(ase_atom, checker)[source]

Script to adjust Rodlike sbus. 1) Its collects the axis responsible for expanding the rod 2) It shifts all coordinates to the axis 3) It rotates the rod to lie in the directions of expansion,

parameter:

ase_atom : ASE atoms object checker : list of indices of atoms responsible for rod expansion

returns:

ase_atom : ASE atoms object with adjusted coordinates

mofstructure.mofdeconstructor.secondary_building_units(ase_atom)[source]
  1. Search for all carboxylate that are connected to a metal. Cut at the position between the carboxylate carbon and the adjecent carbon.

  2. Find all Nitrogen connected to metal. Check whether the nitrogen is in the centre of a porphirin ring. If no, cut at nitrogen metal bond.

  3. Look for oxygen that is connected to metal and two carbon. cut at metal oxygen bond

parameters:

ase_atom: ASE atom

returns:

list_of_connected_components: list of connected components,in which each list contains atom indices bonds_to_break: List of lists of atom indices at breaking points porphyrin_checker: Boolean showing whether the metal is in the centre of a porpherin Regions: Dictionary of regions.

mofstructure.mofdeconstructor.transition_metals()[source]

A function that returns the list of all chemical symbols of metallic elements present in the periodic table

mofstructure.mofdeconstructor.wrap_systems_in_unit_cell(ase_atom, max_iter=30, skin=0.3)[source]

A simple aglorithm to reconnnect all atoms wrapped in a periodic boundary condition such that all atoms outside the box will appear reconnected.

parameters:

ase_atom : ASE atoms object max_iter : int, optional (default=30) Maximum number of iterations for reconnection skin : float, optional (default=0.3) Skin distance for bond reconnection

returns:
  • ase_atom : ASE atoms object with reconnected atoms wrapped in a periodic boundary condition

Computing Porosity

mofstructure.porosity.ase_to_zeoobject(ase_atom)[source]

Converts an ase atom type to a zeo++ Cssr object In zeo++ the xyz coordinate system is rotated to a zyx format.

parameter:

ase_atom: ase atom object

returns:

cssr_object: string representing zeo++ cssr object

mofstructure.porosity.zeo_calculation(ase_atom, probe_radius=1.86, number_of_steps=10000, high_accuracy=True, rad_file=None)[source]

Main script to compute geometric structure of porous systems. The focus here is on MOF, but the script can run on any porous periodic system. The script computes the accesible surface area, accessible volume and the pore geometry. There are many more outputs which can be extracted from ,vol_str and sa_str. Moreover there are also other computation that can be done. Check out the test directory in dependencies/pyzeo/test. Else contact bafgreat@gmail.com. if you need more output and can’t figure it out.

parameter:

ase_atom: ASE atoms object representing the porous structure. probe_radius (float): Radius of the probe (default: 1.86). number_of_steps (int): Number of GCMC simulation cycles (default: 10000). high_accuracy (bool): If True, perform high-accuracy computations. rad_file: Optional file containing user defined atom radii. Must have the .rad extension

return:

python dictionary containing 1) AV_Volume_fraction: Accessible volume void fraction 2) AV_A^3: Accessible volume in A^2 3) AV_cm^3/g: Accessible volume in cm^3/g. This values is often infinity because it literatly divides the given value by the avogadro’s number 4) ASA_A^2: Accessible surface area A^2 5) ASA_m^2/cm^3: Accessible surface area in m^2/cm^3 6) Number_of_channels: Number of channels present in the porous system, which correspond to the number of pores within the system 7) LCD_A: The largest cavity diameter is the largest sphere that can be inserted in a porous system without overlapping with any of the atoms in the system. 8) lfpd_A:The largest included sphere along free sphere path is largest sphere that can be inserted in the pore 9)PLD_A:The pore limiting diameter is the largest sphere that can freely diffuse through the porous network without overlapping with any of the atoms in the system

Computing stacking in 2D systems and inter-layer height

mofstructure.cof_stacking.Main()[source]

Main function to compute the stacking pattern of COFs or layered materials like graphene if input is a file it reads directly from the file and if input is a directory it reads all the files in the directory and computes the stacking pattern for each file For directory input it also writes the output to a json file in the same directory

mofstructure.cof_stacking.compute_cof_stacking(ase_atom)[source]

A a simple function to compute the stacking pattern of COFs or layered materials like graphene

parameter:

ase_atom : ASE Atoms object

returns

layers : list of list wherei each list correspond to a layar lateral_offsets : list of list where each list contains the lateral offsets between two layers interlayer_height : list of list where each list contains the interlayer heights between two layers

Topological Analysis

class mofstructure.generate_cgd.TopologyExtractor(ase_atoms: Atoms | None = None, filename: str | None = None)[source]

Bases: object

A high-level class for extracting a periodic topology from a porous crystal.

The class accepts either an ASE atoms object or a structure filename readable by ASE. It removes unbound guests, performs deconstruction using one of the supported methods, selects node regions, contracts linker-like regions, and writes the resulting CGD PERIODIC_GRAPH.

parameters:

ase_atoms: ASE atoms object, optional

filename: str, optional

Path to an input structure file readable by ASE.

methods:
remove_guest():

Remove unbound guests from the framework.

build_cgd():

Build a CGD periodic graph using one of the supported topology modes.

write_cgd():

Write CGD content to file.

ase_atoms: Atoms | None = None
property atoms
build_cgd(*, method: str = 'sbus', name: str = 'net', top_k_regions: int = 1, connect_mode: str = 'clique')[source]

Build a CGD PERIODIC_GRAPH using one of the supported methods.

parameters:
method: str
One of:
  • “sbus”

  • “ligand_cluster”

  • “all_node”

name: str

CGD graph ID.

top_k_regions: int

Only used for method=”all_node”. Number of most-connected regions to keep as node regions.

connect_mode: str

Either “clique” or “chain”.

returns:
cgd_text: str

CGD PERIODIC_GRAPH content.

filename: str | None = None
remove_guest()[source]

Remove unbound guests from a porous periodic structure.

returns:
ASE atoms object

Guest-free framework.

static write_cgd(cgd_text, path)[source]

Write CGD content to file.

parameters:
cgd_text: str

CGD content.

path: str

Output file path.

returns:
str

Output path.

mofstructure.generate_cgd.base_edges_with_shifts(atoms: Atoms, components: Sequence[Sequence[int]], breaking_pairs: Sequence[Sequence[int | integer]])[source]

Build the base component graph with periodic shifts.

A broken pair returned by mofdeconstructor contains the indices of two atoms that were bonded before deconstruction, and optionally the local bond offset between them. However, this local bond offset alone is not sufficient to determine the true translation between the final post-cut components.

This function therefore:
  1. reconstructs the kept-bond graph,

  2. unwraps each final component using the kept periodic bonds,

  3. computes the translation between components using:

    T(u -> v) = img_u[i] - img_v[j] + s_ij

where:
  • i belongs to component u

  • j belongs to component v

  • img_u[i] is the lattice image of atom i in component u

  • img_v[j] is the lattice image of atom j in component v

  • s_ij is the bond offset stored in breaking_pairs

parameters:

atoms: ASE atoms object

components: list

List of final connected components after bond breaking.

breaking_pairs: list

List of broken bonds returned by the deconstructor. Each entry is typically [i, j, sx, sy, sz].

returns:
edges_out: list
List of component-level edges of the form:

(u, v, sx, sy, sz)

where u and v are component indices and (sx, sy, sz) is the corresponding lattice shift.

mofstructure.generate_cgd.build_argparser()[source]

Build the command-line argument parser.

returns:

argparse.ArgumentParser

mofstructure.generate_cgd.cgd_from_region_targets(atoms: Atoms, components: Sequence[Sequence[int]], breaking_pairs: Sequence[Sequence[int | integer]], regions: Dict[int, List[int]], *, target_regions: Sequence[int], name: str = 'net', connect_mode: str = 'clique', dedup_edges_for_systre: bool = True)[source]

Build a CGD PERIODIC_GRAPH by contracting non-target components into edges.

The logic is:
  1. Build the base component graph with periodic shifts.

  2. Select all components belonging to target_regions as CGD nodes.

  3. Treat all remaining components as edge-components.

  4. Contract each edge-component into effective edges between node-components.

The contraction is incidence-based, meaning that different periodic incidences between a linker-like component and node-like components are preserved. This is essential for recovering the correct 3D net of pillared or otherwise periodic frameworks.

parameters:

atoms: ASE atoms object

components: list

List of connected components from the deconstructor.

breaking_pairs: list

List of broken atom pairs from the deconstructor.

regions: python dictionary

Mapping of region_id -> list of component indices.

target_regions: list

Region IDs that should be treated as node regions.

name: str

CGD graph ID.

connect_mode: str

Either “clique” or “chain”. - “clique”: all incidences are mutually connected - “chain”: incidences are connected in sorted order

dedup_edges_for_systre: bool

If True, remove exact duplicate periodic edges.

returns:
cgd_text: str

CGD PERIODIC_GRAPH content as a string.

mofstructure.generate_cgd.component_atom_images(components: Sequence[Sequence[int]], kept_graph: Dict[int, List[int]], kept_offsets: Dict[Tuple[int, int], List[Tuple[int, int, int]]])[source]

Assign integer lattice image vectors to atoms inside each connected component.

After the bonds listed in breaking_pairs are removed, the structure is split into final connected components. Some of these components may still span the periodic unit cell. This function unwraps each component by traversing the kept internal bonds and assigning an integer image vector (ix, iy, iz) to each atom.

These image vectors are required to compute the true translation between components connected by a broken bond.

parameters:
components: list

List of connected components, where each component is a list of atom indices.

kept_graph: python dictionary

Atom-level connectivity graph after removing broken bonds.

kept_offsets: python dictionary

Dictionary mapping kept bonds to their periodic offsets.

returns:
comp_images: python dictionary
Dictionary of the form:

comp_images[component_id][atom_index] = (ix, iy, iz)

mofstructure.generate_cgd.component_has_transition_metal_not_in_porphyrin(atoms: Atoms, comp: Sequence[int], porphyrin_atoms: Sequence[int] | None, tm_symbols: Sequence[str])[source]

Check whether a connected component contains a transition metal that is not part of a porphyrin-like motif.

parameters:

atoms: ASE atoms object

comp: list

List of atom indices defining a connected component.

porphyrin_atoms: list or None

List of atom indices identified as belonging to a porphyrin motif.

tm_symbols: list

List of transition-metal symbols.

returns:

bool

mofstructure.generate_cgd.main(argv: Sequence[str] | None = None)[source]

Command-line entry point.

parameters:

argv: list, optional

returns:
int

Exit code.

mofstructure.generate_cgd.regions_with_metal(atoms: Atoms, components: Sequence[Sequence[int]], regions: Dict[int, List[int]], porphyrin_atoms: Sequence[int] | None)[source]

Identify regions that contain at least one metal-bearing component.

In this module, a region corresponds to a group of equivalent components returned by the deconstructor. This function selects the regions that contain at least one connected component with a transition metal atom not assigned to a porphyrin motif.

parameters:

atoms: ASE atoms object

components: list

List of connected components.

regions: python dictionary

Mapping of region_id -> list of component indices.

porphyrin_atoms: list or None

Atom indices associated with porphyrin-like motifs.

returns:
list

Sorted list of region IDs containing metal-bearing components.

mofstructure.generate_cgd.remove_broken_bonds_from_breaking_pairs(atom_graph: Dict[int, List[int]], bond_offsets: Dict[Tuple[int, int], List[Tuple[int, int, int]]], breaking_pairs: Sequence[Sequence[int | integer]])[source]

Remove all bonds listed in breaking_pairs from an atom-level periodic graph.

The first two entries of each breaking pair correspond to the atom indices of a bond that was cut during deconstruction. This function reconstructs the graph of bonds that remain after those cuts, while preserving the associated lattice offsets of the kept bonds.

parameters:
atom_graph: python dictionary

Atom-level connectivity graph where each key is an atom index and the value is a list of neighbouring atom indices.

bond_offsets: python dictionary

Dictionary mapping (i, j) atom-index tuples to one or more periodic neighbour offsets, e.g. {(i, j): [(sx, sy, sz), …]}.

breaking_pairs: list

List of broken bonds. Each entry is expected to be of the form [i, j] or [i, j, sx, sy, sz].

returns:
kept_graph: python dictionary

Atom-level connectivity graph after removing the broken bonds.

kept_offsets: python dictionary

Dictionary of offsets corresponding to the bonds kept in the graph.

Systre Topology Identification

class mofstructure.systre.RelaxedComponent(component_index: int, dimension: int, cell: Tuple[float, float, float, float, float, float], nodes: Dict[str, Tuple[float, float, float]], edges: List[Tuple[Tuple[float, float, float], Tuple[float, float, float]]], edge_centers: List[Tuple[float, float, float]], coordination_number: Dict[str, int], given_space_group: str | None = None, ideal_space_group: str | None = None, rcsr_name: str | None = None, td10: int | None = None)[source]

Bases: object

Container for one relaxed topology component parsed from Systre output.

parameters:
component_index: int

Index of the component in the Systre output.

dimension: int

Periodicity of the component.

cell: tuple

Relaxed cell parameters in the form (a, b, c, alpha, beta, gamma).

nodes: python dictionary
Mapping:

node_label -> (x, y, z)

edges: list

List of relaxed edges as coordinate pairs.

edge_centers: list

List of relaxed edge centres.

coordination_number: python dictionary
Mapping:

node_label -> coordination number

given_space_group: str, optional

Given space group reported by Systre.

ideal_space_group: str, optional

Ideal space group reported by Systre.

rcsr_name: str, optional

RCSR name reported by Systre.

td10: int, optional

TD10 value reported by Systre.

cell: Tuple[float, float, float, float, float, float]
component_index: int
coordination_number: Dict[str, int]
crystal2_hash(algorithm: str = 'sha256', name: str | None = None, include_edge_centers: bool = True) str[source]

Compute a hash directly from the CRYSTAL2 text.

parameters:
algorithm: str

Hash algorithm supported by hashlib.

name: str, optional

Name written to the CRYSTAL2 block before hashing.

include_edge_centers: bool

If True, include commented edge-centre metadata.

returns:
str

Hex digest.

crystal2_text(name: str | None = None, include_edge_centers: bool = True) str[source]

Return the CRYSTAL2 CGD representation as text.

parameters:
name: str, optional

Name written to the CRYSTAL2 block.

include_edge_centers: bool

If True, write edge centres as commented metadata lines.

returns:
str

CRYSTAL2 CGD text.

dimension: int
edge_centers: List[Tuple[float, float, float]]
edges: List[Tuple[Tuple[float, float, float], Tuple[float, float, float]]]
given_space_group: str | None = None
ideal_space_group: str | None = None
property is_named_net: bool

Check whether the relaxed component has an RCSR name.

returns:

bool

property n_edges: int

Return the number of relaxed edges.

returns:

int

property n_nodes: int

Return the number of relaxed nodes.

returns:

int

nodes: Dict[str, Tuple[float, float, float]]
normalized_payload(decimals: int = 8) Dict[str, object][source]

Return a normalized payload that can be serialized and hashed.

The payload contains only topology-relevant relaxed information. Floating-point values are rounded to make the hash more stable.

parameters:
decimals: int

Number of decimal places used when rounding floats.

returns:
python dictionary

JSON-serializable normalized topology payload.

rcsr_name: str | None = None
td10: int | None = None
topology_hash(algorithm: str = 'sha256', decimals: int = 8) str[source]

Compute a stable topology hash from the normalized payload.

parameters:
algorithm: str

Hash algorithm supported by hashlib.

decimals: int

Number of decimal places used when rounding floats.

returns:
str

Hex digest.

topology_key(decimals: int = 8) str[source]

Return a deterministic JSON string for hashing or indexing.

parameters:
decimals: int

Number of decimal places used when rounding floats.

returns:
str

Canonical JSON string.

class mofstructure.systre.SystreResult(topology: str, stdout: str, stderr: str, cgd_path: str | None = None)[source]

Bases: object

Container class for a Systre topology-identification result.

parameters:
topology: str

Identified topology name or sentinel value such as “UNKNOWN”, “ERROR”, or “TIMEOUT”.

stdout: str

Standard output from Systre.

stderr: str

Standard error from Systre.

cgd_path: str, optional

Path to the CGD file passed to Systre.

cgd_path: str | None = None
stderr: str
stdout: str
topology: str
class mofstructure.systre.SystreTopology(input_object: str | Path | Atoms, *, input_is_cgd: bool | None = None, method: str = 'all_node', name: str = 'net', java: str | None = None, timeout_s: int = 30, xmx: str = '1024m', keep_tmp: bool = False)[source]

Bases: object

High-level class for running Systre, parsing relaxed output, and generating stable topology hashes.

parameters:
input_object:
Structure-like input. Supported values are:
  • ASE atoms object

  • structure filename

  • CGD filepath

  • CGD text

  • pymatgen Structure object

input_is_cgd: bool, optional

If True, force the input to be treated as CGD.

method: str

Topology extraction mode passed to TopologyExtractor.build_cgd() when a CGD must first be generated.

name: str

CGD graph ID used when generating the initial CGD.

java: str, optional

Java executable name or explicit path. If None, jdk4py is tried first, then the system PATH.

timeout_s: int

Timeout for the Systre call in seconds.

xmx: str

Maximum Java heap size.

keep_tmp: bool

If True, temporary CGD files are kept on disk.

best_component(stdout: str | None = None) RelaxedComponent | None[source]

Return the most informative relaxed component.

Current strategy:

rank by number of edges, then by number of nodes.

parameters:
stdout: str, optional

Systre stdout. If not provided, Systre is executed first.

returns:

RelaxedComponent or None

crystal2_hash(*, component_index: int | None = None, include_edge_centers: bool = True, fallback_to_input_cgd: bool = False, algorithm: str = 'sha256') str | None[source]

Return a hash computed from the CRYSTAL2 CGD text.

parameters:
component_index: int, optional

Component index to export. If not provided, the best component is used.

include_edge_centers: bool

If True, include commented edge-centre metadata.

fallback_to_input_cgd: bool

If True, convert the original PERIODIC_GRAPH CGD to a CRYSTAL2 wrapper when relaxed data is unavailable.

algorithm: str

Hash algorithm supported by hashlib.

returns:

str or None

crystal2_text(*, component_index: int | None = None, include_edge_centers: bool = True, fallback_to_input_cgd: bool = False) str | None[source]

Return CRYSTAL2 CGD text for one parsed relaxed component.

parameters:
component_index: int, optional

Component index to export. If not provided, the best component is used.

include_edge_centers: bool

If True, include commented edge-centre metadata.

fallback_to_input_cgd: bool

If True, convert the original PERIODIC_GRAPH CGD to a CRYSTAL2 wrapper when relaxed data is unavailable.

returns:

str or None

extract_relaxed_components(stdout: str | None = None, force: bool = False) List[RelaxedComponent][source]

Parse relaxed components from Systre stdout.

parameters:
stdout: str, optional

Systre stdout. If not provided, Systre is executed first.

force: bool

If True, rerun Systre when stdout is not provided.

returns:
list

List of parsed relaxed components.

hashes_for_unnamed_components(decimals: int = 8, algorithm: str = 'sha256') Dict[int, str][source]

Return hashes for components that do not have an RCSR name.

parameters:
decimals: int

Number of decimal places used when rounding floats.

algorithm: str

Hash algorithm supported by hashlib.

returns:
python dictionary
Mapping:

component_index -> topology hash

identify(force: bool = False) SystreResult[source]

Run Systre and return the topology-identification result.

Results are cached after the first call unless force=True.

parameters:
force: bool

If True, rerun Systre even if a cached result exists.

returns:

SystreResult

named_components(stdout: str | None = None) List[RelaxedComponent][source]

Return all relaxed components that have an RCSR name.

parameters:
stdout: str, optional

Systre stdout. If not provided, Systre is executed first.

returns:
list

List of named relaxed components.

topology_hash(decimals: int = 8, component_index: int | None = None, algorithm: str = 'sha256') str | None[source]

Return the relaxed-topology hash for one parsed component.

parameters:
decimals: int

Number of decimal places used when rounding floats.

component_index: int, optional

Component index to use. If not provided, the best component is used.

algorithm: str

Hash algorithm supported by hashlib.

returns:
str or None

Hex digest, or None if no relaxed component was parsed.

topology_summary(decimals: int = 8, component_index: int | None = None) Dict[str, object] | None[source]

Return a normalized topology summary for hashing or storage.

parameters:
decimals: int

Number of decimal places used when rounding floats.

component_index: int, optional

Component index to use. If not provided, the best component is used.

returns:

python dictionary or None

unnamed_components(stdout: str | None = None) List[RelaxedComponent][source]

Return all relaxed components without an RCSR name.

parameters:
stdout: str, optional

Systre stdout. If not provided, Systre is executed first.

returns:
list

List of unnamed relaxed components.

write_crystal2(out_path: str | Path, *, component_index: int | None = None, include_edge_centers: bool = True, fallback_to_input_cgd: bool = False) Path[source]

Write CRYSTAL2 CGD text to disk.

parameters:
out_path: str or Path

Output file path.

component_index: int, optional

Component index to export. If not provided, the best component is used.

include_edge_centers: bool

If True, include commented edge-centre metadata.

fallback_to_input_cgd: bool

If True, convert the original PERIODIC_GRAPH CGD to a CRYSTAL2 wrapper when relaxed data is unavailable.

returns:
pathlib.Path

Written file path.

raises:
ValueError:

If no CRYSTAL2 text can be generated.

mofstructure.systre.crystal2_fallback_from_periodic_graph(periodic_graph_cgd: str, *, name: str = 'net') str[source]

Convert a PERIODIC_GRAPH CGD into a CRYSTAL2 wrapper.

This function is intended as a fallback when Systre did not emit relaxed coordinates, but the pipeline still needs a CRYSTAL2-like text block.

parameters:
periodic_graph_cgd: str

Input PERIODIC_GRAPH CGD text.

name: str

Name written to the CRYSTAL2 block.

returns:
str

CRYSTAL2 CGD text.

mofstructure.systre.crystal2_text_from_component(comp: RelaxedComponent, *, name: str, include_edge_centers: bool = True) str[source]

Return CRYSTAL2 CGD text from a parsed relaxed component.

parameters:
comp: RelaxedComponent

Parsed relaxed component.

name: str

Name written to the CRYSTAL2 block.

include_edge_centers: bool

If True, write edge centres as commented metadata lines.

returns:
str

CRYSTAL2 CGD text.

mofstructure.systre.extract_relaxed_components(stdout: str) List[RelaxedComponent][source]

Parse all relaxed components from Systre stdout.

parameters:
stdout: str

Systre standard output.

returns:
list

List of parsed relaxed components.

mofstructure.systre.find_java(java: str | None = None) str[source]

Find a working Java executable.

Resolution order:
  1. explicit java argument

  2. jdk4py bundled Java

  3. system PATH lookup

parameters:
java: str, optional

Java executable name or explicit path.

returns:
str

Working Java command.

raises:
RuntimeError:

If Java cannot be located.

mofstructure.systre.identify_topology(x: str | Path | Atoms, *, input_is_cgd: bool | None = None, method: str = 'all_node', name: str = 'net', java: str | None = None, timeout_s: int = 30, xmx: str = '1024m', keep_tmp: bool = False) SystreResult[source]

Identify the topology of a structure or CGD input using Systre.

parameters:
x:
Input object. Supported values are:
  • CGD filepath

  • CGD text

  • ASE atoms object

  • pymatgen Structure object

  • structure filepath readable by ASE

input_is_cgd: bool, optional

If True, force the input to be treated as CGD.

method: str

Topology mode used when a CGD must first be generated.

name: str

CGD graph ID.

java: str, optional

Java executable name or explicit path.

timeout_s: int

Timeout in seconds.

xmx: str

Maximum Java heap size.

keep_tmp: bool

If True, temporary CGD files are kept.

returns:

SystreResult

mofstructure.systre.identify_topology_batch(folder: str | Path, *, patterns: Tuple[str, ...] = ('.cgd', '.cif', '.vasp', '.poscar'), recursive: bool = True, **kwargs) Dict[str, SystreResult][source]

Identify topologies for all supported files in a folder.

parameters:
folder: str or Path

Input folder.

patterns: tuple

Allowed filename suffixes.

recursive: bool

If True, recurse into subfolders.

**kwargs:

Additional keyword arguments passed to identify_topology().

returns:
python dictionary
Mapping:

filepath -> SystreResult

mofstructure.systre.main(argv: Sequence[str] | None = None) int[source]

Command-line entry point for topology identification and relaxed export.

parameters:
argv: list, optional

Command-line arguments.

returns:
int

Exit status code.

mofstructure.systre.parse_relaxed_component(block: str, component_index: int) RelaxedComponent | None[source]

Parse one relaxed component from a Systre block.

parameters:
block: str

One Systre component block.

component_index: int

Component index.

returns:

RelaxedComponent or None

mofstructure.systre.parse_systre_topology(stdout: str) str[source]

Parse the identified topology name from Systre stdout.

If several components are present and they do not all map to the same topology, the function returns “MISMATCH”.

parameters:
stdout: str

Systre standard output.

returns:
str
Identified topology name or one of the sentinel values:
  • “UNKNOWN”

  • “ERROR”

  • “MISMATCH”

mofstructure.systre.run_systre_on_cgd_path(cgd_path: str | Path, *, java: str | None = None, timeout_s: int = 30, xmx: str = '1024m') CompletedProcess[source]

Run Systre on a CGD file stored on disk.

parameters:
cgd_path: str or Path

Path to a CGD file.

java: str, optional

Java executable name or explicit path.

timeout_s: int

Timeout in seconds.

xmx: str

Maximum Java heap size.

returns:

subprocess.CompletedProcess

mofstructure.systre.systre_command(*, java: str | None = None, xmx: str = '1024m', jar_relpath: str = 'bin/Systre-19.6.0.jar', rcsr_relpath: str = 'db/RCSRnets-2019-06-01.arc') List[str][source]

Build the Systre command-line call.

parameters:
java: str, optional

Java executable name or explicit path.

xmx: str

Maximum Java heap size.

jar_relpath: str

Relative path to the packaged Systre JAR file.

rcsr_relpath: str

Relative path to the packaged RCSR archive.

returns:
list

Command list suitable for subprocess.run.