madman.helpers.ase.workflows.structure

Atomic structure.

  1r"""Atomic structure."""
  2
  3import os
  4from argparse import ArgumentParser
  5from collections.abc import Sequence
  6from numbers import Real
  7from typing import Optional, TypedDict
  8
  9import yaml
 10from ase import Atoms
 11from ase.io import read
 12from ase.visualize import view
 13from mp_api.client import MPRester
 14
 15
 16class AtmStrMap(TypedDict):
 17    r"""Atomic structure mapping."""
 18
 19    atm: Sequence[str, ...]
 20    r"""Atomic species."""
 21
 22    xred: Sequence[Sequence[Real, Real, Real], ...]
 23    r"""Motif reduced coordinates."""
 24
 25    cell: Sequence[
 26        Sequence[Real, Real, Real],
 27        Sequence[Real, Real, Real],
 28        Sequence[Real, Real, Real],
 29    ]
 30    r"""Unit cell vectors."""
 31
 32    pbc: bool
 33    r"""If True, periodic boundary conditions are applied."""
 34
 35
 36def gen_atm_str(
 37    *,
 38    atm_str_map: Optional[AtmStrMap] = None,
 39    atm_str_pth: Optional[str] = None,
 40    mp_api_key: Optional[str] = None,
 41    mpid: Optional[str] = None,
 42    display: Optional[bool] = False,
 43    save_prefix: Optional[str] = None,
 44) -> Atoms:
 45    r"""Generate atomic structure.
 46
 47    Args:
 48        atm_str_map: Atomic structure mapping.
 49        atm_str_pth: Atomic structure path.
 50        mp_api_key: Materials Project API key.
 51        mpid: Materials Project identifier.
 52        display: If True, display atomic structure.
 53        save_prefix: Path to save atomic structure, w/o extension.
 54
 55    Returns:
 56        Atomic structure.
 57    """
 58    if atm_str_map is not None:
 59        atm_str = Atoms(
 60            atm_str_map["atm"],
 61            scaled_positions=atm_str_map["xred"],
 62            cell=atm_str_map["cell"],
 63            pbc=atm_str_map["pbc"],
 64        )
 65        print("Atomic structure generated...")
 66
 67    elif atm_str_pth is not None:
 68        atm_str = read(atm_str_pth)
 69        print("Atomic structure imported...")
 70
 71    else:
 72        with MPRester(mp_api_key, mute_progress_bars=True) as mpr:
 73            atm_str = mpr.get_structure_by_material_id(mpid)
 74        atm_str = atm_str.to_primitive()
 75        atm_str = atm_str.to_ase_atoms()
 76        print("Atomic structure downloaded...")
 77
 78    if display is True:
 79        print("Displaying atomic structure...")
 80        view(atm_str, block=True)
 81
 82    if save_prefix is not None:
 83        root = os.path.dirname(save_prefix)
 84        os.makedirs(root, exist_ok=True)
 85        for ext in [".traj", ".cif"]:
 86            atm_str.write(f"{save_prefix}{ext}")
 87        print("Atomic structure saved...")
 88
 89    return atm_str
 90
 91
 92def gen_atm_str_cli() -> None:
 93    r"""Generate atomic structure - CLI interface."""
 94    parser = ArgumentParser(description="Generate atomic structure")
 95    parser.add_argument(
 96        "config",
 97        nargs="?",
 98        default="./config.yml",
 99        help="configuration file",
100    )
101    args = parser.parse_args()
102    with open(args.config, "r", encoding="utf-8") as stream:
103        config = yaml.safe_load(stream)
104    gen_atm_str(**config)
class AtmStrMap(typing.TypedDict):
17class AtmStrMap(TypedDict):
18    r"""Atomic structure mapping."""
19
20    atm: Sequence[str, ...]
21    r"""Atomic species."""
22
23    xred: Sequence[Sequence[Real, Real, Real], ...]
24    r"""Motif reduced coordinates."""
25
26    cell: Sequence[
27        Sequence[Real, Real, Real],
28        Sequence[Real, Real, Real],
29        Sequence[Real, Real, Real],
30    ]
31    r"""Unit cell vectors."""
32
33    pbc: bool
34    r"""If True, periodic boundary conditions are applied."""

Atomic structure mapping.

atm: collections.abc.Sequence[str, ...]

Atomic species.

xred: collections.abc.Sequence[collections.abc.Sequence[numbers.Real, numbers.Real, numbers.Real], ...]

Motif reduced coordinates.

cell: collections.abc.Sequence[collections.abc.Sequence[numbers.Real, numbers.Real, numbers.Real], collections.abc.Sequence[numbers.Real, numbers.Real, numbers.Real], collections.abc.Sequence[numbers.Real, numbers.Real, numbers.Real]]

Unit cell vectors.

pbc: bool

If True, periodic boundary conditions are applied.

Inherited Members
builtins.dict
get
setdefault
pop
popitem
keys
items
values
update
fromkeys
clear
copy
def gen_atm_str( *, atm_str_map: Optional[AtmStrMap] = None, atm_str_pth: Optional[str] = None, mp_api_key: Optional[str] = None, mpid: Optional[str] = None, display: Optional[bool] = False, save_prefix: Optional[str] = None) -> ase.atoms.Atoms:
37def gen_atm_str(
38    *,
39    atm_str_map: Optional[AtmStrMap] = None,
40    atm_str_pth: Optional[str] = None,
41    mp_api_key: Optional[str] = None,
42    mpid: Optional[str] = None,
43    display: Optional[bool] = False,
44    save_prefix: Optional[str] = None,
45) -> Atoms:
46    r"""Generate atomic structure.
47
48    Args:
49        atm_str_map: Atomic structure mapping.
50        atm_str_pth: Atomic structure path.
51        mp_api_key: Materials Project API key.
52        mpid: Materials Project identifier.
53        display: If True, display atomic structure.
54        save_prefix: Path to save atomic structure, w/o extension.
55
56    Returns:
57        Atomic structure.
58    """
59    if atm_str_map is not None:
60        atm_str = Atoms(
61            atm_str_map["atm"],
62            scaled_positions=atm_str_map["xred"],
63            cell=atm_str_map["cell"],
64            pbc=atm_str_map["pbc"],
65        )
66        print("Atomic structure generated...")
67
68    elif atm_str_pth is not None:
69        atm_str = read(atm_str_pth)
70        print("Atomic structure imported...")
71
72    else:
73        with MPRester(mp_api_key, mute_progress_bars=True) as mpr:
74            atm_str = mpr.get_structure_by_material_id(mpid)
75        atm_str = atm_str.to_primitive()
76        atm_str = atm_str.to_ase_atoms()
77        print("Atomic structure downloaded...")
78
79    if display is True:
80        print("Displaying atomic structure...")
81        view(atm_str, block=True)
82
83    if save_prefix is not None:
84        root = os.path.dirname(save_prefix)
85        os.makedirs(root, exist_ok=True)
86        for ext in [".traj", ".cif"]:
87            atm_str.write(f"{save_prefix}{ext}")
88        print("Atomic structure saved...")
89
90    return atm_str

Generate atomic structure.

Arguments:
  • atm_str_map: Atomic structure mapping.
  • atm_str_pth: Atomic structure path.
  • mp_api_key: Materials Project API key.
  • mpid: Materials Project identifier.
  • display: If True, display atomic structure.
  • save_prefix: Path to save atomic structure, w/o extension.
Returns:

Atomic structure.

def gen_atm_str_cli() -> None:
 93def gen_atm_str_cli() -> None:
 94    r"""Generate atomic structure - CLI interface."""
 95    parser = ArgumentParser(description="Generate atomic structure")
 96    parser.add_argument(
 97        "config",
 98        nargs="?",
 99        default="./config.yml",
100        help="configuration file",
101    )
102    args = parser.parse_args()
103    with open(args.config, "r", encoding="utf-8") as stream:
104        config = yaml.safe_load(stream)
105    gen_atm_str(**config)

Generate atomic structure - CLI interface.