Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch/Optional widget fields setter/getter #148

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

YooSunYoung
Copy link
Member

@YooSunYoung YooSunYoung commented Dec 10, 2024

Fixes #140

I just merged all smaller PRs here after all since they all need each other to understand...

Here are review points

Treat value as one of fields.

The dictionary that is exported from the ParameterBox look like:

{
  type_object: { field_name_1: field_value_1 , field_name_2: field_value_2 }
}

At first I thought if the input widget doesn't have a field but a value, it should be like

{
  type_object: input_widget_value
}

But it made it difficult for wrapping widget like OptionalWidget or SwitchWidget to add their states into the exported dictionary so I updated the exported dictionary to be either

{
  type_object_1: { field_name_1: field_value_1 , field_name_2: field_value_2 },
  type_object_2: { 'value': input_widget_value }
}

So that wrapper widget can extend the dictionary with their state,
i.e. SwitchWidget has enabled so it'll look like

{
  type_object_1: { 'enabled': True/False, field_name_1: field_value_1 , field_name_2: field_value_2 },
  type_object_2: { 'enabled': True/False, 'value': input_widget_value }
}

It picks up the wrapper widget state key and forward the rest to the wrapped widget.

SwitchWidget

As explained above, SwitchWidget extends the widget state with enabled field.

OptionalWidget

Similar to the SwitchWidget, it extends the widget state with opted-out field.

The reason why it's not setting value as None instead of using opted-out flag is explained in the comment in the code.

enabled and opted-out fields.

The set_fields/get_fields methods of SwitchWidget and OptionalWidget are implemented assuming
the wrapped widget don't use the enabled or opted-out for setting/getting their fields.

I thought it's safe to do so because SwitchWidget will always control the availability of the wrapped widget,
so any other widgets will need to export/set enabled/disabled state themselves.

@YooSunYoung YooSunYoung marked this pull request as ready for review December 10, 2024 15:35
@YooSunYoung YooSunYoung force-pushed the save-parameters-optional branch from 917a62c to f37eefd Compare December 11, 2024 08:39
Base automatically changed from save-parameters to main December 11, 2024 11:51
@YooSunYoung YooSunYoung force-pushed the save-parameters-optional branch from f37eefd to 9288132 Compare December 11, 2024 11:51
@YooSunYoung YooSunYoung changed the title Optional widget fields setter/getter Switch/Optional widget fields setter/getter Dec 12, 2024
'y': 5,
'z': 3,
'unit': 'mm',
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably a stupid question but do we really need the switchable and optional widgets?
I found their usability confusing, and their behaviour sometimes inpredictable (e.g. in the Loki workflow, when toggling a switchable widget on (direct beam filename), sometimes it is then set to a default value, and sometimes it has no value set)

Can we do without? It would simplify the code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the optional widget is for setting None
and switchable is for setting it as a parameter, which effectively prune a graph from the workflow.

The usability indeed needs improvement, so we have a issue about that #74

But I don't think we can't simply remove them to support those use cases I mentioned at the beginning.

If you want to remove them from the specific workflow, you can just set optional or switchable from the parameter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I still don't really understand the difference between optional and switchable. They seem very similar: if enabled, use the value?
Can't we manage with only one of the two?
(sorry for being slow here)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nvaytet No worries, we should have had a better documentation from the first place...
I'll first write down some description here and update the documentation.

Switchable widget

is about setting values as parameters of the workflow (sciline.Pipeline object )

  • if enabled, it set the value as the parameter before it computes things
    it could mean it set an intermediate result and prune the graph.
  • if disabled it is ignored and not seen by the workflow object.

Optional widget

is about setting None or a meaningful value.
Some of providers are setting a local variable if an argument is None for example... https://github.com/scipp/esssans/blob/05b6521213150ff89caa75dac00406436607df02/src/ess/sans/normalization.py#L268-L271

So in any cases Optional widget value will be set as a parameter when compute is requested.
We needed a radio button or sth similar to it because the actual meaningful value and the None can't be represented by a same widget.

# Set the value of the option box
opted_out_flag = (
new_values.pop( # We assume ``opted-out`` is not used in any wrapped widget
'opted-out',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is opted-out a safe enough name? I seems rather safe, but should we make it even less likely to clash? e.g. essreduce-opted-out or something like that? (in the past with plopp we often added the name of the library in such attributes).

I'm guessing the opted-out is never seen by users, so the cleanliness of the name doesn't really matter?

raise ValueError(f"`enabled` must be a boolean, got {enabled_flag}")
self.enabled = enabled_flag
# Set the rest of the fields
set_fields(self.wrapped, new_values)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we only fill the rest of the fields if the widget is enabled, or do we fill in anyway?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should restore the state even if they are disabled. So that user can easily switch it on and see the restored status.

'y': 5,
'z': 3,
'unit': 'mm',
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I still don't really understand the difference between optional and switchable. They seem very similar: if enabled, use the value?
Can't we manage with only one of the two?
(sorry for being slow here)

Copy link
Member

@nvaytet nvaytet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for being extremely slow to come back to this (it slipped under my radar).

I think we should just move ahead with this as I don't really have issues with the PR itself, it was more conceptual questions on a higher level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Selected
Development

Successfully merging this pull request may close these issues.

Save parameters widget input values and load them from a dictionary
2 participants