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
141 changes: 99 additions & 42 deletions src/yt_napari/_widget_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
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):
Expand Down Expand Up @@ -94,6 +97,7 @@ def remove_selection(self):

class ReaderWidget(YTReader):
_pydantic_model = _data_model.DataContainer
app = QApplication(sys.argv)
TomasPetro marked this conversation as resolved.
Show resolved Hide resolved

def add_load_group_widgets(self):
load_group = QHBoxLayout()
Expand All @@ -106,6 +110,27 @@ def add_load_group_widgets(self):
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()

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

if file_dialog.exec_():
file_path = file_dialog.selectedFiles()[0]
if file_path:
# Save the JSON data to the selected file
with open(file_path, 'w') as json_file:
json.dump(py_kwargs, json_file, indent=4)
app.exec_()
TomasPetro marked this conversation as resolved.
Show resolved Hide resolved

def clear_cache(self):
dataset_cache.rm_all()

Expand All @@ -114,7 +139,29 @@ def load_data(self):
# 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 +176,17 @@ def load_data(self):
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 @@ -213,6 +243,7 @@ def get_current_pydantic_kwargs(self) -> dict:

class TimeSeriesReader(YTReader):
_pydantic_model = _data_model.Timeseries
app = QApplication(sys.argv)
TomasPetro marked this conversation as resolved.
Show resolved Hide resolved

def add_load_group_widgets(self):
# the load and clear buttons
Expand All @@ -223,7 +254,51 @@ def add_load_group_widgets(self):
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()
# 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 (*)")

if file_dialog.exec_():
file_path = file_dialog.selectedFiles()[0]
if file_path:
# Save the JSON data to the selected file
with open(file_path, 'w') as json_file:
json.dump(py_kwargs, json_file, indent=4)
app.exec_()
TomasPetro marked this conversation as resolved.
Show resolved Hide resolved

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()
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 +329,12 @@ def load_data(self):

# 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