Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tutorials/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ widget cell displays the interactive view.

ShowCIF uses an explicit idealized BaTiO₃ cell. Show3D downloads a public HAADF image and builds a moving-crop
stack. Show3DSlices uses a synthetic scalar volume. None is presented as an
experimental BTO reconstruction or a quantitative multislice simulation.
experimental reconstruction or a quantitative multislice simulation.

## Prepare once

Expand Down
10 changes: 5 additions & 5 deletions docs/tutorials/showcif.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"\n",
"[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/electronmicroscopy/quantem.widget/blob/main/docs/tutorials/showcif.ipynb)\n",
"\n",
"Inspect unit cells, columns, specimen tilt, and depth slabs before planning an experiment. This notebook uses a small **idealized cubic BaTiO₃ model**, built below; it is not a refinement of an experimental BTO sample. No private data or download is required for the model.\n",
"Inspect unit cells, columns, specimen tilt, and depth slabs before planning an experiment. This notebook uses a small **idealized cubic BaTiO₃ model**, built below; it is not a refinement of an experimental sample. No private data or download is required for the model.\n",
"\n",
"Run the cells in order in JupyterLab. Use a WebGPU-capable browser on **localhost or HTTPS**. Install `quantem.widget[crystal]` (abTEM, for the potential preview) in the notebook environment first; see [installation](../install.md). This tutorial requires a build that includes `ShowCIF`. For a source checkout, use the developer installation below rather than assuming an older wheel contains it.\n",
"\n",
Expand Down Expand Up @@ -57,7 +57,7 @@
"\n",
"from ase import Atoms\n",
"\n",
"bto = Atoms(\n",
"crystal = Atoms(\n",
" \"BaTiO3\",\n",
" scaled_positions=[\n",
" (0, 0, 0), (0.5, 0.5, 0.5),\n",
Expand Down Expand Up @@ -87,7 +87,7 @@
"cell_type": "code",
"metadata": {},
"source": [
"atoms = qw.ShowCIF(bto, repeats=(4, 4, 8), zone_axis=(0, 0, 1))\n",
"atoms = qw.ShowCIF(crystal, repeats=(4, 4, 8), zone_axis=(0, 0, 1))\n",
"atoms\n"
],
"outputs": [],
Expand All @@ -113,7 +113,7 @@
"metadata": {},
"source": [
"potential = qw.ShowCIF(\n",
" bto,\n",
" crystal,\n",
" repeats=(4, 4, 8),\n",
" potential=True,\n",
" num_slices=16,\n",
Expand Down Expand Up @@ -167,7 +167,7 @@
"Export when ready:\n",
"\n",
"```python\n",
"potential.export_html(\"bto-inspection.html\")\n",
"potential.export_html(\"crystal-inspection.html\")\n",
"```\n",
"\n",
"The HTML embeds the structure and synced physical settings. It needs a WebGPU browser and network access for the widget manager; temporary camera, playback, blur, and slice selections reset on reopen. To inspect a reconstructed volume, use [Show3D](show3d.ipynb) and [Show3DSlices](show3dslices.ipynb).\n"
Expand Down
24 changes: 12 additions & 12 deletions tests/showcif/test_showcif.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from quantem.widget.showcif import projected_atom_table


def bto() -> Atoms:
def perovskite() -> Atoms:
"""Cubic-like BaTiO3 perovskite cell (5 atoms), the ordered structure most tests inspect."""
return Atoms(
"BaTiO3",
Expand All @@ -30,23 +30,23 @@ def positions(widget: ShowCIF) -> np.ndarray:


def test_cif_file_and_ase_structure_expand_identically(tmp_path):
path = tmp_path / "bto.cif"
write(path, bto())
path = tmp_path / "perovskite.cif"
write(path, perovskite())
from_file = ShowCIF(path, repeats=(2, 3, 4), zone_axis=(0, 0, 1))
from_atoms = ShowCIF(bto(), repeats=(2, 3, 4))
from_atoms = ShowCIF(perovskite(), repeats=(2, 3, 4))
assert positions(from_file).shape == (5, 4)
np.testing.assert_allclose(positions(from_file), positions(from_atoms), atol=1e-6)
np.testing.assert_allclose(from_file.unit_cell, from_atoms.unit_cell)
assert sorted(s["count"] for s in from_file.species) == [24, 24, 72]
assert from_file.title == "BaTiO3 · Atomic structure"
assert from_file.source_summary.startswith("bto.cif · 5 atoms/cell")
assert from_file.source_summary.startswith("perovskite.cif · 5 atoms/cell")
before = from_file.unit_atom_bytes
from_file.visible_species = [False] * 3
from_file.zone_axis = [1, 1, 0]
assert from_file.unit_atom_bytes == before


COD_STYLE_CIF = """data_bto
COD_STYLE_CIF = """data_perovskite
_chemical_formula_sum 'Ba O3 Ti'
_cell_length_a 4.0
_cell_length_b 4.0
Expand All @@ -71,7 +71,7 @@ def test_cif_file_and_ase_structure_expand_identically(tmp_path):

def test_title_names_the_formula_the_cif_writes_else_the_hill_formula(tmp_path):
written = tmp_path / "written.cif"
write(written, bto())
write(written, perovskite())
cod = tmp_path / "cod.cif"
cod.write_text(COD_STYLE_CIF)
chloroform = Atoms("CHCl3", positions=[(0, 0, 0), (0, 0, 1.1), (1.7, 0, -0.5), (-0.9, 1.5, -0.5), (-0.9, -1.5, -0.5)], cell=[8, 8, 8], pbc=True)
Expand All @@ -87,7 +87,7 @@ def test_title_names_the_formula_the_cif_writes_else_the_hill_formula(tmp_path):


def test_repeats_change_rebuilds_the_supercell_not_the_unit_cell():
original = bto()
original = perovskite()
widget = ShowCIF(original, repeats=(4, 4, 8))
unit_bytes = widget.unit_atom_bytes
widget.repeats = [2, 3, 4]
Expand Down Expand Up @@ -115,15 +115,15 @@ def test_repeats_change_rebuilds_the_supercell_not_the_unit_cell():
)
def test_invalid_inputs_fail_before_any_atoms_are_packed(kwargs):
with pytest.raises(ValueError):
ShowCIF(bto(), **kwargs)
ShowCIF(perovskite(), **kwargs)


def test_partial_occupancy_and_degenerate_cells_are_refused():
partial = bto()
partial = perovskite()
partial.info["occupancy"] = {"0": {"Ba": 0.5}}
with pytest.raises(ValueError, match="occupancies"):
ShowCIF(partial)
flat = bto()
flat = perovskite()
flat.cell = [[1, 0, 0], [2, 0, 0], [0, 0, 1]]
with pytest.raises(ValueError, match="finite 3D"):
ShowCIF(flat)
Expand All @@ -133,7 +133,7 @@ def test_partial_occupancy_and_degenerate_cells_are_refused():


def test_specimen_tilt_is_display_state_only():
atoms = bto()
atoms = perovskite()
untilted = ShowCIF(atoms, repeats=(2, 2, 3))
tilted = ShowCIF(atoms, repeats=(2, 2, 3))
tilted.specimen_tilt_mrad = [12, -7]
Expand Down
Loading