add flag for partial fits; closes #83

This commit is contained in:
Dominik Demuth 2023-07-12 20:48:28 +02:00
parent 33afc2ca94
commit 76cd4acfb0
13 changed files with 132 additions and 88 deletions

View File

@ -33,6 +33,7 @@ class ExperimentContainer(QtCore.QObject):
self.id = str(identifier) self.id = str(identifier)
self._fits = [] self._fits = []
self._relations = kwargs.get('relations', {})
self._data = data self._data = data
self._manager = kwargs.get('manager') self._manager = kwargs.get('manager')
self.graph = '' self.graph = ''
@ -228,6 +229,8 @@ class ExperimentContainer(QtCore.QObject):
return self.plot_real, self.plot_imag, self.plot_error return self.plot_real, self.plot_imag, self.plot_error
def get_state(self): def get_state(self):
# TODO preserve relationships
ret_dic = { ret_dic = {
'id': self.id, 'id': self.id,
'data': self._data.get_state(), 'data': self._data.get_state(),
@ -269,6 +272,32 @@ class ExperimentContainer(QtCore.QObject):
else: else:
self._fits.extend(value) self._fits.extend(value)
def has_relation(self, relation_type):
return relation_type in self._relations
def get_relation(self, relation_type: int):
return self._relations.get(relation_type, [])
def add_relation(self, relation_type: int, value: str):
if relation_type not in self._relations:
self._relations[relation_type] = []
self._relations[relation_type].append(value)
def remove_relation(self, relation_type: int, value: str):
if relation_type not in self._relations:
raise ValueError(f'Relationship {relation_type!r} with id {value!r} doe not exist for {self.name}')
related_id_value = self._relations[relation_type]
idx = related_id_value.index(value)
if idx == -1:
raise ValueError(f'Relationship {relation_type!r} with id {value!r} doe not exist for {self.name}')
related_id_value.pop(idx)
if len(related_id_value) == 0:
self._relations.pop(relation_type)
def _update_actions(self): def _update_actions(self):
self.actions.update({'sort': self._data.sort, self.actions.update({'sort': self._data.sort,
'cut': self._data.cut, 'cut': self._data.cut,

View File

@ -5,7 +5,7 @@ from nmreval.lib.colors import available_cycles
from .properties import PropWidget from .properties import PropWidget
from ...Qt import QtWidgets, QtGui, QtCore from ...Qt import QtWidgets, QtGui, QtCore
from ..._py.datawidget import Ui_DataWidget from ..._py.datawidget import Ui_DataWidget
from ...lib import make_action_icons from ...lib.iconloading import make_action_icons
from ...lib.delegates import HeaderDelegate from ...lib.delegates import HeaderDelegate

View File

@ -5,7 +5,7 @@ from nmreval.utils.text import convert
from ..Qt import QtCore, QtWidgets, QtGui from ..Qt import QtCore, QtWidgets, QtGui
from .._py.fitmodelwidget import Ui_FitParameter from .._py.fitmodelwidget import Ui_FitParameter
from .._py.save_fitmodel_dialog import Ui_SaveDialog from .._py.save_fitmodel_dialog import Ui_SaveDialog
from ..lib import get_icon from ..lib.iconloading import get_icon
class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter): class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter):

View File

@ -8,7 +8,7 @@ from nmreval.lib.importer import find_models
from nmreval.lib.colors import BaseColor, Tab10 from nmreval.lib.colors import BaseColor, Tab10
from nmreval.utils.text import convert from nmreval.utils.text import convert
from ..lib import get_icon from ..lib.iconloading import get_icon
from .._py.fitfunctionwidget import Ui_Form from .._py.fitfunctionwidget import Ui_Form
from ..Qt import QtWidgets, QtCore, QtGui from ..Qt import QtWidgets, QtCore, QtGui

View File

@ -13,6 +13,7 @@ from nmreval.fit.result import FitResult
from .fit_forms import FitTableWidget from .fit_forms import FitTableWidget
from .fit_parameter import QFitParameterWidget from .fit_parameter import QFitParameterWidget
from ..lib import Relations
from ..lib.pg_objects import PlotItem from ..lib.pg_objects import PlotItem
from ..Qt import QtGui, QtCore, QtWidgets from ..Qt import QtGui, QtCore, QtWidgets
from .._py.fitdialog import Ui_FitDialog from .._py.fitdialog import Ui_FitDialog
@ -147,7 +148,7 @@ class QFitDialog(QtWidgets.QWidget, Ui_FitDialog):
# deselect all fit sets # deselect all fit sets
for i in range(self.data_table.rowCount()): for i in range(self.data_table.rowCount()):
data_id = self.data_table.item(i, 0).data(QtCore.Qt.UserRole+1) data_id = self.data_table.item(i, 0).data(QtCore.Qt.UserRole+1)
if self._management[data_id].mode == 'fit': if self._management[data_id].mode == 'fit' or self._management[data_id].has_relation(Relations.isFitPartOf):
self.data_table.item(i, 0).setCheckState(QtCore.Qt.Unchecked) self.data_table.item(i, 0).setCheckState(QtCore.Qt.Unchecked)
if self.models: if self.models:

View File

@ -18,7 +18,7 @@ from ..io.filedialog import FileDialog
from ..lib.pg_objects import LegendItemBlock, RegionItem from ..lib.pg_objects import LegendItemBlock, RegionItem
from ..Qt import QtCore, QtWidgets, QtGui from ..Qt import QtCore, QtWidgets, QtGui
from .._py.graph import Ui_GraphWindow from .._py.graph import Ui_GraphWindow
from ..lib import make_action_icons from ..lib.iconloading import make_action_icons
from ..lib.configurations import GraceMsgBox from ..lib.configurations import GraceMsgBox

View File

@ -1,80 +1 @@
import sys from .enums import Relations
if sys.version_info < (3, 7):
HAS_IMPORTLIB_RESOURCE = False
from pkg_resources import resource_filename
else:
HAS_IMPORTLIB_RESOURCE = True
from importlib.resources import path
from ..Qt import QtGui, QtWidgets
# def get_path_importlib(package, resource):
# return path(package, resource)
#
#
# def _get_path_pkg(package, resource):
# return resource_filename(package, resource)
#
#
# if HAS_IMPORTLIB_RESOURCE:
# get_path = get_path_importlib
# else:
# get_path = _get_path_pkg
def make_action_icons(widget):
global HAS_IMPORTLIB_RESOURCE
icon_type = QtWidgets.QApplication.instance().theme
from json import loads
if HAS_IMPORTLIB_RESOURCE:
with path('resources.icons', 'icons.json') as fp:
with fp.open('r') as f:
icon_list = loads(f.read())
for ac, img in icon_list[widget.objectName()].items():
dirname = 'resources.icons.%s_light' % icon_type
with path(dirname, img+'.png') as imgpath:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
getattr(widget, ac).setIcon(icon)
else:
with open(resource_filename('resources.icons', 'icons.json'), 'r') as f:
icon_list = loads(f.read())
for ac, img in icon_list[widget.objectName()].items():
dirname = 'resources.icons.%s_light' % icon_type
imgpath = resource_filename(dirname, img+'.png')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
getattr(widget, ac).setIcon(icon)
def get_icon(icon_name):
try:
icon_type = QtWidgets.QApplication.instance().theme
except AttributeError:
icon_type = 'normal'
global HAS_IMPORTLIB_RESOURCE
if icon_name != 'logo':
dirname = f'resources.icons.{icon_type}_light'
else:
dirname = 'resources.icons'
if HAS_IMPORTLIB_RESOURCE:
with path(dirname, icon_name+'.png') as imgpath:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
return icon
else:
imgpath = resource_filename(dirname, icon_name+'.png')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(imgpath), QtGui.QIcon.Normal, QtGui.QIcon.Off)
return icon

8
src/gui_qt/lib/enums.py Normal file
View File

@ -0,0 +1,8 @@
from enum import IntEnum, auto
class Relations(IntEnum):
isFitOf = auto()
hasFit = auto()
isFitPartOf = auto()
hasFitPart = auto()

View File

@ -0,0 +1,66 @@
import sys
if sys.version_info < (3, 7):
HAS_IMPORTLIB_RESOURCE = False
from pkg_resources import resource_filename
else:
HAS_IMPORTLIB_RESOURCE = True
from importlib.resources import path
from ..Qt import QtGui, QtWidgets
def make_action_icons(widget):
global HAS_IMPORTLIB_RESOURCE
icon_type = QtWidgets.QApplication.instance().theme
from json import loads
if HAS_IMPORTLIB_RESOURCE:
with path('resources.icons', 'icons.json') as fp:
with fp.open('r') as f:
icon_list = loads(f.read())
for ac, img in icon_list[widget.objectName()].items():
dirname = 'resources.icons.%s_light' % icon_type
with path(dirname, img+'.png') as imgpath:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
getattr(widget, ac).setIcon(icon)
else:
with open(resource_filename('resources.icons', 'icons.json'), 'r') as f:
icon_list = loads(f.read())
for ac, img in icon_list[widget.objectName()].items():
dirname = 'resources.icons.%s_light' % icon_type
imgpath = resource_filename(dirname, img+'.png')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
getattr(widget, ac).setIcon(icon)
def get_icon(icon_name):
try:
icon_type = QtWidgets.QApplication.instance().theme
except AttributeError:
icon_type = 'normal'
global HAS_IMPORTLIB_RESOURCE
if icon_name != 'logo':
dirname = f'resources.icons.{icon_type}_light'
else:
dirname = 'resources.icons'
if HAS_IMPORTLIB_RESOURCE:
with path(dirname, icon_name+'.png') as imgpath:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(str(imgpath)), QtGui.QIcon.Normal, QtGui.QIcon.Off)
return icon
else:
imgpath = resource_filename(dirname, icon_name+'.png')
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(imgpath), QtGui.QIcon.Normal, QtGui.QIcon.Off)
return icon

View File

@ -1,4 +1,4 @@
from . import HAS_IMPORTLIB_RESOURCE from .iconloading import HAS_IMPORTLIB_RESOURCE
from ..Qt import QtGui, QtWidgets, QtCore from ..Qt import QtGui, QtWidgets, QtCore

View File

@ -4,6 +4,7 @@ import copy
from numpy import argsort from numpy import argsort
from . import Relations
from ..Qt import QtWidgets, QtCore from ..Qt import QtWidgets, QtCore
from ..data.container import FitContainer from ..data.container import FitContainer
from ..graphs.graphwindow import QGraphWindow from ..graphs.graphwindow import QGraphWindow
@ -242,7 +243,14 @@ class DeleteCommand(QtWidgets.QUndoCommand):
if isinstance(val, FitContainer): if isinstance(val, FitContainer):
try: try:
self.__container[sid].fitted_key._fits.remove(sid) self.__container[val.fitted_key]._fits.remove(sid)
except KeyError:
pass
for (flag1, flag2) in ((Relations.isFitPartOf, Relations.hasFitPart), (Relations.hasFitPart, Relations.isFitPartOf)):
for related_item in val.get_relation(flag1):
try:
self.__container[related_item].remove_relation(flag2, sid)
except KeyError: except KeyError:
pass pass
@ -264,6 +272,13 @@ class DeleteCommand(QtWidgets.QUndoCommand):
except KeyError: except KeyError:
pass pass
for (flag1, flag2) in (('isFitPartOf', 'hasFitPartOf'), ('hasFitPartOf', 'isFitPartOf')):
for related_item in val.get_relation(flag1):
try:
self.__container[related_item].add_relation(flag2, sid)
except KeyError:
pass
self.__signal_add.emit(list(self.__keys), self.__graph_key) self.__signal_add.emit(list(self.__keys), self.__graph_key)
self.__graph_container[self.__graph_key].block(False) self.__graph_container[self.__graph_key].block(False)

View File

@ -22,7 +22,7 @@ from ..graphs.graphwindow import QGraphWindow
from ..graphs.movedialog import QMover from ..graphs.movedialog import QMover
from ..io.fcbatchreader import QFCReader from ..io.fcbatchreader import QFCReader
from ..io.filedialog import * from ..io.filedialog import *
from ..lib import get_icon, make_action_icons from ..lib.iconloading import make_action_icons, get_icon
from ..lib.pg_objects import RegionItem from ..lib.pg_objects import RegionItem
from ..lib.starter import make_starter from ..lib.starter import make_starter
from ..math.binning import BinningWindow from ..math.binning import BinningWindow

View File

@ -18,6 +18,7 @@ from nmreval.math.smooth import smooth
from nmreval.nmr.relaxation import Relaxation from nmreval.nmr.relaxation import Relaxation
from ..Qt import QtCore, QtWidgets from ..Qt import QtCore, QtWidgets
from ..lib import Relations
from ..lib.undos import * from ..lib.undos import *
from ..data.container import * from ..data.container import *
from ..io.filereaders import QFileReader from ..io.filereaders import QFileReader
@ -585,6 +586,9 @@ class UpperManagement(QtCore.QObject):
subfunc.name += data_name subfunc.name += data_name
sub_f_id = self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No) sub_f_id = self.add(subfunc, color=col, linestyle=LineStyle.Dashed, symbol=SymbolStyle.No)
self[sub_f_id].add_relation(Relations.isFitPartOf, f_id)
self[f_id].add_relation(Relations.hasFitPart, sub_f_id)
f_id_list.append(sub_f_id) f_id_list.append(sub_f_id)
gid = data_k.graph gid = data_k.graph
self.delete_sets(tobedeleted) self.delete_sets(tobedeleted)