Source code for napari_locan.widgets.widget_io_save

"""
Save SMLM data files.

A QWidget plugin to save data from the SMLM data model.
"""

import logging
from pathlib import Path

import locan as lc
from napari.utils import progress
from napari.viewer import Viewer
from qtpy.QtWidgets import (
    QComboBox,
    QFileDialog,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

from napari_locan import smlm_data
from napari_locan.data_model.smlm_data import SmlmData

logger = logging.getLogger(__name__)


[docs] class SaveSmlmDataQWidget(QWidget): # type: ignore def __init__(self, napari_viewer: Viewer, smlm_data: SmlmData = smlm_data): super().__init__() self.viewer = napari_viewer self.smlm_data = smlm_data self._add_file_type() self._add_file_path() # self._add_kwargs_edit() self._add_buttons() self._set_layout() def _add_file_type(self) -> None: self._file_type_label = QLabel("File type:") self._file_type_combobox = QComboBox() file_types = [ type_.name for type_ in lc.FileType if type_.name in ["ASDF", "parquet", "SMAP", "SMLM", "THUNDERSTORM"] ] self._file_type_combobox.addItems(file_types) self._file_type_combobox.setCurrentText(lc.FileType.ASDF.name) self._file_type_layout = QHBoxLayout() self._file_type_layout.addWidget(self._file_type_label) self._file_type_layout.addWidget(self._file_type_combobox) def _add_file_path(self) -> None: self._file_path_label = QLabel("File path:") self._file_path_edit = QLineEdit() self._file_path_select_button = QPushButton("Select") self._file_path_select_button.setToolTip("Select a file path.") self._file_path_select_button.clicked.connect( self._file_path_select_button_on_click ) self._file_path_delete_button = QPushButton("Delete") self._file_path_delete_button.setToolTip("Clear the file path.") self._file_path_delete_button.clicked.connect( self._file_path_delete_button_on_click ) self._file_path_layout = QHBoxLayout() self._file_path_layout.addWidget(self._file_path_label) self._file_path_layout.addWidget(self._file_path_edit) self._file_path_layout.addWidget(self._file_path_select_button) self._file_path_layout.addWidget(self._file_path_delete_button) # def _add_kwargs_edit(self) -> None: # self._kwargs_edit_label = QLabel("**kwargs:") # self._kwargs_edit = QLineEdit() # self._kwargs_edit.setToolTip("Add kwargs for save function.") # # self._kwargs_edit_layout = QHBoxLayout() # self._kwargs_edit_layout.addWidget(self._kwargs_edit_label) # self._kwargs_edit_layout.addWidget(self._kwargs_edit) def _add_buttons(self) -> None: self._save_button = QPushButton("Save SMLM data") self._save_button.setToolTip("Save the selected SMLM dataset.") self._save_button.clicked.connect(self._save_button_on_click) def _set_layout(self) -> None: layout = QVBoxLayout() layout.addLayout(self._file_type_layout) layout.addLayout(self._file_path_layout) # layout.addLayout(self._kwargs_edit_layout) layout.addWidget(self._save_button) self.setLayout(layout) def _file_path_select_button_on_click(self) -> None: fname_ = QFileDialog.getSaveFileName( None, "Save as...", "", filter="ASDF (*.asdf);;CSV files (*.csv);;Parquet files (*.parquet);;SMAP (*.csv);;SMLM (*.zip);;THUNDERSTORM (*.csv)", selectedFilter="ASDF (*.asdf)", # kwargs: parent, message, directory, filter # but kw_names are different for different qt_bindings ) fname = fname_[0] if isinstance(fname_, tuple) else str(fname_) self._file_path_edit.setText(fname) def _file_path_delete_button_on_click(self) -> None: self._file_path_edit.clear() def _save_button_on_click(self) -> None: if not self._file_path_edit.text(): self._file_path_select_button_on_click() file_path = Path(self._file_path_edit.text()) file_type = self._file_type_combobox.currentText() # text = self._kwargs_edit.text() # expr = ast.parse(f"dict({text}\n)", mode="eval") # kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.body.keywords} # type: ignore with progress() as progress_bar: progress_bar.set_description("Saving data") if file_type == lc.FileType.ASDF.name and file_path.suffix == ".asdf": lc.save_asdf(locdata=self.smlm_data.locdata, path=file_path) # type: ignore[arg-type] elif file_type == lc.FileType.SMAP.name and file_path.suffix == ".csv": lc.save_SMAP_csv(locdata=self.smlm_data.locdata, path=file_path) # type: ignore[arg-type] elif file_type == lc.FileType.SMLM.name and file_path.suffix == ".zip": lc.save_SMLM(locdata=self.smlm_data.locdata, path=file_path) # type: ignore[arg-type] elif ( file_type == lc.FileType.THUNDERSTORM.name and file_path.suffix == ".csv" ): lc.save_thunderstorm_csv(locdata=self.smlm_data.locdata, path=file_path) # type: ignore[arg-type] else: raise TypeError( "Selected file type cannot be saved. Check that file suffix is correct." )