O(3) transformations¶
The metatomic.torch.o3 module rotates and inverts
System and TensorMap
objects, for example to generate randomly rotated copies of a structure for data
augmentation.
Conventions¶
To transform a TensorBlock, transform_block()
and transform_tensor() need to know, for each component axis, whether it
carries a Cartesian or a spherical tensor. This is inferred from the axis name:
Cartesian axes are named
xyz, orxyz_1,xyz_2, … for blocks with several Cartesian axes (e.g. rank-2 Cartesian tensors). These are rotated directly with the (3, 3) transformation matrix \(R\) passed toO3Transformation, following the usual column-vector convention \(v' = R v\) (equivalently, since values are stored as rows,values_transformed = values @ R.T).Spherical axes are named
o3_mu, oro3_mu_1,o3_mu_2, … They are rotated with the real Wigner-D matrix for the angular momentumo3_lambda(respectivelyo3_lambda_1,o3_lambda_2, …) found in the block’s key. Real, rather than complex, spherical harmonics are used throughout, matching the convention used elsewhere in metatomic and metatensor for spherical targets.
Wigner-D matrices¶
Complex Wigner-D matrices are computed by the wigners package, using the convention
with ZYZ Euler angles \((\alpha, \beta, \gamma)\) extracted from the proper part of \(R\), i.e. from \(R\) itself when \(\det R = 1\), or from \(-R\) when \(\det R = -1\), such that this proper part equals \(R_z(\alpha) R_y(\beta) R_z(\gamma)\).
These are then converted to real Wigner-D matrices through the unitary change of basis \(T\) mapping complex spherical harmonics \(Y_{\ell}^{m}\) to real ones:
so that the real Wigner-D matrix is \(D^{\ell}_{\text{real}} = T^{*} D^{\ell} T^{T}\).
For an improper rotation (a rotation composed with an inversion), Cartesian axes are
flipped as part of the transformation matrix itself, while spherical axes pick up an
extra parity factor \((-1)^{\ell} \sigma\), where \(\ell\) is o3_lambda
and \(\sigma\) is the block’s o3_sigma (its behavior under inversion, +1 or
-1), also read from the key.
A TensorBlock in general contains values associated with
several systems. This information is contained in the "system" samples dimension;
each row is rotated with the transformation of the system it belongs to. Gradient blocks
are routed the same way, via their parent block’s "system" column. When only one
system is being transformed, the "system" column is optional and, if present, is
ignored: every row is rotated with the (single) given transformation.
Reference¶
- class metatomic.torch.o3.O3Transformation(matrix: Tensor, max_angular_momentum: int)[source]¶
A single O(3) transformation, represented by a (3, 3) rotation or improper-rotation matrix.
- Parameters:
- metatomic.torch.o3.random_transformations(n: int, max_angular_momentum: int = 0, *, device: device, dtype: dtype, include_inversions: bool = False, generator: Generator | None = None) list[O3Transformation][source]¶
Sample
nuniformly distributed O(3) transformations.Rotations are sampled from the Haar measure on SO(3) via random unit quaternions. When
include_inversionsisTrue, each matrix is independently negated with probability 0.5, giving a uniform distribution over the full O(3) group.- Parameters:
n (int) – number of transformations to generate
max_angular_momentum (int) – maximum angular momentum for Wigner-D matrices
device (device) – target device for the output tensors
dtype (dtype) – target dtype for the output tensors
include_inversions (bool) – if
True, sample from O(3) instead of SO(3)generator (Generator | None) – optional
torch.Generatorfor reproducible sampling; whenNonethe global RNG is used
- Returns:
list of
northogonal (3, 3) tensors- Return type:
- metatomic.torch.o3.transform_system(system: System, transformation: O3Transformation) System[source]¶
Apply an O(3) transformation to a single System.
This function will transform positions, cell vectors, neighbor-list displacement vectors, and any custom data.
- Parameters:
system (System) – input system
transformation (O3Transformation) – O(3) transformation to apply
- Returns:
new System with transformed geometry
- Return type:
- metatomic.torch.o3.transform_tensor(tensor: TensorMap, systems: list[System], transformations: list[O3Transformation], system_ids: list[int] | Tensor | None = None) TensorMap[source]¶
Rotate every block (and its gradients) of a TensorMap.
The tensor character of each component axis is inferred from its name, so a single
TensorMapmay freely mix scalar, Cartesian and spherical blocks, and blocks may carry gradients.One of the samples dimensions must be
"system", which is used to route each row to the correct system and transformation.- Parameters:
- Returns:
new TensorMap with rotated values and gradients
- Return type:
- metatomic.torch.o3.transform_block(key: LabelsEntry, block: TensorBlock, systems: list[System], transformations: list[O3Transformation], system_ids: list[int] | Tensor | None = None) TensorBlock[source]¶
Rotate one block and all of its gradients.
- Parameters:
key (LabelsEntry) – the block’s key, containing
o3_lambda/o3_sigmavalues for spherical blocksblock (TensorBlock) – the block to rotate
systems (list[System]) – list of systems, one per transformation
transformations (list[O3Transformation]) – per-system O(3) transformation matrices
system_ids (list[int] | Tensor | None) – index of the
systemsused in the samples ofblock; defaults tolist(range(len(systems)))
- Returns:
new block with rotated values and gradients
- Return type: