def export(self): from tifffile import imsave from pyqtgraph import FileDialog start_doc = getattr(self.catalog, self.stream).metadata['start'] if 'FileName' in start_doc: current_dir = str(Path(start_doc['FileName']).parent) current_name = Path(start_doc['FileName']).stem elif 'sample_name' in start_doc: current_dir = str( Path.home()) # sample name is usually just te file stem current_name = Path(start_doc['sample_name']).stem else: current_dir = Path.home() current_name = 'xicamNCEM_output' # Get a file path to save to in current directory fd = FileDialog() fd.setNameFilter("TIF (*.tif)") fd.setDirectory(current_dir) fd.selectFile(current_name) fd.setFileMode(FileDialog.AnyFile) fd.setAcceptMode(FileDialog.AcceptSave) if fd.exec_(): file_names = fd.selectedFiles()[0] outPath = Path(file_names) else: return if outPath.suffix != '.tif': outPath = outPath.with_suffix('.tif') scale0, units0 = self._get_physical_size() # Avoid overflow in field of view later if units0[0] == 'm': units0 = ['um', 'um'] scale0 = [ii * 1e6 for ii in scale0] # Change scale from pixel to 1/pixel FOV = [1 / ii for ii in scale0] # Add units to metadata for Imagej type output metadata = {'unit': units0[0]} # Get the data and change to float image = self.xarray[self.currentIndex, :, :].astype('f') imsave(outPath, image, imagej=True, resolution=FOV, metadata=metadata)
class LibraryEditor(QtWidgets.QWidget): sigApplyClicked = QtCore.Signal() sigReloadClicked = QtCore.Signal(object) def __init__(self, ctrlWidget, library): super().__init__() self.setWindowTitle("Manage Library") self.modules = {} # {mod : [nodes]} self.paths = set() self.ctrl = ctrlWidget self.library = library self.layout = QtWidgets.QGridLayout(self) self.loadBtn = QtWidgets.QPushButton("Load Modules", parent=self) self.loadBtn.clicked.connect(self.loadFile) # self.reloadBtn = QtWidgets.QPushButton("Reload Selected Modules", parent=self) # self.reloadBtn.clicked.connect(self.reloadFile) self.tree = QtWidgets.QTreeWidget(parent=self) self.tree.setHeaderHidden(True) self.applyBtn = QtWidgets.QPushButton("Apply", parent=self) self.applyBtn.clicked.connect(self.applyClicked) self.layout.addWidget(self.loadBtn, 1, 1, 1, -1) # self.layout.addWidget(self.reloadBtn, 1, 2, 1, 1) self.layout.addWidget(self.tree, 2, 1, 1, -1) self.layout.addWidget(self.applyBtn, 3, 1, 1, -1) def loadFile(self): file_filters = "*.py" self.fileDialog = FileDialog(None, "Load Nodes", None, file_filters) self.fileDialog.setFileMode(FileDialog.ExistingFiles) self.fileDialog.filesSelected.connect(self.fileDialogFilesSelected) self.fileDialog.show() def fileDialogFilesSelected(self, pths): dirs = set(map(os.path.dirname, pths)) for pth in dirs: if pth not in sys.path: sys.path.append(pth) self.paths.update(pths) for mod in pths: mod = os.path.basename(mod) mod = os.path.splitext(mod)[0] mod = importlib.import_module(mod) if mod in self.modules: continue nodes = [getattr(mod, name) for name in dir(mod) if isNodeClass(getattr(mod, name))] if not nodes: continue self.modules[mod] = nodes parent = QtWidgets.QTreeWidgetItem(self.tree, [mod.__name__]) parent.mod = mod for node in nodes: child = QtWidgets.QTreeWidgetItem(parent, [node.__name__]) child.mod = mod self.tree.expandAll() def reloadFile(self): mods = set() for item in self.tree.selectedItems(): mods.add(item.mod) for mod in mods: pg.reload.reload(mod) self.sigReloadClicked.emit(mods) def applyClicked(self): loaded = False for mod, nodes in self.modules.items(): for node in nodes: try: self.library.addNodeType(node, [(mod.__name__, )]) loaded = True except Exception as e: printExc(e) if not loaded: return self.ctrl.ui.clear_model(self.ctrl.ui.node_tree) self.ctrl.ui.create_model(self.ctrl.ui.node_tree, self.library.getLabelTree(rebuild=True)) self.sigApplyClicked.emit() def saveState(self): return {'paths': list(self.paths)} def restoreState(self, state): self.fileDialogFilesSelected(state['paths'])
class SourceConfiguration(QtGui.QWidget): sigApply = QtCore.Signal(object) # src_cfg dict def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Configure") self.formLayout = QtWidgets.QFormLayout(self) self.interval = QtGui.QDoubleSpinBox(self) self.interval.setValue(0.01) self.formLayout.addRow("Interval", self.interval) self.init_time = QtGui.QDoubleSpinBox(self) self.init_time.setValue(0.5) self.formLayout.addRow("Init Time", self.init_time) self.hb_period = QtGui.QSpinBox(self) self.hb_period.setValue(10) self.formLayout.addRow("Heartbeat Period", self.hb_period) self.source_type = QtGui.QComboBox(self) self.source_type.addItem("hdf5") self.source_type.addItem("psana") self.formLayout.addRow("Source Type", self.source_type) self.repeat = QtWidgets.QCheckBox(self) self.repeat.setChecked(True) self.formLayout.addRow("Repeat", self.repeat) self.files = [] self.fileListView = QtWidgets.QListView(self) self.fileListView.setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection) self.fileListModel = QtCore.QStringListModel(self.files) self.fileListView.setModel(self.fileListModel) self.formLayout.addRow(self.fileListView) self.horizontalLayout = QtWidgets.QHBoxLayout() self.addBtn = QtWidgets.QPushButton("Add", parent=self) self.addBtn.clicked.connect(self.addFile) self.horizontalLayout.addWidget(self.addBtn) self.removeBtn = QtWidgets.QPushButton("Remove", parent=self) self.removeBtn.clicked.connect(self.removeFiles) self.horizontalLayout.addWidget(self.removeBtn) self.applyBtn = QtWidgets.QPushButton("Apply", parent=self) self.applyBtn.clicked.connect(self.applyClicked) self.horizontalLayout.addWidget(self.applyBtn) self.formLayout.addRow(self.horizontalLayout) def addFile(self): file_filters = self.source_type.currentText() if file_filters == "hdf5": file_filters = "*.h5 *.hdf5" elif file_filters == "psana": file_filters = "*.xtc2" self.fileDialog = FileDialog(None, "Load Data", None, file_filters) self.fileDialog.setFileMode(FileDialog.ExistingFiles) self.fileDialog.filesSelected.connect(self.fileDialogFilesSelected) self.fileDialog.show() def removeFiles(self): selectionModel = self.fileListView.selectionModel() for pth in selectionModel.selection().indexes(): pth = pth.data() self.files.remove(pth) self.fileListModel.setStringList(self.files) def fileDialogFilesSelected(self, pths): self.files.extend(pths) self.fileListModel.setStringList(self.files) def saveState(self): cfg = {} cfg['type'] = self.source_type.currentText() cfg['interval'] = self.interval.value() cfg['init_time'] = self.init_time.value() cfg['hb_period'] = self.hb_period.value() cfg['files'] = self.files cfg['repeat'] = self.repeat.isChecked() return cfg def restoreState(self, state): self.source_type.setCurrentText(state['type']) self.interval.setValue(state['interval']) self.init_time.setValue(state['init_time']) self.hb_period.setValue(state['hb_period']) self.files = state['files'] self.fileListModel.setStringList(self.files) self.repeat.setChecked(state['repeat']) def applyClicked(self): cfg = self.saveState() self.sigApply.emit(cfg)