Python API¶
You can import the configuration classes, PocketVinaGPU, P2RankProcessor and Results directly from
pocketvina.
Configuration and runs¶
- class pocketvina.main.PocketVinaConfig(database_path: str | None = None, protein_paths: str | None = None, protein_list: str | None = None, smiles_file: str | None = None, output_dir: str | None = None, batch_size: int | None = None, p2rank_config: P2RankConfig | None = None, pocket_config: PocketConfig = <factory>, output_format: str = 'files', tmp_dir: str | None = None, top_pockets: int | None = None, pockets: int | Sequence[int] | str | None = None, pockets_dir: str | None = None, seed: int | None = 42, num_modes: int | None = None, energy_range: float | None = None, ligand_prep: str = 'standard', gzip_level: int = 6, posebusters: bool = False, posebusters_workers: int | None = None, ligands_per_call: int | None = None, engine_timeout: float | None = None, gpus: str | None = None, procs_per_gpu: int | str = 'auto', vram_per_proc_mib: int = 6600)[source]¶
Settings of a docking run. Only
smiles_fileandprotein_paths(ordatabase_pathwithprotein_list) are required.protein_paths: text file with one protein structure per line (.pdb, .cif or .pdbqt, may be gzipped).
smiles_file: CSV file with the header
molecule_name,smilesand one ligand per line (.csv or .txt).output_dir: folder the results are written to (default "output").
output_format: "files" (PDBQT files and combined_results.csv, as in v0.1) or "atlas" (tables, resumable).
batch_size: molecules per docking batch (default 10; "atlas": 1000 per engine call, see ligands_per_call).
p2rank_config: how P2Rank finds the pockets, a
P2RankConfig(defaultP2RankConfig()).pocket_config: docking box size and GPU threads, a
PocketConfig(defaultPocketConfig()).top_pockets: dock only the N best-ranked pockets of each protein (default all;
htvs_mode=True: 5).pockets: dock only these P2Rank ranks: 10, [10, 11, 12], range(10, 13) or "10-12" (not with top_pockets or htvs_mode).
pockets_dir: "atlas" only: a folder of P2Rank predictions, <protein file name>.csv, e.g. from P2RankProcessor (its <output_dir>/proteins/pockets): proteins with one there are docked into those pockets, P2Rank is not run.
seed: random seed; the same seed gives the same results (default 42; None: random).
Advanced:
database_path, protein_list: dock the proteins of a prepared database folder instead of protein_paths.
tmp_dir: folder for temp files (default $POCKETVINA_TMPDIR, $SLURM_TMPDIR, $TMPDIR, the system temp folder).
num_modes, energy_range: poses kept per ligand and pocket, and their score range (default 20 within 20 kcal/mol).
ligand_prep: "standard" (largest fragment, seeded 3D) or "legacy" (as before v0.2, to regenerate old results).
gzip_level: compression level of the "atlas" pose files (-1 to 9, default 6).
posebusters: "atlas" only: check the best pose of each ligand with PoseBusters while docking (default False).
posebusters_workers: processes for the PoseBusters checks (default the CPUs available, at most 16).
ligands_per_call: "atlas" only: ligands per engine call (default batch_size if set, else 1000; 0: all at once).
engine_timeout: seconds one engine call may take; a slower call is stopped (default no limit).
gpus: "atlas" only: the GPU to dock on, an nvidia-smi index or UUID (default the first visible one, e.g. the one SLURM gives the job); "all" or "0,2" for several (usually one job per GPU is simpler).
procs_per_gpu: "atlas" only: pockets docked at the same time on the GPU, a number or "auto" (default: as many as its free memory holds at vram_per_proc_mib each, e.g. 3 on a 24 GB P40, 5 on a 40 GB A100).
vram_per_proc_mib: GPU memory one engine needs, in MiB, for procs_per_gpu (default 6600).
- class pocketvina.main.P2RankConfig(threads: int = 4, visualizations: bool = False, vis_copy_proteins: bool = False, output_dir: str = 'output', model: str = 'alphafold_conservation_hmm')[source]¶
How P2Rank finds the pockets of each protein.
P2Rank is described in the "P2Rank: machine learning based tool for rapid and accurate prediction of ligand binding sites from protein structure" paper.
- class pocketvina.main.PocketConfig(size_x: int = 20, size_y: int = 20, size_z: int = 20, thread: int = 8000)[source]¶
The docking box around each pocket centre, and the GPU threads per docking.
- class pocketvina.main.PocketVinaGPU(config: PocketVinaConfig, htvs_mode=False)[source]¶
Docking with PocketVina, from the "PocketVina Enables Scalable and Highly Accurate Physically Valid Docking through Multi-Pocket Conditioning" paper.
P2Rank finds the pockets of each protein ("P2Rank: machine learning based tool for rapid and accurate prediction of ligand binding sites from protein structure") and every ligand is docked into the best pockets on the GPU, with an engine based on QuickVina2-GPU 2.1 ("Vina-GPU 2.1: towards further optimizing docking speed and precision of AutoDock Vina and its derivatives") and AutoDock Vina ("AutoDock Vina: improving the speed and accuracy of docking with a new scoring function, efficient optimization, and multithreading").
- execute_docking() str | None[source]¶
Main docking execution with better error handling
With
output_format="atlas"this ispipeline.run_atlasand returns the results directory; at the end it shows the best scores of the run's proteins (best_scores(), at mostBEST_SCORES_SHOWNrows): a table in a notebook, else printed.
- results()[source]¶
The results in
output_dir(apocketvina.io.results.Results), also of an earlier session:PocketVinaGPU(config).results(). Needsoutput_format="atlas".
- best_scores(protein=None, top: int | None = None) pandas.DataFrame[source]¶
Best (lowest) Vina score of each protein x ligand, best first; see
Results.best_scores.proteina protein id (the file name without extension), e.g. "1fbl", or a list, e.g. ["1fbl", "2W83"];
None (default): all proteins.
toponly the first N rows, e.g. 10; None (default): all rows.
- select(protein: str, ligand, pocket=None, mode=1)[source]¶
One protein x ligand pair, to show, check or save; see
Results.select:pair = pocketvina.select(protein="1fbl", ligand="molecule1"), thenpair.show(),pair.bust(),pair.export("1fbl_molecule1.sdf").proteina protein id as in best_scores(), e.g. "1fbl".
liganda ligand id (its name in the SMILES file) as in best_scores(), e.g. "molecule1".
pocketa pocket number, e.g. 2; None (default): the pocket of the pair's best pose; "all": every pocket the ligand was docked into.
mode1 (default): the best mode of the pocket; 2, 3, ...: that mode; "all": every mode of the pocket(s).
- show(protein=None, *, path=None, molstar: str = 'inline', theme: str = 'auto', height: int = 760, max_ligands: int | None = 100)[source]¶
The results as on the PocketVina Atlas website's protein page (3D view, Top hits, Selected pair, Pockets); in a notebook below the cell, elsewhere an HTML file whose path is returned. See
Results.show.proteina protein id, e.g. "1fbl", or a list of them; None (default): all proteins.
pathwrite the page to this HTML file instead, e.g. "results.html".
molstar"inline" (default, works offline) or "url" (the 3D viewer's code from the PocketVina Atlas website).
theme"auto" (default), "light" or "dark".
heightheight of the view in a notebook, in pixels, e.g. 900.
max_ligandsligands per protein in the page (best first), e.g. 50; None: all.
- class pocketvina.main.P2RankProcessor(config: P2RankConfig = None)[source]¶
Runs P2Rank on a list of proteins and saves their pockets, for docking later.
P2Rank is described in the "P2Rank: machine learning based tool for rapid and accurate prediction of ligand binding sites from protein structure" paper.
PocketVinaGPU(config, htvs_mode=True) docks the 5 best-ranked pockets of each protein if top_pockets is not
set. After execute_docking(), failed_proteins maps each protein that could not be docked to the reason.
- pocketvina.pipeline.run_atlas(pv, force: bool = False) str[source]¶
Dock every protein of
pv(aPocketVinaGPUor aPocketVinaConfig) into the atlas results directoryconfig.output_dirand return its path.Proteins already committed there are skipped. A protein that fails (missing file, P2Rank error, every engine run failed or timed out) is logged, left out and retried by the next run; the ids are in
pv.failed_proteins. An engine call that fails or takes longer thanconfig.engine_timeoutwhile other calls of the protein work leaves its ligands asengine_errorruns of the committed protein. A results directory that holds a run with other settings or ligands raisesValueErrorunlessforce=True(proteins done stay done, unless the ligand list changed: seeResultsDir.init_run). The engine calls run on the slots ofplan_engine_slots(configgpus,procs_per_gpu,vram_per_proc_mib), several at a time when there are several slots; they are not run parameters, so a run may be resumed with others. All temp files live in one folder fromconfig.tmp_dir(seeio.writer.resolve_tmp_dir), removed at the end, also when the run is stopped with Ctrl-C or SIGTERM (engine.exit_on_sigterm; the running engines are killed). Withconfig.posebusters, every protein committed (or found done) is handed to a background process that runsbust.bust_resultson it while docking goes on; the run waits for it at the end. A protein whose checks did not finish (the run was stopped) is checked when the run is resumed.
- pocketvina.pipeline.plan_engine_slots(config: PocketVinaConfig) List[str | None][source]¶
CUDA_VISIBLE_DEVICESof each engine slot of an atlas run:gpu.plan_slotsover the GPUs thatconfig.gpusnames (None: the first visible GPU; "all": every one) withconfig.procs_per_gpu(default "auto": as many as the GPU's free memory holds) andconfig.vram_per_proc_mib.Without a GPU list (no
nvidia-smi, e.g. in a container with the driver's OpenCL library only, or aCUDA_VISIBLE_DEVICESwhose GPUsgpu.visible_gpuscannot match) the engines use the environment's default GPU (the first of NVIDIA's OpenCL platform):procs_per_gpuslots (1 for "auto") of value None.ValueErrorifconfig.gpusnames a GPU that is not visible, or is set whilenvidia-smilists none.
Results¶
Results reads a results folder (Results format). It sees only the proteins
that are done.
- class pocketvina.io.results.Results(path)[source]¶
A results directory written by
pipeline.run_atlasorio.importer.import_legacy.proteinarguments are protein ids;ligandarguments a ligand_id (str) or a ligand_idx (int);pocketa P2Rank rank (1-based);mode1-based. Unknown proteins, ligands and missing poses raiseKeyError. Pose files are kept open (at mostMAX_OPEN_POSE_FILES); use as a context manager or callclose().- manifest(protein: str | None = None) dict[source]¶
MANIFEST.jsonof the run, ormanifest/<protein>.jsonof one protein.
- table(name: str, protein: str | Iterable[str] | None = None, columns: List[str] | None = None) pandas.DataFrame[source]¶
Table
name(one ofTABLES, or another folder undertables/) as one DataFrame, for one protein id, a list of them or (None) all committed proteins, in protein order.
- pairs(protein: str | Iterable[str] | None = None, columns: List[str] | None = None) pandas.DataFrame[source]¶
Best pose per protein x ligand: the
pairstable, thenpb_valid(only when there are PoseBusters results, seeposebusters) andligand_efficiency(-vina / n_heavy, heavy atoms of the docked fragment; NaN without a pose).pb_status/pb_validare those of the PoseBusters row of the best pose (same pocket and mode), if any.columnsmay name these derived columns too.
- best_scores(protein: str | Iterable[str] | None = None, top: int | None = None) pandas.DataFrame[source]¶
Best (lowest) Vina score of each protein x ligand, best first: one row per docked pair with protein_id, ligand_id, vina (kcal/mol), best_pocket, best_mode, ligand_efficiency (-vina / heavy atoms); no PoseBusters columns, also when PoseBusters ran (see
posebusters()). Ligands without a pose are left out.proteina protein id (the file name without extension), e.g. "1fbl", or a list, e.g. ["1fbl", "2W83"];
None (default): all proteins.
toponly the first N rows, e.g. 10; None (default): all rows.
- select(protein: str, ligand, pocket=None, mode=1)[source]¶
One protein x ligand pair, to show, check or save (a
pocketvina.selection.Selection):pair = results.select("1fbl", "molecule1"), thenpair.show(),pair.bust(),pair.export().proteina protein id as in best_scores(), e.g. "1fbl".
liganda ligand id (its name in the SMILES file) as in best_scores(), e.g. "molecule1".
pocketa pocket number, e.g. 2; None (default): the pocket of the pair's best pose; "all": every pocket the ligand was docked into.
mode1 (default): the best mode of the pocket; 2, 3, ...: that mode; "all": every mode of the pocket(s).
- show(protein=None, *, path=None, molstar: str = 'inline', theme: str = 'auto', height: int = 760, max_ligands: int | None = 100)[source]¶
The results as on the PocketVina Atlas website's protein page: the 3D view (pocket chips, modes, legend, contacts, Save image) beside the tabs Top hits (pick a ligand there), Selected pair and Pockets, with a protein menu when there are several proteins. In Jupyter, Colab or VSCode it is shown below the cell; elsewhere an HTML file is written (open it in a browser) and its path returned.
proteina protein id, e.g. "1fbl", or a list of them; None (default): all proteins.
pathwrite the page to this HTML file instead, e.g. "results.html"; returns the path.
molstar"inline" (default): the 3D viewer's code is in the page (works offline); "url": loaded from the PocketVina Atlas website when the page opens (a much smaller page; needs internet).
theme"auto" (default: as the browser), "light" or "dark".
heightheight of the view in a notebook, in pixels, e.g. 900.
max_ligandsligands per protein in the page (best first), e.g. 50; None: all (a large page for a large run).
- posebusters(protein: str | Iterable[str] | None = None, columns: List[str] | None = None) pandas.DataFrame[source]¶
PoseBusters results (
tables.POSEBUSTERS, written bypocketvina.bust.bust_results) of one protein, a list or all committed proteins; empty if there are none. Results of a protein docked again since it was checked are left out. Bitbofpb_mask/pb_na_maskis checkposebusters_checks(protein)[b].
- posebusters_checks(protein: str) List[str][source]¶
Names of the PoseBusters checks in the mask bits of a protein's results (
bust.check_names).
- duckdb()[source]¶
In-memory DuckDB connection with the views
ligands, proteins, pockets, pocket_runs, modes, pairsover the Parquet files of the committed proteins (as they are now: reconnect to see proteins committed later), andposebusterswhen there are PoseBusters results (seeposebusters).The
pairsview has the columns ofpairs(): thepairstable withpb_status/pb_validof the PoseBusters row of the best pose (same pocket and mode;pb_validis NULL without one, also when there are no PoseBusters results) andligand_efficiency(-vina / n_heavy, NULL ifn_heavyis unknown).
- pose_block(protein: str, ligand, pocket: int) str[source]¶
The engine output (all MODELs) of a ligand in a pocket, byte for byte as the engine wrote it.
- pose_model(protein: str, ligand, pocket: int, mode: int) str[source]¶
One MODEL (
MODEL ... ENDMDL) of the engine output;IndexErrorif there is no such mode.
- top_sdf(protein: str, ligand) str | None[source]¶
SDF of the ligand's best pose in the protein (section A), or None if there is none.
- structure_path(protein: str) str[source]¶
Path of the stored input structure (
structures/<protein_id>.pdb.gz,.pdbqt.gz, ...).
- structure(protein: str) bytes[source]¶
The input structure (PDB, mmCIF or PDBQT text), decompressed.
- to_combined_csv(path, protein: str | Iterable[str] | None = None) str[source]¶
Write every mode as a row of the legacy
combined_results.csv(COMBINED_COLUMNS;proteinis<protein_id>-pocket<k>,molecule_namethe ligand_id); returns the path. Rows are in protein, pocket, ligand_idx, mode order; scores are written as the engine printed them.
- export(out_dir, what: str = 'best', fmt: str = 'sdf', protein: str | Iterable[str] | None = None) List[str][source]¶
Write poses or tables as plain files under
out_dir; returns the paths written.fmt="sdf":what="best"the stored best pose per protein x ligand (<protein_id>/<protein_id>-pocket<k>-<ligand>_best.sdf);what="all"every mode of every engine output converted withpocketvina.convert(needs the docked SMILES;<protein_id>/<protein_id>-pocket<k>-<ligand>_out.sdf, modes that do not convert are left out).fmt="pdbqt": the best MODEL (..._best.pdbqt), or every engine output as written (..._out.pdbqt).fmt="csv":best_poses.csv(the pairs table), orcombined_results.csv(to_combined_csv).
- pocketvina.io.importer.import_legacy(output_dir: str, results_dir: str, smiles_file: str | None = None, *, tmp_dir: str | None = None, gzip_level: int = 6, force: bool = False) str[source]¶
Convert a legacy PocketVina
output_dirinto the atlas layout inresults_dir; returns its path.One protein per
proteins/structures/<receptor>.pdbqt; engine outputs of other receptors are skipped with a warning. Ligands are numbered in the order ofsmiles_file(molecule_name,smiles; ligands of the run that it lacks follow), else by name. The docked pockets are those with an engine output or config; a ligand without output in one of them gets a "no_output" run, a ligand ofsmiles_filethat the legacy run never prepared a "skipped" one. Section A holds the best pose of each ligand as SDF (pocketvina.convert) when its SMILES is known; without SMILES it stays empty andsdf_statusis "convert_failed". Box sizes come fromconfigs/when kept, else they are NaN. Docked pockets ranked above 127 do not fit the int8 pocket columns: they are left out with a warning and noted in the proteins table.Importing into a results directory that holds this import already resumes it (proteins done are skipped).
force=Truereplaces another run definition there and imports every protein again.
Selections¶
- class pocketvina.selection.Selection(*, results_dir: str, protein: str, ligand: str, ligand_idx: int, smiles: str, smiles_docked: str, pocket: None | int | str, mode: int | str, best_pocket: int, best_mode: int, vina: float, docked_pockets: List[int], poses: List[Pose], top_sdf: str | None)[source]¶
Poses of one protein x ligand pair, picked with
select(Results.select,PocketVinaGPU.select).Attributes:
protein,ligand(ids),smiles,pocketandmode(as selected),vina(the pair's best Vina score, kcal/mol),best_pocket/best_mode(where that pose is),poses(a table: pocket, mode, vina, rmsd_lb, rmsd_ub),name(the file name stem, e.g.PV_1fbl_molecule1_top).- property poses: pandas.DataFrame¶
The selected poses: pocket, mode, vina (kcal/mol), rmsd_lb, rmsd_ub (A, to mode 1 of the pocket).
- property name: str¶
File name stem of the selection (Atlas IDs with "PV_"):
PV_<protein>_<ligand>_top(the best pose),..._pk2_m03(one pose),..._pk2_modes(all modes of a pocket),..._pocketall_top(the best pose of each pocket),..._pocketall_modes,..._pocketall_m03.
- show(path=None, *, molstar: str = 'inline', theme: str = 'auto', height: int = 760, max_ligands: int = 100)[source]¶
The PocketVina Atlas website's protein page for this pair's protein, with this pair selected: the 3D view (pocket chips, modes, legend, contacts, Save image) beside the tabs Top hits, Selected pair and Pockets.
In Jupyter, Colab or VSCode it is shown below the cell; elsewhere an HTML file is written (open it in a browser) and its path returned. Everything is in the page: it works offline and in a saved notebook.
pathwrite the page to this HTML file instead, e.g. "pair.html"; returns the path.
molstar"inline" (default): the 3D viewer's code is in the page (about 1 MB); "url": loaded from the PocketVina Atlas website when the page opens (needs internet, a much smaller page).
theme"auto" (default: as the browser), "light" or "dark".
heightheight of the view in a notebook, in pixels, e.g. 900.
max_ligandsligands listed in Top hits, best first, e.g. 50 (default 100).
The 3D view is drawn with Mol*, described in the "Mol* Viewer: modern web app for 3D visualization and analysis of large biomolecular structures" paper.
- bust(workers: int | None = None) pandas.DataFrame[source]¶
PoseBusters (config "dock") on the selected poses against the protein; nothing is written to disk and the stored results do not change. Returns one row per pose: pocket, mode, vina, pb_valid (True: every check passed), pb_status ("valid", "invalid", or why it was not checked: "convert_failed", "timeout", "error"), failed_checks, then one column per PoseBusters check (True: passed, False: failed, empty: not applicable).
workersprocesses that run the checks at the same time, e.g. 4; None (default): one per pose, at most the CPUs this process may use.
PoseBusters is described in the "PoseBusters: AI-based docking methods fail to generate physically valid poses or generalise to novel sequences" paper.
- export(path=None, fmt: str = 'sdf') str[source]¶
Write the selected poses into one file; returns its path.
paththe file, e.g. "1fbl_molecule1.sdf", or a folder; None (default):
<name>.<fmt>in the working folder, e.g. PV_1fbl_molecule1_top.sdf.fmt"sdf" (default): one record per pose (converted from the docked model with the ligand's SMILES), with the protein, ligand, pocket, mode and Vina score (affinity, kcal/mol) as properties; "pdbqt": the docked models as the engine wrote them, one MODEL per pose.
PoseBusters¶
PoseBusters checks of the docked poses in a results directory: bust_results, check_names.
Per protein, the poses to check are picked from the results (select): the stored best pose of every ligand
(section A SDF), or the best modes overall or per pocket, converted from the engine output with
pocketvina.convert. The protein structure (structures/<protein_id>.*.gz) is decompressed in memory; PDBQT and
mmCIF structures are converted to PDB text first, since PoseBusters reads only PDB proteins, and crystal waters
(HOH) are left out as for docking (other HETATM records, e.g. metal ions and cofactors, stay). Worker processes
load the protein once each, exactly as PoseBusters loads a .pdb file (same loader options of the config), and
check one pose at a time, so that a pose which takes too long can be stopped: it is tried again with the next of
timeouts in a fresh worker, and recorded as "timeout" after the last one. Every selected pose gets a row in
tables/posebusters/<protein_id>.parquet (io.tables.POSEBUSTERS), written atomically once the protein is done.
The workers share the CPUs this process may use (PoseBusters' internal energy check would otherwise start a thread
per core of the machine in each of them).
PoseBusters (pip install posebusters) is an optional dependency, imported only when checks run. Workers are
forked on Linux; elsewhere they are spawned, which re-imports the calling script: guard it with
if __name__ == "__main__": there.
PoseBusters is described in the "PoseBusters: AI-based docking methods fail to generate physically valid poses or generalise to novel sequences" paper.
- pocketvina.bust.require_posebusters() str[source]¶
The PoseBusters version;
ImportErrorif it is not installed.
- pocketvina.bust.check_names(config='dock') List[str][source]¶
Names of the PoseBusters checks of
configin mask bit order: bitbofpb_mask/pb_na_maskis checkcheck_names(config)[b]. The same names as the columns ofPoseBusters(config).bust(...).
- pocketvina.bust.default_workers() int[source]¶
Worker processes when
workers=None: the CPUs this process may use, at mostMAX_DEFAULT_WORKERS.
- pocketvina.bust.bust_results(results_dir, *, select: str = 'best', top_k: int = 1, config='dock', workers: int | None = None, timeouts=(30, 300), proteins: str | Sequence[str] | None = None, overwrite: bool = False, tmp_dir: str | None = None) List[str][source]¶
Run PoseBusters on the docked poses of a results directory; returns the ids of the proteins checked.
select: "best" the stored best pose of each ligand; "top_k" thetop_kbest modes of each ligand over all pockets; "per_pocket" thetop_kbest modes of each ligand in each pocket. Modes other than the stored best pose are converted from the engine output withpocketvina.convert(a failure is a "convert_failed" row).config: a PoseBusters config name ("dock", "dock_fast", ...) or dict.workers: worker processes (None:default_workers()).timeouts: seconds per pose for each attempt; a pose still running after the last one is a "timeout" row (None: no limit).proteins: protein ids (None: every committed protein). A protein that already has a table is skipped unlessoverwrite(or it was docked again since). Temp files go toio.writer.resolve_tmp_dir(tmp_dir)and are removed at the end.Rows (
io.tables.POSEBUSTERS):pb_status"valid" (no check failed), "invalid", "timeout", "error", "convert_failed" or "no_pose" (pocket and mode are -1 when there is no pose at all); bitbofpb_maskis set if checkcheck_names(config)[b]passed, ofpb_na_maskif it gave no result (all bits for poses that were not checked). The check names are also in the Parquet schema metadata (pocketvina.pb_checks).
Visualisation¶
3D views of docked poses for notebooks (Mol* through MolViewSpec, or py3Dmol) and a table of the best pairs.
from pocketvina import viz
viz.table("results") # best pose per protein x ligand, best first
viz.show("results", "AF-P00533-F1-model_v4", "gefitinib") # best pose (the stored SDF)
viz.show("results", "AF-P00533-F1-model_v4", "gefitinib", pocket=2, mode=3)
viz.show_modes("results", "AF-P00533-F1-model_v4", "gefitinib", pocket=2)
viz.to_html("results", "AF-P00533-F1-model_v4", "gefitinib", path="pose.html") # a file to share
The scene follows the PocketVina Atlas viewer (light theme): grey cartoon, the residues within pocket_radius A of
the pose as thin ball-and-stick with grey carbons under a faint surface in the pocket's colour, the pose as
ball-and-stick with gold carbons, coloured by element, hydrogens hidden, the camera on the pose (+ 8 A), and a label
with protein, ligand, pocket, mode and affinity.
Backends: "molstar" needs molviewspec (Python >= 3.10), "py3dmol" needs py3Dmol; "auto" takes
Mol* when molviewspec imports, else py3Dmol. Both are optional and imported only when a view is made.
Offline: the views hold the structures, but not the viewers' JavaScript. Mol* loads it from a CDN (jsDelivr) when
the view is drawn; without internet use backend="py3dmol" -- py3Dmol also needs its 3Dmol.js, from a CDN by
default, but a small script that the browser often has cached. to_html writes a standalone page (structures
embedded) to share; it, too, loads the viewer's JavaScript when opened.
Mol* version: MOLSTAR_VERSION (5.5.0: released with molviewspec 1.8.1, it reads the scenes molviewspec 1.8
writes), not molviewspec's default "latest", so a view draws the same way later. To use another one, pass
molstar_version= (e.g. "latest") or set $POCKETVINA_MOLSTAR_VERSION (also for pocketvina show).
Mol* is described in the "Mol* Viewer: modern web app for 3D visualization and analysis of large biomolecular structures" paper, MolViewSpec in the "Describing and Sharing Molecular Visualizations Using the MolViewSpec Toolkit" paper and 3Dmol.js in the "3Dmol.js: molecular visualization with WebGL" paper.
- pocketvina.viz.show(results: str | PathLike[str] | Results, protein: str, ligand, pocket: int | None = None, mode: int = 1, *, backend: str = 'auto', width=950, height=600, pocket_radius: float = 5.0, surface: bool = True, molstar_version: str | None = None)[source]¶
3D view of a ligand's pose in a protein; the notebook draws it when it is the cell's result.
results: a results directory (path) orio.results.Results;ligand: ligand_id or ligand_idx.pocket=None: the best pose (the stored SDF of section A; the raw PDBQT model if there is none); else modemodeof that pocket (P2Rank rank), converted to SDF in memory (convert.pose_to_sdf) or, if that fails, the raw PDBQT model. Residues withinpocket_radiusA of the pose are drawn as sticks (and a faint surface ifsurface).backend:"molstar"returns aMolstarView(a MolViewSpec scene withdata={"protein.pdb": ..., "ligand.sdf": ...}, shown withmolviewspec.molstar_notebook),"py3dmol"apy3Dmol.view,"auto"Mol* when molviewspec imports, else py3Dmol. Outside a notebook the object is returned without drawing anything. Mol* loads its JavaScript from a CDN: versionmolstar_version(None:$POCKETVINA_MOLSTAR_VERSION, elseMOLSTAR_VERSION, 5.5.0; any molstar npm version or tag, e.g."latest"); without internet usebackend="py3dmol"(py3Dmol also needs its 3Dmol.js, from a CDN by default). To share a view, seeto_html.Unknown proteins, ligands, pockets or modes, and ligands without a pose, raise
KeyError.
- pocketvina.viz.show_modes(results: str | PathLike[str] | Results, protein: str, ligand, pocket: int | None, *, backend: str = 'auto', width=950, height=600, pocket_radius: float = 5.0, surface: bool = True, molstar_version: str | None = None, ui: str = 'stories')[source]¶
All modes of a ligand in one pocket (
pocket=None: the pocket of its best pose).Mol*: one MolViewSpec snapshot per mode (residues near that mode, the mode table in the description), in the MVS Stories page (
ui="stories", with previous/next buttons) or the plain viewer (ui="viewer", Mol*'s snapshot controls). py3Dmol: the modes as frames of one model, animated (residues near any mode). Each mode is converted to SDF in memory, else drawn from its PDBQT model (py3Dmol: if any mode does not convert, all frames are the PDBQT models). Seeshowfor the arguments and the offline note.
- pocketvina.viz.to_html(results: str | PathLike[str] | Results, protein: str, ligand, pocket: int | None = None, mode: int = 1, path=None, *, backend: str = 'auto', width=950, height=600, pocket_radius: float = 5.0, surface: bool = True, molstar_version: str | None = None) str[source]¶
Standalone HTML page of the
showview (structures embedded); written topathif given.Mol*:
molviewspec.molstar_html(the scene and its files as a base64 MVSX archive); py3Dmol: its full-page HTML. The page loads the viewer's JavaScript from a CDN when opened, so it needs internet to draw.
- pocketvina.viz.table(results: str | PathLike[str] | Results, top: int | None = 50, protein=None) pandas.DataFrame[source]¶
Best pose per protein x ligand, best (lowest) Vina score first;
top=Nonefor all rows.Columns: protein_id, ligand_id, smiles_docked, vina, best_pocket, best_mode, ligand_efficiency (
-vina / n_heavyof the docked fragment), and pb_status / pb_valid when PoseBusters results are there. Ligands without a pose are left out.protein: one protein id or a list (default: all).
- class pocketvina.viz.MolstarView(state, data: Dict[str, bytes], *, info: dict, width=950, height=600, ui: str = 'viewer', molstar_version: str | None = None)[source]¶
A MolViewSpec scene (
state) and the files it loads by name (data), drawn by Mol*.The result of
show/show_modeswith the Mol* backend: Jupyter and Colab draw it when it is a cell's result (throughmolviewspec.molstar_notebook);to_html()gives a standalone page,save(path)writes it.infoholds what is shown (protein, ligand, pocket, mode(s), affinity, residues, files).
GPUs¶
GPUs for the docking engine: the NVIDIA GPUs this process may use (list_gpus) and how many engine processes run
on each of them at the same time (plan_slots).
Each engine process ("slot") is pinned to one GPU through its own CUDA_VISIBLE_DEVICES, which NVIDIA's OpenCL
honours like CUDA does. One engine at the default thread=8000 holds about 6.4 GB of GPU memory (measured on a
Tesla P40; more threads need more), hence DEFAULT_VRAM_PER_PROC_MIB = 6600 MiB. Several engines on one GPU share
its compute units: that pays off when one engine leaves the GPU partly idle (e.g. during the CPU-side work of each
call), which depends on the GPU and the workload.
Standard library only (nvidia-smi for the GPU list), so the "files" output format still docks without pyarrow.
- class pocketvina.gpu.GPU(index: int, uuid: str, name: str, memory_total_mib: int | None, memory_free_mib: int | None)[source]¶
One GPU as
nvidia-smireports it; the memory fields are None when it reports none ([N/A]).- index: int¶
Alias for field number 0
- uuid: str¶
Alias for field number 1
- name: str¶
Alias for field number 2
- memory_total_mib: int | None¶
Alias for field number 3
- memory_free_mib: int | None¶
Alias for field number 4
- pocketvina.gpu.list_gpus() List[GPU][source]¶
The NVIDIA GPUs this process may use:
nvidia-smifiltered by$CUDA_VISIBLE_DEVICES(seevisible_gpus;$CUDA_DEVICE_ORDERtells how it numbers them). [] withoutnvidia-smior when it fails (e.g. a container with the driver's OpenCL library but notnvidia-smi: the engine then uses the first GPU of NVIDIA's OpenCL platform; it docks on NVIDIA GPUs only).
- pocketvina.gpu.select_gpus(gpus: Sequence[GPU], spec: str | None) List[GPU][source]¶
The GPUs that
spec(check_gpu_spec) names, in its order: None the first ofgpus(one GPU per run, e.g. the one SLURM gives the job),"all"all of them;ValueErrorif it names one that is not ingpus(not visible) or the same GPU twice.
- pocketvina.gpu.fitting_procs(gpu: GPU, vram_per_proc_mib: int, margin_mib: int = 1024) int | None[source]¶
Engine processes of
vram_per_proc_mibthat fit in the GPU's free memory lessmargin_mib(at least 1); None whennvidia-smireports no free memory figure.
- pocketvina.gpu.plan_slots(gpus: Sequence[GPU], procs_per_gpu: int | str = 1, vram_per_proc_mib: int = 6600, margin_mib: int = 1024) List[str][source]¶
One entry per engine slot, the
CUDA_VISIBLE_DEVICESvalue of its engine (device_id: the GPU's UUID).procs_per_gpuan int: that many slots per GPU, but no more than its free memory holds atvram_per_proc_mibeach (keepingmargin_mibfree; always at least 1)."auto": as many as fit (fitting_procs; 1 whennvidia-smireports no free memory). Slots alternate between the GPUs ([g0, g1, g0, g1, ...]), so that fewer tasks than slots still spread over all GPUs. [] for no GPUs.
P2Rank and the engine¶
P2Rank, the pocket predictor PocketVina docks into: where it is installed, a one-time download of the release PocketVina is tested with, and the Java it needs.
p2rank_home() is the first P2Rank folder (one with a prank launcher) of
$P2RANK_HOME,the folder of the
prankonPATH(P2Rank's launcher, or a link or wrapper script to it; symlinks resolved; not a compiledprankwithout P2Rank'sbin/p2rank.jarnext to it, such as the PRANK sequence aligner that bioconda and Debian install under that name),pocketvina/p2rank_2.5/in the package directory (source installs before v0.2 unpacked it there),the user cache
~/.cache/pocketvina/p2rank-2.5.1/($XDG_CACHE_HOMEinstead of~/.cachewhen set).
ensure_p2rank() returns the prank launcher of that folder and, if there is none, downloads the official
P2Rank 2.5.1 release once (checked against its pinned sha256) and unpacks it into the user cache; the folder appears
complete or not at all, and processes starting at the same time (e.g. SLURM array jobs) download it only once.
pocketvina setup p2rank does the same ahead of a run, e.g. on a login node that has internet access. Nothing is
ever written into the package directory.
P2Rank needs Java 17 or later: its launcher runs $JAVA_HOME/bin/java when JAVA_HOME is set, else java on
PATH. check_java() finds that Java the same way and explains how to install one.
Standard library only (tqdm draws the download progress bar when asked to).
P2Rank is described in the "P2Rank: machine learning based tool for rapid and accurate prediction of ligand binding sites from protein structure" paper.
- exception pocketvina.p2rank.P2RankError[source]¶
P2Rank is not installed and cannot be installed here (no network, a bad archive, a full disk...).
- pocketvina.p2rank.find_p2rank() P2RankInstall | None[source]¶
The first P2Rank of
$P2RANK_HOME,prankonPATH, the package folderp2rank_2.5/and the user cache (see the module docstring); None if there is none. A$P2RANK_HOMEwithout aprankis skipped with a warning, aprankonPATHthat is not P2Rank (e.g. the PRANK aligner) silently.
- pocketvina.p2rank.p2rank_home() str | None[source]¶
The folder of the P2Rank PocketVina runs (see
find_p2rank), or None if there is none.
- pocketvina.p2rank.ensure_p2rank(download: bool = True, *, root=None, archive=None, force: bool = False, progress: bool = False) str[source]¶
The
pranklauncher of the P2Rank to run, installing P2Rank 2.5.1 first if there is none.Without
root,archiveandforcethe P2Rank offind_p2rank()is used if there is one. Otherwise P2Rank goes to<root>/p2rank-2.5.1(rootdefault:cache_root()), unless it is there already (and notforce): unpacked fromarchive(ap2rank_2.5.1.tar.gzdownloaded elsewhere) or, withdownload, downloaded fromP2RANK_URL; either must matchP2RANK_SHA256.progressshows a download progress bar (tqdm, on stderr). RaisesP2RankErrorwith what to do instead if P2Rank is missing and cannot be installed. A P2Rank installed into anotherrootis found by later runs only through$P2RANK_HOME.
- pocketvina.p2rank.check_java(minimum: int = 17) int[source]¶
The major version of the Java P2Rank would run;
JavaErrorsaying how to get one if it is missing or older thanminimum.
- pocketvina.engine.engine_path() str[source]¶
The engine executable:
$POCKETVINA_ENGINE(a path, or a command onPATH), else the package binarypocketvina/PocketVina-GPU, elsepocketvina-engineonPATHor in<sys.prefix>/bin(a conda env used without activating it, e.g. as a Jupyter kernel). If there is none, the package binary's path (run_enginereports it missing).
- pocketvina.engine.kernel_cache_dir([visible_devices])[source]¶
Folder for the compiled OpenCL kernels (the config's
opencl_binary_path); the engine creates it.$POCKETVINA_KERNEL_CACHEif set, else~/.cache/pocketvina/kernels/<key>($XDG_CACHE_HOMEinstead of~/.cachewhen set; the system temp dir if there is no usable home), where<key>iskernel_cache_key(visible_devices): the folder for an engine run withCUDA_VISIBLE_DEVICES=visible_devices(None: unset), by default with this process's.
- pocketvina.engine.resolve_tmp_dir(explicit: str | None = None) str[source]¶
A fresh private temp folder (
mkdtemp(prefix="pocketvina_")) inside the first ofexplicit,$POCKETVINA_TMPDIR,$SLURM_TMPDIR,$TMPDIR,tempfile.gettempdir().explicitis created if needed; an environment variable naming a missing or read-only folder is skipped. The path returned is absolute. The caller removes the folder when done.