Metadata-Version: 2.4
Name: matsyngate
Version: 0.1.0
Summary: Gatekeeper for the experimental synthesizability of inorganic crystals
Project-URL: Homepage, https://github.com/jwchen25/matsyngate
Project-URL: Documentation, https://matsyngate.readthedocs.io/
Project-URL: Repository, https://github.com/jwchen25/matsyngate
Author-email: Junwu Chen <junwu.chen@epfl.ch>
License-Expression: MIT
License-File: LICENSE
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Chemistry
Requires-Python: <3.14,>=3.10
Requires-Dist: monty>=2024.1.1
Requires-Dist: numpy>=1.24
Requires-Dist: pymatgen>=2024.1.1
Requires-Dist: smact>=2.6
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
Requires-Dist: mkdocstrings[python]>=0.27; extra == 'docs'
Provides-Extra: mp
Requires-Dist: mp-api>=0.41; extra == 'mp'
Provides-Extra: pandas
Requires-Dist: pandas>=2.0; extra == 'pandas'
Description-Content-Type: text/markdown

<div align="center">

<img src="docs/assets/logo-light.svg#gh-light-mode-only" alt="matsyngate — Material Synthesis Gatekeeper" width="360">
<img src="docs/assets/logo-dark.svg#gh-dark-mode-only" alt="matsyngate — Material Synthesis Gatekeeper" width="360">

[![CI](https://github.com/jwchen25/matsyngate/actions/workflows/ci.yml/badge.svg)](https://github.com/jwchen25/matsyngate/actions/workflows/ci.yml)
[![Docs](https://readthedocs.org/projects/matsyngate/badge/?version=latest)](https://matsyngate.readthedocs.io/en/latest/)
[![Python](https://img.shields.io/badge/python-3.10--3.13-blue.svg)](pyproject.toml)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)

</div>

**Mat**erial **Syn**thesis **Gate**keeper — a Python library for evaluating the
experimental synthesizability of inorganic crystals via hard chemical rules.

`matsyngate` is a strict filtering layer for theoretical and AI-generated crystal
structures. A rule earns "hard gate" status only if violating it means the
material cannot be made *no matter how the temperature and dwell time are tuned*.
"Difficult but precedented" is deliberately out of scope: this package answers a
binary question, not a graded one.

**Documentation: <https://matsyngate.readthedocs.io/>** — installation, a full
walkthrough, every threshold with its source, and the API reference.

## Installation

```bash
uv add matsyngate                 # runtime
uv add 'matsyngate[mp,pandas]'    # + G10 (Materials Project) and DataFrame output
```

Development:

```bash
git clone <this repo> && cd matsyngate
uv sync --extra dev
uv run pytest
```

## Quick start

```python
import matsyngate as msg

result = msg.screen(structures, config=msg.SolidStateConfig(n_max=5))

result.passed              # numpy bool mask, aligned with the input
result.n_passed
result.rejection_counts()  # {"G6": 412, "G5": 88, ...}
result[7].verdicts["G6"].reason
result.to_jsonl("screened.jsonl")
```

`structures` may hold `pymatgen` `Structure` objects, `Composition` objects, or
formula strings. Rules that need a structure report `SKIPPED` for the latter two,
and `SKIPPED` never rejects.

Screening repeatedly — inside an RL loop, say — reuse one `Screener` so the
process pool is built once:

```python
with msg.Screener(config=msg.SolidStateConfig.project(), n_jobs=16) as screener:
    for batch in batches:
        mask = screener.screen(batch).passed
```

## The solid-state route

Ten hard rules for conventional ceramic synthesis in an open-air box furnace —
see [the full documentation](https://matsyngate.readthedocs.io/en/latest/solid-state/)
for every threshold, its source, and where it deviates from the reference
implementation it is built from.

| id | rule | tier | rejects |
|---|---|---|---|
| G1 | structure validity | A | overlapping atoms, absurd cell volume |
| G2 | charge and electronegativity validity | A | compositions with no charge-neutral, Pauling-consistent assignment |
| G3 | element blacklist | A | radioactive, exceedingly rare and toxic elements |
| G4 | element count | A | fewer than 3 or more than `n_max` elements |
| G5 | target family | A | non-oxide anion sublattices, and anion groups that decompose below the firing floor |
| G6 | air-accessible oxidation states | A | cations in states that need Ar, H₂ or flowing O₂ |
| G7 | volatility floor | A | elements whose oxides are gone below 600 °C |
| G8 | precursor availability | A | targets no balanced reaction from the available inventory can reach |
| G9 | metastability ceiling | B | E_hull above 0.10 eV/atom |
| G10 | air stability | C | targets predicted to react with O₂, CO₂ or H₂O at firing conditions |

Tier A is offline and needs only composition and structure. G9 activates when you
pass `e_hull=[...]`; G10 when you pass `mp_api_key=...`. Anything not evaluated is
listed in `result.skipped_rules`, so a Tier A screen can never be mistaken for a
full ten-rule one.

## Validation

Against A-Lab's 58 attempted targets (Szymanski et al., *Nature* **624**, 86
(2023); 41 reported successes, 17 failures), under `SolidStateConfig.alab()`:
**41/41 experimental successes retained**, **3 of 17 failures rejected** (all by
G6), precision **75%** versus A-Lab's own 71%. Full numbers, the element-count
sweep, and what this test does and does not measure:
[Validation against A-Lab](https://matsyngate.readthedocs.io/en/latest/solid-state/validation/).

## Known limitations

Reaction kinetics are not modelled at all — 11 of A-Lab's 17 failures were
attributed to slow kinetics, and no rule here can catch that failure mode. Five
more, plus the rare-earth/heavy-metal exclusion's effect on recall, are detailed
in [Known limitations](https://matsyngate.readthedocs.io/en/latest/about/limitations/).

## Provenance

Every threshold is traceable to its source in the docstring of the rule that uses
it, and in the corresponding page under
[The solid-state route](https://matsyngate.readthedocs.io/en/latest/solid-state/).
The design and the literature basis are in
`docs/superpowers/specs/2026-08-07-matsyngate-solidstate-batch-design.md`;
[Extending matsyngate](https://matsyngate.readthedocs.io/en/latest/extending/)
explains how to implement a second route.
