---
description: List finished materials, export their OPTIMADE-shaped records as one JSON array, and read the fields that matter for ranking and filtering.
---

# Get the results out

Finished materials carry an OPTIMADE-shaped `record.json`. This page is how you
list them, export them, and read the fields you will actually rank on.

## List what finished

```console
$ matmelt results
```

```text
Results of run nacl-demo:
        Finished materials
┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┓
┃ Material     ┃ Parent ┃ Record ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━┩
│ Cl1Na1_3D-6  │ Cl1Na1 │ yes    │
│ Cl1Na1_3D-10 │ Cl1Na1 │ yes    │
│ Cl1Na1_3D-16 │ Cl1Na1 │ yes    │
│ Cl1Na1_3D-25 │ Cl1Na1 │ yes    │
└──────────────┴────────┴────────┘
4 DONE material(s), 4 with extracted record(s).
```

`Record: no` is normal rather than broken — a material can be `DONE` without a
record if the run stopped before `extract`. The store is opened read-only, so
this is safe to run against a workspace that is still being written to.

## Export the records

```console
$ matmelt results --export finished.json
```

```text
Exported 4 record(s) to finished.json.
```

One JSON array, written atomically, with one entry per material:

```text
entries: 4 | keys per entry: ['id', 'record']
record top-level: ['attributes', 'id', 'type']
```

A record that cannot be read is skipped loudly rather than silently dropped, so
the count in the message is the count in the file.

## What is in a record

The standard OPTIMADE fields describe the structure:

```text
chemical_formula_reduced: ClNa
chemical_formula_descriptive: Cl1Na1
nsites: 2
elements: ['Cl', 'Na']
nelements: 2
dimension_types: [1, 1, 1]
last_modified: 2026-08-09T00:53:33+00:00
```

plus `lattice_vectors`, `cartesian_site_positions`, `species`,
`species_at_sites`, `elements_ratios`, `chemical_formula_anonymous`,
`nperiodic_dimensions` and `structure_features`.

Everything MatMelt adds lives under `attributes._mcli`, which is OPTIMADE's
convention for custom fields:

```text
_mcli keys: ['geometry_source', 'provenance', 'screen']
```

`provenance` records how the candidate was generated:

```json
{
  "dimension": "3D",
  "space_group": 6,
  "space_group_symbol": "Pm",
  "lattice_type": "monoclinic",
  "formula": "Cl1Na1"
}
```

`screen` records the relaxation that let it through, including the settings, so
a number is never separated from how it was produced:

```json
{
  "category": "RELAXED",
  "converged": true,
  "n_steps": 160,
  "final": {
    "e_eV": -6.524272949937968,
    "e_eV_atom": -3.262136474968984,
    "fmax_eV_A": 0.007047402896295252,
    "stress_max_GPa": 0.2323758502727508,
    "volume_A3": 53.97049592754401,
    "min_bond_A": 2.6713578838390584
  },
  "settings": {
    "model": "mace-mp:small",
    "device": "cpu",
    "dtype": "float64",
    "fmax": 0.05,
    "max_steps": 200
  }
}
```

When the optional `calculate` stage ran, a `calculate` key joins them, carrying
the DFTB+ result and the full healing-attempt history.

## Rank the survivors

The relaxed energy per atom is the field to sort on:

```console
$ python3 -c "
import json
records = json.load(open('finished.json'))
rows = sorted(
    (e['record']['attributes']['_mcli']['screen']['final']['e_eV_atom'], e['id'])
    for e in records
)
for energy, mid in rows:
    print(f'{energy:8.4f} eV/atom  {mid}')
"
```

```text
 -3.2621 eV/atom  Cl1Na1_3D-6
 -3.2409 eV/atom  Cl1Na1_3D-16
 -3.2036 eV/atom  Cl1Na1_3D-25
 -2.8984 eV/atom  Cl1Na1_3D-10
```

:::{warning}
Foundation-model energies are a **screening signal**, not converged
thermodynamics. Use them to rank candidates and to throw out the implausible;
do not report them as formation energies. The optional
{doc}`calculate stage <../tutorials/t6-calculate-dftb>` exists for higher
fidelity.
:::

## Filter without exporting

Records also sit in each material's directory under `run.work_dir`, so ordinary
tools work directly:

```console
$ python3 -c "
import json, glob
for path in sorted(glob.glob('materials-work/*/record.json')):
    a = json.load(open(path))['attributes']
    print(a['_mcli']['provenance']['space_group'],
          a['chemical_formula_reduced'],
          round(a['_mcli']['screen']['final']['e_eV_atom'], 4))
"
```

```text
10 ClNa -2.8984
16 ClNa -3.2409
25 ClNa -3.2036
6 ClNa -3.2621
```

Filtering on `_mcli.provenance.dimension` is how you separate 2-D layer-group
results from 3-D ones in a mixed run.

## Machine-readable listing

```console
$ matmelt results --json
```

Same information as the table, as data. `--export` writes the records
themselves; `--json` describes what finished.

## Related

- {doc}`../reference/config` — `dimensions`, and what lands in `provenance`.
- {doc}`../tutorials/t1-first-local-run` — a full run whose survivors are ranked
  the same way.
