# Free-PROTAC molecular dynamics Explicit-solvent MD of a generated PROTAC on its own, with no target protein and no E3 ligase. Runs in chloroform (a membrane-interior mimic) and in water, and measures the conformational descriptors published work ties to cell permeability: radius of gyration, 3D polar surface area, intramolecular H-bonds, and conformational state populations. The protocol follows "Linker-Dependent Folding Rationalizes PROTAC Cell Permeability" (*J. Med. Chem.* 2022, DOI 10.1021/acs.jmedchem.2c00877) and takes its permeability cutoffs from Atilaw et al., *ACS Med. Chem. Lett.* 2021, 12, 107-114. `reference_protocol.md` has the settings and the target numbers. ## Layout ``` protac_md.py MD driver: conformer -> parametrize -> solvate -> replicas analyze_conformations.py Rg / RMSD / 3D PSA / H-bonds / clustering dashboard rg_basins.py Rg free-energy profiles and basin populations psa_ensemble.py 3D PSA over a finished ensemble ternary_span.py warhead-to-E3 span distribution (water ensembles) validate_psa.py PSA code path checked against grazoprevir psa_method_probe.py element vs charge-threshold polar-atom selection plot_results.py per-replica summary figure render_3d.py extended and collapsed conformations from a trajectory run_candidate.sh detached driver: chloroform + water + analysis environment_md.yml conda environment protacmd-lock-linux64.txt pinned environment, linux-64 reference_protocol.md reference protocol and permeability yardsticks linker_design.md linker rules read off this project's own MD runs ``` PROTAC SMILES are embedded in `protac_md.py` (`CANDIDATES`), so no input files are needed; anything else runs through `--smiles`. ## Environment On linux-64 with a CUDA 12 capable driver (525 or newer), use the lockfile and skip dependency solving: ``` conda create --name protacmd --file protacmd-lock-linux64.txt conda activate protacmd pip install "setuptools<81" ``` That reproduces the environment: openmm 8.5.2, ambertools 24.8, rdkit 2025.09.5, openff-toolkit 0.16.10, python 3.10.20. The lockfile carries no `packmol`, which `--solvent chloroform` needs, so add it afterwards (`conda install -c conda-forge packmol`) or solve from the yml instead. Elsewhere, solve from the yml. Check the driver's CUDA version with `nvidia-smi` first and edit `cuda-version` in `environment_md.yml` to match (remove it entirely for CPU-only): ``` conda env create -f environment_md.yml conda activate protacmd ``` The solve takes around ten minutes: ambertools has a large dependency tree and libmamba is single-threaded, so the spinner sits still while one core works. The install itself takes seconds. Keep `setuptools<81` in the `pip:` section rather than as a conda dependency; an upper bound on setuptools triples the solve time. Activation is not optional. `sqm`, `antechamber` and `packmol` are only on PATH inside the env, and calling `/bin/python` directly is not enough. ## Run ``` conda activate protacmd # chloroform: the membrane mimic, the permeability-relevant run python protac_md.py --solvent chloroform --replicas 3 --prod-ns 50 --gpu 0 # water: the polar reference; the pair shows chameleonic folding python protac_md.py --solvent water --replicas 3 --prod-ns 50 --gpu 0 python analyze_conformations.py --dir egfrvhl_rank4/chloroform --name egfrvhl_rank4 python analyze_conformations.py --dir egfrvhl_rank4/water --name egfrvhl_rank4 ``` Useful flags: `--candidate {egfrvhl_rank4,egfrvhl_rank5,brd9vhl_rank1,cdk6crbn_rank2}`, `--smiles ""` with `--name ms39_ref` for a reference compound, `--platform CPU`, `--prod-ns`, `--replicas`, `--gpu N`. Output lands in `//rep/` (`*_prod.dcd`, `*_prod.csv`, PDBs), with the dashboard and the cluster centroid PDBs in `//`. `run_candidate.sh` chains both solvents and both analyses for one candidate and reuses the chloroform charge cache for water, so AM1-BCC is paid once. Smoke test on a new machine first, about two minutes: ``` python protac_md.py --solvent chloroform --replicas 1 --prod-ns 0.05 \ --heat-ps 5 --equil-ps 10 --report-ps 1 --min-iters 1000 --name smoke python analyze_conformations.py --dir smoke/chloroform --name smoke --clusters 4 ``` ## Comparing finished runs These take run directories, one per compound. `ms39_ref` is not bundled: run the pipeline on MS39 yourself with `--smiles ... --name ms39_ref`. Its components and exact linker are in `../src/protac/ErlotinibVHL.py`. ``` python rg_basins.py egfrvhl_rank4 ms39_ref --solvents chloroform water python psa_ensemble.py egfrvhl_rank4 ms39_ref --solvent chloroform python ternary_span.py egfrvhl_rank4 ms39_ref ``` ## Hardware and runtime The system is small, 2500-2800 atoms, so it is GPU-latency-bound rather than memory-bound and fits in under 2 GB of VRAM. | Platform | Speed | 50 ns x 3 x 2 solvents | |---|---|---| | Free A100 | ~1100 ns/day | ~6.5 h | | Shared GPU (~75% busy) | ~32 ns/day | ~9 days | | CPU (16 threads) | ~28 ns/day | ~10 days | A shared GPU is about 35x slower than a free one and no faster than CPU, so use an idle card. Replicas run sequentially in one process; parallelize by launching one process per GPU. The reference converged within 5-10 ns; 50 ns x 3 leaves a wide margin. Confirm with the RMSD plateau and the replica-mean spread in the dashboard, and extend if either is still drifting. ## Known failure modes 1. `ModuleNotFoundError: No module named 'pkg_resources'` at `SystemGenerator`. `openff.amber_ff_ports` imports `pkg_resources`, which setuptools 81 removed. Install `setuptools<81`. 2. `OSError: Packmol not found`, chloroform only. `pack_box` resolves `packmol` through PATH, so the env has to be activated, and so does `sqm` / `antechamber` for AM1-BCC charges. 3. Charge assignment is slow, one to three minutes on a single CPU core, and happens inside `create_system`. Wrapping the run in a short `timeout` kills it mid-charge and leaves a 0-byte `ff_cache.json`. Charges are cached per molecule in `//ff_cache.json`; copying a populated cache in skips the step. 4. Never select the PROTAC by atom name or element. It carries its own Cl, and counterions named `Na`/`Cl` slip past naive regexes, which inflated Rg by about 13%. Every script here selects it by residue instead: the non-water residue with more than 5 atoms. 5. mdtraj mislabels DCD frame times, so `traj.time` is not trustworthy. Derive time from the frame index times `--report-ps`, as the scripts do. ## Scope The simulations show that a generated PROTAC is physically sane and describe its conformational ensemble, extended versus folded, along with the folding-linked permeability descriptors. That is the same scope as the reference work, which also simulates the free PROTAC only. They do not show that a linker works as a degrader. Degradation needs a productive ternary complex of target, PROTAC and E3, which is a different simulation. `ternary_span.py` describes the span a linker can hold, not whether a complex forms. Folding propensity only means something against a baseline, so run the same pipeline on a reference PROTAC (`--smiles ... --name ms39_ref`) alongside each candidate. Yardsticks, from the 2022 MD paper: a compact minimum at Rg 5.4-5.6 A, and 3D PSA 190-265 A^2 for the permeable compounds against 290-330 A^2 for the poorly permeable one. From Atilaw 2021: passive permeability below Rg 7 A, and low-to-moderate permeability up to roughly 200-210 A^2. The 7 A cutoff on its own does not separate the 2022 compounds; see `reference_protocol.md`.