-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from nodedge/feature/log-analyzer
Feature/log analyzer
- Loading branch information
Showing
24 changed files
with
1,298 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,4 +23,5 @@ _template/ | |
*.egg-info/ | ||
.tox/ | ||
examples/examples | ||
ui | ||
ui | ||
log/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import json | ||
|
||
from PyQt5.QtCore import Qt | ||
from PyQt5.QtWidgets import * | ||
|
||
|
||
class ViewTree(QTreeWidget): | ||
def __init__(self, value): | ||
|
||
super().__init__() | ||
|
||
def fill_item(item, value): | ||
def new_item(parent, text, val=None): | ||
child = QTreeWidgetItem([text]) | ||
child.setFlags(child.flags() | Qt.ItemIsEditable) | ||
fill_item(child, val) | ||
parent.addChild(child) | ||
child.setExpanded(True) | ||
|
||
if value is None: | ||
return | ||
elif isinstance(value, dict): | ||
for key, val in sorted(value.items()): | ||
new_item(item, str(key), val) | ||
elif isinstance(value, (list, tuple)): | ||
for val in value: | ||
text = ( | ||
str(val) | ||
if not isinstance(val, (dict, list, tuple)) | ||
else "[%s]" % type(val).__name__ | ||
) | ||
new_item(item, text, val) | ||
else: | ||
new_item(item, str(value)) | ||
|
||
fill_item(self.invisibleRootItem(), value) | ||
|
||
|
||
if __name__ == "__main__": | ||
|
||
app = QApplication([]) | ||
|
||
fname = QFileDialog.getOpenFileName() | ||
json_file = open(fname[0], "r") | ||
file = json.load(json_file) | ||
|
||
window = ViewTree(file) | ||
window.setGeometry(300, 100, 900, 600) | ||
window.show() | ||
app.exec_() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import pyqtgraph as pg | ||
from PySide2 import QtWidgets | ||
|
||
|
||
class WdgPlot(QtWidgets.QWidget): | ||
def __init__(self, parent=None): | ||
super(WdgPlot, self).__init__(parent) | ||
layout = QtWidgets.QVBoxLayout(self) | ||
|
||
pw = pg.PlotWidget() | ||
pw.plot([1, 2, 3, 4]) | ||
layout.addWidget(pw) | ||
|
||
|
||
if __name__ == "__main__": | ||
import sys | ||
|
||
app = QtWidgets.QApplication(sys.argv) | ||
w = WdgPlot() | ||
w.show() | ||
sys.exit(app.exec_()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
This example demonstrates writing a custom Node subclass for use with flowcharts. | ||
We implement a couple of simple image processing nodes. | ||
""" | ||
# from pyqtgraph import initExample ## Add path to library (just for examples; you do not need this) | ||
|
||
import numpy as np | ||
import pyqtgraph as pg | ||
import pyqtgraph.flowchart.library as fclib | ||
from pyqtgraph.flowchart import Flowchart, Node | ||
from pyqtgraph.flowchart.library.common import CtrlNode | ||
from pyqtgraph.Qt import QtCore, QtGui | ||
|
||
app = QtGui.QApplication([]) | ||
|
||
## Create main window with a grid layout inside | ||
win = QtGui.QMainWindow() | ||
win.setWindowTitle("pyqtgraph example: FlowchartCustomNode") | ||
cw = QtGui.QWidget() | ||
win.setCentralWidget(cw) | ||
layout = QtGui.QGridLayout() | ||
cw.setLayout(layout) | ||
|
||
## Create an empty flowchart with a single input and output | ||
fc = Flowchart(terminals={"dataIn": {"io": "in"}, "dataOut": {"io": "out"}}) | ||
w = fc.widget() | ||
|
||
layout.addWidget(fc.widget(), 0, 0, 2, 1) | ||
|
||
## Create two ImageView widgets to display the raw and processed data with contrast | ||
## and color control. | ||
v1 = pg.ImageView() | ||
v2 = pg.ImageView() | ||
layout.addWidget(v1, 0, 1) | ||
layout.addWidget(v2, 1, 1) | ||
|
||
win.show() | ||
|
||
## generate random input data | ||
data = np.random.normal(size=(100, 100)) | ||
data = 25 * pg.gaussianFilter(data, (5, 5)) | ||
data += np.random.normal(size=(100, 100)) | ||
data[40:60, 40:60] += 15.0 | ||
data[30:50, 30:50] += 15.0 | ||
# data += np.sin(np.linspace(0, 100, 1000)) | ||
# data = metaarray.MetaArray(data, info=[{'name': 'Time', 'values': np.linspace(0, 1.0, len(data))}, {}]) | ||
|
||
## Set the raw data as the input value to the flowchart | ||
fc.setInput(dataIn=data) | ||
|
||
|
||
## At this point, we need some custom Node classes since those provided in the library | ||
## are not sufficient. Each node will define a set of input/output terminals, a | ||
## processing function, and optionally a control widget (to be displayed in the | ||
## flowchart control panel) | ||
|
||
|
||
class ImageViewNode(Node): | ||
"""Node that displays image data in an ImageView widget""" | ||
|
||
nodeName = "ImageView" | ||
|
||
def __init__(self, name): | ||
self.view = None | ||
## Initialize node with only a single input terminal | ||
Node.__init__(self, name, terminals={"data": {"io": "in"}}) | ||
|
||
def setView(self, view): ## setView must be called by the program | ||
self.view = view | ||
|
||
def process(self, data, display=True): | ||
## if process is called with display=False, then the flowchart is being operated | ||
## in batch processing mode, so we should skip displaying to improve performance. | ||
|
||
if display and self.view is not None: | ||
## the 'data' argument is the value given to the 'data' terminal | ||
if data is None: | ||
self.view.setImage( | ||
np.zeros((1, 1)) | ||
) # give a blank array to clear the view | ||
else: | ||
self.view.setImage(data) | ||
|
||
|
||
## We will define an unsharp masking filter node as a subclass of CtrlNode. | ||
## CtrlNode is just a convenience class that automatically creates its | ||
## control widget based on a simple data structure. | ||
class UnsharpMaskNode(CtrlNode): | ||
"""Return the input data passed through an unsharp mask.""" | ||
|
||
nodeName = "UnsharpMask" | ||
uiTemplate = [ | ||
("sigma", "spin", {"value": 1.0, "step": 1.0, "bounds": [0.0, None]}), | ||
( | ||
"strength", | ||
"spin", | ||
{ | ||
"value": 1.0, | ||
"dec": True, | ||
"step": 0.5, | ||
"minStep": 0.01, | ||
"bounds": [0.0, None], | ||
}, | ||
), | ||
] | ||
|
||
def __init__(self, name): | ||
## Define the input / output terminals available on this node | ||
terminals = { | ||
"dataIn": dict(io="in"), # each terminal needs at least a name and | ||
"dataOut": dict(io="out"), # to specify whether it is input or output | ||
} # other more advanced options are available | ||
# as well.. | ||
|
||
CtrlNode.__init__(self, name, terminals=terminals) | ||
|
||
def process(self, dataIn, display=True): | ||
# CtrlNode has created self.ctrls, which is a dict containing {ctrlName: widget} | ||
sigma = self.ctrls["sigma"].value() | ||
strength = self.ctrls["strength"].value() | ||
output = dataIn - (strength * pg.gaussianFilter(dataIn, (sigma, sigma))) | ||
return {"dataOut": output} | ||
|
||
|
||
## To make our custom node classes available in the flowchart context menu, | ||
## we can either register them with the default node library or make a | ||
## new library. | ||
|
||
|
||
## Method 1: Register to global default library: | ||
# fclib.registerNodeType(ImageViewNode, [('Display',)]) | ||
# fclib.registerNodeType(UnsharpMaskNode, [('Image',)]) | ||
|
||
## Method 2: If we want to make our custom node available only to this flowchart, | ||
## then instead of registering the node type globally, we can create a new | ||
## NodeLibrary: | ||
library = fclib.LIBRARY.copy() # start with the default node set | ||
library.addNodeType(ImageViewNode, [("Display",)]) | ||
# Add the unsharp mask node to two locations in the menu to demonstrate | ||
# that we can create arbitrary menu structures | ||
library.addNodeType( | ||
UnsharpMaskNode, [("Image",), ("Submenu_test", "submenu2", "submenu3")] | ||
) | ||
fc.setLibrary(library) | ||
|
||
## Now we will programmatically add nodes to define the function of the flowchart. | ||
## Normally, the user will do this manually or by loading a pre-generated | ||
## flowchart file. | ||
|
||
v1Node = fc.createNode("ImageView", pos=(0, -150)) | ||
v1Node.setView(v1) | ||
|
||
v2Node = fc.createNode("ImageView", pos=(150, -150)) | ||
v2Node.setView(v2) | ||
|
||
fNode = fc.createNode("UnsharpMask", pos=(0, 0)) | ||
fc.connectTerminals(fc["dataIn"], fNode["dataIn"]) | ||
fc.connectTerminals(fc["dataIn"], v1Node["data"]) | ||
fc.connectTerminals(fNode["dataOut"], v2Node["data"]) | ||
fc.connectTerminals(fNode["dataOut"], fc["dataOut"]) | ||
|
||
## Start Qt event loop unless running in interactive mode or using pyside. | ||
if __name__ == "__main__": | ||
import sys | ||
|
||
if (sys.flags.interactive != 1) or not hasattr(QtCore, "PYQT_VERSION"): | ||
QtGui.QApplication.instance().exec_() |
Oops, something went wrong.