374 lines
34 KiB
Python
374 lines
34 KiB
Python
"""
|
|
This example demonstrates the use of pyqtgraph's dock widget system.
|
|
|
|
The dockarea system allows the design of user interfaces which can be rearranged by
|
|
the user at runtime. Docks can be moved, resized, stacked, and torn out of the main
|
|
window. This is similar in principle to the docking system built into Qt, but
|
|
offers a more deterministic dock placement API (in Qt it is very difficult to
|
|
programatically generate complex dock arrangements). Additionally, Qt's docks are
|
|
designed to be used as small panels around the outer edge of a window. Pyqtgraph's
|
|
docks were created with the notion that the entire window (or any portion of it)
|
|
would consist of dockable components.
|
|
"""
|
|
|
|
import numpy as np
|
|
import pyqtgraph as pg
|
|
from pyqtgraph.console import ConsoleWidget
|
|
from pyqtgraph.dockarea.Dock import Dock
|
|
from pyqtgraph.dockarea.DockArea import DockArea
|
|
from pyqtgraph.Qt import QtWidgets, QtCore
|
|
from pyqtgraph.Qt.QtGui import QKeySequence, QShortcut
|
|
|
|
from user_common import nowStr
|
|
|
|
import pyqtgraph.parametertree.parameterTypes as pTypes
|
|
from pyqtgraph.parametertree import Parameter, ParameterTree
|
|
|
|
app = pg.mkQApp("MCA")
|
|
win = QtWidgets.QMainWindow()
|
|
area = DockArea()
|
|
win.setCentralWidget(area)
|
|
win.resize(1000,500)
|
|
win.setWindowTitle('MultiChannel Analyzer')
|
|
|
|
## Create docks, place them into the window one at a time.
|
|
## Note that size arguments are only a suggestion; docks will still have to
|
|
## fill the entire dock area and obey the limits of their internal widgets.
|
|
d1 = Dock("Log Window", size=(100,600)) ## give this dock the minimum possible size
|
|
d2 = Dock("Params Window", size=(100,600))
|
|
d3 = Dock("PHA Window", size=(500,100))
|
|
d4 = Dock("", size=(500,600)) ## give this dock the minimum possible size
|
|
d3.hideTitleBar()
|
|
d4.hideTitleBar()
|
|
|
|
area.addDock(d3, 'left') ## place d1 at left edge of dock area (it will fill the whole space since there are no other docks yet)
|
|
area.addDock(d1, 'right') ## place d2 at right edge of dock area
|
|
area.addDock(d2, 'right', d1) ## place d3 at bottom edge of d1
|
|
area.moveDock(d1, 'bottom', d2)
|
|
area.moveDock(d4, 'bottom', d3)
|
|
## Add widgets into each dock
|
|
|
|
## first dock gets save/restore buttons
|
|
w1 = pg.LayoutWidget()
|
|
label = QtWidgets.QLabel(""" -- DockArea Example --
|
|
This window has 6 Dock widgets in it. Each dock can be dragged
|
|
by its title bar to occupy a different space within the window
|
|
but note that one dock has its title bar hidden). Additionally,
|
|
the borders between docks may be dragged to resize. Docks that are dragged on top
|
|
of one another are stacked in a tabbed layout. Double-click a dock title
|
|
bar to place it in its own window.
|
|
""")
|
|
textEdt = QtWidgets.QTextEdit()
|
|
clearBtn = QtWidgets.QPushButton('Clear Logs')
|
|
|
|
clearBtn.setEnabled(True)
|
|
w1.addWidget(textEdt, row=0, col=0)
|
|
w1.addWidget(clearBtn, row=1, col=0)
|
|
d1.addWidget(w1)
|
|
def clear():
|
|
global tempStr
|
|
tempStr = ''
|
|
clearBtn.clicked.connect(clear)
|
|
|
|
## test subclassing parameters
|
|
## This parameter automatically generates two child parameters which are always reciprocals of each other
|
|
class ComplexParameter(pTypes.GroupParameter):
|
|
def __init__(self, **opts):
|
|
opts['type'] = 'bool'
|
|
opts['value'] = True
|
|
pTypes.GroupParameter.__init__(self, **opts)
|
|
|
|
self.addChild({'name': 'A = 1/B', 'type': 'float', 'value': 7, 'suffix': 'Hz', 'siPrefix': True})
|
|
self.addChild({'name': 'B = 1/A', 'type': 'float', 'value': 1/7., 'suffix': 's', 'siPrefix': True})
|
|
self.a = self.param('A = 1/B')
|
|
self.b = self.param('B = 1/A')
|
|
self.a.sigValueChanged.connect(self.aChanged)
|
|
self.b.sigValueChanged.connect(self.bChanged)
|
|
|
|
def aChanged(self):
|
|
self.b.setValue(1.0 / self.a.value(), blockSignal=self.bChanged)
|
|
|
|
def bChanged(self):
|
|
self.a.setValue(1.0 / self.b.value(), blockSignal=self.aChanged)
|
|
|
|
|
|
## test add/remove
|
|
## this group includes a menu allowing the user to add new parameters into its child list
|
|
class ScalableGroup(pTypes.GroupParameter):
|
|
def __init__(self, **opts):
|
|
opts['type'] = 'group'
|
|
opts['addText'] = "Add"
|
|
opts['addList'] = ['str', 'float', 'int']
|
|
pTypes.GroupParameter.__init__(self, **opts)
|
|
|
|
def addNew(self, typ):
|
|
val = {
|
|
'str': '',
|
|
'float': 0.0,
|
|
'int': 0
|
|
}[typ]
|
|
self.addChild(dict(name="ScalableParam %d" % (len(self.childs)+1), type=typ, value=val, removable=True, renamable=True))
|
|
|
|
# params = [
|
|
# {'name': 'Save/Restore', 'type': 'group', 'children': [
|
|
# {'name': 'Save State', 'type': 'action'},
|
|
# {'name': 'Restore State', 'type': 'action', 'children': [
|
|
# {'name': 'Add missing items', 'type': 'bool', 'value': True},
|
|
# {'name': 'Remove extra items', 'type': 'bool', 'value': True},
|
|
# ]},
|
|
# ]},
|
|
# {'name': 'Custom context menu', 'type': 'group', 'children': [
|
|
# {'name': 'List contextMenu', 'type': 'float', 'value': 0, 'context': [
|
|
# 'menu1',
|
|
# 'menu2'
|
|
# ]},
|
|
# {'name': 'Dict contextMenu', 'type': 'float', 'value': 0, 'context': {
|
|
# 'changeName': 'Title',
|
|
# 'internal': 'What the user sees',
|
|
# }},
|
|
# ]},
|
|
# ComplexParameter(name='Custom parameter group (reciprocal values)'),
|
|
# ScalableGroup(name="Expandable Parameter Group", tip='Click to add children', children=[
|
|
# {'name': 'ScalableParam 1', 'type': 'str', 'value': "default param 1"},
|
|
# {'name': 'ScalableParam 2', 'type': 'str', 'value': "default param 2"},
|
|
# ]),
|
|
# ]
|
|
|
|
params = [
|
|
{'name': 'Save/Restore', 'type': 'group', 'children': [
|
|
{'name': 'Save State', 'type': 'action'},
|
|
{'name': 'Restore State', 'type': 'action', 'children': [
|
|
{'name': 'Add missing items', 'type': 'bool', 'value': True},
|
|
{'name': 'Remove extra items', 'type': 'bool', 'value': True},
|
|
]},
|
|
]},
|
|
{'name':'ROIs', 'type':'group', 'children':[
|
|
]},
|
|
]
|
|
|
|
## Create tree of Parameter objects
|
|
p = Parameter.create(name='params', type='group', children=params)
|
|
|
|
## If anything changes in the tree, print a message
|
|
def change(param, changes):
|
|
# print("tree changes:")
|
|
for param, change, data in changes:
|
|
path = p.childPath(param)
|
|
if path is not None:
|
|
childName = '.'.join(path)
|
|
else:
|
|
childName = param.name()
|
|
# print(' parameter: %s'% childName)
|
|
# print(' change: %s'% change)
|
|
# print(' data: %s'% str(data))
|
|
# print(' ----------')
|
|
|
|
p.sigTreeStateChanged.connect(change)
|
|
|
|
def valueChanging(param, value):
|
|
print("Value changing (not finalized): %s %s" % (param, value))
|
|
|
|
# Only listen for changes of the 'widget' child:
|
|
for child in p.child('Save/Restore'):
|
|
if 'widget' in child.names:
|
|
child.child('widget').sigValueChanging.connect(valueChanging)
|
|
|
|
def save():
|
|
global state
|
|
state = p.saveState()
|
|
|
|
def restore():
|
|
global state
|
|
add = p['Save/Restore', 'Restore State', 'Add missing items']
|
|
rem = p['Save/Restore', 'Restore State', 'Remove extra items']
|
|
p.restoreState(state, addChildren=add, removeChildren=rem)
|
|
p.param('Save/Restore', 'Save State').sigActivated.connect(save)
|
|
p.param('Save/Restore', 'Restore State').sigActivated.connect(restore)
|
|
|
|
w2 = ParameterTree()
|
|
w2.setParameters(p, showTop=False)
|
|
w2.setWindowTitle('pyqtgraph example: Parameter Tree')
|
|
d2.addWidget(w2)
|
|
|
|
|
|
## Hide title bar on dock 3
|
|
# d3.hideTitleBar()
|
|
data = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,118,108, 97,105, 94,121, 91,108,130,105,101,112, 94,102, 98,102,112,109,106,122,112,107,104, 90,110,113, 92, 96,116,102,110,104,116, 96, 93,121, 89, 94, 97, 96,120, 92, 97,105,114, 99,109,107, 97, 96,100,103,109, 97,104, 97,106, 99, 93, 95,109,103,100,104, 92,100, 89, 97,102, 97, 98, 84,110, 99, 94, 92, 86,108, 95, 94,132, 77,104, 94, 90,110,106, 85,103, 97, 95,103,104, 97, 99, 91, 96,107, 99,112,118,106,111,106,114, 99,110,110, 98,105,109, 96,109, 90,114,113,109, 86,107, 97,105, 99, 99,103,102,110, 98,106,113,104,102,104,114,111, 97, 97,104,103,104, 98, 88, 98, 93,110,106,101, 92,100, 93, 88,100, 86,108,111,111,110,122,104, 92, 91,107,108, 99,100,122, 88,105,119,107,111, 94,103,130, 92, 98,121,119, 95, 87, 99,107, 91, 98, 99,102,126,123,104,111,107,104,108,104, 94,121,120,110,109,104, 97,110,102, 79,115,116, 89, 95, 90,119,118,122,127,114,112,111,115,106,108,110, 98,108,117,116,106,105,118,105,118,106, 98,103,130,116, 79,100,129,116, 98, 98,104, 95,122,114,128,103,112,122,128,128,138,132,130,100,127,103,124,118,125,116,122,128,111,110,118,111,115,130,119, 90,126,118,129,123,118,127,140,122,122,122,127,126,122,134,121,102,130,127,119,113,126,124,122,118,117,121,128,124,127,121,139,150,126,133,130,124,115,123,133,132,132,131,139,133,120,107,142,123,150,135,126,127,150,135,140,117,136,133,126,151,136,140,152,165,138,143,149,139,149,133,151,123,147,145,129,113,140,142,140,137,145,143,135,156,160,200,215,268,319,265,250,183,169,152,137,122,136,131,131,149,179,153,136,130,140,166,176,139,146,158,144,145,136,131,143,141,139,154,137,140,169,173,147,156,151,144,161,155,124,138,140,146,135,137,138,132,147,128,154,137,150,127,136,153,161,144,146,175,139,150,174,156,173,174,176,145,156,144,166,141,160,154,141,162,134,165,161,131,164,188,180,171,183,138,156,156,166,160,169,166,153,153,179,152,168,151,155,151,163,155,174,166,158,177,143,165,166,151,160,161,175,167,151,156,181,177,180,147,194,168,157,161,174,196,177,166,162,179,145,170,173,198,149,158,168,187,165,181,167,170,188,172,152,156,181,196,169,173,185,171,157,184,165,172,176,209,177,195,179,178,175,188,208,174,181,185,173,185,189,179,175,201,178,164,204,156,197,173,180,186,178,180,187,166,197,230,185,180,176,186,206,169,207,202,217,194,186,208,184,169,168,178,183,199,204,181,187,199,185,209,181,195,190,194,203,181,200,186,174,200,215,183,159,171,190,166,202,197,173,189,185,176,206,168,167,172,161,171,168,160,228,179,190,189,146,190,211,194,198,193,174,180,159,173,190,176,166,168,152,181,188,174,185,173,180,173,174,165,170,173,164,174,175,197,146,176,177,184,204,173,173,186,166,178,189,173,165,170,172,163,165,169,145,171,174,181,177,173,173,164,181,181,194,154,163,175,187,152,182,206,203,192,187,164,174,198,164,185,153,153,189,172,190,186,181,170,181,187,194,163,153,175,151,172,149,181,170,180,211,149,172,179,149,187,163,160,191,174,154,184,179,165,174,183,161,176,185,203,184,166,170,179,187,177,162,200,182,177,172,158,181,145,191,173,179,189,177,161,171,164,176,158,167,188,153,170,162,172,190,181,190,159,185,165,175,152,176,154,179,162,162,172,179,166,184,195,157,159,161,171,160,182,159,168,162,181,167,155,172,158,170,177,153,168,162,165,180,157,166,167,161,183,166,188,187,200,176,188,197,175,168,170,172,162,156,154,159,155,171,168,181,165,174,166,176,166,171,183,158,177,177,171,161,159,184,198,195,173,139,159,179,178,136,169,163,151,164,164,156,170,156,183,159,183,157,182,151,167,157,171,179,162,188,178,158,176,161,142,163,187,173,150,186,176,159,168,159,172,169,187,160,180,162,186,180,155,137,188,185,182,165,156,159,181,166,150,145,181,171,170,156,181,151,154,159,170,166,150,175,175,164,173,161,172,176,141,173,175,164,161,179,168,185,169,179,150,162,152,174,175,180,170,173,152,181,168,147,183,137,169,161,139,171,191,193,175,167,166,175,151,175,135,165,165,164,169,159,159,147,181,179,156,166,159,169,156,163,182,156,203,154,171,171,166,174,171,164,170,154,176,155,182,162,164,165,156,144,181,183,170,170,160,193,186,171,140,173,174,165,183,173,164,147,171,167,170,171,172,145,179,188,192,147,179,171,175,183,199,171,173,162,160,174,161,160,191,165,189,176,165,159,174,163,160,160,148,168,171,157,143,151,171,177,195,193,166,171,172,159,181,174,170,187,162,162,187,161,166,169,171,161,146,174,187,153,162,157,159,201,155,173,150,170,178,186,188,181,176,173,169,177,190,169,159,203,191,170,167,166,155,176,182,159,206,180,167,201,187,185,163,201,154,176,156,167,160,182,156,158,182,172,166,197,164,187,185,184,166,172,196,136,178,164,165,195,184,189,186,179,160,174,178,174,183,192,191,152,187,167,174,178,162,178,155,153,163,192,170,189,164,164,165,170,154,152,199,180,188,190,186,180,210,158,173,185,177,164,173,181,192,171,160,192,175,175,169,182,150,168,173,187,183,181,200,179,160,185,166,173,205,200,174,157,173,184,162,170,183,185,205,181,171,195,174,165,190,169,196,161,197,177,159,184,185,176,195,189,171,191,189,147,186,161,183,214,169,187,175,185,185,168,179,175,184,177,179,224,203,187,206,145,206,177,186,171,174,195,186,187,176,188,189,200,183,177,173,175,182,203,188,197,167,167,183,186,180,214,198,222,216,198,182,203,189,172,203,175,173,194,187,189,187,206,182,168,196,176,205,212,175,164,174,185,166,158,176,186,181,204,201,200,162,187,186,177,196,207,185,176,195,176,189,167,181,181,187,176,174,173,193,187,175,175,184,209,197,173,195,202,168,185,189,173,145,164,182,194,177,192,194,185,179,194,196,185,178,211,178,214,195,186,205,184,219,176,169,190,170,184,177,179,195,197,185,202,187,142,179,190,199,195,195,203,205,163,200,220,228,165,209,182,182,213,183,173,216,174,189,169,202,192,192,212,169,176,195,203,189,214,201,171,165,210,210,178,170,184,212,203,195,200,195,216,181,186,193,218,219,186,177,144,178,190,179,154,168,167,164,179,174,154,183,164,173,172,164,168,158,169,145,199,184,170,170,164,158,164,157,175,136,141,178,177,166,156,143,166,162,155,154,181,145,172,143,151,147,166,161,176,150,145,153,155,162,158,174,165,163,181,205,228,206,192,181,164,131,151,160,135,162,151,144,165,163,138,162,141,133,146,159,155,156,141,147,157,152,136,145,139,141,154,159,141,145,111,170,149,159,168,167,187,257,329,418,478,524,457,368,284,203,170,155,166,144,144,152,156,158,147,136,152,130,152,163,146,129,124,159,134,130,148,146,137,145,149,147,144,151,151,156,133,151,144,121,125,146,161,160,140,136,132,143,132,136,157,137,142,132,145,130,139,144,135,137,143,171,150,132,121,137,146,148,129,133,118,138,147,130,146,137,124,138,123,135,144,114,113,122,145,135,122,146,142,145,131,121,135,127,128,120,139,154,118,157,155,139,126,120,130,137,141,130,129,125,127,130,140,136,116,114,117,132,135,141,118,127,126,143,130,145,117,164,156,148,147,147,126,152,136,152,138,140,128,122,118,142,124,142,115,124,121,118,129,132,135,125,124,133,162,165,181,197,149,151,185,157,144,135,156,141,141,107,113,125,138,142,151,162,163,208,222,230,206,176,145,116,144,134,128,125,123,116,122,125,111,132,124,117,102,111,123,113,118,114,127,127,121,115,126,112,123,109,110, 98,121,109,141,124,110,117,113,114,121, 97,107,120,100,112,106,108, 91, 97,101, 91,113,107,106,106, 99, 98,110, 90, 97,112, 84,103,103,101,114,121, 83, 88, 97, 99,121,112,119,110,107,105,119,106,113,104,115,115,121,117,103,112,120, 98,121,123,121,101, 98,122,103,111,115,110,141,138,194,262,399,541,646,631,531,420,294,207,137,118, 97,104, 92, 96, 84, 87,110, 99, 97, 94, 93, 88, 99, 90, 98,109, 85, 89,101, 77,104, 93, 97, 99,103, 94,104,101,117,111,112,108, 81, 98, 90,101, 94,120, 92, 93,110,121,167,204,203,272,270,227,192,146,115,104,100, 97,108, 75, 79,100, 67, 76, 81, 89, 84, 68, 79, 95, 82, 86, 82, 83, 71, 76, 80, 87, 94, 93, 87, 93, 93,102, 77, 94, 74, 77, 83, 98, 92,103,111,105,103, 90, 67, 76, 81, 98, 79, 81, 83, 82, 69, 77, 90, 93, 84, 93, 87, 79, 87, 88, 70, 86, 74, 87, 89, 89, 99, 93, 86, 92, 82, 72, 84, 71, 87, 65, 81, 76, 84, 78, 83, 82, 78, 84, 93, 95, 80, 89, 98, 89, 85, 81, 87, 77, 87, 94,101, 76, 95, 94, 89, 88, 91, 90, 91,122,106,140,137,186,311,572, 1221, 2128, 3449, 4890, 5850, 5942, 5096, 3632, 2247, 1201,562,204, 97, 60, 50, 40, 29, 39, 28, 47, 36, 39, 44, 38, 32, 24, 45, 34, 38, 33, 35, 38, 39, 39, 30, 39, 49, 43, 33, 35, 45, 37, 43, 34, 40, 38, 34, 29, 28, 51, 35, 45, 30, 36, 35, 48, 34, 41, 30, 47, 38, 37, 27, 42, 46, 43, 36, 44, 51, 31, 47, 30, 38, 35, 42, 39, 42, 37, 39, 39, 40, 28, 41, 42, 37, 38, 32, 41, 23, 36, 35, 36, 32, 36, 26, 35, 34, 28, 37, 31, 52, 45, 39, 39, 42, 54, 54, 71,102,130,177,177,180,152,113, 80, 69, 46, 43, 35, 39, 47, 45, 36, 37, 32, 33, 39, 34, 32, 28, 32, 41, 32, 35, 26, 38, 33, 32, 39, 31, 28, 42, 40, 37, 49, 27, 41, 41, 48, 30, 35, 37, 31, 36, 38, 32, 26, 42, 38, 40, 33, 28, 37, 42, 29, 38, 36, 25, 32, 33, 39, 42, 44, 37, 32, 36, 36, 48, 48, 45, 46, 37, 27, 36, 34, 34, 36, 61, 73,108,180,251,348,527,629,645,602,408,288,170, 93, 58, 43, 42, 29, 31, 25, 26, 27, 31, 31, 36, 26, 27, 29, 31, 29, 32, 27, 39, 37, 40, 29, 19, 42, 29, 30, 41, 30, 29, 35, 28, 34, 39, 28, 24, 34, 27, 27, 33, 32, 31, 41, 30, 40, 35, 27, 26, 22, 29, 39, 34, 21, 26, 30, 27, 47, 39, 24, 33, 36, 36, 31, 27, 41, 39, 26, 25, 32, 33, 29, 32, 39, 28, 46, 25, 32, 28, 29, 41, 28, 34, 47, 42, 39, 38, 47, 59, 90,124,248,406,587,723,786,713,599,428,247,143, 72, 48, 36, 42, 25, 31, 34, 37, 28, 34, 46, 40, 42, 61, 90,143,320,555, 1013, 1652, 2270, 2740, 2879, 2619, 2046, 1315,786,428,159, 69, 24, 13, 11, 10,7, 12,7, 12,9,4,9, 10,8,4,3,4,8,8, 12,9,5, 11, 11,7,3,5, 11,8,9,6,6,8,9,6,5,5,9,8,7,7, 12,5,9, 10,8,8, 10,8,5,9,7,9,9,4,7,7,8,6,8,7,9, 10,6,6, 10,6,7,8, 10,8,9, 13,7,7, 11, 15, 17, 25, 63,127,163,277,337,430,455,361,300,195,113, 45, 37, 10,8,8,7,7, 10, 14, 23, 18, 40, 37, 48, 58, 33, 20, 16, 11,7,5,3,7,8,6,4,5,6,6,2,4,9,5,6,6,4,5,7,5,4,5,3,1,3,7,4,7,2,6,3,5,4,6,2,5,5,7,6,5,5,4,4,4,4,4,1,3,7,4,3,1,4,5,7,6,2,3,4,1,3,4,9,8,5,3,5,5,5,1,7,2,4,1,3,3,7,5,4,3,1,2,1,6,6,5,5,3,2,3,4,3,4,3,7,6,3,7,3,3,4,6,4,4,2, 10,3,8,3,8,0,5,4,6,6,4,4,2,4,4,4,8,3,2,3,2,2,9,3,4,3,6,3,4,1,8,3,4,3,5,2,4,2,4,5,2,4,3,0,6,1,3,4,1,6,2,6,3,3,4,5,5,4,2,5,4,3,6,3,5,6,3,2,6,1,4,4,5,1,4,2,4,1,6,7,3,1,5,3,5,5,5,0,2,3,4,5,5,7,3,4,6,3,3,4,6,4,4,7,5, 12, 12, 12, 15,6,6, 13,6,3,5,4,5,0,4,5,1,4,5,1,8,5,5,6,2,1,4,1,3,5,3,3,2,2,7,6,4,4,2,5,3,3,3,5,4,2,1,3, 10,7,3,4,2,2,1,0,2,2,4,6,3,1,5,2,4,3,4,5,5,5,5,3,3,4,3,4,4,3,2,3,0,7,1,1,0,4,1,3,6,3,4,1,7,4,4,5,0,3,2,3,3,4,4,3,3,3,0,3,2,2,2,6,6,3,3,3,3,1,5,3,2,2,6,4,3,4,4,3,4,2,6,6,3,5,2,5,0,3,4,6,4,4,3,3,0,2,4,4,8,3,2,0,3,3,1,3,2,1,4,3,3,5,4,4,4,2,2,4,5,4,5,2,5,5,3,6,1,3,2,2,1,2,3,4,2,0,6,3,3,4,1,2,4,4,1,4,3,2,4,6,2,2,2,4,3,4,4,3,3,5,1,4,1,4,4,1,2,1,4,2,1,1,3,2,2,2,5,3,3,4,3,3,2,2,1,1,7,3,5,3,3,1,2,2,3,3,2,4,3,2,3,4,4,4,1,3,4,3,4,3,3,4,3,1,2,3,4,3,3,3,2,4,2,3,4,1,0,4,2,8,5,3,3,4,1,2,4,4,6,6,3,4,4,1,1,2,1,1,1,3,2,5,1,1,7,4,2,3,2,4,2,1,6,3,2,3,4,1,3,3,5,4,2,0,4,1,4,6,3,1,4,3,2,5,3,2,1,4,5,5,4,4,3,3,4,1,1,6,1,4,3,1,5,3,1,1,0,3,3,1,4,4,1,1,2,3,8,6,1,3,2,2,3,4,5,3,5,7, 10, 12,6,4,3,7,6,2,5,4,7,3,4,5,1,4,7,1,1,1,1,3,5,7, 10,9,6,9,8,9, 10,1,8,4,2,3,0,4,2,0,5,2,0,2,3,1,1,1,1,3,3,1,3,1,1,2,4,1,3,6,0,1,3,5,6,2,3,1,2,2,1,2,2,2,0,3,2,3,2,2,3,2,0,1,2,3,6,0,2,5,1,3,2,1,2,3,3,0,2,4,2,2,1,1,2,4,1,6,4,3,3,4,2,3,3,2,4,5,4,2,9,1,3,3,4,5,2,5,6,4,6,8,3,8,7,5,2,5,4,5,3,1,3,5,0,0,1,4,3,2,5,6,3,5,4,5,4,4,4,7,5, 10,6, 11, 18, 18, 33, 25, 29, 20,9,1,6,6,3,4,1,4,5,3,3,2,4,1,3,4,0,2,4,1,1,4,3,7,3,3,5,3,2,4,2,1,3,1,1,2,2,1,2,0,3,0,2,3,5,2,3,1,0,4,3,1,3,2,3,2,3,2,2,1,5,1,2,3,2,2,2,2,0,4,5,5,4,2,2,2,3,2,4,4,3,3,3,2,0,1,1,1,2,4,2,1,5,4,5,1,3,3,1,3,1,4,1,0,7,3,2,4,8,2,1,2,3,3,5,2,2,2,2,4,2,1,1,3,2,0,4,2,4,1,4,3,2,5,2,2,2,2,3,1,0,1,3,2,1,0,4,3,1,2,1,3,2,3,3,2,5,3,3,4,2,2,4,1,3,4,1,1,3,2,0,2,5,3,5,4,1,4,1,3,1,3,4,3,3,4,4,3,2,6,4,3,2,4,3,3,1,1,2,2,2,3,1,2,0,0,2,0,2,4,1,1,0,3,1,2,6,5,3,1,3,4,0,1,2,3,5,3,2,0,3,4,8,5,5,3, 11,4,7,2,3,1,5,3,3,0,1,2,3,4,0,1,2,2,4,4,4,2,2,1,2,1,2,1,2,4,3,3,1,3,0,2,2,0,2,3,2,0,2,3,2,2,3,2,2,2,5,3,1,1,2,0,1,5,1,2,2,2,2,2,0,0,3,5,0,0,2,3,4,0,1,5,2,2,1,0,1,3,1,1,2,2,0,2,2,2,0,4,0,1,2,2,1,1,3,5,5,1,1,3,6,3,4,5,2,3,2,4,4,5,5,8,7,4, 12,4, 15, 12,7,2,5,5,4,5,0,3,6,2,4,1,4,2,0,0,5,0,3,3,1,1,1,2,3,0,4,2,2,1,2,1,0,3,1,2,2,2,0,2,2,1,2,1,0,3,1,5,2,1,1,3,0,2,1,5,3,4,0,4,1,0,1,6,2,1,1,2,1,2,3,3,0,1,2,2,2,2,5,5,1,1,2,1,5,1,2,2,3,3,1,2,1,2,4,1,0,3,0,1,1,6,1,4,1,2,3,3,4,6,5,7,5,3,2,1,1,1,0,2,1,1,0,6,2,3,3,2,0,5,3,2,2,3,1,0,3,1,2,1,0,3,1,3,2,2,3,0,3,1,1,1,2,1,2,0,1,0,1,5,4,2,3,2,2,3,1,0,2,4,3,2,0,1,3,1,5,1,3,1,2,3,6,2,2,3,0,4,0,2,2,1,2,3,4,3,1,1,4,1,1,2,1,1,2,0,0,3,2,1,3,2,1,1,1,2,3,1,2,3,1,2,2,0,1,2,3,1,6,1,1,3,5,1,3,2,3,0,3,1,1,1,1,1,4,2,0,0,2,0,2,3,3,1,0,0,4,3,0,0,1,2,3,2,1,1,4,2,1,2,1,4,0,0,1,2,6,1,0,0,0,1,1,0,2,1,2,1,1,0,0,1,0,1,0,4,1,0,1,0,0,1,2,1,2,2,1,1,2,3,3,1,2,1,2,4,1,2,4,8, 12,6, 12, 12, 20, 16,8,7,2,9,2,1,2,1,5,1,1,1,1,3,0,3,2,2,2,0,2,1,1,3,0,1,0,1,1,0,1,3,2,2,1,1,1,1,1,2,0,2,2,2,0,1,0,1,2,2,1,4,2,3,1,1,2,1,1,2,0,0,1,1,2,0,3,1,1,0,1,1,4,2,1,1,2,3,0,0,2,4,1,4,1,0,1,0,2,3,0,1,1,2,1,1,1,3,0,4,2,1,1,4,1,1,2,1,1,1,1,0,1,3,4,2,1,4,2,3,1,2,0,2,0,1,2,2,0,2,0,4,2,2,2,4,1,0,2,3,2,0,0,1,2,0,1,1,2,3,2,1,4,0,0,0,6,0,0,1,0,2,2,1,0,0,1,2,1,5,3,3,4,0,3,0,2,0,1,0,1,5,2,2,2,1,1,0,4,1,1,0,2,2,0,2,2,0,2,1,2,2,1,1,1,1,1,3,0,1,0,0,0,3,2,5,1,0,0,1,1,0,1,3,2,0,0,2,5,0,2,0,2,2,2,0,1,0,0,0,0,0,0,0,0,1,3,1,2,0,0,2,1,1,0,1,1,0,0,1,3,2,1,2,3,1,1,1,1,5,3, 11, 14, 12, 14, 14, 10,8, 11,4,1,2,0,5,0,3,2,2,2,1,1,2,2,1,3,2,1,0,2,0,1,4,0,0,1,0,2,1,1,3,2,2,0,1,2,1,1,0,1,0,0,2,1,2,1,0,2,1,0,2,1,2,1,0,2,0,0,0,0,4,2,0,1,3,2,1,0,0,1,0,4,3,1,0,0,0,1,0,1,2,1,0,1,2,2,0,1,1,1,0,0,0,1,3,1,1,1,0,2,1,0,1,0,3,1,1,1,0,2,0,1,1,0,0,1,1,2,0,3,1,1,2,2,1,0,1,3,3,3,1,5,0,0,0,1,1,2,2,0,3,2,0,2,1,1,1,0,0,3,2,1,0,0,3,1,1,2,1,4,1,0,1,2,0,3,1,1,1,0,0,2,3,1,0,0,1,1,1,1,0,0,1,2,2,0,1,1,1,0,1,1,1,1,0,0,1,0,0,2,1,1,1,0,0,1,0,1,1,0,2,1,2,0,0,1,1,0,2,0,1,1,1,1,1,0,1,3,2,1,0,1,1,1,0,1,0,0,0,0,1,1,0,0,1,1,0,1,3,3,2,0,1,0,0,0,1,2,1,0,0,0,0,0,1,1,0,2,0,0,0,1,0,1,0,0,0,0,1,1,2,4,4,1,2,4,2, 11, 12,8, 11,8,7,9,3,3,4,1,1,2,0,0,1,2,0,3,0,0,0,1,0,2,3,0,1,1,1,0,3,0,0,0,1,2,2,2,3,1,3,2,0,3,1,2,0,2,1,3,0,2,0,1,0,0,1,1,0,2,0,1,1,1,1,2,1,2,1,2,4,0,0,1,1,2,2,1,2,3,3,7,8, 15, 18, 18, 20, 20, 14, 16, 13, 10,4,6,3,2,2,4,2,1,1,2,2,1,2,0,1,2,0,0,0,1,1,0,1,0,2,0,0,1,1,2,1,1,2,1,0,2,1,0,0,1,1,0,0,1,2,0,0,1,1,1,0,0,1,1,1,1,2,0,0,0,0,0,0,1,0,2,1,1,1,0,0,1,1,1,1,2,0,0,0,0,0,1,1,1,1,2,1,0,2,1,0,1,1,1,2,1,1,1,0,0,2,2,1,3,1,0,0,0,0,1,1,1,2,2,1,1,0,1,0,0,2,3,1,2,2,1,1,1,0,1,0,0,0,2,0,1,1,1,1,0,0,2,1,1,0,1,0,0,2,1,2,0,0,0,1,2,0,1,0,0,0,0,2,0,0,0,0,0,0,0,0,1,2,2,1,3,0,0,1,1,0,0,0,1,1,1,0,0,0,0,1,0,1,0,0,0,2,1,1,0,0,0,0,0,2,1,2,1,0,1,1,0,1,1,2,2,0,0,1,0,2,1,1,1,0,1,1,2,1,0,0,0,0,2,0,0,1,0,0,1,1,0,1,3,1,1,0,3,1,3,0,2,0,0,0,1,2,0,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1,0,0,0,0,3,0,1,0,0,2,0,0,0,0,0,0,0,2,0,0,1,2,0,1,0,0,0,0,3,2,1,1,0,0,1,1,2,1,0,1,1,1,1,0,0,2,0,2,0,0,1,2,4,0,0,0,0,1,2,1,0,1,1,2,1,1,0,1,0,1,0,1,0,0,1,1,1,0,2,0,0,2,1,0,0,0,0,1,1,0,2,2,1,0,1,1,2,0,0,0,0,0,0,0,1,2,2,0,0,1,0,1,0,1,1,0,0,0,0,2,1,0,1,3,1,1,1,1,1,0,0,0,2,0,3,0,1,1,0,0,0,1,0,0,1,1,0,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,1,0,0,1,0,0,1,3,3,1,1,1,1,1,2,1,0,0,2,1,0,1,0,0,0,1,0,0,0,0,2,1,1,1,1,1,1,1,1,0,0,0,0,1,3,0,0,0,2,2,1,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,3,0,2,0,0,0,1,2,0,0,2,1,1,1,0,2,0,2,1,0,0,0,0,0,0,0,1,0,2,0,0,0,0,1,0,1,0,2,1,1,0,1,2,1,0,1,0,0,1,1,0,4,3,4,3,2,2,1,2,3,3,2,3,2,2,1,2,0,0,1,1,0,0,1,0,2,0,2,0,1,1,1,0,0,0,1,0,2,0,0,0,0,0,2,0,1,1,0,1,1,0,1,1,1,0,1,1,0,2,0,0,0,0,1,1,1,0,1,0,1,0,2,1,0,0,0,2,1,0,1,0,1,0,0,2,0,1,1,1,0,0,0,0,0,0,3,1,0,1,1,1,0,1,1,2,0,1,1,0,1,0,2,1,2,0,1,0,1,4,1,0,0,1,0,0,0,2,0,0,1,1,1,1,1,4,1,1,1,1,0,1,0,1,1,0,1,0,0,1,0,0,2,1,1,1,2,0,2,0,1,1,1,4,2,0,0,2,0,0,1,0,0,1,0,1,1,0,2,0,0,0,1,1,1,1,1,1,1,0,1,0,0,1,1,1,0,1,0,0,2,1,2,3,2,0,2,0,2,1,1,0,0,1,0,1,2,0,1,1,1,0,1,0,1,0,1,2,0,1,0,1,0,1,2,0,1,1,0,0,0,1,1,1,0,1,1,1,0,0,0,1,1,0,0,2,1,1,0,1,1,0,0,0,1,0,2,1,0,2,2,3,1,0,1,0,1,0,0,0,1,4,4,0,4,0,2,2,2,0,2,1,0,0,1,0,1,1,1,0,0,1,1,0,0,0,2,1,0,1,0,0,0,1,1,1,0,1,2,2,2,0,0,2,2,1,0,0,0,0,2,1,1,1,1,1,1,1,0,0,2,1,0,0,0,2,2,1,1,1,1,0,0,2,1,0,0,2,0,0,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1,1,1,0,1,0,3,1,1,1,0,1,1,3,2,1,1,1,1,0,3,0,1,1,0,0,0,1,0,0,1,0,1,0,1,1,2,1,0,0,0,1,1,1,0,0,2,0,1,0,1,2,1,1,0,3,0,2,0,0,1,1,2,0,0,0,0,2,1,0,0,1,2,1,1,0,1,0,0,3,4,2,1,2,2,0,0,2,2,0,0,1,1,0,1,0,2,1,1,1,1,0,0,2,1,2,1,0,4,0,0,0,0,1,0,0,2,0,1,0,1,1,1,1,1,0,1,2,1,0,0,0,3,1,1,2,0,0,0,1,0,0,0,2,0,1,0,2,1,0,1,0,1,2,1,1,0,0,0,1,1,0,0,0,0,2,2,0,2,1,2,4,2,1,0,3,0,0,0,2,1,0,2,0,1,1,0,0,0,1,0,0,3,0,0,1,2,0,4,0,1,0,0,1,1,1,0,0,1,0,0,1,0,0,1,2,1,0,2,0,0,0,3,0,0,2,0,1,0,2,2,1,0,1,0,2,1,0,0,2,0,2,1,0,0,0,0,0,0,1,1,0,0,0,1,2,0,0,2,1,0,1,0,2,0,1,1,1,0,1,1,2,0,1,0,0,2,1,0,2,2,0,0,0,0,0,0,2,0,0,1,0,0,0,3,1,2,1,3,0,0,1,1,0,0,2,2,0,2,0,3,0,2,1,0,0,1,1,2,2,1,3,1,1,0,0,2,1,1,0,1,1,1,2,1,1,1,0,3,0,3,0,1,2,2,3,0,0,1,0,2,2,2,1,2,0,1,0,0,1,0,1,0,0,1,1,1,2,1,1,3,0,0,1,0,1,2,1,1,0,0,1,2,0,0,2,2,3,1,0,0,0,1,1,1,2,1,1,1,0,0,1,3,3,0,2,1,2,4,1,0,2,1,0,0,0,1,0,3,0,0,2,3,1,2,0,0,2,1,1,1,1,1,2,0,0,1,1,1,0,2,0,2,0,1,3,3,0,0,1,1,1,1,1,1,1,0,1,2,2,2,1,1,0,1,1,2,3,2,1,1,1,1,1,1,3,1,0,0,1,1,0,0,1,0,0,2,1,1,1,0,0,2,1,2,2,0,1,0,3,1,1,0,0,1,1,0,1,0,1,1,1,0,0,2,0,0,1,1,0,1,0,1,1,0,0,1,1,1,0,1,0,2,0,0,1,0,0,0,1,0,1,2,0,0,1,1,2,0,1,1,2,2,0,0,1,1,2,1,2,2,1,1,0,2,0,1,0,0,3,0,0,0,1,0,0,0,0,1,1,1,0,1,0,1,0,0,0,0,0,1,1,0,1,1,0,1,0,0,0,1,0,0,0,1,0,0,0,2,0,1,0,1,1,1,1,3,1,1,0,0,0,2,2,2,0,1,1,0,1,2,0,0,1,0,0,0,1,0,1,2,0,1,2,0,0,0,0,0,0,1,0,2,0,1,0,1,0,0,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,3,0,0,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,1,0,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,2,1,0,1,0,0,2,0,1,1,1,0,0,0,0,1,0,0,0,2,0,0,0,1,0,1,1,0,2,1,0,0,1,0,0,0,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,1,2,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,2,0,0,0,0,1,1,1,0,1,2,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,1,1,0,0,0,0,1,1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,2,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,0,1,0,1,0,1,0,2,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,2,0,0,1,1,0,2,1,1,1,1,1,1,0,0,0,1,0,2,0,1,0,1,2,1,0,2,5,4,4,8,9, 17, 16, 27, 24, 37, 38, 37, 39, 38, 39, 28, 16, 22, 10, 10,3,2,2,1,3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
|
|
w3 = pg.PlotWidget()
|
|
w3.enableAutoRange('xy', False)
|
|
w3.setXRange(0, len(data))
|
|
w3.hideAxis('left')
|
|
w3.hideAxis('bottom')
|
|
w3.setMouseEnabled(x=False, y=False)
|
|
w3.setLogMode(False, True)
|
|
lr = pg.LinearRegionItem([0,len(data)])
|
|
lr.setZValue(0)
|
|
w3.addItem(lr)
|
|
w3.plot(data)
|
|
d3.addWidget(w3)
|
|
|
|
|
|
# w4 = pg.PlotWidget()
|
|
# plt = w4.plot(data)
|
|
# w4.setXRange(0, len(data))
|
|
# w4.setMouseEnabled(y=False)
|
|
# w4.setAutoVisible(y=True)
|
|
# cursorLine = pg.InfiniteLine(angle=90, movable=True)
|
|
# w4.addItem(cursorLine)
|
|
|
|
# def updatePlot():
|
|
# global w3, w4
|
|
# w4.setXRange(*lr.getRegion(), padding=0)
|
|
# w4.enableAutoRange('y', True)
|
|
|
|
# def updateRegion():
|
|
# global w3, w4
|
|
# lr.setRegion(w4.getViewBox().viewRange()[0])
|
|
# w4.enableAutoRange('y', True)
|
|
|
|
# def mouseMoved(evt):
|
|
# global cursorLine, plt
|
|
# if type(evt) != QtCore.QPointF:
|
|
# return
|
|
# cursorLine.setPos(int(plt.mapFromScene(evt).x()))
|
|
|
|
# def mouseClicked(evt):
|
|
# return
|
|
# global cursorLine, plt
|
|
# if evt.button() == QtCore.Qt.MouseButton.LeftButton:
|
|
# pos = plt.mapFromScene(evt.scenePos())
|
|
# cursorLine.setPos(int(pos.x()))
|
|
|
|
# plt.scene().sigMouseMoved.connect(mouseMoved)
|
|
# plt.scene().sigMouseClicked.connect(mouseClicked)
|
|
# lr.sigRegionChanged.connect(updatePlot)
|
|
|
|
# w4.sigXRangeChanged.connect(updateRegion)
|
|
# w4.enableAutoRange('y', True)
|
|
|
|
# # for i in range(1):
|
|
# # w4.plot(range(2400,2500,1), data[2400:2500], fillLevel=0, brush=(255, 0, 0, 100))
|
|
|
|
# updatePlot()
|
|
# d4.addWidget(w4)
|
|
|
|
w5 = pg.GraphicsLayoutWidget()
|
|
label = pg.LabelItem(justify='left')
|
|
label.setText(f"Channel=?, Count=?")
|
|
w5.addItem(label, row=0, col=0)
|
|
|
|
plt = pg.PlotItem()
|
|
plt.plot(data)
|
|
w5.addItem(plt, row=1, col=0)
|
|
plt.setXRange(0, len(data))
|
|
plt.setMouseEnabled(y=False)
|
|
plt.setAutoVisible(y=True)
|
|
plt.showGrid(x=True, y=True)
|
|
|
|
cursorLine = pg.InfiniteLine(angle=90, movable=True)
|
|
plt.addItem(cursorLine)
|
|
|
|
def updatePlot():
|
|
global w3, plt
|
|
plt.setXRange(*lr.getRegion(), padding=0)
|
|
plt.enableAutoRange('y', True)
|
|
|
|
def updateRegion():
|
|
global w3, plt
|
|
lr.setRegion(plt.getViewBox().viewRange()[0])
|
|
plt.enableAutoRange('y', True)
|
|
|
|
def mouseClicked(evt):
|
|
return
|
|
global cursorLine, plt
|
|
if evt.button() == QtCore.Qt.MouseButton.LeftButton:
|
|
pos = plt.mapFromScene(evt.scenePos())
|
|
cursorLine.setPos(int(pos.x()))
|
|
|
|
def mouseMoved(evt):
|
|
global cursorLine, plt, label
|
|
if type(evt) != QtCore.QPointF:
|
|
return
|
|
cursorLine.setPos(int(plt.mapToView(evt).x()))
|
|
if int(plt.mapToView(evt).x()) >=0 and int(plt.mapToView(evt).x()) < len(data):
|
|
lbStr = f"<font color='green'><B>Channel={int(plt.mapToView(evt).x())}, Count={data[int(plt.mapToView(evt).x())]}</B></font>"
|
|
label.setText(lbStr)
|
|
|
|
ROIs = {}
|
|
currentROI = []
|
|
ROIPlotItems = {}
|
|
def markROI():
|
|
global ROIs, currentROI, cursorLine, tempStr, w2, ROIPlotItems, p
|
|
if len(currentROI) == 0:
|
|
currentROI.append(int(cursorLine.pos()[0]))
|
|
elif len(currentROI) == 1:
|
|
currentROI.append(int(cursorLine.pos()[0]))
|
|
lch = min(currentROI[0],currentROI[1])
|
|
rch = max(currentROI[0],currentROI[1])
|
|
currentROI = [lch, rch]
|
|
ROIs[f"ROI{lch}_{rch}"] = currentROI
|
|
tempDict = [{'name':'lChannel', 'type':'int', 'value':lch, 'removable':False, 'renamable':False, 'readonly':True},
|
|
{'name':'rChannel', 'type':'int', 'value':rch, 'removable':False, 'renamable':False, 'readonly':True},]
|
|
|
|
tempParameter = Parameter.create(name=f"ROI{lch}_{rch}", type='group', children=tempDict)
|
|
paramROIs = p.child('ROIs')
|
|
paramROIs.addChild(tempParameter,autoIncrementName=False)
|
|
p.removeChild(paramROIs)
|
|
p.addChild(paramROIs)
|
|
|
|
w2.setParameters(p, showTop=False)
|
|
tempStr = f"{nowStr()} Create new ROI: ({lch}, {rch})\n" + tempStr
|
|
textEdt.setText(tempStr)
|
|
ROIPlotItems[f"ROI{lch}_{rch}"] = plt.plot(range(lch, rch, 1), data[lch:rch], fillLevel=0, brush=(255, 0, 0, 100))
|
|
currentROI = []
|
|
|
|
def delROI():
|
|
global ROIs, currentROI, cursorLine, tempStr, w2, ROIPlotItems, p
|
|
pos = int(cursorLine.pos()[0])
|
|
error = len(data)
|
|
index = -1
|
|
for key, value in ROIs.items():
|
|
lch = value[0]
|
|
rch = value[1]
|
|
if pos >= lch and pos <= rch and rch - lch < error:
|
|
index = key
|
|
error = rch - lch
|
|
if index in ROIs:
|
|
optionalROI = ROIs[index]
|
|
tempStr = f"{nowStr()} Delete ROI: ({optionalROI[0]}, {optionalROI[1]})\n" + tempStr
|
|
textEdt.setText(tempStr)
|
|
ROIs.pop(index)
|
|
plt.removeItem(ROIPlotItems[index])
|
|
ROIPlotItems.pop(index)
|
|
paramROI = p.child("ROIs").child(f"ROI{optionalROI[0]}_{optionalROI[1]}")
|
|
p.child("ROIs").removeChild(paramROI)
|
|
w2.setParameters(p, showTop=False)
|
|
else:
|
|
pass
|
|
|
|
QShortcut(QKeySequence("Ctrl+Q"), w5).activated.connect(markROI)
|
|
QShortcut(QKeySequence("Ctrl+D"), w5).activated.connect(delROI)
|
|
plt.scene().sigMouseMoved.connect(mouseMoved)
|
|
plt.scene().sigMouseClicked.connect(mouseClicked)
|
|
lr.sigRegionChanged.connect(updatePlot)
|
|
plt.sigXRangeChanged.connect(updateRegion)
|
|
updatePlot()
|
|
d4.addWidget(w5)
|
|
|
|
tempStr = ''
|
|
# def update():
|
|
# global tempStr, textEdt
|
|
# # tempStr = f"{nowStr()}\n"+tempStr
|
|
# textEdt.setText(tempStr)
|
|
|
|
# timer = QtCore.QTimer()
|
|
# timer.timeout.connect(update)
|
|
# timer.start(1000)
|
|
|
|
win.show()
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pg.exec()
|