Commit 70812b04 authored by cponcele's avatar cponcele
Browse files

add slice selector in widgets

parent 317b775c
%% Cell type:code id:4f215451-f873-47a3-b0cf-efe39f21f1ea tags:
``` python
import SonarWidget as w
from SonarWidget import NCExplorer
```
%% Cell type:code id:30ae36d9-cfe8-4245-80b4-fda078680de5 tags:
``` python
f=w.NCExplorer(starting_path=r'C:\data\datasets\XSF\data\0006_20200504_111056_FG_EM122.xsf.nc')
f=NCExplorer(starting_path=r'C:\data\datasets\XSF\data\0006_20200504_111056_FG_EM122.xsf.nc')
f.show()
```
%%%% Output: display_data
%% Cell type:code id:2a5dc0e1-bea5-4ada-a2b7-005169b05e9a tags:
%% Cell type:code id:9245798d-1131-4a21-a999-a2b5c7c9c693 tags:
``` python
```
......
......@@ -2,7 +2,7 @@ import os
from IPython.core.display import display
from ipyfilechooser import FileChooser
from ipywidgets import HBox, VBox, Output, Textarea, Button
from ipywidgets import HBox, VBox, Output, Textarea, Button, IntSlider, Checkbox
from ipytree import Tree, Node
import importer # allow to solve relative imports
......@@ -10,15 +10,56 @@ import sonar_netcdf.utils.nc_reader as reader
import netCDF4 as nc
class SingleDimensionSelector:
def __init__(self, name: str, value: int, max_value: int, enable: bool):
self.slider = IntSlider(description=name, value=value, min=0, max=max_value, disable=False)
self.checkbox = Checkbox(value=enable, description='enable')
self.widget = HBox([self.slider, self.checkbox])
class DimensionsSelector:
def __init__(self):
self.widget = VBox([])
self.clear()
self.values = {}
def clear(self, ):
self.widget.children = ()
def add_child(self, name, max_value, current_value=None):
enable = False
if current_value is None:
#try to retrieve a previous dimension with the same name (may be redefined in another group) and to reuse its value
current_value=0
if name in self.values:
#retrieve the previous widget with the same name
previous_widget = self.values[name]
previous_value = previous_widget.slider.value
if previous_value <= max_value:
current_value = previous_value
else:
current_value = max(max_value-1, 0)
enable = previous_widget.checkbox.value
selector = SingleDimensionSelector(name=name, value=current_value, max_value=max_value, enable=enable)
self.widget.children += (selector.widget,)
self.values[name] = selector
def build_slice_index(self) -> str:
dict_index = {key: value.slider.value for (key, value) in self.values.items() if value.checkbox.value is True}
return dict_index
class AppLayout2:
def clear_output(self, event):
self.content_plt.clear_output()
def clear_all(self):
self.plt_button.disabled=True
self.plt_button.description="plot selection"
self.plt_button.disabled = True
self.plt_button.description = "plot selection"
self.clear_output(None)
self.content_text.value="Empty content"
self.content_text.value = "Empty content"
def __init__(self, top=None):
self.top = top
......@@ -37,7 +78,8 @@ class AppLayout2:
clear_button.on_click(self.clear_output)
plt_toolbox = HBox((self.plt_button, clear_button))
plt_widget = VBox([plt_toolbox, self.content_plt])
self.plt_dimension_selector = DimensionsSelector()
plt_widget = VBox([plt_toolbox, self.plt_dimension_selector.widget, self.content_plt])
self.widget = VBox([top, center, plt_widget], layout={"width": "100%"})
......@@ -62,7 +104,7 @@ class NCExplorer:
# clear previous selection
for n in self.widget.tree.nodes:
self.widget.tree.remove_node(n)
self.node_dataset_dict={}
self.node_dataset_dict = {}
self.widget.clear_all()
root_name = os.path.basename(filename)
......@@ -83,13 +125,13 @@ class NCExplorer:
return self.widget.show()
def _recurseTree(self, current_group: nc.Dataset, current_node: Node):
for g in current_group.groups:
for g in sorted(current_group.groups):
n = Node(g, icon="folder", icon_style="info", opened=False)
current_node.add_node(n)
self.node_dataset_dict[n] = current_group[g]
n.observe(self.handle_tree_click, "selected")
self._recurseTree(current_group.groups[g], n)
for v in current_group.variables:
for v in sorted(current_group.variables):
n = Node(v, icon="leaf", icon_style="info")
variable = current_group.variables[v]
n.observe(self.handle_tree_click, "selected")
......@@ -103,7 +145,7 @@ class NCExplorer:
if hasattr(parent, "path"):
vpath = parent.path
return (f"{vpath}/{dataset.name}", dataset.name)
return None
return None, None
def print_node_overview(self, dataset):
marker = "-> "
......@@ -125,7 +167,7 @@ class NCExplorer:
v = "".join(
(
f"\t{marker}{dim}:{dataset.dimensions[dim].size}\n"
for dim in dataset.dimensions
for dim in sorted(dataset.dimensions)
)
)
desc = "".join([desc, dimensions, v])
......@@ -158,37 +200,53 @@ class NCExplorer:
attributes = f"\nAttributes:\n"
v = "".join(
(f"\t{marker}{att}:{dataset.getncattr(att)}\n" for att in dataset.ncattrs())
(f"\t{marker}{att}:{dataset.getncattr(att)}\n" for att in sorted(dataset.ncattrs()))
)
desc = "".join([desc, attributes, v])
self.widget.content_text.value = str(desc)
def _update_current_selection(self, dataset):
self.current_selection = dataset
self.print_node_overview(self.current_selection)
if self.current_selection is not None and isinstance(
self.current_selection, nc.Variable
):
# update plot description
self.widget.plt_button.description = (
f"Plot {self.current_selection.name}"
)
dimensions = self.current_selection.dimensions
shape = self.current_selection.shape
# shape could have one more dimension due to vlen
# shape = shape[0:len(dimensions)]
self.widget.plt_dimension_selector.clear()
for dim, s in zip(dimensions, shape):
self.widget.plt_dimension_selector.add_child(name=dim, max_value=s, current_value=None)
self.widget.plt_button.disabled = False
else:
self.widget.plt_button.disabled = True
def handle_tree_click(self, event):
if event["new"] and event["owner"] is not None:
node = event["owner"]
self.print_node_overview(self.node_dataset_dict[node])
self.current_selection = self.node_dataset_dict[node]
if self.current_selection is not None and isinstance(
self.current_selection, nc.Variable
):
self.widget.plt_button.description = (
f"Plot {self.current_selection.name}"
)
self.widget.plt_button.disabled = False
else:
self.widget.plt_button.disabled = True
self._update_current_selection(self.node_dataset_dict[node])
def plot_ncvariable(self, dataset):
with self.widget.content_plt:
ret = self._get_variable_path_and_name(dataset)
if ret is not None:
path = ret[0]
name = ret[1]
path, name = self._get_variable_path_and_name(dataset)
if path is not None:
# build a slice index given all dimension selector
slice_index = self.widget.plt_dimension_selector.build_slice_index()
self.current_reader._display_variable(
variable_name=name, variable_path=path, slice_index={}
variable_name=name, variable_path=path, slice_index=slice_index
)
def plot_current_variable(self, event):
......@@ -222,6 +280,7 @@ if __name__ == "__main__":
f.on_file_selected(d)
f.print_node_overview(f.current_reader.dataset["/Sonar/Beam_group1/backscatter_r"])
f._update_current_selection(f.current_reader.dataset["/Sonar/Beam_group1/backscatter_r"])
f.plot_ncvariable(
f.current_reader.dataset["/Sonar/Beam_group1/platform_longitude"]
)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment