File size: 8,076 Bytes
51dd783 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | # 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>
|