forked from IPKM/nmreval
doc added; reading of isochronal bds
This commit is contained in:
@ -1,3 +1,20 @@
|
||||
"""
|
||||
====================================
|
||||
Data container (:mod:`nmreval.data`)
|
||||
====================================
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated/
|
||||
:nosignatures:
|
||||
|
||||
Points
|
||||
Signal
|
||||
FID
|
||||
Spectrum
|
||||
BDS
|
||||
|
||||
"""
|
||||
|
||||
from .points import Points
|
||||
from .signals import Signal
|
||||
from .bds import BDS
|
||||
|
@ -15,10 +15,11 @@ class BDS(Signal):
|
||||
def __init__(self, x, y, **kwargs: Any):
|
||||
super().__init__(x, y, **kwargs)
|
||||
|
||||
if np.all(self._x > 0) and not np.allclose(np.diff(self._x), self._x[1]-self._x[0]):
|
||||
self.dx = self.x[1] / self.x[0]
|
||||
else:
|
||||
self.dx = self._x[1] - self._x[0]
|
||||
if len(self._x) > 1:
|
||||
if np.all(self._x > 0) and np.allclose(self._x[1:]/self._x[:-1], self._x[1]/self._x[0]):
|
||||
self.dx = self.x[1] / self.x[0]
|
||||
else:
|
||||
self.dx = self._x[1] - self._x[0]
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.meta['mode']}: {self.name}"
|
||||
@ -32,10 +33,10 @@ class BDS(Signal):
|
||||
window_length (int)
|
||||
|
||||
Returns:
|
||||
Points
|
||||
Points:
|
||||
New Points instance with
|
||||
|
||||
References:
|
||||
Reference:
|
||||
Wübbenhorst, M.; van Turnhout, J.: Analysis of complex dielectric spectra.
|
||||
I. One-dimensional derivative techniques and three-dimensional modelling.
|
||||
J. Non-Cryst. Solid. 305 (2002) https://doi.org/10.1016/s0022-3093(02)01086-4
|
||||
|
@ -7,6 +7,9 @@ from .signals import Signal
|
||||
|
||||
|
||||
class FID(Signal):
|
||||
"""
|
||||
Extensions if :class:`Signal` for NMR timesignals
|
||||
"""
|
||||
def __init__(self, x, y, **kwargs):
|
||||
super().__init__(x, y, **kwargs)
|
||||
|
||||
@ -16,7 +19,16 @@ class FID(Signal):
|
||||
def __repr__(self):
|
||||
return f"FID: {self.name}"
|
||||
|
||||
def baseline(self, percentage=0.12):
|
||||
def baseline(self, percentage: float = 0.12):
|
||||
"""
|
||||
Substract
|
||||
|
||||
Args:
|
||||
percentage:
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
self._y -= self._y[int(-percentage * self.length):].mean()
|
||||
|
||||
return self
|
||||
@ -51,7 +63,7 @@ class FID(Signal):
|
||||
|
||||
return self
|
||||
|
||||
def fourier(self):
|
||||
def fourier(self) -> 'Spectrum':
|
||||
ft = np.fft.fftshift(np.fft.fft(self._y)) / self.dx
|
||||
freq = np.fft.fftshift(np.fft.fftfreq(self.length, self.dx))
|
||||
|
||||
@ -63,9 +75,15 @@ class FID(Signal):
|
||||
def fft_depake(self, scale: bool = False):
|
||||
"""
|
||||
Calculate deconvoluted Pake spectra
|
||||
M.A. McCabe, S.R. Wassail:
|
||||
Rapid deconvolution of NMR powder spectra by weighted fast Fourier transformation,
|
||||
SSNMR (1997), Vol.10, Nr.1-2, pp. 53-61,
|
||||
|
||||
Args:
|
||||
scale (bool):
|
||||
|
||||
Reference:
|
||||
M.A. McCabe, S.R. Wassail:
|
||||
Rapid deconvolution of NMR powder spectra by weighted fast Fourier transformation,
|
||||
SSNMR (1997), Vol.10, Nr.1-2, pp. 53-61
|
||||
|
||||
"""
|
||||
_y = self._y + 0
|
||||
# Perform FFT depaking
|
||||
@ -102,8 +120,9 @@ class FID(Signal):
|
||||
self._y_err = np.std(self._y[-int(0.1*self.length):])/1.41
|
||||
return self._y_err * np.ones(self.length)
|
||||
|
||||
def shift(self, points: Union[str, float], mode: str = 'pts'):
|
||||
def shift(self, points: int, mode: str = 'pts') -> None:
|
||||
"""
|
||||
Shift y values to new x indexes
|
||||
|
||||
Args:
|
||||
points : shift value,
|
||||
@ -113,13 +132,17 @@ class FID(Signal):
|
||||
|
||||
"""
|
||||
if mode == 'pts':
|
||||
super().shift(points)
|
||||
super().shift(int(points))
|
||||
else:
|
||||
pts = int(points//self.dx)
|
||||
super().shift(pts)
|
||||
|
||||
|
||||
class Spectrum(Signal):
|
||||
"""
|
||||
Extension of :class:`Signal` for NMR spectra
|
||||
"""
|
||||
|
||||
def __init__(self, x, y, dx=None, **kwargs):
|
||||
super().__init__(x, y, **kwargs)
|
||||
if dx is None:
|
||||
@ -139,7 +162,7 @@ class Spectrum(Signal):
|
||||
|
||||
return self
|
||||
|
||||
def fourier(self):
|
||||
def fourier(self) -> FID:
|
||||
ft = np.fft.ifft(np.fft.ifftshift(self._y * self.dx))
|
||||
t = np.arange(len(ft))*self.dx
|
||||
shifted = np.fft.ifftshift(self._x)[0]
|
||||
@ -172,8 +195,8 @@ class Spectrum(Signal):
|
||||
|
||||
return self._y_err * np.ones(self.length)
|
||||
|
||||
def shift(self, points, mode='pts'):
|
||||
def shift(self, points: int, mode: str = 'pts'):
|
||||
if mode == 'pts':
|
||||
super().shift(points)
|
||||
super().shift(int(points))
|
||||
else:
|
||||
return self
|
||||
|
@ -412,11 +412,15 @@ class Points:
|
||||
def diff(self, log: bool = False, limits: Optional[Tuple[float, float]] = None) -> PointLike:
|
||||
"""
|
||||
|
||||
Calculate first derivate :math:`dy/dx` or :math:`dy/d(\ln x)`.
|
||||
|
||||
|
||||
Args:
|
||||
log:
|
||||
limits:
|
||||
log (bool) : Flag if derivative is with respect to ln(x) instead of x. Default is `False`.
|
||||
limits (tuple, optional): Range `(xmin, xmax)` which is differentiated.
|
||||
|
||||
Returns:
|
||||
Copy of set with new y values.
|
||||
|
||||
"""
|
||||
|
||||
@ -430,6 +434,8 @@ class Points:
|
||||
else:
|
||||
new_data.y = np.gradient(new_data.y, new_data.x)
|
||||
|
||||
new_data.remove(np.argwhere(np.isnan(new_data.y)))
|
||||
|
||||
return new_data
|
||||
|
||||
def magnitude(self) -> PointLike:
|
||||
@ -530,6 +536,8 @@ class Points:
|
||||
|
||||
def shift(self, points: int) -> PointLike:
|
||||
"""
|
||||
Shift indexes of y values.
|
||||
|
||||
Move y values `points` indexes, remove invalid indexes and fill remaining with zeros
|
||||
Negative `points` shift to the left, positive `points` shift to the right
|
||||
|
||||
@ -558,11 +566,21 @@ class Points:
|
||||
|
||||
return self
|
||||
|
||||
def sort(self, axis=0):
|
||||
if axis == 0:
|
||||
def sort(self, axis: str = 'x') -> PointLike:
|
||||
"""
|
||||
Sort data in increased order.
|
||||
|
||||
Args:
|
||||
axis (str, {`x`, `y`}) : Axis that determines new order. Default is `x`
|
||||
|
||||
"""
|
||||
|
||||
if axis == 'x':
|
||||
sort_order = np.argsort(self._x)
|
||||
else:
|
||||
elif axis == 'y':
|
||||
sort_order = np.argsort(self._y)
|
||||
else:
|
||||
raise ValueError('Unknown sort axis, use `x` or `y`.')
|
||||
self._x = self._x[sort_order]
|
||||
self._y = self._y[sort_order]
|
||||
self._y_err = self._y_err[sort_order]
|
||||
|
@ -6,7 +6,7 @@ from .points import Points
|
||||
|
||||
class Signal(Points):
|
||||
"""
|
||||
Extension of Points for complex y values.
|
||||
Extension of :class:`Points` for complex y values.
|
||||
"""
|
||||
|
||||
def __init__(self, x, y, **kwargs):
|
||||
@ -18,7 +18,10 @@ class Signal(Points):
|
||||
|
||||
super().__init__(x, y, **kwargs)
|
||||
|
||||
self.dx = kwargs.get('dx', abs(self._x[1] - self._x[0]))
|
||||
if len(self._x) > 1:
|
||||
self.dx = kwargs.get('dx', abs(self._x[1] - self._x[0]))
|
||||
else:
|
||||
self.dx = 0
|
||||
self.meta.update({'phase': [], 'shift': 0})
|
||||
|
||||
def __repr__(self):
|
||||
|
Reference in New Issue
Block a user