⚗️ Dimorphite-DL
A fast, accurate, and modular open-source program for enumerating the ionization states of drug-like small molecules over a user-specified pH range.
⚠️ This repository is a modernized fork of Durrant Lab's original Dimorphite-DL (original article), reworked for easier installation and integration into bigger cheminformatics projects — see CHANGES.md for the full history.
✨ Features
- ⚡ Fast pH-range enumeration — adds/removes hydrogens for any pH window you specify, with a tunable
--pka_precision(number of standard deviations around each predicted pKa). - 🧬 Broad functional-group coverage — alcohols, amides, amines/anilines, azides, carboxyls, guanidines, imides, nitro groups, phosphates/phosphonates (including ATP/NAD-style polyphosphate chains), sulfates/sulfonates/sulfonamides, thiols, indoles/pyrroles, aromatic nitrogens, and more.
- 🖥️ CLI and 🐍 Python API — run it as a
dimorphitecommand, or calldimorphite_dl.run(...)directly from your own scripts. - 📄 Flexible input — SMILES from the command line, an
.smifile, or a Python SMILES string / RDKitMolobject (or list of either). - 🏷️ Optional state labeling — tag each output SMILES as
PROTONATED,DEPROTONATED, orBOTH. - 🛡️ Bounded output —
--max_variantscaps the number of protonation variants generated per input compound. - ✅ Modern tooling —
pyproject.tomlpackaging, apytesttest suite,rufflinting/formatting, and CI across Linux/macOS/Windows × Python 3.11-3.13.
✍️ Copyright and Citation Notice
Olivier J. M. Béquignon is neither the copyright holder of the original Dimorphite-DL algorithm nor responsible for it. This repository packages and modernizes Jacob D. Durrant's original work (Apache-2.0 licensed) — see CONTRIBUTORS.md for the original authors.
Citing
If you use Dimorphite-DL in your research, please cite the original publication:
Ropp PJ, Kaminsky JC, Yablonski S, Durrant JD (2019) Dimorphite-DL: An open-source program for enumerating the ionization states of drug-like small molecules. J Cheminform 11:14. DOI: 10.1186/s13321-019-0336-9
📦 Installation
pip install dimorphite-ojmb
Or from source:
git clone https://github.com/OlivierBeq/dimorphite_dl.git
pip install ./dimorphite_dl
🛠️ Requirements
💡 Usage
Command line
usage: dimorphite [-h] [--min_ph MIN] [--max_ph MAX] [--pka_precision PRE]
[--smiles SMI] [--smiles_file FILE] [--output_file FILE]
[--max_variants MXV] [--label_states] [--silent]
Dimorphite 1.2.4: Creates models of appropriately protonated small moleucles.
Apache 2.0 License. Copyright 2020 Jacob D. Durrant.
Options:
-h, --help Show this message and exit.
--min_ph MIN minimum pH to consider (default: 6.4)
--max_ph MAX maximum pH to consider (default: 8.4)
--pka_precision PRE pKa precision factor (number of standard devations,
default: 1.0)
--smiles SMI SMILES string to protonate NOTE: This argument is
mutually exclusive with smiles_file. [required]
--smiles_file FILE file that contains SMILES strings to protonate NOTE:
This argument is mutually exclusive with smiles.
[required]
--output_file FILE output file to write protonated SMILES (optional)
--max_variants MXV limit number of variants per input compound (default:
128)
--label_states label protonated SMILES with target state (i.e.,
"DEPROTONATED", "PROTONATED", or "BOTH").
--silent do not print any messages to the screen
The default pH range is 6.4 to 8.4, considered biologically relevant pH.
dimorphite --smiles_file sample_molecules.smi
dimorphite --smiles "CCC(=O)O" --min_ph -3.0 --max_ph -2.0
dimorphite --smiles "CCCN" --min_ph -3.0 --max_ph -2.0 --output_file output.smi
dimorphite --smiles_file sample_molecules.smi --pka_precision 2.0 --label_states
Python API
import dimorphite_dl
# Using the dimorphite_dl.run() function, you can run Dimorphite-DL exactly as
# you would from the command line. Here's an example:
dimorphite_dl.run(smiles="CCCN", min_ph=-3.0, max_ph=-2.0)
# One can also provide multiple SMILES at once.
dimorphite_dl.run(["C[C@](F)(Br)CC(O)=O", "CCCCCN"], min_ph=5.0, max_ph=9.0, silent=True)
RDKit Mol objects are accepted too, either on their own or in a list:
from rdkit import Chem
mol = Chem.MolFromSmiles("CCCN")
dimorphite_dl.run(mol, min_ph=-3.0, max_ph=-2.0, silent=True)
dimorphite_dl.run([mol], min_ph=-3.0, max_ph=-2.0, silent=True)
Running the tests
From a source checkout:
pip install -e ".[test]"
pytest
⚠️ Caveats
Dimorphite-DL deprotonates indoles and pyrroles around pH 14.5. But these substructures can also be protonated around pH -3.5. Dimorphite does not perform the protonation.
📄 License
This project is licensed under the Apache 2.0 License - see the LICENSE.txt file for details.
📚 API Documentation
def run(smiles, min_ph=6.4, max_ph=8.4, pka_precision=1.0, max_variants=128, label_states=False, silent=False):
Runs Dimorphite-DL protonation on one or more molecules.
Parameters
- smiles : str | Chem.Mol | list[str] | list[Chem.Mol]
A SMILES string, an RDKit
Molobject, or a list of either, to protonate.Nonereturns[None]. - min_ph : float
Minimum pH to consider (default:
6.4). - max_ph : float
Maximum pH to consider (default:
8.4). - pka_precision : float
pKa precision factor — number of standard deviations around each predicted pKa to consider (default:
1.0). - max_variants : int
Limit on the number of protonation variants generated per input compound (default:
128). - label_states : bool
If
True, each result becomes a(smiles_list, state)tuple, wherestateis"PROTONATED","DEPROTONATED","BOTH", a list thereof (one per site), orNoneif the molecule has no ionizable site. - silent : bool Suppress the citation banner and warning messages.
- return_type : list
One entry per input molecule, in the same order: a SMILES string (or
(smiles_list, state)tuple iflabel_states=True), orNoneif the molecule could not be parsed.
👥 Authors and Contacts
See the CONTRIBUTORS.md file for a full list of original contributors. Please contact Jacob Durrant (durrantj@pitt.edu) with any questions about the original algorithm, or open an issue for questions about this fork.
Metadata
Release files for dimorphite-ojmb 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dimorphite_ojmb-1.3.0.tar.gz | 29.0 kB | Without provenance | Details for dimorphite_ojmb-1.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dimorphite_ojmb-1.3.0-py3-none-any.whl | Python 3 | none | any | Details for dimorphite_ojmb-1.3.0-py3-none-any.whl |
Total release size: 53.0 kB
Release files / dimorphite_ojmb-1.3.0.tar.gz
| Download URL | dimorphite_ojmb-1.3.0.tar.gz |
|---|---|
| Size | 29.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f2188c1942b340db07d457d818bb9c54e933ba2388ad5348a5e07ecdbcd83e0
|
|
BLAKE2b-256 checksum How to use checksums |
50f4b0b637cfc62393ae44f4cdd59cb33794f5fb42934c4fab2c3bf58781abf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Release files / dimorphite_ojmb-1.3.0-py3-none-any.whl
| Download URL | dimorphite_ojmb-1.3.0-py3-none-any.whl |
|---|---|
| Size | 24.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
837f9e2bb202298041b8ce05cc92db805248161121d3b893ee8e14cdbaac9d12
|
|
BLAKE2b-256 checksum How to use checksums |
ed22afc480716d9f3f624e026e7135dc422c621816c53045750ce6096d4805ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.3
|
Security for dimorphite-ojmb 1.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.