forked from IPKM/nmreval
BUGFIX: VFT;
change to src layout
This commit is contained in:
parent
89ce4bab9f
commit
8d148b639b
@ -2,7 +2,7 @@
|
||||
|
||||
import sys
|
||||
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
|
||||
|
||||
@ -15,8 +15,8 @@ check_for_config()
|
||||
from nmreval.lib.logger import handle_exception
|
||||
sys.excepthook = handle_exception
|
||||
|
||||
from nmreval.gui_qt import App
|
||||
from nmreval.gui_qt.main.mainwindow import NMRMainWindow
|
||||
from gui_qt import App
|
||||
from gui_qt.main.mainwindow import NMRMainWindow
|
||||
|
||||
app = App([])
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= /autohome/dominik/miniconda3/bin/sphinx-build
|
||||
SPHINXBUILD ?= # /autohome/dominik/miniconda3/bin/sphinx-build
|
||||
SOURCEDIR = /autohome/dominik/nmreval/doc/source
|
||||
BUILDDIR = /autohome/dominik/nmreval/doc/_build
|
||||
|
||||
|
@ -1,16 +1,9 @@
|
||||
"""
|
||||
==========
|
||||
T1 minimum
|
||||
==========
|
||||
================================
|
||||
Example of apodization functions
|
||||
================================
|
||||
|
||||
``RelaxationEvaluation`` is used to get width parameter from a T1 minimum.
|
||||
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``
|
||||
This file
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB |
@ -3,25 +3,36 @@
|
||||
.. currentmodule:: {{ module }}
|
||||
|
||||
.. 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 %}
|
||||
.. rubric:: {{ _('Methods') }}
|
||||
|
||||
{% for item in methods %}
|
||||
.. automethod:: {{ item }}
|
||||
{%- endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block attributes %}
|
||||
{% if attributes %}
|
||||
.. rubric:: {{ _('Attributes') }}
|
||||
.. rubric:: Methods
|
||||
|
||||
.. autosummary::
|
||||
{% for item in attributes %}
|
||||
~{{ name }}.{{ item }}
|
||||
{%- endfor %}
|
||||
:toctree:
|
||||
|
||||
{% for item in methods %}
|
||||
{%- if not item.startswith('_') or item in ['__call__'] %} ~{{ name }}.{{ item }}
|
||||
{% 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:
|
||||
|
@ -1,5 +1,2 @@
|
||||
.. automodule:: nmreval.distributions
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
|
@ -11,3 +11,4 @@ Reference
|
||||
models
|
||||
distributions
|
||||
nmr
|
||||
math
|
||||
|
@ -12,7 +12,7 @@
|
||||
#
|
||||
import os
|
||||
import sys
|
||||
sys.path.append('/autohome/dominik/nmreval')
|
||||
sys.path.append(os.path.abspath('../../src'))
|
||||
import nmreval
|
||||
|
||||
|
||||
@ -43,6 +43,9 @@ extensions = [
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx_gallery.gen_gallery',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.autosectionlabel',
|
||||
'sphinx.ext.mathjax',
|
||||
]
|
||||
|
||||
# configuration for intersphinx
|
||||
@ -56,7 +59,7 @@ intersphinx_mapping = {
|
||||
|
||||
# # autodoc options
|
||||
autodoc_typehints = 'none'
|
||||
autodoc_class_signature = 'separated'
|
||||
# autodoc_class_signature = 'separated'
|
||||
autoclass_content = 'class'
|
||||
autodoc_member_order = 'groupwise'
|
||||
#
|
||||
@ -79,6 +82,7 @@ sphinx_gallery_conf = {
|
||||
'min_reported_time': 10000000000,
|
||||
'show_memory': False,
|
||||
'show_signature': False,
|
||||
'line_numbers': True,
|
||||
}
|
||||
|
||||
# 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
|
||||
# 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
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
html_theme_options = {
|
||||
'collapse_navigation': False,
|
||||
'show_prev_next': False,
|
||||
'navbar_end': ['navbar-icon-links.html', 'search-field.html'],
|
||||
'nav_title': 'nmreval',
|
||||
# 'base_url': 'https://chaos3.fkp.physik.tu-darmstadt.de/source/nmreval',
|
||||
'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.
|
||||
@ -183,10 +195,10 @@ html_static_path = ['_static']
|
||||
html_logo = '_static/logo.png'
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
html_sidebars = {'**': ['sidebar-nav-bs.html']}
|
||||
# html_sidebars = {
|
||||
# '**': ['localtoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'],
|
||||
# }
|
||||
html_sidebars = {
|
||||
"**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]
|
||||
}
|
||||
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = False
|
||||
@ -205,7 +217,7 @@ html_last_updated_fmt = ''
|
||||
html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
html_domain_indices = False
|
||||
html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
html_use_index = True
|
||||
@ -214,10 +226,10 @@ html_use_index = True
|
||||
html_split_index = False
|
||||
|
||||
# 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.
|
||||
# html_show_copyright = True
|
||||
html_show_copyright = True
|
||||
|
||||
# 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
|
||||
|
@ -10,15 +10,15 @@ NMREval documentation
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
install.rst
|
||||
user_guide/index
|
||||
gallery/index
|
||||
api/index
|
||||
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
| :ref:`genindex`
|
||||
| :ref:`modindex`
|
||||
|
@ -11,7 +11,8 @@ In general, time signals are calculated by integration of all orientations (see
|
||||
.. math::
|
||||
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.
|
||||
|
||||
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.
|
||||
|
@ -4,10 +4,6 @@
|
||||
Fitting data
|
||||
============
|
||||
|
||||
.. image:: ../_static/fit_dialog.png
|
||||
:scale: 80%
|
||||
:align: center
|
||||
|
||||
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
|
||||
model, to different data simultaneously.
|
||||
|
@ -1,11 +1,13 @@
|
||||
==========
|
||||
**********
|
||||
User Guide
|
||||
==========
|
||||
**********
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
read
|
||||
gui/index
|
||||
read/index
|
||||
edit_signals
|
||||
fit
|
||||
shift_scale
|
||||
|
@ -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.
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
@ -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
|
@ -1,8 +1,8 @@
|
||||
matplotlib
|
||||
numpy
|
||||
scipy
|
||||
pyqt
|
||||
h5py
|
||||
pyqtgraph
|
||||
bsddb3
|
||||
h5py
|
||||
pyqt
|
||||
|
||||
|
@ -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>
|
@ -1,7 +1,7 @@
|
||||
|
||||
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.pyqtProperty = QtCore.Property
|
||||
# QtCore.pyqtSlot = QtCore.Slot
|
@ -1,6 +1,7 @@
|
||||
from nmreval.configs import read_configuration
|
||||
|
||||
from .Qt import QtWidgets
|
||||
from .lib.styles import MyProxyStyle
|
||||
from ..configs import read_configuration
|
||||
|
||||
|
||||
class App(QtWidgets.QApplication):
|
77
src/gui_qt/_py/fitcreationdialog.py
Normal file
77
src/gui_qt/_py/fitcreationdialog.py
Normal 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
|
@ -310,5 +310,5 @@ class Ui_shift_dialog(object):
|
||||
self.overwrite_checkbox.setText(_translate("shift_dialog", "Overwrite data"))
|
||||
self.data_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
|
@ -1,3 +1,4 @@
|
||||
from __future__ import annotations
|
||||
from collections import OrderedDict
|
||||
from itertools import cycle
|
||||
from typing import Any
|
||||
@ -5,14 +6,14 @@ from typing import Any
|
||||
import numpy as np
|
||||
from pyqtgraph import mkPen
|
||||
|
||||
from ...data.points import Points
|
||||
from ...data.signals import Signal
|
||||
from ...utils.text import convert
|
||||
from ...data.bds import BDS
|
||||
from ...lib.colors import BaseColor, TUColors
|
||||
from ...lib.lines import LineStyle
|
||||
from ...lib.symbols import SymbolStyle, symbolcycle
|
||||
from ...data.nmr import Spectrum, FID
|
||||
from nmreval.data.points import Points
|
||||
from nmreval.data.signals import Signal
|
||||
from nmreval.utils.text import convert
|
||||
from nmreval.data.bds import BDS
|
||||
from nmreval.lib.colors import BaseColor, TUColors
|
||||
from nmreval.lib.lines import LineStyle
|
||||
from nmreval.lib.symbols import SymbolStyle, symbolcycle
|
||||
from nmreval.data.nmr import Spectrum, FID
|
||||
|
||||
from ..Qt import QtCore, QtGui
|
||||
from ..io.exporters import GraceExporter
|
||||
@ -254,7 +255,7 @@ class ExperimentContainer(QtCore.QObject):
|
||||
def has_fits(self):
|
||||
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):
|
||||
value = [value]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user