mirror of
https://github.com/nqrduck/nqr-blochsimulator.git
synced 2024-06-28 00:09:07 +00:00
Added calculation of losses.
This commit is contained in:
parent
df7bf4f2ce
commit
1ab0a5e053
|
@ -26,7 +26,10 @@ class Simulation:
|
||||||
pulse : PulseArray,
|
pulse : PulseArray,
|
||||||
averages: int,
|
averages: int,
|
||||||
gain: float,
|
gain: float,
|
||||||
temperature: float
|
temperature: float,
|
||||||
|
loss_TX: float = 0,
|
||||||
|
loss_RX: float = 0,
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Constructs all the necessary attributes for the simulation object.
|
Constructs all the necessary attributes for the simulation object.
|
||||||
|
@ -59,6 +62,10 @@ class Simulation:
|
||||||
The gain of the amplifier.
|
The gain of the amplifier.
|
||||||
temperature:
|
temperature:
|
||||||
The temperature of the sample in Kelvin.
|
The temperature of the sample in Kelvin.
|
||||||
|
loss_TX:
|
||||||
|
The loss of the transmitter in dB.
|
||||||
|
loss_RX:
|
||||||
|
The loss of the receiver in dB.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.sample = sample
|
self.sample = sample
|
||||||
|
@ -74,20 +81,29 @@ class Simulation:
|
||||||
self.averages = averages
|
self.averages = averages
|
||||||
self.gain = gain
|
self.gain = gain
|
||||||
self.temperature = temperature
|
self.temperature = temperature
|
||||||
|
self.loss_TX = loss_TX
|
||||||
|
self.loss_RX = loss_RX
|
||||||
|
|
||||||
def simulate(self):
|
def simulate(self):
|
||||||
reference_voltage = self.calculate_reference_voltage()
|
reference_voltage = self.calculate_reference_voltage()
|
||||||
logger.debug(reference_voltage * 1e6)
|
logger.debug(reference_voltage * 1e6)
|
||||||
B1 = self.calc_B1() * 1e3 # I think this is multiplied by 1e3 because everything is in mT
|
B1 = self.calc_B1() * 1e3 # I think this is multiplied by 1e3 because everything is in mT
|
||||||
# B1 = 17.3 # Something might be wrong with the calculation of the B1 field. This has to be checked.
|
B1 = 17.3 # Something might be wrong with the calculation of the B1 field. This has to be checked.
|
||||||
self.sample.gamma = self.sample.gamma * 1e-6 # We need our gamma in MHz / T
|
self.sample.gamma = self.sample.gamma * 1e-6 # We need our gamma in MHz / T
|
||||||
self.sample.T1 = self.sample.T1 * 1e3 # We need our T1 in ms
|
self.sample.T1 = self.sample.T1 * 1e3 # We need our T1 in ms
|
||||||
self.sample.T2 = self.sample.T2 * 1e3 # We need our T2 in ms
|
self.sample.T2 = self.sample.T2 * 1e3 # We need our T2 in ms
|
||||||
|
|
||||||
|
# Calculate the x distribution of the isochromats
|
||||||
xdis = self.calc_xdis()
|
xdis = self.calc_xdis()
|
||||||
|
|
||||||
real_pulsepower = self.pulse.get_real_pulsepower()
|
real_pulsepower = self.pulse.get_real_pulsepower()
|
||||||
imag_pulsepower = self.pulse.get_imag_pulsepower()
|
imag_pulsepower = self.pulse.get_imag_pulsepower()
|
||||||
|
|
||||||
|
# Calculate losses on the pulse
|
||||||
|
real_pulsepower = real_pulsepower * (1 - 10 ** (-self.loss_TX / 20))
|
||||||
|
imag_pulsepower = imag_pulsepower * (1 - 10 ** (-self.loss_TX / 20))
|
||||||
|
|
||||||
|
# Calculate the magnetization
|
||||||
M_sy1 = self.bloch_symmetric_strang_splitting(B1, xdis, real_pulsepower, imag_pulsepower)
|
M_sy1 = self.bloch_symmetric_strang_splitting(B1, xdis, real_pulsepower, imag_pulsepower)
|
||||||
|
|
||||||
# Z-Component
|
# Z-Component
|
||||||
|
@ -100,8 +116,13 @@ 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
|
||||||
|
|
||||||
sigtrans = Mtrans_avg * reference_voltage * 1e6 * self.averages * self.gain
|
# Scale the signal according to the reference voltage, averages and gain
|
||||||
return sigtrans
|
timedomain_signal = Mtrans_avg * reference_voltage * 1e6 * self.averages * self.gain
|
||||||
|
|
||||||
|
# Add the losses of the receiver - this should probably be done before the scaling
|
||||||
|
timedomain_signal = timedomain_signal * (1 - 10 ** (-self.loss_RX / 20))
|
||||||
|
|
||||||
|
return timedomain_signal
|
||||||
|
|
||||||
|
|
||||||
def bloch_symmetric_strang_splitting(self, B1, xdis, real_pulsepower, imag_pulsepower, relax = 1):
|
def bloch_symmetric_strang_splitting(self, B1, xdis, real_pulsepower, imag_pulsepower, relax = 1):
|
||||||
|
|
|
@ -52,6 +52,8 @@ class TestSimulation(unittest.TestCase):
|
||||||
averages = 1,
|
averages = 1,
|
||||||
gain = 6000,
|
gain = 6000,
|
||||||
temperature=77,
|
temperature=77,
|
||||||
|
loss_TX=12,
|
||||||
|
loss_RX=12
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_simulation(self):
|
def test_simulation(self):
|
||||||
|
|
Loading…
Reference in a new issue