archives –––––––– @btnaughton
Brian Naughton | Mon 04 September 2023 | biotech | biotech machine learning ai

Molecular dynamics (MD) means simulating the forces acting on atoms. In drug discovery, MD usually means simulating protein–ligand interactions. This is clearly a crucial step in modern drug discovery, yet MD remains a pretty arcane corner of computational science.

This is a different problem to docking, where molecules are for the most part treated as rigid, and the problem is finding the right ligand orientation and the right pocket. Since in MD simulations the atoms can move, there are many more degrees of freedom, and so a lot more computation is required. For a great primer on this topic, see Molecular dynamics simulation for all (Hollingsworth, 2018).

What about deep learning?

Quantum chemical calculations, though accurate, are too computationally expensive to use for MD simulation. Instead, "force fields" are used, which enable computationally efficient calculation of the major forces. As universal function approximators, deep nets are potentially a good way to get closer to ground truth.

Analogously, fluid mechanics calculations are very computationally expensive, but deep nets appear to do a good job of approximating these expensive functions.

A deep net approximating Navier-Stokes

Recently, the SPICE dataset (Eastman, 2023) was published, which is a reference dataset that can be used to train deep nets for MD.

We describe the SPICE dataset, a new quantum chemistry dataset for training potentials relevant to simulating drug-like small molecules interacting with proteins. It contains over 1.1 million conformations for a diverse set of small molecules, dimers, dipeptides, and solvated amino acids.

This dataset has enabled new ML force fields like Espaloma (Takaba, 2023) and the recent Allegro paper (Musaelian, 2023), where they simulated a 44 million atom system of a HIV capsid. Interestingly, they scaled their system as high as 5120 A100's (which would cost $10k an hour to run!)


There are also hybrid ML/MM approaches (Rufa, 2020) based on the ANI2x ML force field (Devereux, 2020).

All of this work is very recent, and as I understand it, runs too slowly to replace regular force fields any time soon. Despite MD being a key step in drug development, only a small number of labs (e.g., Chodera lab) appear to work on OpenMM, OpenFF, and the other core technologies here.


Doing an MD simulation

I have only a couple of use-cases in mind:

  • does this ligand bind this protein in a human cell?
  • does this mutation affect ligand binding in a human cell?

Doing these MD simulations is tricky since a lot of background is expected of the user. There are many parameter choices to be made, and sensible options are not obvious. For example, you may need to choose force fields, ion concentrations, temperature, timesteps, and more.

By comparison, with AlphaFold you don't need to know how many recycles to run, or specify how the relaxation step works. You can just paste in a sequence and get a structure. As far as I can tell, there is no equivalent "default" for MD simulations.

A lot of MD tutorials I have found are geared towards simulating the trajectory of a system for inspection. However, with no specific numerical output, I don't know what to do with these results.

Choosing an approach

There are several MD tools out there for doing protein–ligand simulations, and calculating binding affinities:

  • Schrodinger is the main player in computational drug discovery, and a mature suite of tools. It's not really suitable for me, since it's expensive, geared toward chemists, designed for interactive use over scripting, and not even necessarily cutting-edge.
  • OpenEye also appears to be used a lot, and has close ties to open-source. Like Schrodinger, the tools are high quality, mostly interactive and designed for chemists.
  • HTMD from Acellera is not open-source, but it has a nice quickstart and tutorials.
  • GROMACS is open-source, actively maintained, and has tutorials, but is still a bit overwhelming with a lot of boilerplate.
  • Amber, like GROMACS, has been around for decades. It gets plenty of use (e.g., AlphaFold uses it as a final "relaxation" step), but is not especially user-friendly.
  • OpenMM seems to be where most of the open-source effort has been over the past five years or so, and is the de facto interface for a lot of the recent ML work in MD (e.g., Espaloma). A lot of tools are built on top or OpenMM:
    • yank is a tool for free energy binding calculations. Simulations are parameterized by a yaml file.
    • perses is also used for free energy calculation. It is pre-alpha software but under active development — e.g., this recent paper on protein–protein interaction. (Note, I will not claim to understand the differences between yank and perses!)
    • SEEKR2 is a tool that enables free energy calculation, among other things.
    • Making it rain is a suite of tools and colabs. It is a very well organized repo that guides you through running simulations on the cloud. For example, they include a friendly colab to run protein–ligand simulations. The authors did a great job and I'd recommend this repo broadly.
    • BAT, the Binding Affinity Tool, calculates binding affinity using MD (also see the related GHOAT).

OpenMM quickstart for protein simulation

Since I am not a chemist, I am really looking for a system with reasonable defaults for typical drug development scenarios. I found a nice repo by tdudgeon that appears to have the same goal. It uses OpenMM, and importantly has input from experts on parameters and settings. For example, I'm not sure I would have guessed you can multiply the mass of Hydrogen by 4.

This keeps their total mass constant while slowing down the fast motions of hydrogens. When combined with constraints (typically constraints=AllBonds), this often allows a further increase in integration step size.

I forked the repo, with the idea that I could keep the simulation parameters intact but change the interface a bit to make it focused on the problems I am interested in.

Calculating affinity

I am interested in calculating ligand–protein affinity (or binding free energy) — in other words, how well does the ligand bind the protein. There's a lot here I do not understand, but here is my basic understanding of how to calculate affinity:

  • Using MD: This is the most accurate way to measure affinity, but the techniques are challenging. There are "end-point" approaches (e.g., MM/PBSA) and Free Energy Perturbation (FEP) / alchemical approaches. Alchemical free energy approaches are more accurate, and have been widely used for years. (I believe Schrodinger were the first to show accurate results (Wang, 2015).) Still, I found it difficult to figure out a straightforward way to do these calculations.
  • Using a scoring function: This is how most docking programs like vina or gnina work. Docking requires a very fast, but precise, score to optimize.
  • Using a deep net: Recently, several deep nets trained to predict affinity have been published. For example, HAC-Net is a CNN trained on PDBbind. This is a very direct way to estimate binding affinity, and should be accurate if there is enough training data.


The SQM/COSMO docking scoring function (Ajani, 2017)

Unfortunately, I do know know of a benchmark comparing all the above approaches, so I just tried out a few things.

Predicting cancer drug resistance

One interesting but tractable problem is figuring out if a mutation in a protein will affect ligand binding. For example, let's say we sequence a cancer genome, and see a mutation in a drug target, do we expect that drug will still bind?

There are many examples of resistance mutations evolving in cancer.

Common cancer resistance mutations (Hamid, 2020)

Experiments

BRAF V600E is a famous cancer target. Vemurafenib is a drug that targets V600E, and L505H is known to be a resistance mutation. There is a crystal structure of BRAF V600E bound to Vemurafenib (PDB:3OG7). Can I see any evidence of reduced binding of Vemurafenib if I introduce an L505H mutation?

PDB:3OG7, showing the distance between vemurafenib (cyan) and L505 (yellow)

I ran a simple simulation: starting with the crystal structure, introduce each possible mutation at position 505, allow the protein–ligand system to relax, and check to see if the new protein–ligand interactions are less favorable according to some measure of affinity.

I first used gnina's scoring function, which is fast and should be relatively precise (in order for gnina to work!) The rationale here was that the "obstruction" due to the resistance mutation would be detectable as the new atom positions of the amino acid and ligand would lead to a lower affinity.

Estimated affinity given mutations at position 505 in 3OG7

Nope. The resistance mutation has higher affinity (realistically, there are no distinguishable differences for any mutation).

We also know that MEK1 V215E acts as a resistance mutation to PD0325901, and the PDB has a crystal structure of MEK1 bound to PD0325901 (PDB:70MX).

Estimated affinity given mutations at position 215 in 70MX

Again, I can't detect any difference in affinity due to the resistance mutation.

HAC-Net

I also tried a deep-learning based affinity calculator, HAC-Net. HAC-Net has a nice colab and is relatively easy to run Dockerized.

The HAC-Net colab gives me a pKd of 8.873 for 3OG7 (wild-type)

Estimated pKd given mutations at position 505 in 3OG7 using HAC-Net

I still see no difference in affinity with HAC-Net.

Each of these simulations (relaxing a protein–ligand system with solvent present) took a few minutes on a single CPU. If I wanted to simulate a full trajectory, which could be 50 nanoseconds or longer, it would take hundreds or thousands of times as long.


Conclusions

On the one hand, I can run state-of-the-art MD simulations pretty easily with this system. On the other hand, I could not discriminate cancer resistance mutations from neutral mutations.

There are several possible reasons. Most likely, the short relaxation I am doing is insufficient and I need longer simulations. The simulations may also be insufficiently accurate, either intrinsically or due to poor parameterization. It's difficult to feel confident in these kinds of simulations, since there's no simple way to verify anything.

If anyone knows of any obvious fix for the approach here, let me know! Probably the next thing I would try would be adapting the Making It Rain tools, which include (non-alchemical) free energy calculation. For some reason the Making It Rain colab specifies "This notebook is NOT a standard protocol for MD simulations! It is just simple MD pipeline illustrating each step of a simulation protocol." which begs the questions, why not and where is such a notebook?

I do think that enabling anyone to run such simulations — specifically, with default parameters blessed by experts for common use-cases — would be a very good thing.

There are already several cancer drug selection companies like Oncobox, so maybe there should be a company doing this kind of MD for predicting cancer resistance. Maybe there is and I just have not heard of it?

Addendum: modal labs

I have been experimenting with modal labs for running code like this, where there are very specific environment requirements (i.e., painful to install libraries) and heavy CPU/GPU load. Previously, I would have used Docker, which is fundamentally awkward, and still requires manually provisioning compute. Modal can be a joy to use and I'll probably write up a separate blogpost on it.

To do your own simulation (bearing in mind all the failed experiments above!), you can either use my MD_protein_ligand colab or if you have a modal account, clone the MD_protein_ligand repo and run

mkdir -p input && modal run run_simulation_modal.py --pdb-id 3OG7 --ligand-id 032 --ligand-chain A

This basic simulation (including solvent) should cost around 10c on modal. That means we could relax all 5000 protein–ligand complexes in the PDB for around $500, perhaps in just a day or two (depending on how many machines modal allows in parallel). I'm not sure if there's any point to that, but pretty cool that things can scale up so easily these days!

Comment

Last year I wrote a post about computational tools for drug development. Since then quite a lot has happened, especially the appearance of several generative models based on equivariant neural networks for drug design. This article is a sort of update to that post, and also a collection of colabs I have found or developed over the past year or so that can be stitched together to design drugs.

The tools listed here are focused on the earliest stages of drug development. Specifically:

  1. Generate a new molecule or use a virtual screen to find one
  2. Evaluate the molecule's potential as a drug
  3. Synthesize or purchase the molecule


1a. Generate a new molecule

Pocket2Mol: Protein structure → small molecules

Pocket2Mol is one of a new crop of generative models that start with a binding pocket and generate molecules that fit in the pocket. VD-Gen (with animation below) is similar to Pocket2Mol but since it has no code available so I cannot tell if it works.

I created a Pocket2Mol colab that enables easy molecule generation. The input is a PDB file and 3D coordinates to search around. The centroid of a bound ligand in the PDB file can serve as the coordinates. The output is a list of generated molecules. I rank the generated molecules with gnina, a fast, easy to install, and relatively accurate way to measure binding affinity.

ColabDesign: Protein structure → peptide binders

ColabDesign is an extremely impressive project that democratizes a lot of the recent work in generative protein models. As you may guess from the name, ColabDesign — and sister project ColabFold — allow anyone to run them via colab.

For example, even the recent state-of-the-art RFDiffusion algorithm from the Baker lab has been incorporated and made available as an RFDiffusion colab.

ColabDesign can generate proteins that conform to a specific shape or reference protein backbone (structure → sequence, i.e., AlphaFold in reverse). It can also generate peptides that can bind to a specific protein.

The same group also developed AfCycDesign, which uses a nice trick to get Alphafold to fold cyclic peptides — an increasingly important drug type, and often an alternative to antibodies. There is an AfCycDesign colab too!

In this animation it is attempting to generate a cyclic peptide covid spike protein binder, as published recently.


1b. Run a virtual screen

gnina: PDB structure + ligand → posed ligand + binding affinity

gnina is the deep-learning–based successor to the extremely popular smina, itself an AutoDock Vina fork. There is a minimal implementation available as a gnina colab. gnina is a successor to smina and appears to be strictly better. gnina can be used for virtual screening and performs very well at that.

PointVS is a new, deep-learning approach. Like many recent methods, it uses an EGNN (equivariant graph neural network). PointVS's performance is impressive, comparable to gnina, but it's unclear which method runs faster. Uni-Dock is a new GPU-accelerated Autodock Vina that claims impressive speed but unfortunately there is no open code.

PointVS and gnina perform comparably

DiffDock: protein structure + ligand → posed ligand

DiffDock is a generative diffusion model with impressive performance. Given a protein and a ligand, DiffDock can try to find the best pose for that ligand. I created a DiffDock colab that runs DiffDock and again ranks the results using gnina.

DiffDock is a pose prediction method and is not designed to do virtual screening per se. It returns a "confidence" score that correlates with smina/gnina affinity.

DiffDock confidence and smina/gnina binding affinities correlate fairly well

As for which algorithm produces superior results, it's unclear, but according to a recent review, gnina comes out ahead.


2. Evaluate molecule properties

SMILES property predictor: molecule → predicted properties

A molecule the binds to a protein has one property necessary to become a drug, but that is far from the only thing that matters. We can also predict a molecule's intrinsic properties using machine learning.

I created a Smiles to properties colab based on chemprop, soltrannet, and SMILES2Caption. Most of the training data is from MoleculeNet. For some reason there was no pre-trained network available so I had to retrain from scratch.

The graphs generated show the predicted properties of your SMILES as compared to FDA-approved drugs (grey bounds). In the example below, acetaminophen appears as the most toxic of the group, as expected.

SwissADME also provides an excellent property prediction service, though anecdotally analyzing proprietary molecules on someone else's server is not commonly done in drug development.

Espaloma Charge: molecule → charge

Espaloma Charge is a standalone part of Chodera lab's Espaloma system. I include it here as they make available a very simple Espaloma Charge colab that will assign charges for your molecule.

HAC-Net: Protein structure + posed ligand → binding affinity

HAC-Net is a new deep learning method specifically designed to estimate protein–ligand binding affinity.

The HAC-Net colab takes as input a protein and posed ligand and returns a dissociation constant (pKd) and a nice pymol image. This method may or may not be more accurate than gnina — I have not attempted to benchmark.


3. Synthesize or purchase molecule

Postera Manifold: SMILES → molecule or building blocks

Postera Manifold is a machine learning tool that helps figure out how to synthesize small molecules. It can supply the building blocks and reactions necessary for synthesis, or there is a "Have PostEra make it for you" button (at least according to their documentation, but I could not find it!) However, usually synthesis of a new small molecule is a custom, CRO-driven process, that could be expensive and take a long time depending on the molecule's complexity.

Biomatik: SMILES → purchasable molecule

For peptides — which are linear, modular molecules — synthesis is much easier. A service like Biomatik (or GenScript, or many others) can supply peptides for as little as $80 per. They can use proteinogenic or non-proteinogenic amino acids, and can cyclize the peptide too.

Small World: SMILES → purchasable molecule

Small world allows you to search for molecules in the largest compound databases: ZINC, Mcule, Enamine REAL... There is also a nice, unofficial Small World Python API.

If you find a close match to your designed molecule, you could evaluaate it to see if it works as a binder, or use it as a starting point for modification.


Orforglipron

As an example of using these tools, I'll use a new GLP-1 agonist, orforglipron, that showed promising results in a phase 2 study published in NEJM just this week.

First, I can generate an image of the protein GLP-1 with a different bound ligand using my pdb2png colab. (PDB:7S15, "Pfizer small molecule bound to GLP-1").

I can look at the molecule and its charges using the Espaloma Charge colab. (Nice image, but to be honest this doesn't mean much to me!)

I can get the molecule's SMILES from pubchem, and search for it using Small World.

orforglipron in Small World: dark green is a match; light green is a mismatch

A little surprisingly, I find a matching molecule that is only two edits from orforglipron in the ZINC20 "for sale" set. It is labeled as orforglipron in MCE and interestingly the text says it was "extracted from a patent". It's unclear to me why it's not an exact match. Most sources charge $2k for 1mg, but there is one source that charges $1k for 5mg.

I can evaluate its properties with SwissADME, and it's interesting to note how far outside the ideal orforglipron is, in terms of size (883 Da!) and predicted solubility.

I can use the DiffDock colab to see how well it might bind to GLP-1

The best binding score I could get after three attempts was a DiffDock confidence of -2 (very unconfident) and a gnina affinity of -6 (poor-to-mediocre affinity). Because this molecule is so large, there are many possible conformers and it may be impossible to adequately sample them adequately. It does at least bind to the same place as the Pfizer small molecule.

When I feed this top pose from DiffDock into the HAC-Net colab, I get a pKd of 11, which is very high affinity.

The tools for drug design are getting very powerful, and colab is a fantastic way to make them widely available and easy to run. Even when I have a command-line equivalent set up, I often find running the colab to be quicker and easier. In theory, Docker provides the same kind of advantages, but it's never quite so easy, as you still have to provision compute, disk, etc. Having easy access to A100's (on the extremely affordable Colab Pro) is not bad either.

Comment
Brian Naughton | Sat 25 February 2023 | biotech | biotech machine learning ai


By now most people have seen what Chat-GPT / GPT-3 can do. It's an amazing tool, but it has a loose affiliation with the truth. This makes it great for anything creative like generating ideas or filler text, but less useful if you are trying to search for information.


(left) What Chat-GPT thinks PDB id 1A00 is (right) What PDB id 1A00 actually is

Tools like GPT Index (now LlamaIndex) allow you to add additional text to augment GPT-3. This leads to the obvious idea: what if you could create a custom knowledge-base for your lab or biotech, indexing all scientific papers, assay results, and written communications. This could be an extremely powerful tool for scientists to access insitutional knowledge, find buried information, etc.

You can get GPT Index running very quickly by following the quickstart. However, for me, trained on scientific papers, it performed worse than vanilla Chat-GPT, even for facts directly addressed in the corpus.

Paper QA

GPT Index is a powerful, but general tool. For our purposes, Andrew White's Paper QA improves upon it by adding the important concept of citations. Citations turn out to be extremely useful for keeping the model honest, and identifying the source of the information for follow-up or verification.

There are two main ways of using this tool:

  1. Automatically search for papers relevant to your question (e.g., on Google Scholar), index those papers, and respond (as Andrew White does)
  2. Index a large corpus of all papers relevant to your lab or biotech once, and respond referencing that corpus

Here, I attempt to get option 2 working. I took a set of 200 scientific papers, indexed them, and tested the answers compared to Chat-GPT.

Results

It's difficult to quantify the results here, but compared to Chat-GPT, Paper QA was less verbose (sometimes good, sometimes bad), less prone to invention, and had explicit citations. Sometimes Paper QA even usefully responds with "I cannot answer".

Trained on Cell Biology By The Numbers, it does a pretty good job of answering, and giving the relevant page numbers. However, the answers are far from perfect, and include some incorrect statements like "3 million genes in the human genome". (Maybe it is dividing the size of the human genome by the size of the "typical protein"?) Chat-GPT gives more detailed answers, but some of the details are strange, and though the formulas are right, the calculations are off by an order of magnitude (twice!).


(left) Paper QA vs (right) Chat-GPT

Answer from book.bionumbers.org


(left) Paper QA vs (right) Chat-GPT

Answer from book.bionumbers.org

Issues

All of this stuff is very new, so there are limitations.

  • The system as implemented costs around 15c per query. Not terrible, but if you had hundreds of users you'd have to pay attention to costs.

  • Even with the addition of citations, it is still prone to fabulation, just like Chat-GPT.

  • Chat-GPT can often produce results that feel more complete, depending on the type of question. Additionally, you can correspond with Chat-GPT, asking follow-on questions or clarifications.

  • You cannot index e.g., your Slack history or your proprietary databases yet, since OpenAI will retain access to all uploaded text. Once an open-source language model emerges (actually open, not pretend open like LlaMa), the addition of this kind of data could make the search really interesting though — we could even ask questions about results stored in the database!

Conclusions

The system works well on certain types of tasks:

  • If you read something a while back, and want to remind yourself what it was and where you read it
  • If you want a very short summary / answer on some topic referenced in the corpus, and you are willing to check the reference to validate

Overall, this seems like a great tool for searching a library of PDFs, though anecdotally, the performance may degrade somewhat as you add papers (e.g., to get a summary of one paper, it may be better to index only that paper.) I can see using the tool routinely, but the next stage, where we index everything anyone has typed, read, or generated in an organization could be where things get very exciting. Or maybe we just go full multimodal and learn a language model for all of life!

Code

You can easily create your own scientific paper knowledge-base with the following code.

For simplicity, I make the citation derive from the filename of the PDF, with all PDFs ending in _[Authorname]_[Year].pdf. (Note Authorname must be capitalized for Paper QA!) You could also use Zotero's bibliography output or similar.

index_pdfs.py

'''
Script to index a directory of PDFs for GPT queries
You need an OpenAI API key to run it.
Register and get a key at https://platform.openai.com/account/api-keys

Uses https://github.com/whitead/paper-qa
Before running the script, install paper-qa:
```pip install paper-qa```

Then run:
```python index_pdfs.py $PDF_DIR```

The cost to build the index should be around ~1c per paper. It cost me <$2 to index 200 papers.

The code indexes 30 papers at a time by default, since otherwise you may hit usage limits.
You can add to the index by just running `python index_pdfs.py` multiple times,
or just changing the limit.
Please check https://platform.openai.com/account/usage to monitor costs!
'''

from paperqa import Docs
import glob, os, pickle, sys

os.environ["OPENAI_API_KEY"] = ADD_OPENAI_API_KEY_HERE
PKL = "pdf_index.pkl"
MAX_PAPERS_PER_RUN = 30

pdfs = glob.glob(f"{sys.argv[1]}/*.pdf")

if os.path.exists(PKL) and os.path.getsize(PKL) > 0:
    with open(PKL, "rb") as f:
        docs = pickle.load(f)
else:
    docs = Docs()

papers_added = 0
for pdf in pdfs:
    citation = ' '.join(pdf.split('.')[-2].split('_')[-2:])

    if os.path.basename(pdf) in [os.path.basename(f) for f in docs.docs.keys()]:
        continue

    print(f"Indexing {citation} {pdf}")
    try:
        docs.add(pdf, citation)
        papers_added += 1
        if papers_added >= MAX_PAPERS_PER_RUN:
            break
    except Exception as e:
        print("ERR", e, pdf)

with open(PKL, "wb") as f:
    pickle.dump(docs, f)

query_pdfs.py

'''
Script to ask questions of your indexed PDFs using GPT.

Run, e.g.:
```python query_pdfs.py What is the largest mammal?```
'''

from paperqa import Docs
import os, pickle, sys

os.environ["OPENAI_API_KEY"] = ADD_OPENAI_API_KEY_HERE
PKL = "pdf_index.pkl"

with open(PKL, "rb") as f:
    docs = pickle.load(f)

question = ' '.join(sys.argv[1:])

answer = docs.query(question)

print(answer)
Comment

Computational tools for drug development

Read More
Brian Naughton | Sat 30 October 2021 | biotech | biotech

Some notes on setting up data infrastructure for a new biotech.

Read More

DNA sequencing at home using Oxford Nanopore's new flongle sequencer.

Read More

A review of the amyloid hypothesis in Alzheimer's and some recent drug trials.

Read More
Brian Naughton | Mon 11 September 2017 | biotech | biotech vc

A brief look at Y Combinator's biotech investments in 2017.

Read More

Some notes on drug development: classes of drug targets and therapies.

Read More

How to automate protein synthesis pipeline using transcriptic and snakemake

Read More

Boolean Biotech © Brian Naughton Powered by Pelican and Twitter Bootstrap. Icons by Font Awesome and Font Awesome More