Skip to content

Further rotation implementation problems #56

@pc494

Description

@pc494

Describe the bug
Following on from #46 further issues have been found with the rotation elements of the code. The presented example was that (-60,60,0) and (30,60,0) produce identical diffraction patterns.

Expected behavior
Using orix or similar you can find that these two rotations differ by a [0,0,1] 90 degree rotation. We would expect them to have different diffraction patterns (the produced patterns don't have 4 fold sym). Extracting the code from simulate_rotated_structure() we (@EirikOpheim and then I via a different work flow) find that the real space lattices are compliant with this.

This pushes us down the chain to calculate_ed_data() which uses the .reciprocal() of our (correct) inputs. It seems here is where the problem is.

Detail the problem
Calling get_point_in_sphere() an looking through the elements we find that for rotated structures the a,b and c values are different. The way the code is laid out what you really want to happen is the indexing to be done in the "normal" orientation and then the final results to be rotated.

Assuming the cartesian outputs are correct the rest of the code doesn't need to worry about the rotations.

Solution
The following seems to work better.

standard_base = diffpy.structure.lattice.Lattice(base=reciprocal_lattice.stdbase)
# changed from using reciprocal_lattice
a, b, c = standard_base.a, standard_base.b, standard_base.c
...
potential_points = np.asarray(list(product(h_list, k_list, l_list)))
#standard here rather than reciprocal
in_sphere = np.abs(standard_base.dist(potential_points, [0, 0, 0])) < reciprocal_radius
spot_indicies = potential_points[in_sphere]
# back to reciprocal for the cartesian conversion
spot_coords = reciprocal_lattice.cartesian(spot_indicies)

Running two cases (no rotation vs small [0.2rad ~ 11degrees] z rotation) supports this:


# same in both cases
spot_indicies =
array([[-1.,  0.,  0.],
       [ 0., -1.,  0.],
       [ 0.,  0., -1.],
       [ 0.,  0.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  0.],
       [ 1.,  0.,  0.]])
no_rotation_coords = 
array([[-0.33333333,  0.        ,  0.        ],
       [ 0.        , -0.33333333,  0.        ],
       [ 0.        ,  0.        , -0.33333333],
       [ 0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.33333333],
       [ 0.        ,  0.33333333,  0.        ],
       [ 0.33333333,  0.        ,  0.        ]])
# our lattice parameter was 3
small_rotation_coords = 
array([[-0.32668886,  0.06622311,  0.        ],
       [-0.06622311, -0.32668886,  0.        ],
       [ 0.        ,  0.        , -0.33333333],
       [ 0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.33333333],
       [ 0.06622311,  0.32668886,  0.        ],
       [ 0.32668886, -0.06622311,  0.        ]])

I plan on implementing this in the coming days.

Further thoughts
This section of the code could really do with some semi-physical testing. I think this should be fairly high on the v0.4 list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions