Download and visualise
How to take the data home, read one pose out of a pose file, and look at it in your own viewer. The example is Erlotinib (PVL01963) on EGFR (P00533).
What to download
Paths are relative to the data address https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1/. Single files of a protein or a pair are also on each protein page (Downloads), and a selection of pairs downloads as a ZIP from any table.
| Path | Content |
|---|---|
proteins/<UniProt>.json.gz | One protein: annotation, pockets, and one row per compound with its scores and the byte position of its top pose. |
compounds/<PVL>.json.gz | One compound: its catalogue entries and the proteins with the highest affinity; .all.json.gz has every protein. |
poses/<UniProt>.poses | Every pose of one protein (PVATLAS1): the top pose of each compound (SDF) and all modes of each pocket run (PDBQT). |
poses_redock/<UniProt>.poses | The same for the desalted forms of salt entries (rows whose pf column points to this file). |
structures/AF-<UniProt>-F1-model_v6.pdb | The AlphaFold model that was docked; also as .pdb.gz. |
tables/*.parquet | The bulk tables: pairs, pocket runs, modes, pockets, compounds (listed on Downloads). |
ligands/<PVL>.svg | The 2D drawing of a docked structure. |
MANIFEST.json | Every file of the release with its size and SHA-256. |
Download with curl or wget
The server answers range requests, so one pose can be fetched without the whole pose file: each row of the protein's table gives the byte offset and length of its top pose (top_off, top_len), and each record is one gzip member.
BASE=https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1
# the protein's table: one row per compound (column names in the file)
curl -s $BASE/proteins/P00533.json.gz | gunzip > P00533.json
# the AlphaFold model that was docked
curl -O $BASE/structures/AF-P00533-F1-model_v6.pdb
# every pose of the protein in one file (large)
wget $BASE/poses/P00533.poses
# one pose only: a range request with the row's top_off and top_len (Erlotinib on EGFR)
curl -s -r 1568949-1569842 $BASE/poses/P00533.poses | gunzip > P00533_PVL01963_top.sdf
# a bulk table, and the list of every file with its checksum
curl -O $BASE/tables/pairs_by_protein.parquet
curl -O $BASE/MANIFEST.jsonThe easy way: the Python package
The PocketVina Python package reads this Atlas directly, with no GPU needed. You can search the results, rank them, view a pair's poses, save them and download part of the Atlas for offline use. Each step below shows what it prints in a console, with long names cut short to fit; in Jupyter or Colab the same results come as HTML tables. The example is imatinib on ABL1.
pip install "pocketvina>=0.3.1"Open the Atlas
It reads this website's data over the internet and keeps what it has read for the next time.
from pocketvina import Atlas
atlas = Atlas()
atlasPocketVina Atlas v1.1: 18,713 proteins, 2,559 drugs, 48,406,051 pairs [https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1/]Find a protein or a drug
search takes a name or any identifier, closest match first.
atlas.search("ABL1") kind id name matched value
0 protein P00519 ABL1: Tyrosine-prote... gene ABL1
1 protein Q8TDN4 CABLES1: CDK5 and AB... protein name CDK5 and ABL1 enzyme...
2 protein Q9BTV7 CABLES2: CDK5 and AB... protein name CDK5 and ABL1 enzyme...protein and drug show what the Atlas knows about one of them.
atlas.protein("ABL1")ProteinInfo P00519 (ABL1): Tyrosine-protein kinase ABL1
AlphaFold model AF-P00519-F1-model_v6, mean pLDDT 63.4
class Enzyme > Kinase
5 pockets (P2Rank)
10 associated diseases (Open Targets)atlas.drug("imatinib")DrugInfo PVL00129: Imatinib (STI571)
ChEMBL ID: CHEMBL1642
catalogue numbers: S1026, S2475
InChIKey: KTUFNOKKBVMGRW-UHFFFAOYSA-N
parent SMILES: Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1Nc1nccc(-c2cccnc2)n1
library SMILES: CN1CCN(CC1)CC2=CC=C(C=C2)C(=O)NC3=CC=C(C)C(=C3)NC4=NC=CC(=N4)C5=CC=CN=C5.C[S](O)(=O)=O
docked SMILES: Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1Nc1nccc(-c2cccnc2)n1
synonyms: Glamox, Imatinib
ATC: L01EA01Rank the results
The drugs with the highest affinity on a protein, and the proteins a drug binds most strongly, lowest Vina score first.
atlas.best_scores(protein="ABL1", top=5) protein_id gene ligand_id name vina best_pocket best_mode ligand_efficiency
0 P00519 ABL1 PVL00898 Hypericin -13.4 1 1 0.353
1 P00519 ABL1 PVL01982 Midostaurin (PKC412) -11.4 1 1 0.265
2 P00519 ABL1 PVL00250 Drospirenone -11.0 1 1 0.407
3 P00519 ABL1 PVL02025 Sanguinarine -10.8 1 1 0.432
4 P00519 ABL1 PVL00271 Staurosporine -10.7 1 1 0.306atlas.best_scores(ligand="imatinib", top=5) protein_id gene ligand_id name vina best_pocket best_mode ligand_efficiency
0 Q9H9P8 L2HGDH PVL00129 Imatinib (STI571) -12.0 1 1 0.324
1 Q9BZH6 WDR11 PVL00129 Imatinib (STI571) -11.9 1 1 0.322
2 Q7KZN9 COX15 PVL00129 Imatinib (STI571) -11.7 1 1 0.316
3 Q8WZ60 KLHL6 PVL00129 Imatinib (STI571) -11.7 1 1 0.316
4 O75908 SOAT2 PVL00129 Imatinib (STI571) -11.6 2 1 0.314best_pocket and best_mode are the pocket and the mode of the pose with that Vina score.
One protein and one drug
select picks the poses of a pair; pocket="all" takes the highest-affinity pose in each pocket.
pair = atlas.select(protein="ABL1", ligand="imatinib", pocket="all")
pairSelection PV_P00519_PVL00129: protein P00519, ligand PVL00129, the highest-affinity pose in each pocket: 5 poses
SMILES: CN1CCN(CC1)CC2=CC=C(C=C2)C(=O)NC3=CC=C(C)C(=C3)NC4=NC=CC(=N4)C5=CC=CN=C5.C[S](O)(=O)=O
pocket lowest Vina score (kcal/mol) modes
1 * -8.5 1
2 -6.9 1
3 -7.8 1
4 -7.7 1
5 -6.8 1The star in that list marks the pocket of the pair's highest-affinity pose.
show draws the pair in 3D, the same view as on a protein page here: in Jupyter, Colab or VS Code below the cell, in a script as an HTML file whose path it returns. Below is the page it draws for this pair, and it works the same way: rotate the protein, switch pockets or step through the poses.
pair.show()bust gives the PoseBusters checks of those poses, one row per pose: pb_valid is true when a pose passes them all, and pb_status is valid, invalid or the reason a pose was not checked.
checks = pair.bust()
checks[["pocket", "mode", "vina", "pb_valid", "pb_status"]] pocket mode vina pb_valid pb_status
0 1 1 -8.5 True valid
1 2 1 -6.9 True valid
2 3 1 -7.8 True valid
3 4 1 -7.7 True valid
4 5 1 -6.8 True validpair.export() writes the poses as an SDF file and returns its path; pair.export(protein=True) also writes the AlphaFold model as a PDB file.
pair.export()'/path/to/PV_P00519_PVL00129_pocketall_top.sdf'Work offline
atlas.download(proteins=["ABL1"], out="my_atlas") copies what the Atlas has on those proteins into a folder, and Atlas("my_atlas") reads that folder without internet. The same commands work in a shell with pocketvina atlas.
The full guide, with every option: PocketVina Atlas in the PocketVina documentation. It also opens as a Colab notebook you can run in your browser.
Without the package: read a pose file yourself
Only if you would rather not install anything: this script reads the same poses out of a pose file with the Python standard library. The package above does this for you.
A pose file starts with a fixed header, then table A (offset and length of the top pose of each compound) and table B (the start of the mode block of each compound and pocket). The script below reads the protein's table, finds the compound's record (cidx, minus cidx_offset in the file of the desalted forms), and writes the top pose as SDF and the modes of its pocket as PDBQT. For a downloaded file, read the same byte ranges from disk.
import gzip, json, struct, sys, urllib.request
BASE = sys.argv[1] if len(sys.argv) > 1 else "https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1"
UNIPROT, PVL = "P00533", "PVL01963" # EGFR, erlotinib
HEADER = struct.Struct("<8sIIIIQQQQQQII") # PVATLAS1 header (first 88 of 128 bytes)
def get(path, start=None, end=None): # a whole file, or bytes start..end (inclusive)
req = urllib.request.Request(f"{BASE}/{path}", headers={} if start is None else {"Range": f"bytes={start}-{end}"})
with urllib.request.urlopen(req) as r:
return r.read()
protein = json.loads(gzip.decompress(get(f"proteins/{UNIPROT}.json.gz")))
c = {name: i for i, name in enumerate(protein["columns"])}
row = next(r for r in protein["rows"] if r[c["pvl"]] == PVL)
pose_file = protein["poses_redock" if row[c["pf"]] == 1 else "poses"] # pf 1: the file of the desalted forms
path = pose_file["file"]
magic, version, N, K, _, table_a, table_b, *_ = HEADER.unpack(get(path, 0, HEADER.size - 1))
assert magic == b"PVATLAS1"
i = row[c["cidx"]] - pose_file.get("cidx_offset", 0) # the compound's record in this file
off, length = struct.unpack("<QI", get(path, table_a + 12 * i, table_a + 12 * i + 11)) # table A: its top pose
assert (off, length) == (row[c["top_off"]], row[c["top_len"]])
open(f"{UNIPROT}_{PVL}_top.sdf", "wb").write(gzip.decompress(get(path, off, off + length - 1)))
pocket = row[c["pocket"]] # table B: the modes of one pocket run
j = i * K + pocket - 1
start, end = struct.unpack("<2Q", get(path, table_b + 8 * j, table_b + 8 * j + 15))
if end > start:
open(f"{UNIPROT}_{PVL}_pk{pocket}_modes.pdbqt", "wb").write(gzip.decompress(get(path, start, end - 1)))
print(f"{N} compounds, {K} pockets; top pose {length} bytes, pocket {pocket} modes {end - start} bytes")
Visualise locally
PyMOL
# in a shell
pymol AF-P00533-F1-model_v6.pdb P00533_PVL01963_top.sdf P00533_PVL01963_pk1_modes.pdbqt
# or at the PyMOL prompt
load AF-P00533-F1-model_v6.pdb
load P00533_PVL01963_top.sdf, top
load P00533_PVL01963_pk1_modes.pdbqt, modes
hide everything
show cartoon, AF-P00533-F1-model_v6
show sticks, top or modes
orient topChimeraX
open AF-P00533-F1-model_v6.pdb
open P00533_PVL01963_top.sdf
open P00533_PVL01963_pk1_modes.pdbqt
view #2py3Dmol in Jupyter
import py3Dmol
view = py3Dmol.view(width=800, height=600)
view.addModel(open("AF-P00533-F1-model_v6.pdb").read(), "pdb")
view.setStyle({"model": 0}, {"cartoon": {"color": "lightgrey"}})
view.addModel(open("P00533_PVL01963_top.sdf").read(), "sdf")
view.setStyle({"model": 1}, {"stick": {"colorscheme": "yellowCarbon"}})
view.zoomTo({"model": 1})
view.show()Mol* in the browser
Open the Mol* viewer and load the model and the pose files from your disk (Open Files). The 3D view on each protein page of this site is Mol* too.
Query the tables
DuckDB reads the Parquet tables over HTTP without downloading them: the ten compounds with the highest affinity on EGFR.
duckdb -c "
SELECT p.catalog_id, e.name, p.vina, p.best_pocket, p.best_mode, p.pb_status
FROM 'https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1/tables/pairs_by_protein.parquet' p
JOIN 'https://bimsbstatic.mdc-berlin.de/akalin/asarigun/pocketvina_atlas/data/v1.1/tables/compound_entries_annotated.parquet' e USING (catalog_id)
WHERE p.uniprot = 'P00533'
ORDER BY p.vina
LIMIT 10"