Skip to main content

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 perceiveConn function

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bosolver-0.1.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bosolver-0.1-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

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

Hashes for bosolver-0.1.tar.gz
Algorithm Hash digest
SHA256 48a79c92b969b11756972aefb44b032111f5ff4ec6d0e7496592b43972f3a970
MD5 ce3a28c977bfdea9b4ee9dd487f7e02a
BLAKE2b-256 b4089a789c01d9bd4bd9c3604ff7fa151c77f576f14bebc970ed70e86bba3e58

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosolver-0.1.tar.gz:

Publisher: python-publish.yml on DOCH-2/BOSolver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for bosolver-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2dc3371cac9fed85be1c3651727127ed291f47c9290493ac773c4be325478154
MD5 992e5117e1d0fdb39376bca93816fa9e
BLAKE2b-256 1a373ca28173db64995ef9452ee548dfbf93478f7daaf2c0e6c2e1e32f8a9ebb

See more details on using hashes here.

Provenance

The following attestation bundles were made for bosolver-0.1-py3-none-any.whl:

Publisher: python-publish.yml on DOCH-2/BOSolver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page