---
description: Export the DFTB+ relaxed structures with matmelt cif, know which geometry you get, and open the files in ASE, VESTA or OVITO.
---

# Look at a structure

MatMelt has no viewer command — it produces CIF files, and you open them in the
tool you already use. What it does have is `matmelt cif`, which exports the
**DFTB+ relaxed** geometry of materials that went through the optional
`calculate` stage.

## Export the relaxed structures

```console
$ matmelt cif --out-dir ./cifs
```

```text
fetching 1 relaxed geometry from AiiDA...
fetched 1/1 geometry
Run full-remote-run: exported 1 CIF file(s) to ./cifs.
```

Narrow it with `--materials id1,id2` or `--materials-file FILE`. The store is
opened read-only, so this is safe while a run is going on.

Eligible materials are those in `CALCULATED`, `EXTRACTED` or `DONE` **with a
converged `calc_result.json`**. Anything else is skipped with a counted reason
rather than silently omitted. If the config has no `calculate` stage at all, the
command says so instead of producing an empty directory:

```text
cif: this config has no 'calculate' stage, so no material has a DFTB+ relaxed
geometry to export. Add a calculate stage (see 'matmelt init' for a commented
example) and run it first.
```

## Which geometry you get — read this once

There are three different structures for a material, and they are not
interchangeable:

| File | What it is |
|---|---|
| `structure.cif` | The candidate PyXtal generated |
| `relaxed.cif` | After the MACE relaxation in `screen` |
| `matmelt cif` output | After the **DFTB+** relaxation in `calculate` |

The DFTB+ geometry is *not* in `calc_result.json`: that document stores each
healing attempt's **input** parameters, so the geometry embedded there is what
DFTB+ started from. The relaxed result lives in the final calculation's
retrieved `geom.out.gen`, which is what this command fetches through AiiDA.

Newer runs cache that geometry into `calc_result.json` as it completes, so
`cif` serves them straight from disk and spawns **no AiiDA process at all** when
everything is already cached.

## What a file looks like

```text
# Generated by MatMelt -- DFTB+ relaxed geometry, P1 (no symmetry claimed).
data_C1Cl1Cu1Fe1O1_2
_cell_length_a                   4.30012912
_cell_length_b                   3.82865202
_cell_length_c                   4.40788721
_cell_angle_alpha                89.79422523
_cell_angle_beta                 90.45743960
_cell_angle_gamma                120.91417125
_cell_volume                     62.25866186
_symmetry_space_group_name_H-M   'P 1'
_symmetry_Int_Tables_number      1
_chemical_formula_sum            'C Cl Cu Fe O'
_mcli_material_id                'C1Cl1Cu1Fe1O1_2'
_mcli_geometry_source            'geom.out.gen (DFTB+ relaxed)'
_mcli_single_wc_pk               13624
_mcli_calcjob_pk                 13698
_mcli_n_attempts                 5
_mcli_total_energy_eV            -348.42856346
_mcli_band_gap_eV                0.06980000
_mcli_fermi_energy_eV            -3.37417976
_mcli_max_force_eV_Ang           0.00021964
```

Everything is written as **P1**: no symmetry is claimed for a relaxed cell,
because DFTB+ was free to break it. The `_mcli_*` items carry the provenance —
including the WorkChain and calculation ids, so any number here can be traced
back through `verdi node show`. `_mcli_n_attempts 5` means the plugin healed
this calculation four times before it converged.

## Open it

```console
$ python3 -c "
from ase.io import read
from ase.visualize import view
view(read('cifs/C1Cl1Cu1Fe1O1_2.cif'))
"
```

Or open the file directly in **VESTA**, **OVITO** or **Jmol** — it is ordinary
CIF. For a quick numerical look without a GUI:

```console
$ python3 -c "
from ase.io import read
a = read('cifs/C1Cl1Cu1Fe1O1_2.cif')
print(a.get_chemical_formula(), a.cell.cellpar().round(4), 'V =', round(a.get_volume(), 4))
"
```

## Structures that never reached `calculate`

For candidates from `structure` or survivors of `screen`, the CIFs are already
in the workspace, one directory per material under `run.work_dir` —
`structure.cif` and `relaxed.cif`. No export step is involved; open them the
same way.

## Script it

```console
$ matmelt cif --out-dir ./cifs --json
```

```json
{
  "run": "full-remote-run",
  "out_dir": "./cifs",
  "written": [
    {"id": "C1Cl1Cu1Fe1O1_2", "path": "./cifs/C1Cl1Cu1Fe1O1_2.cif",
     "wc_pk": 13624, "calc_pk": 13698}
  ],
  "skipped": [], "failed": [], "notes": [], "unmatched": []
}
```

Progress and warnings go to stderr, so stdout stays parseable. `skipped`,
`failed` and `unmatched` are counted rather than silent: a material you asked
for and did not get is always accounted for somewhere.

## Related

- {doc}`configure-calculate` — getting materials into `CALCULATED` in the first
  place.
- {doc}`export-results` — the OPTIMADE records, including the geometry `extract`
  captured.
