Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/nmrsim/_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import numpy as np

from nmrsim.firstorder import first_order_spin_system, multiplet
from nmrsim.math import reduce_peaks, add_lorentzians
from nmrsim.math import reduce_peaks, add_lorentzians_limitable
from nmrsim.qm import qm_spinsystem
from nmrsim._utils import low_high

Expand Down Expand Up @@ -73,7 +73,7 @@ def __init__(self, v, I, J, w=0.5):
self.I = I
self.J = J
self.w = w
self._peaklist = multiplet((v, I), J)
self._peaklist = multiplet((v, I, w), J)

def __eq__(self, other):
if hasattr(other, "peaklist") and callable(other.peaklist):
Expand All @@ -87,7 +87,7 @@ def __add__(self, other):

def __mul__(self, scalar):
if isinstance(scalar, numbers.Real):
return Multiplet(self.v, self.I * scalar, self.J)
return Multiplet(self.v, self.I * scalar, self.J, self.w)
else:
return NotImplemented

Expand All @@ -105,7 +105,7 @@ def __itruediv__(self, scalar):
return self.__imul__(1 / scalar)

def _refresh(self):
self._peaklist = multiplet((self.v, self.I), self.J)
self._peaklist = multiplet((self.v, self.I, self.w), self.J)

def peaklist(self):
"""
Expand Down Expand Up @@ -245,9 +245,9 @@ def peaklist(self):
Array of (frequency, intensity) signals.
"""
if self._second_order:
return qm_spinsystem(self._v, self._J)
return qm_spinsystem(self._v, self._J, width=self.w)
else:
return first_order_spin_system(self._v, self._J)
return first_order_spin_system(self._v, self._J, self.w)

def __eq__(self, other):
if hasattr(other, "peaklist") and callable(other.peaklist):
Expand Down Expand Up @@ -368,7 +368,7 @@ def lineshape(self, points=800):
"""
vmin, vmax = low_high((self.vmin, self.vmax))
x = np.linspace(vmin, vmax, points)
y = [add_lorentzians(x, c.peaklist(), c.w) for c in self._components]
y = [add_lorentzians_limitable(x, c.peaklist()) for c in self._components]
y_sum = np.sum(y, 0)
return x, y_sum

Expand Down
40 changes: 22 additions & 18 deletions src/nmrsim/discrete.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ def AB(Jab, Vab, Vcentr, normalize=True):

Returns
-------
[(float, float)...]
A list of four (frequency, intensity) tuples.
[(float, float, float)...]
A list of four (frequency, intensity, width) tuples.
"""
J = Jab
dv = Vab
Expand All @@ -73,9 +73,10 @@ def AB(Jab, Vab, Vcentr, normalize=True):
I4 = I1
vList = [v1, v2, v3, v4]
IList = [I1, I2, I3, I4]
wList = [0.5 for _ in range(len(IList))]
if normalize:
_normalize(IList, 2)
return list(zip(vList, IList))
return list(zip(vList, IList, wList))


def AB2(Jab, Vab, Vcentr, normalize=True):
Expand All @@ -96,8 +97,8 @@ def AB2(Jab, Vab, Vcentr, normalize=True):

Returns
-------
[(float, float)...]
a list of (frequency, intensity) tuples.
[(float, float, float)...]
a list of (frequency, intensity, width) tuples.
"""
# There is a disconnect between the variable names in the WINDNMR GUI and
# the variable names in this function.
Expand Down Expand Up @@ -148,10 +149,11 @@ def AB2(Jab, Vab, Vcentr, normalize=True):
I9 = (sqrt(2) * sin_dtheta + sintheta_plus * sintheta_minus) ** 2
vList = [V1, V2, V3, V4, V5, V6, V7, V8, V9]
IList = [I1, I2, I3, I4, I5, I6, I7, I8, I9]
wList = [0.5 for _ in range(len(IList))]

if normalize:
_normalize(IList, 3)
return list(zip(vList, IList))
return list(zip(vList, IList, wList))


def ABX(Jab, Jax, Jbx, Vab, Vcentr, vx, normalize=True):
Expand Down Expand Up @@ -181,8 +183,8 @@ def ABX(Jab, Jax, Jbx, Vab, Vcentr, vx, normalize=True):

Returns
-------
[(float, float)...]
a list of (frequency, intensity) tuples.
[(float, float, float)...]
a list of (frequency, intensity, width) tuples.
"""
# Contradictions in naming between WINDNMR's interface, internal code, and
# Pople/Schneider/Bernstein "fixed" with these reassignments:
Expand Down Expand Up @@ -239,9 +241,10 @@ def ABX(Jab, Jax, Jbx, Vab, Vcentr, vx, normalize=True):
I14 = I13
VList = [V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V14]
IList = [I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14]
wList = [0.5 for _ in range(len(IList))]
if normalize:
_normalize(IList, 3)
return list(zip(VList, IList))
return list(zip(VList, IList, wList))


def ABX3(Jab, Jax, Jbx, Vab, Vcentr):
Expand All @@ -264,14 +267,14 @@ def ABX3(Jab, Jax, Jbx, Vab, Vcentr):

Returns
-------
[(float, float)...]
a list of (frequency, intensity) tuples.
[(float, float, float)...]
a list of (frequency, intensity, width) tuples.
"""
# First: simulate two quartets for va and vb ("Jab turned off")
va = Vcentr - Vab / 2
vb = Vcentr + Vab / 2
a_quartet = multiplet((va, 1), [(Jax, 3)])
b_quartet = multiplet((vb, 1), [(Jbx, 3)])
a_quartet = multiplet((va, 1, 0.5), [(Jax, 3)])
b_quartet = multiplet((vb, 1, 0.5), [(Jbx, 3)])
res = []
# Then: for each pair of a and b singlets in the quartets, calculate an
# AB quartet ("Turn Jab on").
Expand All @@ -280,7 +283,7 @@ def ABX3(Jab, Jax, Jbx, Vab, Vcentr):
abcenter = (b_quartet[i][0] + a_quartet[i][0]) / 2
sub_abq = AB(Jab, dv, abcenter, normalize=True)
scale_factor = a_quartet[i][1]
scaled_sub_abq = [(v, i * scale_factor) for v, i in sub_abq]
scaled_sub_abq = [(v, i * scale_factor, w) for v, i, w in sub_abq]
res.extend(scaled_sub_abq)
return res

Expand All @@ -305,8 +308,8 @@ def AAXX(Jaa, Jxx, Jax, Jax_prime, Vcentr, normalize=True):

Returns
-------
[(float, float)...]
a list of (frequency, intensity) tuples.
[(float, float, float)...]
a list of (frequency, intensity, width) tuples.
"""
# Define the constants required to calculate frequencies and intensities

Expand Down Expand Up @@ -347,9 +350,10 @@ def AAXX(Jaa, Jxx, Jax, Jax_prime, Vcentr, normalize=True):

VList = [V1, V2, V3, V4, V5, V6, V7, V8, V9, V10]
IList = [I1, I2, I3, I4, I5, I6, I7, I8, I9, I10]
wList = [0.5 for _ in range(len(IList))]
if normalize:
_normalize(IList, 2)
return list(zip(VList, IList))
return list(zip(VList, IList, wList))


def AABB(Vab, Jaa, Jbb, Jab, Jab_prime, Vcentr, normalize=True, **kwargs):
Expand All @@ -374,7 +378,7 @@ def AABB(Vab, Jaa, Jbb, Jab, Jab_prime, Vcentr, normalize=True, **kwargs):

Returns
-------
[(float, float)...]
[(float, float, float)...]
a list of (frequency, intensity) tuples.
"""
from nmrsim.qm import qm_spinsystem
Expand Down
18 changes: 10 additions & 8 deletions src/nmrsim/firstorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ def _doublet(plist, J):
a list of (frequency, intensity) tuples.
"""
res = []
for v, i in plist:
res.append((v - J / 2, i / 2))
res.append((v + J / 2, i / 2))
for v, i, w in plist:
res.append((v - J / 2, i / 2, w))
res.append((v + J / 2, i / 2, w))
return res


Expand All @@ -43,8 +43,8 @@ def multiplet(signal, couplings):

Parameters
---------
signal : (float, float)
a (frequency (Hz), intensity) tuple;
signal : (float, float, float)
a (frequency (Hz), intensity, width (Hz)) tuple;
couplings : [(float, int)...]
A list of (*J*, # of nuclei) tuples. The order of the tuples in
couplings does not matter.
Expand All @@ -64,7 +64,7 @@ def multiplet(signal, couplings):
return sorted(reduce_peaks(res))


def first_order_spin_system(v, J):
def first_order_spin_system(v, J, w):
"""
Create a first-order peaklist of several multiplets from the same v/J
arguments used for qm calculations.
Expand All @@ -80,16 +80,18 @@ def first_order_spin_system(v, J):
an array of frequencies
J : 2D array-like (square)
a matrix of J coupling constants
w : float or int
peak width at half height (Hz)

Returns
-------
[(float, float)...]
[(float, float, float)...]
a combined peaklist of signals for all the multiplets in the spin
system.
"""
result = []
for i, v_ in enumerate(v):
couplings = ((j, 1) for j in J[i] if j != 0)
signal = multiplet((v_, 1), couplings)
signal = multiplet((v_, 1, w), couplings)
result += signal
return reduce_peaks(sorted(result))
Loading