mirror of
https://github.com/nqrduck/nqr-blochsimulator.git
synced 2024-09-28 08:00:35 +00:00
Adapted units.
This commit is contained in:
parent
c89dda1813
commit
f845135dc2
2 changed files with 46 additions and 35 deletions
|
@ -39,9 +39,9 @@ class Sample:
|
||||||
molar_mass : float
|
molar_mass : float
|
||||||
The molar mass of the sample (g/mol or kg/mol).
|
The molar mass of the sample (g/mol or kg/mol).
|
||||||
resonant_frequency : float
|
resonant_frequency : float
|
||||||
The resonant frequency of the sample in Hz.
|
The resonant frequency of the sample in MHz.
|
||||||
gamma : float
|
gamma : float
|
||||||
The gamma value of the sample in Hz/T.
|
The gamma value of the sample in MHz/T.
|
||||||
nuclear_spin : float
|
nuclear_spin : float
|
||||||
The nuclear spin quantum number of the sample.
|
The nuclear spin quantum number of the sample.
|
||||||
spin_factor : float
|
spin_factor : float
|
||||||
|
@ -51,32 +51,32 @@ class Sample:
|
||||||
filling_factor : float
|
filling_factor : float
|
||||||
The filling factor of the sample.
|
The filling factor of the sample.
|
||||||
T1 : float
|
T1 : float
|
||||||
The spin-lattice relaxation time of the sample in seconds.
|
The spin-lattice relaxation time of the sample in microseconds.
|
||||||
T2 : float
|
T2 : float
|
||||||
The spin-spin relaxation time of the sample in seconds.
|
The spin-spin relaxation time of the sample in microseconds.
|
||||||
T2_star : float
|
T2_star : float
|
||||||
The effective spin-spin relaxation time of the sample in seconds.
|
The effective spin-spin relaxation time of the sample in microseconds.
|
||||||
atom_density : float, optional
|
atom_density : float, optional
|
||||||
The atom density of the sample (atoms per cm^3). By default None.
|
The atom density of the sample (atoms per cm^3). By default None.
|
||||||
sample_volume : float, optional
|
sample_volume : float, optional
|
||||||
The volume of the sample (m^3). By default None.
|
The volume of the sample (m^3). By default None.
|
||||||
sample_length : float, optional
|
sample_length : float, optional
|
||||||
The length of the sample (m). By default None.
|
The length of the sample (mm). By default None.
|
||||||
sample_diameter : float, optional
|
sample_diameter : float, optional
|
||||||
The diameter of the sample (m). By default None.
|
The diameter of the sample m(m). By default None.
|
||||||
"""
|
"""
|
||||||
self.name = name
|
self.name = name
|
||||||
self.density = density
|
self.density = density
|
||||||
self.molar_mass = molar_mass
|
self.molar_mass = molar_mass
|
||||||
self.resonant_frequency = resonant_frequency
|
self.resonant_frequency = resonant_frequency * 1e6
|
||||||
self.gamma = gamma
|
self.gamma = gamma * 1e6
|
||||||
self.nuclear_spin = nuclear_spin
|
self.nuclear_spin = nuclear_spin
|
||||||
self.spin_factor = spin_factor
|
self.spin_factor = spin_factor
|
||||||
self.powder_factor = powder_factor
|
self.powder_factor = powder_factor
|
||||||
self.filling_factor = filling_factor
|
self.filling_factor = filling_factor
|
||||||
self.T1 = T1
|
self.T1 = T1 * 1e-6
|
||||||
self.T2 = T2
|
self.T2 = T2 * 1e-6
|
||||||
self.T2_star = T2_star
|
self.T2_star = T2_star * 1e-6
|
||||||
self.atom_density = atom_density
|
self.atom_density = atom_density
|
||||||
self.sample_volume = sample_volume
|
self.sample_volume = sample_volume
|
||||||
self.sample_length = sample_length
|
self.sample_length = sample_length
|
||||||
|
|
|
@ -23,8 +23,8 @@ class Simulation:
|
||||||
length_coil: float,
|
length_coil: float,
|
||||||
diameter_coil: float,
|
diameter_coil: float,
|
||||||
number_turns: float,
|
number_turns: float,
|
||||||
q_factor_transmit:float,
|
q_factor_transmit: float,
|
||||||
q_factor_receive:float,
|
q_factor_receive: float,
|
||||||
power_amplifier_power: float,
|
power_amplifier_power: float,
|
||||||
pulse: PulseArray,
|
pulse: PulseArray,
|
||||||
averages: int,
|
averages: int,
|
||||||
|
@ -82,8 +82,8 @@ class Simulation:
|
||||||
self.initial_magnetization = initial_magnetization
|
self.initial_magnetization = initial_magnetization
|
||||||
self.gradient = gradient
|
self.gradient = gradient
|
||||||
self.noise = noise
|
self.noise = noise
|
||||||
self.length_coil = length_coil
|
self.length_coil = length_coil * 1e-3 # We need our length in meters
|
||||||
self.diameter_coil = diameter_coil
|
self.diameter_coil = diameter_coil * 1e-3 # We need our diameter in meters
|
||||||
self.number_turns = number_turns
|
self.number_turns = number_turns
|
||||||
self.q_factor_transmit = q_factor_transmit
|
self.q_factor_transmit = q_factor_transmit
|
||||||
self.q_factor_receive = q_factor_receive
|
self.q_factor_receive = q_factor_receive
|
||||||
|
@ -134,7 +134,6 @@ class Simulation:
|
||||||
Mtrans_avg = np.mean(Mtrans, axis=0)
|
Mtrans_avg = np.mean(Mtrans, axis=0)
|
||||||
Mtrans_avg = np.delete(Mtrans_avg, -1) # Remove the last element
|
Mtrans_avg = np.delete(Mtrans_avg, -1) # Remove the last element
|
||||||
|
|
||||||
|
|
||||||
# Scale the signal according to the reference voltage, averages and gain
|
# Scale the signal according to the reference voltage, averages and gain
|
||||||
timedomain_signal = Mtrans_avg * reference_voltage
|
timedomain_signal = Mtrans_avg * reference_voltage
|
||||||
|
|
||||||
|
@ -144,7 +143,9 @@ class Simulation:
|
||||||
# Add noise to the signal
|
# Add noise to the signal
|
||||||
noise_data = self.calculate_noise(timedomain_signal)
|
noise_data = self.calculate_noise(timedomain_signal)
|
||||||
|
|
||||||
timedomain_signal = (timedomain_signal * self.averages * self.gain) + (noise_data * self.gain)
|
timedomain_signal = (timedomain_signal * self.averages * self.gain) + (
|
||||||
|
noise_data * self.gain
|
||||||
|
)
|
||||||
# print(abs(timedomain_signal))
|
# print(abs(timedomain_signal))
|
||||||
|
|
||||||
timedomain_signal = timedomain_signal
|
timedomain_signal = timedomain_signal
|
||||||
|
@ -223,25 +224,37 @@ class Simulation:
|
||||||
for n in range(Nu): # time loop
|
for n in range(Nu): # time loop
|
||||||
Mrot = np.zeros((3, Nx))
|
Mrot = np.zeros((3, Nx))
|
||||||
Mrot[0, :] = (
|
Mrot[0, :] = (
|
||||||
Bd1.conj().T[:, n] * Mt[0, :] + Bd2.conj().T[:, n] * Mt[1, :] + Bd3.conj().T[:, n] * Mt[2, :]
|
Bd1.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd2.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd3.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
Mrot[1, :] = (
|
Mrot[1, :] = (
|
||||||
Bd4.conj().T[:, n] * Mt[0, :] + Bd5.conj().T[:, n] * Mt[1, :] + Bd6.conj().T[:, n] * Mt[2, :]
|
Bd4.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd5.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd6.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
Mrot[2, :] = (
|
Mrot[2, :] = (
|
||||||
Bd7.conj().T[:, n] * Mt[0, :] + Bd8.conj().T[:, n] * Mt[1, :] + Bd9.conj().T[:, n] * Mt[2, :]
|
Bd7.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd8.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd9.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
|
|
||||||
Mt = np.dot(D, Mrot) + np.tile(b, (Nx, 1)).T
|
Mt = np.dot(D, Mrot) + np.tile(b, (Nx, 1)).T
|
||||||
|
|
||||||
Mrot[0, :] = (
|
Mrot[0, :] = (
|
||||||
Bd1.conj().T[:, n] * Mt[0, :] + Bd2.conj().T[:, n] * Mt[1, :] + Bd3.conj().T[:, n] * Mt[2, :]
|
Bd1.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd2.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd3.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
Mrot[1, :] = (
|
Mrot[1, :] = (
|
||||||
Bd4.conj().T[:, n] * Mt[0, :] + Bd5.conj().T[:, n] * Mt[1, :] + Bd6.conj().T[:, n] * Mt[2, :]
|
Bd4.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd5.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd6.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
Mrot[2, :] = (
|
Mrot[2, :] = (
|
||||||
Bd7.conj().T[:, n] * Mt[0, :] + Bd8.conj().T[:, n] * Mt[1, :] + Bd9.conj().T[:, n] * Mt[2, :]
|
Bd7.conj().T[:, n] * Mt[0, :]
|
||||||
|
+ Bd8.conj().T[:, n] * Mt[1, :]
|
||||||
|
+ Bd9.conj().T[:, n] * Mt[2, :]
|
||||||
)
|
)
|
||||||
|
|
||||||
Mt = Mrot
|
Mt = Mrot
|
||||||
|
@ -301,14 +314,12 @@ class Simulation:
|
||||||
u = 4 * np.pi * 1e-7 # permeability of free space
|
u = 4 * np.pi * 1e-7 # permeability of free space
|
||||||
|
|
||||||
magnetization = (
|
magnetization = (
|
||||||
((self.sample.gamma
|
(
|
||||||
* 2
|
(self.sample.gamma * 2 * self.sample.atoms)
|
||||||
* self.sample.atoms)
|
/ (2 * self.sample.nuclear_spin + 1)
|
||||||
/ (2 * self.sample.nuclear_spin + 1))
|
)
|
||||||
* (h**2
|
* (h**2 * self.sample.resonant_frequency)
|
||||||
* self.sample.resonant_frequency)
|
/ (Boltzmann * self.temperature)
|
||||||
/ (Boltzmann
|
|
||||||
* self.temperature)
|
|
||||||
* self.sample.spin_factor
|
* self.sample.spin_factor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -425,16 +436,16 @@ class Simulation:
|
||||||
def q_factor_transmit(self) -> float:
|
def q_factor_transmit(self) -> float:
|
||||||
"""Q-factor of the transmit path of the probe coil."""
|
"""Q-factor of the transmit path of the probe coil."""
|
||||||
return self._q_factor_transmit
|
return self._q_factor_transmit
|
||||||
|
|
||||||
@q_factor_transmit.setter
|
@q_factor_transmit.setter
|
||||||
def q_factor_transmit(self, q_factor_transmit):
|
def q_factor_transmit(self, q_factor_transmit):
|
||||||
self._q_factor_transmit = q_factor_transmit
|
self._q_factor_transmit = q_factor_transmit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def q_factor_receive(self) -> float:
|
def q_factor_receive(self) -> float:
|
||||||
"""Q-factor of the receive path of the probe coil."""
|
"""Q-factor of the receive path of the probe coil."""
|
||||||
return self._q_factor_receive
|
return self._q_factor_receive
|
||||||
|
|
||||||
@q_factor_receive.setter
|
@q_factor_receive.setter
|
||||||
def q_factor_receive(self, q_factor_receive):
|
def q_factor_receive(self, q_factor_receive):
|
||||||
self._q_factor_receive = q_factor_receive
|
self._q_factor_receive = q_factor_receive
|
||||||
|
|
Loading…
Reference in a new issue