change layout

This commit is contained in:
Dominik Demuth 2024-08-01 18:46:28 +02:00
parent 3e1325f3ca
commit 66e8925241
14 changed files with 77 additions and 43 deletions

View File

@ -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
View 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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -1,5 +0,0 @@
from rwsims.sims import run_ste_sim, run_spectrum_sim
# run_ste_sim('config.json')
run_spectrum_sim('config.json')