GeneralBlochOperator#
- class GeneralBlochOperator(name, gamma, time_grid, gradient_waveforms=None, rf_waveforms=None, adc_events=None, submodules=(), device=None)[source]#
General bloch-simulation module: accepts RF-Waveforms, Gradient-Waveforms and ADC-events as input and integrates the Bloch-equation (trapezoidal numerical integration). The specified time-grid does not need to be uniform, but must match the definition of the specified waveforms/adc definitions. The required input format matches the common format of a sequence diagram
The integration allows for moving isochromates, as well as the addition of effects defined in the submodules. For more information on how the isochromate motion is incorporated refer to the __call__ method.
Example usage
# time_raster.shape, grad_grid.shape, rf_grid.shape, adc_grid.grid # >>> (n_reps, t), (n_reps, t, 2), (n_reps, t), (n_reps, t, 2) gammarad = system_specs.gamma_rad.m_as("rad/mT/ms") bloch_mod = cmrsim.bloch.GeneralBlochOperator(name="example", device="GPU:0, gamma=gammarad, time_grid=time_raster, gradient_waveforms=grad_grid, rf_waveforms=rf_grid, adc_events=adc_grid)
properties = ... # From input definition n_samples = tf.shape(module.gradient_waveforms)[1] n_repetitions = tf.shape(module.gradient_waveforms)[0] data_iterator = tf.data.Dataset.from_tensor_slices(properties) for phantom_batch in tqdm(data_iterator.batch(int(3e5))): m, r = bloch_mod(trajectory_module=trajectory_module, run_parallel=True, **phantom_batch)
properties = ... # From input definition n_samples = tf.shape(module.gradient_waveforms)[1] n_repetitions = tf.shape(module.gradient_waveforms)[0] data_iterator = tf.data.Dataset.from_tensor_slices(properties) for phantom_batch in tqdm(data_iterator.batch(int(3e5))): r = phantom_batch.pop("initial_position") m = phantom_batch.pop("magnetization") for rep_idx in tqdm(range(n_repetitions)): m, r = module(trajectory_module=trajectory_module, initial_position=r, magnetization=m, repetition_index=rep_idx, run_parallel=False, **phantom_batch)
- Parameters:
name (
str
) – Verbose name of the module (non-functionally relevant)gamma (
float
) – gyromagnetic ratio in rad/ms/mtime_grid (
Tensor
) – (n_steps) - tf.float32 - time definition for numerical integration stepsgradient_waveforms (
Tensor
) – (#repetitions, #steps, 3) - tf.float32 - Definition of gradients in mT/mrf_waveforms (
Tensor
) – (#repetitions, #steps) - tf.complex64 -adc_events (
Tensor
) – (#repetition, #steps, 2) - tf.float32 - last axis contains the adc-on definitions and the adc-phasesubmodules (
Tuple
[BaseSubmodule
,...
]) – List[tf.Modules] implementing the __call__ function returning the resulting phase increment contributiondevice (
str
) – str
Methods:
__call__
(initial_position, magnetization, ...)Runs bloch simulation for the specified RF/Gradients and accumulates the signal for the times specified in adc_events.
reset
()Resets the time-signal accumulators, i.e. sets all entries to 0.
Attributes:
Sampling events definitions for each time in self.time_grid for R repetitions - shape (R, T, 2), where the two channels have the following meaning: 1.
Grid containing the differences of specified time_grid - shape: (T-1, )
Gyromagnetic ration in rad/ms/m specified on instantiation
Gradient waveforms at times of self.time_grid in mT/m for R repetitions - shape: (R, T, 3)
Number of repetitions derived from specified waveforms
Complex radio-frequency pulse definition at times of self.time_grid in uT for R repetitions - shape: (R, T)
(Non-uniform) temporal raster defining the simulation steps in milliseconds - shape: (T, )
Accumulator variables for the signal acquired at specified adc-events.
- __call__(initial_position, magnetization, T1, T2, M0, trajectory_module=<cmrsim.trajectory._base.StaticParticlesTrajectory object>, repetition_index=0, run_parallel=False, **kwargs)[source]#
Runs bloch simulation for the specified RF/Gradients and accumulates the signal for the times specified in adc_events. For each interval on the time grid, a trapezoidal integration of the flip angle and the gradient phase increment (including the submodules) is performed and subsequently used to rotate the magnetization vectors.
- Parameters:
initial_position (
Tensor
) – (#batch, 3) - tf.float32 - initial positions of particlesmagnetization (
Tensor
) – ([repetitions/1], #batch, 3) - tf.complex64 - [Mx+iMy, Mx-iMy, Mz] magnetization per particle. The first optional axis is only used if run_parallel==True.T1 (
Tensor
) – (#batch, ) - tf.float32 - Longitudinal relaxation time in milliseconds per particleT2 (
Tensor
) – (#batch, ) - tf.float32 - Transversal relaxtion time in milliseconds per particleM0 (
Tensor
) – (#batch, ) - tf.float32 - Equilibrium magnetization of each particle (representing a volume)trajectory_module (
Module
) – tf.function accepting the arguments [r[:, 3](tf.float32), dt[,](tf.float32)] and returning the updated position r_new[:, 3](tf.float32) as well as a dictionary of tensors denoting arbitrary look-up values for the new particle positions. Defaults to static particlesrepetition_index (
Tensor
) – (, ) - tf.int32 - index of the current repetition index to simulate this corresponds to indexing the first dimension of the specified waveforms. Only used if run_parallel==Falserun_parallel (
bool
) – bool - defaults to False. If True, the repetitions of the specified waveforms are simulated for the same particle trajectories. Otherwise only the waveforms for given repetition_index is simulated.kwargs – additional properties of particles, that are required for evaluating the submodules
- Returns:
m, r with shapes - [#reps, #particles, 3] if repetitions are run in parallel - [#particles, 3] if run sequential
-
adc_events:
Variable
= None# Sampling events definitions for each time in self.time_grid for R repetitions - shape (R, T, 2), where the two channels have the following meaning: 1. ADC On/Off [1/0] at time t and 2. Demodulation phase of the ADC at time t in radians
-
dt_grid:
Variable
# Grid containing the differences of specified time_grid - shape: (T-1, )
-
gradient_waveforms:
Variable
= None# Gradient waveforms at times of self.time_grid in mT/m for R repetitions - shape: (R, T, 3)
-
rf_waveforms:
Variable
= None# Complex radio-frequency pulse definition at times of self.time_grid in uT for R repetitions - shape: (R, T)
-
time_grid:
Variable
= None# (Non-uniform) temporal raster defining the simulation steps in milliseconds - shape: (T, )
-
time_signal_acc:
List
[Variable
] = None# Accumulator variables for the signal acquired at specified adc-events. This is empty if no ADC==On events where specified. The length of the List is equal to the number of repetitions and the shape of each tf.Variable is (sum(ADC[R]==1), ), which can result different length if the repetitions have different numbers of samples.