added f-omega option to log-fourier transform; closes #134
This commit is contained in:
parent
dbb35cdba4
commit
9c5d91918f
@ -1,10 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'resources/_ui/integratederive_dialog.ui'
|
# Form implementation generated from reading ui file 'src/resources/_ui/integratederive_dialog.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.12.3
|
# Created by: PyQt5 UI code generator 5.15.9
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# 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
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
@ -13,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||||||
class Ui_Dialog(object):
|
class Ui_Dialog(object):
|
||||||
def setupUi(self, Dialog):
|
def setupUi(self, Dialog):
|
||||||
Dialog.setObjectName("Dialog")
|
Dialog.setObjectName("Dialog")
|
||||||
Dialog.resize(400, 308)
|
Dialog.resize(400, 375)
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
|
self.verticalLayout = QtWidgets.QVBoxLayout(Dialog)
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
self.listWidget = QtWidgets.QListWidget(Dialog)
|
self.listWidget = QtWidgets.QListWidget(Dialog)
|
||||||
@ -49,6 +50,9 @@ class Ui_Dialog(object):
|
|||||||
self.log_checkbox = QtWidgets.QCheckBox(Dialog)
|
self.log_checkbox = QtWidgets.QCheckBox(Dialog)
|
||||||
self.log_checkbox.setObjectName("log_checkbox")
|
self.log_checkbox.setObjectName("log_checkbox")
|
||||||
self.verticalLayout.addWidget(self.log_checkbox)
|
self.verticalLayout.addWidget(self.log_checkbox)
|
||||||
|
self.freq_box = QtWidgets.QCheckBox(Dialog)
|
||||||
|
self.freq_box.setObjectName("freq_box")
|
||||||
|
self.verticalLayout.addWidget(self.freq_box)
|
||||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||||
self.horizontalLayout_2.setContentsMargins(-1, 0, -1, -1)
|
self.horizontalLayout_2.setContentsMargins(-1, 0, -1, -1)
|
||||||
self.horizontalLayout_2.setSpacing(3)
|
self.horizontalLayout_2.setSpacing(3)
|
||||||
@ -67,8 +71,8 @@ class Ui_Dialog(object):
|
|||||||
self.verticalLayout.addWidget(self.buttonBox)
|
self.verticalLayout.addWidget(self.buttonBox)
|
||||||
|
|
||||||
self.retranslateUi(Dialog)
|
self.retranslateUi(Dialog)
|
||||||
self.buttonBox.accepted.connect(Dialog.accept)
|
self.buttonBox.accepted.connect(Dialog.accept) # type: ignore
|
||||||
self.buttonBox.rejected.connect(Dialog.reject)
|
self.buttonBox.rejected.connect(Dialog.reject) # type: ignore
|
||||||
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||||
|
|
||||||
def retranslateUi(self, Dialog):
|
def retranslateUi(self, Dialog):
|
||||||
@ -80,4 +84,5 @@ class Ui_Dialog(object):
|
|||||||
self.ft_comboBox.setItemText(1, _translate("Dialog", "Imag"))
|
self.ft_comboBox.setItemText(1, _translate("Dialog", "Imag"))
|
||||||
self.ft_comboBox.setItemText(2, _translate("Dialog", "Complex"))
|
self.ft_comboBox.setItemText(2, _translate("Dialog", "Complex"))
|
||||||
self.log_checkbox.setText(_translate("Dialog", "use logarithmic x axis"))
|
self.log_checkbox.setText(_translate("Dialog", "use logarithmic x axis"))
|
||||||
|
self.freq_box.setText(_translate("Dialog", "return x axis as f, not omega"))
|
||||||
self.newgraph_checkbox.setText(_translate("Dialog", "New graph"))
|
self.newgraph_checkbox.setText(_translate("Dialog", "New graph"))
|
||||||
|
@ -1139,13 +1139,14 @@ class UpperManagement(QtCore.QObject):
|
|||||||
def logft(self, **kwargs):
|
def logft(self, **kwargs):
|
||||||
new_sets = []
|
new_sets = []
|
||||||
ft_mode = kwargs['ft_mode']
|
ft_mode = kwargs['ft_mode']
|
||||||
|
return_f = kwargs['return_f']
|
||||||
|
|
||||||
for set_id in kwargs['sets']:
|
for set_id in kwargs['sets']:
|
||||||
data_i = self.data[set_id]
|
data_i = self.data[set_id]
|
||||||
if ft_mode in ['cos', 'sin']:
|
if ft_mode in ['cos', 'sin']:
|
||||||
new_data = Points(*logft(data_i.x, data_i.y, mode=ft_mode))
|
new_data = Points(*logft(data_i.x, data_i.y, mode=ft_mode, return_f=return_f))
|
||||||
else:
|
else:
|
||||||
new_data = Signal(*logft(data_i.x, data_i.y, mode=ft_mode))
|
new_data = Signal(*logft(data_i.x, data_i.y, mode=ft_mode, return_f=return_f))
|
||||||
|
|
||||||
new_sets.append(self.add(new_data, color=data_i['color'], symbol=data_i['symbol'], line=data_i['line']))
|
new_sets.append(self.add(new_data, color=data_i['color'], symbol=data_i['symbol'], line=data_i['line']))
|
||||||
self.data[new_sets[-1]].update(data_i.data.meta)
|
self.data[new_sets[-1]].update(data_i.data.meta)
|
||||||
|
@ -16,16 +16,19 @@ class QDeriveIntegrate(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.start_lineedit.setValidator(QtGui.QDoubleValidator())
|
self.start_lineedit.setValidator(QtGui.QDoubleValidator())
|
||||||
self.stop_lineedit.setValidator(QtGui.QDoubleValidator())
|
self.stop_lineedit.setValidator(QtGui.QDoubleValidator())
|
||||||
self.ft_comboBox.hide()
|
self.ft_comboBox.hide()
|
||||||
|
self.freq_box.hide()
|
||||||
|
|
||||||
elif self.mode == 'd':
|
elif self.mode == 'd':
|
||||||
self.setWindowTitle('Differentiation dialog')
|
self.setWindowTitle('Differentiation dialog')
|
||||||
self.widget.hide()
|
self.widget.hide()
|
||||||
self.ft_comboBox.hide()
|
self.ft_comboBox.hide()
|
||||||
|
self.freq_box.hide()
|
||||||
|
|
||||||
elif self.mode == 'l':
|
elif self.mode == 'l':
|
||||||
self.setWindowTitle('Logarithmic FT dialog')
|
self.setWindowTitle('Logarithmic FT dialog')
|
||||||
self.log_checkbox.hide()
|
self.log_checkbox.hide()
|
||||||
self.widget.hide()
|
self.widget.hide()
|
||||||
|
self.freq_box.show()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f'Unknown mode {mode}, use "d", "i", or "l".')
|
raise ValueError(f'Unknown mode {mode}, use "d", "i", or "l".')
|
||||||
@ -54,8 +57,10 @@ class QDeriveIntegrate(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
self.stop_lineedit.setEnabled(full_range != QtCore.Qt.Checked)
|
self.stop_lineedit.setEnabled(full_range != QtCore.Qt.Checked)
|
||||||
|
|
||||||
def get_options(self):
|
def get_options(self):
|
||||||
opts = {'graph': '' if self.newgraph_checkbox.isChecked() else self.graph_combobox.currentData(),
|
opts = {
|
||||||
'mode': self.mode, 'sets': []}
|
'graph': '' if self.newgraph_checkbox.isChecked() else self.graph_combobox.currentData(),
|
||||||
|
'mode': self.mode, 'sets': []
|
||||||
|
}
|
||||||
|
|
||||||
if self.mode == 'i':
|
if self.mode == 'i':
|
||||||
start = None
|
start = None
|
||||||
@ -75,6 +80,7 @@ class QDeriveIntegrate(QtWidgets.QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
if self.mode == 'l':
|
if self.mode == 'l':
|
||||||
opts['ft_mode'] = ['cos', 'sin', 'complex'][self.ft_comboBox.currentIndex()]
|
opts['ft_mode'] = ['cos', 'sin', 'complex'][self.ft_comboBox.currentIndex()]
|
||||||
|
opts['return_f'] = self.freq_box.isChecked()
|
||||||
else:
|
else:
|
||||||
opts['log'] = self.log_checkbox.isChecked()
|
opts['log'] = self.log_checkbox.isChecked()
|
||||||
|
|
||||||
|
@ -27,10 +27,13 @@ More details can be found in [Blo]
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def logft_cos(x, y, new_x=None):
|
def logft_cos(
|
||||||
n = x.size
|
x: np.ndarray,
|
||||||
if new_x is None:
|
y: np.ndarray,
|
||||||
new_x = 2*np.pi * np.geomspace(1/np.max(x), 1/np.min(x), num=n)
|
new_x: np.ndarray = None,
|
||||||
|
return_f: bool = True,
|
||||||
|
):
|
||||||
|
n, new_x, divide_by = _prepare_calculation(x, new_x, return_f)
|
||||||
|
|
||||||
dydx = np.diff(y) / np.diff(x)
|
dydx = np.diff(y) / np.diff(x)
|
||||||
|
|
||||||
@ -48,13 +51,16 @@ def logft_cos(x, y, new_x=None):
|
|||||||
|
|
||||||
ret_val /= new_x**2
|
ret_val /= new_x**2
|
||||||
|
|
||||||
return new_x, ret_val
|
return new_x/divide_by, ret_val
|
||||||
|
|
||||||
|
|
||||||
def logft_sin(x, y, new_x=None):
|
def logft_sin(
|
||||||
n = x.size
|
x: np.ndarray,
|
||||||
if new_x is None:
|
y: np.ndarray,
|
||||||
new_x = 2*np.pi * np.geomspace(1/np.max(x), 1/np.min(x), num=n)
|
new_x: np.ndarray = None,
|
||||||
|
return_f: bool = True,
|
||||||
|
):
|
||||||
|
n, new_x, divide_by = _prepare_calculation(x, new_x, return_f)
|
||||||
|
|
||||||
dydx = np.diff(y) / np.diff(x)
|
dydx = np.diff(y) / np.diff(x)
|
||||||
|
|
||||||
@ -73,13 +79,20 @@ def logft_sin(x, y, new_x=None):
|
|||||||
ret_val /= new_x**2
|
ret_val /= new_x**2
|
||||||
ret_val += y[0] / new_x
|
ret_val += y[0] / new_x
|
||||||
|
|
||||||
return new_x, ret_val
|
return new_x/divide_by, ret_val
|
||||||
|
|
||||||
|
|
||||||
def logft_cmplx(x, y, new_x=None, backward: bool = False):
|
def logft_cmplx(
|
||||||
n = x.size
|
x: np.ndarray,
|
||||||
if new_x is None:
|
y: np.ndarray,
|
||||||
new_x = 2 * np.pi * np.geomspace(1/np.max(x), 1/np.min(x), num=n)
|
new_x: np.ndarray = None,
|
||||||
|
backward: bool = False,
|
||||||
|
return_f: bool = True,
|
||||||
|
):
|
||||||
|
if backward:
|
||||||
|
return_f = False
|
||||||
|
|
||||||
|
n, new_x, divide_by = _prepare_calculation(x, new_x, return_f)
|
||||||
|
|
||||||
dydx = np.diff(y) / np.diff(x)
|
dydx = np.diff(y) / np.diff(x)
|
||||||
|
|
||||||
@ -98,16 +111,22 @@ def logft_cmplx(x, y, new_x=None, backward: bool = False):
|
|||||||
ret_val /= new_x**2
|
ret_val /= new_x**2
|
||||||
ret_val += sign * 1j*y[0]/new_x
|
ret_val += sign * 1j*y[0]/new_x
|
||||||
|
|
||||||
return new_x, ret_val
|
return new_x/divide_by, ret_val
|
||||||
|
|
||||||
|
|
||||||
def logft(x, y, new_x=None, mode='cos'):
|
def logft(
|
||||||
|
x: np.ndarray,
|
||||||
|
y: np.ndarray,
|
||||||
|
new_x: np.ndarray = None,
|
||||||
|
mode: str = 'cos',
|
||||||
|
return_f: bool = True,
|
||||||
|
):
|
||||||
if mode not in ['cos', 'sin', 'complex']:
|
if mode not in ['cos', 'sin', 'complex']:
|
||||||
raise ValueError(f'Unknown mode {mode}, use "cos", "sin", "complex".')
|
raise ValueError(f'Unknown mode {mode}, use "cos", "sin", "complex".')
|
||||||
|
|
||||||
ft_func = {'cos': logft_cos, 'sin': logft_sin, 'complex': logft_cmplx}[mode]
|
ft_func = {'cos': logft_cos, 'sin': logft_sin, 'complex': logft_cmplx}[mode]
|
||||||
|
|
||||||
return ft_func(x, y, new_x=new_x)
|
return ft_func(x, y, new_x=new_x, return_f=return_f)
|
||||||
|
|
||||||
|
|
||||||
def logift(x, y, new_x=None, mode='cos'):
|
def logift(x, y, new_x=None, mode='cos'):
|
||||||
@ -120,3 +139,15 @@ def logift(x, y, new_x=None, mode='cos'):
|
|||||||
return logft_cos(x, y, new_x=new_x)
|
return logft_cos(x, y, new_x=new_x)
|
||||||
else:
|
else:
|
||||||
return logft_sin(x, y, new_x=new_x)
|
return logft_sin(x, y, new_x=new_x)
|
||||||
|
|
||||||
|
|
||||||
|
def _prepare_calculation(x: np.ndarray, new_x: np.ndarray | None, return_f: bool):
|
||||||
|
divide_by = 1.
|
||||||
|
n = x.size
|
||||||
|
if new_x is None:
|
||||||
|
if return_f:
|
||||||
|
divide_by = 2*np.pi
|
||||||
|
new_x = 2 * np.pi * np.geomspace(1 / np.max(x), 1 / np.min(x), num=n)
|
||||||
|
|
||||||
|
return n, new_x, divide_by
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>308</height>
|
<height>375</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -92,6 +92,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="freq_box">
|
||||||
|
<property name="text">
|
||||||
|
<string>return x axis as f, not omega</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
|
Loading…
Reference in New Issue
Block a user