Skip to content

Commit

Permalink
Merge pull request #1199 from psavery/hand-picked-indexing
Browse files Browse the repository at this point in the history
Add hand-picked indexing method
  • Loading branch information
joelvbernier authored Apr 26, 2022
2 parents 369a8a3 + 90acdec commit e9d06ab
Show file tree
Hide file tree
Showing 5 changed files with 842 additions and 34 deletions.
157 changes: 157 additions & 0 deletions hexrd/ui/indexing/fiber_pick_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import numpy as np

from hexrd import constants as cnst
from hexrd.rotations import discreteFiber
from hexrd.transforms import xfcapi


def _pick_to_fiber(pick_coords, eta_ome_maps, map_index, step=0.5,
beam_vec=None, chi=0., as_expmap=True):
"""
Returns the orientations for the specified fiber parameters.
Parameters
----------
pick_coords : array_like
The (2, ) list/vector containing the pick coordinates as (eta, omega)
in DEGREES. This corresponds to the (column, row) or (x, y) dimensions
on the map.
eta_ome_maps : hexrd.xrdutil.utils.EtaOmeMaps
The eta-omega maps.
map_index : int
The index of the current map.
step : scalar, optional
The step size along the fiber in DEGREES. The default is 0.5.
chi : scalar, optional
The chi angle from the associated instrument (specifically,
`instr.chi`). The default is 0.
beam_vec : array_like, optional
The beam vector of the associated instrument (specifically,
`instr.beam_vector`). The default is None (giving [0, 0, -1]).
as_expmap : bool, optional
Flag for converting the output from qauternions to exponential map.
The default is True.
Returns
-------
qfib : numpy.ndarray
The array containing the fiber points as quaternions or exponential
map parameters, according to the `as_expmap` kwarg.
"""
pick_coords = np.atleast_1d(pick_coords).flatten()

if beam_vec is None:
beam_vec = cnst.beam_vec

ndiv = int(np.round(360./float(step)))

# grab the planeData instance from the maps
# !!! this should have a copy of planeData that has hkls consistent with
# the map data.
pd = eta_ome_maps.planeData
bmat = pd.latVecOps['B']

# the crystal direction (plane normal)
crys_dir = pd.hkls[:, map_index].reshape(3, 1)

# the sample direction
tth = pd.getTTh()[map_index] # !!! in radians
angs = np.atleast_2d(np.hstack([tth, np.radians(pick_coords)]))
samp_dir = xfcapi.anglesToGVec(
angs, bHat_l=beam_vec, chi=chi
).reshape(3, 1)

# make the fiber
qfib = discreteFiber(
crys_dir, samp_dir,
B=bmat, ndiv=ndiv,
invert=False,
csym=pd.getQSym(), ssym=None
)[0]

if as_expmap:
phis = 2.*np.arccos(qfib[0, :])
ns = xfcapi.unitRowVector(qfib[1:, :].T)
expmaps = phis*ns.T
return expmaps.T # (3, ndiv)
else:
return qfib.T # (4, ndiv)


def _angles_from_orientation(instr, eta_ome_maps, orientation):
"""
Return the (eta, omega) angles for a specified orientation consistent with
input EtaOmeMaps.
Parameters
----------
instr : hexrd.instrument.HEDMInstrument
The instrument instance used to generate the EtaOmeMaps.
eta_ome_maps : hexrd.xrdutil.utils.EtaOmeMaps
The eta-omega maps.
orientation : array_like
Either a (3, ) or (4, ) element vector specifying an orientation.
Raises
------
RuntimeError
If orientation has more than 4 elements.
Returns
-------
simulated_angles : list
A list with length = len(eta_ome_maps.dataStore) containing the angular
coordinates of all valid reflections for each map. If no valid points
exist for a particular map, the entry contains `None`. Otherwise,
the entry is a (2, p) array of the (eta, omega) coordinates in DEGREES
for the p valid reflections.
"""
plane_data = eta_ome_maps.planeData

# angle ranges from maps
eta_range = (eta_ome_maps.etaEdges[0], eta_ome_maps.etaEdges[-1])
ome_range = (eta_ome_maps.omeEdges[0], eta_ome_maps.omeEdges[-1])
ome_period = eta_ome_maps.omeEdges[0] + np.r_[0., 2*np.pi]

# need the hklids
hklids = [i['hklID'] for i in plane_data.hklDataList]

expmap = np.atleast_1d(orientation).flatten()
if len(expmap) == 4:
# have a quat; convert here
phi = 2.*np.arccos(expmap[0])
n = xfcapi.unitRowVector(expmap[1:])
expmap = phi*n
elif len(expmap) > 4:
raise RuntimeError(
"orientation must be a single exponential map or quaternion"
)

grain_param_list = [np.hstack([expmap, cnst.zeros_3, cnst.identity_6x1]), ]
sim_dict = instr.simulate_rotation_series(
plane_data, grain_param_list,
eta_ranges=[eta_range, ], ome_ranges=[ome_range, ],
ome_period=ome_period, wavelength=None
)

rids = []
angs = []
for sim in sim_dict.values():
rids.append(sim[0][0])
angs.append(sim[2][0])
rids = np.hstack(rids)
angs = np.vstack(angs)

simulated_angles = []
for rid in hklids:
this_idx = rids == rid
if np.any(this_idx):
simulated_angles.append(
np.degrees(np.atleast_2d(angs[this_idx, 1:]))
)
else:
simulated_angles.append(None)

return simulated_angles
3 changes: 3 additions & 0 deletions hexrd/ui/indexing/ome_maps_select_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def update_config(self):
# Set the new config options on the internal config
indexing_config = HexrdConfig().indexing_config
maps_config = indexing_config['find_orientations']['orientation_maps']
maps_config['_select_method'] = self.method_name
maps_config['file'] = self.file_name
maps_config['threshold'] = self.threshold
maps_config['bin_frames'] = self.bin_frames
Expand All @@ -162,6 +163,8 @@ def update_gui(self):
indexing_config = HexrdConfig().indexing_config
maps_config = indexing_config['find_orientations']['orientation_maps']

self.method_name = maps_config.get('_select_method', 'load')

file_name = maps_config['file'] if maps_config['file'] else ''

self.ui.file_name.setText(file_name)
Expand Down
Loading

0 comments on commit e9d06ab

Please sign in to comment.