change layout
This commit is contained in:
parent
3e1325f3ca
commit
66e8925241
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"simulation": {
|
"simulation": {
|
||||||
"num_walker": 20000,
|
"num_walker": 30000,
|
||||||
"seed": null
|
"seed": null
|
||||||
},
|
},
|
||||||
"molecule": {
|
"molecule": {
|
||||||
@ -9,15 +9,10 @@
|
|||||||
},
|
},
|
||||||
"correlation_times": {
|
"correlation_times": {
|
||||||
"distribution": "DeltaDistribution",
|
"distribution": "DeltaDistribution",
|
||||||
"tau": {
|
"tau": 1e-3
|
||||||
"start": 1e-3,
|
|
||||||
"stop": 1e0,
|
|
||||||
"steps": 1,
|
|
||||||
"is_log": true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"motion": {
|
"motion": {
|
||||||
"model": "RandomJump"
|
"model": "TetrahedralJump"
|
||||||
},
|
},
|
||||||
"spectrum": {
|
"spectrum": {
|
||||||
"dwell_time": 1e-6,
|
"dwell_time": 1e-6,
|
||||||
@ -37,16 +32,16 @@
|
|||||||
},
|
},
|
||||||
"stimulated_echo": {
|
"stimulated_echo": {
|
||||||
"t_evo": {
|
"t_evo": {
|
||||||
"start": 10e-6,
|
"start": 1e-6,
|
||||||
"stop": 100e-6,
|
"stop": 100e-6,
|
||||||
"steps": 98
|
"steps": 99
|
||||||
},
|
},
|
||||||
"t_mix": {
|
"t_mix": {
|
||||||
"start": 1e-7,
|
"start": 1e-6,
|
||||||
"stop": 1e-1,
|
"stop": 1e0,
|
||||||
"steps": 31,
|
"steps": 19,
|
||||||
"is_log": true
|
"is_log": true
|
||||||
},
|
},
|
||||||
"t_echo": 15e-6
|
"t_echo": 0e-6
|
||||||
}
|
}
|
||||||
}
|
}
|
22
main.py
Normal file
22
main.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from numpy.random import default_rng
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from rwsims.sims import run_ste_sim, run_spectrum_sim
|
||||||
|
from rwsims.motions import TetrahedralJump
|
||||||
|
|
||||||
|
|
||||||
|
# run_ste_sim('config.json')
|
||||||
|
# run_spectrum_sim('config.json')
|
||||||
|
|
||||||
|
rng = default_rng()
|
||||||
|
|
||||||
|
tetra = TetrahedralJump(1, 0, rng)
|
||||||
|
|
||||||
|
for _ in range(100):
|
||||||
|
tetra.start()
|
||||||
|
omegas = tetra.jump(100)
|
||||||
|
|
||||||
|
plt.plot(omegas, '.')
|
||||||
|
break
|
||||||
|
|
||||||
|
plt.show()
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.typing import ArrayLike
|
# from numpy.typing import ArrayLike
|
||||||
from numpy.random import Generator
|
from numpy.random import Generator
|
||||||
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.typing import ArrayLike
|
# from numpy.typing import ArrayLike
|
||||||
|
|
||||||
from distributions import BaseDistribution
|
from .distributions import BaseDistribution
|
||||||
from motions import BaseMotion
|
from .motions import BaseMotion
|
||||||
|
|
||||||
|
|
||||||
def ste(x, a, f_infty, tau, beta):
|
def ste(x, a, f_infty, tau, beta):
|
||||||
return a*((1-f_infty) * np.exp(-(x/tau)**beta) + f_infty)
|
return a*((1-f_infty) * np.exp(-(x/tau)**beta) + f_infty)
|
||||||
|
|
||||||
|
|
||||||
def pulse_attn(freq: ArrayLike, t_pulse: float) -> ArrayLike:
|
def pulse_attn(freq, t_pulse: float):
|
||||||
# cf. Schmitt-Rohr/Spieß eq. 2.126; omega_1 * t_p = pi/2
|
# cf. Schmitt-Rohr/Spieß eq. 2.126; omega_1 * t_p = pi/2
|
||||||
pi_half_squared = np.pi**2 / 4
|
pi_half_squared = np.pi**2 / 4
|
||||||
omega = 2 * np.pi * freq
|
omega = 2 * np.pi * freq
|
||||||
@ -19,4 +19,4 @@ def pulse_attn(freq: ArrayLike, t_pulse: float) -> ArrayLike:
|
|||||||
numerator = np.sin(np.sqrt(pi_half_squared + omega**2 * t_pulse**2 / 2))
|
numerator = np.sin(np.sqrt(pi_half_squared + omega**2 * t_pulse**2 / 2))
|
||||||
denominator = np.sqrt(pi_half_squared + omega**2 * t_pulse**2 / 4)
|
denominator = np.sqrt(pi_half_squared + omega**2 * t_pulse**2 / 4)
|
||||||
|
|
||||||
return np.pi * numerator/denominator / 2
|
return np.pi * numerator/denominator / 2
|
@ -4,7 +4,6 @@ from abc import ABC, abstractmethod
|
|||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy.random import Generator
|
from numpy.random import Generator
|
||||||
from numpy.typing import ArrayLike
|
|
||||||
|
|
||||||
|
|
||||||
class BaseMotion(ABC):
|
class BaseMotion(ABC):
|
||||||
@ -26,7 +25,7 @@ class BaseMotion(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def jump(self, size: int = 1) -> ArrayLike:
|
def jump(self, size: int = 1) -> 'ArrayLike':
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ class RandomJump(BaseMotion):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Random Jump'
|
return 'Random Jump'
|
||||||
|
|
||||||
def jump(self, size: int = 1) -> ArrayLike:
|
def jump(self, size: int = 1) -> 'ArrayLike':
|
||||||
return omega_q(self._delta, self._eta, *draw_orientation(self._rng, size=size))
|
return omega_q(self._delta, self._eta, *draw_orientation(self._rng, size=size))
|
||||||
|
|
||||||
|
|
||||||
@ -74,15 +73,28 @@ class TetrahedralJump(BaseMotion):
|
|||||||
corners[0],
|
corners[0],
|
||||||
np.array(spherical_to_xyz(1., np.arccos(cos_theta0), phi0)),
|
np.array(spherical_to_xyz(1., np.arccos(cos_theta0), phi0)),
|
||||||
)
|
)
|
||||||
|
|
||||||
orientations = np.zeros(4)
|
orientations = np.zeros(4)
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
corner_lab = np.dot(rot, corners[i])
|
corner_lab = rot @ corners[i]
|
||||||
_, theta_i, phi_i = xyz_to_spherical(*corner_lab)
|
_, theta_i, phi_i = xyz_to_spherical(*corner_lab)
|
||||||
orientations[i] = omega_q(self._delta, self._eta, theta_i, phi_i)
|
orientations[i] = omega_q(self._delta, self._eta, theta_i, phi_i)
|
||||||
|
|
||||||
|
# print(orientations)
|
||||||
|
#
|
||||||
|
# theta0 = np.arccos(cos_theta0)
|
||||||
|
# v0 = np.array([np.sin(theta0) * np.cos(phi0), np.sin(theta0)*np.sin(theta0), cos_theta0])
|
||||||
|
# norm = np.linalg.norm(v0)
|
||||||
|
# print(norm)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# corners = np.zeros((4, 3))
|
||||||
|
# corners[0] = v0
|
||||||
|
|
||||||
|
|
||||||
return orientations
|
return orientations
|
||||||
|
|
||||||
def jump(self, size: int = 1) -> ArrayLike:
|
def jump(self, size: int = 1) -> 'ArrayLike':
|
||||||
jumps = self._rng.choice([1, 2, 3], size=size)
|
jumps = self._rng.choice([1, 2, 3], size=size)
|
||||||
jumps = np.cumsum(jumps) + self._start
|
jumps = np.cumsum(jumps) + self._start
|
||||||
jumps %= 4
|
jumps %= 4
|
||||||
@ -94,10 +106,10 @@ class TetrahedralJump(BaseMotion):
|
|||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
|
|
||||||
def xyz_to_spherical(x_in: float, y_in: float, z_in: float) -> tuple[float, float, float]:
|
def xyz_to_spherical(x_in: float, y_in: float, z_in: float) -> tuple[np.floating, float, float]:
|
||||||
r = np.linalg.norm([x_in, y_in, z_in])
|
r = np.linalg.norm([x_in, y_in, z_in])
|
||||||
theta = np.arccos(z_in)
|
theta: float = np.arccos(z_in)
|
||||||
phi = np.arctan2(y_in, x_in)
|
phi: float = np.arctan2(y_in, x_in)
|
||||||
|
|
||||||
return r, theta, phi
|
return r, theta, phi
|
||||||
|
|
@ -6,9 +6,9 @@ from math import prod
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from numpy._typing import ArrayLike
|
# from numpy.typing import ArrayLike
|
||||||
|
|
||||||
from functions import pulse_attn
|
from .functions import pulse_attn
|
||||||
from .distributions import BaseDistribution
|
from .distributions import BaseDistribution
|
||||||
from .motions import BaseMotion
|
from .motions import BaseMotion
|
||||||
|
|
||||||
@ -41,8 +41,8 @@ class MoleculeParameter:
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class StimEchoParameter:
|
class StimEchoParameter:
|
||||||
t_evo: ArrayLike
|
t_evo: 'ArrayLike'
|
||||||
t_mix: ArrayLike
|
t_mix: 'ArrayLike'
|
||||||
t_echo: float
|
t_echo: float
|
||||||
t_max: float = field(init=False)
|
t_max: float = field(init=False)
|
||||||
|
|
||||||
@ -54,14 +54,14 @@ class StimEchoParameter:
|
|||||||
class SpectrumParameter:
|
class SpectrumParameter:
|
||||||
dwell_time: float
|
dwell_time: float
|
||||||
num_points: int
|
num_points: int
|
||||||
t_echo: ArrayLike
|
t_echo: 'ArrayLike'
|
||||||
lb: float
|
lb: float
|
||||||
t_pulse: float
|
t_pulse: float
|
||||||
t_acq: ArrayLike = field(init=False)
|
t_acq: 'ArrayLike' = field(init=False)
|
||||||
freq: ArrayLike = field(init=False)
|
freq: 'ArrayLike' = field(init=False)
|
||||||
t_max: float = field(init=False)
|
t_max: float = field(init=False)
|
||||||
dampening: ArrayLike = field(init=False)
|
dampening: 'ArrayLike' = field(init=False)
|
||||||
pulse_attn: ArrayLike = field(init=False)
|
pulse_attn: 'ArrayLike' = field(init=False)
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
self.t_acq = np.arange(self.num_points) * self.dwell_time
|
self.t_acq = np.arange(self.num_points) * self.dwell_time
|
@ -54,6 +54,7 @@ def run_ste_sim(config_file: str):
|
|||||||
dephased = phase(t_evo_k)
|
dephased = phase(t_evo_k)
|
||||||
t0 = t_mix + t_evo_k
|
t0 = t_mix + t_evo_k
|
||||||
rephased = phase(t0 + t_evo_k + 2*t_echo) + phase(t0) - 2 * phase(t0+t_echo)
|
rephased = phase(t0 + t_evo_k + 2*t_echo) + phase(t0) - 2 * phase(t0+t_echo)
|
||||||
|
# print(t_evo_k, t0 + t_evo_k + 2*t_echo, t0)
|
||||||
cc[:, k] += np.cos(dephased)*np.cos(rephased)
|
cc[:, k] += np.cos(dephased)*np.cos(rephased)
|
||||||
ss[:, k] += np.sin(dephased)*np.sin(rephased)
|
ss[:, k] += np.sin(dephased)*np.sin(rephased)
|
||||||
|
|
||||||
@ -174,17 +175,20 @@ def make_trajectory(
|
|||||||
|
|
||||||
# number of jumps that are simulated at once
|
# number of jumps that are simulated at once
|
||||||
chunks = min(int(0.51 * t_max / dist.tau_jump), 100_000) + 1
|
chunks = min(int(0.51 * t_max / dist.tau_jump), 100_000) + 1
|
||||||
|
# print(chunks)
|
||||||
|
|
||||||
t = [np.array([t_passed])]
|
t = [np.array([t_passed])]
|
||||||
phase = [np.array([init_phase])]
|
phase = [np.array([init_phase])]
|
||||||
|
# omega = [np.array([0])]
|
||||||
while t_passed < t_max:
|
while t_passed < t_max:
|
||||||
# frequencies between jumps
|
# frequencies between jumps
|
||||||
current_omega = motion.jump(size=chunks)
|
current_omega = motion.jump(size=chunks)
|
||||||
# times at a particular position
|
# times at a particular position
|
||||||
t_wait = dist.wait(size=chunks)
|
t_wait = dist.wait(size=chunks)
|
||||||
|
|
||||||
accumulated_phase = np.cumsum(t_wait * current_omega) + phase[-1]
|
accumulated_phase = np.cumsum(t_wait * current_omega) + phase[-1][-1]
|
||||||
phase.append(accumulated_phase)
|
phase.append(accumulated_phase)
|
||||||
|
# omega.append(current_omega)
|
||||||
|
|
||||||
t_wait = np.cumsum(t_wait) + t_passed
|
t_wait = np.cumsum(t_wait) + t_passed
|
||||||
t_passed = t_wait[-1]
|
t_passed = t_wait[-1]
|
||||||
@ -192,6 +196,12 @@ def make_trajectory(
|
|||||||
|
|
||||||
t = np.concatenate(t)
|
t = np.concatenate(t)
|
||||||
phase = np.concatenate(phase)
|
phase = np.concatenate(phase)
|
||||||
|
# omega = np.concatenate(omega)
|
||||||
|
|
||||||
|
# fig_test, ax_test = plt.subplots()
|
||||||
|
# ax_test.plot(t, phase, 'x-')
|
||||||
|
|
||||||
|
# np.savetxt('trajectory.dat', np.c_[t, phase, omega])
|
||||||
|
|
||||||
# convenient interpolation to get phase at arbitrary times
|
# convenient interpolation to get phase at arbitrary times
|
||||||
phase_interpol = interp1d(t, phase)
|
phase_interpol = interp1d(t, phase)
|
@ -1,5 +0,0 @@
|
|||||||
from rwsims.sims import run_ste_sim, run_spectrum_sim
|
|
||||||
|
|
||||||
# run_ste_sim('config.json')
|
|
||||||
|
|
||||||
run_spectrum_sim('config.json')
|
|
Loading…
Reference in New Issue
Block a user