Skip to content

Commit 4ea30e9

Browse files
committed
Apply all corrections after SNIP in polar
We will just now combine all intensity corrections together, warp them to the polar view, and apply them after SNIP... Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
1 parent 3cd8ee3 commit 4ea30e9

File tree

2 files changed

+84
-53
lines changed

2 files changed

+84
-53
lines changed

hexrdgui/calibration/polarview.py

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from skimage.transform import warp
66

77
from hexrd.transforms.xfcapi import mapAngle
8+
from hexrd.utils.warnings import ignore_warnings
89

910
from hexrd import constants as ct
1011
from hexrd.xrdutil import (
@@ -54,11 +55,14 @@ def __init__(self, instrument, distortion_instrument=None):
5455
else:
5556
# Use an image dict with the panel buffers applied.
5657
# This keeps invalid pixels from bleeding out in the polar view
57-
self.images_dict = HexrdConfig().images_dict
58+
self.images_dict = HexrdConfig().raw_images_dict
5859
# 0 is a better fill value because it results in fewer nans in
5960
# the final image.
6061
HexrdConfig().apply_panel_buffer_to_images(self.images_dict, 0)
6162

63+
# Update the intensity corrections. They'll be used later.
64+
self.update_intensity_corrections()
65+
6266
self.warp_dict = {}
6367

6468
self.raw_img = None
@@ -395,8 +399,8 @@ def apply_image_processing(self):
395399
img = self.raw_img.data
396400
img = self.apply_snip(img)
397401

398-
# Always apply absorption correction after snip
399-
img = self.apply_absorption_correction(img)
402+
# Always apply intensity corrections after snip
403+
img = self.apply_intensity_corrections(img)
400404

401405
# cache this step so we can just re-apply masks if needed
402406
self.snipped_img = img
@@ -444,21 +448,35 @@ def apply_snip(self, img):
444448

445449
return img
446450

447-
def apply_absorption_correction(self, img):
448-
if not HexrdConfig().apply_absorption_correction:
451+
def apply_intensity_corrections(self, img):
452+
if not HexrdConfig().any_intensity_corrections:
453+
# No corrections
449454
return img
450455

451-
# Warp the absorption correction images to the polar view,
452-
# sum them, and apply.
453-
absorption_corrections = HexrdConfig().absorption_corrections_dict
456+
# Warp the intensity corrections to polar, mean them, and apply
457+
intensity_corrections = HexrdConfig().intensity_corrections_dict
454458

455459
output = {}
456460
for det_key, panel in self.detectors.items():
457-
corrections = absorption_corrections[det_key]
461+
corrections = intensity_corrections[det_key]
458462
output[det_key] = self.warp_image(corrections, panel)
459463

460-
correction_field = np.ma.sum(np.ma.stack(output.values()), axis=0)
461-
return img * correction_field.data
464+
stacked = np.ma.stack(output.values()).filled(np.nan)
465+
466+
# It's okay to have all nan-slices here, but it produces a warning.
467+
# Just ignore the warning.
468+
with ignore_warnings(RuntimeWarning):
469+
# In case there are overlapping detectors, we do nanmean for
470+
# the intensities instead of nansum. This would produce a
471+
# somewhat more reasonable intensity.
472+
correction_field = np.nanmean(stacked, axis=0)
473+
474+
img *= correction_field
475+
476+
if HexrdConfig().intensity_subtract_minimum:
477+
img -= np.nanmin(img)
478+
479+
return img
462480

463481
def apply_visible_masks(self, img):
464482
# Apply user-specified masks if they are present
@@ -530,16 +548,16 @@ def warp_all_images(self):
530548
# Generate the final image
531549
self.generate_image()
532550

533-
def update_images_dict(self):
551+
def update_intensity_corrections(self):
534552
if HexrdConfig().any_intensity_corrections:
535-
self.images_dict = HexrdConfig().images_dict
553+
HexrdConfig().create_intensity_corrections_dict()
536554

537555
def update_detectors(self, detectors):
538556
self.reset_cached_distortion_fields()
539557

540558
# If there are intensity corrections and the detector transform
541-
# has been modified, we need to update the images dict.
542-
self.update_images_dict()
559+
# has been modified, we need to update the intensity corrections.
560+
self.update_intensity_corrections()
543561

544562
# First, convert to the "None" angle convention
545563
iconfig = HexrdConfig().instrument_config_none_euler_convention

hexrdgui/hexrd_config.py

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ def __init__(self):
325325
self._physics_package = None
326326
self._detector_coatings = {}
327327
self._instrument_rigid_body_params = {}
328-
self.absorption_corrections_dict = {}
328+
self.intensity_corrections_dict = {}
329329

330330
# Make sure that the matplotlib font size matches the application
331331
self.font_size = self.font_size
@@ -912,75 +912,88 @@ def raw_images_dict(self):
912912
def intensity_corrected_images_dict(self):
913913
"""Performs intensity corrections, if any, before returning"""
914914
images_dict = self.raw_images_dict
915-
916915
if not self.any_intensity_corrections:
917916
# No intensity corrections. Return.
918917
return images_dict
919918

919+
# Create this corrections dict, even if we don't use it, because
920+
# it updates the `intensity_corrections_dict` that may be used
921+
# elsewhere.
922+
corrections_dict = self.create_intensity_corrections_dict()
923+
if (
924+
self.image_mode not in
925+
(constants.ViewType.polar, constants.ViewType.stereo)
926+
):
927+
# If it's not polar or stereo, go ahead and apply the
928+
# corrections
929+
for name in images_dict:
930+
images_dict[name] *= corrections_dict[name]
931+
932+
# In the polar view, minimum will be subtracted later
933+
if self.intensity_subtract_minimum:
934+
minimum = min([np.nanmin(x) for x in images_dict.values()])
935+
for name in images_dict:
936+
images_dict[name] -= minimum
937+
938+
return images_dict
939+
940+
def create_intensity_corrections_dict(self) -> dict:
941+
# The corrections dict is both stored in `intensity_corrections_dict`
942+
# and returned from this function.
943+
corrections_dict = self.intensity_corrections_dict
944+
corrections_dict.clear()
945+
920946
# Some methods require an instrument. Go ahead and create one.
921947
from hexrdgui.create_hedm_instrument import create_hedm_instrument
922948
instr = create_hedm_instrument()
923949

924-
if HexrdConfig().apply_pixel_solid_angle_correction:
925-
sangle = dict.fromkeys(images_dict.keys())
950+
# Initialize the intensity corrections dict as ones
951+
for det_key, panel in instr.detectors.items():
952+
corrections_dict[det_key] = np.ones(panel.shape)
953+
954+
if not self.any_intensity_corrections:
955+
return corrections_dict
956+
957+
if self.apply_pixel_solid_angle_correction:
958+
sangle = dict.fromkeys(instr.detectors)
926959
mi = np.finfo(np.float64).max # largest floating point number
927960
# normalize by minimum of the entire instrument
928961
# not each detector individually
929-
for name, img in images_dict.items():
930-
panel = instr.detectors[name]
962+
for name, panel in instr.detectors.items():
931963
sangle[name] = panel.pixel_solid_angles
932964
mi = np.min((mi, sangle[name].min()))
933-
for name, img in images_dict.items():
934-
images_dict[name] = mi * img / sangle[name]
935965

936-
if HexrdConfig().apply_polarization_correction:
966+
for name in sangle:
967+
corrections_dict[name] *= mi / sangle[name]
968+
969+
if self.apply_polarization_correction:
937970
options = self.config['image']['polarization']
938971
kwargs = {
939972
'unpolarized': options['unpolarized'],
940973
'f_hor': options['f_hor'],
941974
'f_vert': options['f_vert'],
942975
}
943976

944-
for name, img in images_dict.items():
945-
panel = instr.detectors[name]
977+
for name, panel in instr.detectors.items():
946978
factor = panel.polarization_factor(**kwargs)
947-
images_dict[name] = img / factor
979+
corrections_dict[name] /= factor
948980

949-
if HexrdConfig().apply_lorentz_correction:
950-
for name, img in images_dict.items():
951-
panel = instr.detectors[name]
981+
if self.apply_lorentz_correction:
982+
for name, panel in instr.detectors.items():
952983
factor = panel.lorentz_factor()
953-
images_dict[name] = img / factor
954-
955-
HexrdConfig().absorption_corrections_dict.clear()
956-
if HexrdConfig().apply_absorption_correction:
957-
absorption_corrections = HexrdConfig().absorption_corrections_dict
984+
corrections_dict[name] /= factor
958985

986+
if self.apply_absorption_correction:
959987
transmissions = instr.calc_transmission()
960988
max_transmission = max(
961989
[np.nanmax(v) for v in transmissions.values()])
962990

963-
for name, img in images_dict.items():
964-
transmission = transmissions[name]
991+
for name, transmission in transmissions.items():
965992
# normalize by maximum of the entire instrument
966993
transmission /= max_transmission
967-
absorption_corrections[name] = 1 / transmission
968-
969-
if (
970-
HexrdConfig().image_mode not in
971-
(constants.ViewType.polar, constants.ViewType.stereo)
972-
):
973-
# If it's not polar or stereo, go ahead and apply the
974-
# corrections
975-
for name, img in images_dict.items():
976-
images_dict[name] = img * absorption_corrections[name]
977-
978-
if HexrdConfig().intensity_subtract_minimum:
979-
minimum = min([np.nanmin(x) for x in images_dict.values()])
980-
for name, img in images_dict.items():
981-
images_dict[name] = img - minimum
994+
corrections_dict[name] /= transmission
982995

983-
return images_dict
996+
return corrections_dict
984997

985998
@property
986999
def images_dict(self):

0 commit comments

Comments
 (0)