Summary
atom_data on StructureScene is a plain dict[str, np.ndarray]. Users can bypass set_atom_data() and write directly to the dict with no validation -- wrong-length arrays, non-arrays, and mixed None/numeric object arrays silently enter the system and cause confusing errors downstream during colour resolution.
Proposed changes
-
AtomData container -- a MutableMapping[str, np.ndarray] that validates on assignment: checks 1-D shape, correct length, and rejects object-dtype arrays containing mixed None + numeric values.
-
Convert StructureScene from dataclass to hand-rolled class -- the current __setattr__ and __post_init__ overrides fight the dataclass machinery. An explicit __init__ with property setters for view, lattice, and atom_data would be cleaner.
Future consideration
Per-frame atom data (shape (n_frames, n_atoms) in addition to the current (n_atoms,)) for trajectory colouring (e.g. per-frame velocities, charges). The AtomData container should be designed so this can be added without breaking changes.
Summary
atom_dataonStructureSceneis a plaindict[str, np.ndarray]. Users can bypassset_atom_data()and write directly to the dict with no validation -- wrong-length arrays, non-arrays, and mixedNone/numeric object arrays silently enter the system and cause confusing errors downstream during colour resolution.Proposed changes
AtomDatacontainer -- aMutableMapping[str, np.ndarray]that validates on assignment: checks 1-D shape, correct length, and rejects object-dtype arrays containing mixedNone+ numeric values.Convert
StructureScenefrom dataclass to hand-rolled class -- the current__setattr__and__post_init__overrides fight the dataclass machinery. An explicit__init__with property setters forview,lattice, andatom_datawould be cleaner.Future consideration
Per-frame atom data (shape
(n_frames, n_atoms)in addition to the current(n_atoms,)) for trajectory colouring (e.g. per-frame velocities, charges). TheAtomDatacontainer should be designed so this can be added without breaking changes.