Skip to content

Commit 7aecf99

Browse files
authored
Merge pull request #1761 from bnmajor/fiddle-instrument
Fiddle instrument
2 parents ba0b426 + b40a179 commit 7aecf99

10 files changed

+891
-197
lines changed

hexrdgui/constants.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ class PolarXAxisType:
7878

7979
DOCUMENTATION_URL = 'https://hexrdgui.readthedocs.io/'
8080

81+
FIDDLE_HDF5_PATH = [
82+
'ATTRIBUTES/SHOT_IMAGE/ATTRIBUTES/FRAME_IMAGESFRAME_IMAGES/0/DATA',
83+
'DATA'
84+
]
85+
8186
KNOWN_HDF5_PATHS = [
8287
['ATTRIBUTES/TARGET_ORIENTED_IMAGE/DATA', 'DATA'],
8388
['ATTRIBUTES/PINHOLE_ORIENTED_IMAGE/DATA', 'DATA'],
@@ -87,6 +92,7 @@ class PolarXAxisType:
8792
['ATTRIBUTES/TIME_ADJUSTED_IMAGE/DATA', 'DATA'],
8893
['ATTRIBUTES/PSL_IMAGE/DATA', 'DATA'],
8994
['DATA', 'DATA'],
95+
FIDDLE_HDF5_PATH,
9096
]
9197

9298
DEFAULT_LIMITED_CMAPS = [
@@ -99,6 +105,7 @@ class LLNLTransform:
99105
IP3 = UI_TRANS_INDEX_FLIP_VERTICALLY
100106
IP4 = UI_TRANS_INDEX_FLIP_VERTICALLY
101107
PXRDIP = UI_TRANS_INDEX_FLIP_HORIZONTALLY
108+
FIDDLE = UI_TRANS_INDEX_FLIP_HORIZONTALLY
102109

103110

104111
KNOWN_DETECTOR_NAMES = {
@@ -145,3 +152,5 @@ class LLNLTransform:
145152
"Rotate 180°",
146153
"Rotate 270°"
147154
]
155+
156+
FIDDLE_FRAMES = 4

hexrdgui/hexrd_config.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import h5py
1010
import matplotlib
1111
import numpy as np
12+
from scipy.signal import medfilt2d
1213
import yaml
1314

1415
import hexrd.imageseries.save
@@ -18,6 +19,7 @@
1819
from hexrd.instrument.physics_package import HEDPhysicsPackage
1920
from hexrd.material import load_materials_hdf5, save_materials_hdf5, Material
2021
from hexrd.rotations import RotMatEuler
22+
from hexrd.utils.decorators import memoize
2123
from hexrd.utils.yaml import NumpyToNativeDumper
2224
from hexrd.valunits import valWUnit
2325

@@ -331,6 +333,7 @@ def __init__(self):
331333
self._physics_package = None
332334
self._detector_coatings = {}
333335
self._instrument_rigid_body_params = {}
336+
self._median_filer_correction = {}
334337

335338
# Make sure that the matplotlib font size matches the application
336339
self.font_size = self.font_size
@@ -434,6 +437,8 @@ def _attributes_to_persist(self):
434437
('custom_polar_tth_distortion_object_serialized', None),
435438
('detector_coatings_dictified', {}),
436439
('overlays_dictified', []),
440+
('apply_median_filter_correction', False),
441+
('median_filter_kernel_size', 7),
437442
]
438443

439444
# Provide a mapping from attribute names to the keys used in our state
@@ -563,6 +568,8 @@ def load_from_state(self, state):
563568
self.show_all_colormaps = self.show_all_colormaps == 'true'
564569
if not isinstance(self.apply_absorption_correction, bool):
565570
self.apply_absorption_correction = self.apply_absorption_correction == 'true'
571+
if not isinstance(self.apply_median_filter_correction, bool):
572+
self.apply_median_filter_correction = self.apply_median_filter_correction == 'true'
566573

567574
# This is None sometimes. Make sure it is an empty list instead.
568575
if self.recent_state_files is None:
@@ -973,6 +980,13 @@ def intensity_corrected_images_dict(self):
973980
for name, img in images_dict.items():
974981
images_dict[name] = img - minimum
975982

983+
if HexrdConfig().apply_median_filter_correction:
984+
for name, img in images_dict.items():
985+
images_dict[name] = medfilt2d_memoized(
986+
img,
987+
kernel_size=HexrdConfig().median_filter_kernel_size
988+
)
989+
976990
return images_dict
977991

978992
@property
@@ -2479,6 +2493,7 @@ def any_intensity_corrections(self):
24792493
'apply_lorentz_correction',
24802494
'intensity_subtract_minimum',
24812495
'apply_absorption_correction',
2496+
'apply_median_filter_correction',
24822497
]
24832498

24842499
return any(getattr(self, x) for x in corrections)
@@ -2992,3 +3007,30 @@ def update_detector_phosphor(self, det_name, **kwargs):
29923007
self._set_detector_coatings('phosphor')
29933008
phosphor = self._detector_coatings[det_name]['phosphor']
29943009
phosphor.deserialize(**kwargs)
3010+
3011+
@property
3012+
def apply_median_filter_correction(self):
3013+
return self._median_filer_correction.get('apply', False)
3014+
3015+
@apply_median_filter_correction.setter
3016+
def apply_median_filter_correction(self, v):
3017+
if v != self.apply_median_filter_correction:
3018+
self._median_filer_correction['apply'] = v
3019+
self.deep_rerender_needed.emit()
3020+
3021+
@property
3022+
def median_filter_kernel_size(self):
3023+
return self._median_filer_correction.get('kernel', 7)
3024+
3025+
@median_filter_kernel_size.setter
3026+
def median_filter_kernel_size(self, v):
3027+
if v != self.median_filter_kernel_size:
3028+
self._median_filer_correction['kernel'] = int(v)
3029+
self.deep_rerender_needed.emit()
3030+
3031+
3032+
# This is set to (num_fiddle_plates * num_time_steps) + num_image_plates
3033+
# This feature is primarily for FIDDLE
3034+
@memoize(maxsize=21)
3035+
def medfilt2d_memoized(img: np.ndarray, kernel_size: int):
3036+
return medfilt2d(img, kernel_size)

hexrdgui/interactive_template.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def key_rotation_angle(self):
6969
@key_rotation_angle.setter
7070
def key_rotation_angle(self, angle=None):
7171
if angle is None:
72-
angle = KEY_ROTATE_ANGLE
72+
angle = KEY_ROTATE_ANGLE_FINE
7373
self._key_angle = angle
7474

7575
def update_image(self, img):
@@ -83,10 +83,15 @@ def rotate_shape(self, angle):
8383
def create_polygon(self, verts, **polygon_kwargs):
8484
self.complete = False
8585
self.shape = patches.Polygon(verts, **polygon_kwargs)
86+
self.outer_polygon = self.shape
8687
if has_nan(verts):
8788
# This template contains more than one polygon and the last point
8889
# should not be connected to the first. See Tardis IP for example.
8990
self.shape.set_closed(False)
91+
# For the sake of checking events we only need the outer polygon
92+
nans = np.where(np.isnan(verts))
93+
boundary = self.shape.xy[:nans[0][0]]
94+
self.outer_polygon = patches.Polygon(boundary)
9095
self.shape_styles.append(polygon_kwargs)
9196
self.update_position()
9297
self.connect_translate_rotate()
@@ -331,7 +336,7 @@ def on_press_translate(self, event):
331336
if event.inaxes != self.shape.axes or self.event_key == 'shift':
332337
return
333338

334-
contains, info = self.shape.contains(event)
339+
contains, info = self.outer_polygon.contains(event)
335340
if not contains:
336341
return
337342
self.press = self.shape.xy, event.xdata, event.ydata
@@ -366,7 +371,7 @@ def on_press_rotate(self, event):
366371
if event.inaxes != self.shape.axes or self.event_key != 'shift':
367372
return
368373

369-
contains, info = self.shape.contains(event)
374+
contains, info = self.outer_polygon.contains(event)
370375
if not contains:
371376
return
372377
# FIXME: Need to come back to this to understand why we

0 commit comments

Comments
 (0)