orix icon indicating copy to clipboard operation
orix copied to clipboard

Is S6 alright?

Open maclariz opened this issue 1 year ago • 11 comments

This doesn't look right. Normal hexagonal indexing would have the top left index as [-12-10]

Image

maclariz avatar Jan 23 '25 12:01 maclariz

@harripj @hakonanes any thoughts?

maclariz avatar Feb 10 '25 13:02 maclariz

I agree, this does not look right! Our chosen [UVTW] convention as stated in the docs,

Image

shows that it should be [-12-10], if it starts out as [uvw] = [010].

Looking at the implementation

https://github.com/pyxem/orix/blob/43d6a8e343bd23301dd3c46ba2eeb176ae0dfe53/orix/vector/miller.py#L986-L999

it is as expected. So, perhaps that vector doesn't start out as [uvw] = [010]? We should have a closer look.

hakonanes avatar Feb 18 '25 20:02 hakonanes

@hakonanes I presume this was not fixed

maclariz avatar Mar 24 '25 17:03 maclariz

I can't even help you because I cannot see where these labels come from or what calls them to be printed

maclariz avatar Mar 24 '25 17:03 maclariz

I don't see how the fundamental sector can be right

Here is D3d (which should work for R3c symmetry): FundamentalSector (3,) [[ 0. 0. 1. ] [ 0.5 0.866 0. ] [ 0.5 -0.866 0. ]]

I already don't understand this as that seems to encompass 120° (although it doesn't look like that in the plots)

Here is S6 (which should work for R-3): FundamentalSector (3,) [[0. 0. 1. ] [0. 1. 0. ] [0.866 0.5 0. ]]

I don't make sense of that at all. Surely the fundamental sector is only 60° on that definition, and it should be 120°. And it is switched in angles from the D3d definition. Why not use [[0. 0. 1. ] [0. 1. 0. ] [0.866 -0.5 0. ]]

or

something with axis definitions closer to D3d?

maclariz avatar Mar 25 '25 12:03 maclariz

@maclariz , do these look right to you? Hex has always been confusing to me.

If so, culprid is in the code linked below. The function _add_crystal_direction_labels uses the same hkl coordinates for plotting as for the labels. So, in @maclariz example, it's plotting the corners at (1,0,0),(0,0,1),(-0.5,0.866,0), which is correct, but then trying to use points to determine UVTW, instead of (1,0,0) (0,0,1) (0,1,0)

If it looks right to you, I can make a PR for it.

https://github.com/pyxem/orix/blob/e92d14a8241ceba71e356fc215d3f48c8d60bf54/orix/plot/inverse_pole_figure_plot.py#L226-230

Image

argerlt avatar May 19 '25 09:05 argerlt

@maclariz to hit some of your other points though (heavily edited, as I learned a lot while fact-checking myself):

I don't see how the fundamental sector can be right

Here is D3d (which should work for R3c symmetry): FundamentalSector (3,) [[ 0. 0. 1. ] [ 0.5 0.866 0. ] [ 0.5 -0.866 0. ]] I already don't understand this as that seems to encompass 120° (although it doesn't look like that in the plots)

I believe the current behavior is correct. The following points: [[ 0. 0. 1. ] [ 1 0.866 0. ] [ 1 -0.866 0. ]] describe 3-fold axes and would give you the 120 degrees you expect, going from [11-20] to [1-210]. However, the points you quoted are two different 6-fold edges, [10-10] and [1-110], each 30 degrees from the x-axis (60 degrees from each other)

Here is S6 (which should work for R-3): FundamentalSector (3,) [[0. 0. 1. ] [0. 1. 0. ] [0.866 0.5 0. ]]

I don't make sense of that at all. Surely the fundamental sector is only 60° on that definition, and it should be 120°.

Same deal as above, stereographic mapping of the points given will produce 120 degrees, whereas [0.866, 1, 0] would give the 60 degrees.

And it is switched in angles from the D3d definition. Why not use [[0. 0. 1. ] [0. 1. 0. ] [0.866 -0.5 0. ]]

or something with axis definitions closer to D3d?

Others feel free to fact check me, but my understanding is as follows:

The ORIX standard IPF mapping follows the "TSL" convention from MTEX/Dream3D/TSL. This includes both how colors are chosen and the shape/position of the FS. The option you gave is valid, it would just cause color images made with ORIX and other software using the TSL coloring to display identical data differently, which can be maddening.

Different software sometime use different colors, But almost everyone uses an identical definition for FS shape, making it an unofficial standard. This paper describes a consistent standard for defining the shapes, which roughly boils down to " stick z up, stick x to the right, and chose a shape that touches both and is entirely above the x axis when possible".

argerlt avatar May 19 '25 18:05 argerlt

Here is D3d (which should work for R3c symmetry): FundamentalSector (3,) [[ 0. 0. 1. ] [ 0.5 0.866 0. ] [ 0.5 -0.866 0. ]]

I already don't understand this as that seems to encompass 120° (although it doesn't look like that in the plots)

@maclariz, these are the fundamental sector normals. I believe you're confusing them with the vertices obtained from the cross products of the normals:

import orix.quaternion as oqu

fs = oqu.symmetry.D3d.fundamental_sector

c = [f"C{i}" for i in range(fs.size)]
fig = fs.scatter(color=c, return_figure=True, label="Normals")
fig.axes[0].draw_circle(fs, color=c, label="Normal traces")
fig.axes[0].scatter(fs.vertices, color="r", label="Vertices")
fig.legend()

Image

You want to look at the vertices FundamentalSector.vertices, not the normals.

hakonanes avatar Jul 03 '25 09:07 hakonanes

The root of the problem is an incorrect structure matrix A when transforming the fundamental sector labels from the Cartesian vectors v = (x, y, z) to crystal directions t = [UVTW]. If we create a crystal Phase with hexagonal or trigonal lattice angles (90, 90, 120), we get the expected labels.

from diffpy.structure import Lattice, Structure

import orix.crystal_map as ocm
import orix.quaternion as oqu
import orix.vector as ove

sym = oqu.symmetry.S6
fs = sym.fundamental_sector
v = fs.vertices

structure = Structure(lattice=Lattice(1, 1, 1, 90, 90, 120))
phase = ocm.Phase(
    point_group=sym,
    structure=structure,
)
print(phase.structure.lattice.base)
# [[ 1.         0.         0.       ]
#  [-0.5        0.8660254  0.       ]
#  [ 0.         0.         1.       ]]

t = ove.Miller(xyz=v.data, phase=phase)
t.coordinate_format = "UVTW"
print(t.round())
# Miller (3,), point group -3, UVTW
# [[ 2. -1. -1.  0.]
#  [ 0.  0. -0.  1.]
#  [-1.  2. -1.  0.]]

If we don't set the crystal structure in the Phase, we get incorrect labels:

phase = ocm.Phase(
    point_group=sym,
#    structure=structure,
)
print(phase.structure.lattice.base)
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

t = ove.Miller(xyz=v.data, phase=phase)
t.coordinate_format = "UVTW"
print(t.round())
# Miller (3,), point group -3, UVTW
# [[ 2. -1. -1.  0.]
#  [ 0.  0. -0.  1.]
#  [-5.  6. -1.  0.]]

This carries on to the creation of the fundamental sector labels:

https://github.com/pyxem/orix/blob/ce19a5248674194cad08b45fd77d68ff84305ba6/orix/plot/inverse_pole_figure_plot.py#L471-L475

We don't supply a hexagonal lattice, thus, the [UVTW] labels are incorrect.

The solution is to ensure an hexagonal lattice is used in Phase.structure when creating a phase with a hexagonal or trigonal. This should fix the labels.

hakonanes avatar Jul 03 '25 10:07 hakonanes

Ah, you're right, I was fixing the symptom, not the cause. my suggested way, all the plotting and most of the real space calculations are correct, but anything using reciprocal space b axis is wrong.

Thanks for this catch, everything makes more sense now. At the time, I couldn't understand why xyz and uvw were giving identical values for trigonal systems. I just assumed I misunderstood the definitions, but with this, everything falls into place

argerlt avatar Jul 03 '25 17:07 argerlt

Note that I showed the incorrect structure matrix when not giving an hexagonal lattice in my above example, it should be an identity matrix (and is now).

hakonanes avatar Jul 04 '25 04:07 hakonanes