def __init__(self, addmode=True): super(CredentialDialog, self).__init__() # Set size and position # self.setGeometry(0, 0, 800, 500) frameGm = self.frameGeometry() screen = QApplication.desktop().screenNumber(QApplication.desktop().cursor().pos()) centerPoint = QApplication.desktop().screenGeometry(screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) # Setup fields self.host = QLineEdit() self.profiles = QComboBox() self.profiles.addItem("New...") self.profilename = QLineEdit() self.username = QLineEdit() self.password = QLineEdit() self.password.setEchoMode(QLineEdit.Password) self.savepassword = QCheckBox("Save Password") self.rememberprofile = QCheckBox("Remember Profile") # Setup dialog buttons self.addButton = QPushButton("&Add") self.connectButton = QPushButton("C&onnect") self.cancelButton = QPushButton("&Cancel") self.addButton.clicked.connect(self.add) self.connectButton.clicked.connect(self.connect) self.cancelButton.clicked.connect(self.close) self.profiles.currentTextChanged.connect(self.loadProfile) self.buttonboxWidget = QDialogButtonBox() if addmode: self.buttonboxWidget.addButton(self.addButton, QDialogButtonBox.AcceptRole) else: self.buttonboxWidget.addButton(self.connectButton, QDialogButtonBox.AcceptRole) self.buttonboxWidget.addButton(self.cancelButton, QDialogButtonBox.RejectRole) # Compose main layout mainLayout = QFormLayout() if not addmode: mainLayout.addRow("Profile", self.profiles) mainLayout.addRow("Profile", self.profilename) mainLayout.addRow("Host", self.host) mainLayout.addRow("Username", self.username) mainLayout.addRow("Password", self.password) mainLayout.addRow(self.savepassword) if not addmode: mainLayout.addRow(self.rememberprofile) mainLayout.addRow(self.buttonboxWidget) # Populate profiles for name, credential in manager.get_plugin_by_name("Connections", "SettingsPlugin").credentials.items(): self.profiles.addItem(name) self.setLayout(mainLayout) self.setWindowTitle("Add Connection...") # Set modality self.setModal(True)
def __init__(self): super(DeviceView, self).__init__() happi_settings_plugin = pluginmanager.get_plugin_by_name('happi_devices', 'SettingsPlugin') self.view = happi_settings_plugin.devices_view self.model = happi_settings_plugin.devices_model
def fieldChanged(self, field): self.setCatalog(self.catalog, self.stream, field) # TODO -- figure out where to put the geometry update if QSpace in inspect.getmro(type(self)): self.setGeometry( pluginmanager.get_plugin_by_name('xicam.SAXS.calibration', 'SettingsPlugin').AI(field))
def setField(self, field): self.clear() self.field = field self._updateCatalog() # TODO -- figure out where to put the geometry update if QSpace in inspect.getmro(type(self)): self.setGeometry(pluginmanager.get_plugin_by_name("xicam.SAXS.calibration", "SettingsPlugin").AI(field)) self.sigFieldChanged.emit(field)
def __init__(self): super(ipythonconsole, self).__init__() plugin = pluginmanager.get_plugin_by_name('IPython', 'GUIPlugin') self.kernel_manager = plugin.kernel_manager self.kernel_client = plugin.kernel_client # self.style_sheet = (qdarkstyle.load_stylesheet()) self.syntax_style = u'monokai' self.set_default_style(colors='Linux')
def widget(self): if not self._widget: controllername = self.device.controller controllerclass = pluginmanager.get_plugin_by_name( controllername, 'ControllerPlugin') if not controllerclass: raise ImportError( f"The '{controllername}' controller could not be loaded.") self._widget = controllerclass(self.device) return self._widget
def is_matching_canvas_type(self, index: QModelIndex, match_index: QModelIndex): match_intent = match_index.data(EnsembleModel.object_role) intent = index.data(EnsembleModel.object_role) if not isinstance(intent, Intent): print( f"WARNING: during matching, index {index.data} is not an Intent" ) return False if not isinstance(match_intent, Intent): print( f"WARNING: during matching, match_index {index.data} is not an Intent" ) return False # assert isinstance(intent, Intent) # assert isinstance(match_intent, Intent) # Ignore self matching if intent is match_intent: return False match_canvas_type_string = match_intent.canvas intent_canvas_type_string = intent.canvas match_intent_canvas_type = pluginmanager.get_plugin_by_name( match_canvas_type_string, "IntentCanvasPlugin") intent_canvas_type = pluginmanager.get_plugin_by_name( intent_canvas_type_string, "IntentCanvasPlugin") if not issubclass(intent_canvas_type, match_intent_canvas_type) \ and not issubclass(match_intent_canvas_type, intent_canvas_type): return False # By definition, if a match_key is not provided, the intent is un-matchable if intent.match_key is None or match_intent.match_key is None: return False if intent.match_key != match_intent.match_key: return False return True
def project_intents(run_catalog): intents = [] for projection in run_catalog.metadata['start'].get('projections', []): if projection['name'] == 'intent': intent_class_name = projection['projection']['intent_type']['value'] args = projection['projection']['args']['value'] kwargs = projection['projection']['kwargs']['value'] output_map = projection['projection']['output_map']['value'] name = projection['projection']['name']['value'] operation_id = projection['projection']['operation_id']['value'] intent_class = plugin_manager.get_plugin_by_name(intent_class_name, 'intents') for intent_kwarg_name, output_name in output_map.items(): kwargs[intent_kwarg_name] = getattr(run_catalog, operation_id).to_dask()[output_name] intent = intent_class(name=name, *args, **kwargs) intents.append(intent) return intents
def loadProfile(self): profilename = self.profiles.currentText() if profilename == "New...": self.username.setEnabled(True) self.password.setEnabled(True) self.host.setEnabled(True) self.savepassword.setEnabled(True) self.rememberprofile.setVisible(True) else: credential = manager.get_plugin_by_name("Connections", "SettingsPlugin").credentials[profilename] self.username.setText(credential["username"]) self.host.setText(credential["host"]) self.password.setText(credential["password"]) self.savepassword.setChecked(credential["savepassword"]) self.profilename.setText(profilename) self.username.setEnabled(False) self.password.setEnabled(False) self.host.setEnabled(False) self.savepassword.setEnabled(False) self.rememberprofile.setVisible(False)
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 _activate(self, index: QModelIndex): display = index.data( HappiClientModel.displayRole) # try to get display from model if not display: happi_item = index.data(HappiClientModel.happiItemRole) device = from_container(happi_item) try: device.wait_for_connection() except TimeoutError as ex: msg.logError(ex) controller_name = happi_item.extraneous.get( "controller_class", "typhos") controller = pluginmanager.get_plugin_by_name( controller_name, 'ControllerPlugin') display = controller(device) # Stash display back on the model self.model().setData(index, display, HappiClientModel.displayRole) self.sigShowControl.emit(display)
def __new__(cls, datasource): model = pluginmanager.get_plugin_by_name('plans', "SettingsPlugin").plansmodel model.dataresource = datasource return model
def SavePlan(self): pluginmanager.get_plugin_by_name('plans', 'SettingsPlugin').add_plan( self.editor.toPlainText())
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, device: Device): super(DiodeController, self).__init__(device) self.RE = get_run_engine() full_layout = QVBoxLayout() self.setLayout(full_layout) # create upper layout/widget top_layout = QHBoxLayout() top_widget = QWidget() top_widget.setLayout(top_layout) # add actual widgets to the top part typhos_panel = TyphosCompositeSignalPanel.from_device(device) typhos_panel.setMaximumHeight(50) time_plot = PyDMTimePlot() time_plot.setTimeSpan(120) time_plot.addYChannel(y_channel=f'ca://{device.prefix}', name="Diode", color="red", lineWidth=3) top_layout.addWidget(time_plot) top_layout.addWidget(typhos_panel) # create lower layout/widget bottom_layout = QHBoxLayout() bottom_widget = QWidget() bottom_widget.setLayout(bottom_layout) bottom_widget.setMinimumHeight(350) # add actual widgets to the bottom part self.plot_panel = CatalogImagePlotView(field_filter=None) config_layout = QVBoxLayout() scan_panel = QGroupBox('Diode Scan') scan_panel.setMaximumSize(200, 250) scan_panel.setLayout(config_layout) bottom_layout.addWidget(self.plot_panel) bottom_layout.addWidget(scan_panel) # add a splitter splitter = QSplitter(Qt.Vertical) splitter.addWidget(top_widget) splitter.addWidget(bottom_widget) full_layout.addWidget(splitter) # get devices from happi database happi_settings = plugin_manager.get_plugin_by_name( "happi_devices", "SettingsPlugin") def from_device_container(container) -> Device: try: return from_container(container.device) except Exception as e: logError(e) return None self.async_poll_devices = list( map( from_device_container, happi_settings.search(source='labview', device_class='ophyd.EpicsMotor'))) self.async_poll_devices += map( from_device_container, happi_settings.search(prefix=device.prefix)) # Remove errored from_container devices (Nones) self.async_poll_devices = list( filter(lambda device: device, self.async_poll_devices)) self.async_poll_devices.remove(device) self.device_dict = { device.name: device for device in self.async_poll_devices } # get the diode as detector diode = device.diode self.device_selector = QComboBox() self.device_selector.addItems(list(self.device_dict.keys())) input_layout = QFormLayout() self.start_range = QLineEdit() self.stop_range = QLineEdit() self.n_steps = QLineEdit() self.step_size = QLineEdit() input_layout.addRow('Start Range', self.start_range) input_layout.addRow('Stop Range', self.stop_range) input_layout.addRow('N Steps', self.n_steps) input_layout.addRow('Step Size', self.step_size) config_layout.addWidget(self.device_selector) config_layout.addLayout(input_layout) button_layout = QHBoxLayout() start_button = QPushButton("Start") button_layout.addWidget(start_button) start_button.clicked.connect(self.push_start) config_layout.addLayout(button_layout) # TODO get data from bluesky run in callback # runs = [] # self.RE.subscribe(stream_documents_into_runs(self.plot_panel.setCatalog)) # self.plot_panel.setData(runs) # Wireup display to receive completed runs self.run_dispatcher = RunDispatcher(self.plot_panel.setCatalog)
def __init__(self, device: Device): super(FastCCDController, self).__init__(device) camera_layout = QVBoxLayout() camera_panel = QGroupBox('Camera State') camera_panel.setLayout(camera_layout) camera_layout.addWidget( PyDMLabel(init_channel=f'ca://{device.cam.state.pvname}')) camera_layout.addWidget( PyDMPushButton( pressValue=1, init_channel=f'ca://{device.cam.initialize.setpoint_pvname}', label='Initialize')) camera_layout.addWidget( PyDMPushButton( pressValue=1, init_channel=f'ca://{device.cam.shutdown.setpoint_pvname}', label='Shutdown')) dg_layout = QHBoxLayout() dg_panel = QGroupBox('Delay Gen State') dg_panel.setLayout(dg_layout) dg_state_layout = QVBoxLayout() dg_layout.addLayout(dg_state_layout) dg_state_layout.addWidget( PyDMLabel(init_channel=f'ca://{device.dg1.state.pvname}')) dg_state_layout.addWidget( PyDMPushButton( pressValue=1, init_channel=f'ca://{device.dg1.initialize.setpoint_pvname}', label='Initialize')) dg_state_layout.addWidget( PyDMPushButton( pressValue=1, init_channel=f'ca://{device.dg1.reset.setpoint_pvname}', label='Reset')) dg_shutter_layout = QVBoxLayout() dg_layout.addLayout(dg_shutter_layout) dg_shutter_layout.addWidget( PyDMLabel( init_channel=f'ca://{device.dg1.shutter_enabled.pvname}')) dg_shutter_layout.addWidget( PyDMPushButton( pressValue=0, init_channel= f'ca://{device.dg1.shutter_enabled.setpoint_pvname}', label='Enable Trigger')) dg_shutter_layout.addWidget( PyDMPushButton( pressValue=2, init_channel= f'ca://{device.dg1.shutter_enabled.setpoint_pvname}', label='Keep Closed')) dg_shutter_layout.addWidget( PyDMPushButton( pressValue=1, init_channel= f'ca://{device.dg1.shutter_enabled.setpoint_pvname}', label='Keep Open')) self.hlayout.addWidget(camera_panel) self.hlayout.addWidget(dg_panel) self.passive.setVisible( False) # active mode is useless for fastccd at COSMIC-Scattering # Subscribe to the error status PV so we can create notifications # (only relevant for cam init errors for now) self.device.cam.error_status.subscribe(self.report_error, 'value') # TODO: pull from settingsplugin self.db = Broker.named('local').v2 happi_settings = plugin_manager.get_plugin_by_name( "happi_devices", "SettingsPlugin") # Find coupled devices and add them so they'll be used with RE def from_device_container(container) -> Device: try: return from_container(container.device) except Exception as e: logError(e) return None self.async_poll_devices = list( map(from_device_container, happi_settings.search(source='labview'))) self.async_poll_devices += map( from_device_container, happi_settings.search(prefix=device.prefix)) # Remove errored from_container devices (Nones) self.async_poll_devices = list( filter(lambda device: device, self.async_poll_devices)) self.async_poll_devices.remove(device) self.metadata["projections"] = [{ 'name': 'NXsas', 'version': '0.1.0', 'projection': { NXsas.DATA_PROJECTION_KEY: { 'type': 'linked', 'stream': 'primary', 'location': 'event', 'field': f"{device.name}_image" }, NXsas.AZIMUTHAL_ANGLE_PROJECTION_KEY: { 'type': 'linked', 'stream': 'labview', 'location': 'event', 'field': 'detector_rotate' }, # TODO: source this from somewhere NXsas.ENERGY_PROJECTION_KEY: { 'type': 'linked', 'stream': 'labview', 'location': 'event', 'field': 'mono_energy' }, NXsas.INCIDENCE_ANGLE_PROJECTION_KEY: { 'type': 'linked', 'stream': 'labview', 'location': 'event', 'field': 'sample_rotate_steppertheta' }, # TODO: CHECK IF THIS EXISTS # FIXME: Is this the right motor??? NXsas.DETECTOR_TRANSLATION_X_PROJECTION_KEY: { 'type': 'linked', 'stream': 'labview', 'location': 'event', 'field': 'det_translate' }, }, 'configuration': { 'detector_name': 'fastccd', 'sdd': 0.5, 'geometry_mode': 'transmission', 'poni1': 480, 'poni2': 1025 } }]
def __new__(cls, datasource): model = pluginmanager.get_plugin_by_name('xicam.Acquire.devices', "SettingsPlugin").devicesmodel model.dataresource = datasource return model
def __init__(self, *args, **kwargs): super(RunEngineWidget, self).__init__(*args, **kwargs) self.planview = QListView() self.plansmodel = pluginmanager.get_plugin_by_name('plans', 'SettingsPlugin').plansmodel # type: QStandardItemModel self.planview.setModel(self.plansmodel) self.selectionmodel = QItemSelectionModel(self.plansmodel) self.planview.setSelectionModel(self.selectionmodel) self.parameterview = ParameterTree() self.metadata = MetadataWidget() self.runbutton = QPushButton('Run') self.pausebutton = QPushButton('Pause') self.resumebutton = QPushButton('Resume') self.abortbutton = QPushButton('Abort') self.abortbutton.setStyleSheet('background-color:red;color:white;font-weight:bold;') # Layout self.layout = QVBoxLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout) self.splitter = QSplitter() self.layout.addWidget(self.splitter) self.splitter.addWidget(self.planview) self.runwidget = QWidget() self.runlayout = QVBoxLayout() self.runlayout.setContentsMargins(0, 0, 0, 0) self.runlayout.addWidget(self.parameterview) self.runlayout.addWidget(self.runbutton) self.runlayout.addWidget(self.pausebutton) self.runlayout.addWidget(self.resumebutton) self.runlayout.addWidget(self.abortbutton) self.runwidget.setLayout(self.runlayout) self.splitter.addWidget(self.runwidget) self.splitter.addWidget(self.metadata) # Set initial states self._resumed() self._finished() # Wireup signals self.selectionmodel.currentChanged.connect(self.showPlan) self.runbutton.clicked.connect(self.run) self.abortbutton.clicked.connect(self.abort) self.pausebutton.clicked.connect(self.pause) self.resumebutton.clicked.connect(self.resume) self.RE = get_run_engine() self.RE.sigPause.connect(self._paused) self.RE.sigResume.connect(self._resumed) self.RE.sigFinish.connect(self._finished) self.RE.sigStart.connect(self._started) self.RE.sigAbort.connect(self._aborted) # Run model self.runmodel = QStandardItemModel() self.runselectionmodel = QItemSelectionModel(self.runmodel) self._current_planitem = None