示例#1
0
    def __init__(self, view):
        QtGui.QMenu.__init__(self)
        
        self.view = view
        self.valid = False  ## tells us whether the ui needs to be updated

        self.setTitle("ViewBox options")
        self.viewAll = QtGui.QAction("View All", self)
        self.viewAll.triggered.connect(self.autoRange)
        self.addAction(self.viewAll)
        
        self.axes = []
        self.ctrl = []
        self.widgetGroups = []
        self.dv = QtGui.QDoubleValidator(self)
        for axis in 'XY':
            m = QtGui.QMenu()
            m.setTitle("%s Axis" % axis)
            w = QtGui.QWidget()
            ui = AxisCtrlTemplate()
            ui.setupUi(w)
            a = QtGui.QWidgetAction(self)
            a.setDefaultWidget(w)
            m.addAction(a)
            self.addMenu(m)
            self.axes.append(m)
            self.ctrl.append(ui)
            wg = WidgetGroup(w)
            self.widgetGroups.append(w)
            
            connects = [
                (ui.mouseCheck.toggled, 'MouseToggled'),
                (ui.manualRadio.clicked, 'ManualClicked'),
                (ui.minText.editingFinished, 'MinTextChanged'),
                (ui.maxText.editingFinished, 'MaxTextChanged'),
                (ui.autoRadio.clicked, 'AutoClicked'),
                (ui.autoPercentSpin.valueChanged, 'AutoSpinChanged'),
                (ui.linkCombo.currentIndexChanged, 'LinkComboChanged'),
            ]
            
            for sig, fn in connects:
                sig.connect(getattr(self, axis.lower()+fn))
            
        ## exporting is handled by GraphicsScene now
        #self.export = QtGui.QMenu("Export")
        #self.setExportMethods(view.exportMethods)
        #self.addMenu(self.export)
        
        self.leftMenu = QtGui.QMenu("Mouse Mode")
        group = QtGui.QActionGroup(self)
        pan = self.leftMenu.addAction("3 button", self.set3ButtonMode)
        zoom = self.leftMenu.addAction("1 button", self.set1ButtonMode)
        pan.setCheckable(True)
        zoom.setCheckable(True)
        pan.setActionGroup(group)
        zoom.setActionGroup(group)
        self.mouseModes = [pan, zoom]
        self.addMenu(self.leftMenu)
        
        self.view.sigStateChanged.connect(self.viewStateChanged)
        
        self.updateState()
示例#2
0
    def __init__(self, view):
        QtGui.QMenu.__init__(self)

        self.view = weakref.ref(
            view
        )  ## keep weakref to view to avoid circular reference (don't know why, but this prevents the ViewBox from being collected)
        self.valid = False  ## tells us whether the ui needs to be updated
        self.viewMap = weakref.WeakValueDictionary(
        )  ## weakrefs to all views listed in the link combos

        self.setTitle("ViewBox options")
        self.viewAll = QtGui.QAction("View All", self)
        self.viewAll.triggered.connect(self.autoRange)
        self.addAction(self.viewAll)

        self.axes = []
        self.ctrl = []
        self.widgetGroups = []
        self.dv = QtGui.QDoubleValidator(self)
        for axis in 'XY':
            m = QtGui.QMenu()
            m.setTitle("%s Axis" % axis)
            w = QtGui.QWidget()
            ui = AxisCtrlTemplate()
            ui.setupUi(w)
            a = QtGui.QWidgetAction(self)
            a.setDefaultWidget(w)
            m.addAction(a)
            self.addMenu(m)
            self.axes.append(m)
            self.ctrl.append(ui)
            wg = WidgetGroup(w)
            self.widgetGroups.append(w)

            connects = [(ui.mouseCheck.toggled, 'MouseToggled'),
                        (ui.manualRadio.clicked, 'ManualClicked'),
                        (ui.minText.editingFinished, 'MinTextChanged'),
                        (ui.maxText.editingFinished, 'MaxTextChanged'),
                        (ui.autoRadio.clicked, 'AutoClicked'),
                        (ui.autoPercentSpin.valueChanged, 'AutoSpinChanged'),
                        (ui.linkCombo.currentIndexChanged, 'LinkComboChanged'),
                        (ui.autoPanCheck.toggled, 'AutoPanToggled'),
                        (ui.visibleOnlyCheck.toggled, 'VisibleOnlyToggled')]

            for sig, fn in connects:
                sig.connect(getattr(self, axis.lower() + fn))

        self.ctrl[0].invertCheck.hide()  ## no invert for x-axis
        self.ctrl[1].invertCheck.toggled.connect(self.yInvertToggled)
        ## exporting is handled by GraphicsScene now
        #self.export = QtGui.QMenu("Export")
        #self.setExportMethods(view.exportMethods)
        #self.addMenu(self.export)

        self.leftMenu = QtGui.QMenu("Mouse Mode")
        group = QtGui.QActionGroup(self)
        pan = self.leftMenu.addAction("3 button", self.set3ButtonMode)
        zoom = self.leftMenu.addAction("1 button", self.set1ButtonMode)
        pan.setCheckable(True)
        zoom.setCheckable(True)
        pan.setActionGroup(group)
        zoom.setActionGroup(group)
        self.mouseModes = [pan, zoom]
        self.addMenu(self.leftMenu)

        self.view().sigStateChanged.connect(self.viewStateChanged)

        self.updateState()
示例#3
0
def generateUi(opts):
    """Convenience function for generating common UI types"""
    widget = QtGui.QWidget()
    l = QtGui.QFormLayout()
    l.setSpacing(0)
    widget.setLayout(l)
    ctrls = {}
    row = 0
    for opt in opts:
        if len(opt) == 2:
            k, t = opt
            o = {}
        elif len(opt) == 3:
            k, t, o = opt
        else:
            raise Exception("Widget specification must be (name, type) or (name, type, {opts})")
        if t == 'intSpin':
            w = QtGui.QSpinBox()
            if 'max' in o:
                w.setMaximum(o['max'])
            if 'min' in o:
                w.setMinimum(o['min'])
            if 'value' in o:
                w.setValue(o['value'])
        elif t == 'doubleSpin':
            w = QtGui.QDoubleSpinBox()
            if 'max' in o:
                w.setMaximum(o['max'])
            if 'min' in o:
                w.setMinimum(o['min'])                
            if 'value' in o:
                w.setValue(o['value'])
        elif t == 'spin':
            w = SpinBox()
            w.setOpts(**o)
        elif t == 'check':
            w = QtGui.QCheckBox()
            if 'checked' in o:
                w.setChecked(o['checked'])
        elif t == 'combo':
            w = QtGui.QComboBox()
            for i in o['values']:
                w.addItem(i)
        #elif t == 'colormap':
            #w = ColorMapper()
        elif t == 'color':
            w = ColorButton()
        else:
            raise Exception("Unknown widget type '%s'" % str(t))
        if 'tip' in o:
            w.setToolTip(o['tip'])
        w.setObjectName(k)
        l.addRow(k, w)
        if o.get('hidden', False):
            w.hide()
            label = l.labelForField(w)
            label.hide()
            
        ctrls[k] = w
        w.rowNum = row
        row += 1
    group = WidgetGroup(widget)
    return widget, group, ctrls
示例#4
0
    def __init__(self, parent=None, name=None, labels=None, title=None, viewBox=None, axisItems=None, enableMenu=True, **kargs):
        """
        Create a new PlotItem. All arguments are optional.
        Any extra keyword arguments are passed to PlotItem.plot().
        
        ==============  ==========================================================================================
        **Arguments**
        *title*         Title to display at the top of the item. Html is allowed.
        *labels*        A dictionary specifying the axis labels to display::
                   
                            {'left': (args), 'bottom': (args), ...}
                     
                        The name of each axis and the corresponding arguments are passed to 
                        :func:`PlotItem.setLabel() <pyqtgraph.PlotItem.setLabel>`
                        Optionally, PlotItem my also be initialized with the keyword arguments left,
                        right, top, or bottom to achieve the same effect.
        *name*          Registers a name for this view so that others may link to it
        *viewBox*       If specified, the PlotItem will be constructed with this as its ViewBox.
        *axisItems*     Optional dictionary instructing the PlotItem to use pre-constructed items
                        for its axes. The dict keys must be axis names ('left', 'bottom', 'right', 'top')
                        and the values must be instances of AxisItem (or at least compatible with AxisItem).
        ==============  ==========================================================================================
        """
        
        GraphicsWidget.__init__(self, parent)
        
        self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        
        ## Set up control buttons
        path = os.path.dirname(__file__)
        #self.autoImageFile = os.path.join(path, 'auto.png')
        #self.lockImageFile = os.path.join(path, 'lock.png')
        self.autoBtn = ButtonItem(pyqtgraph.pixmaps.getPixmap('auto'), 14, self)
        self.autoBtn.mode = 'auto'
        self.autoBtn.clicked.connect(self.autoBtnClicked)
        #self.autoBtn.hide()
        self.buttonsHidden = False ## whether the user has requested buttons to be hidden
        self.mouseHovering = False
        
        self.layout = QtGui.QGraphicsGridLayout()
        self.layout.setContentsMargins(1,1,1,1)
        self.setLayout(self.layout)
        self.layout.setHorizontalSpacing(0)
        self.layout.setVerticalSpacing(0)
        
        if viewBox is None:
            viewBox = ViewBox()
        self.vb = viewBox
        self.vb.sigStateChanged.connect(self.viewStateChanged)
        self.setMenuEnabled(enableMenu, enableMenu) ## en/disable plotitem and viewbox menus
        
        if name is not None:
            self.vb.register(name)
        self.vb.sigRangeChanged.connect(self.sigRangeChanged)
        self.vb.sigXRangeChanged.connect(self.sigXRangeChanged)
        self.vb.sigYRangeChanged.connect(self.sigYRangeChanged)
        
        self.layout.addItem(self.vb, 2, 1)
        self.alpha = 1.0
        self.autoAlpha = True
        self.spectrumMode = False
        
        self.legend = None
        
        ## Create and place axis items
        if axisItems is None:
            axisItems = {}
        self.axes = {}
        for k, pos in (('top', (1,1)), ('bottom', (3,1)), ('left', (2,0)), ('right', (2,2))):
            axis = axisItems.get(k, AxisItem(orientation=k))
            axis.linkToView(self.vb)
            self.axes[k] = {'item': axis, 'pos': pos}
            self.layout.addItem(axis, *pos)
            axis.setZValue(-1000)
            axis.setFlag(axis.ItemNegativeZStacksBehindParent)
        
        self.titleLabel = LabelItem('', size='11pt')
        self.layout.addItem(self.titleLabel, 0, 1)
        self.setTitle(None)  ## hide
        
        
        for i in range(4):
            self.layout.setRowPreferredHeight(i, 0)
            self.layout.setRowMinimumHeight(i, 0)
            self.layout.setRowSpacing(i, 0)
            self.layout.setRowStretchFactor(i, 1)
            
        for i in range(3):
            self.layout.setColumnPreferredWidth(i, 0)
            self.layout.setColumnMinimumWidth(i, 0)
            self.layout.setColumnSpacing(i, 0)
            self.layout.setColumnStretchFactor(i, 1)
        self.layout.setRowStretchFactor(2, 100)
        self.layout.setColumnStretchFactor(1, 100)
        

        ## Wrap a few methods from viewBox
        for m in [
            'setXRange', 'setYRange', 'setXLink', 'setYLink', 'setAutoPan', 'setAutoVisible',
            'setRange', 'autoRange', 'viewRect', 'viewRange', 'setMouseEnabled',
            'enableAutoRange', 'disableAutoRange', 'setAspectLocked', 'invertY',
            'register', 'unregister']:  ## NOTE: If you update this list, please update the class docstring as well.
            setattr(self, m, getattr(self.vb, m))
            
        self.items = []
        self.curves = []
        self.itemMeta = weakref.WeakKeyDictionary()
        self.dataItems = []
        self.paramList = {}
        self.avgCurves = {}
        
        ### Set up context menu
        
        w = QtGui.QWidget()
        self.ctrl = c = Ui_Form()
        c.setupUi(w)
        dv = QtGui.QDoubleValidator(self)
        
        menuItems = [
            ('Transforms', c.transformGroup),
            ('Downsample', c.decimateGroup),
            ('Average', c.averageGroup),
            ('Alpha', c.alphaGroup),
            ('Grid', c.gridGroup),
            ('Points', c.pointsGroup),
        ]
        
        
        self.ctrlMenu = QtGui.QMenu()
        
        self.ctrlMenu.setTitle('Plot Options')
        self.subMenus = []
        for name, grp in menuItems:
            sm = QtGui.QMenu(name)
            act = QtGui.QWidgetAction(self)
            act.setDefaultWidget(grp)
            sm.addAction(act)
            self.subMenus.append(sm)
            self.ctrlMenu.addMenu(sm)
        
        self.stateGroup = WidgetGroup()
        for name, w in menuItems:
            self.stateGroup.autoAdd(w)
        
        self.fileDialog = None
        
        c.alphaGroup.toggled.connect(self.updateAlpha)
        c.alphaSlider.valueChanged.connect(self.updateAlpha)
        c.autoAlphaCheck.toggled.connect(self.updateAlpha)

        c.xGridCheck.toggled.connect(self.updateGrid)
        c.yGridCheck.toggled.connect(self.updateGrid)
        c.gridAlphaSlider.valueChanged.connect(self.updateGrid)

        c.fftCheck.toggled.connect(self.updateSpectrumMode)
        c.logXCheck.toggled.connect(self.updateLogMode)
        c.logYCheck.toggled.connect(self.updateLogMode)

        c.downsampleSpin.valueChanged.connect(self.updateDownsampling)
        c.downsampleCheck.toggled.connect(self.updateDownsampling)
        c.autoDownsampleCheck.toggled.connect(self.updateDownsampling)
        c.subsampleRadio.toggled.connect(self.updateDownsampling)
        c.meanRadio.toggled.connect(self.updateDownsampling)
        c.clipToViewCheck.toggled.connect(self.updateDownsampling)

        self.ctrl.avgParamList.itemClicked.connect(self.avgParamListClicked)
        self.ctrl.averageGroup.toggled.connect(self.avgToggled)
        
        self.ctrl.maxTracesCheck.toggled.connect(self.updateDecimation)
        self.ctrl.maxTracesSpin.valueChanged.connect(self.updateDecimation)
        
        self.hideAxis('right')
        self.hideAxis('top')
        self.showAxis('left')
        self.showAxis('bottom')
        
        if labels is None:
            labels = {}
        for label in list(self.axes.keys()):
            if label in kargs:
                labels[label] = kargs[label]
                del kargs[label]
        for k in labels:
            if isinstance(labels[k], basestring):
                labels[k] = (labels[k],)
            self.setLabel(k, *labels[k])
                
        if title is not None:
            self.setTitle(title)
        
        if len(kargs) > 0:
            self.plot(**kargs)
示例#5
0
文件: profiler.py 项目: slac-lcls/ami
    async def process_profile_data(self):
        self.profile.connect(self.profile_addr)

        while True:
            await self.profile.recv_string()
            name = await self.profile.recv_string()
            data_type = await self.profile.recv_string()
            data = await self.profile.recv_serialized(self.deserializer,
                                                      copy=False)

            if data_type == "profile":
                heartbeat = data['heartbeat']
                version = data['version']

                if heartbeat not in self.heartbeat_data:
                    if version not in self.metadata:
                        continue

                    metadata = self.metadata[version]
                    self.heartbeat_data[heartbeat] = HeartbeatData(
                        data['heartbeat'], metadata)
                heartbeat_data = self.heartbeat_data[heartbeat]

                if name.startswith('worker'):
                    heartbeat_data.add_worker_data(name, data['times'])
                elif name.startswith('localCollector'):
                    heartbeat_data.add_local_collector_data(
                        name, data['times'])
                elif name.startswith('globalCollector'):
                    heartbeat_data.add_global_collector_data(data['times'])

                    if version > self.current_version:
                        self.current_version = version

                        self.percent_per_heartbeat_data = collections.defaultdict(
                            lambda: 0)
                        if self.percent_per_heartbeat_trace:
                            self.percent_per_heartbeat.removeItem(
                                self.percent_per_heartbeat_trace)
                            self.percent_per_heartbeat_trace = None

                        parents = set()

                        for k, v in self.metadata[version].items():
                            parent = v['parent']
                            parents.add(parent)
                            if parent not in self.enabled_nodes:
                                widget = QtWidgets.QCheckBox(self.widget)
                                widget.node = parent
                                widget.setCheckState(QtCore.Qt.Checked)
                                self.enabled_nodes[parent] = widget
                                self.trace_layout.addRow(parent, widget)

                        deleted_nodes = self.parents.difference(parents)
                        for node in deleted_nodes:
                            self.trace_layout.removeRow(
                                self.enabled_nodes[node])
                            del self.enabled_nodes[node]
                            trace = self.time_per_heartbeat_traces[node]
                            self.time_per_heartbeat.removeItem(trace)
                            self.time_per_heartbeat_legend.removeItem(trace)
                            del self.time_per_heartbeat_traces[node]
                            del self.time_per_heartbeat_data[node]

                        self.parents = parents

                        self.trace_group.sigChanged.disconnect(
                            self.state_changed)
                        self.trace_group = WidgetGroup()
                        self.trace_group.sigChanged.connect(self.state_changed)
                        for node, ctrl in self.enabled_nodes.items():
                            self.trace_group.addWidget(ctrl, node)

                    self.time_per_heartbeat_data["heartbeat"][-1] = heartbeat
                    self.time_per_heartbeat_data["heartbeat"] = np.roll(
                        self.time_per_heartbeat_data["heartbeat"], -1)

                    total = 1
                    for node, time in heartbeat_data.total_time_per_heartbeat.items(
                    ):
                        self.time_per_heartbeat_data[node][-1] = time
                        self.time_per_heartbeat_data[node] = np.roll(
                            self.time_per_heartbeat_data[node], -1)
                        self.percent_per_heartbeat_data[
                            node] = time / heartbeat_data.total_heartbeat_time
                        total -= time / heartbeat_data.total_heartbeat_time

                    self.percent_per_heartbeat_data['Transfer'] = total

                    i = 0
                    for node, times in self.time_per_heartbeat_data.items():
                        if node == "heartbeat":
                            continue

                        if node not in self.time_per_heartbeat_traces:
                            symbol, color = symbols_colors[i]
                            self.time_per_heartbeat_traces[
                                node] = self.time_per_heartbeat.plot(
                                    x=self.
                                    time_per_heartbeat_data["heartbeat"],
                                    y=times,
                                    name=node,
                                    symbol=symbol,
                                    symbolBrush=color)
                        else:
                            self.time_per_heartbeat_traces[node].setData(
                                x=self.time_per_heartbeat_data["heartbeat"],
                                y=times)
                        i += 1

                    nodes, times = zip(
                        *self.percent_per_heartbeat_data.items())

                    if self.percent_per_heartbeat_trace is None:
                        x = np.arange(len(nodes))
                        self.percent_per_heartbeat_trace = pg.BarGraphItem(
                            x=x, height=times, width=1, brush='b')
                        self.percent_per_heartbeat.addItem(
                            self.percent_per_heartbeat_trace)
                        xticks = dict(zip(x, nodes))
                        ax = self.percent_per_heartbeat.getAxis('bottom')
                        ax.setTicks([xticks.items()])
                    else:
                        self.percent_per_heartbeat_trace.setOpts(height=times)

                    self.heartbeats_per_second_data[
                        -1] = 1 / heartbeat_data.total_heartbeat_time
                    self.heartbeats_per_second_data = np.roll(
                        self.heartbeats_per_second_data, -1)
                    if self.heartbeats_per_second_trace is None:
                        symbol, color = symbols_colors[0]
                        self.heartbeats_per_second_trace = self.heartbeats_per_second.plot(
                            x=self.time_per_heartbeat_data["heartbeat"],
                            y=self.heartbeats_per_second_data,
                            symbol=symbol,
                            symbolBrush=color)
                    else:
                        self.heartbeats_per_second_trace.setData(
                            x=self.time_per_heartbeat_data["heartbeat"],
                            y=self.heartbeats_per_second_data)

                    now = dt.datetime.now()
                    now = now.strftime("%H:%M:%S")
                    last_updated = f"Last Updated: {now}"
                    self.last_updated.setText(last_updated)
                    text = f"Seconds/Heartbeat: {heartbeat_data.total_heartbeat_time:.6f}<br/>Heartbeat: {heartbeat}"
                    self.total_heartbeat_time.setText(text)
                    text = f"Heartbeats/Second: {1/heartbeat_data.total_heartbeat_time:.0f}<br/>Heartbeat: {heartbeat}"
                    self.heartbeat_per_second.setText(text)

                    del self.heartbeat_data[heartbeat]

            elif data_type == "metadata":
                graph_name = data['graph']
                version = data['version']
                logger.info("Received metadata for %s v%d", graph_name,
                            version)

                self.metadata[version] = data['metadata']
示例#6
0
文件: profiler.py 项目: slac-lcls/ami
    def __init__(self,
                 broker_addr="",
                 profile_addr="",
                 graph_name="graph",
                 loop=None):
        super().__init__()

        if loop is None:
            self.app = QtGui.QApplication([])
            loop = QEventLoop(self.app)

        asyncio.set_event_loop(loop)

        self.ctx = zmq.asyncio.Context()

        if broker_addr:
            self.broker = self.ctx.socket(zmq.SUB)
            self.broker.setsockopt_string(zmq.SUBSCRIBE, 'profiler')
            self.broker.connect(broker_addr)
        else:
            self.broker = None

        self.graph_name = graph_name
        self.profile_addr = profile_addr
        self.profile = self.ctx.socket(zmq.SUB)
        self.profile.setsockopt_string(zmq.SUBSCRIBE, self.graph_name)
        self.task = None

        self.deserializer = Deserializer()
        self.current_version = 0
        self.metadata = {}  # {version : metadata}
        self.parents = set()

        self.heartbeat_data = {}

        self.widget = QtWidgets.QWidget()
        self.layout = QtGui.QGridLayout(self.widget)
        self.widget.setLayout(self.layout)

        self.enabled_nodes = {}
        self.trace_layout = QtGui.QFormLayout(self.widget)
        hbox = QtWidgets.QHBoxLayout(self.widget)
        selectAll = QtWidgets.QPushButton("Select All", self.widget)
        selectAll.clicked.connect(self.selectAll)
        unselectAll = QtWidgets.QPushButton("Unselect All", self.widget)
        unselectAll.clicked.connect(self.unselectAll)
        hbox.addWidget(selectAll)
        hbox.addWidget(unselectAll)
        self.trace_layout.addRow(hbox)
        self.trace_group = WidgetGroup()
        self.trace_group.sigChanged.connect(self.state_changed)
        self.layout.addLayout(self.trace_layout, 0, 0, -1, 1)

        self.graphicsLayoutWidget = pg.GraphicsLayoutWidget()
        self.layout.addWidget(self.graphicsLayoutWidget, 0, 1, -1, -1)

        self.time_per_heartbeat = self.graphicsLayoutWidget.addPlot(row=0,
                                                                    col=0)
        self.time_per_heartbeat.showGrid(True, True)
        self.time_per_heartbeat.setLabel('bottom', "Heartbeat")
        self.time_per_heartbeat.setLabel('left', "Time (Sec)")
        self.time_per_heartbeat_data = collections.defaultdict(
            lambda: np.array([np.nan] * 100))
        self.time_per_heartbeat_traces = {}
        self.time_per_heartbeat_legend = self.time_per_heartbeat.addLegend()

        self.heartbeats_per_second = self.graphicsLayoutWidget.addPlot(row=0,
                                                                       col=1)
        self.heartbeats_per_second.showGrid(True, True)
        self.heartbeats_per_second.setLabel('bottom', "Heartbeat")
        self.heartbeats_per_second.setLabel('left', "Heartbeats/Second")
        self.heartbeats_per_second_data = np.array([np.nan] * 100)
        self.heartbeats_per_second_trace = None

        self.percent_per_heartbeat = self.graphicsLayoutWidget.addPlot(
            row=1, col=0, rowspan=1, colspan=2)
        self.percent_per_heartbeat.showGrid(True, True)
        self.percent_per_heartbeat_trace = None

        self.last_updated = pg.LabelItem(
            parent=self.time_per_heartbeat.getViewBox())
        self.total_heartbeat_time = pg.LabelItem(
            parent=self.percent_per_heartbeat.getViewBox())
        self.heartbeat_per_second = pg.LabelItem(
            parent=self.heartbeats_per_second.getViewBox())

        self.win = ProfilerWindow(self)
        self.win.setWindowTitle('Profiler')
        self.win.setCentralWidget(self.widget)
        self.win.show()

        with loop:
            loop.run_until_complete(
                asyncio.gather(self.process_broker_message(), self.monitor()))