Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9cbea6b
Add the new FIDDLE instrument
Dec 11, 2024
96adf7b
Add hdf5 path to known paths list
Dec 11, 2024
26d252d
Support manually loading images and dark files
Dec 12, 2024
4714948
Try to automatically match images and dark files
Dec 12, 2024
78f17a2
Improve naming for clarity
Dec 12, 2024
96ded23
Make sure that the transform option is enabled on image load
Dec 16, 2024
eef07ba
Add property to simplify check for template
Dec 16, 2024
7f2aee7
Add some inline comments for clarity
Dec 16, 2024
340c575
PEP8 fixes & use consistent formatting
Dec 16, 2024
05f08b0
Infer which values are detectors and which are image plates
Dec 16, 2024
5b67dca
Add support for median filter intensity correction
Dec 17, 2024
d576bd9
Only apply one template to an image at a time
Dec 17, 2024
0130af3
Duplicate image plate image if it exists
Dec 17, 2024
7cdaf70
PEP8 fixes
Dec 17, 2024
e5ee684
Add default config for FIDDLE instrument
Dec 18, 2024
9d2141b
Memoize median filter results for FIDDLE
psavery Dec 18, 2024
913f178
Refactor median kernel into its own dialog
Dec 22, 2024
1316801
Make sure kernel size is always stored as an int
Dec 22, 2024
0b60914
Do not apply the median filter during import
Dec 22, 2024
bfff57e
Re-organize reset function for readability
Dec 22, 2024
3709948
Automatically flip FIDDLE image plate
Dec 22, 2024
19b303d
Do not assume that dark files end with "003"
bnmajor Feb 26, 2025
af25d47
Fix event check for translate/rotate template
bnmajor Feb 28, 2025
49224ef
Fix constant value
bnmajor Feb 28, 2025
6bb2113
Improve final dialogs
bnmajor Feb 28, 2025
71be9ad
Rescale colormap range when a new image is loaded
bnmajor Feb 28, 2025
8cd08aa
Remember images directory
bnmajor Feb 28, 2025
38024aa
Make sure we are not transforming detector images
bnmajor Feb 28, 2025
ca61976
Disable detecor image load during image plate load
bnmajor Feb 28, 2025
ecf99ee
Fix import fort/ordering
bnmajor Mar 20, 2025
e37b3aa
Fix formatting
bnmajor Mar 20, 2025
1c94d55
Use overall shape min for all imgs as kernel upper bound
bnmajor Mar 20, 2025
b40a179
Enforce odd values only
bnmajor Mar 20, 2025
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
9 changes: 9 additions & 0 deletions hexrdgui/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class PolarXAxisType:

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

FIDDLE_HDF5_PATH = [
'ATTRIBUTES/SHOT_IMAGE/ATTRIBUTES/FRAME_IMAGESFRAME_IMAGES/0/DATA',
'DATA'
]

KNOWN_HDF5_PATHS = [
['ATTRIBUTES/TARGET_ORIENTED_IMAGE/DATA', 'DATA'],
['ATTRIBUTES/PINHOLE_ORIENTED_IMAGE/DATA', 'DATA'],
Expand All @@ -87,6 +92,7 @@ class PolarXAxisType:
['ATTRIBUTES/TIME_ADJUSTED_IMAGE/DATA', 'DATA'],
['ATTRIBUTES/PSL_IMAGE/DATA', 'DATA'],
['DATA', 'DATA'],
FIDDLE_HDF5_PATH,
]

DEFAULT_LIMITED_CMAPS = [
Expand All @@ -99,6 +105,7 @@ class LLNLTransform:
IP3 = UI_TRANS_INDEX_FLIP_VERTICALLY
IP4 = UI_TRANS_INDEX_FLIP_VERTICALLY
PXRDIP = UI_TRANS_INDEX_FLIP_HORIZONTALLY
FIDDLE = UI_TRANS_INDEX_FLIP_HORIZONTALLY


KNOWN_DETECTOR_NAMES = {
Expand Down Expand Up @@ -137,3 +144,5 @@ class LLNLTransform:
"Rotate 180°",
"Rotate 270°"
]

FIDDLE_FRAMES = 4
42 changes: 42 additions & 0 deletions hexrdgui/hexrd_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import h5py
import matplotlib
import numpy as np
from scipy.signal import medfilt2d
import yaml

import hexrd.imageseries.save
Expand All @@ -18,6 +19,7 @@
from hexrd.instrument.physics_package import HEDPhysicsPackage
from hexrd.material import load_materials_hdf5, save_materials_hdf5, Material
from hexrd.rotations import RotMatEuler
from hexrd.utils.decorators import memoize
from hexrd.utils.yaml import NumpyToNativeDumper
from hexrd.valunits import valWUnit

Expand Down Expand Up @@ -326,6 +328,7 @@ def __init__(self):
self._physics_package = None
self._detector_coatings = {}
self._instrument_rigid_body_params = {}
self._median_filer_correction = {}

# Make sure that the matplotlib font size matches the application
self.font_size = self.font_size
Expand Down Expand Up @@ -435,6 +438,8 @@ def _attributes_to_persist(self):
('custom_polar_tth_distortion_object_serialized', None),
('detector_coatings_dictified', {}),
('overlays_dictified', []),
('apply_median_filter_correction', False),
('median_filter_kernel_size', 7),
]

# Provide a mapping from attribute names to the keys used in our state
Expand Down Expand Up @@ -551,6 +556,8 @@ def load_from_state(self, state):
self.show_all_colormaps = self.show_all_colormaps == 'true'
if not isinstance(self.apply_absorption_correction, bool):
self.apply_absorption_correction = self.apply_absorption_correction == 'true'
if not isinstance(self.apply_median_filter_correction, bool):
self.apply_median_filter_correction = self.apply_median_filter_correction == 'true'

# This is None sometimes. Make sure it is an empty list instead.
if self.recent_state_files is None:
Expand Down Expand Up @@ -1002,6 +1009,13 @@ def intensity_corrected_images_dict(self):
for name, img in images_dict.items():
images_dict[name] = img - minimum

if HexrdConfig().apply_median_filter_correction:
for name, img in images_dict.items():
images_dict[name] = medfilt2d_memoized(
img,
kernel_size=HexrdConfig().median_filter_kernel_size
)

return images_dict

@property
Expand Down Expand Up @@ -2674,6 +2688,7 @@ def any_intensity_corrections(self):
'apply_lorentz_correction',
'intensity_subtract_minimum',
'apply_absorption_correction',
'apply_median_filter_correction',
]

return any(getattr(self, x) for x in corrections)
Expand Down Expand Up @@ -3190,3 +3205,30 @@ def update_detector_phosphor(self, det_name, **kwargs):
self._set_detector_coatings('phosphor')
phosphor = self._detector_coatings[det_name]['phosphor']
phosphor.deserialize(**kwargs)

@property
def apply_median_filter_correction(self):
return self._median_filer_correction.get('apply', False)

@apply_median_filter_correction.setter
def apply_median_filter_correction(self, v):
if v != self.apply_median_filter_correction:
self._median_filer_correction['apply'] = v
self.deep_rerender_needed.emit()

@property
def median_filter_kernel_size(self):
return self._median_filer_correction.get('kernel', 7)

@median_filter_kernel_size.setter
def median_filter_kernel_size(self, v):
if v != self.median_filter_kernel_size:
self._median_filer_correction['kernel'] = int(v)
self.deep_rerender_needed.emit()


# This is set to (num_fiddle_plates * num_time_steps) + num_image_plates
# This feature is primarily for FIDDLE
@memoize(maxsize=21)
def medfilt2d_memoized(img: np.ndarray, kernel_size: int):
return medfilt2d(img, kernel_size)
11 changes: 8 additions & 3 deletions hexrdgui/interactive_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def key_rotation_angle(self):
@key_rotation_angle.setter
def key_rotation_angle(self, angle=None):
if angle is None:
angle = KEY_ROTATE_ANGLE
angle = KEY_ROTATE_ANGLE_FINE
self._key_angle = angle

def update_image(self, img):
Expand All @@ -83,10 +83,15 @@ def rotate_shape(self, angle):
def create_polygon(self, verts, **polygon_kwargs):
self.complete = False
self.shape = patches.Polygon(verts, **polygon_kwargs)
self.outer_polygon = self.shape
if has_nan(verts):
# This template contains more than one polygon and the last point
# should not be connected to the first. See Tardis IP for example.
self.shape.set_closed(False)
# For the sake of checking events we only need the outer polygon
nans = np.where(np.isnan(verts))
boundary = self.shape.xy[:nans[0][0]]
self.outer_polygon = patches.Polygon(boundary)
self.shape_styles.append(polygon_kwargs)
self.update_position()
self.connect_translate_rotate()
Expand Down Expand Up @@ -331,7 +336,7 @@ def on_press_translate(self, event):
if event.inaxes != self.shape.axes or self.event_key == 'shift':
return

contains, info = self.shape.contains(event)
contains, info = self.outer_polygon.contains(event)
if not contains:
return
self.press = self.shape.xy, event.xdata, event.ydata
Expand Down Expand Up @@ -366,7 +371,7 @@ def on_press_rotate(self, event):
if event.inaxes != self.shape.axes or self.event_key != 'shift':
return

contains, info = self.shape.contains(event)
contains, info = self.outer_polygon.contains(event)
if not contains:
return
# FIXME: Need to come back to this to understand why we
Expand Down
Loading
Loading