Skip to content

Commit

Permalink
Merge pull request #176 from Wiebke/string-parameter-validation
Browse files Browse the repository at this point in the history
Add string parameter validation and `qlty` parameters
  • Loading branch information
Wiebke authored Mar 8, 2024
2 parents 7e452c8 + 6760fed commit 2f9cfcf
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 6 deletions.
115 changes: 111 additions & 4 deletions assets/models.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
"name": "dilation_array",
"title": "Dilation Array",
"param_key": "dilation_array",
"value": "[1, 2, 4]",
"placeholder": "e.g. [1, 2, 4]",
"error": "Provide a list of ints for dilation",
"debounce": 1000,
"comp_group": "train_model"
},
{
Expand Down Expand Up @@ -228,7 +230,9 @@
"name": "weights",
"title": "Class Weights",
"param_key": "weights",
"value": "[1.0, 1.0, 1.0]",
"placeholder": "e.g [0.1, 0.4, 0.5]",
"error": "Provide a list with a float for each class",
"debounce": 1000,
"comp_group": "train_model"
},
{
Expand Down Expand Up @@ -269,6 +273,39 @@
],
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_window",
"title": "Qlty Window",
"param_key": "qlty_window",
"value": 64,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_step",
"title": "Qlty Step",
"param_key": "qlty_step",
"value": 32,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_border",
"title": "Qlty Border",
"param_key": "qlty_border",
"value": 8,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "slider",
"name": "val_pct",
Expand Down Expand Up @@ -616,7 +653,9 @@
"name": "weights",
"title": "Class Weights",
"param_key": "weights",
"value": "[1.0, 1.0, 1.0]",
"placeholder": "e.g [0.1, 0.4, 0.5]",
"error": "Provide a list with a float for each class",
"debounce": 1000,
"comp_group": "train_model"
},
{
Expand Down Expand Up @@ -657,6 +696,39 @@
],
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_window",
"title": "Qlty Window",
"param_key": "qlty_window",
"value": 64,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_step",
"title": "Qlty Step",
"param_key": "qlty_step",
"value": 32,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_border",
"title": "Qlty Border",
"param_key": "qlty_border",
"value": 8,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "slider",
"name": "val_pct",
Expand Down Expand Up @@ -1008,7 +1080,9 @@
"name": "weights",
"title": "Class Weights",
"param_key": "weights",
"value": "[1.0, 1.0, 1.0]",
"placeholder": "e.g [0.1, 0.4, 0.5]",
"error": "Provide a list with a float for each class",
"debounce": 1000,
"comp_group": "train_model"
},
{
Expand Down Expand Up @@ -1049,6 +1123,39 @@
],
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_window",
"title": "Qlty Window",
"param_key": "qlty_window",
"value": 64,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_step",
"title": "Qlty Step",
"param_key": "qlty_step",
"value": 32,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "int",
"name": "qlty_border",
"title": "Qlty Border",
"param_key": "qlty_border",
"value": 8,
"min": 0,
"max": 4096,
"step": 1,
"comp_group": "train_model"
},
{
"type": "slider",
"name": "val_pct",
Expand Down
71 changes: 71 additions & 0 deletions callbacks/control_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ def open_annotation_class_modal(
disable_class_creation = True
error_msg.append("Label Already in Use!")
error_msg.append(html.Br())
if new_label == "":
disable_class_creation = True
error_msg.append("Label name cannot be empty!")
error_msg.append(html.Br())
if new_label == "Unlabeled":
disable_class_creation = True
error_msg.append("Label name cannot be 'Unlabeled'")
Expand Down Expand Up @@ -414,6 +418,14 @@ def open_edit_class_modal(
error_msg.append("Label Already in Use!")
error_msg.append(html.Br())
edit_disabled = True
if new_label == "":
error_msg.append("Label name cannot be empty!")
error_msg.append(html.Br())
edit_disabled = True
if new_label == "Unlabeled":
error_msg.append("Label name cannot be 'Unlabeled'!")
error_msg.append(html.Br())
edit_disabled = True
if new_color in current_colors:
error_msg.append("Color Already in use!")
edit_disabled = True
Expand Down Expand Up @@ -935,3 +947,62 @@ def update_model_parameters(model_name):
return item_list
else:
return html.Div("Model has no parameters")


@callback(
Output(
{"type": MATCH, "param_key": "weights", "layer": "input", "name": "weights"},
"error",
),
State({"type": "annotation-class-store", "index": ALL}, "data"),
Input(
{"type": MATCH, "param_key": "weights", "layer": "input", "name": "weights"},
"value",
),
)
def validate_class_weights(all_annotation_classes, weights):
parsed_weights = weights.strip("[]").split(",")
try:
parsed_weights = [float(weight.strip()) for weight in parsed_weights]
# All elements are floats, check if there are the correct number
# (number of classes)
if len(parsed_weights) != len(all_annotation_classes):
return "This list of floats has the wrong number of entries"
# All good
return False
except ValueError:
# If there's any error in parsing or validation, return False
return "Provide a list with a float for each class"


@callback(
Output(
{
"type": MATCH,
"param_key": "dilation_array",
"layer": "input",
"name": "dilation_array",
},
"error",
),
Input(
{
"type": MATCH,
"param_key": "dilation_array",
"layer": "input",
"name": "dilation_array",
},
"value",
),
)
def validate_dilation_array(dilation_array):
parsed_dilation_array = dilation_array.strip("[]").split(",")
try:
parsed_dilation_array = [
int(array_entry.strip()) for array_entry in parsed_dilation_array
]
# Check if all elements in the list are floats
return False
except ValueError:
# If there's any error in parsing or validation, return False
return "Provide a list of ints for dilation"
6 changes: 4 additions & 2 deletions utils/data_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def get_data_sequence_by_name(self, project_name):
elif isinstance(project_client, Container):
# Check if the specs give us information about which sub-container to access
specs = project_client.specs
# TODO: Read yaml file with spec to path mapping
if any(spec.name == "NXtomoproc" for spec in specs):
# Example for how to access data if the project container corresponds to a
# nexus-file following the NXtomoproc definition
Expand Down Expand Up @@ -171,12 +172,13 @@ def save_annotations_data(self, global_store, all_annotations, project_name):
if "image_shapes" in global_store:
image_shape = global_store["image_shapes"][0]
else:
print("Global store was not filled.")
data_shape = (
tiled_datasets.get_data_shape_by_name(project_name)
if project_name
else None
)
if data_shape is None:
return "Image shape could not be determined."
image_shape = (data_shape[1], data_shape[2])

annotations = Annotations(all_annotations, image_shape)
Expand All @@ -192,7 +194,7 @@ def save_annotations_data(self, global_store, all_annotations, project_name):
metadata = {
"project_name": project_name,
"data_uri": tiled_datasets.get_data_uri_by_name(project_name),
"image_shape": global_store["image_shapes"][0],
"image_shape": image_shape,
"mask_idx": list(annnotations_per_slice.keys()),
"classes": annotation_classes,
"annotations": annnotations_per_slice,
Expand Down

0 comments on commit 2f9cfcf

Please sign in to comment.