Skip to content

Quick start

This page runs the complete workflow on the tetrahedral pore of UiO-66, built as a Tri4Di6 cage from the UiO-66 Zr6 node and a 1,4-phenylene linker. Every structure used ships with the package (cage_isomer_builder.example_data), so the code runs as it is. Each step links to the page that explains it in full.

1. Build and optimise the pore

from cage_isomer_builder import example_data
from cage_isomer_builder.cage import Tri4Di6CageBuilder

cage = Tri4Di6CageBuilder(
    node=example_data.path("uio66_tri_node"),   # Zr6 node, three X connection points
    linker=example_data.path("bdc"),            # 1,4-phenylene, two X connection points
    scale_multiplier=0.225,                     # place the bulky node close to the linkers
)
cage.build()
cage.optimise(include_charges=False, logfile=None)   # UFF4MOF, nodes and linkers kept rigid
cage.save("uio66_pore.xyz")

See Build & enumerate and Optimisation.

2. Find the functional-group sites and count isomers

anchors, sites = cage.functionalise()      # every aromatic C-H becomes an R site
print(len(sites))                          # 24: four on each of the six linkers
print(cage.point_group().name)             # Td
print(cage.count_unique_isomers_burnside())   # 176 symmetry-unique isomers, one group per linker

3. Write the isomers and attach a real group

from cage_isomer_builder.utils.functionalise import functionalise_isomer_sites
from cage_isomer_builder.utils.sites import read_isomer

isomers = cage.enumerate_isomers(output_path="isomers")      # 176 files
isomer = read_isomer(f"isomers/{'-'.join(map(str, isomers[0]))}.xyz")
print(isomer.info["r_sites"])            # {atom index: 'R1', ...}

decorated = functionalise_isomer_sites(isomer, example_data.read("NH2"))
print(decorated.get_chemical_formula())  # six NH2 groups attached

See Functionalise isomers and R sites & file formats.

4. Several groups, ratios and defects

print(cage.count_rgroup_isomers(linker_patterns={"A": 3, "B": 3}))   # 3424 (50:50)
print(cage.count_defect_isomers(1, groups="A"))                      # 256 (one linker missing)

See Multivariate pores & defects.

5. Descriptors

desc = cage.get_descriptor()                 # pairs of all feature sites
print(desc.summary()[("fg", "pi")])          # (120, 120.0): FG site - ring pairs

# 50:50 NH2/CH3 linkers; named groups are tuples (a string means one letter per group)
ensemble = cage.get_ensemble_descriptor(linker_patterns={("NH2",): 3, ("CH3",): 3}, by="label")
print(round(ensemble.total(), 3))            # 15.0 group-group pairs per pore (6 groups)

See Descriptors.

6. Dock a guest

from cage_isomer_builder.utils.functionalise import max_guests_in_host, place_guest_in_host

host = cage.to_ase(hydrogens=True)          # the pore with H back on every site
methane = example_data.read("methane")
print(max_guests_in_host(host, methane, seed=0))     # 4 methane fit in the 7.5 A cavity
best = place_guest_in_host(host, methane, method="energy", n_samples=200, seed=0)[0]
print(best.atoms.info["interaction_energy"])         # eV, negative = bound

See Host-guest docking and Guests & matching.