#!/usr/bin/env python3
"""Widgets for tilt correction."""
import numpy as np
import panel as pn
import param
from imars3d.backend.diagnostics.tilt import tilt_correction
[docs]
class TiltCorrection(param.Parameterized):
"""Tilt correction widget.
Widget for tilt correction from iMars3D, must have parent widget with valid
ct stack.
"""
#
parent = param.Parameter()
#
tilt_search_bounds = param.Range(default=(-5.0, 5.0), doc="tilt angle search range")
cut_off_angle_deg = param.Number(default=1e-3, doc="ignore tilt angle below this value")
#
execute = param.Action(lambda x: x.param.trigger("execute"), label="Execute")
status = param.Boolean(default=False, doc="IFC completion status")
[docs]
@param.depends("execute", watch=True)
def apply(self):
"""Apply tilt correction."""
if self.parent.ct is None:
pn.state.notifications.warning("no CT found", duration=3000)
else:
# perform tilt correction
self.parent.ct = tilt_correction(
arrays=self.parent.ct,
omegas=np.radians(self.parent.omegas),
low_bound=self.tilt_search_bounds[0],
high_bound=self.tilt_search_bounds[1],
cut_off_angle_deg=self.cut_off_angle_deg,
)
#
self.status = True
#
pn.state.notifications.success("Tilt correction complete.", duration=3000)
[docs]
def panel(self, width=200):
"""App card view."""
#
tilt_search_bounds_input = pn.widgets.LiteralInput.from_param(
self.param.tilt_search_bounds,
name="tilt search range (deg)",
)
cutoff_angle_input = pn.widgets.LiteralInput.from_param(
self.param.cut_off_angle_deg,
name="cutoff tilt angle (deg)",
)
#
status_indicator = pn.widgets.BooleanStatus.from_param(
self.param.status,
color="success",
)
execute_button = pn.widgets.Button.from_param(
self.param.execute,
width=width // 2,
)
#
app = pn.Column(
tilt_search_bounds_input,
cutoff_angle_input,
pn.Row(status_indicator, execute_button, width=width),
width=width,
)
return app