Chemically-intuitive-descriptors is a fully automated hybrid quantum chemistry (QM)-based machine learning (ML) workflow that computes the CM5 atomic charges and steric descriptors for carbon and hydrogen in unique C-H bonds of molecules. Chemically-intuitive-descriptors includes an atom-based machine learning model (ML) to predict the site of reaction at C-H. The ML model (LightGBM classification model) is based on electronic features (CM5 atomic charges & pKa) and various steric features that are computed using semiempirical tight binding (GFN1-xTB) and Morfeus.
For more, see Chemically Intuitive Descriptors for Predicting C–H Borylation Regioselectivity
TBD
We recommend using uv to get the required dependencies. To install uv, see Installing uv, e.g. curl -LsSf https://astral.sh/uv/install.sh | sh
Then go to the project folder and do:
uv sync# in sasa.py under the class SASA and the function _calculate, insert around line 127
self.atom_volumes = {atom.index: atom.volume for atom in self._atoms}# In calculators.py line 62, there is a typo. Therefore, replace:
polarizabilities = properties["polarizibilities"]
# With:
polarizabilities = properties["polarizabilities"]We recommend downloading the precompiled binaries for the latest version of xTB (v. 6.7.1)
mkdir dep; cd dep; wget https://github.com/grimme-lab/xtb/releases/download/v6.7.1/xtb-6.7.1-linux-x86_64.tar.xz; tar -xvf ./xtb-6.7.1-linux-x86_64.tar.xz; mv xtb-dist xtb-6.7.1; cd ..If you have xtb installed in ~/bin, you can do:
mkdir dep; ln -s ~/bin/xtb-dist/ dep/xtb-6.7.1If this does not work for your system, xTB can also be installed through conda or brew
conda install -c conda-forge xtb brew tap grimme-lab/qc
brew install xtbFor more information, please see:
- https://grimme-lab.github.io/workshops/page/xtb
- https://xtb-docs.readthedocs.io/en/latest/setup.html
The prediction tool can predict which C-H bond in a molecule a reaction is likely to occur based on:
- Steric descriptors (buried volume, SASA, etc.)
- Electronic descriptors (pKa, CM5 charges)
- Machine learning models trained on experimental data
# easiest way
uv run cheminit-run
# a wrapper for predict_reaction_site.py
sh predict.sh
# Use custom config
run cheminit-run --config config/predict_reaction_sites.yaml# Predict reaction site for a single molecule
uv run src/cheminit/predict_reaction_site.py \
--smiles "CCO" \
--name "ethanol"
# Use specific model
uv run src/cheminit/predict_reaction_site.py \
--smiles "c1ccccc1O" \
--name "phenol" \
--model "full_models_top2cat/model_all_features_24_features"# Configuration
--config, -c Path to config YAML file (default: config/predict_reaction_sites.yaml)
# Single SMILES mode
--smiles, -s SMILES string for single molecule
--name, -n Molecule name (default: "molecule_1")
# Overrides (override config file settings)
--model, -m Model path (e.g., "full_models_top2cat/model_name")
--output, -o Output directory path
--input, -i Input dataset pathThe config file (config/predict_reaction_sites.yaml) controls all aspects of the prediction:
# Model settings
model:
model_dir: "full_models_top2cat" # Model directory in models/
model_name: "model_all_features_24_features" # Model filename (without extension)
model_type: "joblib" # "joblib" or "txt" (for LightGBM)
# Feature selection
feature_mode: "manual" # "manual", "predefined", or "auto"
# For manual mode: specify features explicitly
manual_features:
steric:
- "atom_v_bur_3_5_Cs"
- "atom_area_sasa_Cs"
# ... more features
electronic:
- "lst_pka_pred_nshell3"
- "cm5_CH_Cs"
# For predefined mode: use a predefined set
predefined_features: "Chemist_selection"
# Paths
paths:
input_dataset: "tests/test_dataset.json.gz"
output_dir: "data/results/predictions"
# Processing
processing:
n_shells: 3 # or 6 depending on pKa model
prediction_threshold: 0.5
# Visualization
visualization:
generate_svg: true
img_size: [300, 300]predictions/
├── [folder name 1]/
│ ├── predictions_full.json.gz # Full predictions with all data
│ ├── predictions_summary.json # Summary (names, SMILES, predicted sites)
│ ├── molecule_name_predicted_sites.svg # Visualizations
├── [folder name 2/
└──
[
{
"names": "val11",
"smiles": "O=C(Oc1ccc2C(=O)COc2c1)c3cccs3",
"lst_atomindex": [1, 2, ..., 10, ...],
"lst_proba": [0.1, 0.4, ..., 0.95, ...],
"atomindex_pred": [4, 9],
"atommap_pred": [5, 10],
"v_bur_frac_3_5_Cs_pred":[0.45, 0.55],
"v_bur_frac_3_5_Hs_min_pred":[0.36, 0.44],
"pka_pred":[33.1,38.8]
}
]uv run src/cheminit/scripts/prep_substrate_descriptors.py --config config/prep_substrate_descriptors_test.yaml
uv run src/cheminit/scripts/prep_lsfml_dataset.py --config config/prep_lsfml_dataset_test.yaml
uv run src/cheminit/scripts/compute_ligands.py --config config/compute_ligands_test.yaml
uv run src/cheminit/ml/train_full_models.py --config config/ml_experiments/train_full_models.yamlAll additionl data can be found here
Here the data is split into three folders: data, models and results. The description for each folder is found below:
| Folder | Description |
|---|---|
data |
Includes all datasets. The data is split into raw, interim, and processed. See README.md in data. Each .json.gz contains a pandas DataFrame that can be loaded using the following command pd.read_json({'dataset name'}, orient='records', compression='gzip'). |
models |
Includes all models. See README.md in models for more information. |
results |
Includes all the results. See README.md in results for more information. |