Skip to content

Commit d7774a4

Browse files
committed
Mask out invalid pixels in the polar view
This makes it so that any invalid pixels (as defined by the detector's panel buffer) do not have an effect on the resulting polar image and lineout. Any polar view pixels that were interpolated with an invalid pixel will be nan. The intended usage is as follows: ```python img = pv.warp_image(image_dict, pad_with_nans=True, do_interpolation=True) cake = np.mean(img, axis=0) ``` The `img` that is returned from the warp image is a masked array, with all invalid pixels being masked out. If `np.mean(img, axis=0)` is applied to this, it ignores all masked out pixels when computing the mean along the axis (which is the behavior we want). This is preferred over doing something like `np.sum(img.filled(0), axis=0)`, since columns with invalid pixels will be reduced in value. Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
1 parent c6f1247 commit d7774a4

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

hexrd/projections/polar.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
_project_on_detector_cylinder,
77
_project_on_detector_plane,
88
)
9+
from hexrd.utils.panel_buffer import panel_buffer_as_2d_array
910

1011

1112
class PolarView:
@@ -325,10 +326,25 @@ def _warp_image_from_coordinate_map(
325326
coordinate_map: dict[str, dict[str, np.ndarray]],
326327
pad_with_nans: bool = False,
327328
do_interpolation=True) -> np.ma.MaskedArray:
329+
330+
panel_buffer_fill_value = np.nan
328331
img_dict = dict.fromkeys(self.detectors)
329332
nan_mask = None
330333
for detector_id, panel in self.detectors.items():
331-
img = image_dict[detector_id]
334+
# Make a copy since we may modify
335+
img = image_dict[detector_id].copy()
336+
337+
# Before warping, mask out any pixels that are invalid,
338+
# so that they won't affect the results.
339+
buffer = panel_buffer_as_2d_array(panel)
340+
if (np.issubdtype(type(panel_buffer_fill_value), np.floating) and
341+
not np.issubdtype(img.dtype, np.floating)):
342+
# Convert to float. This is especially important
343+
# for nan, since it is a float...
344+
img = img.astype(float)
345+
346+
img[~buffer] = panel_buffer_fill_value
347+
332348
xypts = coordinate_map[detector_id]['xypts']
333349
on_panel = coordinate_map[detector_id]['on_panel']
334350

hexrd/utils/panel_buffer.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import numpy as np
2+
3+
from hexrd.instrument.detector import Detector
4+
5+
6+
def panel_buffer_as_2d_array(panel: Detector) -> np.ndarray:
7+
# Take whatever the panel buffer is and convert it to a 2D array
8+
if panel.panel_buffer is None:
9+
# Just make a panel buffer with all True values
10+
return np.ones(panel.shape, dtype=bool)
11+
elif panel.panel_buffer.shape == (2,):
12+
# The two floats are specifying the borders in mm for x and y.
13+
# Convert to pixel borders. Swap x and y so we have i, j in pixels.
14+
borders = np.round([
15+
panel.panel_buffer[1] / panel.pixel_size_row,
16+
panel.panel_buffer[0] / panel.pixel_size_col,
17+
]).astype(int)
18+
19+
# Convert to array
20+
panel_buffer = np.zeros(panel.shape, dtype=bool)
21+
22+
# We can't do `-borders[i]` since that doesn't work for 0,
23+
# so we must do `panel.shape[i] - borders[i]` instead.
24+
panel_buffer[borders[0]:panel.shape[0] - borders[0],
25+
borders[1]:panel.shape[1] - borders[1]] = True
26+
return panel_buffer
27+
elif panel.panel_buffer.ndim == 2:
28+
return panel.panel_buffer
29+
30+
raise NotImplementedError(panel.panel_buffer.ndim)

0 commit comments

Comments
 (0)