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#
$ matmelt results
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#
$ matmelt results --export finished.json
Exported 4 record(s) to finished.json.
One JSON array, written atomically, with one entry per material:
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:
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:
_mcli keys: ['geometry_source', 'provenance', 'screen']
provenance records how the candidate was generated:
{
"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:
{
"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:
$ 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}')
"
-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 calculate stage exists for higher fidelity.
Filter without exporting#
Records also sit in each material’s directory under run.work_dir, so ordinary
tools work directly:
$ 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))
"
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#
$ matmelt results --json
Same information as the table, as data. --export writes the records
themselves; --json describes what finished.