diff --git a/geoapps/base/plot.py b/geoapps/base/plot.py index 8836cd32d..d67efd2fe 100644 --- a/geoapps/base/plot.py +++ b/geoapps/base/plot.py @@ -338,10 +338,10 @@ def set_bounding_box(self, _): self.window_center_y.min = lim_y[0] - height * 0.1 self.window_width.max = width * 1.2 - self.window_width.value = self.window_width.max / 2.0 + self.window_width.value = self.window_width.max self.window_width.min = 0 self.window_height.max = height * 1.2 self.window_height.min = 0 - self.window_height.value = self.window_height.max / 2.0 + self.window_height.value = self.window_height.max self.refresh.value = True diff --git a/geoapps/driver_base/params.py b/geoapps/driver_base/params.py index 13dcc43e5..664c17d68 100644 --- a/geoapps/driver_base/params.py +++ b/geoapps/driver_base/params.py @@ -121,12 +121,21 @@ def update(self, params_dict: dict[str, Any], validate=True): params_dict = self.input_file._promote( # pylint: disable=protected-access params_dict ) + for key, value in params_dict.items(): if key not in self.ui_json or key == "geoh5": continue # ignores keys not in default_ui_json setattr(self, key, value) + # Set all parameters belonging to groupOptional disabled. + for key in utils.find_all(self.ui_json, "groupOptional"): + if key in params_dict and params_dict[key] is None: + for elem in utils.collect( + self.ui_json, "group", self.ui_json[key]["group"] + ): + setattr(self, elem, None) + self.validate = original_validate_state @property diff --git a/geoapps/inversion/params.py b/geoapps/inversion/params.py index 6b3fc6e73..0bf0bc7ab 100644 --- a/geoapps/inversion/params.py +++ b/geoapps/inversion/params.py @@ -135,6 +135,11 @@ def __init__( super().__init__(input_file=input_file, **kwargs) + if not self.forward_only: + for key in self.__dict__: + if "channel_bool" in key and getattr(self, key[:-5], None) is not None: + setattr(self, key, True) + def data_channel(self, component: str): """Return uuid of data channel.""" return getattr(self, "_".join([component, "channel"]), None) diff --git a/geoapps/inversion/potential_fields/application.py b/geoapps/inversion/potential_fields/application.py index 195f32b0f..0e886df07 100644 --- a/geoapps/inversion/potential_fields/application.py +++ b/geoapps/inversion/potential_fields/application.py @@ -957,17 +957,6 @@ def inversion_type_observer(self, _): ) data_channel_options = {} self.data_channel_choices.options = data_type_list - obj, _ = self.get_selected_entities() - if obj is not None: - children_list = {child.uid: child.name for child in obj.children} - ordered = OrderedDict(sorted(children_list.items(), key=lambda t: t[1])) - options = [ - [name, uid] - for uid, name in ordered.items() - if "visual parameter" not in name.lower() - ] - else: - options = [] def channel_setter(caller): channel = caller["owner"] @@ -1062,9 +1051,7 @@ def value_setter(self, key, value): ] ), ) - setattr(InversionApp, f"{key}_uncertainty", value_setter) - data_channel_options[key] = getattr(self, f"{key}_group") data_channel_options[key].children[3].children[0].header = key data_channel_options[key].children[3].children[1].header = key @@ -1082,15 +1069,12 @@ def value_setter(self, key, value): data_channel_options[key].children[3].children[1].observe( uncert_setter, names="value" ) - data_channel_options[key].children[1].options = [["", None]] + options - data_channel_options[key].children[3].children[1].options = [ - ["", None] - ] + options self.data_channel_choices.value = inversion_defaults()["component"][ self.inversion_type.value ] self.data_channel_choices.data_channel_options = data_channel_options + self.update_data_channel_options() self.data_channel_panel.children = [ self.data_channel_choices, data_channel_options[self.data_channel_choices.value], @@ -1148,12 +1132,33 @@ def object_observer(self, _): return self.update_data_list(None) + self.update_data_channel_options() self.sensor.update_data_list(None) self.inversion_type_observer(None) self.write.button_style = "warning" self._run_params = None self.trigger.button_style = "danger" + def update_data_channel_options(self): + if getattr(self.data_channel_choices, "data_channel_options", None) is None: + return + + obj, _ = self.get_selected_entities() + if obj is not None: + children_list = {child.uid: child.name for child in obj.children} + ordered = OrderedDict(sorted(children_list.items(), key=lambda t: t[1])) + options = [ + [name, uid] + for uid, name in ordered.items() + if "visual parameter" not in name.lower() + ] + else: + options = [] + + for channel_option in self.data_channel_choices.data_channel_options.values(): + channel_option.children[1].options = [["", None]] + options + channel_option.children[3].children[1].options = [["", None]] + options + def data_channel_choices_observer(self, _): if hasattr( self.data_channel_choices, "data_channel_options" @@ -1363,8 +1368,13 @@ def file_browser_change(self, _): InputFile.read_ui_json(self.file_browser.selected) ) self.params.geoh5.open(mode="r") + + params = self.params.to_dict(ui_json_format=False) + if params["resolution"] is None: + params["resolution"] = 0 + self.refresh.value = False - self.__populate__(**self.params.to_dict(ui_json_format=False)) + self.__populate__(**params) self.refresh.value = True elif extension == ".geoh5": diff --git a/geoapps/iso_surfaces/application.py b/geoapps/iso_surfaces/application.py index 954a92ca3..71a014d1b 100644 --- a/geoapps/iso_surfaces/application.py +++ b/geoapps/iso_surfaces/application.py @@ -92,13 +92,10 @@ def trigger_click(self, _) -> str: with self.get_output_workspace( self.export_directory.selected_path, temp_geoh5 ) as new_workspace: - with self.workspace.open(mode="r"): - param_dict["objects"] = param_dict["objects"].copy( - parent=new_workspace, copy_children=False - ) - param_dict["data"] = param_dict["data"].copy( - parent=param_dict["objects"] - ) + param_dict["objects"] = param_dict["objects"].copy( + parent=new_workspace, copy_children=False + ) + param_dict["data"] = param_dict["data"].copy(parent=param_dict["objects"]) param_dict["geoh5"] = new_workspace if self.live_link.value: @@ -106,7 +103,6 @@ def trigger_click(self, _) -> str: new_params = IsoSurfacesParams(**param_dict) new_params.write_input_file(name=temp_geoh5.replace(".geoh5", ".ui.json")) - driver = IsoSurfacesDriver(new_params) driver.run() diff --git a/geoapps/iso_surfaces/driver.py b/geoapps/iso_surfaces/driver.py index 15b5deeb6..4a202a48a 100644 --- a/geoapps/iso_surfaces/driver.py +++ b/geoapps/iso_surfaces/driver.py @@ -33,12 +33,11 @@ def run(self): """ Create iso surfaces from input values """ - - workspace = self.params.geoh5.open(mode="r+") levels = input_string_2_float(self.params.contours) if levels is None: return + print("Starting the isosurface creation.") surfaces = self.iso_surface( self.params.objects, @@ -66,7 +65,7 @@ def run(self): ): monitored_directory_copy(self.params.monitoring_directory, container) print("Isosurface completed. " f"-> {len(surfaces)} surface(s) created.") - workspace.close() + return result @staticmethod @@ -193,4 +192,6 @@ def iso_surface( file = sys.argv[1] params_class = IsoSurfacesParams(InputFile.read_ui_json(file)) driver = IsoSurfacesDriver(params_class) - driver.run() + + with params_class.geoh5.open(mode="r+"): + driver.run() diff --git a/tests/run_tests/apps_inversion_test.py b/tests/run_tests/apps_inversion_test.py index 3fe3862ce..e3b4a5c89 100644 --- a/tests/run_tests/apps_inversion_test.py +++ b/tests/run_tests/apps_inversion_test.py @@ -5,7 +5,7 @@ # geoapps is distributed under the terms and conditions of the MIT License # (see LICENSE file at the root of this source code package). -# pylint: disable=W0212, W0611 +# pylint: disable=W0212 from os import path from uuid import UUID @@ -17,7 +17,7 @@ from ipywidgets import Widget from geoapps.inversion.airborne_electromagnetics.application import InversionApp -from geoapps.inversion.electricals import InducedPolarizationParams +from geoapps.inversion.electricals import DirectCurrentParams, InducedPolarizationParams from geoapps.inversion.electricals.application import InversionApp as DCInversionApp from geoapps.inversion.potential_fields.application import ( InversionApp as MagInversionApp, @@ -162,24 +162,11 @@ def test_dc_inversion(tmp_path): # dc object currents = ws.get_entity(UUID("{c2403ce5-ccfd-4d2f-9ffd-3867154cb871}"))[0] currents.copy(parent=new_geoh5) - mesh = ws.get_entity(UUID("da109284-aa8c-4824-a647-29951109b058"))[0].copy( - parent=new_geoh5 - ) changes = { "topography_object": new_topo.uid, "z_from_topo": False, "forward_only": False, - "starting_model_object": mesh.uid, - "starting_model": mesh.children[0].uid, - "u_cell_size": 50, - "v_cell_size": 60, - "w_cell_size": 75, - "octree_levels_topo": "1, 2, 3", - "octree_levels_obs": "4, 5, 6", - "depth_core": 150.0, - "horizontal_padding": 150.0, - "vertical_padding": 150.0, - "max_distance": 150.0, + "starting_model": 0.01, } side_effects = {} app = DCInversionApp(geoh5=project_dcip, plot_result=False) @@ -193,58 +180,49 @@ def test_dc_inversion(tmp_path): app.write_trigger(None) app.write_trigger(None) # Check that this can run more than once + ifile = InputFile.read_ui_json(getattr(app, "_run_params").input_file.path_name) + params_reload = DirectCurrentParams(ifile) - new_app = DCInversionApp(plot_result=False) - new_app._file_browser.reset( - path=getattr(app, "_run_params").input_file.path, - filename=getattr(app, "_run_params").input_file.name, - ) - new_app._file_browser._apply_selection() - new_app.file_browser_change(None) - - with new_app.params.geoh5.open(): - for param, value in changes.items(): - p_value = getattr(new_app.params, param) - p_value = p_value.uid if isinstance(p_value, Entity) else p_value - assert p_value == str2list( - value - ), f"Parameter {param} not saved and loaded correctly." - - for param, value in side_effects.items(): - p_value = getattr(new_app.params, param) - p_value = p_value.uid if isinstance(p_value, Entity) else p_value + for param, value in changes.items(): + p_value = getattr(params_reload, param) + p_value = p_value.uid if isinstance(p_value, Entity) else p_value + assert p_value == value, f"Parameter {param} not saved and loaded correctly." + + for param, value in side_effects.items(): + p_value = getattr(params_reload, param) + p_value = p_value.uid if isinstance(p_value, Entity) else p_value + assert ( + p_value == value + ), f"Side effect parameter {param} not saved and loaded correctly." + + # Test the groups + groups = [ + "topography", + "reference_model", + "starting_model", + "upper_bound", + "lower_bound", + ] + + for group in groups: + if "Constant" in getattr(app, "_" + group + "_group").options.options: + setattr(app, group, 1.0) assert ( - p_value == value - ), f"Side effect parameter {param} not saved and loaded correctly." - - # Test the groups - groups = [ - "topography", - "reference_model", - "starting_model", - "upper_bound", - "lower_bound", - ] - - for group in groups: - if "Constant" in getattr(app, "_" + group + "_group").options.options: - setattr(app, group, 1.0) - assert ( - getattr(app, "_" + group + "_group").options.value == "Constant" - ), f"Property group {group} did not reset to 'Constant'" + getattr(app, "_" + group + "_group").options.value == "Constant" + ), f"Property group {group} did not reset to 'Constant'" - if "None" in getattr(app, "_" + group + "_group").options.options: - setattr(app, group, None) - assert ( - getattr(app, "_" + group + "_group").options.value == "None" - ), f"Property group {group} did not reset to 'None'" + if "None" in getattr(app, "_" + group + "_group").options.options: + setattr(app, group, None) + assert ( + getattr(app, "_" + group + "_group").options.value == "None" + ), f"Property group {group} did not reset to 'None'" - if "Model" in getattr(app, "_" + group + "_group").options.options: - getattr(app, "_" + group + "_group").objects.value = new_topo.uid - setattr(app, group, new_topo.children[1].uid) - assert ( - getattr(app, "_" + group + "_group").options.value == "Model" - ), f"Property group {group} did not reset to 'Model'" + if "Model" in getattr(app, "_" + group + "_group").options.options: + getattr(app, "_" + group + "_group").objects.value = new_topo.uid + setattr(app, group, new_topo.children[1].uid) + assert ( + getattr(app, "_" + group + "_group").options.value == "Model" + ), f"Property group {group} did not reset to 'Model'" def test_ip_inversion(tmp_path): @@ -283,49 +261,47 @@ def test_ip_inversion(tmp_path): app.write_trigger(None) ifile = InputFile.read_ui_json(getattr(app, "_run_params").input_file.path_name) params_reload = InducedPolarizationParams(ifile) - with params_reload.geoh5.open(): - for param, value in changes.items(): - p_value = getattr(params_reload, param) - p_value = p_value.uid if isinstance(p_value, Entity) else p_value - assert ( - p_value == value - ), f"Parameter {param} not saved and loaded correctly." - for param, value in side_effects.items(): - p_value = getattr(params_reload, param) - p_value = p_value.uid if isinstance(p_value, Entity) else p_value + for param, value in changes.items(): + p_value = getattr(params_reload, param) + p_value = p_value.uid if isinstance(p_value, Entity) else p_value + assert p_value == value, f"Parameter {param} not saved and loaded correctly." + + for param, value in side_effects.items(): + p_value = getattr(params_reload, param) + p_value = p_value.uid if isinstance(p_value, Entity) else p_value + assert ( + p_value == value + ), f"Side effect parameter {param} not saved and loaded correctly." + + groups = [ + "topography", + "reference_model", + "starting_model", + "conductivity_model", + "upper_bound", + "lower_bound", + ] + + for group in groups: + if "Constant" in getattr(app, "_" + group + "_group").options.options: + setattr(app, group, 1.0) assert ( - p_value == value - ), f"Side effect parameter {param} not saved and loaded correctly." + getattr(app, "_" + group + "_group").options.value == "Constant" + ), f"Property group {group} did not reset to 'Constant'" - groups = [ - "topography", - "reference_model", - "starting_model", - "conductivity_model", - "upper_bound", - "lower_bound", - ] - - for group in groups: - if "Constant" in getattr(app, "_" + group + "_group").options.options: - setattr(app, group, 1.0) - assert ( - getattr(app, "_" + group + "_group").options.value == "Constant" - ), f"Property group {group} did not reset to 'Constant'" - - if "None" in getattr(app, "_" + group + "_group").options.options: - setattr(app, group, None) - assert ( - getattr(app, "_" + group + "_group").options.value == "None" - ), f"Property group {group} did not reset to 'None'" + if "None" in getattr(app, "_" + group + "_group").options.options: + setattr(app, group, None) + assert ( + getattr(app, "_" + group + "_group").options.value == "None" + ), f"Property group {group} did not reset to 'None'" - if "Model" in getattr(app, "_" + group + "_group").options.options: - getattr(app, "_" + group + "_group").objects.value = new_topo.uid - setattr(app, group, new_topo.children[1].uid) - assert ( - getattr(app, "_" + group + "_group").options.value == "Model" - ), f"Property group {group} did not reset to 'Model'" + if "Model" in getattr(app, "_" + group + "_group").options.options: + getattr(app, "_" + group + "_group").objects.value = new_topo.uid + setattr(app, group, new_topo.children[1].uid) + assert ( + getattr(app, "_" + group + "_group").options.value == "Model" + ), f"Property group {group} did not reset to 'Model'" def test_em1d_inversion(tmp_path): diff --git a/tests/run_tests/apps_run_test.py b/tests/run_tests/apps_run_test.py index 4b16331b2..5e3d6939a 100644 --- a/tests/run_tests/apps_run_test.py +++ b/tests/run_tests/apps_run_test.py @@ -66,7 +66,7 @@ def test_contour_values(tmp_path): with Workspace(get_output_workspace(tmp_path)) as workspace: output = workspace.get_entity("Airborne_TMI")[0] - assert output.n_vertices == 2740, "Change in output. Need to verify." + assert output.n_vertices == 4603, "Change in output. Need to verify." def test_create_surface(tmp_path):