This repository provides a Python workflow for decomposing CIF files of covalent organic frameworks (COFs) into constituent molecular building blocks.
The code is designed for high-throughput processing of large COF datasets. It reads periodic CIF files, reconstructs bonding under periodic boundary conditions (PBCs), identifies chemically meaningful bonds to cut, extracts molecular fragments, removes duplicate fragments globally, and writes unique building blocks as XYZ files.
The workflow is particularly useful for:
- constructing building-block datasets from COF databases;
- studying linker and node diversity in COFs;
- preparing datasets for machine learning and generative modeling;
- analyzing structural motifs and topology-dependent chemistry.
Figure 1. Schematic illustration of the COF decomposition workflow.
The overall decomposition workflow proceeds as follows:
- Read periodic COF CIF structures.
- Construct a supercell to recover periodic connectivity.
- Identify the central image to avoid edge artifacts.
- Build a periodic bonding graph using covalent-radius cutoffs.
- Convert the graph into an RDKit molecular representation.
- Detect chemically meaningful bonds to cut.
- Fragment the structure into molecular building blocks.
- Unwrap fragments across periodic boundaries.
- Generate canonical molecular fingerprints.
- Deduplicate fragments globally across all CIFs.
- Save unique fragments and metadata.
Each COF structure is read using ASE:
from ase.io import readThe workflow assumes periodic crystalline structures stored as .cif files.
To reconstruct bonds crossing unit-cell boundaries, the primitive cell is expanded into a supercell:
repeat = (3, 3, 3)
This helps recover full molecular connectivity under periodic boundary conditions.
The default supercell size is:
3 × 3 × 3
but can be modified with:
--repeat 3 3 3Only atoms belonging to the central periodic image are retained for molecular graph construction.
This avoids edge artifacts and prevents duplicated connectivity caused by periodic wrapping.
Bond connectivity is reconstructed using interatomic distances and covalent radii:
cutoff = scale × (r_i + r_j)
where:
r_iandr_jare covalent radii;scaleis a user-defined scaling factor.
Default:
--scale 1.20Neighbor searching is performed using ASE neighbor lists.
The periodic bonding graph is converted into an RDKit molecule.
This enables:
- ring analysis;
- bond fragmentation;
- canonical SMILES generation;
- graph-based molecular operations.
The workflow applies chemically motivated decomposition rules designed for COFs.
- center-first patterns in small rings;
- selected B–O, N–O, N–N, C–N, and Si–O environments;
- ring-aware decomposition rules;
- local coordination analysis.
The code avoids:
- cutting bonds inside protected small rings;
- generating isolated single atoms after fragmentation.
A greedy filtering procedure ensures chemically meaningful fragments.
RDKit fragmentation is performed using:
Chem.FragmentOnBonds(...)This produces disconnected molecular fragments corresponding to potential building blocks.
Fragments split across periodic boundaries are unwrapped in fractional-coordinate space.
This ensures each fragment becomes a continuous molecular object before being written to disk.
Without this step, fragments crossing unit-cell boundaries would appear artificially broken.
Each fragment is converted into a canonical isomeric SMILES string:
Chem.MolToSmiles(...)The fingerprint is used to identify globally unique fragments.
Dummy atoms introduced during fragmentation are removed before fingerprint generation.
A SQLite database tracks all previously observed fragment fingerprints.
If a fragment already exists:
- it is not written again;
- its occurrence is recorded for bookkeeping.
This allows:
- efficient processing of very large datasets;
- resume support;
- global uniqueness tracking across all CIFs.
The workflow produces:
- unique fragment
.xyzfiles; - a fragment record file;
- a SQLite database;
- a CSV mapping fragments to CIF structures.
- numpy
- ase
- rdkit
Install with pip:
pip install numpy aseRDKit is usually easier to install via conda:
conda install -c conda-forge rdkitRecommended environment:
conda create -n cof-decompose python=3.11
conda activate cof-decompose
conda install -c conda-forge rdkit ase numpypython COFs_decompose.py \
--cif-dir ./cifs \
--out-dir ./uniq_xyz \
--record ./fragments_record.txt \
--db ./fragments_seen.sqlite \
--csv-out ./fragment_to_cifs.csvpython COFs_decompose.py \
--cif-dir ./cifs \
--out-dir ./uniq_xyz \
--record ./fragments_record.txt \
--db ./fragments_seen.sqlite \
--csv-out ./fragment_to_cifs.csv \
--repeat 3 3 3 \
--scale 1.20 \
--span-warn 0.75 \
--workers 16 \
--resume| Argument | Description |
|---|---|
--cif-dir |
Directory containing input CIF files |
--out-dir |
Output directory for unique XYZ fragments |
--record |
Text record file for fragment bookkeeping |
--db |
SQLite database for deduplication and resume support |
--csv-out |
CSV mapping fragments to CIF structures |
--repeat |
Supercell replication size |
--scale |
Covalent-radius scaling factor for bond detection |
--span-warn |
Warn if fragment spans too much fractional space |
--workers |
Number of parallel worker processes |
--max-files |
Maximum number of CIFs to process |
--resume |
Skip CIFs already processed |
Output directory:
./uniq_xyz/
Example:
opt_example_uniq00000001.xyz
Each XYZ file corresponds to a globally unique fragment.
Example:
example.cif 00000001 SMI:C1=CC=CC=C1 uniq_xyz/example_uniq00000001.xyz
Columns:
| Column | Meaning |
|---|---|
| CIF | Source CIF file |
| unique_fragment_index | Global fragment index |
| fingerprint | Canonical fingerprint |
| xyz_path | Path to XYZ file |
The SQLite database stores:
- fragment fingerprints;
- processed CIF files;
- fragment occurrences;
- resume information.
This enables robust large-scale processing.
Example:
fragment_idx,n_cifs,cif_basenames
This file maps each unique fragment to all CIF structures containing it.
The workflow supports multiprocessing using:
ProcessPoolExecutorExample:
--workers 32Threading for BLAS/OpenMP libraries is automatically limited to reduce oversubscription on HPC systems.
Interrupted jobs can be resumed using:
--resumePreviously completed CIF files will be skipped automatically.
- The current implementation assumes single-bond connectivity in the RDKit graph.
- Fragment uniqueness is determined using canonical isomeric SMILES.
- Bonding is reconstructed using covalent-radius heuristics.
- The workflow is primarily designed for COFs and related porous organic frameworks.
- Cutting rules may need adjustment for unusual linkage chemistries.
Potential future extensions include:
- bond-order assignment;
- topology-aware decomposition;
- visualization utilities;
- direct CIF export for fragments;
- support for MOFs and hybrid materials;
- graph neural network dataset generation;
- integration with generative AI workflows.
[Add citation here]

