Source code for mrsprint.sequence.sequence

#! python
# -*- coding: utf-8 -*-


"""Module for pulse sequence related classes and functions.

Authors:
    * Victor Hugo de Mello Pessoa <victor.pessoa@usp.br>
    * Daniel Cosmo Pizetta <daniel.pizetta@usp.br>

Since:
    2017/07/01

"""

import logging

import numpy as np
import pyqtgraph.parametertree as pt

from mrsprint.system import gradient, rf

_logger = logging.getLogger(__name__)


[docs]class Sequence(pt.parameterTypes.GroupParameter): """Class that represents a sequence for magnetic resonance systems.""" def __init__(self, settings, nucleus, **opts): opts['name'] = 'Sequence' opts['type'] = 'bool' opts['value'] = True pt.parameterTypes.GroupParameter.__init__(self, **opts) # Main constant values self.dt = settings.simulator_group.timeResolution.value() self.b1_max = settings.rf_group.amMaxValue.value() self.gamma = nucleus.gamma.value() self.__rf = rf.rf_delay(self.dt, self.dt) self.__gradient = gradient.gradient_delay(self.dt, self.dt)
[docs] def setRF(self, rf_value): """Properly sets the rf stream signal.""" for rep_num, events in rf_value: for _ in np.arange(0, rep_num): for event in events: self.__rf = np.append(self.__rf, event)
[docs] def getRF(self): """Return the entire rf.""" return self.__rf
[docs] def setGradient(self, grad_value): """Properly sets the gradient.""" for rep_num, events in gradient_value: for _ in np.arange(0, rep_num): for event in events: self.__gradient = np.append(self.__gradient, event)
[docs] def getGradient(self): """Return the entire gradient.""" rf_shape = self.__rf.shape gradient_size = self.__gradient.size grad_zero = np.zeros(3 * (rf_shape[0])).reshape(3, rf_shape[0]) if 3 * rf_shape[0] != gradient_size: if gradient_size <= 3: self.__gradient = grad_zero else: raise ValueError("RF and Gradient must have the same temporal size!") return self.__gradient
[docs]class CPMGSequence(Sequence): """Generates a CPMG sequence.""" def __init__(self): Sequence.__init__(self) # sequence specific parameters self.numberOfCycles = self.addChild({'name': 'Number of Cycles', 'type': 'int', 'value': 3}) self.te = self.addChild({'name': 'Time to Echo', 'type': 'float', 'value': 0.02, 'suffix': 's', 'siPrefix': True}) self.dtr = self.addChild({'name': 'Delay TR', 'type': 'float', 'value': 0.02, 'suffix': 's', 'siPrefix': True}) # pulse of 90 degrees in x rf_90_x = rf.square_rf_pulse(flip_angle=90, phase=0) t_half_rf_90 = rf.rf_duration(rf_90_x) / 2. # pulse of 180 degrees in y rf_180_y = rf.square_rf_pulse(flip_angle=180, phase=90) t_half_rf_180 = rf.rf_duration(rf_180_y) / 2. # delay between pulse 90x and 180y = te/2 between pulse centers d_90_180 = rf.rf_delay(-t_half_rf_90 + self.te.value() / 2. - t_half_rf_180) # delay between pulse 180y and 180y = te between pulse centers d_180_180 = rf.rf_delay(-t_half_rf_180 + self.te.value() - t_half_rf_180) # delay repetition time before restart d_tr = rf.rf_delay(self.dtr.value()) # rf for CPMG self.setRF([(1, [rf_90_x, d_90_180]), (self.numberOfCycles.value(), [-rf_180_y, d_180_180, rf_180_y, d_180_180]), (1, [d_tr])])
[docs]class GradientEchoSequence(Sequence): """Generate a Gradient Echo sequence.""" def __init__(self): Sequence.__init__(self) # sequence specific parameters self.a90 = self.addChild({'name': 'Delay After RF', 'type': 'float', 'value': 0.01, 'suffix': 's', 'siPrefix': True}) self.te = self.addChild({'name': 'Time to Echo', 'type': 'float', 'value': 0.02, 'suffix': 's', 'siPrefix': True}) self.dtr = self.addChild({'name': 'Delay TR', 'type': 'float', 'value': 0.01, 'suffix': 's', 'siPrefix': True}) # first event, excitation rf_90_x = rf.square_rf_pulse(flip_angle=90, phase=0) t_rf_90 = rf.rf_duration(rf_90_x) d_gr_90 = gradient.gradient_delay(t_rf_90) # second event, a delay d_rf_a90 = rf.rf_delay(self.dbgr.value()) d_gr_a90 = gradient.gradient_delay(self.dbgr.value()) # third event, dephasing d_rf_deph = rf.rf_delay() gr_deph = gradient.SquareGradient() # fourth event, read d_rf_read = rf.rf_delay() gr_read = gradient.SquareGradient() # fifty event, a delay d_rf_tr = rf.rf_delay(self.dtr.value()) d_gr_tr = gradient.gradient_delay(self.dtr.value()) self.setRF([(1, [rf_90_x, d_rf_a90, d_rf_deph, d_rf_read, d_rf_tr])]) self.setGradient([(1, [d_gr_90, d_gr_a90, gr_deph, gr_read, d_gr_tr])])