torchref.symmetry.spacegroup module

Space group utilities using gemmi as the canonical representation.

This module provides a unified interface for space group handling throughout torchref. The primary class is SpaceGroup, an nn.Module that: - Normalizes input (string, int, gemmi.SpaceGroup) in the constructor - Stores symmetry matrices and translations as registered buffers - Provides all symmetry operation methods

Example

from torchref.symmetry.spacegroup import SpaceGroup

# Create from various inputs
sg = SpaceGroup('P 21')
sg = SpaceGroup('P21')  # Same result
sg = SpaceGroup(19)     # From space group number

# Access properties
print(sg.hm)            # 'P 21 21 21' (Hermann-Mauguin)
print(sg.number)        # 19
print(sg.name)          # 'P21' (short name)

# Apply symmetry operations
coords = torch.tensor([[0.1, 0.2, 0.3]])
transformed = sg(coords)  # Apply all symmetry operations
torchref.symmetry.spacegroup.spacegroup_to_str(spacegroup, style='short')[source]

Convert space group to string representation.

Parameters:
  • spacegroup (SpaceGroupLike) – Space group in any supported format.

  • style (str, default 'short') – Output style: - ‘short’: No spaces (e.g., ‘P212121’) - ‘hm’: Hermann-Mauguin with spaces (e.g., ‘P 21 21 21’) - ‘xhm’: Extended Hermann-Mauguin (e.g., ‘P 21 21 21’)

Returns:

Space group name in requested style.

Return type:

str

torchref.symmetry.spacegroup.get_symmetry_operations(spacegroup)[source]

Get symmetry operations from a space group.

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

List of symmetry operations.

Return type:

list of gemmi.Op

torchref.symmetry.spacegroup.get_operations_as_tensors(spacegroup, dtype=torch.float32, device=device(type='cpu'))[source]

Get symmetry operations as PyTorch tensors.

Parameters:
  • spacegroup (SpaceGroupLike) – Space group in any supported format.

  • dtype (torch.dtype, optional) – Data type for tensors. Defaults to the configured dtypes.float.

  • device (torch.device, optional) – Device for tensors. Defaults to the configured device.current.

Returns:

  • matrices (torch.Tensor, shape (n_ops, 3, 3)) – Rotation matrices.

  • translations (torch.Tensor, shape (n_ops, 3)) – Translation vectors (in fractional coordinates).

torchref.symmetry.spacegroup.is_same_spacegroup(sg1, sg2)[source]

Check if two space groups are the same.

Parameters:
  • sg1 (SpaceGroupLike) – Space groups to compare.

  • sg2 (SpaceGroupLike) – Space groups to compare.

Returns:

True if the space groups are identical.

Return type:

bool

torchref.symmetry.spacegroup.get_point_group(spacegroup)[source]

Get the point group symbol for a space group.

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

Point group symbol (e.g., ‘222’, ‘mmm’, ‘4/mmm’).

Return type:

str

torchref.symmetry.spacegroup.get_crystal_system(spacegroup)[source]

Get the crystal system for a space group.

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

Crystal system name (triclinic, monoclinic, orthorhombic, tetragonal, trigonal, hexagonal, or cubic).

Return type:

str

torchref.symmetry.spacegroup.is_centrosymmetric(spacegroup)[source]

Check if a space group is centrosymmetric.

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

True if the space group has an inversion center.

Return type:

bool

torchref.symmetry.spacegroup.n_operations(spacegroup)[source]

Get the number of symmetry operations in a space group.

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

Number of symmetry operations.

Return type:

int

torchref.symmetry.spacegroup.is_fft_friendly(n)[source]

Check if a number has only factors of 2, 3, and 5.

These are optimal for radix-2,3,5 FFT algorithms used by PyTorch/cuFFT.

Parameters:

n (int) – Number to check.

Returns:

True if n has only factors of 2, 3, 5.

Return type:

bool

Examples

is_fft_friendly(128)  # True (2^7)
is_fft_friendly(135)  # True (3^3 * 5)
is_fft_friendly(131)  # False (prime)
torchref.symmetry.spacegroup.find_fft_friendly_size(n, divisibility=1)[source]

Find the nearest FFT-friendly size >= n that satisfies divisibility constraint.

FFT-friendly means factors only of 2, 3, and 5 (radix-2,3,5 FFT algorithms).

Parameters:
  • n (int) – Minimum grid size.

  • divisibility (int, default 1) – Required divisibility (e.g., 2 for screw axes).

Returns:

Optimal grid size.

Return type:

int

Examples

find_fft_friendly_size(131)      # 135
find_fft_friendly_size(131, 2)   # 160 (divisible by 2, FFT-friendly)
torchref.symmetry.spacegroup.get_grid_requirements(spacegroup)[source]

Analyze symmetry operations to determine grid size requirements.

Examines all rotation matrices and translations to determine which grid dimensions must satisfy divisibility constraints for exact integer indexing (interpolation-free symmetry expansion).

Parameters:

spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

{‘nx_mod’: int, ‘ny_mod’: int, ‘nz_mod’: int} Required divisibility for each axis.

Return type:

dict

Examples

get_grid_requirements('P21')
# {'nx_mod': 1, 'ny_mod': 2, 'nz_mod': 1}

get_grid_requirements('P212121')
# {'nx_mod': 2, 'ny_mod': 2, 'nz_mod': 2}
torchref.symmetry.spacegroup.check_grid_compatibility(grid_shape, spacegroup)[source]

Check if a grid is compatible with space group symmetry and FFT requirements.

Verifies that the grid satisfies both: 1. Symmetry requirements (divisibility for screw axes) 2. FFT-friendly sizes (factors of 2, 3, 5 only)

Parameters:
  • grid_shape (tuple of int) – Grid dimensions (nx, ny, nz).

  • spacegroup (SpaceGroupLike) – Space group in any supported format.

Returns:

Dictionary with the following keys:

  • ’compatible’bool

    True if grid satisfies all requirements.

  • ’symmetry_compatible’bool

    True if grid satisfies symmetry requirements.

  • ’fft_friendly’bool

    True if all dimensions are FFT-friendly.

  • ’can_use_direct_indexing’bool

    True if interpolation-free expansion is possible.

  • ’issues’list of str

    Descriptions of incompatibilities (empty if compatible).

  • ’requirements’dict

    Required divisibility from get_grid_requirements().

Return type:

dict

Examples

check_grid_compatibility((131, 163, 148), 'P21')
# {'compatible': False, 'issues': ['ny=163 not divisible by 2', ...]}

check_grid_compatibility((135, 164, 150), 'P21')
# {'compatible': True, 'issues': []}
torchref.symmetry.spacegroup.suggest_grid_size(min_grid_shape, spacegroup, make_fft_friendly=True)[source]

Suggest an optimal grid size that satisfies symmetry and FFT requirements.

Given a minimum grid size, finds the nearest larger size that: 1. Satisfies symmetry requirements (divisibility constraints) 2. Optionally, is FFT-friendly (factors of 2, 3, 5 only)

Parameters:
  • min_grid_shape (tuple of int) – Minimum (nx, ny, nz) grid dimensions.

  • spacegroup (SpaceGroupLike) – Space group in any supported format.

  • make_fft_friendly (bool, default True) – If True, ensures result has only factors of 2, 3, 5.

Returns:

Suggested grid dimensions (nx, ny, nz).

Return type:

tuple of int

Examples

suggest_grid_size((131, 163, 148), 'P21')
# (135, 164, 150) or similar

suggest_grid_size((131, 163, 148), 'P212121')
# (135, 164, 150) - all divisible by 2 and FFT-friendly
class torchref.symmetry.spacegroup.SpaceGroup(space_group=None, dtype=torch.float32, device=device(type='cpu'))[source]

Bases: DeviceMixin, DebugMixin, Module

Unified space group handler for crystallographic symmetry operations.

This class combines space group normalization with symmetry operations, providing a single interface for: - Normalizing input (string, int, gemmi.SpaceGroup) in the constructor - Storing symmetry matrices and translations as PyTorch buffers - Applying symmetry operations to fractional coordinates - Grid size utilities for symmetry-compatible grids

Parameters:
  • space_group (str, int, gemmi.SpaceGroup, SpaceGroup, or None) – Space group specification. Accepts: - Hermann-Mauguin symbol (e.g., ‘P21’, ‘P 21 21 21’) - Space group number (1-230) - gemmi.SpaceGroup object - Another SpaceGroup instance - None (defaults to P1)

  • dtype (torch.dtype, default torch.float64) – Data type for rotation matrices and translations.

  • device (torch.device, default: configured device.current) – Device for computation.

matrices

Rotation matrices for all symmetry operations (registered buffer).

Type:

torch.Tensor, shape (n_ops, 3, 3)

translations

Translation vectors for all symmetry operations (registered buffer).

Type:

torch.Tensor, shape (n_ops, 3)

n_ops

Number of symmetry operations.

Type:

int

Examples

# Create from various inputs
sg = SpaceGroup('P21')
sg = SpaceGroup('P 21')      # Same result
sg = SpaceGroup(4)           # P21 by number
sg = SpaceGroup(None)        # Returns P1

# Access properties
print(sg.name)          # 'P21' (short name)
print(sg.hm)            # 'P 21' (Hermann-Mauguin with spaces)
print(sg.number)        # 4

# Apply symmetry operations
coords = torch.tensor([[0.1, 0.2, 0.3]])
transformed = sg(coords)  # Apply all symmetry operations

# Grid utilities
req = sg.get_grid_requirements()
suggested = sg.suggest_grid_size((131, 163, 148))
__init__(space_group=None, dtype=torch.float32, device=device(type='cpu'))[source]
property n_ops: int

Number of symmetry operations.

property name: str

Short space group name (e.g., ‘P21’).

property hm: str

Hermann-Mauguin notation with spaces (e.g., ‘P 21’).

property xhm: str

Extended Hermann-Mauguin notation.

property number: int

Space group number (1-230).

property gemmi: SpaceGroup

Access a gemmi.SpaceGroup object (created on demand, not stored).

property point_group: str

Point group symbol (e.g., ‘222’, ‘mmm’).

property crystal_system: str

Crystal system name.

property centrosymmetric: bool

True if space group has inversion center.

property dtype: dtype

Data type used for matrices.

property device: device

Device for matrices.

property spacegroup: SpaceGroup

Alias for gemmi property (backward compatibility).

property space_group: SpaceGroup

Alias for gemmi property (backward compatibility).

property space_group_name: str

Alias for name property (backward compatibility).

property space_group_number: int

Alias for number property (backward compatibility).

short_name()[source]

Get short space group name.

operations()[source]

Get symmetry operations (creates temporary gemmi object on demand).

apply(xyz_fractional, apply_translation=True)[source]

Apply symmetry operations to fractional coordinates (rotation + translation).

For real space coordinates, applies the full symmetry operation: x’ = R·x + t

Parameters:

xyz_fractional (torch.Tensor) – Input tensor of shape (N, 3) representing fractional coordinates.

Returns:

Transformed coordinates of shape (N, 3, ops) where ops is the number of symmetry operations.

Return type:

torch.Tensor

See also

apply_to_hkl

For reciprocal space (Miller indices), rotation only.

apply_to_hkl(hkl)[source]

Apply symmetry operations to Miller indices (rotation only, no translation).

For reciprocal space, only the rotational part of symmetry operations applies to Miller indices: h’ = R·h. The translation vector affects the phase of structure factors, not the indices themselves.

Parameters:

hkl (torch.Tensor) – Input tensor of shape (N, 3) representing Miller indices.

Returns:

Transformed Miller indices of shape (N, 3, ops) where ops is the number of symmetry operations.

Return type:

torch.Tensor

See also

apply

For real space coordinates (rotation + translation).

expand_coords_to_P1(xyz_fractional)[source]

Expand fractional coordinates by applying all symmetry operations.

Parameters:

xyz_fractional (torch.Tensor) – Input tensor of shape (N, 3) representing fractional coordinates.

Returns:

Expanded coordinates of shape (N * ops, 3).

Return type:

torch.Tensor

forward(xyz_fractional)[source]

Forward pass applies symmetry operations.

get_grid_requirements()[source]

Analyze symmetry operations to determine grid size requirements.

Returns:

{‘nx_mod’: int, ‘ny_mod’: int, ‘nz_mod’: int} Required divisibility for each axis.

Return type:

dict

Examples

sg = SpaceGroup('P21')
req = sg.get_grid_requirements()
print(req)  # {'nx_mod': 1, 'ny_mod': 2, 'nz_mod': 1}
check_grid_compatibility(grid_shape)[source]

Check if a grid size is compatible with the symmetry operations.

Parameters:

grid_shape (tuple of int) – (nx, ny, nz) grid dimensions.

Returns:

Dictionary with keys: - ‘compatible’ : bool - True if grid satisfies all requirements - ‘symmetry_compatible’ : bool - True if grid satisfies symmetry - ‘fft_friendly’ : bool - True if all dimensions are FFT-friendly - ‘can_use_direct_indexing’ : bool - True if no interpolation needed - ‘issues’ : list of str - Descriptions of incompatibilities - ‘requirements’ : dict - Required divisibility

Return type:

dict

Examples

sg = SpaceGroup('P21')
result = sg.check_grid_compatibility((131, 163, 148))
print(result['compatible'])  # False
print(result['issues'])  # ['ny=163 not divisible by 2']
suggest_grid_size(min_grid_shape, make_fft_friendly=True)[source]

Suggest an optimal grid size that satisfies symmetry requirements.

Parameters:
  • min_grid_shape (tuple of int) – Minimum (nx, ny, nz) grid dimensions.

  • make_fft_friendly (bool, default True) – If True, ensures result has only factors of 2, 3, 5.

Returns:

Suggested grid dimensions (nx, ny, nz).

Return type:

tuple of int

Examples

sg = SpaceGroup('P21')
suggested = sg.suggest_grid_size((131, 163, 148))
print(suggested)  # (135, 164, 150) or similar
__hash__()[source]

Hash based on space group number.

__eq__(other)[source]

Equality based on space group number.

copy()[source]

Create a deep copy of this SpaceGroup.

Returns:

A new SpaceGroup instance with cloned buffers.

Return type:

SpaceGroup