model of DCN pyramidal neuron
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

131 lines
4.4 KiB

# -*- coding: utf-8 -*-
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.pgcollections import OrderedDict
from .TableWidget import TableWidget
from pyqtgraph.python2_3 import asUnicode
import types, traceback
import numpy as np
try:
import metaarray
HAVE_METAARRAY = True
except:
HAVE_METAARRAY = False
__all__ = ["DataTreeWidget"]
class DataTreeWidget(QtGui.QTreeWidget):
"""
Widget for displaying hierarchical python data structures
(eg, nested dicts, lists, and arrays)
"""
def __init__(self, parent=None, data=None):
QtGui.QTreeWidget.__init__(self, parent)
self.setVerticalScrollMode(self.ScrollPerPixel)
self.setData(data)
self.setColumnCount(3)
self.setHeaderLabels(["key / index", "type", "value"])
self.setAlternatingRowColors(True)
def setData(self, data, hideRoot=False):
"""data should be a dictionary."""
self.clear()
self.widgets = []
self.nodes = {}
self.buildTree(data, self.invisibleRootItem(), hideRoot=hideRoot)
self.expandToDepth(3)
self.resizeColumnToContents(0)
def buildTree(self, data, parent, name="", hideRoot=False, path=()):
if hideRoot:
node = parent
else:
node = QtGui.QTreeWidgetItem([name, "", ""])
parent.addChild(node)
# record the path to the node so it can be retrieved later
# (this is used by DiffTreeWidget)
self.nodes[path] = node
typeStr, desc, childs, widget = self.parse(data)
node.setText(1, typeStr)
node.setText(2, desc)
# Truncate description and add text box if needed
if len(desc) > 100:
desc = desc[:97] + "..."
if widget is None:
widget = QtGui.QPlainTextEdit(asUnicode(data))
widget.setMaximumHeight(200)
widget.setReadOnly(True)
# Add widget to new subnode
if widget is not None:
self.widgets.append(widget)
subnode = QtGui.QTreeWidgetItem(["", "", ""])
node.addChild(subnode)
self.setItemWidget(subnode, 0, widget)
self.setFirstItemColumnSpanned(subnode, True)
# recurse to children
for key, data in childs.items():
self.buildTree(data, node, asUnicode(key), path=path + (key,))
def parse(self, data):
"""
Given any python object, return:
* type
* a short string representation
* a dict of sub-objects to be parsed
* optional widget to display as sub-node
"""
# defaults for all objects
typeStr = type(data).__name__
if typeStr == "instance":
typeStr += ": " + data.__class__.__name__
widget = None
desc = ""
childs = {}
# type-specific changes
if isinstance(data, dict):
desc = "length=%d" % len(data)
if isinstance(data, OrderedDict):
childs = data
else:
childs = OrderedDict(sorted(data.items()))
elif isinstance(data, (list, tuple)):
desc = "length=%d" % len(data)
childs = OrderedDict(enumerate(data))
elif HAVE_METAARRAY and (
hasattr(data, "implements") and data.implements("MetaArray")
):
childs = OrderedDict(
[("data", data.view(np.ndarray)), ("meta", data.infoCopy())]
)
elif isinstance(data, np.ndarray):
desc = "shape=%s dtype=%s" % (data.shape, data.dtype)
table = TableWidget()
table.setData(data)
table.setMaximumHeight(200)
widget = table
elif isinstance(
data, types.TracebackType
): ## convert traceback to a list of strings
frames = list(
map(str.strip, traceback.format_list(traceback.extract_tb(data)))
)
# childs = OrderedDict([
# (i, {'file': child[0], 'line': child[1], 'function': child[2], 'code': child[3]})
# for i, child in enumerate(frames)])
# childs = OrderedDict([(i, ch) for i,ch in enumerate(frames)])
widget = QtGui.QPlainTextEdit(asUnicode("\n".join(frames)))
widget.setMaximumHeight(200)
widget.setReadOnly(True)
else:
desc = asUnicode(data)
return typeStr, desc, childs, widget