Skip to content

Commit

Permalink
Keep label with widget
Browse files Browse the repository at this point in the history
  • Loading branch information
paddyroddy committed Jul 27, 2023
1 parent 506f4aa commit 0f75672
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 67 deletions.
4 changes: 2 additions & 2 deletions btrack/napari/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def create_btrack_widget() -> Container:

# First create our UI along with some default configs for the widgets
all_configs = btrack.napari.config.create_default_configs()
btrack_widget = btrack.napari.BtrackWidget(
viewer=napari.current_viewer(),
btrack_widget = btrack.napari.widgets.BtrackWidget(
napari_viewer=napari.current_viewer(),
)

# Set the cell_config defaults in the gui
Expand Down
10 changes: 4 additions & 6 deletions btrack/napari/widgets/_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,20 @@ def create_input_widgets() -> dict[str, QtWidgets.QWidget]:

# TODO: annotation=napari.layers.Labels,
segmentation = QtWidgets.QComboBox()
segmentation.setName("segmentation")
segmentation.setToolTip(
"Select a 'Labels' layer to use for tracking.\n"
"To use an 'Image' layer, first convert 'Labels' by right-clicking "
"on it in the layers list, and clicking on 'Convert to Labels'"
)
widgets = {"segmentation": segmentation}
widgets = {"segmentation": ("segmentation", segmentation)}

config = QtWidgets.QComboBox()
config.addItems(["cell", "particle"])
config.setName("config")
config.setTooltip(
"Select a loaded configuration.\n"
"Note, this will update values set below."
)
widgets["config"] = config
widgets["config"] = ("config", config)

return widgets

Expand All @@ -49,8 +47,8 @@ def create_update_method_widgets() -> dict[str, QtWidgets.QWidget]:
max_search_radius = QtWidgets.QSPinBox()
max_search_radius.setRange(0, 1000)
max_search_radius.setSingleStep(1)
max_search_radius.setWrapping(True) # noqa: FBT003
max_search_radius.setTooltip = (
max_search_radius.setWrapping(w=True)
max_search_radius.setTooltip(
"The local spatial search radius (isotropic, pixels) used when the update "
"method is 'APPROXIMATE'"
)
Expand Down
65 changes: 26 additions & 39 deletions btrack/napari/widgets/_hypothesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ def _create_hypotheses_widgets() -> dict[str, QtWidgets.QWidget]:
hypotheses_widgets = {}
for hypothesis, tooltip in zip(hypotheses, tooltips):
widget = QtWidgets.QCheckBox()
widget.setName(hypothesis)
widget.setToolTip(tooltip)
widget.setCheckState(True) # noqa: FBT003
hypotheses_widgets[hypothesis] = widget
widget.setCheckState(state=True)
hypotheses_widgets[hypothesis] = (hypothesis, widget)

# P_FP is always required
P_FP_hypothesis = hypotheses_widgets[0]
Expand Down Expand Up @@ -65,10 +64,10 @@ def _create_scaling_factor_widgets() -> dict[str, QtWidgets.QWidget]:
for value, name, label, tooltip in zip(
widget_values, names, labels, tooltips
):
scaling_factor_widgets[name] = QtWidgets.QDoubleSpinBox()
scaling_factor_widgets[name].setName(label)
scaling_factor_widgets[name].setToolTip(tooltip)
scaling_factor_widgets[name].setValue(value)
widget = QtWidgets.QDoubleSpinBox()
widget.setToolTip(tooltip)
widget.setValue(value)
scaling_factor_widgets[name] = (label, widget)

return scaling_factor_widgets

Expand All @@ -77,31 +76,28 @@ def _create_threshold_widgets() -> dict[str, QtWidgets.QWidget]:
"""Create widgets for setting thresholds for the HypothesisModel"""

distance_threshold = QtWidgets.QDoubleSpinBox()
distance_threshold.setName("distance threshold")
distance_threshold.setToolTip(
"A threshold distance from the edge of the field of view to add an "
"initialization or termination hypothesis."
)
distance_threshold.setValue(20.0)
widgets = {"theta_dist": distance_threshold}
widgets = {"theta_dist": ("distance threshold", distance_threshold)}

time_threshold = QtWidgets.QDoubleSpinBox()
time_threshold.setName("time threshold")
time_threshold.setToolTip(
"A threshold time from the beginning or end of movie to add "
"an initialization or termination hypothesis."
)
time_threshold.setValue(5.0)
widgets["theta_time"] = time_threshold
widgets["theta_time"] = ("time threshold", time_threshold)

apoptosis_threshold = QtWidgets.QSpinBox()
apoptosis_threshold.setName("apoptosis threshold")
apoptosis_threshold.setToolTip(
"Number of apoptotic detections to be considered a genuine event.\n"
"Detections are counted consecutively from the back of the track"
)
apoptosis_threshold.setValue(5)
widgets["apop_thresh"] = apoptosis_threshold
widgets["apop_thresh"] = ("apoptosis threshold", apoptosis_threshold)

return widgets

Expand All @@ -110,22 +106,20 @@ def _create_bin_size_widgets() -> dict[str, QtWidgets.QWidget]:
"""Create widget for setting bin sizes for the HypothesisModel"""

distance_bin_size = QtWidgets.QDoubleSpinBox()
distance_bin_size.setName("distance bin size")
distance_bin_size.setToolTip(
"Isotropic spatial bin size for considering hypotheses.\n"
"Larger bin sizes generate more hypothesese for each tracklet."
)
distance_bin_size.setValue(40.0)
widgets = {"dist_thresh": distance_bin_size}
widgets = {"dist_thresh": ("distance bin size", distance_bin_size)}

time_bin_size = QtWidgets.QDoubleSpinBox()
time_bin_size.setName("time bin size")
time_bin_size.setToolTip(
"Temporal bin size for considering hypotheses.\n"
"Larger bin sizes generate more hypothesese for each tracklet."
)
time_bin_size.setValue(2.0)
widgets["time_thresh"] = time_bin_size
widgets["time_thresh"] = ("time bin size", time_bin_size)

return widgets

Expand All @@ -134,39 +128,32 @@ def create_hypothesis_model_widgets() -> dict[str, QtWidgets.QWidget]:
"""Create widgets for setting parameters of the MotionModel"""

hypothesis_model_label = QtWidgets.QLabel()
hypothesis_model_label.setName("<b>Hypothesis model</b>") # bold label
widgets = {"hypothesis": hypothesis_model_label}

hypotheses_widgets = _create_hypotheses_widgets()
scaling_factor_widgets = _create_scaling_factor_widgets()
threshold_widgets = _create_threshold_widgets()
bin_size_widgets = _create_bin_size_widgets()
widgets = {
"hypothesis": ("<b>Hypothesis model</b>", hypothesis_model_label)
}

widgets |= (
_create_hypotheses_widgets()
| _create_scaling_factor_widgets()
| _create_threshold_widgets()
| _create_bin_size_widgets()
)

segmentation_miss_rate = QtWidgets.QDoubleSpinBox()
segmentation_miss_rate.setName("miss rate")
segmentation_miss_rate.setToolTip(
"Miss rate for the segmentation.\n"
"e.g. 1/100 segmentations incorrect gives a segmentation miss rate of 0.01."
)
segmentation_miss_rate.setValue(0.1)
widgets["segmentation_miss_rate"] = segmentation_miss_rate
widgets["segmentation_miss_rate"] = ("miss rate", segmentation_miss_rate)

relax = QtWidgets.QCheckBox()
relax.setName("relax thresholds")
relax.setToolTip(
"Disable the time and distance thresholds.\n"
"This means that tracks can initialize or terminate anywhere and"
"at any time in the dataset."
)
relax.setCheckState(True) # noqa: FBT003
widgets["relax"] = relax

return [
hypothesis_model_label,
*hypotheses_widgets,
*scaling_factor_widgets,
*threshold_widgets,
*bin_size_widgets,
segmentation_miss_rate,
relax,
]
relax.setCheckState(state=True)
widgets["relax"] = ("relax thresholds", relax)

return widgets
20 changes: 8 additions & 12 deletions btrack/napari/widgets/_motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,26 @@ def _create_sigma_widgets() -> dict[str, QtWidgets.QWidget]:
"""Create widgets for setting the magnitudes of the MotionModel matrices"""

P_sigma = QtWidgets.QDoubleSpinBox()
P_sigma.setName(f"max({_make_label_bold('P')})")
P_sigma.setToolTip(
"Magnitude of error in initial estimates.\n"
"Used to scale the matrix P."
)
P_sigma.setValue(150.0)
widgets = {"P_sigma": P_sigma}
widgets = {"P_sigma": (f"max({_make_label_bold('P')})", P_sigma)}

G_sigma = QtWidgets.QDoubleSpinBox()
G_sigma.setName(f"max({_make_label_bold('G')})")
G_sigma.setToolTip(
"Magnitude of error in process.\n Used to scale the matrix G."
)
G_sigma.setValue(15.0)
widgets["G_sigma"] = G_sigma
widgets["G_sigma"] = (f"max({_make_label_bold('G')})", G_sigma)

R_sigma = QtWidgets.QDoubleSpinBox()
R_sigma.setName(f"max({_make_label_bold('R')})")
R_sigma.setToolTip(
"Magnitude of error in measurements.\n Used to scale the matrix R."
)
R_sigma.setValue(5.0)
widgets["R_sigma"] = R_sigma
widgets["R_sigma"] = (f"max({_make_label_bold('R')})", R_sigma)

return widgets

Expand All @@ -44,23 +41,22 @@ def create_motion_model_widgets() -> dict[str, QtWidgets.QWidget]:
"""Create widgets for setting parameters of the MotionModel"""

motion_model_label = QtWidgets.QLabel()
motion_model_label.setName(_make_label_bold("Motion model"))
widgets = {"motion_model": motion_model_label}
widgets = {
"motion_model": (_make_label_bold("Motion model"), motion_model_label)
}

widgets |= _create_sigma_widgets()

accuracy = QtWidgets.QDoubleSpinBox()
accuracy.setName("accuracy")
accuracy.setToolTip("Integration limits for calculating probabilities")
accuracy.setValue(7.5)
widgets["accuracy"] = accuracy
widgets["accuracy"] = ("accuracy", accuracy)

max_lost_frames = QtWidgets.QSpinBox()
max_lost_frames.setName("max lost")
max_lost_frames.setToolTip(
"Number of frames without observation before marking as lost"
)
max_lost_frames.setValue(5)
widgets["max_lost"] = max_lost_frames
widgets["max_lost"] = ("max lost", max_lost_frames)

return widgets
28 changes: 20 additions & 8 deletions btrack/napari/widgets/create_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,48 +67,60 @@ def __init__(self, napari_viewer: Viewer) -> None:

def _add_input_widgets(self):
"""Create input widgets and add to main layout"""
self._input_widgets = create_input_widgets()
labels_and_widgets = create_input_widgets()
self._input_widgets = {
key: value.widget for key, value in labels_and_widgets.items()
}
self._widgets.update(self._input_widgets)

widget = QtWidgets.QWidget()
layout = QtWidgets.QFormLayout()
for label, widget in self._input_widgets:
for label, widget in labels_and_widgets.values():
layout.addRow(label, widget)
widget.setLayout(layout)
self._layout.addWidget(widget)

def _add_update_method_widgets(self):
"""Create update method widgets and add to main layout"""
self._update_method_widgets = create_update_method_widgets()
labels_and_widgets = create_update_method_widgets()
self._update_method_widgets = {
key: value.widget for key, value in labels_and_widgets.items()
}
self._widgets.update(self._update_method_widgets)

widget = QtWidgets.QWidget()
layout = QtWidgets.QFormLayout()
for label, widget in self._update_method_widgets:
for label, widget in labels_and_widgets.values():
layout.addRow(label, widget)
widget.setLayout(layout)
self._layout.addWidget(widget)

def _add_motion_model_widgets(self):
"""Create motion model widgets and add to main layout"""
self._motion_model_widgets = create_motion_model_widgets()
labels_and_widgets = create_motion_model_widgets()
self._motion_model_widgets = {
key: value.widget for key, value in labels_and_widgets.items()
}
self._widgets.update(self._motion_model_widgets)

widget = QtWidgets.QWidget()
layout = QtWidgets.QFormLayout()
for label, widget in self._motion_model_widgets:
for label, widget in labels_and_widgets.values():
layout.addRow(label, widget)
widget.setLayout(layout)
self._layout.addWidget(widget)

def _add_hypothesis_model_widgets(self):
"""Create hypothesis model widgets and add to main layout"""
self._hypothesis_model_widgets = create_hypothesis_model_widgets()
labels_and_widgets = create_hypothesis_model_widgets()
self._hypothesis_model_widgets = {
key: value.widget for key, value in labels_and_widgets.items()
}
self._widgets.update(self._hypothesis_model_widgets)

widget = QtWidgets.QWidget()
layout = QtWidgets.QFormLayout()
for label, widget in self._hypothesis_model_widgets:
for label, widget in labels_and_widgets.values():
layout.addRow(label, widget)
widget.setLayout(layout)
self._layout.addWidget(widget)
Expand Down

0 comments on commit 0f75672

Please sign in to comment.