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

GUI: Basic/Advanced modes toggle feature #64

Merged
merged 16 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions aydin/gui/_qt/custom_widgets/constructor_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,14 @@ def params_dict(self):
params_dict["kwargs"][name] = value

return params_dict

def set_advanced_enabled(self, enable: bool = False):
for _ in range(self.arguments_layout.rowCount()):
if (
"(advanced)"
in self.arguments_layout.itemAtPosition(_, 2).widget().text()
):
for column_index in range(3):
self.arguments_layout.itemAtPosition(
_, column_index
).widget().setHidden(not enable)
2 changes: 1 addition & 1 deletion aydin/gui/_qt/custom_widgets/denoise_tab_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def __init__(self, parent, name=None, description=None):
for component in list(args.keys()):
sub_dict = args[component]

self.constructor_arguments_widget = ConstructorArgumentsWidget(
self.constructor_arguments_widget = ConstructorArgumentsWidget( # TODO: making return of this member doesn't make sense, double check
self,
arg_names=sub_dict["arguments"],
arg_defaults=sub_dict["defaults"],
Expand Down
8 changes: 7 additions & 1 deletion aydin/gui/_qt/transforms_tab_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ def __init__(self, parent):

class_itself = response.__getattribute__(elem)
fullargspec = inspect.getfullargspec(class_itself.__init__)
# print(fullargspec)

widget = TransformsTabItem(
self,
Expand All @@ -50,3 +49,10 @@ def __init__(self, parent):

def clear_the_list(self):
self.clear()

def set_advanced_enabled(self, enable: bool = False):
for index, item_widget in enumerate(self.list_of_item_widgets):
if "(advanced)" in item_widget.transform_class.__doc__:
self.setTabEnabled(index, enable)

item_widget.constructor_arguments_widget.set_advanced_enabled(enable=enable)
31 changes: 16 additions & 15 deletions aydin/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def setupMenubar(self):
mainMenu.setNativeMenuBar(False)
fileMenu = mainMenu.addMenu(' &File')
runMenu = mainMenu.addMenu(' &Run')
preferencesMenu = mainMenu.addMenu(' &Preferences')
helpMenu = mainMenu.addMenu(' &Help')

# File Menu
Expand Down Expand Up @@ -89,21 +90,21 @@ def setupMenubar(self):
)
runMenu.addAction(saveOptionsJSONButton)

# loadOptionsJSONButton = QAction('Load Options JSON', self)
# loadOptionsJSONButton.setStatusTip('Load options JSON')
# # loadOptionsJSONButton.triggered.connect(
# # self.main_widget.tabs["File(s)"].openFileNamesDialog
# # )
# loadOptionsJSONButton.setEnabled(False)
# runMenu.addAction(loadOptionsJSONButton)
#
# saveModelJSONButton = QAction('Save Model', self)
# saveModelJSONButton.setStatusTip('Save the most-recent trained model')
# saveModelJSONButton.setEnabled(False)
# # saveModelJSONButton.triggered.connect(
# # self.main_widget.tabs["File(s)"].openFileNamesDialog
# # )
# runMenu.addAction(saveModelJSONButton)
# Preferences Menu
self.basicModeButton = QAction('Basic mode', self)
self.basicModeButton.setEnabled(False)
self.basicModeButton.setStatusTip('Switch to basic mode')
self.basicModeButton.triggered.connect(
lambda: self.main_widget.toggle_basic_advanced_mode()
)
preferencesMenu.addAction(self.basicModeButton)

self.advancedModeButton = QAction('Advanced mode', self)
self.advancedModeButton.setStatusTip('Switch to advanced mode')
self.advancedModeButton.triggered.connect(
lambda: self.main_widget.toggle_basic_advanced_mode()
)
preferencesMenu.addAction(self.advancedModeButton)

# Help Menu
versionButton = QAction("ver" + self.version, self)
Expand Down
17 changes: 17 additions & 0 deletions aydin/gui/main_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,23 @@ def handle_use_same_crop_state_changed(self):
not self.tabs["Training Crop"].use_same_crop_checkbox.isChecked(),
)

def toggle_basic_advanced_mode(self):
# make calls to toggle the GUI at lower levels
self.tabs["Pre/Post-Processing"].set_advanced_enabled(
self.parent.advancedModeButton.isEnabled()
)
self.tabs["Denoise"].set_advanced_enabled(
self.parent.advancedModeButton.isEnabled()
)

# swap the enabled state of `basic` and `advanced` menu items
self.parent.basicModeButton.setEnabled(
not self.parent.basicModeButton.isEnabled()
)
self.parent.advancedModeButton.setEnabled(
not self.parent.advancedModeButton.isEnabled()
)

def add_activity_dockable(self):
self.activity_dock.setHidden(True)
self.parent.addDockWidget(Qt.BottomDockWidgetArea, self.activity_dock)
Expand Down
67 changes: 57 additions & 10 deletions aydin/gui/tabs/qt/denoise.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,44 @@ def __init__(self, parent):
backend_options_descriptions,
) = get_list_of_denoiser_implementations()

backend_options, backend_options_descriptions = (
self.backend_options, self.backend_options_descriptions = (
list(t)
for t in zip(*sorted(zip(backend_options, backend_options_descriptions)))
)

self.basic_backend_options = [
'Classic-butterworth',
'Classic-gaussian',
'Classic-gm',
'Classic-nlm',
'Classic-tv',
'Noise2SelfCNN-jinet',
'Noise2SelfFGR-cb',
'Noise2SelfFGR-lgbm',
'Noise2SelfFGR-rf',
]

self.basic_backend_options_descriptions = []

self.stacked_widget = QStackedWidget(self)

default_option_index = 0
for idx, (backend_option, description) in enumerate(
zip(backend_options, backend_options_descriptions)
zip(self.backend_options, self.backend_options_descriptions)
):
self.leftlist.insertItem(idx, backend_option)
# self.leftlist.item(idx).setToolTip(tooltip)
if backend_option in self.basic_backend_options:
self.basic_backend_options_descriptions.append(description)

self.stacked_widget.addWidget(
DenoiseTabMethodWidget(
self, name=backend_option, description=description
self.leftlist.insertItem(idx, backend_option)

self.stacked_widget.addWidget(
DenoiseTabMethodWidget(
self, name=backend_option, description=description
)
)
)

if backend_option == "Classic-butterworth":
default_option_index = idx
if backend_option == "Classic-butterworth":
default_option_index = idx

self.leftlist.item(default_option_index).setSelected(True)
self.change_current_method(default_option_index)
Expand All @@ -97,6 +113,8 @@ def __init__(self, parent):

self.setLayout(self.tab_layout)

self.set_advanced_enabled(enable=False) # to init the tab correctly

def change_current_method(self, new_index):
self.stacked_widget.setCurrentIndex(new_index)

Expand All @@ -111,3 +129,32 @@ def current_backend_qwidget(self):
@property
def lower_level_args(self):
return self.stacked_widget.currentWidget().lower_level_args()

def set_advanced_enabled(self, enable: bool = False):
self.leftlist.clear()

while self.stacked_widget.count():
self.stacked_widget.removeWidget(self.stacked_widget.widget(0))

for index, backend_option in enumerate(
self.backend_options if enable else self.basic_backend_options
):
self.leftlist.insertItem(index, backend_option)

description_list = (
self.backend_options_descriptions
if enable
else self.basic_backend_options_descriptions
)

self.stacked_widget.addWidget(
DenoiseTabMethodWidget(
self, name=backend_option, description=description_list[index]
)
)

for widget_index in range(self.stacked_widget.count()):
for key, constructor_arguments_widget in self.stacked_widget.widget(
widget_index
).constructor_arguments_widget_dict.items():
constructor_arguments_widget.set_advanced_enabled(enable=enable)
5 changes: 5 additions & 0 deletions aydin/gui/tabs/qt/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ def __init__(self, parent):

self.setLayout(self.tab_layout)

self.set_advanced_enabled(enable=False) # to init the tab correctly

@property
def transforms(self):
if len(self.panes_widget.list_of_item_widgets) < 1:
Expand All @@ -57,3 +59,6 @@ def transforms(self):
transforms.append(item.params_dict)

return transforms

def set_advanced_enabled(self, enable: bool = False):
self.panes_widget.set_advanced_enabled(enable=enable)
2 changes: 1 addition & 1 deletion aydin/it/transforms/deskew.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class DeskewTransform(ImageTransformBase):
per plane - must be an integer. We automatically snap the delta value to the closest integer. Padding is supported.

Note: this only works for images with at least 3 dimensions. Does nothing
on images with less than 3 dimensions.
on images with less than 3 dimensions.(advanced)
"""

preprocess_description = "Deskew image" + ImageTransformBase.preprocess_description
Expand Down
2 changes: 1 addition & 1 deletion aydin/it/transforms/motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class MotionStabilisationTransform(ImageTransformBase):
we assume that all frames can be registered to a common reference frame,
and thus that all images have a common background that can be used for
registration. For completeness, multiple axis can be specified and the
correction is applied along each in sequence.
correction is applied along each in sequence.(advanced)
"""

preprocess_description = (
Expand Down
2 changes: 1 addition & 1 deletion aydin/it/transforms/periodic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class PeriodicNoiseSuppressionTransform(ImageTransformBase):
Some images have a form of periodic noise that can be seen as strong
peaks in their power spectral density. Suppressing these peaks before and
after denoising is often a good idea. This is tricky to use, use with
care. Works with non-axis aligned periodic patterns.
care. Works with non-axis aligned periodic patterns.(advanced)
"""

preprocess_description = (
Expand Down