Skip to content

Commit

Permalink
Merge pull request #1767 from HEXRD/cartesian-fix
Browse files Browse the repository at this point in the history
get cartesian view invalid pixels to be nan.
  • Loading branch information
saransh13 authored Dec 19, 2024
2 parents 164b618 + d38e5a7 commit 95e7586
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 9 deletions.
29 changes: 25 additions & 4 deletions hexrdgui/calibration/cartesian_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@
def cartesian_viewer():
return InstrumentViewer()

def get_xray_propagation_sign(instr):
return np.sign(instr.beam_vector[2])

class InstrumentViewer:

def __init__(self):
self.type = ViewType.cartesian
self.instr = create_hedm_instrument()
self.images_dict = HexrdConfig().images_dict

# Set invalid pixels to be nan
HexrdConfig().apply_panel_buffer_to_images(self.images_dict)

self.img = None

# Perform some checks before proceeding
Expand All @@ -40,7 +46,8 @@ def __init__(self):
self.detector_corners = {}

dist = HexrdConfig().cartesian_virtual_plane_distance
dplane_tvec = np.array([0., 0., -dist])
sgn = get_xray_propagation_sign(self.instr)
dplane_tvec = np.array([0., 0., sgn*dist])

rotate_x = HexrdConfig().cartesian_plane_normal_rotate_x
rotate_y = HexrdConfig().cartesian_plane_normal_rotate_y
Expand Down Expand Up @@ -280,8 +287,15 @@ def create_warped_image(self, detector_id):

res = tf.warp(img, tform3,
output_shape=(self.dpanel.rows, self.dpanel.cols),
preserve_range=True)
self.warp_dict[detector_id] = res
preserve_range=True, cval=np.nan)
nan_mask = np.isnan(res)

self.warp_dict[detector_id] = np.ma.masked_array(
res,
mask=nan_mask,
fill_value=0,
)

return res

@property
Expand All @@ -290,8 +304,15 @@ def display_img(self):

def generate_image(self):
img = np.zeros((self.dpanel.rows, self.dpanel.cols))
always_nan = np.ones(img.shape, dtype=bool)
for key in self.images_dict.keys():
img += self.warp_dict[key]
# Use zeros when summing, but identify pixels that
# are nans in all images and set those to nan.
warp_img = self.warp_dict[key]
img += warp_img.filled(0)
always_nan = np.logical_and(always_nan, warp_img.mask)

img[always_nan] = np.nan

# In case there were any nans...
nan_mask = np.isnan(img)
Expand Down
21 changes: 17 additions & 4 deletions hexrdgui/hexrd_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,12 @@ def load_from_state(self, state):
pinhole_settings.pop('pinhole_radius') * 2
)

if self.cartesian_virtual_plane_distance < 0:
# We used to allow this to be negative, but now must be positive.
# Taking the absolute value should correct this adequately.
self.cartesian_virtual_plane_distance = abs(
self.cartesian_virtual_plane_distance)

# All QSettings come back as strings. So check that we are dealing with
# a boolean and convert if necessary
if not isinstance(self.live_update, bool):
Expand Down Expand Up @@ -2511,7 +2517,8 @@ def _cartesian_pixel_size(self):
def _set_cartesian_pixel_size(self, v):
if v != self.cartesian_pixel_size:
self.config['image']['cartesian']['pixel_size'] = v
self.rerender_needed.emit()
if self.image_mode == constants.ViewType.cartesian:
self.rerender_needed.emit()

cartesian_pixel_size = property(_cartesian_pixel_size,
_set_cartesian_pixel_size)
Expand All @@ -2520,9 +2527,13 @@ def _cartesian_virtual_plane_distance(self):
return self.config['image']['cartesian']['virtual_plane_distance']

def set_cartesian_virtual_plane_distance(self, v):
if v < 0:
raise RuntimeError(f'Invalid plane distance: {v}')

if v != self.cartesian_virtual_plane_distance:
self.config['image']['cartesian']['virtual_plane_distance'] = v
self.rerender_needed.emit()
if self.image_mode == constants.ViewType.cartesian:
self.rerender_needed.emit()

cartesian_virtual_plane_distance = property(
_cartesian_virtual_plane_distance,
Expand All @@ -2534,7 +2545,8 @@ def _cartesian_plane_normal_rotate_x(self):
def set_cartesian_plane_normal_rotate_x(self, v):
if v != self.cartesian_plane_normal_rotate_x:
self.config['image']['cartesian']['plane_normal_rotate_x'] = v
self.rerender_needed.emit()
if self.image_mode == constants.ViewType.cartesian:
self.rerender_needed.emit()

cartesian_plane_normal_rotate_x = property(
_cartesian_plane_normal_rotate_x,
Expand All @@ -2546,7 +2558,8 @@ def _cartesian_plane_normal_rotate_y(self):
def set_cartesian_plane_normal_rotate_y(self, v):
if v != self.cartesian_plane_normal_rotate_y:
self.config['image']['cartesian']['plane_normal_rotate_y'] = v
self.rerender_needed.emit()
if self.image_mode == constants.ViewType.cartesian:
self.rerender_needed.emit()

cartesian_plane_normal_rotate_y = property(
_cartesian_plane_normal_rotate_y,
Expand Down
3 changes: 3 additions & 0 deletions hexrdgui/image_mode_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def __init__(self, parent=None):
# Always start with raw tab
self.ui.tab_widget.setCurrentIndex(0)

# Don't allow negative distances
self.ui.cartesian_virtual_plane_distance.setMinimum(1e-8)

# Hide stereo_project_from_polar for now, as projecting from polar
# appears to give a better image (lines up better with overlays)
# than projecting from raw.
Expand Down
5 changes: 4 additions & 1 deletion hexrdgui/resources/ui/image_mode_widget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<property name="iconSize">
<size>
Expand Down Expand Up @@ -167,6 +167,9 @@
<property name="decimals">
<number>8</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
Expand Down

0 comments on commit 95e7586

Please sign in to comment.