Metadata-Version: 2.3
Name: bindtools
Version: 0.2.2
Keywords: chemistry,analytical chemistry,binding constants,supramolecular
Author: Martin Peeks
Author-email: Martin Peeks <martinp23@googlemail.com>, m.peeks@unsw.edu.au
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Dist: arviz==0.21.0
Requires-Dist: corner==2.2.3
Requires-Dist: emcee==3.1.6
Requires-Dist: h5py>=3.14.0
Requires-Dist: lmfit==1.3.3
Requires-Dist: matplotlib==3.10.7
Requires-Dist: numba>=0.65.1
Requires-Dist: numpy>=2.3.4
Requires-Dist: openpyxl>=3.1.5
Requires-Dist: pandas>=2.3.3
Requires-Dist: scipy==1.16.3
Requires-Dist: tqdm==4.66.3
Requires-Dist: uncertainties==3.2.3
Requires-Python: >=3.12
Project-URL: Homepage, https://github.com/martinp23/bindtools
Project-URL: Documentation, https://readthedocs.org
Project-URL: Repository, https://github.com/martinp23/bindtools.git
Project-URL: Issues, https://github.com/martinp23/bindtools/issues
Description-Content-Type: text/markdown

# bindtools

[![PyPI version](https://badge.fury.io/py/bindtools.svg)](https://badge.fury.io/py/bindtools)
[![Python Version](https://img.shields.io/pypi/pyversions/bindtools.svg)](https://pypi.org/project/bindtools/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

`bindtools` is a Python library for supramolecular chemistry designed for modeling, fitting, and analyzing binding equilibria. It provides numerical and analytical solvers for complex chemical systems, robust parameter optimization, and Bayesian parameter estimation.

---

## Features

- **Speciation Solvers**: 
  - **Numerical**: A Newton-Raphson solver (`DoNR` and `getConcs`) JIT-compiled with `numba` for fast operation.
  - **Analytical**: High-speed analytical solvers for common topologies (e.g., `1:1`, `1:2`, `2:1` fast exchange).
- **Flexible Optimization**:
  - Uses `lmfit` to manage model parameters (binding constants, physical observables).
  - Handles various experimental data including NMR integrations, chemical shifts (NMR `deltaH`/`deltaF`), and linear concentration-weighted observables (UV-vis / fluorescence).
- **Bayesian Inference & Uncertainty Quantification**:
  - Uses `emcee` for Markov Chain Monte Carlo (MCMC) sampling.
  - Generates trace/chain convergence plots and corner plots using `corner` and `arviz`.
  - MCMC runs can be serialized and stored as HDF5 files for future analysis.

---

## Installation

`bindtools` is available on PyPI. You can install it directly using `pip`:

```bash
pip install bindtools
```

### Using Conda / Mamba (Recommended for Virtual Environments)

To avoid dependency conflicts, you can set up a dedicated environment with Conda/Mamba and install `bindtools` inside it:

```bash
# 1. Create and configure environment with base scientific dependencies
mamba create -n binding -c conda-forge \
  python jupyter tqdm ipython uncertainties lmfit scipy numpy emcee tqdm numba corner matplotlib numdifftools

# 2. Activate the environment
conda activate binding

# 3. Install bindtools via pip
pip install bindtools
```

---

## Quick Start

### 1. Speciation (Solving Concentration Problems)

You can compute the equilibrium concentration of free species (components and complexes) given initial total concentrations, a stoichiometry matrix, and equilibrium constants ($K$ values).

```python
import numpy as np
from bindtools import binding as bd

# Define total concentrations: 50 data points of Host (1e-3 M) and Guest (0 to 1e-2 M)
component_concs = np.zeros((50, 2))
component_concs[:, 0] = 1e-3
component_concs[:, 1] = np.linspace(0, 1e-2, 50)

# Stoichiometry / Equilibrium Matrix
# Row 0: Host balance, Row 1: Guest balance
# Columns represent: [Free Host, Free Guest, Host-Guest Complex (1:1)]
eq_mat = np.array([
    [1, 0, 1],  # [H]_tot = [H] + [HG]
    [0, 1, 1]   # [G]_tot = [G] + [HG]
])

# log10(K) values for each species. 
# Constants for free components are fixed at logK = 0.
# The complex (HG) has logK = 4 (K = 10,000 M^-1).
logK = np.array([0, 0, 4])

# Solve for concentrations at each point
results = []
for total_concs in component_concs:
    spec_concs = bd.getConcs(eq_mat, total_concs, logK)
    results.append(spec_concs)

results = np.array(results)
print("First point [H, G, HG]:", results[0])
```

---

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
