### Install PoseBusters Source: https://github.com/maabuu/posebusters/blob/main/docs/source/index.rst Install PoseBusters using pip. This command installs the library and its dependencies. ```bash >>> pip install posebusters ``` -------------------------------- ### Setup Python Environment with Conda Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Installs PoseBusters and its dependencies using Conda and pip. Ensure you have Python 3.10 or compatible. ```bash conda create -n posebusters python=3.10 jupyter notebook conda activate posebusters pip install posebusters --upgrade ``` -------------------------------- ### Load and use built-in redocking dataset with PoseBusters Source: https://context7.com/maabuu/posebusters/llms.txt Load the 'four_redocks' dataset, which provides paths to four bundled PDB crystal structures, and use it with PoseBusters for testing or reproducing examples. ```python from posebusters.datasets.load_datasets import four_redocks, four_docks, four_mols from posebusters import PoseBusters # Full redocking dataset (mol_pred + mol_true + mol_cond) df = four_redocks() print(df.columns.tolist()) # ['name', 'mol_pred', 'mol_true', 'mol_cond'] pb = PoseBusters(config="redock") results = pb.bust_table(df) print(results) ``` -------------------------------- ### Verify Molecule File Loading with check_loading Source: https://context7.com/maabuu/posebusters/llms.txt Checks if molecule files (`mol_pred`, `mol_true`, `mol_cond`) are valid RDKit Mol objects. This is the first module executed. Ensure RDKit is installed and molecule files exist. ```python from rdkit.Chem import MolFromMolFile from posebusters import check_loading mol_pred = MolFromMolFile("ligand_pred.sdf") mol_true = MolFromMolFile("crystal_ligand.sdf") mol_cond = None # protein not provided result = check_loading(mol_pred=mol_pred, mol_true=mol_true, mol_cond=mol_cond) print(result) # {'results': {'mol_pred_loaded': True, 'mol_true_loaded': True, 'mol_cond_loaded': False}} ``` -------------------------------- ### Custom PoseBusters Configuration Source: https://context7.com/maabuu/posebusters/llms.txt Configure PoseBusters by providing a custom YAML file or Python dictionary to specify modules, functions, parameters, and output column names. This example demonstrates a minimal configuration focusing on chemistry and geometry checks. ```python from posebusters import PoseBusters # Minimal custom config: only chemistry and geometry checks custom_config = { "modules": [ { "name": "Chemistry", "function": "rdkit_sanity", "chosen_binary_test_output": ["passes_rdkit_sanity_checks"], "rename_outputs": {"passes_rdkit_sanity_checks": "Sanitization"}, }, { "name": "Geometry", "function": "distance_geometry", "parameters": { "threshold_bad_bond_length": 0.25, "threshold_bad_angle": 0.25, "threshold_clash": 0.3, "ignore_hydrogens": True, "sanitize": True, }, "chosen_binary_test_output": [ "bond_lengths_within_bounds", "bond_angles_within_bounds", "no_internal_clash", ], "rename_outputs": { "bond_lengths_within_bounds": "Bond lengths", "bond_angles_within_bounds": "Bond angles", "no_internal_clash": "Internal steric clash", }, }, ], "top_n": None, "max_workers": 0, "chunk_size": 100, "loading": { "mol_pred": {"sanitize": False, "add_hs": False, "assign_stereo": False}, }, } pb = PoseBusters(config=custom_config) results = pb.bust("molecule.sdf") print(results) ``` -------------------------------- ### Built-in Dataset Loaders Source: https://context7.com/maabuu/posebusters/llms.txt Utility functions to load pre-packaged DataFrames containing paths to four bundled PDB crystal structures. These are useful for testing installations and reproducing examples. ```APIDOC ## Built-in dataset loaders — `four_redocks`, `four_docks`, `four_mols` Utility functions that return pre-packaged DataFrames pointing to the four bundled PDB crystal structures (1ia1, 1of6, 1s3v, 1uou). Useful for smoke-testing installations and for reproducing paper examples. ```python from posebusters.datasets.load_datasets import four_redocks, four_docks, four_mols from posebusters import PoseBusters # Full redocking dataset (mol_pred + mol_true + mol_cond) df = four_redocks() print(df.columns.tolist()) # ['name', 'mol_pred', 'mol_true', 'mol_cond'] pb = PoseBusters(config="redock") results = pb.bust_table(df) print(results) ``` ``` -------------------------------- ### Save output to a file Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst The '--out' option allows saving the command output to a specified file, for example, 'results.csv'. ```bash bust generated_molecules.sdf --outfmt csv --out results.csv ``` -------------------------------- ### Detect Radical Electrons with check_radicals Source: https://context7.com/maabuu/posebusters/llms.txt Checks for radical electrons in a molecule before and after sanitization. Radicals often indicate malformed AI-generated structures. Ensure RDKit is installed and molecule is valid. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_radicals mol = MolFromSmiles("c1ccccc1") AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_radicals(mol) print(result) # {'results': {'no_radicals': True, 'no_radicals_before_sanitization': True}} ``` -------------------------------- ### Display help information Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Running the 'bust' command with the '--help' option displays detailed information about available command-line options. ```bash bust --help ``` -------------------------------- ### PoseBusters Class Initialization and `bust` Method Source: https://context7.com/maabuu/posebusters/llms.txt Demonstrates how to initialize the PoseBusters class with different configurations ('mol', 'dock', 'redock') and use the `bust` method to perform checks on single or multiple molecule files. It also shows how to specify additional arguments like `mol_cond` for protein structures and `full_report` for detailed results. ```APIDOC ## PoseBusters Class The central class that loads a YAML or built-in configuration, initializes check modules, and runs them over one or more predicted molecule files. Accepts RDKit `Mol` objects or file paths (`.sdf`, `.mol`, `.mol2`, `.pdb`) for all molecule arguments. Parallelization is supported via `ProcessPoolExecutor`. ### Mode: mol Check a standalone generated molecule (no protein, no reference ligand) ```python from posebusters import PoseBusters pb = PoseBusters(config="mol") results = pb.bust("generated_molecule.sdf") print(results) # MultiIndex DataFrame: (file, molecule, position) # Columns: mol_pred_loaded, sanitization, inchi_convertible, all_atoms_connected, # no_radicals, bond_lengths, bond_angles, internal_steric_clash, # aromatic_ring_flatness, non-aromatic_ring_non-flatness, # double_bond_flatness, internal_energy ``` ### Mode: dock Check a docked ligand against a protein (no reference crystal ligand) ```python from posebusters import PoseBusters pb = PoseBusters(config="dock") results = pb.bust("docked_ligand.sdf", mol_cond="protein.pdb") print(results[["protein-ligand_maximum_distance", "minimum_distance_to_protein", "no_volume_clash"]]) ``` ### Mode: redock Full redocking check: predicted ligand vs. crystal ligand vs. protein ```python from posebusters import PoseBusters pb = PoseBusters(config="redock") results = pb.bust( "ligand_pred.sdf", mol_true="crystal_ligand.sdf", mol_cond="protein.pdb", full_report=True, # include all numeric detail columns, not just boolean pass/fail ) # Check pass rate print(results.all(axis=1).mean()) # fraction of poses passing all tests ``` ### Batch: multiple predicted files ```python import pandas as pd from posebusters import PoseBusters pb = PoseBusters(config="mol") results = pb.bust(["mol_a.sdf", "mol_b.sdf", "mol_c.sdf"]) ``` ### Parallelization ```python from posebusters import PoseBusters pb = PoseBusters(config="redock", max_workers=4, chunk_size=50) results = pb.bust("large_ensemble.sdf", mol_true="crystal.sdf", mol_cond="protein.pdb") ``` ``` -------------------------------- ### Define Input File Paths Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Sets up Path objects for input files: predicted molecules, ground truth molecules, and conditioning molecule. ```python from pathlib import Path pred_file = Path("inputs/generated_molecules.sdf") # predicted or generated molecules true_file = Path("inputs/crystal_ligand.sdf") # "ground truth" molecules cond_file = Path("inputs/protein.pdb") # conditioning molecule ``` -------------------------------- ### Display version information Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Running the 'bust' command with the '--version' option displays the current version of the software. ```bash bust --version ``` -------------------------------- ### Check a single docked ligand (short output) Source: https://github.com/maabuu/posebusters/blob/main/docs/source/index.rst Use the 'bust' command to check a redocked ligand against a crystal ligand and protein. The '--outfmt short' option provides a concise summary of the checks. ```bash bust redocked_ligand.sdf -l crystal_ligand.sdf -p protein.pdb --outfmt short ``` -------------------------------- ### Check a single docked ligand (CSV output) Source: https://github.com/maabuu/posebusters/blob/main/docs/source/index.rst Use the 'bust' command to check a redocked ligand against a crystal ligand and protein. The '--outfmt csv' option outputs the results in CSV format, suitable for further analysis. ```bash bust redocked_ligand.sdf -l crystal_ligand.sdf -p protein.pdb --outfmt csv ``` -------------------------------- ### Initialize PoseBusters for 'dock' mode Source: https://context7.com/maabuu/posebusters/llms.txt Initialize PoseBusters for checking a docked ligand against a protein. This mode does not require a reference crystal ligand. ```python # --- Mode: dock --- # Check a docked ligand against a protein (no reference crystal ligand) pb = PoseBusters(config="dock") results = pb.bust("docked_ligand.sdf", mol_cond="protein.pdb") print(results[["protein-ligand_maximum_distance", "minimum_distance_to_protein", "no_volume_clash"]]) ``` -------------------------------- ### Initialize PoseBusters for 'redock' mode with full report Source: https://context7.com/maabuu/posebusters/llms.txt Initialize PoseBusters for a full redocking check, comparing a predicted ligand against a crystal ligand and protein. Set full_report=True to include all numeric detail columns. ```python # --- Mode: redock --- # Full redocking check: predicted ligand vs. crystal ligand vs. protein pb = PoseBusters(config="redock") results = pb.bust( "ligand_pred.sdf", mol_true="crystal_ligand.sdf", mol_cond="protein.pdb", full_report=True, # include all numeric detail columns, not just boolean pass/fail ) # Check pass rate print(results.all(axis=1).mean()) # fraction of poses passing all tests ``` -------------------------------- ### PoseBusters CLI Usage Source: https://context7.com/maabuu/posebusters/llms.txt The `bust` command-line interface allows for various checks and modes, including standalone molecule checks, docked ligand comparisons, full redocking, batch processing via CSV, and output format customization. ```bash # Check a standalone generated molecule bust molecule_pred.sdf ``` ```bash # Check multiple molecules at once bust mol_a.sdf mol_b.sdf mol_c.sdf ``` ```bash # Check a docked ligand against a protein (dock mode) bust ligand_pred.sdf -p protein.pdb ``` ```bash # Full redocking check (redock mode) bust ligand_pred.sdf -l crystal_ligand.sdf -p protein.pdb ``` ```bash # Batch mode via CSV (columns: mol_pred, mol_true, mol_cond) bust -t input_table.csv ``` ```bash # Output formats: short (default), long (per-test detail), csv bust ligand_pred.sdf -l crystal.sdf -p protein.pdb --outfmt csv --output results.csv ``` ```bash # Full report includes numeric detail columns, not just boolean pass/fail bust ligand_pred.sdf --outfmt long --full-report ``` ```bash # Parallel processing with 8 workers, chunks of 50 poses bust large_ensemble.sdf -p protein.pdb --max-workers 8 --chunk-size 50 ``` ```bash # Only check the top 5 poses per file bust ensemble.sdf --top-n 5 ``` -------------------------------- ### Check re-docked ligands against crystal ligand and protein Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Check a series of re-docked ligands against a crystal ligand and protein. Use -l for the crystal ligand and -p for the protein. ```bash bust redocked_ligand.sdf -l crystal_ligand.sdf -p protein.pdb --outfmt long ``` -------------------------------- ### Check a new ligand against a protein Source: https://github.com/maabuu/posebusters/blob/main/README.md Check a newly generated ligand pose against a protein structure by providing the ligand SDF and protein PDB files. ```bash bust ligand_pred.sdf -p mol_cond.pdb ``` -------------------------------- ### check_loading Source: https://context7.com/maabuu/posebusters/llms.txt Verifies that molecule files (`mol_pred`, `mol_true`, `mol_cond`) are successfully loaded as RDKit Mol objects. This is typically the first check performed. ```APIDOC ## `check_loading` — Verify molecule files loaded successfully Checks whether `mol_pred`, `mol_true`, and `mol_cond` are valid RDKit `Mol` objects. Returns a results dict with boolean flags. This is always the first module run in any configuration. ```python from rdkit.Chem import MolFromMolFile from posebusters import check_loading mol_pred = MolFromMolFile("ligand_pred.sdf") mol_true = MolFromMolFile("crystal_ligand.sdf") mol_cond = None # protein not provided result = check_loading(mol_pred=mol_pred, mol_true=mol_true, mol_cond=mol_cond) print(result) # {'results': {'mol_pred_loaded': True, 'mol_true_loaded': True, 'mol_cond_loaded': False}} ``` ``` -------------------------------- ### Check a re-docked ligand against a crystal complex Source: https://github.com/maabuu/posebusters/blob/main/README.md Verify a re-docked ligand pose by comparing it against the ligand from a given protein-ligand crystal complex. Requires the predicted ligand, the crystal ligand, and the protein PDB file. ```bash bust ligand_pred.sdf -l mol_true.sdf -p protein.pdb ``` -------------------------------- ### Robust Molecule Loading Utilities Source: https://context7.com/maabuu/posebusters/llms.txt Safely load single molecules or iterate over multi-conformer SDF files, supporting various formats. These utilities return `None` on failure, preventing exceptions in batch processing. ```python from posebusters.tools.loading import safe_load_mol, safe_supply_mols, get_num_mols from pathlib import Path # Load a single molecule (e.g., a PDB protein) mol = safe_load_mol(Path("protein.pdb"), sanitize=False, proximityBonding=False) if mol is None: print("Failed to load molecule") # Count poses in an SDF before processing n = get_num_mols(Path("ensemble.sdf")) print(f"Found {n} poses") # Iterate over all poses in an SDF for mol in safe_supply_mols(Path("ensemble.sdf"), sanitize=True): if mol is not None: print(mol.GetProp("_Name"), mol.GetNumAtoms()) ``` -------------------------------- ### Loading Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Checks the loading of molecules, likely related to solubility or binding. ```APIDOC def check_loading(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol = None, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Checks the loading of molecules.""" pass ``` -------------------------------- ### Check multiple generated molecule poses Source: https://github.com/maabuu/posebusters/blob/main/README.md Check multiple generated molecule poses by listing their SDF file paths or using a wildcard. ```bash bust molecule_a.sdf molecule_b.sdf ``` ```bash bust molecule_*.sdf ``` -------------------------------- ### Dock Mode Analysis Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Initializes PoseBusters in 'dock' mode for de-novo generated molecules or ligands docked into non-cognate receptors. Returns binary test report columns by default. ```python buster = PoseBusters(config="dock") df = buster.bust([pred_file], true_file, cond_file) print(df.shape) df ``` -------------------------------- ### Default output format (short) Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst The 'bust' command defaults to a short output format, providing a concise summary of results. ```bash bust generated_molecules.sdf --outfmt short ``` -------------------------------- ### Check Planarity with check_flatness Source: https://context7.com/maabuu/posebusters/llms.txt Verifies planarity of aromatic rings and double bonds using SVD, and can check for puckering in non-aromatic rings. Use `flat_systems` for custom SMARTS. `threshold_flatness` controls deviation tolerance. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_flatness mol = MolFromSmiles("c1ccccc1") # benzene — should be flat AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_flatness(mol_pred=mol, threshold_flatness=0.1) print(result["results"]) # {'num_systems_checked': 1, 'num_systems_passed': 1, 'max_distance': 0.001, 'flatness_passes': True} # Custom SMARTS to check planarity of a specific substructure custom_systems = {"my_group": "[c]1[c][c][c][c][c]1"} result_custom = check_flatness(mol, flat_systems=custom_systems, threshold_flatness=0.05) ``` -------------------------------- ### Mol Mode Analysis Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Initializes PoseBusters in 'mol' mode for de-novo generated molecules or generated molecular conformations. Returns binary test report columns by default. ```python buster = PoseBusters(config="mol") df = buster.bust([pred_file], None, None) print(df.shape) df ``` -------------------------------- ### Initialize PoseBusters for 'mol' mode Source: https://context7.com/maabuu/posebusters/llms.txt Initialize the PoseBusters class for checking standalone generated molecules. This mode does not require a protein or reference ligand. ```python from posebusters import PoseBusters # --- Mode: mol --- # Check a standalone generated molecule (no protein, no reference ligand) pb = PoseBusters(config="mol") results = pb.bust("generated_molecule.sdf") print(results) ``` -------------------------------- ### CSV output format for saving Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Use the 'csv' output format for easy copying and saving of the results to a file. ```bash bust generated_molecules.sdf --outfmt csv ``` -------------------------------- ### Check a single generated molecule pose Source: https://github.com/maabuu/posebusters/blob/main/README.md Use the 'bust' command to check a single generated molecule pose from an SDF file. ```bash bust molecule_pred.sdf ``` -------------------------------- ### Check molecules in an SDF file Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Use 'bust' to check a series of molecules within a single .sdf file. The output format can be set to 'long' for detailed results. ```bash bust generated_molecules.sdf --outfmt long ``` -------------------------------- ### Redock Mode Analysis Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Initializes PoseBusters in 'redock' mode for ligands docked into cognate receptor crystal structures. Returns binary test report columns by default. ```python # by default only the binary test report columns are returned buster = PoseBusters(config="redock") df = buster.bust([pred_file], true_file, cond_file) print(df.shape) df ``` -------------------------------- ### Python API for checking a molecule Source: https://github.com/maabuu/posebusters/blob/main/README.md Use the DockBuster Python API to check a general molecule. Requires the molecule file and the protein crystal file. ```python # check molecule DockBuster().bust(ligand_pred_file, protein_crystal_file) ``` -------------------------------- ### Mol Mode with Full Report Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Initializes PoseBusters in 'mol' mode and enables the 'full_report' option to return all columns of the test reports, useful for debugging and further analysis. ```python buster = PoseBusters(config="mol") df = buster.bust([pred_file], None, None, full_report=True) print(df.shape) df ``` -------------------------------- ### PoseBusters.bust_table() Method Source: https://context7.com/maabuu/posebusters/llms.txt Provides a method to perform batch checking of molecule poses using a pandas DataFrame. The DataFrame should contain columns like `mol_pred`, `mol_true`, and `mol_cond`, which can hold file paths or RDKit `Mol` objects. This method is the programmatic equivalent of the `--table` CLI option. ```APIDOC ## `PoseBusters.bust_table()` — Batch checking via DataFrame Accepts a pandas DataFrame with columns `mol_pred`, `mol_true`, `mol_cond` (all optional except `mol_pred`) containing file paths or RDKit `Mol` objects. This is the programmatic equivalent of the `--table` CLI option. ```python import pandas as pd from posebusters import PoseBusters # Build an input table (paths or Mol objects) table = pd.DataFrame({ "mol_pred": ["pose1.sdf", "pose2.sdf", "pose3.sdf"], "mol_true": ["crystal.sdf", "crystal.sdf", "crystal.sdf"], "mol_cond": ["protein.pdb", "protein.pdb", "protein.pdb"], }) pb = PoseBusters(config="redock", top_n=1) # top_n: only check first pose per file results = pb.bust_table(table, full_report=False) # Filter passing poses passing = results[results.all(axis=1)] print(f"{len(passing)} / {len(results)} poses pass all checks") # Export results to CSV results.to_csv("results.csv") ``` ``` -------------------------------- ### Import PoseBusters Class Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Imports the main PoseBusters class for use in the notebook. ```python from posebusters import PoseBusters ``` -------------------------------- ### Python API for checking docked ligand Source: https://github.com/maabuu/posebusters/blob/main/README.md Use the DockBuster Python API to check a docked ligand against a protein structure. Requires the predicted ligand file and the protein crystal file. ```python # check docked ligand DockBuster().bust(ligand_pred_file, protein_crystal_file) ``` -------------------------------- ### Python API for checking re-docked ligand Source: https://github.com/maabuu/posebusters/blob/main/README.md Use the DockBuster Python API to check a re-docked ligand. This involves providing the predicted ligand file, the crystal ligand file, and the protein crystal file. ```python from dockbusters import DockBuster # check re-docked ligand DockBuster().bust(ligand_pred_file, ligand_crystal_file, protein_crystal_file) ``` -------------------------------- ### Check Molecular Identity and Stereochemistry Source: https://context7.com/maabuu/posebusters/llms.txt Compares predicted and crystal ligands by decomposing their InChI strings layer-by-layer. This is critical for docking validation to ensure ligand identity is preserved. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_identity mol_pred = MolFromSmiles("C[C@@H](O)c1ccccc1") # (R)-1-phenylethan-1-ol mol_true = MolFromSmiles("C[C@H](O)c1ccccc1") # (S)-1-phenylethan-1-ol (wrong stereoisomer) AllChem.EmbedMolecule(mol_pred, AllChem.ETKDGv3()) AllChem.EmbedMolecule(mol_true, AllChem.ETKDGv3()) result = check_identity(mol_pred=mol_pred, mol_true=mol_true) print(result["results"]) # { # 'inchi_crystal_valid': True, # 'inchi_docked_valid': True, # 'formula': True, # 'connections': True, # 'stereo_dbond': True, # 'stereo_tetrahedral': False, # <-- chirality mismatch detected # 'stereo': False, # 'inchi_overall': False, # } ``` -------------------------------- ### PoseBusters mol mode Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb The 'mol' mode is intended for *de-novo* generated molecules or for analyzing generated molecular conformations. It does not require a 'ground truth' or conditioning file. ```APIDOC ## PoseBusters.bust (mol mode) ### Description Analyzes *de-novo* generated molecules or generated molecular conformations. ### Method PoseBusters(config="mol") ### Parameters - **config** (string): Set to "mol" for this mode. - **pred_files** (list of Path objects): Paths to predicted or generated molecule files (e.g., SDF format). - **true_file** (Path object or None): Not required for this mode. - **cond_file** (Path object or None): Not required for this mode. ### Request Example ```python from posebusters import PoseBusters from pathlib import Path pred_file = Path("inputs/generated_molecules.sdf") buster = PoseBusters(config="mol") df = buster.bust([pred_file], None, None) print(df.shape) df ``` ### Response Returns a DataFrame containing analysis results. By default, only binary test report columns are returned. ``` -------------------------------- ### Load Molecule-Only Dataset with PoseBusters Source: https://context7.com/maabuu/posebusters/llms.txt Initializes PoseBusters for molecule-only analysis and processes a DataFrame containing molecular data. Use this for datasets without protein or reference structures. ```python from posebusters import PoseBusters df_mol = four_mols() pb_mol = PoseBusters(config="mol") results_mol = pb_mol.bust_table(df_mol) print(results_mol.all(axis=1)) # True/False per pose ``` -------------------------------- ### PoseBusters dock mode Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb The 'dock' mode is suitable for *de-novo* generated molecules or for ligands docked into a non-cognate receptor. It facilitates the analysis of these docking scenarios. ```APIDOC ## PoseBusters.bust (dock mode) ### Description Analyzes *de-novo* generated molecules or ligands docked into non-cognate receptors. ### Method PoseBusters(config="dock") ### Parameters - **config** (string): Set to "dock" for this mode. - **pred_files** (list of Path objects): Paths to predicted or generated molecule files (e.g., SDF format). - **true_file** (Path object): Path to the 'ground truth' molecule file. - **cond_file** (Path object): Path to the conditioning molecule file (e.g., protein PDB format). ### Request Example ```python from posebusters import PoseBusters from pathlib import Path pred_file = Path("inputs/generated_molecules.sdf") true_file = Path("inputs/crystal_ligand.sdf") cond_file = Path("inputs/protein.pdb") buster = PoseBusters(config="dock") df = buster.bust([pred_file], true_file, cond_file) print(df.shape) df ``` ### Response Returns a DataFrame containing analysis results. By default, only binary test report columns are returned. ``` -------------------------------- ### Check ligand conditioned on a protein Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Check a docked ligand or generated molecule that is conditioned on a protein. Specify the protein PDB file using the -p option. ```bash bust generated_ligands.sdf -p protein.pdb --outfmt long ``` -------------------------------- ### Batch checking poses using a DataFrame with PoseBusters.bust_table() Source: https://context7.com/maabuu/posebusters/llms.txt Use the bust_table method to perform batch checks on poses provided in a pandas DataFrame. The DataFrame should contain columns like mol_pred, mol_true, and mol_cond. ```python import pandas as pd from posebusters import PoseBusters # Build an input table (paths or Mol objects) table = pd.DataFrame({ "mol_pred": ["pose1.sdf", "pose2.sdf", "pose3.sdf"], "mol_true": ["crystal.sdf", "crystal.sdf", "crystal.sdf"], "mol_cond": ["protein.pdb", "protein.pdb", "protein.pdb"], }) pb = PoseBusters(config="redock", top_n=1) # top_n: only check first pose per file results = pb.bust_table(table, full_report=False) # Filter passing poses passing = results[results.all(axis=1)] print(f"{len(passing)} / {len(results)} poses pass all checks") # Export results to CSV results.to_csv("results.csv") ``` -------------------------------- ### PoseBusters.bust with full_report Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb Enables the 'full_report' option within the `bust` method to retrieve all columns from the test reports, which is beneficial for detailed debugging and analysis. ```APIDOC ## PoseBusters.bust (full_report option) ### Description Retrieves all columns from the test reports for comprehensive analysis and debugging. ### Method buster.bust(pred_files, true_file, cond_file, full_report=True) ### Parameters - **pred_files** (list of Path objects): Paths to predicted or generated molecule files. - **true_file** (Path object or None): Path to the 'ground truth' molecule file (can be None). - **cond_file** (Path object or None): Path to the conditioning molecule file (can be None). - **full_report** (boolean): If True, returns all columns of the test reports. Defaults to False. ### Request Example ```python from posebusters import PoseBusters from pathlib import Path pred_file = Path("inputs/generated_molecules.sdf") buster = PoseBusters(config="mol") # Example config, can be 'redock' or 'dock' as well df = buster.bust([pred_file], None, None, full_report=True) print(df.shape) df ``` ### Response Returns a DataFrame containing all columns of the test reports. ``` -------------------------------- ### Energy Ratio Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Calculates the ratio of energies between predicted and true states. ```APIDOC def check_energy_ratio(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Calculates the energy ratio.""" pass ``` -------------------------------- ### check_flatness Source: https://context7.com/maabuu/posebusters/llms.txt Assesses the planarity of aromatic rings (5- and 6-membered) and trigonal-planar double bonds using SVD. It can also verify that non-aromatic rings are puckered. Custom substructures can be checked using SMARTS. ```APIDOC ## `check_flatness` — Aromatic ring and double bond planarity Verifies that aromatic 5- and 6-membered rings and trigonal-planar double bonds are sufficiently flat, using SVD to find the best-fit plane and measuring atom deviations from it. Can also check that non-aromatic rings are *not* flat (puckered). ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_flatness mol = MolFromSmiles("c1ccccc1") # benzene — should be flat AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_flatness(mol_pred=mol, threshold_flatness=0.1) print(result["results"]) # {'num_systems_checked': 1, 'num_systems_passed': 1, 'max_distance': 0.001, 'flatness_passes': True} # Custom SMARTS to check planarity of a specific substructure custom_systems = {"my_group": "[c]1[c][c][c][c][c]1"} result_custom = check_flatness(mol, flat_systems=custom_systems, threshold_flatness=0.05) ``` ``` -------------------------------- ### Check Energy Ratio of Conformer Source: https://context7.com/maabuu/posebusters/llms.txt Computes the UFF energy of a predicted conformer and compares it to the average UFF energy of an ensemble of conformers. A high ratio indicates a strained pose. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_energy_ratio mol = MolFromSmiles("CC(C)Cc1ccc(cc1)[C@@H](C)C(=O)O") # ibuprofen AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_energy_ratio( mol_pred=mol, threshold_energy_ratio=7.0, # default: 7× the ensemble average ensemble_number_conformations=100, # number of reference conformers to generate ) print(result["results"]) # { # 'num_h_added': 0, # 'mol_pred_energy': 34.2, # 'ensemble_avg_energy': 28.1, # 'energy_ratio': 1.22, # 'energy_ratio_passes': True # } ``` -------------------------------- ### Flatness Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Assesses the flatness of the molecule. ```APIDOC def check_flatness(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol = None, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Assesses the flatness of the molecule.""" pass ``` -------------------------------- ### Check Ligand-Protein Distance and Clash Detection Source: https://context7.com/maabuu/posebusters/llms.txt Verifies that the predicted ligand is within a specified distance from the protein binding site and does not clash sterically with protein atoms or other molecules. Uses configurable van der Waals or covalent radii. ```python from rdkit.Chem import MolFromMolFile, MolFromPDBFile from posebusters import check_intermolecular_distance mol_pred = MolFromMolFile("ligand.sdf") mol_cond = MolFromPDBFile("protein.pdb", removeHs=False, sanitize=False) result = check_intermolecular_distance( mol_pred=mol_pred, mol_cond=mol_cond, radius_type="vdw", clash_cutoff=0.75, ignore_types={"hydrogens", "organic_cofactors", "inorganic_cofactors", "waters"}, max_distance=5.0, ) print(result["results"]) # { # 'smallest_distance': 2.87, # 'not_too_far_away': True, # 'num_pairwise_clashes': 0, # 'no_clashes': True, # } ``` -------------------------------- ### Full report with CSV/long format Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst For 'csv' and 'long' output formats, the '--full-report' option can be used to include extra information beyond the pass/fail status. ```bash bust generated_molecules.sdf --outfmt csv --full-report ``` -------------------------------- ### Verify Geometry with check_geometry Source: https://context7.com/maabuu/posebusters/llms.txt Uses RDKit's distance geometry to check bond lengths, angles, and steric clashes in a predicted conformer. Adjust thresholds for tolerance. `ignore_hydrogens` can be set to `False` if needed. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_geometry mol = MolFromSmiles("C1CCCCC1") AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_geometry( mol_pred=mol, threshold_bad_bond_length=0.2, # 20% tolerance beyond DG bounds threshold_bad_angle=0.2, threshold_clash=0.2, ignore_hydrogens=True, ) print(result["results"]) # { # 'number_bonds': 6, # 'bond_lengths_within_bounds': True, # 'bond_angles_within_bounds': True, # 'no_internal_clash': True, # 'shortest_bond_relative_length': 0.97, # 'longest_bond_relative_length': 1.02, # ... # } # Access per-bond detail DataFrame print(result["details"]["bonds"].head()) ``` -------------------------------- ### Check files listed in a CSV table Source: https://github.com/maabuu/posebusters/blob/main/README.md Use the '-t' option with a CSV file to specify multiple checks. The CSV should contain paths to files to be checked. ```bash bust -t file_table.csv ``` -------------------------------- ### check_energy_ratio Source: https://context7.com/maabuu/posebusters/llms.txt Computes the UFF energy of a predicted conformer and compares it to the average UFF energy of an ensemble of ETKDGv3-generated conformers. A high ratio indicates a strained or physically implausible pose. ```APIDOC ## `check_energy_ratio` — Internal conformation energy vs. ensemble average Computes the UFF energy of the predicted conformer and compares it to the average UFF energy of an ensemble of ETKDGv3-generated conformers for the same molecule (identified by InChI). A high ratio signals a strained, physically implausible pose. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_energy_ratio mol = MolFromSmiles("CC(C)Cc1ccc(cc1)[C@@H](C)C(=O)O") # ibuprofen AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_energy_ratio( mol_pred=mol, threshold_energy_ratio=7.0, # default: 7× the ensemble average ensemble_number_conformations=100, # number of reference conformers to generate ) print(result["results"]) # { # 'num_h_added': 0, # 'mol_pred_energy': 34.2, # 'ensemble_avg_energy': 28.1, # 'energy_ratio': 1.22, # 'energy_ratio_passes': True # } ``` ``` -------------------------------- ### Batch checking multiple predicted files with PoseBusters Source: https://context7.com/maabuu/posebusters/llms.txt Use PoseBusters to check multiple predicted molecule files in a batch. This is useful for processing large sets of generated poses. ```python # --- Batch: multiple predicted files --- import pandas as pd pb = PoseBusters(config="mol") results = pb.bust(["mol_a.sdf", "mol_b.sdf", "mol_c.sdf"]) ``` -------------------------------- ### Parallelize PoseBusters checks Source: https://context7.com/maabuu/posebusters/llms.txt Configure PoseBusters for parallelization using ProcessPoolExecutor by specifying max_workers and chunk_size. This is beneficial for large datasets. ```python # --- Parallelization --- pb = PoseBusters(config="redock", max_workers=4, chunk_size=50) results = pb.bust("large_ensemble.sdf", mol_true="crystal.sdf", mol_cond="protein.pdb") ``` -------------------------------- ### PoseBusters Class Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst The main PoseBusters class for managing molecular tests. ```APIDOC class PoseBusters: """The PoseBusters class collects the molecules to test, runs the *modules*, and reports the test results.""" pass ``` -------------------------------- ### Distance Geometry Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Checks the geometry of the molecule using distance-based constraints. ```APIDOC def check_geometry(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol = None, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Checks the geometry of the molecule.""" pass ``` -------------------------------- ### PoseBusters redock mode Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api_notebook.ipynb The 'redock' mode is designed for ligands that have been docked into their cognate receptor crystal structures. It allows for analysis and comparison of these poses. ```APIDOC ## PoseBusters.bust (redock mode) ### Description Analyzes docked ligand poses against cognate receptor crystal structures. ### Method PoseBusters(config="redock") ### Parameters - **config** (string): Set to "redock" for this mode. - **pred_files** (list of Path objects): Paths to predicted or generated molecule files (e.g., SDF format). - **true_file** (Path object): Path to the 'ground truth' molecule file. - **cond_file** (Path object): Path to the conditioning molecule file (e.g., protein PDB format). ### Request Example ```python from posebusters import PoseBusters from pathlib import Path pred_file = Path("inputs/generated_molecules.sdf") true_file = Path("inputs/crystal_ligand.sdf") cond_file = Path("inputs/protein.pdb") buster = PoseBusters(config="redock") df = buster.bust([pred_file], true_file, cond_file) print(df.shape) df ``` ### Response Returns a DataFrame containing analysis results. By default, only binary test report columns are returned. ``` -------------------------------- ### Identity Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Checks if the predicted molecule is identical to the true molecule. ```APIDOC def check_identity(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Checks if the predicted molecule is identical to the true molecule.""" pass ``` -------------------------------- ### Calculate RMSD Between Predicted and Crystal Ligand Source: https://context7.com/maabuu/posebusters/llms.txt Calculates the symmetric RMSD (and optionally Kabsch-aligned RMSD) between predicted and crystal ligands. Handles tautomers and charge variants robustly, with a configurable Å threshold for pass/fail. ```python from rdkit.Chem import MolFromMolFile from posebusters import check_rmsd mol_pred = MolFromMolFile("docked_pose.sdf") mol_true = MolFromMolFile("crystal_ligand.sdf") result = check_rmsd( mol_pred=mol_pred, mol_true=mol_true, rmsd_threshold=2.0, heavy_only=True, ) print(result["results"]) # { # 'rmsd': 1.43, # 'kabsch_rmsd': 1.41, # 'centroid_distance': 0.92, # 'rmsd_within_threshold': True # } ``` -------------------------------- ### Volume Overlap Module Source: https://github.com/maabuu/posebusters/blob/main/docs/source/api.rst Quantifies the overlap in volume between molecules. ```APIDOC def check_volume_overlap(mol_pred: RDKit.Chem.rdchem.Mol, mol_true: RDKit.Chem.rdchem.Mol, mol_cond: RDKit.Chem.rdchem.Mol = None) -> dict: """Quantifies the overlap in volume between molecules.""" pass ``` -------------------------------- ### Bulk check multiple sets of files Source: https://github.com/maabuu/posebusters/blob/main/docs/source/cli.rst Use the -t option to perform bulk checks on multiple sets of files, specified in a CSV table. ```bash bust -t molecule_table.csv --outfmt long ``` -------------------------------- ### RDKit Chemical Sanitization with check_chemistry Source: https://context7.com/maabuu/posebusters/llms.txt Validates a molecule against RDKit's sanitization rules, checking for valence, kekulization, and overall chemical validity. Requires RDKit and PoseBusters. EmbedMolecule is used to generate a 3D conformer. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_chemistry_using_rdkit, check_chemistry_using_inchi, check_all_atoms_connected # Build a molecule with a 3D conformer mol = MolFromSmiles("c1ccccc1CC(=O)O") AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) # RDKit-based chemistry check result = check_chemistry_using_rdkit(mol) print(result["results"]) # {'passes_valence_checks': True, 'passes_kekulization': True, 'passes_rdkit_sanity_checks': True} # InChI-based check (round-trip convertibility) result_inchi = check_chemistry_using_inchi(mol) print(result_inchi) # {'results': {'inchi_convertible': True}, 'details': {'errors': '', 'inchi': 'InChI=1S/...'}} # Connectivity check (no disconnected fragments) result_conn = check_all_atoms_connected(mol) print(result_conn) # {'results': {'all_atoms_connected': True}, 'details': {'number_fragments': 1}} ``` -------------------------------- ### check_geometry Source: https://context7.com/maabuu/posebusters/llms.txt Verifies bond lengths, bond angles, and checks for internal steric clashes within a molecule's conformer using RDKit's distance geometry bounds matrix. Customizable thresholds are available for deviations. ```APIDOC ## `check_geometry` — Bond lengths, bond angles, and internal steric clash Uses RDKit's distance geometry bounds matrix to verify that all bond lengths and angles in the predicted conformer fall within physically reasonable bounds, and that no pairs of non-bonded atoms clash internally. ```python from rdkit.Chem import MolFromSmiles, AllChem from posebusters import check_geometry mol = MolFromSmiles("C1CCCCC1") AllChem.EmbedMolecule(mol, AllChem.ETKDGv3()) result = check_geometry( mol_pred=mol, threshold_bad_bond_length=0.2, # 20% tolerance beyond DG bounds threshold_bad_angle=0.2, threshold_clash=0.2, ignore_hydrogens=True, ) print(result["results"]) # { # 'number_bonds': 6, # 'bond_lengths_within_bounds': True, # 'bond_angles_within_bounds': True, # 'no_internal_clash': True, # 'shortest_bond_relative_length': 0.97, # 'longest_bond_relative_length': 1.02, # ... # } # Access per-bond detail DataFrame print(result["details"]["bonds"].head()) ``` ``` -------------------------------- ### PoseBusters BibTeX Entry Source: https://github.com/maabuu/posebusters/blob/main/docs/source/index.rst BibTeX entry for citing the PoseBusters paper. This includes author, title, journal, and DOI information. ```bibtex @article{buttenschoen2024posebusters, title = {{{PoseBusters}}: {{AI-based}} Docking Methods Fail to Generate Physically Valid Poses or Generalise to Novel Sequences}, shorttitle = {{{PoseBusters}}}, author = {Buttenschoen, Martin and Morris, Garrett M. and Deane, Charlotte M.}, year = "2024", journal = "Chemical Science", volume = "15", issue = "9", pages = "3130-3139", publisher = "The Royal Society of Chemistry", doi = "10.1039/D3SC04185A", url = "http://dx.doi.org/10.1039/D3SC04185A", } ```