Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 86 additions & 1 deletion hexrdgui/llnl_import_tool_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from hexrd import resources as hexrd_resources
from hexrd.instrument import HEDMInstrument
from hexrd.rotations import (
angleAxisOfRotMat, make_rmat_euler, angles_from_rmat_zxz
angleAxisOfRotMat, make_rmat_euler, angles_from_rmat_zxz, rotMatOfExpMap
)

import hexrdgui.resources.calibration
Expand All @@ -39,6 +39,65 @@
from hexrdgui.utils.dialog import add_help_url


class AtlasConfig:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it'd be nicer if AtlasConfig was on its own separate file, such as atlas_config.py. But we can leave it for this PR.

def __init__(self, atlas_coords, instr):
self.coords = atlas_coords
self.instr = instr

def _get_orientation(self, crds, det):
"""vertex in 4x3 matrix of the
4 vertices. we return the normal
using a cross product
"""
vertex = self._get_vertices(crds)
if det == 'CAMERA-05':
xhat = -vertex[1, :] + vertex[0, :]
yhat = vertex[3, :] - vertex[0, :]
else:
xhat = vertex[3, :] - vertex[0, :]
yhat = vertex[1, :] - vertex[0, :]

xhat = xhat/np.linalg.norm(xhat)
yhat = yhat/np.linalg.norm(yhat)

zhat = np.cross(xhat, yhat)
zhat = zhat/np.linalg.norm(zhat)

xhat = np.cross(yhat, zhat)
xhat = xhat/np.linalg.norm(xhat)

rmat = np.vstack((-xhat, yhat, -zhat)).T

RMAT_Z_180 = rotMatOfExpMap(np.pi*zhat)
if det in ['CAMERA-02', 'CAMERA-03']:
return np.dot(RMAT_Z_180, rmat)
return rmat

def _get_center(self, vertex):
"""return center of detector given
the four vertex
"""
return np.mean(vertex, axis=0)

def _get_vertices(self, crds):
# by default we will look up from TCC, so there is
# flip in the x-component sign
return crds[0:4, :]

def update_instrument(self, detector):
v = self._get_vertices(self.coords[detector])
# tvec sample is the position of the sample in NIF
# chamber coordinates. the position of each detector
# is measured from this point, so we need to take this
# off
tvec_sample= np.array([0, 0, 9.8])
tvec = self._get_center(v) - tvec_sample
rmat = self._get_orientation(self.coords[detector], detector)
ang, ax = angleAxisOfRotMat(rmat)
self.instr.detectors[detector].tvec = tvec
self.instr.detectors[detector].tilt = ang * ax


class LLNLImportToolDialog(QObject):

# Emitted when new config is loaded
Expand Down Expand Up @@ -76,6 +135,7 @@ def __init__(self, cmap=None, parent=None):
self.loaded_images = []
self.canvas = parent.image_tab_widget.active_canvas
self.detector_images = {}
self.atlas_coords = None

# Disable these by default.
# If we disable these in Qt Designer, there are some weird bugs
Expand All @@ -99,6 +159,8 @@ def __init__(self, cmap=None, parent=None):
self.ui.detector_raw_image,
self.ui.instr_settings_label,
self.ui.instr_settings,
self.ui.load_atlas,
self.ui.atlas_label,
visible=False)

self.update_config_settings()
Expand Down Expand Up @@ -137,6 +199,7 @@ def setup_connections(self):
self.ui.dark_load.clicked.connect(self.load_detector_images)
self.ui.accept_detector.clicked.connect(
self.manually_load_detector_images)
self.ui.load_atlas.clicked.connect(self.load_atlas_coords)

def enable_widgets(self, *widgets, enabled):
for w in widgets:
Expand Down Expand Up @@ -263,6 +326,8 @@ def instrument_selected(self, idx):
self.ui.detector_raw_image,
self.ui.instr_settings_label,
self.ui.instr_settings,
self.ui.load_atlas,
self.ui.atlas_label,
visible=is_fiddle)

has_ip = self.ui.instr_settings.currentIndex() == 0
Expand Down Expand Up @@ -352,6 +417,16 @@ def update_config_settings(self):
if prev:
combo.setCurrentText(prev)

def load_atlas_coords(self):
file, filter = QFileDialog.getOpenFileName(
self.ui, 'Select coordinates file', dir=HexrdConfig().working_dir)
if not file:
return
with open(file, 'r') as f:
coords = yaml.safe_load(f)
self.atlas_coords = {d: np.array(c) for d, c in coords.items()}
self.ui.atlas_label.setText(Path(file).name)

def load_instrument_config(self):
temp = tempfile.NamedTemporaryFile(delete=False, suffix='.hexrd')
self.config_file = temp.name
Expand Down Expand Up @@ -813,6 +888,7 @@ def reset_panel(self):
self.clear_boundry()
# Reset internal state
self.completed = []
self.atlas_coords = None
self.defaults.clear()
self.config_file = None
self.import_in_progress = False
Expand All @@ -831,6 +907,7 @@ def reset_panel(self):
self.ui.config_file_label.setText('No File Selected')
self.ui.config_file_label.setToolTip(
'Defaults to currently loaded configuration')
self.ui.atlas_label.setText('No File Selected')
# Reset widget states - disable/enable/show/hide as appropriate
self.enable_widgets(
self.ui.image_plate_raw_image,
Expand All @@ -854,6 +931,8 @@ def reset_panel(self):
self.ui.detector_raw_image,
self.ui.instr_settings_label,
self.ui.instr_settings,
self.ui.load_atlas,
self.ui.atlas_label,
visible=False)
# We're all reset and ready to re-enable the main UI features
HexrdConfig().enable_image_mode_widget.emit(True)
Expand All @@ -871,6 +950,12 @@ def import_complete(self):

instr = HEDMInstrument(
instrument_config=self.ip_and_det_defaults['default_config'])

if self.atlas_coords is not None:
atlas_config = AtlasConfig(self.atlas_coords, instr)
for detector in self.detectors:
atlas_config.update_instrument(detector)

for det in self.completed:
panel = instr.detectors[det]
# first need the zxz Euler angles from the panel rotation matrix.
Expand Down
164 changes: 89 additions & 75 deletions hexrdgui/resources/ui/llnl_import_tool_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>565</width>
<height>854</height>
<height>883</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -24,6 +24,94 @@
<string>Instrument</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="1" column="0">
<widget class="QFrame" name="config">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Select Configuration</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="config_settings"/>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="load_atlas">
<property name="text">
<string>Load ATLAS Coordinates</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="config_selection">
<item>
<property name="text">
<string>Default configuration</string>
</property>
</item>
<item>
<property name="text">
<string>Currently loaded configuration</string>
</property>
</item>
<item>
<property name="text">
<string>Load configuration from file</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="load_config">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Load Instrument Config</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="config_settings_label">
<property name="text">
<string>Configuration Settings:</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLabel" name="config_file_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string extracomment="Defaults to currently loaded configuration"/>
</property>
<property name="text">
<string>No File Selected</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLabel" name="atlas_label">
<property name="text">
<string>No File Selected</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QFrame" name="instrument">
<property name="enabled">
Expand Down Expand Up @@ -112,80 +200,6 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="config">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="config_selection">
<item>
<property name="text">
<string>Default configuration</string>
</property>
</item>
<item>
<property name="text">
<string>Currently loaded configuration</string>
</property>
</item>
<item>
<property name="text">
<string>Load configuration from file</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="load_config">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Load Instrument Config</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Select Configuration</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLabel" name="config_file_label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string extracomment="Defaults to currently loaded configuration"/>
</property>
<property name="text">
<string>No File Selected</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="config_settings_label">
<property name="text">
<string>Configuration Settings:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QComboBox" name="config_settings"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
Loading