コード例 #1
0
ファイル: mainwindow.py プロジェクト: ihumphrey/Xi-cam
    def _build_nodes(self):
        self._nodes = []
        for plugin in pluginmanager.get_plugins_of_type(
                "GUIPlugin") + pluginmanager.get_plugins_of_type("EZPlugin"):

            node = Node(plugin, plugin.name)

            for name, stage in plugin.stages.items():
                node.children.append(
                    self._build_subnodes(name, stage, parent=node))

            self._nodes.append(node)
コード例 #2
0
    def showMenu(self, pos):
        self.menu = QMenu()
        # Add all resource plugins
        self.actions = {}
        from xicam.plugins import manager as pluginmanager

        for plugin in pluginmanager.get_plugins_of_type("CatalogPlugin") + pluginmanager.get_plugins_of_type(
                "DataResourcePlugin"):
            self.actions[plugin.name] = QAction(plugin.name)
            self.actions[plugin.name].triggered.connect(partial(self._addBrowser, plugin))
            self.menu.addAction(self.actions[plugin.name])

        self.menu.popup(pos)
コード例 #3
0
def detect_mimetypes(filename: str) -> List[str]:
    """
    Take in a filename; return a mimetype string like 'image/tiff'.
    """
    # First rely on custom "sniffers" that can employ file signatures (magic
    # numbers) or any other format-specific tricks to extract a mimetype.
    matched_mimetypes = list()

    with open(filename, "rb") as file:
        # The choice of 64 bytes is arbitrary. We may increase this in the
        # future if we discover reason to. Therefore, sniffers should not
        # assume that they will receive this exact number of bytes.
        first_bytes = file.read(64)

    from xicam.plugins import manager as plugin_manager

    for sniffer in plugin_manager.get_plugins_of_type("sniffers"):
        matched_mimetype = sniffer(filename, first_bytes)
        if matched_mimetype:
            matched_mimetypes.append(matched_mimetype)

    # Guessing the mimetype from the mimemtype db is quick, lets do it always
    matched_mimetype = mimetypes.guess_type(filename)[0]
    if matched_mimetype:
        matched_mimetypes.append(matched_mimetype)

    if not matched_mimetypes:
        raise UnknownFileType(
            f"Could not identify the MIME type of {filename}")

    return matched_mimetypes
コード例 #4
0
    def populateFunctionMenu(self):
        self.functionmenu.clear()
        sortingDict = MenuDict()
        operations = pluginmanager.get_plugins_of_type("OperationPlugin")
        if self.operation_filter is not None:
            operations = filter(self.operation_filter, operations)
        for operation in operations:

            categories = operation.categories
            if not categories:
                categories = [("Uncategorized", )
                              ]  # put found operations into a default category

            for categories_tuple in categories:
                if isinstance(categories_tuple, str):
                    categories_tuple = (categories_tuple, )
                submenu = sortingDict
                categories_list = list(categories_tuple)
                while categories_list:
                    category = categories_list.pop(0)
                    submenu = submenu[category]

                submenu['___'].append(operation)

        self._mkMenu(sortingDict)
コード例 #5
0
    def __init__(self):
        # # Enforce global style within the console
        # with open('xicam/gui/style.stylesheet', 'r') as f:
        #     style = f.read()
        # style = (qdarkstyle.load_stylesheet() + style)

        # Setup the kernel
        self.kernel_manager = QtInProcessKernelManager()
        self.kernel_manager.start_kernel()
        kernel = self.kernel_manager.kernel
        kernel.gui = 'qt'

        # Push Xi-cam variables into the kernel
        kernel.shell.push({
            plugin.name: plugin
            for plugin in pluginmanager.get_plugins_of_type("GUIPlugin") +
            pluginmanager.get_plugins_of_type("EZPlugin")
        })

        # Observe plugin changes
        pluginmanager.attach(self.pluginsChanged)

        # Continue kernel setuppluginmanager.getPluginsOfCategory("GUIPlugin")
        self.kernel_client = self.kernel_manager.client()
        threads.invoke_in_main_thread(self.kernel_client.start_channels)

        # Setup console widget
        def stop():
            self.kernel_client.stop_channels()
            self.kernel_manager.shutdown_kernel()

        control = RichJupyterWidget()
        control.kernel_manager = self.kernel_manager
        threads.invoke_in_main_thread(setattr, control, "kernel_client",
                                      self.kernel_client)
        control.exit_requested.connect(stop)
        # control.style_sheet = style
        control.syntax_style = u'monokai'
        control.set_default_style(colors='Linux')

        # Setup layout
        self.stages = {'Terminal': GUILayout(control)}

        # Save for later
        self.kernel = kernel

        super(IPythonPlugin, self).__init__()
コード例 #6
0
ファイル: sasmodelfit.py プロジェクト: tangkong/Xi-cam.SAXS
 def __init__(self):
     super(AstropyQSpectraFit, self).__init__()
     self.model.limits = {
         plugin.name: plugin
         for plugin in pluginmanager.get_plugins_of_type(
             'Fittable1DModelPlugin')
     }
     self.model.value = list(self.model.limits.values())[0]
コード例 #7
0
    def __init__(self):
        super(DeviceDialog, 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())
        self.namedynamically = True

        # Setup fields
        self.name = QLineEdit()
        self.devicestring = QLineEdit()
        self.controller = QComboBox()
        self.deviceclass = QComboBox()
        for name in self.deviceclasses:
            self.deviceclass.addItem(name)

        # TODO: add controller plugin
        # Temporary hard coded values
        for plugin in pluginmanager.get_plugins_of_type('ControllerPlugin'):
            self.controller.addItem(plugin.name())

        # Setup dialog buttons
        self.addButton = QPushButton("&Add")
        self.connectButton = QPushButton("Test 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.buttonboxWidget = QDialogButtonBox()
        self.buttonboxWidget.addButton(self.addButton,
                                       QDialogButtonBox.AcceptRole)
        self.buttonboxWidget.addButton(self.connectButton,
                                       QDialogButtonBox.AcceptRole)
        self.buttonboxWidget.addButton(self.cancelButton,
                                       QDialogButtonBox.RejectRole)

        # Wireup signals
        self.devicestring.textChanged.connect(self.fillName)
        self.name.textChanged.connect(self.stopDynamicName)

        # Compose main layout
        mainLayout = QFormLayout()
        mainLayout.addRow('Device Name', self.name)
        mainLayout.addRow('Device PV', self.devicestring)
        mainLayout.addRow('Controller Type', self.controller)
        mainLayout.addRow('Device Class', self.deviceclass)
        mainLayout.addRow(self.buttonboxWidget)

        self.setLayout(mainLayout)
        self.setWindowTitle("Add Device...")

        # Set modality
        self.setModal(True)
コード例 #8
0
 def createIcons(self):
     self.contentsModel.clear()
     for plugin in pluginmanager.get_plugins_of_type("SettingsPlugin"):
         item = QStandardItem(plugin.icon, plugin.name())
         item.widget = plugin.widget
         item.setTextAlignment(Qt.AlignHCenter)
         item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
         item.setSizeHint(QSize(136, 80))
         self.contentsModel.appendRow(item)
コード例 #9
0
def applicable_ingestors(filename, mimetype):
    """
    Take in a filename and its mimetype; return a list of compatible ingestors.
    """
    # Find ingestor(s) for this mimetype.
    ingestors = []

    from xicam.plugins import manager as plugin_manager

    for ingestor in plugin_manager.get_plugins_of_type("ingestors"):
        if ingestor._name == mimetype:
            ingestors.append(ingestor)

    return ingestors
コード例 #10
0
 def populateFunctionMenu(self):
     self.functionmenu.clear()
     sortingDict = {}
     for plugin in pluginmanager.get_plugins_of_type("OperationPlugin"):
         typeOfOperationPlugin = plugin.getCategory()
         if not typeOfOperationPlugin in sortingDict.keys():
             sortingDict[typeOfOperationPlugin] = []
         sortingDict[typeOfOperationPlugin].append(plugin)
     for key in sortingDict.keys():
         self.functionmenu.addSeparator()
         self.functionmenu.addAction(key)
         self.functionmenu.addSeparator()
         for plugin in sortingDict[key]:
             self.functionmenu.addAction(
                 plugin.name,
                 partial(self.addOperation, plugin, autoconnectall=True))
コード例 #11
0
ファイル: astropyfit.py プロジェクト: ihumphrey/Xi-cam.SAXS
 def as_parameter(self):
     return [{
         "name":
         "Model",
         "type":
         "list",
         "limits":
         self.limits.get(
             'model', {
                 plugin.name: plugin
                 for plugin in pluginmanager.get_plugins_of_type(
                     'Fittable1DModelPlugin')
             })
     }, {
         "name": "Model Parameters",
         "type": "group"
     }]
コード例 #12
0
 def populateFunctionMenu(self):
     self.functionmenu.clear()
     sortingDict = {}
     for plugin in pluginmanager.get_plugins_of_type("OperationPlugin"):
         typeOfOperationPlugin = plugin.categories
         # TODO : should OperationPlugin be responsible for initializing categories
         # to some placeholder value (instead of [])?
         if typeOfOperationPlugin == []:
             typeOfOperationPlugin = "uncategorized"  # put found operations into a default category
         if not typeOfOperationPlugin in sortingDict.keys():
             sortingDict[typeOfOperationPlugin] = []
         sortingDict[typeOfOperationPlugin].append(plugin)
     for key in sortingDict.keys():
         self.functionmenu.addSeparator()
         self.functionmenu.addAction(key)
         self.functionmenu.addSeparator()
         for plugin in sortingDict[key]:
             self.functionmenu.addAction(
                 plugin.name,
                 partial(self.addOperation, plugin, autoconnectall=True))
コード例 #13
0
    def restore(self):
        for plugin in pluginmanager.get_plugins_of_type("SettingsPlugin"):
            plugin.restore()

        self.apply()
コード例 #14
0
 def pluginsChanged(self):
     self.kernel.shell.push({
         plugin.name: plugin
         for plugin in pluginmanager.get_plugins_of_type("GUIPlugin") +
         pluginmanager.get_plugins_of_type("EZPlugin")
     })
コード例 #15
0
 def apply(self):
     for plugin in pluginmanager.get_plugins_of_type("SettingsPlugin"):
         plugin.save()
コード例 #16
0
 def request_reload():
     for plugin in pluginmanager.get_plugins_of_type("SettingsPlugin"):
         plugin.restore()
         plugin.save()
コード例 #17
0
def load_header(uris: List[Union[str, Path]] = None, uuid: str = None):
    """
    Load a document object, either from a file source or a databroker source, by uuid. If loading from a filename, the
    file will be registered in databroker.

    Parameters
    ----------
    uris
    uuid

    Returns
    -------
    NonDBHeader

    """
    from xicam.plugins import manager as pluginmanager  # must be a late import

    # ext = Path(filename).suffix[1:]
    # for cls, extensions in extension_map.items():
    #     if ext in extensions:

    # First try to see if we have a databroker ingestor, then fall-back to Xi-cam DataHandlers
    ingestor = None
    filename = str(Path(uris[0]))

    # Sanity checks
    if Path(filename).is_dir():
        msg.logMessage("Opening dir; nothing to load.")
        return

    if not Path(filename).exists():
        raise FileExistsError(
            f"Attempted to load non-existent file: {filename}")

    try:
        mimetypes = detect_mimetypes(filename)
    except UnknownFileType as ex:
        msg.logError(ex)
        mimetypes = []
    else:
        msg.logMessage(f"Mimetypes detected: {mimetypes}")

        # TODO: here, we try each valid mimetype; some GUI for selection will be needed

        for mimetype in mimetypes:
            try:
                ingestor = choose_ingestor(filename, mimetype)
            except NoIngestor as e:
                pass
            else:
                msg.logMessage(f"Ingestor selected: {ingestor}")
                break

    if ingestor:
        document = list(ingestor(uris))
        uid = document[0][1]["uid"]
        catalog = BlueskyInMemoryCatalog()
        # TODO -- change upsert signature to put start and stop as kwargs
        # TODO -- ask about more convenient way to get a BlueskyRun from a document generator
        catalog.upsert(document[0][1], document[-1][1], ingestor, [uris], {})
        return catalog[uid]
    else:
        warn(f"No applicable ingestor found. Falling-back to DataHandlers")

    handlercandidates = []
    ext = Path(uris[0]).suffix
    for plugin in pluginmanager.get_plugins_of_type("DataHandlerPlugin"):
        if ext in plugin.DEFAULT_EXTENTIONS:
            handlercandidates.append(plugin)
    if not handlercandidates:
        return NonDBHeader({}, [], [], {})
    # try:
    msg.logMessage(f"Handler selected: {handlercandidates[0]}")
    return NonDBHeader(**handlercandidates[0].ingest(uris))