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

Update _widget_reader.py #108

Merged
merged 13 commits into from
Nov 30, 2023
137 changes: 94 additions & 43 deletions src/yt_napari/_widget_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
from magicgui import widgets
from napari.qt.threading import thread_worker
from qtpy import QtCore
from qtpy.QtWidgets import QComboBox, QHBoxLayout, QPushButton, QVBoxLayout, QWidget

from qtpy.QtWidgets import QVBoxLayout, QWidget, QFileDialog, QApplication
from qtpy.QtWidgets import QComboBox, QHBoxLayout, QPushButton
from yt_napari import _data_model, _gui_utilities, _model_ingestor
from yt_napari._ds_cache import dataset_cache
from yt_napari.viewer import _check_for_reference_layer

import sys
import json

class YTReader(QWidget):
_pydantic_model = None
Expand Down Expand Up @@ -106,6 +107,26 @@
load_group.addWidget(cc.native)
self.layout().addLayout(load_group)

ss = widgets.PushButton(text="Save Selection")
ss.clicked.connect(self.save_selection)
load_group.addWidget(ss.native)

def save_selection(self):
py_kwargs = {}
py_kwargs = self._validate_data_model()

Check warning on line 116 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L115-L116

Added lines #L115 - L116 were not covered by tests

file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.AnyFile)
file_dialog.setAcceptMode(QFileDialog.AcceptSave)
file_dialog.setNameFilter("JSON Files (*.json);;All Files (*)")

Check warning on line 121 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L118-L121

Added lines #L118 - L121 were not covered by tests

if file_dialog.exec_():
file_path = file_dialog.selectedFiles()[0]
if file_path:

Check warning on line 125 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L123-L125

Added lines #L123 - L125 were not covered by tests
# Save the JSON data to the selected file
with open(file_path, 'w') as json_file:
json.dump(py_kwargs, json_file, indent=4)

Check warning on line 128 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L127-L128

Added lines #L127 - L128 were not covered by tests

def clear_cache(self):
dataset_cache.rm_all()

Expand All @@ -114,7 +135,29 @@
# instantiate pydantic objects, which are then handed off to the
# same data ingestion function as the json loader.

# first, get the pydantic args for each selection type, embed in lists
py_kwargs = {}
py_kwargs = self._validate_data_model()
model = _data_model.InputModel.parse_obj(py_kwargs)

# process each layer
layer_list, _ = _model_ingestor._process_validated_model(model)

# align all layers after checking for or setting the reference layer
ref_layer = _check_for_reference_layer(self.viewer.layers)
if ref_layer is None:
ref_layer = _model_ingestor._choose_ref_layer(layer_list)
layer_list = ref_layer.align_sanitize_layers(layer_list)

for new_layer in layer_list:
im_arr, im_kwargs, _ = new_layer
if self._post_load_function is not None:
im_arr = self._post_load_function(im_arr)

# add the new layer
self.viewer.add_image(im_arr, **im_kwargs)

def _validate_data_model(self):
# this function save json data
selections_by_type = defaultdict(list)
for selection in self.active_selections.values():
py_kwargs = selection.get_current_pydantic_kwargs()
Expand All @@ -129,34 +172,17 @@
py_kwargs,
ignore_attrs="selections",
)

# add selections in
py_kwargs["selections"] = selections_by_type

# now ready to instantiate the base model
py_kwargs = {
"$schema": "https://yt-napari.readthedocs.io/en/latest/_static/yt-napari_latest.json",
chrishavlin marked this conversation as resolved.
Show resolved Hide resolved
"datasets": [
py_kwargs,
]
}
model = _data_model.InputModel.parse_obj(py_kwargs)

# process each layer
layer_list, _ = _model_ingestor._process_validated_model(model)

# align all layers after checking for or setting the reference layer
ref_layer = _check_for_reference_layer(self.viewer.layers)
if ref_layer is None:
ref_layer = _model_ingestor._choose_ref_layer(layer_list)
layer_list = ref_layer.align_sanitize_layers(layer_list)

for new_layer in layer_list:
im_arr, im_kwargs, _ = new_layer
if self._post_load_function is not None:
im_arr = self._post_load_function(im_arr)

# add the new layer
self.viewer.add_image(im_arr, **im_kwargs)
return py_kwargs


class SelectionEntry(QWidget):
Expand Down Expand Up @@ -223,7 +249,50 @@
load_group.addWidget(pb.native)
self.layout().addLayout(load_group)

ss = widgets.PushButton(text="Save Selection")
ss.clicked.connect(self.save_selection)
load_group.addWidget(ss.native)

def save_selection(self):
py_kwargs = {}
py_kwargs = self._validate_data_model()

Check warning on line 258 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L257-L258

Added lines #L257 - L258 were not covered by tests
# model = _data_model.InputModel.parse_obj(py_kwargs)

file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.AnyFile)
file_dialog.setAcceptMode(QFileDialog.AcceptSave)
file_dialog.setNameFilter("JSON Files (*.json);;All Files (*)")

Check warning on line 264 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L261-L264

Added lines #L261 - L264 were not covered by tests

if file_dialog.exec_():
file_path = file_dialog.selectedFiles()[0]
if file_path:

Check warning on line 268 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L266-L268

Added lines #L266 - L268 were not covered by tests
# Save the JSON data to the selected file
with open(file_path, 'w') as json_file:
json.dump(py_kwargs, json_file, indent=4)

Check warning on line 271 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L270-L271

Added lines #L270 - L271 were not covered by tests

def load_data(self):
py_kwargs = {}
py_kwargs = self._validate_data_model()
model = _data_model.InputModel.parse_obj(py_kwargs)

if _use_threading:
worker = time_series_load(model)
worker.returned.connect(self.process_timeseries_layers)
worker.start()

Check warning on line 281 in src/yt_napari/_widget_reader.py

View check run for this annotation

Codecov / codecov/patch

src/yt_napari/_widget_reader.py#L279-L281

Added lines #L279 - L281 were not covered by tests
else:
_, layer_list = _model_ingestor._process_validated_model(model)
self.process_timeseries_layers(layer_list)

def process_timeseries_layers(self, layer_list):
for new_layer in layer_list:
im_arr, im_kwargs, _ = new_layer
# probably can remove since the _special_loaders can be used
# if self._post_load_function is not None:
# im_arr = self._post_load_function(im_arr)
# add the new layer
self.viewer.add_image(im_arr, **im_kwargs)

def _validate_data_model(self):
# first, get the pydantic args for each selection type, embed in lists
selections_by_type = defaultdict(list)
for selection in self.active_selections.values():
Expand Down Expand Up @@ -254,30 +323,12 @@

# now ready to instantiate the base model
py_kwargs = {
"$schema": "https://yt-napari.readthedocs.io/en/latest/_static/yt-napari_latest.json",
chrishavlin marked this conversation as resolved.
Show resolved Hide resolved
"timeseries": [
py_kwargs,
]
}

model = _data_model.InputModel.parse_obj(py_kwargs)

if _use_threading:
worker = time_series_load(model)
worker.returned.connect(self.process_timeseries_layers)
worker.start()
else:
_, layer_list = _model_ingestor._process_validated_model(model)
self.process_timeseries_layers(layer_list)

def process_timeseries_layers(self, layer_list):
for new_layer in layer_list:
im_arr, im_kwargs, _ = new_layer
# probably can remove since the _special_loaders can be used
# if self._post_load_function is not None:
# im_arr = self._post_load_function(im_arr)
# add the new layer
self.viewer.add_image(im_arr, **im_kwargs)

return py_kwargs

@thread_worker(progress=True)
def time_series_load(model):
Expand Down
Loading