BUGFIX: VFT;

change to src layout
This commit is contained in:
dominik 2022-10-20 17:23:15 +02:00
parent 89ce4bab9f
commit 8d148b639b
445 changed files with 1387 additions and 1920 deletions

View File

@ -2,7 +2,7 @@
import sys import sys
import pathlib import pathlib
sys.path.append(str(pathlib.Path().cwd().parent)) sys.path.append(str(pathlib.Path(__file__).parent.parent / 'src'))
from nmreval.configs import check_for_config from nmreval.configs import check_for_config
@ -15,8 +15,8 @@ check_for_config()
from nmreval.lib.logger import handle_exception from nmreval.lib.logger import handle_exception
sys.excepthook = handle_exception sys.excepthook = handle_exception
from nmreval.gui_qt import App from gui_qt import App
from nmreval.gui_qt.main.mainwindow import NMRMainWindow from gui_qt.main.mainwindow import NMRMainWindow
app = App([]) app = App([])

View File

@ -4,7 +4,7 @@
# You can set these variables from the command line, and also # You can set these variables from the command line, and also
# from the environment for the first two. # from the environment for the first two.
SPHINXOPTS ?= SPHINXOPTS ?=
SPHINXBUILD ?= /autohome/dominik/miniconda3/bin/sphinx-build SPHINXBUILD ?= # /autohome/dominik/miniconda3/bin/sphinx-build
SOURCEDIR = /autohome/dominik/nmreval/doc/source SOURCEDIR = /autohome/dominik/nmreval/doc/source
BUILDDIR = /autohome/dominik/nmreval/doc/_build BUILDDIR = /autohome/dominik/nmreval/doc/_build

View File

@ -1,16 +1,9 @@
""" """
========== ================================
T1 minimum Example of apodization functions
========== ================================
``RelaxationEvaluation`` is used to get width parameter from a T1 minimum. This file
As a subclass of ``Relaxation`` it can also be used to calculate Relaxation times.
The basic steps are:
* Determine a T1 minimum with `nmreval.nmr.RelaxationEvaluation.calculate_t1_min`
* Calculate width parameter of a spectral density/coupling constants/... with
``RelaxationEvaluation.get_increase``
* Calculate correlation times from these values with ``RelaxationEvaluation.correlation_from_t1``
""" """
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

@ -3,25 +3,36 @@
.. currentmodule:: {{ module }} .. currentmodule:: {{ module }}
.. autoclass:: {{ objname }} .. autoclass:: {{ objname }}
:exclude-members: {% for item in methods %}{%- if not item.startswith('_') or item in ['__call__'] %}{{ item }}, {% endif %}{%- endfor %}
{% block methods %} {%- block methods %}
{% if methods %} {% if methods %}
.. rubric:: {{ _('Methods') }} .. rubric:: Methods
{% for item in methods %}
.. automethod:: {{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
{% block attributes %}
{% if attributes %}
.. rubric:: {{ _('Attributes') }}
.. autosummary:: .. autosummary::
{% for item in attributes %} :toctree:
~{{ name }}.{{ item }}
{%- endfor %} {% for item in methods %}
{%- if not item.startswith('_') or item in ['__call__'] %} ~{{ name }}.{{ item }}
{% endif %} {% endif %}
{% endblock %} {%- endfor %}
{%- endif %}
{%- endblock %}
{%- block attributes %}
{%- if attributes %}
.. rubric:: Properties
.. autosummary::
:toctree:
{% for item in attributes %}
{%- if not item.startswith('_') or item in ['__call__'] %} ~{{ name }}.{{ item }}
{% endif %}
{%- endfor %}
{%- endif %}
{%- endblock %}
.. _sphx_glr_backref_{{ fullname }}:
.. minigallery:: {{ objname }}
:add-heading:

View File

@ -1,5 +1,2 @@
.. automodule:: nmreval.distributions .. automodule:: nmreval.distributions
:members: :members:
:inherited-members:
:undoc-members:

View File

@ -11,3 +11,4 @@ Reference
models models
distributions distributions
nmr nmr
math

View File

@ -12,7 +12,7 @@
# #
import os import os
import sys import sys
sys.path.append('/autohome/dominik/nmreval') sys.path.append(os.path.abspath('../../src'))
import nmreval import nmreval
@ -43,6 +43,9 @@ extensions = [
'sphinx.ext.viewcode', 'sphinx.ext.viewcode',
'sphinx.ext.intersphinx', 'sphinx.ext.intersphinx',
'sphinx_gallery.gen_gallery', 'sphinx_gallery.gen_gallery',
'sphinx.ext.todo',
'sphinx.ext.autosectionlabel',
'sphinx.ext.mathjax',
] ]
# configuration for intersphinx # configuration for intersphinx
@ -56,7 +59,7 @@ intersphinx_mapping = {
# # autodoc options # # autodoc options
autodoc_typehints = 'none' autodoc_typehints = 'none'
autodoc_class_signature = 'separated' # autodoc_class_signature = 'separated'
autoclass_content = 'class' autoclass_content = 'class'
autodoc_member_order = 'groupwise' autodoc_member_order = 'groupwise'
# #
@ -79,6 +82,7 @@ sphinx_gallery_conf = {
'min_reported_time': 10000000000, 'min_reported_time': 10000000000,
'show_memory': False, 'show_memory': False,
'show_signature': False, 'show_signature': False,
'line_numbers': True,
} }
# The suffix(es) of source filenames. # The suffix(es) of source filenames.
@ -151,15 +155,23 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for # The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes. # a list of builtin themes.
# #
html_theme = 'pydata_sphinx_theme' html_theme = 'sphinx_material' # 'sphinx_rtd_theme' # 'pydata_sphinx_theme'
# Theme options are theme-specific and customize the look and feel of a theme # Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the # further. For a list of options available for each theme, see the
# documentation. # documentation.
html_theme_options = { html_theme_options = {
'collapse_navigation': False, 'nav_title': 'nmreval',
'show_prev_next': False, # 'base_url': 'https://chaos3.fkp.physik.tu-darmstadt.de/source/nmreval',
'navbar_end': ['navbar-icon-links.html', 'search-field.html'], 'repo_url': 'https://chaos3.fkp.physik.tu-darmstadt.de/source/nmreval',
'repo_name': 'Repo',
'html_minify': True,
'css_minify': True,
'master_doc': False,
'globaltoc_depth': 3,
'globaltoc_collapse': True,
'globaltoc_includehidden': True,
'heroes': {'index': 'Fun for the whole family!!!!'}
} }
# Add any paths that contain custom themes here, relative to this directory. # Add any paths that contain custom themes here, relative to this directory.
@ -183,10 +195,10 @@ html_static_path = ['_static']
html_logo = '_static/logo.png' html_logo = '_static/logo.png'
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
html_sidebars = {'**': ['sidebar-nav-bs.html']} html_sidebars = {
# html_sidebars = { "**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]
# '**': ['localtoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'], }
# }
# If true, links to the reST sources are added to the pages. # If true, links to the reST sources are added to the pages.
html_show_sourcelink = False html_show_sourcelink = False
@ -205,7 +217,7 @@ html_last_updated_fmt = ''
html_additional_pages = {} html_additional_pages = {}
# If false, no module index is generated. # If false, no module index is generated.
html_domain_indices = False html_domain_indices = True
# If false, no index is generated. # If false, no index is generated.
html_use_index = True html_use_index = True
@ -214,10 +226,10 @@ html_use_index = True
html_split_index = False html_split_index = False
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will # If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the # contain a <link> tag referring to it. The value of this option must be the

View File

@ -10,15 +10,15 @@ NMREval documentation
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
install.rst
user_guide/index user_guide/index
gallery/index gallery/index
api/index api/index
Indices and tables Indices
================== =======
* :ref:`genindex` | :ref:`genindex`
* :ref:`modindex` | :ref:`modindex`
* :ref:`search`

View File

@ -11,7 +11,8 @@ In general, time signals are calculated by integration of all orientations (see
.. math:: .. math::
g(t) = \int f[\omega_\text{int}(\theta, \phi)t]\sin\theta\,\mathrm{d}\theta\,\mathrm{d}\phi g(t) = \int f[\omega_\text{int}(\theta, \phi)t]\sin\theta\,\mathrm{d}\theta\,\mathrm{d}\phi
with :math:`f(\theta, \phi, t) = \cos[\omega_\text{int}(\theta, \phi) t]` or :math:`\exp[i\omega_\text{int}(\theta) t]` and fourier transform for a spectrum. with :math:`f(\theta, \phi, t) = \cos[\omega_\text{int}(\theta, \phi) t]` or :math:`\exp[i\omega_\text{int}(\theta) t]`
and fourier transform for a spectrum.
However, summation over :math:`\theta`, :math:`\phi`, and calculating :math:`f(\theta, \phi, t)` for each orientation is time consuming. However, summation over :math:`\theta`, :math:`\phi`, and calculating :math:`f(\theta, \phi, t)` for each orientation is time consuming.
Alternatively, if the orientations are equidistant in :math:`\cos\theta`, one can get to the spectrum directly by creating a histogram of :math:`\omega_\text{int}(\theta, \phi)`, thus circumventing a lot of calculations. Alternatively, if the orientations are equidistant in :math:`\cos\theta`, one can get to the spectrum directly by creating a histogram of :math:`\omega_\text{int}(\theta, \phi)`, thus circumventing a lot of calculations.

View File

@ -4,10 +4,6 @@
Fitting data Fitting data
============ ============
.. image:: ../_static/fit_dialog.png
:scale: 80%
:align: center
The picture gives an example of dialog to setup and start fits. The picture gives an example of dialog to setup and start fits.
First, there is the possibiity to fit different functions, called models to differentiate from the functions inside each First, there is the possibiity to fit different functions, called models to differentiate from the functions inside each
model, to different data simultaneously. model, to different data simultaneously.

View File

@ -1,11 +1,13 @@
========== **********
User Guide User Guide
========== **********
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
read gui/index
read/index
edit_signals
fit fit
shift_scale shift_scale

View File

@ -1,19 +0,0 @@
.. _user_guide.read:
*************
Reading files
*************
Supported filetypes are
* Text files,
* DAMARIS HDF5 files,
* Grace images.
* HP alpha-analyzer EPS files
* NTNMR .tnt files
DAMARIS HDF files
=================
After scanning the selected file the program shows a list of the available data.

View File

@ -1,111 +0,0 @@
from typing import Union
import numpy as np
from scipy.integrate import simps
from scipy.special import gammaln
from .base import Distribution
class GGAlpha(Distribution):
name = r'General \Gamma (\alpha-process)'
parameter = [r'\alpha', r'\beta']
@staticmethod
def correlation(t, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0-20, logtau0+20, num=4001)
taus = np.exp(logtau)
gtau = GGAlpha.distribution(taus, tau0, *args)
ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t])
return ret_val
@staticmethod
def susceptibility(omega, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001)
taus = np.exp(logtau)
gtau = GGAlpha.distribution(taus, tau0, *args)
ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega])
return ret_val
@staticmethod
def distribution(taus: Union[float, np.ndarray], tau: float, *args) -> Union[float, np.ndarray]:
alpha, beta = args
b_to_a = beta / alpha
norm = np.exp(gammaln(b_to_a) - b_to_a * np.log(b_to_a)) / alpha
t_to_t0 = taus / tau
ret_val = np.exp(-b_to_a * t_to_t0 ** alpha) * t_to_t0 ** beta
return ret_val / norm
class GGAlphaEW(Distribution):
name = r'General \Gamma (\alpha-process + EW)'
parameter = [r'\alpha', r'\beta']
@staticmethod
def correlation(t, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0-20, logtau0+20, num=4001)
taus = np.exp(logtau)
gtau = GGAlphaEW.distribution(taus, tau0, *args)
# wir integrieren ueber lntau, nicht tau
ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t])
return ret_val
@staticmethod
def susceptibility(omega, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001)
taus = np.exp(logtau)
gtau = GGAlphaEW.distribution(taus, tau0, *args)
ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega])
return ret_val
@staticmethod
def distribution(tau: Union[float, np.ndarray], tau0: float, *args) -> Union[float, np.ndarray]:
alpha, beta, sigma, gamma = args
if gamma == beta:
return GGAlpha.distribution(tau, tau0, alpha, beta)
b_to_a = beta / alpha
g_to_a = gamma / alpha
t_to_t0 = tau / tau0
norm = (np.exp(gammaln(b_to_a)) + sigma**(gamma-beta) *
np.exp(gammaln(g_to_a) + (b_to_a-g_to_a)*np.log(b_to_a))) / np.exp(b_to_a*np.log(b_to_a)) / alpha
ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta * (1 + (t_to_t0*sigma)**(gamma-beta))
return ret_val / norm
class GGBeta(Distribution):
name = r'General \Gamma (\beta-process)'
parameter = [r'\alpha', r'\beta']
@staticmethod
def correlation(t, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0-20, logtau0+20, num=4001)
taus = np.exp(logtau)
gtau = GGBeta.distribution(taus, tau0, *args)
# wir integrieren ueber lntau, nicht tau
ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t])
return ret_val
@staticmethod
def susceptibility(omega, tau0, *args):
logtau0 = np.log(tau0)
logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001)
taus = np.exp(logtau)
gtau = GGBeta.distribution(taus, tau0, *args)
ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega])
return ret_val
@staticmethod
def distribution(tau: Union[float, np.ndarray], tau0: float, *args) -> Union[float, np.ndarray]:
a, b = args
norm = a * (1+b) * np.sin(np.pi*b/(1+b)) * b**(b/(1+b)) / np.pi
ret_val = b * (tau/tau0)**a + (tau/tau0)**(-a*b)
return norm / ret_val

View File

@ -1,189 +0,0 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/fitcreationdialog.ui'
#
# Created by: PyQt5 UI code generator 5.12.3
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(614, 776)
self.verticalLayout_5 = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout_5.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_5.setSpacing(3)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.groupBox = QtWidgets.QGroupBox(Dialog)
self.groupBox.setCheckable(True)
self.groupBox.setChecked(False)
self.groupBox.setObjectName("groupBox")
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.groupBox)
self.verticalLayout_7.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_7.setSpacing(3)
self.verticalLayout_7.setObjectName("verticalLayout_7")
self.widget_2 = QtWidgets.QWidget(self.groupBox)
self.widget_2.setObjectName("widget_2")
self.gridLayout_2 = QtWidgets.QGridLayout(self.widget_2)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setSpacing(3)
self.gridLayout_2.setObjectName("gridLayout_2")
self.name_lineedit = QtWidgets.QLineEdit(self.widget_2)
self.name_lineedit.setObjectName("name_lineedit")
self.gridLayout_2.addWidget(self.name_lineedit, 0, 1, 1, 1)
self.group_lineedit = QtWidgets.QLineEdit(self.widget_2)
self.group_lineedit.setObjectName("group_lineedit")
self.gridLayout_2.addWidget(self.group_lineedit, 1, 1, 1, 1)
self.group_label = QtWidgets.QLabel(self.widget_2)
self.group_label.setObjectName("group_label")
self.gridLayout_2.addWidget(self.group_label, 1, 0, 1, 1)
self.name_label = QtWidgets.QLabel(self.widget_2)
self.name_label.setObjectName("name_label")
self.gridLayout_2.addWidget(self.name_label, 0, 0, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(self.widget_2)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout_2.addWidget(self.lineEdit, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.widget_2)
self.label_2.setObjectName("label_2")
self.gridLayout_2.addWidget(self.label_2, 2, 0, 1, 1)
self.verticalLayout_7.addWidget(self.widget_2)
self.verticalLayout_5.addWidget(self.groupBox)
self.groupBox_2 = QtWidgets.QGroupBox(Dialog)
self.groupBox_2.setCheckable(True)
self.groupBox_2.setChecked(False)
self.groupBox_2.setObjectName("groupBox_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_2)
self.verticalLayout_2.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_2.setSpacing(3)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.widget_3 = QtWidgets.QWidget(self.groupBox_2)
self.widget_3.setObjectName("widget_3")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.widget_3)
self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_8.setSpacing(3)
self.verticalLayout_8.setObjectName("verticalLayout_8")
self.tableWidget = QtWidgets.QTableWidget(self.widget_3)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
self.tableWidget.setSizePolicy(sizePolicy)
self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.tableWidget.setColumnCount(4)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
self.verticalLayout_8.addWidget(self.tableWidget)
self.parameter_button = QtWidgets.QToolButton(self.widget_3)
self.parameter_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.parameter_button.setAutoRaise(False)
self.parameter_button.setArrowType(QtCore.Qt.RightArrow)
self.parameter_button.setObjectName("parameter_button")
self.verticalLayout_8.addWidget(self.parameter_button)
self.verticalLayout_2.addWidget(self.widget_3)
self.verticalLayout_5.addWidget(self.groupBox_2)
self.groupBox_3 = QtWidgets.QGroupBox(Dialog)
self.groupBox_3.setCheckable(True)
self.groupBox_3.setChecked(False)
self.groupBox_3.setObjectName("groupBox_3")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_3)
self.verticalLayout_3.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_3.setSpacing(3)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.widget = QtWidgets.QWidget(self.groupBox_3)
self.widget.setObjectName("widget")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout_6.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_6.setSpacing(3)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.use_nuclei = QtWidgets.QCheckBox(self.widget)
self.use_nuclei.setObjectName("use_nuclei")
self.verticalLayout_6.addWidget(self.use_nuclei)
self.tabWidget = QtWidgets.QTabWidget(self.widget)
self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West)
self.tabWidget.setTabsClosable(True)
self.tabWidget.setObjectName("tabWidget")
self.verticalLayout_6.addWidget(self.tabWidget)
self.selection_button = QtWidgets.QToolButton(self.widget)
self.selection_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
self.selection_button.setArrowType(QtCore.Qt.RightArrow)
self.selection_button.setObjectName("selection_button")
self.verticalLayout_6.addWidget(self.selection_button)
self.verticalLayout_3.addWidget(self.widget)
self.verticalLayout_5.addWidget(self.groupBox_3)
self.groupBox_4 = QtWidgets.QGroupBox(Dialog)
self.groupBox_4.setCheckable(True)
self.groupBox_4.setChecked(False)
self.groupBox_4.setObjectName("groupBox_4")
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_4)
self.verticalLayout.setObjectName("verticalLayout")
self.namespace_widget = QNamespaceWidget(self.groupBox_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.namespace_widget.sizePolicy().hasHeightForWidth())
self.namespace_widget.setSizePolicy(sizePolicy)
self.namespace_widget.setObjectName("namespace_widget")
self.verticalLayout.addWidget(self.namespace_widget)
self.verticalLayout_5.addWidget(self.groupBox_4)
self.frame_4 = QtWidgets.QFrame(Dialog)
self.frame_4.setObjectName("frame_4")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_4)
self.verticalLayout_4.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_4.setSpacing(3)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.label = QtWidgets.QLabel(self.frame_4)
self.label.setObjectName("label")
self.verticalLayout_4.addWidget(self.label)
self.plainTextEdit = CodeEditor(self.frame_4)
self.plainTextEdit.setObjectName("plainTextEdit")
self.verticalLayout_4.addWidget(self.plainTextEdit)
self.verticalLayout_5.addWidget(self.frame_4)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout_5.addWidget(self.buttonBox)
self.name_label.setBuddy(self.name_lineedit)
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.groupBox.setTitle(_translate("Dialog", "Description"))
self.group_label.setText(_translate("Dialog", "Group"))
self.name_label.setText(_translate("Dialog", "Name"))
self.label_2.setText(_translate("Dialog", "Equation"))
self.groupBox_2.setTitle(_translate("Dialog", "Variables"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("Dialog", "Variable"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("Dialog", "Name"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("Dialog", "Lower bound"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("Dialog", "Upper bound"))
self.parameter_button.setText(_translate("Dialog", "Add parameter"))
self.groupBox_3.setTitle(_translate("Dialog", "Multiple choice part"))
self.use_nuclei.setText(_translate("Dialog", "Add gyromagnetic ratios"))
self.selection_button.setText(_translate("Dialog", "Add selection"))
self.groupBox_4.setTitle(_translate("Dialog", "Available namespace"))
self.label.setText(_translate("Dialog", "Function y = func(x)"))
from ..lib.codeeditor import CodeEditor
from ..lib.namespace import QNamespaceWidget

View File

@ -1,238 +0,0 @@
import re
import numexpr as ne
import numpy as np
from ..Qt import QtCore, QtWidgets
from .._py.fitcreationdialog import Ui_Dialog
_numexpr_funcs = []
for k, _ in ne.expressions.functions.items():
pat = k + r'\('
_numexpr_funcs.append((re.compile(pat), 'np.' + k + '('))
class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog):
classCreated = QtCore.pyqtSignal(object)
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setupUi(self)
self.namespace_widget.make_namespace()
self.tableWidget.itemChanged.connect(self.update_function)
self.groupBox.toggled.connect(self.change_visibility)
self.groupBox_2.toggled.connect(self.change_visibility)
self.groupBox_3.toggled.connect(self.change_visibility)
self.groupBox_4.toggled.connect(self.change_visibility)
self.groupBox.setChecked(True)
def __call__(self, *args, **kwargs):
for w in [self.lineEdit_4, self.lineEdit, self.lineEdit_3, self.lineEdit_2,
self.parameterLineEdit, self.externalParametersLineEdit]:
w.clear()
def check(self):
self.name = self.name_lineedit.text()
self.group = self.group_lineedit.text()
self.eq = str(self.lineEdit.text())
self.p = str(self.parameterLineEdit.text()).split()
self.func = str(self.lineEdit_4.text())
self._func_string = ''
error = []
for k, v in [('Name', self.name), ('Group', self.group), ('Parameters', self.p), ('Function', self.func)]:
if not v:
error.append('Empty ' + str(k))
if self.name:
if self.name[0].isdigit():
error.append('Name starts with digit')
if self.p:
if set(self.p) & set(self.ext_p):
error.append('Duplicate entries: {}'.format(list(set(self.p) & set(self.ext_p))))
if self.p and self.func:
p_test = np.ones((len(self.p)+len(self.ext_p)))
_x = np.arange(2)
namespace = {'x': _x}
for i, pp in enumerate(p_test):
namespace[f'p_{i}'] = pp
self._func_string = self.func + ''
self._func_string = self._func_string.replace('[', '_').replace(']', '')
try:
ne.evaluate(self._func_string, local_dict=namespace)
except KeyError:
error.append(f'Incorrect evaluation {self.func}')
if error:
QtWidgets.QMessageBox().warning(self, 'Invalid entries', '\n'.join(error))
else:
return True
def accept(self):
self.confirm()
super().accept()
def confirm(self):
print(f' name = {self.name_lineedit.text()}')
group_type = self.group_lineedit.text()
if group_type:
print(f' group = "{group_type}"')
else:
print(' group = "User-defined"')
var = []
for row in range(self.tableWidget.rowCount()):
var.append(self.tableWidget.item(row, 1).text())
if var:
print(' params = [r"', end='')
print('", r"'.join(var) + '"]')
else:
print(' params = []')
print('\n@staticmethod')
print(self.label.text())
import inspect
for k, v in self.namespace_widget.namespace.flatten().items():
if inspect.isfunction(v):
print(k, inspect.getmodule(v))
print(k, [cc[1] for cc in inspect.getmembers(v) if cc[0] == '__qualname__'])
else:
print(k, v)
print(self.plainTextEdit.toPlainText())
@QtCore.pyqtSlot(name='on_parameter_button_clicked')
def add_variable(self):
self.tableWidget.blockSignals(True)
row = self.tableWidget.rowCount()
self.tableWidget.setRowCount(row+1)
self.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem('p'+str(row)))
self.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem('p_{'+str(row)+'}'))
self.tableWidget.setItem(row, 2, QtWidgets.QTableWidgetItem('--'))
self.tableWidget.setItem(row, 3, QtWidgets.QTableWidgetItem('--'))
self.tableWidget.blockSignals(False)
self.update_function(None)
@QtCore.pyqtSlot(name='on_selection_button_clicked')
def add_choice(self):
cnt = self.tabWidget.count()
self.tabWidget.addTab(ChoiceWidget(self), 'choice' + str(cnt))
self.tabWidget.setCurrentIndex(cnt)
def register(self):
i = 0
basename = self.name.replace(' ', '')
classname = basename
# while classname in _userfits:
# classname = basename + '_' + str(i)
# i += 1
c = register_class(classname, self.name, self.group, self.p, self.eq, self._func_string)
self.classCreated.emit(c)
return classname, c
def save(self, cname):
t = '\n# Created automatically\n' \
'class {cname:}(object):\n'\
' name = "{name:}"\n' \
' type = "{group:}"\n'\
' equation = "{eq:}"\n'\
' params = {p:}\n' \
' ext_params = {ep:}\n\n' \
' @staticmethod\n' \
' def func(p, x):\n' \
' return {func:}\n'
f_string = self.func
for pat, repl in _numexpr_funcs:
f_string = re.sub(pat, repl, f_string)
@QtCore.pyqtSlot(QtWidgets.QTableWidgetItem)
@QtCore.pyqtSlot(str)
def update_function(self, _):
var = []
for row in range(self.tableWidget.rowCount()):
var.append(self.tableWidget.item(row, 0).text())
if self.use_nuclei.isChecked():
var.append('nucleus=2.67522128e8')
# for row in range(self.selection_combobox.count()):
# var.append(self.selection_combobox.itemText(row) + '=')
self.label.setText('def func(x, ' + ', '.join(var) + '):')
def change_visibility(self):
sender = self.sender()
for gb in [self.groupBox, self.groupBox_2, self.groupBox_3, self.groupBox_4]:
gb.blockSignals(True)
gb.setChecked(sender == gb)
gb.blockSignals(False)
self.widget_2.setVisible(sender == self.groupBox)
self.widget_3.setVisible(sender == self.groupBox_2)
self.widget.setVisible(sender == self.groupBox_3)
self.namespace_widget.setVisible(sender == self.groupBox_4)
class ChoiceWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent=parent)
self._init_ui()
def _init_ui(self):
layout = QtWidgets.QGridLayout()
layout.setContentsMargins(3, 3, 3, 3)
layout.setHorizontalSpacing(6)
self.label = QtWidgets.QLabel('Name', parent=self)
layout.addWidget(self.label, 0, 0)
self.name_line = QtWidgets.QLineEdit(self)
layout.addWidget(self.name_line, 0, 1)
self.label_2 = QtWidgets.QLabel('Displayed name', parent=self)
layout.addWidget(self.label_2, 0, 2)
self.display_line = QtWidgets.QLineEdit(self)
layout.addWidget(self.display_line, 0, 3)
self.label_3 = QtWidgets.QLabel('Type', parent=self)
layout.addWidget(self.label_3)
self.types = QtWidgets.QComboBox(self)
self.types.addItems(['str', 'int', 'float'])
layout.addWidget(self.types)
self.add_button = QtWidgets.QPushButton('Add option')
layout.addWidget(self.add_button)
self.table = QtWidgets.QTableWidget(self)
self.table.setColumnCount(2)
self.table.setHorizontalHeaderLabels(['Name', 'Value'])
layout.addWidget(self.table, 2, 0, 1, 4)
self.setLayout(layout)
def register_class(cname, name, group, p, eq, func):
c = type(cname, (), {})
c.name = name
c.type = group
c.params = p
c.equation = eq
c.func = func_decorator(func)
return c
def func_decorator(f_string):
# we need this decorator because the result is used in a class
def wrapped_f(*args):
namespace = {'x': args[1]}
for i, pp in enumerate(args[0]):
namespace['p_{}'.format(i)] = pp
return ne.evaluate(f_string, local_dict=namespace)
return wrapped_f

View File

@ -1,357 +0,0 @@
import numpy as np
from scipy.integrate import trapz
from .orientations import zcw_spherical as crystallites
class Powder(object):
def __init__(self, n=100):
self.alpha, self.beta, self.wt = crystallites(n)
class Pake(object):
parameter = {'delta': 0., 'eta': 0., 'w_iso': 0.,
'x': None, 'y': None, 'half': False}
def __init__(self, samples=10000):
self.powder = Powder(n=samples)
self.dw = None
self.parameter = {}
self.GB = 1000
self.pw = 1e-6
self.legendre = 0
self.axial = 0
self.calc_prefactor()
def calc_prefactor(self):
"""
Calculates angular dependencies
Returns
-------
"""
self.legendre = 3 * np.square(np.cos(self.powder.beta)) - 1
self.axial = np.square(np.sin(self.powder.beta)) * np.cos(2 * self.powder.alpha)
def set_parameter(self, p, dw=None):
self.parameter['delta'] = p[0] * 1e3
self.parameter['eta'] = p[1]
self.GB = p[2] * 1e3
self.pw = p[3] * 1e-6
if len(p) == 5:
self.parameter['w_iso'] = p[4] * 1e3
if dw is not None:
self.dw = dw
@staticmethod
def _check_old_data(x, d, e, w, h):
if Pake.parameter['x'] is None:
return False
if Pake.parameter['w_iso'] == w and Pake.parameter['delta'] == d and \
Pake.parameter['eta'] == e and Pake.parameter['half'] == h and \
Pake.parameter['x'][0] == x[0] and Pake.parameter['x'][1] == x[1]:
return True
return False
def calc_timesignal(self, tt, p, half=False):
"""
Calculate time signal of pake spectrum
Parameters
----------
tt: time array
p: list of parameters [delta, eta, GB, omega_iso]
half: if False, Pake spectrum will be calculated, if True, chemical shift spectrum will be calculated
Returns
-------
timesignal
"""
_delta, _eta, _wiso = p
omega = 0.5 * _delta * (self.legendre - _eta * self.axial)
if half:
omega += _wiso
weight = self.powder.wt
if half:
fid_real = np.zeros_like(tt, dtype=float)
fid_imag = np.zeros_like(tt, dtype=float)
for k, v in zip(omega, weight):
pha = 2 * np.pi * k * tt
fid_real += (np.cos(pha)) * v
fid_imag += (np.sin(pha)) * v
fid = 1j * fid_imag
fid += fid_real
else:
fid = np.zeros_like(tt, dtype=float)
for k, v in zip(omega, weight):
fid += np.cos(2 * np.pi * k * tt) * v
return fid
@staticmethod
def calc_pulse(pw, f):
_phi = 2 * np.pi * f * pw
pulse = ((0.5 * np.pi * np.sin(np.sqrt(0.25 * np.pi ** 2 + 0.5 * _phi ** 2))) /
np.sqrt(0.25 * np.pi ** 2 + 0.25 * _phi ** 2)) ** 1
return pulse
def pake_spectrum(self, x, p=None, half=False):
if p is None:
_gb = self.GB
_pw = self.pw
try:
_delta = self.parameter['delta']
_eta = self.parameter['eta']
_wiso = self.parameter['w_iso']
except KeyError:
_delta = Pake.parameter['delta']
_eta = Pake.parameter['eta']
_wiso = Pake.parameter['w_iso']
else:
_delta = p[0] * 1e3
_eta = p[1]
_gb = p[2] * 1e3
_pw = p[3] * 1e-6
_wiso = p[4] * 1e3
# x is time
if abs(x[1] - x[0]) < 1:
if self.dw is None:
self.dw = x[1] - x[0]
t = x
nop = len(x)
isfreq = False
# x is frequency
else:
df = (x[1] - x[0])
if self.dw is None:
self.dw = 1 / (df * len(x))
if len(x) != 1 / (self.dw * df):
nop = int(1 / (self.dw * df))
else:
nop = len(x)
# avoid calculation for to much points
t = np.arange(0, min(8192, nop)) * self.dw
isfreq = True
new_data = self._check_old_data((nop, self.dw), _delta, _eta, _wiso, half)
if new_data:
fid = Pake.parameter['y'] + 0
Pake.parameter['delta'] = _delta
Pake.parameter['eta'] = _eta
Pake.parameter['w_iso'] = _wiso
Pake.parameter['x'] = (nop, self.dw)
Pake.parameter['half'] = half
self.GB = _gb
self.pw = _pw
fid = self.calc_timesignal(t, [_delta, _eta, _wiso], half=half)
Pake.parameter['y'] = fid + 0
fid *= np.exp(-(_gb * t) ** 2)
# add zeros to get desired signal length
if len(fid) != nop:
fid = np.append(fid, np.zeros((nop - len(fid))), axis=0)
spec = np.fft.fftshift(np.fft.fft(fid))
spec -= np.mean(spec[:10])
_f = np.fft.fftshift(np.fft.fftfreq(nop, d=self.dw))
# take finite pulse length into account
if _pw != 0:
pulse = self.calc_pulse(_pw, _f)
spec *= pulse
# shift pake spectrum by isotropic shift
if not half:
spec = np.roll(spec, int(self.dw * _wiso * nop))
# cut to original frequency range
if isfreq:
# mask = np.ma.masked_inside(_f, min(x), max(x)).mask
# spec = spec[mask]
spec = np.interp(x, _f, spec.real)
spec.real -= np.mean(spec.real[:10])
return spec.real / max(spec.real)
def pake(self, x, p=None):
return self.pake_spectrum(x, p=p)
def halfpake(self, x, p=None):
return self.pake_spectrum(x, p=p, half=True)
class SecondOrder(object):
parameter = {'c_q': 1e6, 'eta': 0.,
'x': None, 'y': None}
def __init__(self, samples=200000):
self.powder = Powder(n=samples)
self.dw = None
self.parameter = {}
self.GB = 1000
self.pw = 1e-6
self.legendre = 0
self.axial = 0
self.coupling = 1
self.larmor = 2 * np.pi * 100e6
def set_parameter(self, p, dw=None, larmor=None, spin=2.5):
self.parameter['c_q'] = 2 * np.pi * p[0] * 1e6
self.parameter['eta'] = p[1]
self.GB = p[2] * 1e3
if dw is not None:
self.dw = dw
if larmor is not None:
self.larmor = 2 * np.pi * larmor
self._calc_coupling(2 * np.pi * p[0] * 1e6, spin=spin)
def _calc_coupling(self, c_q, spin=2.5):
omega_q = c_q / (2 * spin * (2 * spin - 1))
self.coupling = 1.5 * omega_q ** 2 / self.larmor * (spin * (spin + 1) - 0.75)
def calc_omega(self, eta, delta):
self._calc_coupling(delta)
cos2phi = np.cos(2 * self.powder.alpha)
cos_theta_square = 0.5 + 0.5 * np.cos(2 * self.powder.beta)
prefactor_a = -3.375 + 2.25 * eta * cos2phi - 0.375 * (eta * cos2phi) ** 2
prefactor_b = 3.75 - 0.5 * eta ** 2 - 2 * eta * cos2phi + 0.75 * (eta * cos2phi) ** 2
prefactor_c = -0.375 + (eta ** 2) / 3. - 0.25 * eta * cos2phi - 0.375 * (eta * cos2phi) ** 2
ret_val = np.zeros_like(cos2phi)
ret_val += prefactor_a * cos_theta_square ** 2
ret_val += prefactor_b * cos_theta_square
ret_val += prefactor_c
return self.coupling * ret_val
def calc_timesignal(self, tt, p):
delta, eta = p
omega = self.calc_omega(eta, delta)
weight = self.powder.wt
fid_real = np.zeros_like(tt, dtype=float)
fid_imag = np.zeros_like(tt, dtype=float)
for o, w in zip(omega, weight):
pha = o * tt
co_pha = np.cos(pha)
si_pha = np.sin(pha)
fid_real += co_pha * w
fid_imag += si_pha * w
fid = 1j * fid_imag
fid += fid_real
return fid
def spectrum(self, x, p=None):
if p is None:
p = [self.parameter['c_q'], self.parameter['eta'], self.GB]
if abs(x[1] - x[0]) < 1:
if self.dw is None:
self.dw = x[1] - x[0]
t = x
nop = len(x)
isfreq = False
else:
df = (x[1] - x[0])
if self.dw is None:
self.dw = 1 / (df * len(x))
if len(x) != 1 / (self.dw * df):
nop = int(1 / (self.dw * df))
else:
nop = len(x)
t = np.arange(0, min(8192, nop)) * self.dw
isfreq = True
fid = self.calc_timesignal(t, p[:-1])
fid *= np.exp(-(p[-1] * t) ** 2)
if len(fid) != nop:
fid = np.append(fid, np.zeros((nop - len(fid))), axis=0)
spec = np.fft.fftshift(np.fft.fft(fid))
_f = np.fft.fftshift(np.fft.fftfreq(nop, d=self.dw))
if isfreq:
mask = np.ma.masked_inside(_f, min(x), max(x)).mask
spec = spec[mask]
return spec.real - np.mean(spec.real[:10])
def csa(x: np.ndarray, delta: float, eta: float, wiso: float, gb: float, sw: float):
dw = 1 / sw
a, b, _ = crystallites(200000)
bins = 0.5 * (x[1:] + x[:-1])
bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])])))
omega = wiso + delta * 0.5 * (3 * np.cos(b) ** 2 - 1 - eta * np.square(np.sin(b)) * np.cos(2 * a))
s_left = np.histogram(omega, bins=bins)[0]
s = s_left
if gb != 0:
apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / sw) ** 2) * \
2 * np.sqrt(np.log(2) / np.pi) / gb
ret_val = np.convolve(s, apd, mode='same')
else:
ret_val = s
return ret_val / trapz(ret_val, x)
def pake(p, x):
dw = 1/p[-1]
a, b, _ = crystallites(200000)
bins = 0.5 * (x[1:] + x[:-1])
bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])])))
omega = p[0] * 0.5 * (3*np.cos(b)**2 - 1 - p[1] * np.square(np.sin(b)) * np.cos(2 * a))
s_left = np.histogram(omega, bins=bins)[0]
s_right = np.histogram(-omega, bins=bins)[0]
s = s_left + s_right
if p[2] != 0:
apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / p[2]) ** 2) * \
2 * np.sqrt(np.log(2) / np.pi) / p[2]
ret_val = np.convolve(s, apd, mode='same')
else:
ret_val = s
return ret_val/trapz(ret_val, x)
def sec_order(p, x, spin=2.5):
dw = 1/p[-1]
a, b, _ = crystallites(200000)
bins = 0.5 * (x[1:] + x[:-1])
bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])])))
omega_q = 2 * np.pi * p[0] / (2*spin * (2*spin - 1))
coupling = 1.5 * (omega_q**2 / (2 * np.pi *p[3])) * (spin*(spin + 1) - 0.75)
cos2phi = np.cos(2 * a)
cos_theta_square = 0.5+0.5*np.cos(2*b)
prefactor_a = -3.375 + 2.25*p[1] * cos2phi - 0.375 * (p[1] * cos2phi)**2
prefactor_b = 3.75 - 0.5 * p[1]**2 - 2*p[1]*cos2phi + 0.75 * (p[1]*cos2phi)**2
prefactor_c = -0.375 + (p[1]**2)/3. - 0.25*p[1]*cos2phi - 0.375 * (p[1]*cos2phi)**2
orient = np.zeros_like(cos2phi)
orient += prefactor_a * cos_theta_square ** 2
orient += prefactor_b * cos_theta_square
orient += prefactor_c
omega = coupling * orient
s = np.histogram(omega/(2*np.pi), bins=bins)[0]
if p[2] != 0:
apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / p[2]) ** 2) * \
2 * np.sqrt(np.log(2) / np.pi) / p[2]
ret_val = np.convolve(s, apd, mode='same')
else:
ret_val = s
return ret_val / trapz(ret_val, x)

View File

@ -1,268 +0,0 @@
import numpy as np
from scipy.special import gammaln
from ..math.logfourier import logft
stepsize = 0.2 # 0.05
span1 = 20
span2 = 30
class GeneralGamma(object):
lower_b = 20
upper_b = 20
dx = 0.2
@staticmethod
def gga_dist(tau, tau0, alpha, beta):
b_to_a = beta / alpha
norm = np.exp(gammaln(b_to_a) - b_to_a * np.log(b_to_a)) / alpha
t_to_t0 = tau / tau0
ret_val = np.exp(-b_to_a * t_to_t0 ** alpha) * t_to_t0 ** beta
return ret_val / norm
@staticmethod
def gga_ew_dist(tau, tau0, alpha, beta, sigma, gamma):
if gamma == beta:
return GeneralGamma.gga_dist(tau, tau0, alpha, beta)
b_to_a = beta / alpha
g_to_a = gamma / alpha
t_to_t0 = tau / tau0
norm = (np.exp(gammaln(b_to_a)) + sigma**(gamma-beta) * np.exp(gammaln(g_to_a) + (b_to_a-g_to_a)*np.log(b_to_a))) / np.exp(b_to_a*np.log(b_to_a)) / alpha
ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta * (1 + (t_to_t0*sigma)**(gamma-beta))
return ret_val / norm
@staticmethod
def ggb_dist(tau, tau0, a, b):
norm = a * (1+b) * np.sin(np.pi*b/(1+b)) * b**(b/(1+b)) / np.pi
ret_val = b * (tau/tau0)**a + (tau/tau0)**(-a*b)
return norm / ret_val
@staticmethod
def _gg_time(t, tau0, *args, **kwargs):
logtau = np.log(tau0)
steps = np.arange(logtau - GeneralGamma.lower_b, logtau + GeneralGamma.upper_b, GeneralGamma.dx)
taus = np.exp(steps)
ret_val = np.zeros_like(t)
dist = {'gga': GeneralGamma.gga_dist,
'gga_ew': GeneralGamma.gga_ew_dist,
'ggb': GeneralGamma.ggb_dist}[kwargs.pop('mode', 'gga')]
gtau = dist(taus, tau0, *args)
for i, xval in enumerate(t):
y = np.exp(- xval / taus)
y *= gtau
y = y[1:] + y[:-1]
ret_val[i] = np.sum(y) * GeneralGamma.dx / 2
return ret_val
@staticmethod
def ggaew_b_freq(f, tau0, alpha, beta, sigma, gamma, tau1, a, b, r, dec=5):
t = np.logspace(np.log10(1 / max(f)) - dec, np.log10(1 / min(f)) + dec, num=int(len(f) * (0.5 * dec)))
phi_a = GeneralGamma.ggaew(t, tau0, alpha, beta, sigma, gamma)
phi_b = GeneralGamma.ggb(t, tau1, a, b)
temp = phi_a * (1 - r + r * phi_b)
ret_val = logft(t, temp, new_x=2 * np.pi * f)[1].y
return ret_val * f * 2 * np.pi
@staticmethod
def gga_b_freq(f, tau0, alpha, beta, tau1, a, b, r, dec=5):
t = np.logspace(np.log10(1 / max(f)) - dec, np.log10(1 / min(f)) + dec, num=int(len(f) * (0.5 * dec)))
phi_a = GeneralGamma.gga(t, tau0, alpha, beta)
phi_b = GeneralGamma.ggb(t, tau1, a, b)
temp = phi_a * (1 - r + r * phi_b)
ret_val = logft(t, temp, new_x=2 * np.pi * f)[1].y
return ret_val * f * 2 * np.pi
@staticmethod
def gga(t, tau0, alpha, beta):
return GeneralGamma._gg_time(t, tau0, alpha, beta, mode='gga')
@staticmethod
def ggaew(t, tau0, alpha, beta, sigma, gamma):
return GeneralGamma._gg_time(t, tau0, alpha, beta, sigma, gamma, mode='gga_ew')
@staticmethod
def ggb(t, tau0, a, b):
return GeneralGamma._gg_time(t, tau0, a, b, mode='ggb')
@staticmethod
def ggaew_b(t, tau0, alpha, beta, sigma, gamma, tau1, a, b, r):
phi_a = GeneralGamma.ggaew(t, tau0, alpha, beta, sigma, gamma)
phi_b = GeneralGamma.ggb(t, tau1, a, b)
ret_val = phi_a * (1 - r + r * phi_b)
return ret_val
@staticmethod
def gga_b(t, tau0, alpha, beta, tau1, a, b, r):
phi_a = GeneralGamma.gga(t, tau0, alpha, beta)
phi_b = GeneralGamma.ggb(t, tau1, a, b)
ret_val = phi_a * (1 - r + r * phi_b)
return ret_val
class FitGG(object):
name = 'Alpha + Beta + EW'
type = 'Gamma-Functions'
equation = r'A*\Phi_{\alpha,EW} * [1 - C + C*\Phi_{\beta}] + B'
params = ['A', 'B',
r'\tau_{\alpha}', r'\alpha', r'\beta', '\sigma', '\gamma',
r'\tau_{\beta}', 'a', 'b', 'C']
@staticmethod
def func(p, x):
amp, base, tau0, alpha, beta, sigma, gamma, tau1, a, b, c = p
phi_a = GeneralGamma.ggaew(x, tau0, alpha, beta, sigma, gamma)
phi_b = GeneralGamma.ggb(x, tau1, a, b)
ret_val = amp * phi_a * (1 - c + c * phi_b) + base
return ret_val
# Definiere Funktionen #
def glntau1_td(ttime, tau, alpha, beta):
lnx = np.log(tau) + span1
intmin = np.log(tau) - span2
steps = np.arange(lnx, intmin, -stepsize)
explnx = np.exp(steps)
betatoalpha = beta / alpha
logtau = np.log(tau)
if betatoalpha > 80:
norm = np.exp(.5 * np.log(2 * np.pi / betatoalpha) - betatoalpha) / alpha
else:
norm = np.exp(gammaln(betatoalpha)) / alpha / np.power(betatoalpha, betatoalpha)
y = np.exp(-np.exp((steps - logtau) * alpha) * betatoalpha) * np.power(explnx / tau, beta) * np.exp(-ttime / explnx)
y = y[1:] + y[:-1]
intval = np.sum(y) / 2
intval = intval * stepsize / norm
return intval
def gga(t, tau0, alpha, beta):
logtau = np.log(tau0)
stepsize = 0.2
steps = np.arange(logtau - 20, logtau + 20, stepsize)
taus = np.exp(steps)/tau0
betatoalpha = beta / alpha
norm = np.exp(gammaln(betatoalpha) - betatoalpha*np.log(betatoalpha)) / alpha
ret_val = np.zeros_like(t)
gtau = np.exp(-taus ** alpha * betatoalpha) * taus ** beta
for i, xval in enumerate(t):
# exponent = -taus**alpha * betatoalpha - xval/taus/tau0
y = np.exp(- xval/taus/tau0)
y *= gtau
y = y[1:] + y[:-1]
ret_val[i] = np.sum(y) * stepsize / norm / 2
return ret_val
def ggaew(t, tau0, alpha, beta, sigma, gamma):
logtau = np.log(tau0)
stepsize = 0.2
steps = np.arange(logtau - 20, logtau + 20, stepsize)
taus = np.exp(steps) / tau0
q1 = beta / alpha
q2 = gamma / alpha
norm = (np.exp(gammaln(q1)) + sigma**(gamma-beta) * np.exp((q1-q2)*np.log(q1)) * np.exp(gammaln(q2))) / alpha / np.exp(q1*np.log(q1))
ret_val = np.empty_like(t)
gtau = np.exp(-taus**alpha * q1) * taus**beta * (1 + (taus*sigma)**(gamma-beta))
for i, xval in enumerate(t):
y = np.exp(-xval/taus/tau0)
y *= gtau
y = y[1:] + y[:-1]
ret_val[i] = np.sum(y) * stepsize / norm / 2
return ret_val
def ggaew_b(t, tau0, alpha, beta, sigma, gamma, tau1, a, b, r):
phi_a = ggaew(t, tau0, alpha, beta,sigma, gamma)
phi_b = ggb(t, tau1, a, b)
ret_val = phi_a * (1-r + r*phi_b)
return ret_val
def ggb(t, tau0, a, b):
logtau = np.log(tau0)
stepsize = 0.2
steps = np.arange(logtau - 20, logtau + 20, stepsize)
taus = np.exp(steps) / tau0
norm = np.pi / (a*(1+b)) / b**(b/(1+b)) / np.sin(np.pi*b / (1+b))
ret_val = np.empty_like(t)
gtau = 1. / (b * taus**a + taus**(-b*a))
for i, xval in enumerate(t):
y = np.exp(-xval / taus / tau0)
y *= gtau
y = y[1:] + y[:-1]
ret_val[i] = np.sum(y) * stepsize / norm / 2
return ret_val
def glntau2_td(ttime, tau, alpha, beta, sigma, gam):
intval = 0
lnx = np.log(tau) + span1
intmin = np.log(tau) - span2
steps = np.arange(lnx, intmin, -stepsize)
explnx = np.exp(steps)
logtau = np.log(tau)
q1 = beta / alpha
q2 = gam / alpha
if q2 > 80:
norm = (np.exp(.5 * np.log(2 * np.pi / q1) - q1) + np.power(sigma, alpha * (q2 - q1)) * np.power(q2 / q1,
-q2) * np.exp(
.5 * np.log(2 * np.PI / q2) - q2)) / alpha
elif q1 > 80:
norm = (np.exp(.5 * np.log(2 * np.pi / q1) - q1) + np.power(sigma, alpha * (q2 - q1)) * np.power(q2 / q1,
-q2) * np.exp(
gammaln(q2)) * np.power(q1, -q1)) / alpha
else:
norm = (np.exp(gammaln(q1)) + np.power(sigma, gam - beta) * np.power(q1, q1 - q2) * np.exp(gammaln(q2))) / (
alpha * np.power(q1, q1))
y = np.exp(-np.exp((steps - logtau) * alpha) * q1) * np.power(explnx / tau, beta) * (
1 + np.power(explnx * sigma / tau, gam - beta)) * np.exp(-ttime / explnx)
y = y[1:] + y[:-1]
intval = np.sum(y) / 2
intval = intval * stepsize / norm
return intval
def glnbeta_td(ttime, tau, a, b):
intval = 0
lnx = np.log(tau) + span1
intmin = np.log(tau) - span2
steps = np.arange(lnx, intmin, -stepsize)
explnx = np.exp(steps)
norm = np.pi / (a * (1 + b)) / np.power(b, b / (1. + b)) / np.sin(np.pi * b / (1. + b))
y = 1. / (b * np.power(explnx / tau, a) + np.power(explnx / tau, -(b * a))) * np.exp(-ttime / explnx)
y = y[1:] + y[:-1]
intval = np.sum(y) / 2
intval = intval * stepsize / norm
return intval
def g2(p, x):
ret_val = np.empty(np.shape(x))
for i, xval in enumerate(x):
# fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[4], p[5])
# fkt1 = glntau1_td(xval, p[1], p[2], p[3])
fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[4], p[5])
fkt2 = glnbeta_td(xval, p[6], p[7], p[8])
# ret_val[i] = (fkt1 * ((1 - p[4]) + p[4] * fkt2) * p[0]) + np.abs(p[9]) * np.exp(-(xval/p[10])**p[11]) + p[8]
ret_val[i] = fkt1 * (1-p[0] + p[0]*fkt2)
return ret_val
def g1(p, x):
ret_val = np.empty(np.shape(x))
for i, xval in enumerate(x):
# fkt1 = glntau1_td(xval,p[1],p[2],p[3])
fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[11], p[12])
fkt2 = glnbeta_td(xval, p[5], p[6], p[7])
ret_val[i] = p[0] * (fkt1 * ((1 - p[4]) + p[4] * fkt2)) + np.abs(p[8]) * np.exp(-(xval / p[9]) ** p[10])
return ret_val

View File

@ -1,8 +1,8 @@
matplotlib matplotlib
numpy numpy
scipy scipy
pyqt
h5py
pyqtgraph pyqtgraph
bsddb3 bsddb3
h5py
pyqt

View File

@ -1,419 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>614</width>
<height>776</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Description</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="name_lineedit"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="group_lineedit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="group_label">
<property name="text">
<string>Group</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="name_label">
<property name="text">
<string>Name</string>
</property>
<property name="buddy">
<cstring>name_lineedit</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Equation</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Variables</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="columnCount">
<number>4</number>
</property>
<column>
<property name="text">
<string>Variable</string>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Lower bound</string>
</property>
</column>
<column>
<property name="text">
<string>Upper bound</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QToolButton" name="parameter_button">
<property name="text">
<string>Add parameter</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
<property name="arrowType">
<enum>Qt::RightArrow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Multiple choice part</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="use_nuclei">
<property name="text">
<string>Add gyromagnetic ratios</string>
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::West</enum>
</property>
<property name="tabsClosable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="selection_button">
<property name="text">
<string>Add selection</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="arrowType">
<enum>Qt::RightArrow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Available namespace</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QNamespaceWidget" name="namespace_widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_4">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>3</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Function y = func(x)</string>
</property>
</widget>
</item>
<item>
<widget class="CodeEditor" name="plainTextEdit"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QNamespaceWidget</class>
<extends>QWidget</extends>
<header>..lib.namespace</header>
<container>1</container>
</customwidget>
<customwidget>
<class>CodeEditor</class>
<extends>QPlainTextEdit</extends>
<header>..lib.codeeditor</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,7 +1,7 @@
from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport
# from PySide2 import QtCore, QtGui, QtWidgets # from PySide2 import QtCore, QtGui, QtWidgets, QtPrintSupport
# QtCore.pyqtSignal = QtCore.Signal # QtCore.pyqtSignal = QtCore.Signal
# QtCore.pyqtProperty = QtCore.Property # QtCore.pyqtProperty = QtCore.Property
# QtCore.pyqtSlot = QtCore.Slot # QtCore.pyqtSlot = QtCore.Slot

View File

@ -1,6 +1,7 @@
from nmreval.configs import read_configuration
from .Qt import QtWidgets from .Qt import QtWidgets
from .lib.styles import MyProxyStyle from .lib.styles import MyProxyStyle
from ..configs import read_configuration
class App(QtWidgets.QApplication): class App(QtWidgets.QApplication):

View File

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'resources/_ui/fitcreationdialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(773, 633)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth())
Dialog.setSizePolicy(sizePolicy)
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.splitter = QtWidgets.QSplitter(Dialog)
self.splitter.setOrientation(QtCore.Qt.Vertical)
self.splitter.setObjectName("splitter")
self.tabWidget = QtWidgets.QTabWidget(self.splitter)
self.tabWidget.setObjectName("tabWidget")
self.description_box = QtWidgets.QWidget()
self.description_box.setObjectName("description_box")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.description_box)
self.verticalLayout_2.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.tabWidget.addTab(self.description_box, "")
self.args_box = QtWidgets.QWidget()
self.args_box.setObjectName("args_box")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.args_box)
self.verticalLayout_3.setContentsMargins(3, 3, 3, 3)
self.verticalLayout_3.setSpacing(0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.tabWidget.addTab(self.args_box, "")
self.kwargs_box = QtWidgets.QWidget()
self.kwargs_box.setObjectName("kwargs_box")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.kwargs_box)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.tabWidget.addTab(self.kwargs_box, "")
self.namespace_box = QtWidgets.QWidget()
self.namespace_box.setObjectName("namespace_box")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.namespace_box)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.tabWidget.addTab(self.namespace_box, "")
self.plainTextEdit = CodeEditor(self.splitter)
self.plainTextEdit.setEnabled(True)
self.plainTextEdit.setObjectName("plainTextEdit")
self.verticalLayout.addWidget(self.splitter)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
self.tabWidget.setCurrentIndex(0)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Create fit function"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.description_box), _translate("Dialog", "Description"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.args_box), _translate("Dialog", "Variables"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.kwargs_box), _translate("Dialog", "Multiple choice"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.namespace_box), _translate("Dialog", "Available Functions"))
from ..lib.codeeditor import CodeEditor

View File

@ -310,5 +310,5 @@ class Ui_shift_dialog(object):
self.overwrite_checkbox.setText(_translate("shift_dialog", "Overwrite data")) self.overwrite_checkbox.setText(_translate("shift_dialog", "Overwrite data"))
self.data_newgraph.setText(_translate("shift_dialog", "New graph")) self.data_newgraph.setText(_translate("shift_dialog", "New graph"))
self.values_newgraph.setText(_translate("shift_dialog", "New graph")) self.values_newgraph.setText(_translate("shift_dialog", "New graph"))
from ..lib.utils import SciSpinBox from ..lib.spinboxes import SciSpinBox
from pyqtgraph import PlotWidget from pyqtgraph import PlotWidget

View File

@ -1,3 +1,4 @@
from __future__ import annotations
from collections import OrderedDict from collections import OrderedDict
from itertools import cycle from itertools import cycle
from typing import Any from typing import Any
@ -5,14 +6,14 @@ from typing import Any
import numpy as np import numpy as np
from pyqtgraph import mkPen from pyqtgraph import mkPen
from ...data.points import Points from nmreval.data.points import Points
from ...data.signals import Signal from nmreval.data.signals import Signal
from ...utils.text import convert from nmreval.utils.text import convert
from ...data.bds import BDS from nmreval.data.bds import BDS
from ...lib.colors import BaseColor, TUColors from nmreval.lib.colors import BaseColor, TUColors
from ...lib.lines import LineStyle from nmreval.lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, symbolcycle from nmreval.lib.symbols import SymbolStyle, symbolcycle
from ...data.nmr import Spectrum, FID from nmreval.data.nmr import Spectrum, FID
from ..Qt import QtCore, QtGui from ..Qt import QtCore, QtGui
from ..io.exporters import GraceExporter from ..io.exporters import GraceExporter
@ -254,7 +255,7 @@ class ExperimentContainer(QtCore.QObject):
def has_fits(self): def has_fits(self):
return len(self._fits) != 0 return len(self._fits) != 0
def set_fits(self, value: str or list, replace: bool = False): def set_fits(self, value: str | list, replace: bool = False):
if isinstance(value, str): if isinstance(value, str):
value = [value] value = [value]

Some files were not shown because too many files have changed in this diff Show More