BOSolver: A Python package for solving Bond Order (and Formal Charge) Assignment based on Integer Linear Programming
Project description
Bond Order Solver utilizing Integer Linear Programming
BOSolver calculates the CORRECT bond orders of bonds between atoms from XYZ file of molecule(s).
Lewis diagram drawing procedure is translated into Integer Linear Programming (ILP), and BOSolver solves the bond order assignment problem EXACTLY when elements of atoms, connectivity, and total charge is provided.
Thanks to the ILP formulation, BOSolver has multiple strength points such as,
- BOSolver can handle complex molecules with multiple resonance structures within definite time.
- BOSolver preserves the total charge of the molecule.
- BOSolver is free from loopholes of heuristics-based methods.
- BOSolver shows, empirically, stable time complexity regardless of cases (worst-case, best-case, and average).
BOSolver relies on RDKit for the molecular representation,
and BOSolver can assign correct bond orders to RDKit.Chem.Mol objects
within a few lines.
Read the usage section for more details.
Installation
Pip
Installation via pip (PyPi) is available.
>>> pip install BOSolver
From source
Installation from source is also possible. Clone the repository and install with pip.
git clone https://github.com/DOCH-2/BOSolver.git
and then run
>>> cd BOSolver # move to the top directory
>>> python -m build
>>> pip install dist/BOSolver.xxx.whl
To check whether the installation is properly done,
you can use pytest. Run pytest at the top directory of the repository.
>>> cd BOSolver # move to the top directory
>>> pytest
Usage
BOsolver requires an .xyz file (or text formatted in xyz) of a molecule (system) and the total charge of the molecule (system).
BOSolver can be used as a command line tool or as a Python package.
as Command Line Tool
bosolve molecule.xyz 0
or pass the content of .xyz file directly
bosolve "$(cat molecule.xyz)" 0
For more details, run bosolve -h
as Python package
To assign bond orders to a rdkit.Chem.Mol object, use BOSolver.bosolve.assignBO
from BOsolver.bosolve import assignBO, perceiveConn
mol = Chem.MolFromXYZFile("molecule.xyz")
chg = 0
# if molecule has no connectivity information, call perceiveConn first
if not mol.GetNumBonds():
mol = perceiveConn(mol)
# if molecule has no connectivity information, then assignBO will raise an error
mol = assignBO(mol, chg)
Notes
- A note on
perceiveConnfunction
Providing the correct connectivity information is crucial for BOSolver to work correctly.
perceiveConn is a function that perceives connectivity information from the atomic coordinates.
Various algorithms can be applied to perceive the connectivity information.
Here is an example of using perceiveConn function using different perception algorithms.
from BOsolver.bosolve import perceiveConn
from BOSolver.utils.coord2adj import BondPerception, CovalentRadius, Simple, BaberHodgkin
mol = Chem.MolFromXYZFile("molecule.xyz")
chg = 0
algo1 = CovalentRadius(relTol=1.1, absTol=0.0) # default
mol = perceiveConn(mol, algo1) # apply CovalentRadius algorithm
algo2 = Simple() # relTol=1.15, absTol=0.0
mol = perceiveConn(mol, algo2) # apply Simple algorithm
algo3 = BaberHodgkin() # relTol=1.0, absTol=0.45
mol = perceiveConn(mol, algo3) # apply BaberHodgkin algorithm
# or define your own algorithm
# refer to the BondPerception class for more details
class MyAlgorithm(BondPerception):
def __init__(self, *args, **kwargs):
super().__init__()
# write your algorithm
# blah blah blah
# blah blah blah
def __call__(self, mol):
# your own algorithm
return mol
Class CovalenRadius and its subclasses has an attribute R_TABLE,
which contains covalent radii of elements.
As you are dealing with specific systems, you might want to adjust the covalent radii of some elements.
from BOSolver.utils.coord2adj import CovalentRadius
algo = CovalentRadius()
algo.R_TABLE[6] = 0.8 # change the covalent radius of Carbon(atomic number 6) to 0.8
- A note on dealing with a system with unknown charge
BOSolver requires the total charge of the system (it does not have to be single molecule) to work correctly.
When the total charge of the system is unknown, you can try any charge values to guess the total charge of the system.
In practice, for a given connectivity, there are only one or two possible charge values that give a valid bond order assignment. So try giving charge values from -2 to 2 to find the correct charge value.
from rdkit import Chem
from BOsolver.bosolve import assignBO
chg_table = [0, 1, -1, 2, 2] # start from small absolute value
candidates = []
mol = Chem.MolFromXYZFile("molecule.xyz")
for chg in chg_table:
try:
mol = assignBO(mol, chg)
Chem.SanitizeMol(mol) # RDkit's SanitizeMol function will check the validity
except:
continue
else:
candidates.append(mol)
Reference
This work is based on the Doctoral thesis of the Dr. Kyunghoon Lee, one of the authors.
Support
If you have any questions or suggestions, open issues or contact Jinwon Lee.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bosolver-0.1.tar.gz.
File metadata
- Download URL: bosolver-0.1.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48a79c92b969b11756972aefb44b032111f5ff4ec6d0e7496592b43972f3a970
|
|
| MD5 |
ce3a28c977bfdea9b4ee9dd487f7e02a
|
|
| BLAKE2b-256 |
b4089a789c01d9bd4bd9c3604ff7fa151c77f576f14bebc970ed70e86bba3e58
|
Provenance
The following attestation bundles were made for bosolver-0.1.tar.gz:
Publisher:
python-publish.yml on DOCH-2/BOSolver
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bosolver-0.1.tar.gz -
Subject digest:
48a79c92b969b11756972aefb44b032111f5ff4ec6d0e7496592b43972f3a970 - Sigstore transparency entry: 189401499
- Sigstore integration time:
-
Permalink:
DOCH-2/BOSolver@b5eaca6c6cb89630fc5cee99134a46e088d818e2 -
Branch / Tag:
refs/tags/v0.1 - Owner: https://github.com/DOCH-2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@b5eaca6c6cb89630fc5cee99134a46e088d818e2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file bosolver-0.1-py3-none-any.whl.
File metadata
- Download URL: bosolver-0.1-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dc3371cac9fed85be1c3651727127ed291f47c9290493ac773c4be325478154
|
|
| MD5 |
992e5117e1d0fdb39376bca93816fa9e
|
|
| BLAKE2b-256 |
1a373ca28173db64995ef9452ee548dfbf93478f7daaf2c0e6c2e1e32f8a9ebb
|
Provenance
The following attestation bundles were made for bosolver-0.1-py3-none-any.whl:
Publisher:
python-publish.yml on DOCH-2/BOSolver
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bosolver-0.1-py3-none-any.whl -
Subject digest:
2dc3371cac9fed85be1c3651727127ed291f47c9290493ac773c4be325478154 - Sigstore transparency entry: 189401503
- Sigstore integration time:
-
Permalink:
DOCH-2/BOSolver@b5eaca6c6cb89630fc5cee99134a46e088d818e2 -
Branch / Tag:
refs/tags/v0.1 - Owner: https://github.com/DOCH-2
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@b5eaca6c6cb89630fc5cee99134a46e088d818e2 -
Trigger Event:
release
-
Statement type: