mantidproject / mantid

Main repository for Mantid code
https://www.mantidproject.org
GNU General Public License v3.0
207 stars 122 forks source link

Add methods to find consistent UBs and optimise goniometer axes and angles in ISIS single-crystal classes #37599

Open RichardWaiteSTFC opened 1 week ago

RichardWaiteSTFC commented 1 week ago

Description of work

This PR adds 2 features:

Fixes #35713 - albeit with different solution (doesn't change FindGoniometerFromUB algorithm) Fixes #36907

Further detail of work

To test:

(1) To test making a set of consistent UBs

from mantid.simpleapi import *
import numpy as np
from Diffraction.single_crystal.sxd import SXD

sxd = SXD(detcal_path="SXD34330_peaks_detcal.xml")

omega = [-45.0, 10.0, 10.0]
chi = [-38.0, -38.0, 0.0]
runs = list(range(34363,34366))

pk_ws_list = []
for irun, run in enumerate(runs):
    ws = sxd.load_run(run)
    SetGoniometer(Workspace=ws, Axis0=str(omega[irun])+',0,1,0,1',Axis1=str(chi[irun]) + ',1,0,0,-1')
    peaks_ws = sxd.find_sx_peaks(ws, PeakFindingStrategy="IOverSigma", NCols=7, NRows=7, NFWHM=6, ThresholdIoverSigma=15)
    sxd.remove_peaks_on_detector_edge(peaks_ws, 1)
    # set goniometer on peaks workspace for later use
    SetGoniometer(Workspace=peaks_ws, Axis0=str(omega[irun])+',0,1,0,1',Axis1=str(chi[irun]) + ',1,0,0,-1')
    pk_ws_list.append(peaks_ws)              

# optimise set of consistent UBs independently (could also use FindGlobalBMatrix)
iref = len(omega) - 1 # use last workspace
FindUBUsingFFT(PeaksWorkspace=pk_ws_list[iref], MinD=1, MaxD=20, DegreesPerStep=0.5)
for irun, peaks in enumerate(pk_ws_list):
    sxd.find_consistent_ub(pk_ws_list[iref], peaks, hkl_tol=0.15)
    predicted_peaks = PredictPeaks(InputWorkspace=peaks, WavelengthMin=0.3, MinDSpacing=1, ReflectionCondition='Primitive', 
                                   OutputWorkspace=peaks + '_indep_predicted', EnableLogging=False)
    print("ub of ", peaks)
    print(np.round(predicted_peaks.sample().getOrientedLattice().getUB(),3))  # should be very similar but not quite the same

The UBs should be very similar but maybe the 2nd or 3rd decimal point will be different.

(2) Optimise the goniometer axis and angles

axes, angles = SXD.optimize_goniometer_axis(pk_ws_list, iaxis=1, euler_axes="yz", fix_angles=False)

print("axes = ", np.round(axes,2))
# axes =  [[ 0.    1.    0.  ]
#          [-1.    0.   -0.04]]

print("angles = ", np.round(angles,2))
# angles =  [[-45.   -40.41]
#            [ 10.   -40.56]
#            [ 10.     0.76]]

Reviewer

Please comment on the points listed below (full description). Your comments will be used as part of the gatekeeper process, so please comment clearly on what you have checked during your review. If changes are made to the PR during the review process then your final comment will be the most important for gatekeepers. In this comment you should make it clear why any earlier review is still valid, or confirm that all requested changes have been addressed.

Code Review

Functional Tests

Does everything look good? Mark the review as Approve. A member of @mantidproject/gatekeepers will take care of it.

Gatekeeper

If you need to request changes to a PR then please add a comment and set the review status to "Request changes". This will stop the PR from showing up in the list for other gatekeepers.