Metadata-Version: 2.4
Name: chemigraph
Version: 1.0.1
Summary: ChemiGraph — a Python library for chemical graph theory: a priori VIF/LPI and EI mass-spectral fragment prediction directly from a molecular structure.
Author: Sinan Gökmen
License: MIT
Keywords: chemical-graph-theory,mass-spectrometry,valency-interaction-formula,quantum-chemistry,cheminformatics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy
Requires-Dist: networkx
Requires-Dist: matplotlib
Requires-Dist: rdkit
Requires-Dist: mendeleev
Requires-Dist: requests

<p align="center">
  <img src="logo.png" alt="ChemiGraph logo" width="260">
</p>

<h1 align="center">ChemiGraph</h1>
<p align="center"><em>A Python Library for Chemical Graph Theory</em></p>

ChemiGraph turns a molecular structure into quantum-chemical insight using only
graph theory and linear algebra. It is a fully automated implementation of the
**Valency Interaction Formula (VIF)** theory — formulated by Oktay Sinanoğlu
(*Theoret. Chim. Acta* **1985**, 68, 251) — and its application to mass
spectrometry by Berkay Sütay (*JOTCSA* **2017**, 4(1), 179).

Give it nothing but a structure (a SMILES string or a PubChem name) and it will:

- build the **VIF graph** of the molecule,
- compute the **Level Pattern Indices (LPI)** = the exact count of bonding,
  nonbonding and antibonding molecular orbitals,
- locate the **soft bonds** (the weakest linkages), and
- predict the principal **electron-impact (EI) mass-spectral fragments** —
  *a priori*, in milliseconds, without any large-scale quantum-chemical
  computation.

---

## Theoretical background

**1. The molecule becomes a graph.** Each atom is drawn as a set of vertices
equal to the size of its valence shell — 1 for H/He, 4 (*s + 3p*) for the second-
and third-row main-group elements, 9 for transition metals. The vertices of one
atom form an *intra-atomic clique* (the hybrid-orbital interactions), and each
chemical bond is an edge joining vertices of neighbouring atoms.

**2. The graph *is* the Hamiltonian.** This picture is exactly the matrix
representation — the adjacency matrix — of the one-electron molecular
Hamiltonian in a **non-orthonormal valence-orbital basis**. Nothing is
approximated away; the graph encodes the same connectivity the operator does.

**3. Reduction = congruence = invariant signature.** Sinanoğlu showed that the
pictorial reduction rules of VIF are **congruence transformations**
(*A → SᵀAS*) of this matrix under the general linear group. By **Sylvester's
law of inertia** (1852), a congruence transformation cannot change the
*signature* — the number of positive, zero and negative eigenvalues. That
invariant is the LPI:

```
LPI = (n+, n0, n-)
      n+  = # positive eigenvalues = bonding molecular orbitals
      n0  = # zero eigenvalues     = nonbonding molecular orbitals
      n-  = # negative eigenvalues = antibonding molecular orbitals
```

So the electronic level pattern of a molecule can be read off its structural
formula alone — no basis-set SCF cycle required.

**4. Soft bonds and mass spectra.** Sütay's insight (2017) is that the
interactions which *cancel* during reduction — the **soft bonds** — are the
chemically weakest linkages, and are precisely the bonds that break first under
70 eV electron impact. Each soft-bond cleavage is a fragment peak in the mass
spectrum.

### What ChemiGraph adds

It reduces Sinanoğlu's hand-drawn calculus directly to numerical linear algebra:

```
LPI(G) = signature of the adjacency matrix of G,  via numpy.linalg.eigvalsh   (O(n³))
```

Soft-bond detection is a **rank-2 perturbation test**: if deleting bond *(i, j)*
leaves the LPI unchanged, that bond would already have vanished during reduction
— so it is soft. A chemically motivated **α-cleavage rule** suppresses
unphysical fragments (e.g. a bare carbonyl oxygen would never leave as atomic
O), and every *m/z* is reported on the **nominal-mass** (most-abundant-isotope)
scale, the mass-spectrometric convention.

The implementation reproduces the reference LPI values of Sinanoğlu (1985) and
the mass-spectral predictions of Sütay (2017) — including the chlorine-
substituted cyclohexanone-oxime of the 2017 paper, for which it returns the
experimental peaks at *m/z* = 35 (Cl), 17 (OH) and 218 (M − OH) exactly.

---

## Worked example — nitrobenzene

```bash
chemigraph nitrobenzene
```

<p align="center">
  <img src="assets/example_graph.png" alt="Nitrobenzene VIF graph" width="46%">
  &nbsp;&nbsp;
  <img src="assets/example_spectrum.png" alt="Nitrobenzene predicted MS" width="52%">
</p>

**Left — the VIF graph.** Every atom is a coloured clique of valence-orbital
vertices; solid black edges are ordinary bonds; **red dashed edges are soft
bonds**. The single soft bond linking the benzene ring to the nitro group is the
C–N bond — LPI = {18, 0, 23}.

**Right — the predicted mass spectrum.** Because the C–N bond is soft, the nitro
group is lost, giving the phenyl cation **C₆H₅⁺ at *m/z* = 77** — the dominant
fragment observed experimentally — alongside the molecular ion M⁺ at 123. This
matches Figure 6 of Sütay (2017).

> Bar heights are schematic: VIF predicts *which* fragments form, not their
> intensities.

---

## Installation

ChemiGraph is distributed as a **pre-compiled package** — one `pip` command
installs it and its five scientific dependencies (`numpy`, `networkx`,
`matplotlib`, `rdkit`, `mendeleev`). Python 3.9+ is required.

```bash
pip install chemigraph
```

`pip` automatically downloads the pre-built binary matching your operating
system (Linux, Windows, macOS) and Python version. Alternatively, grab the wheel
for your platform from the [Releases](../../releases) page and install it
directly:

```bash
pip install chemigraph-1.0.0-<your-platform>.whl
```

> **Windows users:** install Python from <https://www.python.org/downloads/>
> (tick **“Add Python to PATH”** during setup), then open the **Command Prompt**
> (`Win + R` → `cmd` → Enter) and run `pip install chemigraph`. A virtual
> environment (`python -m venv venv && source venv/bin/activate`) is recommended
> on every platform.

---

## Usage

### From the terminal

After installation a `chemigraph` command is available everywhere:

```bash
chemigraph aspirin                 # a molecule name → fetched from PubChem
chemigraph "Clc1ccccc1"            # a raw SMILES string
chemigraph caffeine nitrobenzene   # several molecules in one run
chemigraph                         # no argument → the substituted-halogen demo
```

Each molecule prints its LPI and predicted fragment list, and opens two windows:
the VIF graph and the predicted mass spectrum.

### As a Python library

```python
import chemigraph as cg

# Full analysis from a SMILES string
result = cg.VIF("Clc1ccccc1")           # chlorobenzene
lpi = result["lpi"]
print(lpi["n+"], lpi["n0"], lpi["n-"])  # 15 0 18   (bonding / nonbonding / antibonding)
print(result["mol_mass"])               # 112       (nominal M+)

# Fetch a molecule by name from PubChem
cg.VIF_from_pubchem("nitrobenzene")

# Silent analysis (no plots), inspect the fragments
r = cg.VIF("CC(=O)Oc1ccccc1C(=O)O", draw=False, show_spectrum=False, verbose=False)
for f in r["fragments"]:
    if f["split"]:
        print(f["bond"], "->", [(x[0], x[2]) for x in f["fragments"]])
```

### Interpreting the output

| Field | Meaning |
|-------|---------|
| `lpi` | `{n+, n0, n-}` — counts of bonding / nonbonding / antibonding MOs |
| `mol_mass` | nominal mass of the molecular ion M⁺ (*m/z*) |
| `soft_bonds` | the weak interactions detected by the perturbation test |
| `fragments` | predicted EI fragments; each split gives two `(formula, m/z)` pairs |

---

## References

1. O. Sinanoğlu, *Theoret. Chim. Acta* **1985**, 68, 251.
2. O. Sinanoğlu, *Chem. Phys. Lett.* **1984**, 103, 315.
3. B. Sütay, *J. Turk. Chem. Soc. A* **2017**, 4(1), 179.
