Source code for hyperspy_gui_anywidget.tools

"""Interactive tool widgets for HyperSpy signals using anywidget."""

import traits.api as t
from hyperspy.signal_tools import (
    IMAGE_CONTRAST_EDITOR_HELP_IPYWIDGETS,
    SPIKES_REMOVAL_INSTRUCTIONS,
)
from link_traits import link

from hyperspy_gui_anywidget.custom_widgets import (
    ButtonWidget,
    CheckboxWidget,
    ContainerWidget,
    FloatRangeSliderWidget,
    FloatSliderWidget,
    FloatTextWidget,
    HTMLWidget,
    IntProgressWidget,
    IntSliderWidget,
    IntTextWidget,
    LabelWidget,
    OddIntSliderWidget,
    TextWidget,
    ToggleButtonWidget,
)
from hyperspy_gui_anywidget.utils import (
    _Dropdown,
    add_display_arg,
    enum2dropdown,
    labelme,
)


[docs] @add_display_arg def interactive_range_aw(obj, **kwargs): """Build a widget for interactive range selection. Parameters ---------- obj : hyperspy.signal_tools.InteractiveRangeSelector The interactive range selector instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} axis = obj.axis left = FloatTextWidget(disabled=True, description="Left") right = FloatTextWidget(disabled=True, description="Right") units = LabelWidget() help_text = HTMLWidget( value=( "Click on the signal figure and drag to the right to select a signal " "range. Press `Apply` to perform the operation or `Close` to cancel." ) ) help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) close = ButtonWidget( description="Close", tooltip="Close widget and remove span selector from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Perform the operation using the selected range.", ) wdict["left"] = left wdict["right"] = right wdict["units"] = units wdict["help_text"] = help_text wdict["close_button"] = close wdict["apply_button"] = apply link((obj, "ss_left_value"), (left, "value")) link((obj, "ss_right_value"), (right, "value")) link((axis, "units"), (units, "value")) def on_apply_clicked(change): if obj.ss_left_value != obj.ss_right_value: obj.span_selector_switch(False) for method, cls in obj.on_close: method(cls, obj.ss_left_value, obj.ss_right_value) obj.span_selector_switch(True) apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.span_selector_switch(False) if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") box = ContainerWidget( children=[ ContainerWidget( children=[left, units, LabelWidget(value="-"), right, units], layout="horizontal" ), help, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def calibrate2d_aw(obj, **kwargs): """Build a widget for 2D signal calibration. Parameters ---------- obj : hyperspy.signal_tools.Calibrate2D The 2D calibration tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} length = FloatTextWidget(disabled=True, description="Current length") scale = FloatTextWidget(disabled=True, description="Scale") new_length = FloatTextWidget(disabled=False, description="New length") units = TextWidget(description="Units") unitsl = LabelWidget() help_text = HTMLWidget( value=( "Click on the signal figure and drag line to some feature with a " "known size. Set the new length, then press `Apply` to update both " "the x- and y-dimensions in the signal, or press `Close` to cancel. " "The units can also be set with `Units`" ) ) wdict["help_text"] = help_text help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) close = ButtonWidget( description="Close", tooltip="Close widget and remove line from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Set the x- and y-scaling with the `scale` value.", ) link((obj, "length"), (length, "value")) link((obj, "new_length"), (new_length, "value")) link((obj, "units"), (units, "value")) link((obj, "units"), (unitsl, "value")) link((obj, "scale"), (scale, "value")) def on_apply_clicked(change): obj.apply() obj.on = False apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() # disconnects _line.events.changed then sets obj.on = False if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") box = ContainerWidget( children=[ ContainerWidget(children=[new_length, unitsl], layout="horizontal"), length, scale, units, help, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) wdict["length"] = length wdict["scale"] = scale wdict["new_length"] = new_length wdict["units"] = units wdict["close_button"] = close wdict["apply_button"] = apply return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def calibrate_aw(obj, **kwargs): """Build a widget for 1D signal calibration. Parameters ---------- obj : hyperspy.signal_tools.Calibrate The 1D calibration tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} left = FloatTextWidget(disabled=True, description="Left") right = FloatTextWidget(disabled=True, description="Right") offset = FloatTextWidget(disabled=True, description="Offset") scale = FloatTextWidget(disabled=True, description="Scale") new_left = FloatTextWidget(disabled=False, description="New left") new_right = FloatTextWidget(disabled=False, description="New right") units = TextWidget(description="Units") unitsl = LabelWidget() help_text = HTMLWidget( value=( "Click on the signal figure and drag to the right to select a signal " "range. Set the new left and right values and press `Apply` to update " "the calibration of the axis with the new values or press " " `Close` to cancel." ) ) wdict["help_text"] = help_text help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) close = ButtonWidget( description="Close", tooltip="Close widget and remove span selector from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Set the axis calibration with the `offset` and `scale` values above.", ) link((obj, "ss_left_value"), (left, "value")) link((obj, "ss_right_value"), (right, "value")) link((obj, "left_value"), (new_left, "value")) link((obj, "right_value"), (new_right, "value")) link((obj, "units"), (units, "value")) link((obj, "units"), (unitsl, "value")) link((obj, "offset"), (offset, "value")) link((obj, "scale"), (scale, "value")) def on_apply_clicked(change): if (new_left.value, new_right.value) != (0, 0): if new_left.value == 0 and obj.left_value is t.Undefined: obj.left_value = 0 elif new_right.value == 0 and obj.right_value is t.Undefined: obj.right_value = 0 obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.span_selector_switch(False) if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") box = ContainerWidget( children=[ ContainerWidget(children=[new_left, unitsl], layout="horizontal"), ContainerWidget(children=[new_right, unitsl], layout="horizontal"), ContainerWidget(children=[left, unitsl], layout="horizontal"), ContainerWidget(children=[right, unitsl], layout="horizontal"), ContainerWidget(children=[offset, unitsl], layout="horizontal"), ContainerWidget(children=[scale], layout="horizontal"), ContainerWidget(children=[units], layout="horizontal"), help, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) wdict["left"] = left wdict["right"] = right wdict["offset"] = offset wdict["scale"] = scale wdict["new_left"] = new_left wdict["new_right"] = new_right wdict["units"] = units wdict["close_button"] = close wdict["apply_button"] = apply return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def smooth_savitzky_golay_aw(obj, **kwargs): """Build a widget for Savitzky-Golay smoothing. Parameters ---------- obj : hyperspy.signal_tools.SmoothSavitzkyGolay The smoothing tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} window_length = OddIntSliderWidget( value=3, step=2, min=3, max=max(int(obj.axis.size * 0.25), 3), description="Window length", slider_width="220px", ) polynomial_order = IntSliderWidget( value=3, min=1, max=window_length.value - 1, description="Polynomial order", slider_width="220px", ) def update_bound(change): polynomial_order.max = change.new - 1 window_length.observe(update_bound, names="value") differential_order = IntSliderWidget( value=0, min=0, max=10, description="Differential order", slider_width="220px", ) color = TextWidget(description="Color") close = ButtonWidget( description="Close", tooltip="Close widget and remove the smoothed line from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Perform the operation using the selected range.", ) link((obj, "polynomial_order"), (polynomial_order, "value")) link((obj, "window_length"), (window_length, "value")) link((obj, "differential_order"), (differential_order, "value")) def update_diff_max(change): differential_order.max = change.new polynomial_order.observe(update_diff_max, names="value") link((obj, "line_color_ipy"), (color, "value")) box = ContainerWidget( children=[ window_length, polynomial_order, differential_order, color, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) wdict["window_length"] = window_length wdict["polynomial_order"] = polynomial_order wdict["differential_order"] = differential_order wdict["color"] = color wdict["close_button"] = close wdict["apply_button"] = apply def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def smooth_lowess_aw(obj, **kwargs): """Build a widget for LOWESS smoothing. Parameters ---------- obj : hyperspy.signal_tools.SmoothLowess The LOWESS smoothing tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} smoothing_parameter = FloatSliderWidget(min=0, max=1, description="Smoothing parameter") number_of_iterations = IntTextWidget(description="Number of iterations") color = TextWidget(description="Color") close = ButtonWidget( description="Close", tooltip="Close widget and remove the smoothed line from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Perform the operation using the selected range.", ) link((obj, "smoothing_parameter"), (smoothing_parameter, "value")) link((obj, "number_of_iterations"), (number_of_iterations, "value")) link((obj, "line_color_ipy"), (color, "value")) box = ContainerWidget( children=[ smoothing_parameter, labelme("Number of iterations", number_of_iterations), color, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) wdict["smoothing_parameter"] = smoothing_parameter wdict["number_of_iterations"] = number_of_iterations wdict["color"] = color wdict["close_button"] = close wdict["apply_button"] = apply def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def smooth_tv_aw(obj, **kwargs): """Build a widget for total variation smoothing. Parameters ---------- obj : hyperspy.signal_tools.SmoothTV The total variation smoothing tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} smoothing_parameter = FloatSliderWidget(min=0.1, max=1000, description="Weight") smoothing_parameter_max = FloatTextWidget( value=smoothing_parameter.max, description="Weight max" ) color = TextWidget(description="Color") close = ButtonWidget( description="Close", tooltip="Close widget and remove the smoothed line from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Perform the operation using the selected range.", ) link((obj, "smoothing_parameter"), (smoothing_parameter, "value")) link((smoothing_parameter_max, "value"), (smoothing_parameter, "max")) link((obj, "line_color_ipy"), (color, "value")) wdict["smoothing_parameter"] = smoothing_parameter wdict["smoothing_parameter_max"] = smoothing_parameter_max wdict["color"] = color wdict["close_button"] = close wdict["apply_button"] = apply box = ContainerWidget( children=[ smoothing_parameter, labelme("Weight max", smoothing_parameter_max), color, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def remove_background_aw(obj, **kwargs): """Build a widget for background removal. Parameters ---------- obj : hyperspy.signal_tools.BackgroundRemoval The background removal tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} left = FloatTextWidget(disabled=True, description="Left") right = FloatTextWidget(disabled=True, description="Right") red_chisq = FloatTextWidget(disabled=True, description="red-χ²") link((obj, "ss_left_value"), (left, "value")) link((obj, "ss_right_value"), (right, "value")) link((obj, "red_chisq"), (red_chisq, "value")) fast = CheckboxWidget(description="Fast") zero_fill = CheckboxWidget(description="Zero Fill") help_text = HTMLWidget( value=( "Click on the signal figure and drag to the right to select a " "range. Press `Apply` to remove the background in the whole dataset. " 'If "Fast" is checked, the background parameters are estimated ' "using a fast (analytical) method that can compromise accuracy. " "When unchecked, non-linear least squares is employed instead. " 'If "Zero Fill" is checked, all the channels prior to the fitting ' "region will be set to zero. " "Otherwise the background subtraction will be performed in the " "pre-fitting region as well." ) ) wdict["help_text"] = help_text help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) close = ButtonWidget( description="Close", tooltip="Close widget and remove span selector from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Remove the background in the whole dataset.", ) polynomial_order = IntTextWidget(description="Polynomial order") background_type = enum2dropdown(obj.traits()["background_type"]) background_type.description = "Background type" def enable_poly_order(change): is_polynomial = change.new == "Polynomial" polynomial_order.disabled = not is_polynomial polynomial_order.visible = is_polynomial background_type.observe(enable_poly_order, names="value") link((obj, "background_type"), (background_type, "value")) class Dummy: new = background_type.value enable_poly_order(change=Dummy()) link((obj, "polynomial_order"), (polynomial_order, "value")) link((obj, "fast"), (fast, "value")) link((obj, "zero_fill"), (zero_fill, "value")) wdict["left"] = left wdict["right"] = right wdict["red_chisq"] = red_chisq wdict["fast"] = fast wdict["zero_fill"] = zero_fill wdict["polynomial_order"] = polynomial_order wdict["background_type"] = background_type wdict["apply_button"] = apply box = ContainerWidget( children=[ left, right, red_chisq, background_type, polynomial_order, fast, zero_fill, help, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) def on_apply_clicked(change): obj.apply() obj.span_selector_switch(False) apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.span_selector_switch(False) if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def image_constast_editor_aw(obj, **kwargs): """Build a widget for image contrast editing. Parameters ---------- obj : hyperspy.signal_tools.ImageContrastEditor The image contrast editor tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} left = FloatTextWidget(disabled=True, description="Vmin") right = FloatTextWidget(disabled=True, description="Vmax") bins = IntTextWidget(description="Bins") norm = enum2dropdown(obj.traits()["norm"]) norm.description = "Norm" norm.value = obj.norm percentile = FloatRangeSliderWidget( value=[0.0, 100.0], min=0.0, max=100.0, step=0.1, description="Vmin/vmax percentile" ) gamma = FloatSliderWidget(value=1.0, min=0.1, max=3.0, description="Gamma") linthresh = FloatSliderWidget( value=0.01, min=0.001, max=1.0, step=0.001, description="Linear threshold" ) linscale = FloatSliderWidget( value=0.1, min=0.001, max=10.0, step=0.001, description="Linear scale" ) auto = CheckboxWidget(value=True, description="Auto") help_text = HTMLWidget(value=IMAGE_CONTRAST_EDITOR_HELP_IPYWIDGETS) wdict["help_text"] = help_text help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) close = ButtonWidget(description="Close", tooltip="Close widget.") apply = ButtonWidget( description="Apply", tooltip="Use the selected range to re-calculate the histogram." ) reset = ButtonWidget(description="Reset", tooltip="Reset the settings to their initial values.") wdict["left"] = left wdict["right"] = right wdict["bins"] = bins wdict["norm"] = norm wdict["percentile"] = percentile wdict["gamma"] = gamma wdict["linthresh"] = linthresh wdict["linscale"] = linscale wdict["auto"] = auto wdict["close_button"] = close wdict["apply_button"] = apply wdict["reset_button"] = reset link((obj, "ss_left_value"), (left, "value")) link((obj, "ss_right_value"), (right, "value")) link((obj, "bins"), (bins, "value")) link((obj, "norm"), (norm, "value")) link((obj, "gamma"), (gamma, "value")) link((obj, "linthresh"), (linthresh, "value")) link((obj, "linscale"), (linscale, "value")) link((obj, "auto"), (auto, "value")) def on_percentile_change(change): obj.vmin_percentile = change.new[0] obj.vmax_percentile = change.new[1] percentile.observe(on_percentile_change, names="value") def on_vmin_change(change): percentile.value = [change.new, percentile.value[1]] obj.observe(on_vmin_change, "vmin_percentile") def on_vmax_change(change): percentile.value = [percentile.value[0], change.new] obj.observe(on_vmax_change, "vmax_percentile") def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_reset_clicked(change): obj.reset() reset.observe(on_reset_clicked, names="clicks") box = ContainerWidget( children=[ left, right, auto, percentile, bins, norm, gamma, linthresh, linscale, help, ContainerWidget(children=[apply, reset, close], layout="horizontal"), ], layout="vertical", ) def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def spikes_removal_aw(obj, **kwargs): """Build a widget for spikes removal. Parameters ---------- obj : hyperspy.signal_tools.SpikesRemoval The spikes removal tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} threshold = FloatTextWidget(description="Threshold") add_noise = CheckboxWidget(description="Add noise") default_spike_width = IntTextWidget(description="Default spike width") spline_order = IntSliderWidget(min=1, max=10, description="Spline order") progress_bar = IntProgressWidget(max=len(obj.coordinates) - 1, description="Progress") help_text = HTMLWidget(value=SPIKES_REMOVAL_INSTRUCTIONS.replace("\n", "<br/>")) help = ContainerWidget(children=[help_text], layout="accordion", titles=["Help"]) show_diff = ButtonWidget( description="Show derivative histogram", tooltip="This figure is useful to estimate the threshold.", ) close = ButtonWidget( description="Close", tooltip="Close widget and remove span selector from the signal figure.", ) next_btn = ButtonWidget(description="Find next", tooltip="Find next spike") previous = ButtonWidget(description="Find previous", tooltip="Find previous spike") remove = ButtonWidget(description="Remove spike", tooltip="Remove spike and find next one.") wdict["threshold"] = threshold wdict["add_noise"] = add_noise wdict["default_spike_width"] = default_spike_width wdict["spline_order"] = spline_order wdict["progress_bar"] = progress_bar wdict["show_diff_button"] = show_diff wdict["close_button"] = close wdict["next_button"] = next_btn wdict["previous_button"] = previous wdict["remove_button"] = remove def on_show_diff_clicked(change): obj._show_derivative_histogram_fired() show_diff.observe(on_show_diff_clicked, names="clicks") def on_next_clicked(change): obj.find() next_btn.observe(on_next_clicked, names="clicks") def on_previous_clicked(change): obj.find(back=True) previous.observe(on_previous_clicked, names="clicks") def on_remove_clicked(change): obj.apply() remove.observe(on_remove_clicked, names="clicks") link((obj, "threshold"), (threshold, "value")) link((obj, "add_noise"), (add_noise, "value")) link((obj, "default_spike_width"), (default_spike_width, "value")) link((obj, "spline_order"), (spline_order, "value")) link((obj, "index"), (progress_bar, "value")) advanced = ContainerWidget( children=[ labelme("Add noise", add_noise), labelme("Default spike width", default_spike_width), spline_order, ], layout="accordion", titles=["Advanced settings"], ) box = ContainerWidget( children=[ ContainerWidget( children=[ show_diff, labelme("Threshold", threshold), labelme("Progress", progress_bar), ], layout="vertical", ), advanced, help, ContainerWidget(children=[previous, next_btn, remove, close], layout="horizontal"), ], layout="vertical", ) def on_close_clicked(change): obj.span_selector_switch(False) if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def remove_baseline_aw(obj, **kwargs): """Build a widget for baseline removal. Parameters ---------- obj : hyperspy.signal_tools.BaselineRemoval The baseline removal tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} algorithm = enum2dropdown(obj.traits()["algorithm"], description="Method") _time_per_pixel = FloatTextWidget(disabled=True, description="Time per pixel (ms)") lam = FloatTextWidget(description="lam") diff_order = IntSliderWidget(min=1, max=3, description="diff_order") p = FloatSliderWidget(min=0.0, max=1.0, description="p") lam_1 = FloatSliderWidget(min=-10, max=0, description="lam_1") eta = FloatSliderWidget(min=0.0, max=1.0, description="eta") penalized_spline = CheckboxWidget(description="penalized_spline") poly_order = IntSliderWidget(min=1, max=10, description="poly_order") peak_ratio = FloatSliderWidget(min=0.0, max=1.0, description="peak_ratio") num_knots = IntSliderWidget(min=10, max=10000, description="num_knots") spline_degree = IntSliderWidget(min=1, max=5, description="spline_degree") symmetric = CheckboxWidget(description="symmetric") quantile = FloatSliderWidget(min=0.001, max=0.5, description="quantile") smooth_half_window = IntSliderWidget(min=1, max=100, description="smooth_half_window") num_std = IntSliderWidget(min=1, max=100, description="num_std") interp_half_window = IntSliderWidget(min=1, max=100, description="interp_half_window") half_window = IntSliderWidget(min=1, max=100, description="half_window") section = IntSliderWidget(min=1, max=100, description="section") segments = IntSliderWidget(min=1, max=100, description="segments") link((obj, "lam"), (lam, "value")) link((obj, "_time_per_pixel"), (_time_per_pixel, "value")) link((obj, "algorithm"), (algorithm, "value")) link((obj, "diff_order"), (diff_order, "value")) link((obj, "p"), (p, "value")) link((obj, "lam_1"), (lam_1, "value")) link((obj, "eta"), (eta, "value")) link((obj, "penalized_spline"), (penalized_spline, "value")) link((obj, "poly_order"), (poly_order, "value")) link((obj, "peak_ratio"), (peak_ratio, "value")) link((obj, "num_knots"), (num_knots, "value")) link((obj, "spline_degree"), (spline_degree, "value")) link((obj, "symmetric"), (symmetric, "value")) link((obj, "quantile"), (quantile, "value")) link((obj, "smooth_half_window"), (smooth_half_window, "value")) link((obj, "num_std"), (num_std, "value")) link((obj, "interp_half_window"), (interp_half_window, "value")) link((obj, "half_window"), (half_window, "value")) link((obj, "section"), (section, "value")) link((obj, "segments"), (segments, "value")) parameters_widget_dict = { "lam": lam, "diff_order": diff_order, "p": p, "lam_1": lam_1, "eta": eta, "penalized_spline": penalized_spline, "poly_order": poly_order, "peak_ratio": peak_ratio, "num_knots": num_knots, "spline_degree": spline_degree, "symmetric": symmetric, "quantile": quantile, "smooth_half_window": smooth_half_window, "num_std": num_std, "interp_half_window": interp_half_window, "half_window": half_window, "section": section, "segments": segments, } def update_algorithm_parameters(change): for parameter_name, parameter_widget in parameters_widget_dict.items(): if getattr(obj, f"_enable_{parameter_name}"): parameter_widget.disabled = False else: parameter_widget.disabled = True algorithm.observe(update_algorithm_parameters, names="value") class Dummy: new = algorithm.value update_algorithm_parameters(change=Dummy()) close = ButtonWidget( description="Close", tooltip="Close widget and remove baseline from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Remove the baseline in the whole dataset.", ) method_parameters = ContainerWidget( children=[value for value in parameters_widget_dict.values()], layout="accordion", titles=["Method parameters"], ) wdict["algorithm"] = algorithm wdict["_time_per_pixel"] = _time_per_pixel wdict["lam"] = lam wdict["diff_order"] = diff_order wdict["p"] = p wdict["lam_1"] = lam_1 wdict["eta"] = eta wdict["penalized_spline"] = penalized_spline wdict["poly_order"] = poly_order wdict["peak_ratio"] = peak_ratio wdict["num_knots"] = num_knots wdict["spline_degree"] = spline_degree wdict["symmetric"] = symmetric wdict["quantile"] = quantile wdict["smooth_half_window"] = smooth_half_window wdict["num_std"] = num_std wdict["interp_half_window"] = interp_half_window wdict["half_window"] = half_window wdict["section"] = section wdict["segments"] = segments wdict["apply"] = apply box = ContainerWidget( children=[ algorithm, _time_per_pixel, method_parameters, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def smooth_butterworth_aw(obj, **kwargs): """Build a widget for Butterworth smoothing. Parameters ---------- obj : hyperspy.signal_tools.SmoothButterworth The Butterworth smoothing tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} cutoff = FloatSliderWidget(min=0.01, max=1.0, description="Cutoff") order = IntTextWidget(description="Order") type_ = _Dropdown(options=["low", "high"], value="low", description="Type") color = TextWidget(description="Color") close = ButtonWidget( description="Close", tooltip="Close widget and remove the smoothed line from the signal figure.", ) apply = ButtonWidget( description="Apply", tooltip="Perform the operation using the selected range.", ) link((obj, "cutoff_frequency_ratio"), (cutoff, "value")) link((obj, "type"), (type_, "value")) link((obj, "order"), (order, "value")) link((obj, "line_color_ipy"), (color, "value")) wdict["cutoff"] = cutoff wdict["order"] = order wdict["type"] = type_ wdict["color"] = color wdict["close_button"] = close wdict["apply_button"] = apply box = ContainerWidget( children=[ cutoff, labelme("Type", type_), labelme("Order", order), color, ContainerWidget(children=[apply, close], layout="horizontal"), ], layout="vertical", ) def on_apply_clicked(change): obj.apply() apply.observe(on_apply_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }
[docs] @add_display_arg def find_peaks2D_aw(obj, **kwargs): """Build a widget for 2D peak finding. Parameters ---------- obj : hyperspy.signal_tools.PeakFinder2D The 2D peak finder tool instance. **kwargs Passed through to the widget builder. Returns ------- dict or None ``{"widget": ContainerWidget, "wdict": {...}}`` when ``display=False``, otherwise ``None`` (widget displayed inline). """ wdict = {} local_max_distance = IntSliderWidget(min=1, max=20, value=3, description="Distance") local_max_threshold = FloatSliderWidget(min=0, max=20, value=10, description="Threshold") max_alpha = FloatSliderWidget(min=0, max=6, value=3, description="Alpha") max_distance = IntSliderWidget(min=1, max=20, value=10, description="Distance") minmax_distance = FloatSliderWidget(min=0, max=6, value=3, description="Distance") minmax_threshold = FloatSliderWidget(min=0, max=20, value=10, description="Threshold") zaefferer_grad_threshold = FloatSliderWidget( min=0, max=0.2, value=0.1, step=0.2 * 1e-1, description="Gradient threshold" ) zaefferer_window_size = IntSliderWidget(min=2, max=80, value=40, description="Window size") zaefferer_distance_cutoff = FloatSliderWidget( min=0, max=100, value=50, description="Distance cutoff" ) stat_alpha = FloatSliderWidget(min=0, max=2, value=1, description="Alpha") stat_window_radius = IntSliderWidget(min=5, max=20, value=10, description="Radius") stat_convergence_ratio = FloatSliderWidget( min=0, max=0.1, value=0.05, description="Convergence ratio" ) log_min_sigma = FloatSliderWidget(min=0, max=2, value=1, description="Min sigma") log_max_sigma = FloatSliderWidget(min=0, max=100, value=50, description="Max sigma") log_num_sigma = FloatSliderWidget(min=0, max=20, value=10, description="Num sigma") log_threshold = FloatSliderWidget(min=0, max=0.4, value=0.2, description="Threshold") log_overlap = FloatSliderWidget(min=0, max=1, value=0.5, description="Overlap") log_log_scale = CheckboxWidget(value=False, description="Log scale") dog_min_sigma = FloatSliderWidget(min=0, max=2, value=1, description="Min sigma") dog_max_sigma = FloatSliderWidget(min=0, max=100, value=50, description="Max sigma") dog_sigma_ratio = FloatSliderWidget(min=0, max=3.2, value=1.6, description="Sigma ratio") dog_threshold = FloatSliderWidget(min=0, max=0.4, value=0.2, description="Threshold") dog_overlap = FloatSliderWidget(min=0, max=1, value=0.5, description="Overlap") xc_distance = FloatSliderWidget(min=0, max=10.0, value=5.0, description="Distance") xc_threshold = FloatSliderWidget(min=0, max=2.0, value=0.5, description="Threshold") wdict["local_max_distance"] = local_max_distance wdict["local_max_threshold"] = local_max_threshold wdict["max_alpha"] = max_alpha wdict["max_distance"] = max_distance wdict["minmax_distance"] = minmax_distance wdict["minmax_threshold"] = minmax_threshold wdict["zaefferer_grad_threshold"] = zaefferer_grad_threshold wdict["zaefferer_window_size"] = zaefferer_window_size wdict["zaefferer_distance_cutoff"] = zaefferer_distance_cutoff wdict["stat_alpha"] = stat_alpha wdict["stat_window_radius"] = stat_window_radius wdict["stat_convergence_ratio"] = stat_convergence_ratio wdict["log_min_sigma"] = log_min_sigma wdict["log_max_sigma"] = log_max_sigma wdict["log_num_sigma"] = log_num_sigma wdict["log_threshold"] = log_threshold wdict["log_overlap"] = log_overlap wdict["log_log_scale"] = log_log_scale wdict["dog_min_sigma"] = dog_min_sigma wdict["dog_max_sigma"] = dog_max_sigma wdict["dog_sigma_ratio"] = dog_sigma_ratio wdict["dog_threshold"] = dog_threshold wdict["dog_overlap"] = dog_overlap wdict["xc_distance"] = xc_distance wdict["xc_threshold"] = xc_threshold link((obj, "local_max_distance"), (local_max_distance, "value")) link((obj, "local_max_threshold"), (local_max_threshold, "value")) link((obj, "max_alpha"), (max_alpha, "value")) link((obj, "max_distance"), (max_distance, "value")) link((obj, "minmax_distance"), (minmax_distance, "value")) link((obj, "minmax_threshold"), (minmax_threshold, "value")) link((obj, "zaefferer_grad_threshold"), (zaefferer_grad_threshold, "value")) link((obj, "zaefferer_window_size"), (zaefferer_window_size, "value")) link((obj, "zaefferer_distance_cutoff"), (zaefferer_distance_cutoff, "value")) link((obj, "stat_alpha"), (stat_alpha, "value")) link((obj, "stat_window_radius"), (stat_window_radius, "value")) link((obj, "stat_convergence_ratio"), (stat_convergence_ratio, "value")) link((obj, "log_min_sigma"), (log_min_sigma, "value")) link((obj, "log_max_sigma"), (log_max_sigma, "value")) link((obj, "log_num_sigma"), (log_num_sigma, "value")) link((obj, "log_threshold"), (log_threshold, "value")) link((obj, "log_overlap"), (log_overlap, "value")) link((obj, "log_log_scale"), (log_log_scale, "value")) link((obj, "dog_min_sigma"), (dog_min_sigma, "value")) link((obj, "dog_max_sigma"), (dog_max_sigma, "value")) link((obj, "dog_sigma_ratio"), (dog_sigma_ratio, "value")) link((obj, "dog_threshold"), (dog_threshold, "value")) link((obj, "dog_overlap"), (dog_overlap, "value")) link((obj, "xc_distance"), (xc_distance, "value")) link((obj, "xc_threshold"), (xc_threshold, "value")) method = enum2dropdown(obj.traits()["method"]) link((obj, "method"), (method, "value")) close = ButtonWidget( description="Close", tooltip="Close widget and close figure.", ) compute = ButtonWidget( description="Compute over navigation axes.", tooltip="Find the peaks by iterating over the navigation axes.", ) box_local_max = ContainerWidget( children=[local_max_distance, local_max_threshold], layout="vertical", ) box_max = ContainerWidget( children=[max_alpha, max_distance], layout="vertical", ) box_minmax = ContainerWidget( children=[minmax_distance, minmax_threshold], layout="vertical", ) box_zaefferer = ContainerWidget( children=[ zaefferer_grad_threshold, zaefferer_window_size, zaefferer_distance_cutoff, ], layout="vertical", ) box_stat = ContainerWidget( children=[ stat_alpha, stat_window_radius, stat_convergence_ratio, ], layout="vertical", ) box_log = ContainerWidget( children=[ log_min_sigma, log_max_sigma, log_num_sigma, log_threshold, log_overlap, labelme("Log scale", log_log_scale), ], layout="vertical", ) box_dog = ContainerWidget( children=[ dog_min_sigma, dog_max_sigma, dog_sigma_ratio, dog_threshold, dog_overlap, ], layout="vertical", ) box_xc = ContainerWidget( children=[xc_distance, xc_threshold], layout="vertical", ) method_parameters = ContainerWidget( children=[ box_local_max, box_max, box_minmax, box_zaefferer, box_stat, box_log, box_dog, box_xc, ], layout="accordion", titles=["Method parameters"], ) widgets_list = [ labelme("Method", method), method_parameters, ContainerWidget(children=[compute, close], layout="horizontal"), ] box = ContainerWidget(children=widgets_list, layout="vertical") def on_compute_clicked(change): obj.compute_navigation() compute.observe(on_compute_clicked, names="clicks") def on_close_clicked(change): obj.close() if hasattr(box, "close"): box.close() close.observe(on_close_clicked, names="clicks") return { "widget": box, "wdict": wdict, }