Category Archives: Python

Predicting ADME Properties with Machine Learning: 82% of the Performance From Two Descriptors

A Nature survey of ~1500 scientists reported that more than 70% had failed to reproduce another scientist’s experiments, and 50% had failed to replicate their own (Baker, 2016). This study wasn’t specific to machine learning, but the crisis has its own flavour in computational drug discovery.

One aspect of this is that available datasets have known quality issues, and results built on them can be fragile. MoleculeNet and the Therapeutic Data Commons (TDC) opened drug discovery to a wider ML community, but they’re no longer sufficient for driving further advances (Wognum et al., 2024).

Amongst a number of issues, 71% of molecules in one MoleculeNet dataset (BACE) contained at least one undefined stereocenter (a point where the same atoms can sit in two different 3D arrangements), making it unclear what chemical entity is actually being modelled (Li et al., 2026).

The stakes are high. In 2017, a research group found their cancer-target inhibitor inactive from one vendor and highly active from another. Eventually they traced this to vendors selling different mixtures of the compound’s two 3D forms where only one was active on the target and mechanism they were investigating (Baker, 2017).

Most approved pharmaceuticals are relatively small chemical molecules, typically weighing under 900 g/mol, with most of the rest being biologics. Whilst in Oxford in OPIG over the summer as a UNIQ+ student, I focused on ADME, an aspect of early stage drug discovery, where assays are measured in vitro as a stand-in to predict how a compound will behave in vivo (in the human body) before clinical trials. Absorption (does it enter the body), Distribution (where does it go), Metabolism (how quickly it’s transformed) and Excretion (how quickly it’s eliminated) are processes critical to whether a candidate succeeds. 

Continue reading →

App-ready databases from Python with SQLModel and FastAPI

Python is ubiquitous for those of us coming into programming from academic research backgrounds, both for generating scientific data and for analysing it. Of course, modern data-driven research only thrives when data is FAIR (findable, accessible, interoperable, and reusable) and traditional relational databases and APIs for interacting with them are a tried-and-true method of ensuring FAIRness. (And in the age of machine learning, the machines need things to be FAIR arguably even more than we do…)

“But I’m a data scientist/computational chemist/bioinformatician!” you protest. “I just (ab)use databases using Python, I don’t make them for someone else to use!” Understandable, but the barrier to entry may be much lower than you think, thanks to two related Python libraries: SQLModel and FastAPI. These powerful tools by developer Sebastián Ramírez (@tiangolo on GitHub) work in concert to make relational databases and APIs much easier to implement for Python natives. Let’s see how they can help…

Continue reading →

How Unusual Is Your Generated Molecule? Let The CCDC Tell You

In this post I’ll walk through how to set up the CCDC Python API and use the CSD Geometry Analyser to evaluate the geometric quality of molecules from three representative structure-based de novo design models. I’ve put together a small GitHub repo with the full analysis code where we look at bond lengths, angles, torsions, and ring conformations across the three methods, and compare these against their PoseBusters validity scores to see what each metric is really capturing.

Continue reading →

Speeding up python through profiling

Python is a shockingly slow language. A test on a raspberry pi of simply “turn this pin on and off as fast as you can” gave the results below.

SystemLibrarySpeed
Shell/proc/mem access2.8 kHz
Shell / gpio utilityWiringPi gpio utility40 Hz
PythonRPI.GPIO70 kHz
PythonwiringPi2 bindings28 kHz
RubywiringPi bindings21 kHz
CNative library22 MHz
CBCM 28355.4 MHz
CwiringPi4.1 – 4.6 MHz
PerlBCM 283548 kHz
Continue reading →

SigmaDock: untwisting molecular docking with fragment-based SE(3) diffusion

Alvaro Prat, Leo Zhang, Charlotte Deane, Yee Whye Teh, & Garrett M. Morris
International Conference On Learning Representations (ICLR 2026)

Molecular docking sits at the heart of structure-based drug discovery. If we can reliably predict how a small molecule binds in a protein pocket, we can prioritize compounds faster, reason about interactions more clearly, and build better pipelines for hit discovery and lead optimization. But in practice, docking is still a difficult problem: classical methods are often robust but imperfect, while recent deep learning approaches have sometimes looked promising on headline metrics without consistently producing chemically plausible poses.

SigmaDock was built to address exactly that gap. Instead of treating docking as a problem of directly diffusing on torsion angles or unconstrained atomic coordinates, SigmaDock represents ligands as collections of rigid fragments and learns how to reassemble them inside the binding pocket using diffusion on SE(3)\text{SE}(3). In plain English: rather than trying to “wiggle” every flexible degree of freedom in a tangled way, SigmaDock breaks the ligand into chemically meaningful rigid pieces and learns where those pieces should go, and how they should reorient, to recover a valid bound pose.

Figure 1: Illustration of SigmaDock using PDB 1V4S and ligand MRK. We create an initial conformation of a query ligand where we define our mm rigid body fragments (colour coded). The corresponding forward diffusion process operates in SE(3)m\text{SE}(3)^m via independent roto-translations.
Continue reading →

Advanced PyMOL Visualization for Weighted Structural Ensembles (Part 2): Efficient Weighted SASA Surfaces

In Part 1, we covered reference state handling, RMSD-based coloring, and cluster visualization for weighted structural ensembles. Now we tackle a more ambitious goal: generating solvent-accessible surface area (SASA) surfaces that reflect the weighted conformational distribution of your ensemble.

Why surfaces? Because they show the accessible conformational space—where your protein can actually be found, weighted by population. This is particularly powerful when comparing different fitting methods or showing how experimental constraints reshape the ensemble.

The challenge? A typical ensemble might have 500+ frames, each generating thousands of surface points. Naive approaches choke on the computational and memory demands. This post shares the optimizations that make weighted SASA visualization practical.

Continue reading →

Democratising the Dark Arts: Writing Triton Kernels with Claude

Why would you ever want to leave the warm, fuzzy embrace of torch.nn? It works, it’s differentiable, and it rarely causes your entire Python session to segfault without a stack trace. The answer usually comes down to the “Memory Wall.” Modern deep learning is often less bound by how fast your GPU can do math (FLOPS) and more bound by how fast it can move data around (Memory Bandwidth). When you write a sequence of simple PyTorch operations, something like x = x * 2 + y the GPU often reads x from memory, multiplies it, writes it back, reads it again to add y, and writes it back again. It’s the computational equivalent of making five separate trips to the grocery store because you forgot the eggs, then the milk, then the bread. Writing a custom kernel lets you “fuse” these operations. You load the data once, perform a dozen mathematical operations on it while it sits in the ultra-fast chip registers, and write it back once. The performance gains can be massive (often 2x-10x for specific layers).But traditionally, the “cost” of accessing those gains, learning C++, understanding warp divergence, and manual memory management, was just too high for most researchers. That equation is finally changing.

Continue reading →

Extracting 3D Pharmacophore Points with RDKit

Pharmacophores are simplified representations of the key interactions ligands make with proteins, such as hydrogen bonds, charge interactions, and aromatic contacts. Think of them as the essential “bumps and grooves” on a key that allow it to fit its lock (the protein). These maps can be derived from ligands or protein–ligand complexes and are powerful tools for virtual screening and generative models. Here, we’ll see how to extract 3D pharmacophore points from a ligand using RDKit.
(Code adapted from Dr. Ruben Sanchez.)

Why pharmacophore “points”?

RDKit represents each pharmacophore feature (donor, acceptor, aromatic, etc.) as a point in 3D space, located at the feature center. These points capture the essential interaction motifs of a ligand without requiring the full atomic detail.

Continue reading →

Exploring the Protein Data Bank programmatically

The Worldwide Protein Data Bank (wwPDB or just the PDB to its friends) is a key resource for structural biology, providing a single central repository of protein and nucleic acid structure data. Most researchers interact with the PDB either by downloading and parsing individual entries as mmCIF files (or as legacy PDB files), or by downloading aggregated data, such as the RCSB‘s collection in a single FASTA file of all polymer entity sequences. All too often, researchers end up laboriously writing their own file parsers to digest these files. In recent years though, more sophisticated tools have been made available that make it much easier to access only the data that you need.

Continue reading →