• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

globus-labs / cascade / 18732618520

22 Oct 2025 11:21PM UTC coverage: 25.34% (-70.0%) from 95.34%
18732618520

Pull #70

github

miketynes
fix init, logging init, waiting
Pull Request #70: Academy proto

261 of 1030 relevant lines covered (25.34%)

0.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.29
/cascade/utils.py
1
"""Utilities employed across cascade"""
2
from io import StringIO
1✔
3
from copy import deepcopy
1✔
4

5
from ase import io as aio
1✔
6
import numpy as np
1✔
7
from ase import Atoms
1✔
8
from ase.calculators.calculator import Calculator
1✔
9
from ase.calculators.singlepoint import SinglePointCalculator
1✔
10

11

12
# Taken from ExaMol
13
# Taken from jitterbug
14
def write_to_string(atoms: Atoms, fmt: str, **kwargs) -> str:
1✔
15
    """Write an ASE atoms object to string
16

17
    Args:
18
        atoms: Structure to write
19
        fmt: Target format
20
        kwargs: Passed to the write function
21
    Returns:
22
        Structure written in target format
23
    """
24

25
    out = StringIO()
×
26
    atoms.write(out, fmt, **kwargs)
×
27
    return out.getvalue()
×
28

29

30
def read_from_string(atoms_msg: str, fmt: str, index=None) -> Atoms:
1✔
31
    """Read an ASE atoms object from a string
32

33
    Args:
34
        atoms_msg: String format of the object to read
35
        fmt: Format (cannot be autodetected)
36
        index: Which frame(s) to read. See :meth:`ase.io.read`
37
    Returns:
38
        Parsed atoms object
39
    """
40

41
    out = StringIO(str(atoms_msg))  # str() ensures that Proxies are resolved
×
42
    return aio.read(out, format=fmt, index=index)
×
43

44

45
def canonicalize(atoms: Atoms) -> Atoms:
1✔
46
    """A convenience function to standardize the format of an ase.Atoms object
47

48
    The main motivation is to freeze the Atoms.calc attribute into an immutable
49
    singlepoint calculator
50

51
    Args:
52
        atoms: Structure to write
53
    Returns:
54
        Atoms object that has been serialized and deserialized
55
    """
56
    # TODO (wardlt): Make it so the single-point calculator can hold unknown properties? (see discussion https://gitlab.com/ase/ase/-/issues/782)
57
    out_atoms = atoms.copy()
×
58
    if atoms.calc is not None:
×
59
        old_calc = atoms.calc
×
60
        out_atoms.calc = SinglePointCalculator(atoms)
×
61
        out_atoms.calc.results = old_calc.results.copy()
×
62
    return out_atoms
×
63

64

65
def apply_calculator(
1✔
66
        calc: Calculator,
67
        traj: list[Atoms]) -> list[Atoms]:
68
    """Run a calculator on every atoms object in a list, returning a new list
69

70
    Args:
71
        calc: the calculator to be applied
72
        traj: the list of atoms to have the calculator applied to
73
    Returns:
74
        list of atoms that have been canonicalized s.t. their results are stored in a SinglePointCalculator
75
    """
76
    traj = deepcopy(traj)
×
77
    for i, atoms in enumerate(traj):
×
78
        atoms.calc = calc
×
79
        atoms.get_forces()
×
80
        traj[i] = canonicalize(atoms)
×
81
    return traj
×
82

83

84
def to_voigt(stress: np.ndarray) -> np.ndarray:
1✔
85
    """Converts a (3,3) stress tensor to voigt form, or do nothing if its already in this form
86

87
    Args:
88
        stress: a stess tensor of shape (3,3) or (6,), in which case this function is a no-op
89
    Returns:
90
        stress: a (6,) stress tensor in voigt form
91
    """
92
    if stress.shape == (3, 3):
×
93
        stress = np.array([stress[0, 0], stress[1, 1], stress[2, 2],
×
94
                           stress[1, 2], stress[0, 2], stress[0, 1]])
95
    elif stress.shape != (6,):
×
96
        raise ValueError(f"Stress tensor must either be of shape (3,3) or (6,), got {stress.shape}")
×
97
    return stress
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc