RandomRotation.random_map in marathon/grain/transforms/transforms.py has two issues, found while using rotational augmentation with a magnetic model (ASE 3.29.0).
1. Stale ASE import (breaks augmentation with Voigt-6 stress)
Line ~134:
from ase.constraints import (
full_3x3_to_voigt_6_stress,
voigt_6_to_full_3x3_stress,
)
These were moved to ase.stress in recent ASE (3.29). This raises ImportError: cannot import name 'full_3x3_to_voigt_6_stress' from 'ase.constraints' whenever a sample carries stress in Voigt-6 shape (6,) (the stress.shape == (6,) branch).
Note: marathon/grain/data_source/properties.py::convert_stress already imports these correctly from ase.stress — so the fix is just to match that here.
2. In-place mutation of the input atoms' calculator (minor)
Line ~126:
results = atoms.calc.results
if "forces" in self.keys and "forces" in results:
results["forces"] = np.einsum("ab,ib->ia", R, F)
results aliases the input atoms' calc.results, so the rotation is written back onto the source atoms before atoms.copy(). Harmless in a grain pipeline (fresh atoms per read), but surprising and a footgun. Suggest results = dict(atoms.calc.results) first.
Repro
from marathon.grain import RandomRotation
import numpy as np
# atoms with a Voigt-6 stress in its SinglePointCalculator
RandomRotation().random_map(atoms, np.random.default_rng(0)) # ImportError under ASE 3.29
Fix: import full_3x3_to_voigt_6_stress, voigt_6_to_full_3x3_stress from ase.stress, and copy results before mutating.
RandomRotation.random_mapinmarathon/grain/transforms/transforms.pyhas two issues, found while using rotational augmentation with a magnetic model (ASE 3.29.0).1. Stale ASE import (breaks augmentation with Voigt-6 stress)
Line ~134:
These were moved to
ase.stressin recent ASE (3.29). This raisesImportError: cannot import name 'full_3x3_to_voigt_6_stress' from 'ase.constraints'whenever a sample carries stress in Voigt-6 shape(6,)(thestress.shape == (6,)branch).Note:
marathon/grain/data_source/properties.py::convert_stressalready imports these correctly fromase.stress— so the fix is just to match that here.2. In-place mutation of the input atoms' calculator (minor)
Line ~126:
resultsaliases the input atoms'calc.results, so the rotation is written back onto the source atoms beforeatoms.copy(). Harmless in a grain pipeline (fresh atoms per read), but surprising and a footgun. Suggestresults = dict(atoms.calc.results)first.Repro
Fix: import
full_3x3_to_voigt_6_stress, voigt_6_to_full_3x3_stressfromase.stress, and copyresultsbefore mutating.