123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- from PyQt5.QtWidgets import QVBoxLayout, QMessageBox, QWidget, QPushButton
- from .file_selector_combobox import get_file_selector_combobox_using_settings
- from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, QMetaObject
- from ..python_core.p1_class import Default_P1_Getter, P1SingleWavelengthTIF, \
- P1SingleWavelengthLSM, P1DualWavelengthTill, P1SingleWavelengthTill, P1DualWavelengthTIFSingleFile, \
- P1SingleWavelengthLIF, P1SingleWavelength666, get_empty_p1
- from view.python_core.flags import FlagsManager
- import pathlib as pl
- import traceback
- import sys
- from abc import abstractmethod
- import tempfile
- # modified version of solution from https://stackoverflow.com/questions/9374063/remove-all-items-from-a-layout
- def clear_layout(layout):
- if layout is not None:
- while layout.count():
- item = layout.takeAt(0)
- widget = item.widget()
- if widget is not None:
- widget.setParent(None)
- else:
- clear_layout(item.layout())
- class DirectDataLoader(QWidget):
- data_loaded_signal = pyqtSignal(dict, FlagsManager)
- def __init__(self, parent, default_LE_loadExp=3):
- super().__init__(parent=parent)
- vbox = QVBoxLayout(self)
- self.refresh_layout(default_LE_loadExp)
- @pyqtSlot(int)
- def refresh_layout(self, LE_loadExp):
- loader_interface_class = get_loader_interface_class(LE_loadExp)
- self.loader_interface = loader_interface_class(self)
- self.loader_interface.refresh_layout(self)
- self.loader_interface.data_loaded_signal.connect(self.data_loaded_signal)
- def get_a_pst_combobox(parent, multiple_selection_allowed=True):
- combobox_class = get_file_selector_combobox_using_settings(multiple_selection_allowed=multiple_selection_allowed)
- return combobox_class(parent=parent,
- groupbox_title="Till Vision Raw Data File(s)",
- use_list_in_settings="raw data files",
- settings_list_value_filter=lambda x: x.endswith(".pst"),
- default_directory=None,
- file_type="PST",
- file_filter="PST files(*.pst)",
- comment=None)
- def get_an_lsm_combobox(parent):
- combobox_class = get_file_selector_combobox_using_settings(multiple_selection_allowed=True)
- return combobox_class(parent=parent,
- groupbox_title="Zeiss Raw Data File(s)",
- use_list_in_settings="raw data files",
- settings_list_value_filter=lambda x: x.endswith(".lsm"),
- default_directory=None,
- file_type="LSM",
- file_filter="LSM files(*.lsm)",
- comment=None)
- def get_a_lif_combobox(parent):
- combobox_class = get_file_selector_combobox_using_settings(multiple_selection_allowed=True)
- return combobox_class(parent=parent,
- groupbox_title="Leica .lif Data File(s)",
- use_list_in_settings="raw data files",
- settings_list_value_filter=lambda x: x.endswith(".lif"),
- default_directory=None,
- file_type="Lif",
- file_filter="Llif files(*.lif)",
- comment=None)
- def get_a_tiff_combobox(parent):
- combobox_class = get_file_selector_combobox_using_settings(multiple_selection_allowed=True)
- return combobox_class(parent=parent,
- groupbox_title="VIEW-tif File(s)",
- use_list_in_settings="raw data files",
- settings_list_value_filter=lambda x: x.endswith(".tif") or x.endswith(".tiff"),
- default_directory=None,
- file_type="TIF",
- file_filter="TIF files(*.tif *.tiff)",
- comment=None)
- class BaseLoaderInterface(QObject):
- data_loaded_signal = pyqtSignal(dict, FlagsManager)
- def __init__(self, parent):
- super().__init__(parent)
- self.default_p1_getter = Default_P1_Getter()
- def write_status(self, msg):
- self.parent().parent().parent().parent().write_status(msg)
- @pyqtSlot(list)
- @pyqtSlot(str)
- def load_list(self, filenames):
- filenames = self.check_revise_filenames(filenames)
- temp_dir = pl.Path(filenames[0][0]).parent / "temp_dir_for_view_analyses"
- temp_dir.mkdir(exist_ok=True)
- if filenames is not None:
- current_flags = self.parent().parent().parent().parent().flags.copy()
- # by default, compound path flags are not set, so set to parent of the raw files
- for flag_name in current_flags.compound_path_flags:
- current_flags.update_flags({flag_name: str(temp_dir)})
- current_flags.update_flags({"STG_Datapath": str(temp_dir.parent)})
- label_p1_mapping = {}
- for filename in filenames:
- p1 = self.check_read_data(current_flags, filename)
- if p1 is not None:
- p1.calculate_signals(current_flags)
- label_p1_mapping[p1.metadata.ex_name] = p1
- if label_p1_mapping:
- self.data_loaded_signal.emit(label_p1_mapping, current_flags)
- def check_read_data(self, flags, filenames):
- p1 = get_empty_p1(LE_loadExp=flags["LE_loadExp"], odor_conc=10) # here p1 has not data, i.e. empty
- self.write_status(f"[working] Loading raw data directly from {filenames} using {p1.__class__.__name__}")
- try:
- p1.load_without_metadata(filenames=filenames, flags=flags)
- except Exception as e:
- exception_formatted = traceback.format_exception(*sys.exc_info())
- QMessageBox.critical(self.parent(), "Error reading file",
- f"Please check {filenames}.\n\n"
- f"Complete error message:\n"
- f"\n{''.join(exception_formatted)}")
- self.write_status(f"[failure] Loading raw data directly from {filenames}")
- return None
- self.write_status(f"[success] Loading raw data directly from {filenames}")
- return p1
- def check_revise_filenames(self, filenames):
- return [[x] for x in filenames]
- @abstractmethod
- def refresh_layout(self, widget):
- pass
- class SampleData666LoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- self.temp_sample_dir = pl.Path(tempfile.gettempdir()) / "SampleDataPyView"
- self.temp_sample_dir.mkdir(exist_ok=True)
- def load_list_fake(self):
- self.load_list([str(self.temp_sample_dir / "Fake")])
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- button = QPushButton("&Load sample Data", widget)
- button.clicked.connect(self.load_list_fake)
- widget.layout().addWidget(button)
- class VIEWTIFFLoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- view_tif_combobox = get_a_tiff_combobox(widget)
- view_tif_combobox.return_filenames_signal.connect(self.load_list)
- widget.layout().addWidget(view_tif_combobox)
- class TillSingleLoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- pst_combobox = get_a_pst_combobox(widget, multiple_selection_allowed=True)
- pst_combobox.return_filenames_signal.connect(self.load_list)
- widget.layout().addWidget(pst_combobox)
- class TillDualLoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- self.pst_1_combobox = get_a_pst_combobox(widget, multiple_selection_allowed=False)
- # for the case when pst2 combobox is selected before pst1 combobox
- self.pst_1_combobox.return_filename_signal.connect(self.load_list)
- widget.layout().addWidget(self.pst_1_combobox)
- self.pst_2_combobox = get_a_pst_combobox(widget, multiple_selection_allowed=False)
- # for the case when pst1 combobox is selected before pst2 combobox
- self.pst_2_combobox.return_filename_signal.connect(self.load_list)
- widget.layout().addWidget(self.pst_2_combobox)
- @pyqtSlot(str)
- def check_revise_filenames(self, filenames):
- dbb1_filename = self.pst_1_combobox.get_current_entry()
- dbb2_filename = self.pst_2_combobox.get_current_entry()
- # load data and return only if both dbb1 and dbb2 files have been selected
- if dbb1_filename is not None and dbb2_filename is not None:
- return [[dbb1_filename, dbb2_filename]]
- else:
- return None
- class LifSingleLoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- lif_combobox = get_a_lif_combobox(widget)
- lif_combobox.return_filenames_signal.connect(self.load_list)
- widget.layout().addWidget(lif_combobox)
- class ZeissSingleLoaderInterface(BaseLoaderInterface):
- def __init__(self, parent):
- super().__init__(parent)
- def refresh_layout(self, widget):
- clear_layout(widget.layout())
- lsm_combobox = get_an_lsm_combobox(widget)
- lsm_combobox.return_filenames_signal.connect(self.load_list)
- widget.layout().addWidget(lsm_combobox)
- def get_loader_interface_class(LE_loadExp):
- if LE_loadExp == 3:
- return TillSingleLoaderInterface
- elif LE_loadExp == 4:
- return TillDualLoaderInterface
- elif LE_loadExp == 20:
- return ZeissSingleLoaderInterface
- elif LE_loadExp == 21:
- return LifSingleLoaderInterface
- elif LE_loadExp == 33:
- return VIEWTIFFLoaderInterface
- elif LE_loadExp == 35:
- return VIEWTIFFLoaderInterface
- elif LE_loadExp in (665, 667, 676):
- return SampleData666LoaderInterface
- else:
- raise NotImplementedError
|