class TomographyPlugin(GUIPlugin): name = "Tomography" def __init__(self, *args, **kwargs): self.active_filename = "" self._main_view = QMainWindow() self._main_view.setCentralWidget(QWidget()) self._main_view.centralWidget().hide() self._editors = QStackedWidget() self.workflow_process_selector = QComboBox() self.workflow_process_selector.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) self.workflow_process_selector.addItem("TomoPy Workflow") self._workflow = None self._tomo_workflow = TomographyWorkflow() # Create a workflow self._workflow = self._tomo_workflow self._workflow_editor = WorkflowEditor(workflow=self._workflow) self._workflow_editor.sigRunWorkflow.connect(self.run_workflow) self._active_workflow_executor = QTreeWidget() self._editors.addWidget(self._workflow_editor) if hasLTT: self._alt_workflow = LTTWorkflow() self.workflow_process_selector.addItem("LTT Workflow") self._alt_workflow_editor = WorkflowEditor(self._alt_workflow) self._alt_workflow_editor.sigRunWorkflow.connect(self.run_workflow) self._editors.addWidget(self._alt_workflow_editor) self.workflow_process_selector.setCurrentIndex(0) self.workflow_process_selector.currentIndexChanged.connect(self.active_workflow_changed) self._active_workflow_widget = QWidget() self._active_layout = QVBoxLayout() self._active_layout.addWidget(self.workflow_process_selector) self._active_layout.addWidget(self._editors) self._active_layout.addWidget(self._active_workflow_executor) self._active_workflow_widget.setLayout(self._active_layout) # self.hdf5_viewer = HDFTreeViewer() # self.hdf5_viewer.load("/Users/hari/20200521_160002_heartbeat_test.h5") self.top_controls = QWidget() self.top_controls_layout = QHBoxLayout() self.top_controls.setLayout(self.top_controls_layout) self.top_controls_add_new_selector = QComboBox() self.top_controls_frequency_selector = QSpinBox() self.top_controls_frequency_selector.setValue(0) self.top_controls_add_new_viewer = QPushButton() self.top_controls_add_new_viewer.setText("Add Viewer") self.top_controls_add_new_viewer.clicked.connect(self.add_new_viewer_selected) self.top_controls_preview = QPushButton() self.top_controls_preview.setText("Preview") self.top_controls_preview.clicked.connect(self.preview_workflows) self.top_controls_execute = QPushButton() self.top_controls_execute.setText("Execute All") self.top_controls_execute.clicked.connect(self.execute_workflows) self.top_controls_add_new_selector.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) self.top_controls_add_new_viewer.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.top_controls_execute.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.top_controls_frequency_selector.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.top_controls_layout.addWidget(self.top_controls_add_new_selector) self.top_controls_layout.addWidget(self.top_controls_add_new_viewer) self.top_controls_layout.addWidget(self.top_controls_frequency_selector) self.top_controls_layout.addWidget(self.top_controls_preview) self.top_controls_layout.addWidget(self.top_controls_execute) self.top_controls.setLayout(self.top_controls_layout) self.status_bar = QLabel("None Loaded...") # Create a layout to organize our widgets # The first argument (which corresponds to the center widget) is required. catalog_viewer_layout = GUILayout(self._main_view, top=self.top_controls, right=self._active_workflow_widget, bottom=self.status_bar) # Create a "View" stage that has the catalog viewer layout self.stages = {"View": catalog_viewer_layout} self.active_workflows = [] # For classes derived from GUIPlugin, this super __init__ must occur at end super(TomographyPlugin, self).__init__(*args, **kwargs) def active_workflow_changed(self, index): self._editors.setCurrentIndex(index) if index == 0: self._workflow = self._tomo_workflow else: self._workflow = self._alt_workflow def preview_workflows(self): if len(self.active_filename) == 0: return preview_sinogram = self.top_controls_frequency_selector.value() workflows = [] for aw in range(self._active_workflow_executor.topLevelItemCount()): widget_item = self._active_workflow_executor.topLevelItem(aw) workflow = widget_item.data(0, Qt.UserRole) workflows.append(workflow) active_workflows = self.active_workflows for workflow in workflows: def results_ready(workflow, *results): output_image = results[0]["recon"] # We want the output_image from the last operation # print("RECON SHAPE", output_image.shape) for active_workflow in active_workflows: if active_workflow[1] == workflow: active_workflow[0].widget().setImage(output_image) # Update the result view widget workflow.execute(callback_slot=partial(results_ready, workflow), path=self.active_filename, sinoindex=preview_sinogram) def execute_workflows(self): if len(self.active_filename) == 0: return workflows = [] for aw in range(self._active_workflow_executor.topLevelItemCount()): widget_item = self._active_workflow_executor.topLevelItem(aw) workflow = widget_item.data(0, Qt.UserRole) workflows.append(workflow) active_workflows = self.active_workflows for workflow in workflows: def results_ready(workflow, *results): output_image = results[0]["recon"] # We want the output_image from the last operation # print("RECON SHAPE", output_image.shape) for active_workflow in active_workflows: if active_workflow[1] == workflow: active_workflow[0].widget().setImage(output_image) # Update the result view widget workflow.execute(callback_slot=partial(results_ready, workflow), path=self.active_filename) def add_new_viewer_selected(self, checked): if self.top_controls_add_new_selector.count() == 0: return selected = self.top_controls_add_new_selector.currentIndex() if selected < 0: return workflow = self.top_controls_add_new_selector.currentData(Qt.UserRole) print("WORKFLOW", workflow, workflow.name) dock_widget = QDockWidget() viewer = CatalogView() dock_widget.setWidget(viewer) dock_widget.setWindowTitle(workflow.name) if len(self.active_workflows) == 0: self._main_view.addDockWidget(Qt.RightDockWidgetArea, dock_widget) else: self._main_view.tabifyDockWidget(self.active_workflows[-1][0], dock_widget) self.active_workflows.append((dock_widget, workflow)) def appendHeader(self, header, **kwargs): filename = header._documents["start"][0]["filename"] self.active_filename = filename self.status_bar.setText("Loading Filename:" + filename) dataset, bkgs, drks = read_als_hdf5(filename) slice_widget = MyCatalogView() dw = QDockWidget() dw.setWidget(slice_widget) dw.setWindowTitle(filename) slice_widget.setImage(dataset) dock_children = self._main_view.findChildren(QDockWidget) print(dock_children) #if len(dock_children) == 0: # self._main_view.addDockWidget(Qt.LeftDockWidgetArea, dw) #else: # self._main_view.tabifyDockWidget(dock_children[0], dw) self._main_view.addDockWidget(Qt.LeftDockWidgetArea, dw) self.status_bar.setText("Done Loading Filename:" + filename) def appendCatalog(self, catalog, **kwargs): """Re-implemented from GUIPlugin - gives us access to a catalog reference You MUST implement this method if you want to load catalog data into your GUIPlugin. """ # Set the catalog viewer's catalog, stream, and field (so it knows what to display) # This is a quick and simple demonstration; stream and field should NOT be hardcoded # stream = "primary" # field = "img" # self._catalog_viewer.setCatalog(catalog, stream, field) print("CATALOG CALLED", catalog) pass def run_workflow(self): """Run the internal workflowi. In this example, this will be called whenever the "Run Workflow" in the WorkflowEditor is clicked. """ item = QTreeWidgetItem() workflow_name = self._workflow.name + ":" + str(self._active_workflow_executor.model().rowCount()) workflow = self._workflow.clone() workflow.name = workflow_name workflow._pretty_print() item.setText(0, workflow_name) item.setData(0, Qt.UserRole, workflow) self._active_workflow_executor.addTopLevelItem(item) self.top_controls_add_new_selector.addItem(workflow_name, userData=workflow)