Skip to content

sym_u: Laue class rotations of any space group, from xfab - #678

Merged
jonwright merged 4 commits into
FABLE-3DXRD:masterfrom
jadball:sym-u-laue
Oct 30, 2026
Merged

jonwright merged 4 commits into
FABLE-3DXRD:masterfrom
jadball:sym-u-laue

Conversation

@jadball

@jadball jadball commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Claude written - careful!

Second of the sym_u PRs proposed in #675. Independent of the trigonal fix PR.

  • sym_u.laue_rotations(spacegroup, cell_choice="standard"): rotations of a space group's Laue class, built from xfab.sglib. These are the orientations diffraction cannot tell apart. It returns a sym_u group, so it works with find_uniq_u like cubic() etc. cell_choice="rhombohedral" covers R groups on rhombohedral axes.
  • sym_u.cartesian(grp, B): the same operations as rotations S of the crystal frame, with (op·ubi)⁻¹ = U·S·B.
  • tensor_map.sym_ops_from_phase uses them. Its signature is unchanged; the private helpers it no longer needs are removed (added in 988ca39, in no release).

Existing sym_u functions are unchanged.

Results change in tensor_map (KAM, GROD, grain mean orientation):

space groups before after
187 that already worked identical operators
50 with Laue class 4/m, -3, -31m, 6/m, m-3 ValueError work
cell not in the standard setting (e.g. c-unique monoclinic) matrices that are not rotations ValueError

Tests:

  • All 230 space groups plus the 7 rhombohedral settings give proper rotation groups that keep the cell under op @ ubi.
  • Group sizes for one space group per Laue class.
  • The new groups equal the old hand-written ones where those apply.
  • cartesian satisfies the identity above.
  • tensor_map handles the formerly refused classes and raises on a non-standard cell.

Run with numpy 1.26; not run under Python 2.7 or numpy 2.

🤖 Generated with Claude Code

jadball and others added 3 commits October 30, 2026 14:36
sym_u.laue_rotations(spacegroup, cell_choice) builds the rotations of a
space group's Laue class from xfab.sglib, as a group acting on ubi like
cubic() etc. sym_u.cartesian(grp, B) gives them as rotations of the
crystal frame: (op.ubi)^-1 = U.S.B.

tensor_map.sym_ops_from_phase uses them. For the 187 space groups it
handled the operators are identical; the 50 with Laue class 4/m, -3,
-31m, 6/m or m-3 no longer raise. A cell outside the standard setting
now raises instead of returning matrices that are not rotations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test_sym_u: both PRs defined CELLS; the crystal-system one is now
SYSTEM_CELLS. laue_rotations(150) is compared with the fixed trigonal().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jonwright jonwright left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I see you are making the list of proper rotations, but I didn't understand why? Doesn't a Laue group include mirrors and inversion too? Or is the purpose just to get the list of proper rotations ... presumably for some good reason. I think I miss where is this code used - it is in tensor map apparently - isn't it that we miss the list of all 11 classes in the form "trigonal", etc, together with mappings to those?

Probably OK to merge, but for now, I have not fully understood why we have this done like this. There should be ~11 Laue groups and like this they are hard-wired to xfab anyway, so non-standard settings are banned. It is deriving them from a small table but looking up the operators from a table. I suspect it could just be a small table if the tabulation is used, or the function if the the list of operators comes in

Comment thread ImageD11/sym_u.py Outdated
for r in sg.sg(sgno=spacegroup, cell_choice=cell_choice).rot:
# xfab has x' = W.x, here W.T acts on the rows of ubi.
# The inversion in the Laue class makes each operation proper.
w = np.array(r, float).T * np.sign(np.linalg.det(r))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is sign of determinant being done? You are making these all be rotations with no mirrors?

As suggested in review: laue_generators holds the generators of the 14
rotation groups (11 Laue classes, -3m1 and -31m on hexagonal axes, -3
and -3m on rhombohedral axes), using the same strings as cubic() etc,
so those are the same group objects. laue_class() looks up the class of
a space group in xfab. The operators xfab lists are now the test: the
table gives the same groups for all 230 space groups and the
rhombohedral settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@jonwright jonwright left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beautiful - thanks!

@jonwright
jonwright merged commit fdb15dc into FABLE-3DXRD:master Oct 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants