| # TopG API — brief for another agent |
|
|
| Everything needed to call the TopG structure generator. Self-contained: paste this whole file. |
|
|
| ## What it does |
|
|
| TopG takes a **coordination query** — a description of each inequivalent metal site's local |
| environment — and returns **complete crystal structures**: space group, Wyckoff positions, free |
| coordinates and cell shape. It is a 4.5M-parameter conditional transformer. **No search or |
| refinement is involved; the output is the model's raw emission.** |
|
|
| It generates a **metal sublattice**, not a composition. Element identities in the returned CIF are |
| arbitrary palette entries and carry no chemical meaning. |
|
|
| ## Endpoint and auth |
|
|
| - Space `RGPalgrave/TopG-demo` · base URL `https://rgpalgrave-topg-demo.hf.space` |
| - Endpoint **`/generate`** — use this one. (`/run` is the web page's own button and takes |
| UI-shaped arguments.) |
| - **The Space is private, so every call needs a HuggingFace token** with read access to it. |
| Pass it via the `HF_TOKEN` environment variable; do not hard-code it. |
|
|
| ## Python |
|
|
| ```python |
| import json, os |
| from gradio_client import Client # pip install gradio_client |
| |
| c = Client("RGPalgrave/TopG-demo", token=os.environ["HF_TOKEN"]) |
| r = c.predict(json.dumps({ |
| "sites": [ |
| {"H": "4/mmm", "cs": [4, 2], "ratios": [1.0, 1.15], "orbit_size": 2}, |
| {"H": "mmm", "cs": [2, 4], "ratios": [1.0, 1.02], "orbit_size": 2} |
| ], |
| "n_atoms": 4, "model": "H_pq0", "candidates": 8, "seed": 0, |
| "score": True, "cif": True |
| }), api_name="/generate") |
| r = json.loads(r) if isinstance(r, str) else r |
| ``` |
|
|
| ## curl |
|
|
| POST returns an `event_id`; GET streams the result. |
|
|
| ```bash |
| EV=$(curl -s -X POST "https://rgpalgrave-topg-demo.hf.space/gradio_api/call/generate" \ |
| -H "Authorization: Bearer $HF_TOKEN" -H "Content-Type: application/json" \ |
| -d '{"data":["{\"sites\":[{\"H\":\"m-3m\",\"cs\":[6,12],\"ratios\":[1.0,1.414],\"orbit_size\":4}],\"n_atoms\":4}"]}' \ |
| | python -c "import sys,json;print(json.load(sys.stdin)['event_id'])") |
| curl -s -N "https://rgpalgrave-topg-demo.hf.space/gradio_api/call/generate/$EV" \ |
| -H "Authorization: Bearer $HF_TOKEN" | grep -m1 '^data:' |
| ``` |
|
|
| ## Request fields |
|
|
| | field | required | meaning | |
| |---|---|---| |
| | `sites` | **yes** | one object per *inequivalent* site (below). 1–12 of them | |
| | `n_atoms` | no | metal atoms in the **conventional** cell, 1–192. Defaults to the sum of `orbit_size`. **Orbit sizes must sum to it** — a mismatch is accepted but returns a `warning` and usually few or no structures | |
| | `model` | no | `H_pq0` (default), `H_pq1`, `H_pq2`, `I_full0`, `I_full1`, `I_full2` | |
| | `candidates` | no | beams to draw, default 8. More candidates → more distinct structures, linear cost | |
| | `seed` | no | default 0 | |
| | `score` | no | default `true`; scores each structure against the query. The slow part for large cells. `false` returns `best_rung: null` | |
| | `cif` | no | default `true`; `false` omits CIF text | |
|
|
| Each entry of `sites`: |
|
|
| | field | meaning | |
| |---|---| |
| | `H` | site symmetry, Hermann–Mauguin (table below) | |
| | `cs` | coordination sequence — metal neighbours in each successive shell, e.g. `[4, 2]` | |
| | `ratios` | each shell's distance **relative to the nearest**, so `ratios[0]` is always `1.0` | |
| | `orbit_size` | atoms this site contributes to the conventional cell | |
|
|
| `cs` and `ratios` must be the same length: **1 to 6 shells**. Fewer than 6 is a *partial query* — |
| supported, and easier for the model — but **use an `H_pq` model for it**. `I_full` is trained on |
| full-depth queries only and collapses on short ones (~10% vs ~50% skeleton accuracy). |
| |
| ## Accepted site symmetries (36) |
| |
| Any symmetry may be used in any query; the row says where it actually occurs among the 230 space groups. |
| |
| | system | site symmetries | |
| |---|---| |
| | triclinic | `1` `-1` | |
| | monoclinic | `1` `-1` `2` `m` `2/m` | |
| | orthorhombic | `1` `-1` `2` `m` `2/m` `222` `2mm` `m2m` `mm2` `mmm` | |
| | tetragonal | `1` `-1` `2` `m` `-4` `2/m` `222` `2mm` `4` `m2m` `-42m` `-4m2` `4/m` `422` `4mm` `mmm` `4/mmm` | |
| | trigonal | `1` `-1` `2` `m` `3` `2/m` `-3` `32` `3m` `-3m` | |
| | hexagonal | `1` `-1` `2` `m` `3` `2/m` `222` `2mm` `m2m` `mm2` `-3` `-6` `32` `3m` `6` `mmm` `-3m` `-62m` `-6m2` `6/m` `622` `6mm` `6/mmm` | |
| | cubic | `1` `2` `m` `3` `-4` `2/m` `222` `2mm` `4` `mm2` `-3` `32` `3m` `-42m` `-4m2` `4/m` `422` `4mm` `mmm` `-3m` `23` `4/mmm` `-43m` `432` `m-3` `m-3m` | |
| |
| **Not usable:** `312` `31m` `321` `3m1` `-31m` `-3m1` — these are in the model's vocabulary but occur in no Wyckoff table, so no |
| training example ever contained one. The API rejects them; use the form without the axis suffix |
| (`321`→`32`, `3m1`→`3m`, `-3m1`→`-3m`). |
|
|
| ## Response |
|
|
| ```json |
| {"ok": true, |
| "query": {"n_atoms": 4, "k": 2, "depth": 2, "sites": [...]}, |
| "candidates_built": 8, "distinct_structures": 2, "warning": null, |
| "provenance": {"model": "H_pq0", "tokenizer_fingerprint": "e1db473d06e14c82", |
| "device": "cpu", "note": "pure model output; no search or refinement"}, |
| "structures": [ |
| {"rank": 1, "space_group": 139, "crystal_system": "tetragonal", |
| "orbits": "2a 2b", "cell_shape": "c_over_a=1.4714", |
| "best_rung": "r0_2sh_noratio", "times_drawn": 6, "cif": "# generated using pymatgen..."} |
| ]} |
| ``` |
|
|
| Errors never raise — they return `{"ok": false, "error": "..."}`, with `expected` carrying the |
| schema when the payload was malformed. |
|
|
| - `structures` are **deduplicated** and ranked: scored hits first, then by `times_drawn`. |
| - `times_drawn` is how many of the `candidates` beams produced that same structure — a rough |
| confidence signal, not a probability. |
| - `cell_shape` lists only the **free** shape parameters of the crystal system (cubic none; |
| tetragonal/trigonal/hexagonal `c_over_a`; orthorhombic 2, monoclinic 3, triclinic 5). |
| **No absolute length is emitted** — a scale-free query cannot determine one, so the CIF's absolute |
| cell size is a placeholder and only ratios are meaningful. |
| - The **CIF is written in P1** with every atom explicit, so the file says `P 1` while `space_group` |
| gives the real symmetry. The symmetry is in the coordinates. |
|
|
| ## `best_rung` — how well a structure answers the query |
| |
| Nested criteria, each stricter than the last. `null` means it passed none. |
| |
| | rung | shells checked | distance tolerance | |
| |---|---|---| |
| | `r0_2sh_noratio` | 2 | ignored | |
| | `r1_3sh_noratio` | 3 | ignored | |
| | `r2_3sh_t04` | 3 | 4% | |
| | `r2a_3sh_t08` | 3 | 8% | |
| | `r5_6sh_noratio` | 6 | ignored | |
| | **`r3_6sh_t04`** | **6** | **4%** — the project's historical criterion | |
| | `r3a_6sh_t08` | 6 | 8% | |
| | `r3b_6sh_t15` | 6 | 15% | |
| |
| ## How much to trust the output |
| |
| Measured on a frozen, skeleton-disjoint evaluation set; pure model, no search: |
| |
| - The **discrete** answer (space group + Wyckoff labels + N) is exactly right **~54–59%** of the time. |
| - The **geometry** meets the strict `r3_6sh_t04` criterion **~2–3%** of the time, and essentially |
| never above ~9 free parameters. **Treat returned coordinates as a starting point, not an answer.** |
| - A *perfect* model would score **95.67%**, not 100% — that is the emission grid's own ceiling. |
| - A structure passing no rung still answers the query approximately; `best_rung` says which |
| criterion it actually meets. |
|
|
| ## Gotchas |
|
|
| - **`seed` reproduces within one deployment, not across environments.** The same seed on this Space |
| and on a local checkout gives the same structures but different draw counts, because the Python |
| and torch builds differ. Do not use `seed` as a portable identifier. |
| - **The first call after the Space wakes is slow** — it downloads the checkpoint once, then caches. |
| A small query (N ≤ 8, 8 candidates) then takes a few seconds. |
| - Cost grows with **cell size**, not with hardware; the model is too small for a GPU to help. |
| For N > 40 send `"score": false`. |
| - Sites are **inequivalent sites, not atoms**: `k` is the number of orbits, `n_atoms` the number of |
| atoms, and `orbit_size` links them. |
|
|
| Model card: `RGPalgrave/TopG` · code and full record: <https://github.com/rgpalgrave/TopG> |
|
|