From 3ac40d62d3a397ff7849194360d55b4e074ca0f0 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Fri, 8 Nov 2024 15:17:22 +0100 Subject: [PATCH 1/3] add filename, multifilename, string, multistring widgets --- src/ess/reduce/parameter.py | 5 ++ src/ess/reduce/widgets/__init__.py | 67 +++++++++++++++------- src/ess/reduce/widgets/_filename_widget.py | 40 +++++++++++++ src/ess/reduce/widgets/_string_widget.py | 40 +++++++++++++ src/ess/reduce/workflow.py | 9 +-- 5 files changed, 136 insertions(+), 25 deletions(-) create mode 100644 src/ess/reduce/widgets/_filename_widget.py create mode 100644 src/ess/reduce/widgets/_string_widget.py diff --git a/src/ess/reduce/parameter.py b/src/ess/reduce/parameter.py index df5cbe2c..78f193c8 100644 --- a/src/ess/reduce/parameter.py +++ b/src/ess/reduce/parameter.py @@ -126,6 +126,11 @@ class StringParameter(Parameter[str]): pass +@dataclass +class MultiStringParameter(Parameter[tuple[str, ...]]): + """Widget for entering multiple strings.""" + + @dataclass(kw_only=True) class ParamWithBounds(Parameter[T]): bounds: tuple[T, T] diff --git a/src/ess/reduce/widgets/__init__.py b/src/ess/reduce/widgets/__init__.py index 2459e9df..212994a3 100644 --- a/src/ess/reduce/widgets/__init__.py +++ b/src/ess/reduce/widgets/__init__.py @@ -10,6 +10,7 @@ BooleanParameter, FilenameParameter, MultiFilenameParameter, + MultiStringParameter, ParamWithOptions, StringParameter, Parameter, @@ -21,9 +22,11 @@ from ._config import default_layout, default_style from ._binedges_widget import BinEdgesWidget +from ._filename_widget import FilenameWidget, MultiFilenameWidget from ._linspace_widget import LinspaceWidget from ._vector_widget import VectorWidget from ._bounds_widget import BoundsWidget +from ._string_widget import StringWidget, MultiStringWidget from ._switchable_widget import SwitchWidget from ._optional_widget import OptionalWidget @@ -100,44 +103,64 @@ def boolean_parameter_widget(param: BooleanParameter): ) +# @create_parameter_widget.register(StringParameter) +# def string_parameter_widget(param: StringParameter): +# name = param.name +# description = param.description +# if param.switchable: +# return widgets.Text( +# description=name, +# tooltip=description, +# layout=default_layout, +# style=default_style, +# ) +# else: +# return widgets.Text( +# value=param.default, +# description=name, +# tooltip=description, +# layout=default_layout, +# style=default_style, +# ) + + @create_parameter_widget.register(StringParameter) def string_parameter_widget(param: StringParameter): - name = param.name - description = param.description - if param.switchable: - return widgets.Text( - description=name, - tooltip=description, - layout=default_layout, - style=default_style, - ) - else: - return widgets.Text( - value=param.default, - description=name, - tooltip=description, - layout=default_layout, - style=default_style, - ) + return StringWidget( + description=param.name, + value=param.default, + layout=default_layout, + style=default_style, + ) + + +@create_parameter_widget.register(MultiStringParameter) +def multi_string_parameter_widget(param: MultiStringParameter): + return MultiStringWidget( + description=param.name, + value=param.default, + layout=default_layout, + style=default_style, + ) @create_parameter_widget.register(FilenameParameter) def filename_parameter_widget(param: FilenameParameter): - return widgets.Text( + return FilenameWidget( description=param.name, + value=param.default, layout=default_layout, style=default_style, - value=param.default, ) @create_parameter_widget.register(MultiFilenameParameter) def multi_filename_parameter_widget(param: MultiFilenameParameter): - return widgets.Text( + return MultiFilenameWidget( description=param.name, + value=param.default, layout=default_layout, style=default_style, - value=param.default, ) @@ -183,7 +206,9 @@ def vector_3d_parameter_widget(param: Vector3dParameter): 'BinEdgesWidget', 'BoundsWidget', 'EssWidget', + 'FilenameWidget', 'LinspaceWidget', + 'MultiFilenameWidget', 'OptionalWidget', 'SwitchWidget', 'VectorWidget', diff --git a/src/ess/reduce/widgets/_filename_widget.py b/src/ess/reduce/widgets/_filename_widget.py new file mode 100644 index 00000000..705db564 --- /dev/null +++ b/src/ess/reduce/widgets/_filename_widget.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2024 Scipp contributors (https://github.com/scipp) +# import scipp as sc +from ipywidgets import HBox, Text, ValueWidget + +from ._config import default_layout + + +class FilenameWidget(HBox, ValueWidget): + def __init__(self, description: str, value: str | None = None, **kwargs): + super().__init__(layout=default_layout) + self.text_widget = Text(description=description, value=value, **kwargs) + self.children = [self.text_widget] + + @property + def value(self) -> str | None: + v = self.text_widget.value.strip() + if not v: + return None + return v + + @value.setter + def value(self, value: str | None): + if value is None: + self.text_widget.value = '' + else: + self.text_widget.value = value + + +class MultiFilenameWidget(FilenameWidget): + @property + def value(self) -> tuple[str, ...]: + v = super().value + if v is None: + return () + return tuple(s.strip() for s in v.split(',')) + + @value.setter + def value(self, value: tuple[str, ...]): + self.text_widget.value = ', '.join(value) diff --git a/src/ess/reduce/widgets/_string_widget.py b/src/ess/reduce/widgets/_string_widget.py new file mode 100644 index 00000000..00380d3a --- /dev/null +++ b/src/ess/reduce/widgets/_string_widget.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2024 Scipp contributors (https://github.com/scipp) +# import scipp as sc +from ipywidgets import HBox, Text, ValueWidget + +from ._config import default_layout + + +class StringWidget(HBox, ValueWidget): + def __init__(self, description: str, value: str | None = None, **kwargs): + super().__init__(layout=default_layout) + self.text_widget = Text(description=description, value=value, **kwargs) + self.children = [self.text_widget] + + @property + def value(self) -> str | None: + v = self.text_widget.value.strip() + if not v: + return None + return v + + @value.setter + def value(self, value: str | None): + if value is None: + self.text_widget.value = '' + else: + self.text_widget.value = value + + +class MultiStringWidget(StringWidget): + @property + def value(self) -> tuple[str, ...]: + v = super().value + if v is None: + return () + return tuple(s.strip() for s in v.split(',')) + + @value.setter + def value(self, value: tuple[str, ...]): + self.text_widget.value = ', '.join(value) diff --git a/src/ess/reduce/workflow.py b/src/ess/reduce/workflow.py index 7bdf46b3..f08f6030 100644 --- a/src/ess/reduce/workflow.py +++ b/src/ess/reduce/workflow.py @@ -86,10 +86,11 @@ def assign_parameter_values(pipeline: Pipeline, values: dict[Key, Any]) -> Pipel """Set a value for a parameter in the pipeline.""" pipeline = pipeline.copy() for key, value in values.items(): - if ( - isinstance(value, tuple) - and (mapper := parameter_mappers.get(key)) is not None - ): + # if ( + # isinstance(value, (tuple, list)) + # and (mapper := parameter_mappers.get(key)) is not None + # ): + if (mapper := parameter_mappers.get(key)) is not None: pipeline = mapper(pipeline, value) else: pipeline[key] = value From 8b11f91aeaa6ad2e405e9bfd9fd922c5ae334b73 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Thu, 28 Nov 2024 14:58:45 +0100 Subject: [PATCH 2/3] remove commented code --- src/ess/reduce/workflow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ess/reduce/workflow.py b/src/ess/reduce/workflow.py index f08f6030..7d2eba59 100644 --- a/src/ess/reduce/workflow.py +++ b/src/ess/reduce/workflow.py @@ -86,10 +86,6 @@ def assign_parameter_values(pipeline: Pipeline, values: dict[Key, Any]) -> Pipel """Set a value for a parameter in the pipeline.""" pipeline = pipeline.copy() for key, value in values.items(): - # if ( - # isinstance(value, (tuple, list)) - # and (mapper := parameter_mappers.get(key)) is not None - # ): if (mapper := parameter_mappers.get(key)) is not None: pipeline = mapper(pipeline, value) else: From 9870ce5c2d0d6fd058532abcca8b1eebd1349022 Mon Sep 17 00:00:00 2001 From: Neil Vaytet Date: Thu, 28 Nov 2024 15:33:12 +0100 Subject: [PATCH 3/3] reduce code duplication between stringwidget and filenamewidget --- src/ess/reduce/widgets/__init__.py | 23 +------------- src/ess/reduce/widgets/_filename_widget.py | 36 ++-------------------- src/ess/reduce/widgets/_string_widget.py | 1 - 3 files changed, 4 insertions(+), 56 deletions(-) diff --git a/src/ess/reduce/widgets/__init__.py b/src/ess/reduce/widgets/__init__.py index 78fd08de..27780af7 100644 --- a/src/ess/reduce/widgets/__init__.py +++ b/src/ess/reduce/widgets/__init__.py @@ -26,7 +26,7 @@ from ._linspace_widget import LinspaceWidget from ._vector_widget import VectorWidget from ._bounds_widget import BoundsWidget -from ._string_widget import StringWidget, MultiStringWidget +from ._string_widget import MultiStringWidget, StringWidget from ._switchable_widget import SwitchWidget from ._optional_widget import OptionalWidget @@ -102,27 +102,6 @@ def boolean_parameter_widget(param: BooleanParameter): ) -# @create_parameter_widget.register(StringParameter) -# def string_parameter_widget(param: StringParameter): -# name = param.name -# description = param.description -# if param.switchable: -# return widgets.Text( -# description=name, -# tooltip=description, -# layout=default_layout, -# style=default_style, -# ) -# else: -# return widgets.Text( -# value=param.default, -# description=name, -# tooltip=description, -# layout=default_layout, -# style=default_style, -# ) - - @create_parameter_widget.register(StringParameter) def string_parameter_widget(param: StringParameter): return StringWidget( diff --git a/src/ess/reduce/widgets/_filename_widget.py b/src/ess/reduce/widgets/_filename_widget.py index 705db564..ebda89d0 100644 --- a/src/ess/reduce/widgets/_filename_widget.py +++ b/src/ess/reduce/widgets/_filename_widget.py @@ -1,40 +1,10 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2024 Scipp contributors (https://github.com/scipp) -# import scipp as sc -from ipywidgets import HBox, Text, ValueWidget -from ._config import default_layout +from ._string_widget import MultiStringWidget, StringWidget -class FilenameWidget(HBox, ValueWidget): - def __init__(self, description: str, value: str | None = None, **kwargs): - super().__init__(layout=default_layout) - self.text_widget = Text(description=description, value=value, **kwargs) - self.children = [self.text_widget] +class FilenameWidget(StringWidget): ... - @property - def value(self) -> str | None: - v = self.text_widget.value.strip() - if not v: - return None - return v - @value.setter - def value(self, value: str | None): - if value is None: - self.text_widget.value = '' - else: - self.text_widget.value = value - - -class MultiFilenameWidget(FilenameWidget): - @property - def value(self) -> tuple[str, ...]: - v = super().value - if v is None: - return () - return tuple(s.strip() for s in v.split(',')) - - @value.setter - def value(self, value: tuple[str, ...]): - self.text_widget.value = ', '.join(value) +class MultiFilenameWidget(MultiStringWidget): ... diff --git a/src/ess/reduce/widgets/_string_widget.py b/src/ess/reduce/widgets/_string_widget.py index 00380d3a..dc1273f0 100644 --- a/src/ess/reduce/widgets/_string_widget.py +++ b/src/ess/reduce/widgets/_string_widget.py @@ -1,6 +1,5 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2024 Scipp contributors (https://github.com/scipp) -# import scipp as sc from ipywidgets import HBox, Text, ValueWidget from ._config import default_layout