Skip to content

Commit

Permalink
enable nested docking
Browse files Browse the repository at this point in the history
  • Loading branch information
kklmn committed Mar 7, 2023
1 parent 89215a9 commit b55aef0
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 37 deletions.
3 changes: 2 additions & 1 deletion parseq/core/save_restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def load_project(fname, qMessageBox=None, restore_perspective=None):
configProject = config.ConfigParser()
configProject.optionxform = str # makes it case sensitive
try:
configProject.read(fname, encoding=encoding)
with open(fname) as f:
configProject.read_file(f)
except Exception as e:
if qMessageBox is None:
print("Invalid project file {0}\n{1}".format(fname, e))
Expand Down
3 changes: 2 additions & 1 deletion parseq/core/spectra.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ def check_shape(self):
sl = '0'
checkName = toNode.get_prop(stem, 'raw')
arr = getattr(self, checkName)
shape = arr.shape[eval(sl)]
shape = arr.shape[eval(sl)] if arr is not None else []
if iarr == 0:
shape0 = shape
continue
Expand Down Expand Up @@ -929,6 +929,7 @@ def read_file(self):
formatSection = 'Format_' + toNode.name
config.configLoad[formatSection] = dict(df)

arr = []
if self.dataType == cco.DATA_COLUMN_FILE:
header = cco.get_header(madeOf, df)
elif self.dataType == cco.DATA_DATASET:
Expand Down
6 changes: 4 additions & 2 deletions parseq/gui/mainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,14 +276,15 @@ def initTabs(self):
qt.QDockWidget.DockWidgetFloatable) # |
# qt.QDockWidget.DockWidgetVerticalTitleBar)
self.docks = {} # nodeWidget: (dock, node, tabName)
self.setDockNestingEnabled(True)
for i, (name, node) in enumerate(csi.nodes.items()):
tabName = u'{0} \u2013 {1}'.format(i+1, name)
dock = QDockWidgetNoClose(tabName, self)
dock.setAllowedAreas(qt.Qt.AllDockWidgetAreas)
dock.setFeatures(dockFeatures)
dock.defStyleSheet = "QDockWidget {font: bold; padding-left: 5px;}"
# dock.setStyleSheet(dock.defStyleSheet)
self.addDockWidget(qt.Qt.TopDockWidgetArea, dock)
self.addDockWidget(qt.Qt.LeftDockWidgetArea, dock)
nodeWidget = NodeWidget(node, dock)
# nodeWidget = None # for testing fo app closure
dock.setWidget(nodeWidget)
Expand Down Expand Up @@ -439,7 +440,8 @@ def setTabIcons(self):

def setTabIcon(self, itab, dock, state=0):
icon = dock.dimIconBusy if state == 1 else dock.dimIcon
self.tabWidget.setTabIcon(itab, icon)
if self.tabWidget is not None:
self.tabWidget.setTabIcon(itab, icon)

def dataChanged(self):
for node in csi.nodes.values():
Expand Down
3 changes: 2 additions & 1 deletion parseq/gui/nodeWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def __init__(self, text, parent, isVertical=False,
super().__init__(text, parent)
self.rawText = str(text)
self.isVertical = isVertical
fontSize = "10" if sys.platform == "darwin" else "7.7"
fontSize = "10" if sys.platform == "darwin" else "8.5" \
if sys.platform == "linux" else "8"
grad = "x1: 0, y1: 0, x2: 0, y2: 1"
bottomMargin = '-1' if isVertical else '-3'
self.setStyleSheet("""
Expand Down
63 changes: 46 additions & 17 deletions parseq/gui/roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,8 @@ def updateCounts(self):
if self.dataToCount is None:
return
data = self.dataToCount
if data is None: # when data file is missing
return
rois = self.roiManager.getRois()
if len(rois) == 0:
return
Expand Down Expand Up @@ -871,7 +873,11 @@ def createRoi(self, vmin=None, vmax=None):
if hasattr(self, 'visibleCB'):
self.roi.setVisible(self.visibleCB.isChecked())
if vmin is None or vmax is None:
vmin, vmax = self.defaultRange
if callable(self.defaultRange):
defRange = self.defaultRange()
else:
defRange = self.defaultRange
vmin, vmax = defRange
ran = self.convert(1, vmin, vmax)
if ran is None:
return
Expand Down Expand Up @@ -908,14 +914,20 @@ def convert(self, direction, vmin, vmax):


class RangeWidget(RangeWidgetBase):
def __init__(self, parent, plot, caption, suffix, rangeName, color,
def __init__(self, parent, plot, caption, tooltip, rangeName, color,
formatStr, defaultRange):
"""
*defaultRange*: callable or 2-sequence
"""
super().__init__(parent)
self.plot = plot
self.is3dStack = hasattr(plot, '_plot')
self.formatStr = formatStr
self.defaultRange = list(defaultRange)
self.suffix = suffix
if callable(defaultRange):
self.defaultRange = defaultRange
else:
self.defaultRange = list(defaultRange)
self.tooltip = tooltip
self.rangeName = rangeName
self.roiManager = None
self.roi = None
Expand All @@ -931,20 +943,22 @@ def __init__(self, parent, plot, caption, suffix, rangeName, color,
layoutP.setContentsMargins(10, 0, 0, 0)
self.rbAuto = qt.QRadioButton('auto', panel)
self.rbAuto.clicked.connect(self.setAutoRange)
if self.defaultRange:
fs = "[" + self.formatStr + "] as {1}"
self.rbAuto.setToolTip(fs.format(self.defaultRange, suffix))
if not callable(self.defaultRange):
fs = "[" + self.formatStr + "]{1}{2}"
self.rbAuto.setToolTip(fs.format(
self.defaultRange, ' as ' if tooltip else '', tooltip))
layoutP.addWidget(self.rbAuto)
self.rbCustom = qt.QRadioButton('custom', panel)
self.rbCustom.setStyleSheet("QRadioButton{color: " + color + ";}")
self.rbCustom.clicked.connect(self.setCustomRange)
layoutP.addWidget(self.rbCustom)
self.editCustom = qt.QLineEdit()
self.editCustom.setStyleSheet("QLineEdit{color: " + color + ";}")
self.editSetText(self.defaultRange)
if not callable(self.defaultRange):
self.editSetText(self.defaultRange)
layoutP.addWidget(self.editCustom)
if suffix:
self.editCustom.setToolTip(suffix)
if tooltip:
self.editCustom.setToolTip(tooltip)
panel.setLayout(layoutP)
layout.addWidget(panel)
self.setLayout(layout)
Expand All @@ -964,16 +978,24 @@ def setRange(self, ran):
if len(ran) == 2:
self.editSetText(ran)
self.createRoi(*ran)
isDefault = np.allclose(ran, self.defaultRange)
if callable(self.defaultRange):
defRange = self.defaultRange()
else:
defRange = self.defaultRange
isDefault = np.allclose(ran, defRange)
self.rbAuto.setChecked(isDefault)
self.rbCustom.setChecked(not isDefault)
self.roi.setVisible(not isDefault)

def setAutoRange(self):
if callable(self.defaultRange):
defRange = self.defaultRange()
else:
defRange = self.defaultRange
if self.roi is not None:
self.setRange(self.defaultRange)
self.rangeChanged.emit(self.defaultRange)
self.editSetText(self.defaultRange)
self.setRange(defRange)
self.rangeChanged.emit(defRange)
self.editSetText(defRange)
self.rbAuto.setChecked(True)
self.rbCustom.setChecked(False)

Expand Down Expand Up @@ -1017,7 +1039,10 @@ def __init__(self, parent, plot, var, optionsMin, optionsMax, rangeName,
self.roiManager = None
self.roi = None
self.color = color
self.defaultRange = defaultRange
if callable(defaultRange):
self.defaultRange = defaultRange
else:
self.defaultRange = list(defaultRange)
minLabelTxt, maxLabelTxt = var[0:2]
if 'min' in minLabelTxt:
self.roiClass = HorizontalRangeROI
Expand Down Expand Up @@ -1088,11 +1113,15 @@ def setRange(self, ran):
return
if len(ran) == 2:
if ran[0] is None or ran[1] is None:
if callable(self.defaultRange):
defRange = self.defaultRange()
else:
defRange = self.defaultRange
if self.roiClass == HorizontalRangeROI:
vmin = self.defaultRange[0]
vmin = defRange[0]
vmax = self.maxSpinBox.minimum() # special value
elif self.roiClass == CrossROI:
vmin, vmax = self.defaultRange
vmin, vmax = defRange
self.minSpinBox.blockSignals(True)
self.maxSpinBox.blockSignals(True)
self.minSpinBox.setValue(vmin if ran[0] is None else ran[0])
Expand Down
4 changes: 2 additions & 2 deletions parseq/help/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
# built documents.
#
# The short X.Y version.
version = '0.9.9'
version = '0.9.91'
# The full version, including alpha/beta/rc tags.
release = '0.9.9'
release = '0.9.91'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
8 changes: 4 additions & 4 deletions parseq/help/top.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Main features
(parts of analysis pipeline).

- Two ways of acting from GUI onto multiple data: (a) simultaneous work with
multiply selected data and (b) applying a specific parameter or a group of
parameters to a later selected subset of data.
multiply selected data and (b) copying a specific parameter or a group of
parameters from active data items to later selected data items.

- Undo and redo for most of treatment steps.

Expand All @@ -69,8 +69,8 @@ Main features
type and location of the occurred error.

- Export of the workflow into a project file. Export of data into various data
formats (so far unstructured) with accompanied Python scripts that visualize
the exported data for the user to tune their publication plots.
formats with accompanied Python scripts that visualize the exported data for
the user to tune their publication plots.

- ParSeq understands container files (presently only hdf5) and adds them to
the system file tree as subfolders. The file tree, including hdf5
Expand Down
6 changes: 4 additions & 2 deletions parseq/utils/ft.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ def make_ft_window(kind, x, xmin, xmax, width, vmin):
res = np.ones_like(x)
if not kind or kind == 'none':
return res
res[x < xmin] = 0
res[x > xmax] = 0
if kind == 'box':
res[x < xmin] = 0
res[x > xmax] = 0
return res

left_lobe = (x-xmin >= 0) & (x-xmin <= width)
Expand All @@ -55,4 +55,6 @@ def make_ft_window(kind, x, xmin, xmax, width, vmin):
sigma2 = width**2 / (2*abs(np.log(v0)))
res[left_lobe] = np.exp(-0.5*(x[left_lobe]-xmin-width)**2/sigma2)
res[right_lobe] = np.exp(-0.5*(xmax-width-x[right_lobe])**2/sigma2)
res[x < xmin] = res[left_lobe][0]
res[x > xmax] = res[right_lobe][-1]
return res
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
(parts of analysis pipeline).
- Two ways of acting from GUI onto multiple data: (a) simultaneous work with
multiply selected data and (b) applying a specific parameter or a group of
parameters to a later selected subset of data.
multiply selected data and (b) copying a specific parameter or a group of
parameters from active data items to later selected data items.
- Undo and redo for most of treatment steps.
Expand All @@ -52,8 +52,8 @@
type and location of the occurred error.
- Export of the workflow into a project file. Export of data into various data
formats (so far unstructured) with accompanied Python scripts that visualize
the exported data for the user to tune their publication plots.
formats with accompanied Python scripts that visualize the exported data for
the user to tune their publication plots.
- ParSeq understands container files (presently only hdf5) and adds them to
the system file tree as subfolders. The file tree, including hdf5
Expand Down Expand Up @@ -98,7 +98,7 @@

setup(
name='parseq',
version='0.9.2',
version='0.9.91',
description='ParSeq is a python software library for Parallel execution of'
' Sequential data analysis.',
long_description=long_description,
Expand Down
4 changes: 2 additions & 2 deletions version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
__versioninfo__ = (0, 9, 2)
__versioninfo__ = (0, 9, 91)
__version__ = '.'.join(map(str, __versioninfo__))
__date__ = "26 Feb 2023"
__date__ = "7 Mar 2023"

0 comments on commit b55aef0

Please sign in to comment.