def __init__(self, *args, **kwargs): self.mapToH5 = mapToH5() # Data model self.headermodel = QStandardItemModel() # Selection model self.selectionmodel = QItemSelectionModel(self.headermodel) self.PCA_widget = FactorizationWidget(self.headermodel, self.selectionmodel) self.NMF_widget = FactorizationWidget(self.headermodel, self.selectionmodel) # update headers list when a tab window is closed self.headermodel.rowsRemoved.connect( partial(self.PCA_widget.setHeader, 'spectra')) self.headermodel.rowsRemoved.connect( partial(self.NMF_widget.setHeader, 'volume')) # Setup tabviews and update map selection self.imageview = TabView(self.headermodel, self.selectionmodel, MapView, 'image') self.stages = { "MapToH5": GUILayout(self.mapToH5), "Image View": GUILayout(self.imageview), "PCA": GUILayout(self.PCA_widget), "NMF": GUILayout(self.NMF_widget) } super(BSISB, self).__init__(*args, **kwargs)
def __init__(self): self.workflow = Workflow() self.headermodel = QStandardItemModel() # self.alignmenttabview = TabView(self.headermodel) self.rawtabview = TabView(self.headermodel, widgetcls=RAWViewer, field='primary') self.recontabs = QTabWidget() self.workfloweditor = WorkflowEditor(self.workflow) self.workfloweditor.setHidden(True) self.tomotoolbar = TomoToolbar() self.tomotoolbar.sigSliceReconstruction.connect(self.sliceReconstruct) self.tomotoolbar.sigFullReconstruction.connect(self.fullReconstruction) self.stages = { 'Alignment': GUILayout(QLabel('Alignment'), right=self.workfloweditor, top=self.tomotoolbar), 'Preprocess': GUILayout(self.rawtabview, right=self.workfloweditor, top=self.tomotoolbar), 'Reconstruct': GUILayout(self.recontabs, top=self.tomotoolbar, right=self.workfloweditor), } super(TomographyPlugin, self).__init__()
def __init__(self, headermodel): super(SAXSMultiViewerPlugin, self).__init__() self.leftTabView = TabView() self.leftTabView.setWidgetClass(SAXSViewerPlugin) self.leftTabView.setModel(headermodel) self.rightTabView = TabView() self.rightTabView.setWidgetClass(SAXSViewerPlugin) self.rightTabView.setModel(headermodel) self.addWidget(self.leftTabView) self.addWidget(self.rightTabView)
def __init__(self, headermodel, selectionmodel): super(SAXSMultiViewerPlugin, self).__init__() self.leftTabView = TabView() self.leftTabView.setWidgetClass(SAXSViewerPluginBase) self.leftTabView.setHeaderModel(headermodel) self.leftTabView.setSelectionModel(selectionmodel) self.rightTabView = TabView() self.rightTabView.setWidgetClass(SAXSViewerPluginBase) self.rightTabView.setHeaderModel(headermodel) self.addWidget(self.leftTabView) self.addWidget(self.rightTabView)
def __init__(self, *args, **kwargs): # Data model self.headermodel = QStandardItemModel() self.toolbar = QToolBar() # plot widget self.reduceWidget = QWidget() self.plot = pg.PlotWidget() self.layout = QGridLayout() self.reduceWidget.setLayout(self.layout) self.layout.addWidget(self.plot) x = np.random.random(20) y = np.random.random(20) self.plot.plot(x, y) # table widget self.tableWidget = QWidget() self.table = QTableWidget() self.layout2 = QGridLayout() self.tableWidget.setLayout(self.layout2) self.layout2.addWidget(self.table) self.table.setRowCount(len(x)) self.table.setColumnCount(2) for i in range(0, len(x)): self.table.setItem(i, 0, QTableWidgetItem(str(round(x[i], 3)))) self.table.setItem(i, 1, QTableWidgetItem(str(round(y[i], 3)))) # Selection model self.selectionmodel = QItemSelectionModel(self.headermodel) # Setup TabViews self.rawview = TabView(self.headermodel, self.selectionmodel, widgets.EFIViewerPlugin, 'primary') self.reduceview = TabView(self.headermodel, self.selectionmodel, self.reduceWidget) self.metadataview = MetadataView(self.headermodel, self.selectionmodel) self.stages = { 'View': GUILayout(self.rawview, top=self.toolbar, right=self.metadataview), 'Reduce': GUILayout(self.reduceWidget, top=self.toolbar, right=self.tableWidget) # 'View': GUILayout(QLabel('View')) } super(EFIPlugin, self).__init__(*args, **kwargs)
def __init__(self): #Define workflows self.my_workflow = MyWorkflow() #self.my_workflow_editor = WorkflowEditor(self.my_workflow) # Define a GUILayout # GUILayouts must provide a center widget #self.container_widget = QWidget() self.split_widget = CatalogAndAnalysisSplitWidget() layout = QVBoxLayout() # what kind of layout self.button = QPushButton("push this") #layout.addWidget(self.split_widget) # add things to the layout one by one #layout.addWidget(self.button) #self.container_widget.setLayout(layout) # apply layout to the basic widget bottom_widget = QLabel('bottom') left_widget = QLabel('left') leftbottom_widget = QLabel('left bottom') right_widget = QLabel('right') self.model = QStandardItemModel() self.selectionmodel = QItemSelectionModel(self.model) stream = 'primary' field = 'img' self.test_tab_view = TabView(self.model, self.selectionmodel, widgetcls=MyImageView, stream=stream, field=field) self.parameter_view = ParameterTree() for operation in self.my_workflow.operations: parameter_dict = operation.as_parameter() for list_parameter in parameter_dict: parameter = Parameter.create(**list_parameter) self.parameter_view.addParameters(parameter) stage_layout = GUILayout( center=self.split_widget, #left=left_widget, #right=right_widget, #leftbottom = leftbottom_widget, bottom=self.button, ) second_stage_layout = GUILayout(center=self.test_tab_view, righttop=self.parameter_view) #workflow_stage = GUILayout(center=self.test_tab_view, righttop=self.my_workflow_editor) #self.button.clicked.connect(self.update_label) #self.button.clicked.connect(self.show_message) self.button.clicked.connect(self.run_workflow) self.stages = { 'catalogviewer and fft': stage_layout, 'Something Else': second_stage_layout, #'testing workflow editor': workflow_stage, } super(MyGUIPlugin, self).__init__()
class SAXSMultiViewerPlugin(QSplitter, QWidgetPlugin): def __init__(self, headermodel, selectionmodel): super(SAXSMultiViewerPlugin, self).__init__() self.leftTabView = TabView() self.leftTabView.setWidgetClass(SAXSViewerPluginBase) self.leftTabView.setHeaderModel(headermodel) self.leftTabView.setSelectionModel(selectionmodel) self.rightTabView = TabView() self.rightTabView.setWidgetClass(SAXSViewerPluginBase) self.rightTabView.setHeaderModel(headermodel) self.addWidget(self.leftTabView) self.addWidget(self.rightTabView) def __getattr__(self, attr): ## implicitly wrap methods from leftViewer if hasattr(self.plotwidget, attr): m = getattr(self.leftViewer, attr) if hasattr(m, '__call__'): return m raise NameError(attr)
def __init__(self): # Data model self.catalogModel = QStandardItemModel() # Selection model self.selectionmodel = QItemSelectionModel(self.catalogModel) # Setup TabViews self.rawview = TabView(self.catalogModel, self.selectionmodel, widgets.NCEMViewerPlugin, 'primary', field='raw') self.fftview = TabView(self.catalogModel, self.selectionmodel, widgets.FFTViewerPlugin, 'primary', field='raw') #self.fourDview = TabView(self.headermodel, self.selectionmodel, widgets.FourDImageView, 'primary') self.metadataview = MetadataView(self.catalogModel, self.selectionmodel, excludedkeys=('uid', 'descriptor', 'data')) # self.toolbar = widgets.NCEMToolbar(self.catalogModel, self.selectionmodel) self.stages = { 'View': GUILayout(self.rawview, right=self.metadataview), # top=self.toolbar, )), # 'View': GUILayout(self.rawview, top=self.toolbar), # '4D STEM': GUILayout(self.fourDview, ), 'FFT View': GUILayout(self.fftview, ) } super(NCEMPlugin, self).__init__()
class SAXSPlugin(GUIPlugin): name = 'SAXS' def __init__(self): # Late imports required due to plugin system from xicam.SAXS.calibration import CalibrationPanel from xicam.SAXS.widgets.SAXSViewerPlugin import SAXSCalibrationViewer, SAXSMaskingViewer, SAXSReductionViewer from xicam.SAXS.widgets.SAXSToolbar import SAXSToolbarRaw, SAXSToolbarMask, SAXSToolbarReduce from xicam.SAXS.widgets.XPCSToolbar import XPCSToolBar self.derivedDataModel = DerivedDataModel() self.catalogModel = QStandardItemModel() # Data model self.catalogModel = QStandardItemModel() self.selectionmodel = QItemSelectionModel(self.catalogModel) # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() self.roiworkflow = ROIWorkflow() # Grab the calibration plugin self.calibrationsettings = pluginmanager.get_plugin_by_name('xicam.SAXS.calibration', 'SettingsPlugin') # Setup TabViews # FIXME -- rework how fields propagate to displays (i.e. each image has its own detector, switching # between tabs updates the detector combobbox correctly) field = "fccd_image" self.calibrationtabview = TabView(self.catalogModel, widgetcls=SAXSCalibrationViewer, stream='primary', field=field, selectionmodel=self.selectionmodel, bindings=[(self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.masktabview = TabView(self.catalogModel, widgetcls=SAXSMaskingViewer, selectionmodel=self.selectionmodel, stream='primary', field=field, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.reducetabview = TabView(self.catalogModel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, stream='primary', field=field, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.comparemultiview = QLabel("COMING SOON!") # SAXSMultiViewerPlugin(self.catalogModel, self.selectionmodel) # Setup correlation views self.correlationView = TabView(self.catalogModel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, stream='primary', field=field) self.twoTimeProcessor = TwoTimeParameterTree(processor=self.processTwoTime) self.twoTimeToolBar = XPCSToolBar(headermodel=self.catalogModel, selectionmodel=self.selectionmodel, view=self.correlationView.currentWidget, workflow=self.roiworkflow, index=0) self.oneTimeProcessor = OneTimeParameterTree(processor=self.processOneTime) self.oneTimeToolBar = XPCSToolBar(view=self.correlationView.currentWidget, workflow=self.roiworkflow, index=0) # Setup toolbars self.rawtoolbar = SAXSToolbarRaw(self.catalogModel, self.selectionmodel) self.masktoolbar = SAXSToolbarMask(self.catalogModel, self.selectionmodel) self.reducetoolbar = SAXSToolbarReduce(self.catalogModel, self.selectionmodel, view=self.reducetabview.currentWidget, workflow=self.reduceworkflow) self.reducetabview.kwargs['toolbar'] = self.reducetoolbar self.reducetoolbar.sigDeviceChanged.connect(self.deviceChanged) # Setup calibration widgets self.calibrationsettings.setModels(self.catalogModel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel(self.catalogModel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect(self.doCalibrateWorkflow) self.calibrationsettings.sigGeometryChanged.connect(self.doSimulateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = DerivedDataWidget(self.derivedDataModel) self.reducetoolbar.sigDoWorkflow.connect(self.doReduceWorkflow) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(self.catalogChanged) # Setup correlation widgets self.correlationResults = DerivedDataWidget(self.derivedDataModel) self.stages = { 'Calibrate': GUILayout(self.calibrationtabview, right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.rawtoolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor, top=self.masktoolbar), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.reducetoolbar), 'Compare': GUILayout(self.comparemultiview, top=self.reducetoolbar, bottom=self.reduceplot, right=self.reduceeditor), 'Correlate': { '2-Time Correlation': GUILayout(self.correlationView, top=self.twoTimeToolBar, rightbottom=self.twoTimeProcessor, bottom=self.correlationResults), '1-Time Correlation': GUILayout(self.correlationView, top=self.oneTimeToolBar, rightbottom=self.oneTimeProcessor, bottom=self.correlationResults) } } super(SAXSPlugin, self).__init__() # Start visualizations self.displayworkflow.visualize(self.reduceplot, imageview=lambda: self.reducetabview.currentWidget(), toolbar=self.reducetoolbar) def getAI(self): """ Convenience method to get current field's AI """ device = self.reducetoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) return ai def indexChanged(self): if not self.reduceplot.toolbar.multiplot.isChecked(): self.doReduceWorkflow() def catalogChanged(self): # TODO: both catalogChanged and deviceChanged will fire, redundantly, when the first image is opened self.doReduceWorkflow() self.doDisplayWorkflow() def deviceChanged(self, device_name): self.doReduceWorkflow() self.doDisplayWorkflow() def currentCatalog(self): return self.catalogModel.itemFromIndex(self.selectionmodel.currentIndex()).data(Qt.UserRole) def schema(self): saxs_schema = { "techniques": [ { "technique": "scattering", "configuration": { "geometry": "transmission", "detector_model": "fastccd", }, "data_mapping": { # "incoming_energy": [ # "baseline", # "E" # ] "data_image": [ "primary", "fccd_image" ], "dark_image": [ "dark", "fccd_image" ] }, "version": 0 }, ]} return saxs_schema def appendCatalog(self, catalog: BlueskyRun, **kwargs): catalog.metadata.update(self.schema()) displayName = "" if 'sample_name' in catalog.metadata['start']: displayName = catalog.metadata['start']['sample_name'] elif 'scan_id' in catalog.metadata['start']: displayName = f"Scan: {catalog.metadata['start']['scan_id']}" else: displayName = f"UID: {catalog.metadata['start']['uid']}" item = CheckableItem(displayName) item.setData(displayName, Qt.DisplayRole) item.setData(catalog, Qt.UserRole) self.catalogModel.appendRow(item) self.catalogModel.dataChanged.emit(item.index(), item.index()) def checkDataShape(self, data): """Checks the shape of the data and gets the first frame if able to.""" if data.shape[0] > 1: msg.notifyMessage("Looks like you did not open a single data frame. " "Automated calibration only works with single frame data.") return None else: return data[0] @threads.method() def doCalibrateWorkflow(self, workflow: Workflow): data = self.calibrationtabview.currentWidget().image data = self.checkDataShape(data) if data is None: return device = self.rawtoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) # ai.detector = detectors.Pilatus2M() calibrant = self.calibrationpanel.parameter['Calibrant Material'] def setAI(result): self.calibrationsettings.setAI(result['ai'].value, device) self.doMaskingWorkflow() workflow.execute(None, data=data, ai=ai, calibrant=calibrant, callback_slot=setAI, threadkey='calibrate') @threads.method() def doSimulateWorkflow(self, *_): # TEMPORARY HACK for demonstration # if self.reducetabview.currentWidget(): # threads.invoke_in_main_thread(self.reducetabview.currentWidget().setTransform) if not self.calibrationtabview.currentWidget(): return data = self.calibrationtabview.currentWidget().image data = self.checkDataShape(data) if data is None: return device = self.rawtoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) if not ai: return calibrant = self.calibrationpanel.parameter['Calibrant Material'] outputwidget = self.calibrationtabview.currentWidget() def showSimulatedCalibrant(result=None): outputwidget.setCalibrantImage(result['data'].value) self.simulateworkflow.execute(None, data=data, ai=ai, calibrant=calibrant, callback_slot=showSimulatedCalibrant, threadkey='simulate') @threads.method() def doMaskingWorkflow(self, workflow=None): if not self.masktabview.currentWidget(): return if not self.checkPolygonsSet(self.maskingworkflow): data = self.masktabview.currentWidget().image device = self.masktoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) outputwidget = self.masktabview.currentWidget() def showMask(result=None): if result: outputwidget.setMaskImage(result['mask'].value) else: outputwidget.setMaskImage(None) self.doDisplayWorkflow() self.doReduceWorkflow() if not workflow: workflow = self.maskingworkflow workflow.execute(None, data=data, ai=ai, callback_slot=showMask, threadkey='masking') # disabled @threads.method() def doDisplayWorkflow(self): return if not self.reducetabview.currentWidget(): return currentwidget = self.reducetabview.currentWidget() data = currentwidget.image data = [data[currentwidget.timeIndex(currentwidget.timeline)[0]]] device = self.reducetoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) if not ai: return mask = self.maskingworkflow.lastresult[0]['mask'].value if self.maskingworkflow.lastresult else None outputwidget = currentwidget def showDisplay(*results): outputwidget.setResults(results) self.displayworkflow.execute(None, data=data, ai=ai, mask=mask, callback_slot=showDisplay, threadkey='display') @threads.method() def doReduceWorkflow(self): return if not self.reducetabview.currentWidget(): return multimode = self.reducetoolbar.multiplot.isChecked() currentItem = self.catalogModel.itemFromIndex(self.selectionmodel.currentIndex()) # FIXME -- hardcoded stream stream = "primary" data = currentItem.data(Qt.UserRole) field = self.reducetoolbar.detectorcombobox.currentText() if not field: return eventStream = getattr(currentItem.data(Qt.UserRole), stream).to_dask()[ self.reducetoolbar.detectorcombobox.currentText()] if eventStream.ndim > 3: eventStream = eventStream[0] data = MetaXArray(eventStream) if not multimode: currentwidget = self.reducetabview.currentWidget() data = [data[currentwidget.timeIndex(currentwidget.timeLine)[0]]] device = self.reducetoolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) if not ai: return ai = [ai] * len(data) mask = [self.maskingworkflow.lastresult[0]['mask'].value if self.maskingworkflow.lastresult else None] * len( data) def showReduce(*results): # FIXME -- Better way to get the hints from the results parentItem = CheckableItem("Scattering Reduction") for result in results: hints = next(iter(result.items()))[-1].parent.hints for hint in hints: item = CheckableItem(hint.name) item.setData(hint, Qt.UserRole) parentItem.appendRow(item) self.derivedDataModel.appendRow(parentItem) self.reduceworkflow.execute_all(None, data=data, ai=ai, mask=mask, callback_slot=showReduce, threadkey='reduce') def checkPolygonsSet(self, workflow: Workflow): """ Check for any unset polygonmask processes; start masking mode if found Parameters ---------- workflow: Workflow Returns ------- bool True if unset polygonmask process is found """ pluginmaskclass = pluginmanager.get_plugin_by_name('Polygon Mask', 'ProcessingPlugin') for process in workflow.processes: if isinstance(process, pluginmaskclass): if process.polygon.value is None: self.startPolygonMasking(process) return True return False def startPolygonMasking(self, process): self.setEnabledOuterWidgets(False) # Start drawing mode viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.imageItem.setDrawKernel(kernel=np.array([[0]]), mask=None, center=(0, 0), mode='add') viewer.imageItem.drawMode = self.drawEvent viewer.maskROI.clearPoints() # Setup other signals process.parameter.child('Finish Mask').sigActivated.connect(partial(self.finishMask, process)) process.parameter.child('Clear Selection').sigActivated.connect(self.clearMask) def setEnabledOuterWidgets(self, enabled): # Disable other widgets mainwindow = self.masktabview.window() for dockwidget in mainwindow.findChildren(QDockWidget): dockwidget.setEnabled(enabled) mainwindow.rightwidget.setEnabled(True) self.maskeditor.workflowview.setEnabled(enabled) self.masktabview.tabBar().setEnabled(enabled) mainwindow.menuBar().setEnabled(enabled) mainwindow.pluginmodewidget.setEnabled(enabled) def clearMask(self): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.maskROI.clearPoints() def finishMask(self, process, sender): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase process.polygon.value = np.array([list(handle['pos']) for handle in viewer.maskROI.handles]) self.setEnabledOuterWidgets(True) # End drawing mode viewer.imageItem.drawKernel = None viewer.maskROI.clearPoints() process.parameter.clearChildren() # Redo workflow with polygon self.doMaskingWorkflow() def drawEvent(self, kernel, imgdata, mask, ss, ts, event): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.maskROI.addFreeHandle(viewer.view.vb.mapSceneToView(event.scenePos())) if len(viewer.maskROI.handles) > 1: viewer.maskROI.addSegment(viewer.maskROI.handles[-2]['item'], viewer.maskROI.handles[-1]['item']) def processOneTime(self): self.process(self.oneTimeProcessor, self.correlationView.currentWidget(), finished_slot=self.updateDerivedDataModel) def processTwoTime(self): self.process(self.twoTimeProcessor, self.correlationView.currentWidget(), finished_slot=self.updateDerivedDataModel) def process(self, processor: CorrelationParameterTree, widget, **kwargs): if processor: roiFuture = self.roiworkflow.execute(data=self.correlationView.currentWidget().image[0], image=self.correlationView.currentWidget().imageItem) # Pass in single frame for data shape roiResult = roiFuture.result() label = roiResult[-1]["roi"] if label is None: msg.notifyMessage("Please define an ROI using the toolbar before running correlation.") return workflow = processor.workflow # FIXME -- don't grab first match technique = \ [technique for technique in self.schema()['techniques'] if technique['technique'] == 'scattering'][0] stream, field = technique['data_mapping']['data_image'] # TODO: the compute() takes a long time..., do we need to do this here? If so, show a progress bar... # Trim the data frames catalog = self.currentCatalog() data = [getattr(catalog, stream).to_dask()[field][0].where( DataArray(label, dims=["dim_1", "dim_2"]), drop=True).compute()] # Trim the dark images msg.notifyMessage("Skipping dark correction...") darks = [None] * len(data) dark_stream, dark_field = technique['data_mapping']['dark_image'] if stream in catalog: darks = [getattr(catalog, dark_stream).to_dask()[dark_field][0].where( DataArray(label, dims=["dim_1", "dim_2"]), drop=True).compute()] else: msg.notifyMessage(f"No dark stream named \"{dark_stream}\" for current catalog. No dark correction.") label = label.compress(np.any(label, axis=0), axis=1).compress(np.any(label, axis=1), axis=0) labels = [label] * len(data) # TODO: update for multiple ROIs numLevels = [1] * len(data) numBufs = [] for i in range(len(data)): shape = data[i].shape[0] # multi_tau_corr requires num_bufs to be even if shape % 2: shape += 1 numBufs.append(shape) if kwargs.get('finished_slot'): finishedSlot = kwargs['finished_slot'] else: finishedSlot = self.updateDerivedDataModel # workflow_pickle = pickle.dumps(workflow) workflow.execute_all(None, # data=data, images=data, darks=darks, labels=labels, finished_slot=partial(finishedSlot, workflow=workflow)) # workflow_pickle=workflow_pickle)) def updateDerivedDataModel(self, workflow, **kwargs): parentItem = CheckableItem(workflow.name) for hint in workflow.hints: item = CheckableItem(hint.name) item.setData(hint, Qt.UserRole) item.setCheckable(True) parentItem.appendRow(item) self.derivedDataModel.appendRow(parentItem)
class TomographyPlugin(GUIPlugin): name = 'Tomography' sigLog = Signal(int, str, str, np.ndarray) slice = 0 multislice = 1 preview3d = 2 fullrecon = 3 def __init__(self): self.workflow = Workflow() self.headermodel = QStandardItemModel() # self.alignmenttabview = TabView(self.headermodel) self.rawtabview = TabView(self.headermodel, widgetcls=RAWViewer, field='primary') self.recontabs = QTabWidget() self.workfloweditor = WorkflowEditor(self.workflow) self.workfloweditor.setHidden(True) self.tomotoolbar = TomoToolbar() self.tomotoolbar.sigSliceReconstruction.connect(self.sliceReconstruct) self.tomotoolbar.sigFullReconstruction.connect(self.fullReconstruction) self.stages = { 'Alignment': GUILayout(QLabel('Alignment'), right=self.workfloweditor, top=self.tomotoolbar), 'Preprocess': GUILayout(self.rawtabview, right=self.workfloweditor, top=self.tomotoolbar), 'Reconstruct': GUILayout(self.recontabs, top=self.tomotoolbar, right=self.workfloweditor), } super(TomographyPlugin, self).__init__() def appendHeader(self, header: NonDBHeader, **kwargs): item = QStandardItem(header.startdoc.get('sample_name', '????')) item.header = header self.headermodel.appendRow(item) self.headermodel.dataChanged.emit(QModelIndex(), QModelIndex()) def sliceReconstruct(self): currentitem = self.headermodel.item(self.rawtabview.currentIndex()) if not currentitem: msg.showMessage( 'Error: You must open files before reconstructing.') try: msg.showBusy() msg.showMessage('Running slice reconstruction...', level=msg.INFO) path = self.headermodel.item( self.rawtabview.currentIndex()).header.startdoc['path'] self.workflow.execute( None, path=path, threadkey='slicereconstruct', callback_slot=partial(self.showReconstruction, mode=self.slice), except_slot=self.exceptionCallback) except Exception as ex: msg.logError(ex) msg.showReady() msg.clearMessage() def fullReconstruction(self): volumeviewer = VolumeViewer() self.recontabs.addTab(volumeviewer, '????') currentitem = self.headermodel.item(self.rawtabview.currentIndex()) if not currentitem: msg.showMessage( 'Error: You must open files before reconstructing.') try: msg.showBusy() msg.showMessage('Running slice reconstruction...', level=msg.INFO) currentheader = self.headermodel.item( self.rawtabview.currentIndex()).header readprocess = self.workflow.processes[ 0] # hopefully! TODO: require a readprocess first readprocess.path.value = currentheader.startdoc['path'] numofsinograms = currentheader.meta_array('primary').shape[1] executor = DaskExecutor() client = distributed.Client() def chunkiterator(workflow): for i in range(0, int(numofsinograms), int(readprocess.chunksize.value)): readprocess.sinoindex.value = i yield executor.execute(workflow) _reconthread = QThreadFutureIterator( chunkiterator, self.workflow, callback_slot=partial(self.showReconstruction, mode=self.fullrecon), except_slot=self.exceptionCallback) _reconthread.start() except Exception as ex: msg.logError(ex) msg.showReady() msg.clearMessage() def exceptionCallback(self, ex): msg.notifyMessage("Reconstruction failed;\n see log for error") msg.showMessage("Reconstruction failed; see log for error") msg.logError(ex) msg.showReady() def showReconstruction(self, result, mode): print('result:', result) if mode == self.slice: sliceviewer = SliceViewer() sliceviewer.setImage(list(result.values())[0].value.squeeze()) self.recontabs.addTab(sliceviewer, '????') if mode == self.fullrecon: self.recontabs.widget(self.recontabs.count() - 1).appendData( list(result.values())[0].value[::4, ::4, ::4]) msg.showReady()
class BSISB(GUIPlugin): name = 'BSISB' def __init__(self, *args, **kwargs): self.mapToH5 = mapToH5() # Data model self.headermodel = QStandardItemModel() # Selection model self.selectionmodel = QItemSelectionModel(self.headermodel) self.PCA_widget = FactorizationWidget(self.headermodel, self.selectionmodel) self.NMF_widget = FactorizationWidget(self.headermodel, self.selectionmodel) # update headers list when a tab window is closed self.headermodel.rowsRemoved.connect( partial(self.PCA_widget.setHeader, 'spectra')) self.headermodel.rowsRemoved.connect( partial(self.NMF_widget.setHeader, 'volume')) # Setup tabviews and update map selection self.imageview = TabView(self.headermodel, self.selectionmodel, MapView, 'image') self.stages = { "MapToH5": GUILayout(self.mapToH5), "Image View": GUILayout(self.imageview), "PCA": GUILayout(self.PCA_widget), "NMF": GUILayout(self.NMF_widget) } super(BSISB, self).__init__(*args, **kwargs) def appendHeader(self, header: NonDBHeader, **kwargs): # init item item = QStandardItem( header.startdoc.get('sample_name', '????') + '_' + str(self.headermodel.rowCount())) item.header = header item.selectedPixels = None self.headermodel.appendRow(item) self.headermodel.dataChanged.emit(QModelIndex(), QModelIndex()) # read out image shape imageEvent = next(header.events(fields=['image'])) imgShape = imageEvent['imgShape'] # get current MapView widget currentMapView = self.imageview.currentWidget() # transmit imgshape to currentMapView currentMapView.getImgShape(imgShape) # get xy coordinates of ROI selected pixels currentMapView.sigRoiPixels.connect( partial(self.appendSelection, 'pixel')) currentMapView.sigRoiState.connect(partial(self.appendSelection, 'ROI')) currentMapView.sigAutoMaskState.connect( partial(self.appendSelection, 'autoMask')) currentMapView.sigSelectMaskState.connect( partial(self.appendSelection, 'select')) self.PCA_widget.setHeader(field='spectra') self.NMF_widget.setHeader(field='volume') for i in range(4): self.PCA_widget.roiList[i].sigRegionChangeFinished.connect( self.updateROI) def appendSelection(self, sigCase, sigContent): # get current widget and append selectedPixels to item currentItemIdx = self.imageview.currentIndex() if sigCase == 'pixel': self.headermodel.item(currentItemIdx).selectedPixels = sigContent elif sigCase == 'ROI': self.headermodel.item(currentItemIdx).roiState = sigContent self.PCA_widget.updateRoiMask() self.NMF_widget.updateRoiMask() elif sigCase == 'autoMask': self.headermodel.item(currentItemIdx).maskState = sigContent self.PCA_widget.updateRoiMask() self.NMF_widget.updateRoiMask() elif sigCase == 'select': self.headermodel.item(currentItemIdx).selectState = sigContent self.PCA_widget.updateRoiMask() self.NMF_widget.updateRoiMask() def updateROI(self, roi): if self.selectionmodel.hasSelection(): selectMapIdx = self.selectionmodel.selectedIndexes()[0].row() else: selectMapIdx = 0 self.imageview.widget(selectMapIdx).roiMove(roi) def updateTab(self, tabIdx): if tabIdx >= 0: self.selectionmodel.select(self.headermodel.index(tabIdx, 0), QItemSelectionModel.ClearAndSelect)
def __init__(self): # Late imports required due to plugin system from xicam.SAXS.calibration import CalibrationPanel from xicam.SAXS.widgets.SAXSMultiViewer import SAXSMultiViewerPlugin from xicam.SAXS.widgets.SAXSViewerPlugin import SAXSViewerPluginBase, SAXSCalibrationViewer, SAXSMaskingViewer, \ SAXSReductionViewer from xicam.SAXS.widgets.SAXSToolbar import SAXSToolbar from xicam.SAXS.widgets.SAXSSpectra import SAXSSpectra # Data model self.headermodel = QStandardItemModel() self.selectionmodel = QItemSelectionModel(self.headermodel) # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() # Grab the calibration plugin self.calibrationsettings = pluginmanager.getPluginByName( 'xicam.SAXS.calibration', 'SettingsPlugin').plugin_object print( pluginmanager.getPluginByName('xicam.SAXS.calibration', 'SettingsPlugin').path) # Setup TabViews self.calibrationtabview = TabView( self.headermodel, widgetcls=SAXSCalibrationViewer, selectionmodel=self.selectionmodel, bindings=[(self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.masktabview = TabView( self.headermodel, widgetcls=SAXSMaskingViewer, selectionmodel=self.selectionmodel, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.reducetabview = TabView( self.headermodel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.comparemultiview = SAXSMultiViewerPlugin(self.headermodel, self.selectionmodel) # self.tabviewsynchronizer = TabViewSynchronizer( # [self.calibrationtabview, self.masktabview, self.reducetabview, self.comparemultiview.leftTabView]) # Setup toolbars self.toolbar = SAXSToolbar(self.headermodel, self.selectionmodel) self.calibrationtabview.kwargs['toolbar'] = self.toolbar self.reducetabview.kwargs['toolbar'] = self.toolbar # Setup calibration widgets self.calibrationsettings.setModels( self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel( self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect( self.doCalibrateWorkflow) self.calibrationsettings.sigGeometryChanged.connect( self.doSimulateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = SAXSSpectra(self.reduceworkflow, self.toolbar) self.toolbar.sigDoWorkflow.connect(partial(self.doReduceWorkflow)) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(self.headerChanged) self.reducetabview.currentChanged.connect(self.headerChanged) # Setup more bindings self.calibrationsettings.sigSimulateCalibrant.connect( partial(self.doSimulateWorkflow)) self.stages = { 'Calibrate': GUILayout( self.calibrationtabview, # pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object() right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.toolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor, top=self.toolbar), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.toolbar), 'Compare': GUILayout(self.comparemultiview, top=self.toolbar, bottom=self.reduceplot, right=self.reduceeditor) } super(SAXSPlugin, self).__init__() # Start visualizations self.displayworkflow.visualize( self.reduceplot, imageview=lambda: self.reducetabview.currentWidget(), toolbar=self.toolbar)
class XPCS(GUIPlugin): name = 'XPCS' def __init__(self): self.catalog = BlueskyInMemoryCatalog() # XPCS data model self.resultsModel = QStandardItemModel() # Input (raw) data model self.headerModel = QStandardItemModel() self.selectionModel = QItemSelectionModel(self.headerModel) # Widgets self.calibrationSettings = pluginmanager.getPluginByName( 'xicam.SAXS.calibration', 'SettingsPlugin').plugin_object # Setup TabViews self.rawTabView = TabView( self.headerModel, widgetcls=XPCSViewerPlugin, selectionmodel=self.selectionModel, bindings=[(self.calibrationSettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) # Setup correlation views self.twoTimeView = TwoTimeView() self.twoTimeFileSelection = FileSelectionView(self.headerModel, self.selectionModel) self.twoTimeProcessor = TwoTimeProcessor() self.twoTimeToolBar = QToolBar() self.twoTimeToolBar.addAction(QIcon(static.path('icons/run.png')), 'Process', self.processTwoTime) self.twoTimeToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.oneTimeView = OneTimeView() self.oneTimeFileSelection = FileSelectionView(self.headerModel, self.selectionModel) self.oneTimeProcessor = OneTimeProcessor() self.oneTimeToolBar = QToolBar() self.oneTimeToolBar.addAction(QIcon(static.path('icons/run.png')), 'Process', self.processOneTime) self.oneTimeToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # self.placeholder = QLabel('correlation parameters') self.stages = { 'Raw': GUILayout(self.rawTabView, right=self.calibrationSettings.widget), '2-Time Correlation': GUILayout( self.twoTimeView, top=self.twoTimeToolBar, right=self.twoTimeFileSelection, rightbottom=self.twoTimeProcessor, ), # bottom=self.placeholder), '1-Time Correlation': GUILayout( self.oneTimeView, top=self.oneTimeToolBar, right=self.oneTimeFileSelection, rightbottom=self.oneTimeProcessor, ) # bottom=self.placeholder) } # TODO -- improve result caching self._results = [] super(XPCS, self).__init__() def appendHeader(self, header: NonDBHeader, **kwargs): item = QStandardItem(header.startdoc.get('sample_name', '????')) item.header = header self.headerModel.appendRow(item) self.selectionModel.reset() self.selectionModel.setCurrentIndex( self.headerModel.index(self.headerModel.rowCount() - 1, 0), QItemSelectionModel.Rows) self.headerModel.dataChanged.emit(QModelIndex(), QModelIndex()) # Load any reduced (processed) data reduced = False for descriptor in header.descriptordocs: if descriptor['name'] == 'reduced': reduced = True break paths = header.startdoc.get('paths') for path in paths: if reduced: startItem = QStandardItem( header.startdoc.get('sample_name', '??')) eventlist = header.eventdocs for event in eventlist: eventItem = QStandardItem(event['data']['name']) eventItem.setData(event, Qt.UserRole) eventItem.setCheckable(True) startItem.appendRow(eventItem) # TODO -- properly add to view (one-time or 2-time, etc.) self.oneTimeView.model.invisibleRootItem().appendRow(startItem) def getAI(self): return None def currentheader(self): return self.headerModel.itemFromIndex( self.selectionModel.currentIndex()).header def currentheaders(self): selected_indices = self.selectionModel.selectedIndexes() headers = [] for model_index in selected_indices: headers.append(self.headerModel.itemFromIndex(model_index).header) return headers def processOneTime(self): self.process(self.oneTimeProcessor, callback_slot=partial( self.saveResult, fileSelectionView=self.oneTimeFileSelection), finished_slot=partial(self.createDocument, view=self.oneTimeView)) def processTwoTime(self): self.process(self.twoTimeProcessor, callback_slot=partial( self.saveResult, fileSelectionView=self.twoTimeFileSelection), finished_slot=partial(self.createDocument, view=self.twoTimeView)) def process(self, processor: XPCSProcessor, **kwargs): if processor: workflow = processor.workflow data = [header.meta_array() for header in self.currentheaders()] currentWidget = self.rawTabView.currentWidget() rois = [ item for item in currentWidget.view.items if isinstance(item, BetterROI) ] labels = [currentWidget.poly_mask()] * len(data) numLevels = [1] * len(data) numBufs = [] for i, _ in enumerate(data): shape = data[i].shape[0] # multi_tau_corr requires num_bufs to be even if shape % 2: shape += 1 numBufs.append(shape) if kwargs.get('callback_slot'): callbackSlot = kwargs['callback_slot'] else: callbackSlot = self.saveResult if kwargs.get('finished_slot'): finishedSlot = kwargs['finished_slot'] else: finishedSlot = self.createDocument workflowPickle = pickle.dumps(workflow) workflow.execute_all(None, data=data, labels=labels, num_levels=numLevels, num_bufs=numBufs, callback_slot=callbackSlot, finished_slot=partial( finishedSlot, header=self.currentheader(), roi=repr(rois[0]), workflow=workflowPickle)) # TODO -- should header be passed to callback_slot # (callback slot handle can handle multiple data items in data list) def saveResult(self, result, fileSelectionView=None): if fileSelectionView: data = dict() if not fileSelectionView.correlationName.displayText(): data[ 'name'] = fileSelectionView.correlationName.placeholderText( ) else: data['name'] = fileSelectionView.correlationName.displayText() data['result'] = result self._results.append(data) def createDocument(self, view: CorrelationView, header, roi, workflow): self.catalog.upsert(self._createDocument, (self._results, header, roi, workflow), {}) # TODO -- make sure that this works for multiple selected series to process key = list(self.catalog)[-1] parentItem = QStandardItem(self._results[-1]['name']) for name, doc in self.catalog[key].read_canonical(): if name == 'event': resultsModel = view.model # item = QStandardItem(doc['data']['name']) # TODO -- make sure passed data['name'] is unique in model -> CHECK HERE item = QStandardItem(doc['data']['name']) item.setData(doc, Qt.UserRole) item.setCheckable(True) parentItem.appendRow(item) selectionModel = view.selectionModel selectionModel.reset() selectionModel.setCurrentIndex( resultsModel.index(resultsModel.rowCount() - 1, 0), QItemSelectionModel.Rows) selectionModel.select(selectionModel.currentIndex(), QItemSelectionModel.SelectCurrent) resultsModel.appendRow(parentItem) self._results = [] def _createDocument(self, results, header, roi, workflow): timestamp = time.time() run_bundle = event_model.compose_run() yield 'start', run_bundle.start_doc # TODO -- make sure workflow pickles, or try dill / cloudpickle source = 'Xi-cam' peek_result = results[0]['result'] g2_shape = peek_result['g2'].value.shape[0] # TODO -- make sure g2_err is calculated and added to internal process documents import numpy as np g2_err = np.zeros(g2_shape) g2_err_shape = g2_shape lag_steps_shape = peek_result['lag_steps'].value.shape[0] workflow = [] workflow_shape = len(workflow) reduced_data_keys = { 'g2': { 'source': source, 'dtype': 'number', 'shape': [g2_shape] }, 'g2_err': { 'source': source, 'dtype': 'number', 'shape': [g2_err_shape] }, 'lag_steps': { 'source': source, 'dtype': 'number', 'shape': [lag_steps_shape] }, 'fit_curve': { 'source': source, 'dtype': 'number', 'shape': [lag_steps_shape] }, 'name': { 'source': source, 'dtype': 'string', 'shape': [] }, # todo -- shape 'workflow': { 'source': source, 'dtype': 'string', 'shape': [workflow_shape] } } reduced_stream_name = 'reduced' reduced_stream_bundle = run_bundle.compose_descriptor( data_keys=reduced_data_keys, name=reduced_stream_name) yield 'descriptor', reduced_stream_bundle.descriptor_doc # todo -- peek frame shape frame_data_keys = { 'frame': { 'source': source, 'dtype': 'number', 'shape': [] } } frame_stream_name = 'primary' frame_stream_bundle = run_bundle.compose_descriptor( data_keys=frame_data_keys, name=frame_stream_name) yield 'descriptor', frame_stream_bundle.descriptor_doc # todo -- store only paths? store the image data itself (memory...) # frames = header.startdoc['paths'] frames = [] for frame in frames: yield 'event', frame_stream_bundle.compose_event( data={frame}, timestamps={timestamp}) for result in results: yield 'event', reduced_stream_bundle.compose_event( data={ 'g2': result['result']['g2'].value, 'g2_err': g2_err, 'lag_steps': result['result']['lag_steps'].value, 'fit_curve': result['result']['fit_curve'].value, 'name': roi, # TODO update to roi 'workflow': workflow }, timestamps={ 'g2': timestamp, 'g2_err': timestamp, 'lag_steps': timestamp, 'fit_curve': timestamp, 'name': timestamp, 'workflow': workflow }) yield 'stop', run_bundle.compose_stop()
class SAXSPlugin(GUIPlugin): name = 'SAXS' def __init__(self): # Late imports required due to plugin system from xicam.SAXS.calibration import CalibrationPanel from xicam.SAXS.widgets.SAXSMultiViewer import SAXSMultiViewerPlugin from xicam.SAXS.widgets.SAXSViewerPlugin import SAXSViewerPluginBase, SAXSCalibrationViewer, SAXSMaskingViewer, \ SAXSReductionViewer from xicam.SAXS.widgets.SAXSToolbar import SAXSToolbar from xicam.SAXS.widgets.SAXSSpectra import SAXSSpectra # Data model self.headermodel = QStandardItemModel() self.selectionmodel = QItemSelectionModel(self.headermodel) # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() # Grab the calibration plugin self.calibrationsettings = pluginmanager.getPluginByName( 'xicam.SAXS.calibration', 'SettingsPlugin').plugin_object print( pluginmanager.getPluginByName('xicam.SAXS.calibration', 'SettingsPlugin').path) # Setup TabViews self.calibrationtabview = TabView( self.headermodel, widgetcls=SAXSCalibrationViewer, selectionmodel=self.selectionmodel, bindings=[(self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.masktabview = TabView( self.headermodel, widgetcls=SAXSMaskingViewer, selectionmodel=self.selectionmodel, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.reducetabview = TabView( self.headermodel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.comparemultiview = SAXSMultiViewerPlugin(self.headermodel, self.selectionmodel) # self.tabviewsynchronizer = TabViewSynchronizer( # [self.calibrationtabview, self.masktabview, self.reducetabview, self.comparemultiview.leftTabView]) # Setup toolbars self.toolbar = SAXSToolbar(self.headermodel, self.selectionmodel) self.calibrationtabview.kwargs['toolbar'] = self.toolbar self.reducetabview.kwargs['toolbar'] = self.toolbar # Setup calibration widgets self.calibrationsettings.setModels( self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel( self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect( self.doCalibrateWorkflow) self.calibrationsettings.sigGeometryChanged.connect( self.doSimulateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = SAXSSpectra(self.reduceworkflow, self.toolbar) self.toolbar.sigDoWorkflow.connect(partial(self.doReduceWorkflow)) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(self.headerChanged) self.reducetabview.currentChanged.connect(self.headerChanged) # Setup more bindings self.calibrationsettings.sigSimulateCalibrant.connect( partial(self.doSimulateWorkflow)) self.stages = { 'Calibrate': GUILayout( self.calibrationtabview, # pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object() right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.toolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor, top=self.toolbar), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.toolbar), 'Compare': GUILayout(self.comparemultiview, top=self.toolbar, bottom=self.reduceplot, right=self.reduceeditor) } super(SAXSPlugin, self).__init__() # Start visualizations self.displayworkflow.visualize( self.reduceplot, imageview=lambda: self.reducetabview.currentWidget(), toolbar=self.toolbar) # def experimentChanged(self): # self.doReduceWorkflow(self.reduceworkflow) def getAI(self): """ Convenience method to get current field's AI """ device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) return ai def indexChanged(self): if not self.reduceplot.toolbar.multiplot.isChecked(): self.doReduceWorkflow(self.reduceworkflow) def headerChanged(self): self.toolbar.updatedetectorcombobox(None, None) self.doReduceWorkflow() self.doDisplayWorkflow() def appendHeader(self, header: NonDBHeader, **kwargs): item = QStandardItem(header.startdoc.get('sample_name', '????')) item.header = header self.headermodel.appendRow(item) self.selectionmodel.setCurrentIndex( self.headermodel.index(self.headermodel.rowCount() - 1, 0), QItemSelectionModel.Rows) self.headermodel.dataChanged.emit(QModelIndex(), QModelIndex()) def doCalibrateWorkflow(self, workflow: Workflow): data = self.calibrationtabview.currentWidget().header.meta_array()[0] device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) # ai.detector = detectors.Pilatus2M() calibrant = self.calibrationpanel.parameter['Calibrant Material'] def setAI(result): self.calibrationsettings.setAI(result['ai'].value, device) self.doMaskingWorkflow() workflow.execute(None, data=data, ai=ai, calibrant=calibrant, callback_slot=setAI, threadkey='calibrate') def doSimulateWorkflow(self): # TEMPORARY HACK for demonstration #self.reducetabview.currentWidget().setTransform() if not self.calibrationtabview.currentWidget(): return data = self.calibrationtabview.currentWidget().header.meta_array()[0] device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) calibrant = self.calibrationpanel.parameter['Calibrant Material'] outputwidget = self.calibrationtabview.currentWidget() def showSimulatedCalibrant(result=None): outputwidget.setCalibrantImage(result['data'].value) self.simulateworkflow.execute(None, data=data, ai=ai, calibrant=calibrant, callback_slot=showSimulatedCalibrant, threadkey='simulate') def doMaskingWorkflow(self, workflow=None): if not self.masktabview.currentWidget(): return if not self.checkPolygonsSet(self.maskingworkflow): data = self.masktabview.currentWidget().header.meta_array()[0] device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) outputwidget = self.masktabview.currentWidget() def showMask(result=None): if result: outputwidget.setMaskImage(result['mask'].value) else: outputwidget.setMaskImage(None) self.doDisplayWorkflow() self.doReduceWorkflow() if not workflow: workflow = self.maskingworkflow workflow.execute(None, data=data, ai=ai, callback_slot=showMask, threadkey='masking') def doDisplayWorkflow(self): if not self.reducetabview.currentWidget(): return currentwidget = self.reducetabview.currentWidget() data = currentwidget.header.meta_array()[currentwidget.timeIndex( currentwidget.timeLine)[0]] device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) mask = self.maskingworkflow.lastresult[0][ 'mask'].value if self.maskingworkflow.lastresult else None outputwidget = currentwidget def showDisplay(*results): outputwidget.setResults(results) self.displayworkflow.execute(None, data=data, ai=ai, mask=mask, callback_slot=showDisplay, threadkey='display') def doReduceWorkflow(self): if not self.reducetabview.currentWidget(): return multimode = self.reduceplot.toolbar.multiplot.isChecked() currentwidget = self.reducetabview.currentWidget() data = currentwidget.header.meta_array() if not multimode: data = [data[currentwidget.timeIndex(currentwidget.timeLine)[0]]] device = self.toolbar.detectorcombobox.currentText() ai = self.calibrationsettings.AI(device) ai = [ai] * len(data) mask = [ self.maskingworkflow.lastresult[0]['mask'].value if self.maskingworkflow.lastresult else None ] * len(data) outputwidget = self.reduceplot # outputwidget.clear_all() def showReduce(*results): self.reduceplot.plot_mode(results) pass self.reduceworkflow.execute_all(None, data=data, ai=ai, mask=mask, callback_slot=showReduce, threadkey='reduce') def checkPolygonsSet(self, workflow: Workflow): """ Check for any unset polygonmask processes; start masking mode if found Parameters ---------- workflow: Workflow Returns ------- bool True if unset polygonmask process is found """ pluginmaskclass = pluginmanager.getPluginByName( 'Polygon Mask', 'ProcessingPlugin') for process in workflow.processes: if isinstance(process, pluginmaskclass.plugin_object): if process.polygon.value is None: self.startPolygonMasking(process) return True return False def startPolygonMasking(self, process): self.setEnabledOuterWidgets(False) # Start drawing mode viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.imageItem.setDrawKernel(kernel=np.array([[0]]), mask=None, center=(0, 0), mode='add') viewer.imageItem.drawMode = self.drawEvent viewer.maskROI.clearPoints() # Setup other signals process.parameter.child('Finish Mask').sigActivated.connect( partial(self.finishMask, process)) process.parameter.child('Clear Selection').sigActivated.connect( self.clearMask) def setEnabledOuterWidgets(self, enabled): # Disable other widgets mainwindow = self.masktabview.window() for dockwidget in mainwindow.findChildren(QDockWidget): dockwidget.setEnabled(enabled) mainwindow.rightwidget.setEnabled(True) self.maskeditor.workflowview.setEnabled(enabled) self.masktabview.tabBar().setEnabled(enabled) mainwindow.menuBar().setEnabled(enabled) mainwindow.pluginmodewidget.setEnabled(enabled) def clearMask(self): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.maskROI.clearPoints() def finishMask(self, process, sender): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase process.polygon.value = np.array( [list(handle['pos']) for handle in viewer.maskROI.handles]) self.setEnabledOuterWidgets(True) # End drawing mode viewer.imageItem.drawKernel = None viewer.maskROI.clearPoints() process.parameter.clearChildren() # Redo workflow with polygon self.doMaskingWorkflow() def drawEvent(self, kernel, imgdata, mask, ss, ts, event): viewer = self.masktabview.currentWidget() # type: SAXSViewerPluginBase viewer.maskROI.addFreeHandle( viewer.view.vb.mapSceneToView(event.scenePos())) if len(viewer.maskROI.handles) > 1: viewer.maskROI.addSegment(viewer.maskROI.handles[-2]['item'], viewer.maskROI.handles[-1]['item'])
def __init__(self): # Data model self.headermodel = QStandardItemModel() # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() # Setup TabViews self.calibrationtabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary') self.masktabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary') self.reducetabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary', bindings=[('sigTimeChangeFinished', self.indexChanged)]) self.comparemultiview = SAXSMultiViewerPlugin(self.headermodel) self.tabviewsynchronizer = TabViewSynchronizer( [self.calibrationtabview, self.masktabview, self.reducetabview, self.comparemultiview.leftTabView]) # Setup toolbars self.calibrationtoolbar = SAXSToolbar(self.calibrationtabview, workflow=self.reduceworkflow) self.reducetoolbar = SAXSToolbar(self.reducetabview, workflow=self.reduceworkflow) self.calibrationtabview.kwargs['toolbar'] = self.calibrationtoolbar self.reducetabview.kwargs['toolbar'] = self.reducetoolbar # Setup calibration widgets self.calibrationsettings = pluginmanager.getPluginByName('DeviceProfiles', 'SettingsPlugin').plugin_object self.calibrationsettings.setModels(self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel() self.calibrationpanel.setModels(self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect(self.doCalibrateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceworkflow.attach(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = SAXSSpectra(self.reduceworkflow, self.reducetoolbar) self.reducetoolbar.sigDoWorkflow.connect(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reducetabview.currentChanged.connect(partial(self.doDisplayWorkflow, self.displayworkflow)) # Setup more bindings self.calibrationsettings.sigSimulateCalibrant.connect(partial(self.doSimulateWorkflow, self.simulateworkflow)) self.stages = { 'Calibrate': GUILayout(self.calibrationtabview, # pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object() right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.calibrationtoolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.reducetoolbar), 'Compare': GUILayout(self.comparemultiview, top=self.reducetoolbar, bottom=self.reduceplot, right=self.reduceeditor) } super(SAXSPlugin, self).__init__()
class SAXSPlugin(GUIPlugin): name = 'SAXS' sigLog = Signal(int, str, str, np.ndarray) def __init__(self): # Data model self.headermodel = QStandardItemModel() # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() # Setup TabViews self.calibrationtabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary') self.masktabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary') self.reducetabview = TabView(self.headermodel, pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object, 'primary', bindings=[('sigTimeChangeFinished', self.indexChanged)]) self.comparemultiview = SAXSMultiViewerPlugin(self.headermodel) self.tabviewsynchronizer = TabViewSynchronizer( [self.calibrationtabview, self.masktabview, self.reducetabview, self.comparemultiview.leftTabView]) # Setup toolbars self.calibrationtoolbar = SAXSToolbar(self.calibrationtabview, workflow=self.reduceworkflow) self.reducetoolbar = SAXSToolbar(self.reducetabview, workflow=self.reduceworkflow) self.calibrationtabview.kwargs['toolbar'] = self.calibrationtoolbar self.reducetabview.kwargs['toolbar'] = self.reducetoolbar # Setup calibration widgets self.calibrationsettings = pluginmanager.getPluginByName('DeviceProfiles', 'SettingsPlugin').plugin_object self.calibrationsettings.setModels(self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel() self.calibrationpanel.setModels(self.headermodel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect(self.doCalibrateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceworkflow.attach(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = SAXSSpectra(self.reduceworkflow, self.reducetoolbar) self.reducetoolbar.sigDoWorkflow.connect(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(partial(self.doReduceWorkflow, self.reduceworkflow)) self.reducetabview.currentChanged.connect(partial(self.doDisplayWorkflow, self.displayworkflow)) # Setup more bindings self.calibrationsettings.sigSimulateCalibrant.connect(partial(self.doSimulateWorkflow, self.simulateworkflow)) self.stages = { 'Calibrate': GUILayout(self.calibrationtabview, # pluginmanager.getPluginByName('SAXSViewerPlugin', 'WidgetPlugin').plugin_object() right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.calibrationtoolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.reducetoolbar), 'Compare': GUILayout(self.comparemultiview, top=self.reducetoolbar, bottom=self.reduceplot, right=self.reduceeditor) } super(SAXSPlugin, self).__init__() def experimentChanged(self): self.doReduceWorkflow(self.reduceworkflow) def indexChanged(self): if not self.reduceplot.toolbar.multiplot.isChecked(): self.doReduceWorkflow(self.reduceworkflow) def appendHeader(self, header: NonDBHeader, **kwargs): item = QStandardItem(header.startdoc.get('sample_name', '????')) item.header = header self.headermodel.appendRow(item) self.headermodel.dataChanged.emit(QModelIndex(), QModelIndex()) def doCalibrateWorkflow(self, workflow: Workflow): data = self.calibrationtabview.currentWidget().header.meta_array('primary')[0] device = self.calibrationpanel.parameter['Device'] ai = self.calibrationsettings.AI('pilatus2M') ai.detector = detectors.Pilatus2M() c = calibrant.ALL_CALIBRANTS('AgBh') def setAI(result): self.calibrationsettings.setAI(result['ai'].value, device) self.doMaskingWorkflow(self.maskingworkflow) workflow.execute(None, data=data, ai=ai, calibrant=c, callback_slot=setAI, threadkey='calibrate') def doSimulateWorkflow(self, workflow: Workflow): data = self.calibrationtabview.currentWidget().header.meta_array('primary')[0] ai = self.calibrationsettings.AI('pilatus2M') ai.detector = detectors.Pilatus2M() calibrant = self.calibrationpanel.parameter['Calibrant Material'] outputwidget = self.calibrationtabview.currentWidget() def showSimulatedCalibrant(result=None): outputwidget.setCalibrantImage(result['data'].value) workflow.execute(None, data=data, ai=ai, calibrant=calibrant, callback_slot=showSimulatedCalibrant, threadkey='simulate') def doMaskingWorkflow(self, workflow: Workflow): if not self.checkPolygonsSet(workflow): data = self.calibrationtabview.currentWidget().header.meta_array('primary')[0] ai = self.calibrationsettings.AI('pilatus2M') ai.detector = detectors.Pilatus2M() outputwidget = self.masktabview.currentWidget() def showMask(result=None): if result: outputwidget.setMaskImage(result['mask'].value) else: outputwidget.setMaskImage(None) self.doDisplayWorkflow(self.displayworkflow) self.doReduceWorkflow(self.reduceworkflow) workflow.execute(None, data=data, ai=ai, callback_slot=showMask, threadkey='masking') def doDisplayWorkflow(self, workflow: Workflow): currentwidget = self.reducetabview.currentWidget() data = currentwidget.header.meta_array('primary')[currentwidget.timeIndex(currentwidget.timeLine)[0]] ai = self.calibrationsettings.AI('pilatus2M') ai.detector = detectors.Pilatus2M() mask = self.maskingworkflow.lastresult[0]['mask'].value if self.maskingworkflow.lastresult else None outputwidget = currentwidget def showDisplay(*results): outputwidget.setResults(results) workflow.execute(None, data=data, ai=ai, mask=mask, callback_slot=showDisplay, threadkey='display') def doReduceWorkflow(self, workflow: Workflow): multimode = self.reduceplot.toolbar.multiplot.isChecked() currentwidget = self.reducetabview.currentWidget() data = currentwidget.header.meta_array('primary') if not multimode: data = [data[currentwidget.timeIndex(currentwidget.timeLine)[0]]] ai = self.calibrationsettings.AI('pilatus2M') ai.detector = detectors.Pilatus2M() ai = [ai] * len(data) mask = [self.maskingworkflow.lastresult[0]['mask'].value if self.maskingworkflow.lastresult else None] * len( data) outputwidget = self.reduceplot outputwidget.clear() def showReduce(*results): outputwidget.appendResult(results) workflow.execute_all(None, data=data, ai=ai, mask=mask, callback_slot=showReduce, threadkey='reduce') def checkPolygonsSet(self, workflow: Workflow): """ Check for any unset polygonmask processes; start masking mode if found Parameters ---------- workflow: Workflow Returns ------- bool True if unset polygonmask process is found """ pluginmaskclass = pluginmanager.getPluginByName('Polygon Mask', 'ProcessingPlugin') for process in workflow.processes: if isinstance(process, pluginmaskclass.plugin_object): if process.polygon.value is None: self.startPolygonMasking(process) return True return False def startPolygonMasking(self, process): self.setEnabledOuterWidgets(False) # Start drawing mode viewer = self.masktabview.currentWidget() # type: SAXSViewerPlugin viewer.imageItem.setDrawKernel(kernel=np.array([[0]]), mask=None, center=(0, 0), mode='add') viewer.imageItem.drawMode = self.drawEvent viewer.maskROI.clearPoints() # Setup other signals process.parameter.child('Finish Mask').sigActivated.connect(partial(self.finishMask, process)) process.parameter.child('Clear Selection').sigActivated.connect(self.clearMask) def setEnabledOuterWidgets(self, enabled): # Disable other widgets mainwindow = self.masktabview.window() for dockwidget in mainwindow.findChildren(QDockWidget): dockwidget.setEnabled(enabled) mainwindow.rightwidget.setEnabled(True) self.maskeditor.workflowview.setEnabled(enabled) self.masktabview.tabBar().setEnabled(enabled) mainwindow.menuBar().setEnabled(enabled) mainwindow.pluginmodewidget.setEnabled(enabled) def clearMask(self): viewer = self.masktabview.currentWidget() # type: SAXSViewerPlugin viewer.maskROI.clearPoints() def finishMask(self, process, sender): viewer = self.masktabview.currentWidget() # type: SAXSViewerPlugin process.polygon.value = np.array([list(handle['pos']) for handle in viewer.maskROI.handles]) self.setEnabledOuterWidgets(True) # End drawing mode viewer.imageItem.drawKernel = None viewer.maskROI.clearPoints() process.parameter.clearChildren() # Redo workflow with polygon self.doMaskingWorkflow(process._workflow) def drawEvent(self, kernel, imgdata, mask, ss, ts, event): viewer = self.masktabview.currentWidget() # type: SAXSViewerPlugin viewer.maskROI.addFreeHandle(viewer.view.vb.mapSceneToView(event.scenePos())) if len(viewer.maskROI.handles) > 1: viewer.maskROI.addSegment(viewer.maskROI.handles[-2]['item'], viewer.maskROI.handles[-1]['item'])
def __init__(self): # Late imports required due to plugin system from xicam.SAXS.calibration import CalibrationPanel from xicam.SAXS.widgets.SAXSViewerPlugin import SAXSCalibrationViewer, SAXSMaskingViewer, SAXSReductionViewer from xicam.SAXS.widgets.SAXSToolbar import SAXSToolbarRaw, SAXSToolbarMask, SAXSToolbarReduce from xicam.SAXS.widgets.XPCSToolbar import XPCSToolBar self.derivedDataModel = DerivedDataModel() self.catalogModel = QStandardItemModel() # Data model self.catalogModel = QStandardItemModel() self.selectionmodel = QItemSelectionModel(self.catalogModel) # Initialize workflows self.maskingworkflow = MaskingWorkflow() self.simulateworkflow = SimulateWorkflow() self.displayworkflow = DisplayWorkflow() self.reduceworkflow = ReduceWorkflow() self.roiworkflow = ROIWorkflow() # Grab the calibration plugin self.calibrationsettings = pluginmanager.get_plugin_by_name('xicam.SAXS.calibration', 'SettingsPlugin') # Setup TabViews # FIXME -- rework how fields propagate to displays (i.e. each image has its own detector, switching # between tabs updates the detector combobbox correctly) field = "fccd_image" self.calibrationtabview = TabView(self.catalogModel, widgetcls=SAXSCalibrationViewer, stream='primary', field=field, selectionmodel=self.selectionmodel, bindings=[(self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.masktabview = TabView(self.catalogModel, widgetcls=SAXSMaskingViewer, selectionmodel=self.selectionmodel, stream='primary', field=field, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.reducetabview = TabView(self.catalogModel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, stream='primary', field=field, bindings=[('sigTimeChangeFinished', self.indexChanged), (self.calibrationsettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) self.comparemultiview = QLabel("COMING SOON!") # SAXSMultiViewerPlugin(self.catalogModel, self.selectionmodel) # Setup correlation views self.correlationView = TabView(self.catalogModel, widgetcls=SAXSReductionViewer, selectionmodel=self.selectionmodel, stream='primary', field=field) self.twoTimeProcessor = TwoTimeParameterTree(processor=self.processTwoTime) self.twoTimeToolBar = XPCSToolBar(headermodel=self.catalogModel, selectionmodel=self.selectionmodel, view=self.correlationView.currentWidget, workflow=self.roiworkflow, index=0) self.oneTimeProcessor = OneTimeParameterTree(processor=self.processOneTime) self.oneTimeToolBar = XPCSToolBar(view=self.correlationView.currentWidget, workflow=self.roiworkflow, index=0) # Setup toolbars self.rawtoolbar = SAXSToolbarRaw(self.catalogModel, self.selectionmodel) self.masktoolbar = SAXSToolbarMask(self.catalogModel, self.selectionmodel) self.reducetoolbar = SAXSToolbarReduce(self.catalogModel, self.selectionmodel, view=self.reducetabview.currentWidget, workflow=self.reduceworkflow) self.reducetabview.kwargs['toolbar'] = self.reducetoolbar self.reducetoolbar.sigDeviceChanged.connect(self.deviceChanged) # Setup calibration widgets self.calibrationsettings.setModels(self.catalogModel, self.calibrationtabview.selectionmodel) self.calibrationpanel = CalibrationPanel(self.catalogModel, self.calibrationtabview.selectionmodel) self.calibrationpanel.sigDoCalibrateWorkflow.connect(self.doCalibrateWorkflow) self.calibrationsettings.sigGeometryChanged.connect(self.doSimulateWorkflow) # Setup masking widgets self.maskeditor = WorkflowEditor(self.maskingworkflow) self.maskeditor.sigWorkflowChanged.connect(self.doMaskingWorkflow) # Setup reduction widgets self.displayeditor = WorkflowEditor(self.displayworkflow) self.reduceeditor = WorkflowEditor(self.reduceworkflow) self.reduceplot = DerivedDataWidget(self.derivedDataModel) self.reducetoolbar.sigDoWorkflow.connect(self.doReduceWorkflow) self.reduceeditor.sigWorkflowChanged.connect(self.doReduceWorkflow) self.displayeditor.sigWorkflowChanged.connect(self.doDisplayWorkflow) self.reducetabview.currentChanged.connect(self.catalogChanged) # Setup correlation widgets self.correlationResults = DerivedDataWidget(self.derivedDataModel) self.stages = { 'Calibrate': GUILayout(self.calibrationtabview, right=self.calibrationsettings.widget, rightbottom=self.calibrationpanel, top=self.rawtoolbar), 'Mask': GUILayout(self.masktabview, right=self.maskeditor, top=self.masktoolbar), 'Reduce': GUILayout(self.reducetabview, bottom=self.reduceplot, right=self.reduceeditor, righttop=self.displayeditor, top=self.reducetoolbar), 'Compare': GUILayout(self.comparemultiview, top=self.reducetoolbar, bottom=self.reduceplot, right=self.reduceeditor), 'Correlate': { '2-Time Correlation': GUILayout(self.correlationView, top=self.twoTimeToolBar, rightbottom=self.twoTimeProcessor, bottom=self.correlationResults), '1-Time Correlation': GUILayout(self.correlationView, top=self.oneTimeToolBar, rightbottom=self.oneTimeProcessor, bottom=self.correlationResults) } } super(SAXSPlugin, self).__init__() # Start visualizations self.displayworkflow.visualize(self.reduceplot, imageview=lambda: self.reducetabview.currentWidget(), toolbar=self.reducetoolbar)
def __init__(self): self.catalog = BlueskyInMemoryCatalog() # XPCS data model self.resultsModel = QStandardItemModel() # Input (raw) data model self.headerModel = QStandardItemModel() self.selectionModel = QItemSelectionModel(self.headerModel) # Widgets self.calibrationSettings = pluginmanager.getPluginByName( 'xicam.SAXS.calibration', 'SettingsPlugin').plugin_object # Setup TabViews self.rawTabView = TabView( self.headerModel, widgetcls=XPCSViewerPlugin, selectionmodel=self.selectionModel, bindings=[(self.calibrationSettings.sigGeometryChanged, 'setGeometry')], geometry=self.getAI) # Setup correlation views self.twoTimeView = TwoTimeView() self.twoTimeFileSelection = FileSelectionView(self.headerModel, self.selectionModel) self.twoTimeProcessor = TwoTimeProcessor() self.twoTimeToolBar = QToolBar() self.twoTimeToolBar.addAction(QIcon(static.path('icons/run.png')), 'Process', self.processTwoTime) self.twoTimeToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.oneTimeView = OneTimeView() self.oneTimeFileSelection = FileSelectionView(self.headerModel, self.selectionModel) self.oneTimeProcessor = OneTimeProcessor() self.oneTimeToolBar = QToolBar() self.oneTimeToolBar.addAction(QIcon(static.path('icons/run.png')), 'Process', self.processOneTime) self.oneTimeToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # self.placeholder = QLabel('correlation parameters') self.stages = { 'Raw': GUILayout(self.rawTabView, right=self.calibrationSettings.widget), '2-Time Correlation': GUILayout( self.twoTimeView, top=self.twoTimeToolBar, right=self.twoTimeFileSelection, rightbottom=self.twoTimeProcessor, ), # bottom=self.placeholder), '1-Time Correlation': GUILayout( self.oneTimeView, top=self.oneTimeToolBar, right=self.oneTimeFileSelection, rightbottom=self.oneTimeProcessor, ) # bottom=self.placeholder) } # TODO -- improve result caching self._results = [] super(XPCS, self).__init__()