API Reference

The following section outlines the API of shimming-toolbox.

Field mapping

shimmingtoolbox.prepare_fieldmap.complex_difference(phase1, phase2)

Calculates the complex difference between 2 phase arrays (phase2 - phase1)

Parameters:
  • phase1 (numpy.ndarray) -- Array containing phase data in radians

  • phase2 (numpy.ndarray) -- Array containing phase data in radians. Must be the same shape as phase1.

Returns:

The difference in phase between each voxels of phase2 and phase1 (phase2 - phase1)

Return type:

numpy.ndarray

shimmingtoolbox.prepare_fieldmap.correct_2pi_offset(unwrapped, mag, mask, validity_threshold)
Removes 2*pi offsets from unwrapped for a time series. If there is no offset, it returns the same array. The

'correct' offset is assumed to be at time 0.

Parameters:
  • unwrapped (numpy.ndarray) -- Array of the spatially unwrapped phase. If there is a time dimension, the offset is corrected in time, if unwrapped is 3D, the offset closest to 0 is chosen.

  • mag (numpy.ndarray) -- Array containing the magnitude values of the phase. Same shape as unwrapped.

  • mask (numpy.ndarray) -- Mask of the unwrapped phase array. Same shape as unwrapped.

  • validity_threshold (float) -- Threshold to create a mask on each timepoints and assume as reliable phase data

Returns:

4d array of the unwrapped phase corrected if there were n*2*pi offsets between time points

Return type:

numpy.ndarray

shimmingtoolbox.prepare_fieldmap.get_mask(nii_target, mag, nii_mask=None, threshold=None)
Return a mask resampled (if required) to nii_target. If nii_mask is None, a mask is created using the threshold.

This functions hanles 3D and 4D nii_targets.

Parameters:
  • nii_target (nib.Nifti1Image) -- Target nifti image to resample the mask to.

  • nii_mask (nib.Nifti1Image) -- Mask to be resampled to nii_target. If None, a mask is created using the threshold.

  • mag (np.ndarray) -- Magnitude data to create the mask from.

  • threshold (float) -- Threshold to create the mask. If nii_mask is not None, this value is ignored.

Returns:

Mask resampled to nii_target.

Return type:

np.ndarray

shimmingtoolbox.prepare_fieldmap.prepare_fieldmap(list_nii_phase, echo_times, mag, unwrapper='prelude', nii_mask=None, threshold=0.05, gaussian_filter=False, sigma=1, process_in_2d=False, fname_save_mask=None)

Creates fieldmap (in Hz) from phase images. This function accommodates multiple echoes (2 or more) and phase difference. This function also accommodates 4D phase inputs, where the 4th dimension represents the time, in case multiple field maps are acquired across time for the purpose of real-time shimming experiments.

Parameters:
  • list_nii_phase (list) -- List of nib.Nifti1Image phase values. The array can be [x, y], [x, y, z] or [x, y, z, t]. The values must range from [-pi to pi].

  • echo_times (list) -- List of echo times in seconds for each echo. The number of echotimes must match the number of echoes. It input is a phasediff (1 phase), input 2 echotimes.

  • unwrapper (str) -- Unwrapper to use for phase unwrapping. Supported: prelude, skimage.

  • mag (numpy.ndarray) -- Array containing magnitude data relevant for phase input. Shape must match phase[echo].

  • nii_mask (nib.Nifti1Image) -- Mask for masking output fieldmap.

  • threshold -- Threshold for masking if no mask is provided. Allowed range: [0, 1] where all scaled values lower than the threshold are set to 0.

  • gaussian_filter (bool) -- Option of using a Gaussian filter to smooth the fieldmaps (boolean)

  • sigma (float) -- Standard deviation of gaussian filter.

  • process_in_2d (bool) -- Unwrap and filter slice by slice. Default is False, which unwraps the whole 3D volume at once.

  • fname_save_mask (str) -- Filename of the mask calculated by the unwrapper

Returns

numpy.ndarray: Unwrapped fieldmap in Hz.

Wrapper to different unwrapping algorithms.

shimmingtoolbox.unwrap.unwrap_phase.unwrap_phase(nii_phase_wrapped, unwrapper='prelude', mag=None, mask=None, threshold=None, is_unwrapping_in_2d=False, fname_save_mask=None)

Calls different unwrapping algorithms according to the specified unwrapper parameter. The function also allows to call the different unwrappers with more flexibility regarding input shape.

Parameters:
  • nii_phase_wrapped (nib.Nifti1Image) -- 2D, 3D or 4D radian values [-pi to pi] to perform phase unwrapping. Supported shapes: [x, y], [x, y, z] or [x, y, z, t].

  • unwrapper (str, optional) -- Unwrapper algorithm name. Possible values: prelude, skimage.

  • mag (numpy.ndarray) -- 2D, 3D or 4D magnitude data corresponding to phase data. Shape must be the same as phase.

  • mask (numpy.ndarray) -- numpy array of booleans with shape of phase to mask during phase unwrapping.

  • threshold (float) -- Prelude parameter, see prelude for more detail.

  • is_unwrapping_in_2d (bool) -- Unwrap and filter slice by slice. Default is False, which unwraps the whole 3D volume at once.

  • fname_save_mask (str) -- Filename of the mask calculated by the unwrapper

Returns:

Unwrapped phase image.

Return type:

numpy.ndarray

Wrapper to FSL Prelude (https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FUGUE/Guide#PRELUDE_.28phase_unwrapping.29)

shimmingtoolbox.unwrap.prelude.prelude(nii_wrapped_phase, mag=None, mask=None, threshold=None, is_unwrapping_in_2d=False, fname_save_mask=None)

wrapper to FSL prelude

This function enables phase unwrapping by calling FSL prelude on the command line. A mask can be provided to mask the phase image provided. 2D unwrapping can be turned off. The output path can be specified. The temporary niis can optionally be saved.

Parameters:
  • nii_wrapped_phase (nib.Nifti1Image) -- 2D or 3D radian numpy array to perform phase unwrapping. (2 pi interval)

  • mag (numpy.ndarray) -- 2D or 3D magnitude numpy array corresponding to the phase array

  • mask (numpy.ndarray, optional) -- numpy array of booleans with shape of complex_array to mask during phase unwrapping

  • threshold -- Threshold value for automatic mask generation (Use either mask or threshold, not both)

  • is_unwrapping_in_2d (bool, optional) -- prelude parameter to unwrap slice by slice

  • fname_save_mask (str) -- Filename of the mask calculated by the unwrapper

Returns:

3D array with the shape of complex_array of the unwrapped phase output from prelude

Return type:

numpy.ndarray

Wrapper to skimage unwrap_phase

shimmingtoolbox.unwrap.skimage_unwrap.skimage_unwrap(nii_wrapped_phase, mag=None, mask=None, threshold=None, is_unwrapping_in_2d=False, fname_save_mask=None)

Unwraps the phase using skimage unwrap_phase.

Parameters:
  • nii_wrapped_phase (nib.Nifti1Image) -- 2D or 3D radian numpy array to perform phase unwrapping. (2 pi interval)

  • mag (numpy.ndarray) -- 2D or 3D magnitude numpy array corresponding to the phase array

  • mask (numpy.ndarray) -- numpy array of booleans with shape of complex_array to mask during phase unwrapping

  • threshold -- Threshold value for automatic mask generation (Use either mask or threshold, not both)

  • is_unwrapping_in_2d (bool, optional) -- Parameter to unwrap slice by slice

  • fname_save_mask (str) -- Filename of the mask calculated by the unwrapper

Returns:

3D array with the shape of complex_array of the unwrapped phase output from prelude

Return type:

numpy.ndarray

Masking

Image mask with shape API

shimmingtoolbox.masking.shapes.shape_cube(data, len_dim1, len_dim2, len_dim3, center_dim1=None, center_dim2=None, center_dim3=None)

Creates a cube mask. Returns mask with the same shape as data.

Parameters:
  • data (numpy.ndarray) -- Data to mask, must be 3 dimensional array.

  • len_dim1 (int) -- Length of the side of the square along first dimension (in pixels).

  • len_dim2 (int) -- Length of the side of the square along second dimension (in pixels).

  • len_dim3 (int) -- Length of the side of the square along third dimension (in pixels).

  • center_dim1 (int) -- Center of the square along first dimension (in pixels). If no center is provided, the middle is used.

  • center_dim2 (int) -- Center of the square along second dimension (in pixels). If no center is provided, the middle is used.

  • center_dim3 (int) -- Center of the square along third dimension (in pixels). If no center is provided, the middle is used.

Returns:

Mask with booleans. True where the cube is located and False in the background.

Return type:

numpy.ndarray

shimmingtoolbox.masking.shapes.shape_sphere(data, radius, center_dim1=None, center_dim2=None, center_dim3=None)

Creates a spherical mask. Returns mask with the same shape as data.

Parameters:
  • data (numpy.ndarray) -- Data to mask, must be 3 dimensional array.

  • radius (int) -- Radius of the sphere (in pixels).

  • center_dim1 (int) -- Center of the sphere along the first dimension (in pixels). If no center is provided, the middle is used.

  • center_dim2 (int) -- Center of the sphere along the second dimension (in pixels). If no center is provided, the middle is used.

  • center_dim3 (int) -- Center of the sphere along the third dimension (in pixels). If no center is provided, the middle is used.

Returns:

Mask with booleans. True where the sphere is located and False in the background.

Return type:

numpy.ndarray

shimmingtoolbox.masking.shapes.shape_square(data, len_dim1, len_dim2, center_dim1=None, center_dim2=None)

Creates a square mask. Returns mask with the same shape as data.

Parameters:
  • data (numpy.ndarray) -- Data to mask, must be 2 dimensional array.

  • len_dim1 (int) -- Length of the side of the square along first dimension (in pixels).

  • len_dim2 (int) -- Length of the side of the square along second dimension (in pixels).

  • center_dim1 (int) -- Center of the square along first dimension (in pixels). If no center is provided, the middle is used.

  • center_dim2 (int) -- Center of the square along second dimension (in pixels). If no center is provided, the middle is used.

Returns:

Mask with booleans. True where the square is located and False in the background.

Return type:

numpy.ndarray

shimmingtoolbox.masking.shapes.shapes(data, shape, **kargs)

Wrapper to different shape masking functions.

Parameters:
  • data (numpy.ndarray) -- Data to mask.

  • shape (str) -- Shape to mask, implemented shapes include: {'square', 'cube', 'sphere'}.

  • **kargs -- Refer to the specific function in this file for the specific arguments for each shape. See example section for more details.

Returns:

Mask with booleans. True where the shape is located and False in the background.

Return type:

numpy.ndarray

Examples

>>> dummy_data = np.ones([4,3])
>>> dummy_mask = shapes(dummy_data, 'square', center_dim1=1, center_dim2=1, len_dim1=1, len_dim2=3)

Image thresholding API

shimmingtoolbox.masking.threshold.threshold(data, thr=30, scaled_thr=False)

Threshold an image

Parameters:
  • data (threshold. For complex) -- Data to be masked

  • thr (float) -- Value to threshold the data: voxels will be set to zero if their value is equal or less than this

  • data

  • values. (threshold is applied on the absolute)

  • scaled_thr (bool) -- Specifies if the threshold is absolute or scaled [0, 1].

Returns:

Boolean mask with same dimensions as data

Return type:

numpy.ndarray

shimmingtoolbox.masking.mask_utils.modify_binary_mask(mask, shape='sphere', size=3, operation='dilate')

Dilates or erodes a binary mask according to different shapes and kernel size

Parameters:
  • mask (numpy.ndarray) -- 3d array containing the binary mask.

  • shape (str) -- 3d kernel to perform the dilation. Allowed shapes are: 'sphere', 'cross', 'line', 'cube', 'None'. 'line' uses 3 line kernels to extend in each directions by "(size - 1) / 2" only if that direction is smaller than (size - 1) / 2

  • size (int) -- Length of a side of the 3d kernel. Must be odd.

  • operation (str) -- Operation to perform. Allowed operations are: 'dilate', 'erode'.

Returns:

Dilated/eroded mask.

Return type:

numpy.ndarray

Notes

Kernels for

  • 'cross' size 3:
    np.array([[[0, 0, 0],
               [0, 1, 0],
               [0, 0, 0]],
              [[0, 1, 0],
               [1, 1, 1],
               [0, 1, 0]],
              [[0, 0, 0],
               [0, 1, 0],
               [0, 0, 0]]])
    
  • 'sphere' size 5:
    np.array([[[0 0 0 0 0],
               [0 0 0 0 0],
               [0 0 1 0 0],
               [0 0 0 0 0],
               [0 0 0 0 0]],
              [[0 0 0 0 0],
               [0 0 1 0 0],
               [0 1 1 1 0],
               [0 0 1 0 0],
               [0 0 0 0 0]],
              [[0 0 1 0 0],
               [0 1 1 1 0],
               [1 1 1 1 1],
               [0 1 1 1 0],
               [0 0 1 0 0]],
              [[0 0 0 0 0],
               [0 0 1 0 0],
               [0 1 1 1 0],
               [0 0 1 0 0],
               [0 0 0 0 0]],
              [[0 0 0 0 0],
               [0 0 0 0 0],
               [0 0 1 0 0],
               [0 0 0 0 0],
               [0 0 0 0 0]]]
    
  • 'cube' size 3:
    np.array([[[1, 1, 1],
               [1, 1, 1],
               [1, 1, 1]],
              [[1, 1, 1],
               [1, 1, 1],
               [1, 1, 1]],
              [[1, 1, 1],
               [1, 1, 1],
               [1, 1, 1]]])
    
  • 'line' size 3:
    np.array([[[0, 0, 0],
               [0, 1, 0],
               [0, 0, 0]],
              [[0, 0, 0],
               [0, 1, 0],
               [0, 0, 0]],
              [[0, 0, 0],
               [0, 1, 0],
               [0, 0, 0]]])
    
shimmingtoolbox.masking.mask_utils.resample_mask(nii_mask_from, nii_target, from_slices=None, dilation_kernel='None', dilation_size=3, path_output=None, return_non_dil_mask=False)

Resample a source mask (nii_mask_from) onto a target image (nii_target) while selecting specific slices and applying optional dilation restricted to the region of interest (ROI).

This function performs the following steps:

  1. Slice Selection: If from_slices is specified, only the corresponding axial slices from the input mask are used.

  2. Resampling: The sliced mask is resampled to match the spatial resolution, dimensions, and orientation of nii_target.

  3. Dilation:

    • If the mask is binary (i.e., contains only 0/1 or boolean values), morphological dilation is applied using the specified kernel and size.

    • If the mask is soft (i.e., contains float values between 0 and 1), dilation is performed by assigning the minimum non-zero voxel value to the surrounding voxels within a specified distance, based on the Euclidean distance transform.

  4. ROI Constraint: The dilated mask is intersected with the resampled full original mask (before slice selection) to ensure that added voxels remain within the originally defined ROI.

  5. Output: The function returns the final mask (dilated and ROI-restricted). If return_non_dil_mask is True, it also returns the undilated mask.

Parameters:
  • nii_mask_from (nib.Nifti1Image) -- Source mask to resample. Voxels with value 0 or False are considered outside the mask.

  • nii_target (nib.Nifti1Image) -- Target image defining the desired output space.

  • from_slices (tuple) -- Indices of the slices to select from nii_mask_from. If None, all slices are used.

  • dilation_kernel (str) -- Shape of the kernel used for dilation. Allowed shapes: 'sphere', 'cross', 'line', 'cube'. See modify_binary_mask() for more details.

  • dilation_size (int) -- Size of the 3D dilation kernel. Must be odd. For instance, a size of 3 dilates the mask by 1 voxel.

  • path_output (str) -- Optional path to save masks when debugging.

  • return_non_dil_mask (bool) -- If True, both the dilated and undilated resampled masks are returned.

Returns:

Mask resampled with nii_target.shape and nii_target.affine.

Return type:

nib.Nifti1Image

Creating MRS mask API

shimmingtoolbox.masking.mask_mrs.mask_mrs(fname_input, raw_data, center, size)

Create a mask to shim single voxel MRS

Parameters:
  • fname_input (str) -- Input path of the fieldmap to be shimmed (supported extension .nii and .nii.gz)

  • raw_data (str) -- Input path of the siemens raw-data (supported extension .rda)

  • center (list) -- Voxel's center position in mm of the x, y and z scanner coordinates

  • size (list) -- Voxel size in mm of the x, y and z scanner coordinates

Returns:

Cubic mask with the same dimensions as the MRS voxel.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.add_softmask_to_binmask(soft_mask, binary_mask)

Add a soft mask to a binary mask to create a new soft mask.

Parameters:
  • soft_mask (numpy.ndarray) -- 3D array containing the soft mask.

  • binary_mask (numpy.ndarray) -- 3D array containing the binary mask.

Returns:

New soft mask.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.create_gaussian_softmask(binary_mask, soft_width)

Create a soft mask from a binary mask. The final mask contains a gaussian blur from the binary mask to the background.

Parameters:
  • binary_mask (numpy.ndarray) -- 3D array containing the binary mask.

  • soft_width (int) -- Width of the soft zone (in pixels).

Returns:

Soft mask created from the binary mask.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.create_linear_softmask(binary_mask, soft_width)

Create a soft mask from a binary mask. The final mask contains a linear gradient from the binary mask to the background.

Parameters:
  • binary_mask (numpy.ndarray) -- 3D array containing the binary mask.

  • soft_width (int) -- Width of the soft zone (in pixels).

Returns:

Soft mask created from the binary mask.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.create_softmask(fname_binmask, fname_softmask=None, type='2levels', soft_width=6, width_unit='mm', soft_value=0.5)

Create a soft mask from a binary mask by adding a soft zone around the binary mask.

Parameters:
  • fname_binmask (str) -- Path to the binary mask.

  • fname_softmask (str) -- Path to an existing soft mask. Used only if type is 'sum'.

  • type (str) -- Type of soft mask to create. Allowed types are: '2levels', 'linear', 'gaussian', 'sum'.

  • soft_width (float) -- Width of the soft zone.

  • soft_units (str) -- Units of the soft width ('mm' or 'px').

  • soft_value (float) -- Value of the intensity of the pixels in the soft zone. Used only if type is '2levels'.

Returns:

3D array containing the soft mask.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.create_two_levels_softmask(binary_mask, soft_width, soft_value)

Create a soft mask from a binary mask. The final mask combines the binary mask and its dilated version multiplied by a soft value.

Parameters:
  • binary_mask (numpy.ndarray) -- 3D array containing the binary mask.

  • soft_width (int) -- Width of the soft zone (in pixels).

  • soft_value (float) -- Value of the intensity of the pixels in the soft zone.

Returns:

Soft mask created from the binary mask.

Return type:

numpy.ndarray

shimmingtoolbox.masking.softmasks.save_softmask(soft_mask, fname_soft_mask, fname_binary_mask)

Save the soft mask to a NIFTI file

Parameters:
  • soft_mask (numpy.ndarray) -- 3D array containing the soft mask.

  • fname_soft_mask (str) -- Path to save the soft mask.

  • fname_binary_mask (str) -- Path to the binary mask used to create the soft mask.

Returns:

NIFTI file containing the soft mask created from the binary mask.

Return type:

nib.Nifti1Image

Coils

class shimmingtoolbox.coils.coil.Coil(profile, affine, constraints)

Coil profile object that stores coil profiles and there constraints

dim

Dimension along specific axis. dim: 0,1,2 are spatial axes, while dim: 3 corresponds to the coil channel.

Type:

Tuple[int]

profile

(dim1, dim2, dim3, channels) 4d array of N 3d coil profiles

Type:

np.ndarray

affine

4x4 array containing the affine transformation associated with the NIfTI file of the coil profile. This transformation relates to the physical coordinates of the scanner (qform).

Type:

np.ndarray

required_constraints

List containing the required keys for constraints

Type:

list

coef_sum_max

Contains the maximum value for the sum of the coefficients

Type:

float

coef_channel_minmax

Dict of (min, max) pairs for each coil channels. (None, None) is used to specify no bounds.

Type:

dict

name

Name of the coil.

Type:

str

__init__(profile, affine, constraints)

Initialize Coil

Parameters:
  • profile (np.ndarray) -- Coil profile (dim1, dim2, dim3, channels) 4d array of N 3d coil profiles

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the coil profiles

  • constraints (dict) --

    dict containing the constraints for the coil profiles.

    • name (str): Name of the coil. (Required)

    • coef_sum_max (float): Contains the maximum value for the sum of the coefficients. None is used to specify no bounds. (Required)

    • coef_channel_minmax (list): List of [min, max] pairs for each coil channels. (None, None) is used to specify no bounds. (Required)

    • coefs_used (list): List of the coefficients that are currently being used. Defaults to 0 if not set. (Optional)

Examples

# Example of constraints
constraints = {
    "name": "custom",
    "coef_channel_minmax": {
        "coil": [[-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5],
                 [-2.5, 2.5]]
    },
    "coef_sum_max": 20,
    "coefs_used": {"coil": [1, 1, 1, 1, 1, 1, 1, 1]},
    "Units": "A"
}
constraints = {
    "name": "Prisma_fit",
    "coef_channel_minmax": {
        "0": [[123100100, 123265000]],
        "1": [[-2300, 2300],
              [-2300, 2300],
              [-2300, 2300]],
        "2": [[-4959.01, 4959.01],
              [-3551.29, 3551.29],
              [-3503.299, 3503.299],
              [-3551.29, 3551.29],
              [-3487.302, 3487.302]]
        },
    "coef_sum_max": None
    "coefs_used": {
        "0": [1],
        "1": [1, 1, 1],
        "2": [1, 1, 1, 1, 1]
    },
}
load_constraints(constraints: dict)

Loads the constraints as attribute to this class. The constraints are updated according to the 'coefs_used', if available.

class shimmingtoolbox.coils.coil.ScannerCoil(dim_volume, affine, constraints, orders, manufacturer='', shim_cs=None, isocenter=array([0, 0, 0]))

Coil class for scanner coils as they require extra arguments

__init__(dim_volume, affine, constraints, orders, manufacturer='', shim_cs=None, isocenter=array([0, 0, 0]))
Parameters:
  • dim_volume (tuple) -- x, y and z dimensions.

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the coil profiles

  • constraints (dict) --

    dict containing the constraints for the coil profiles. Required keys:

    • name (str): Name of the coil.

    • coef_sum_max (float): Contains the maximum value for the sum of the coefficients. None is used to specify no bounds

    • coef_channel_max (list): List of (min, max) pairs for each coil channels. (None, None) is used to specify no bounds.

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order)

  • manufacturer (str) -- Manufacturer of the scanner. "SIEMENS", "GE" or "PHILIPS".

  • shim_cs (str) -- Coordinate system of the shims. Letter 1 'R' or 'L', letter 2 'A' or 'P', letter 3 'S' or 'I'. Only relevant if the manufacturer is unknown. Default: 'RAS'.

  • isocenter (np.ndarray) -- Position of the isocenter in the image. Default: [0, 0, 0]

shimmingtoolbox.coils.coil.get_scanner_constraints(manufacturers_model_name, orders, manufacturer, device_serial_number, shim_settings, external_constraints=None)
Returns the scanner spherical harmonics constraints depending on the manufacturer's model name and required

order

Parameters:
  • manufacturers_model_name (str) -- Name of the scanner

  • orders (list) -- List of all orders of the shim system to be used

  • manufacturer (str) -- Manufacturer of the scanner

  • device_serial_number (str) -- Serial number of the device, used to identify the scanner

  • shim_settings (dict) -- Dictionary containing the shim settings

  • external_constraints (dict) -- External constraints to be used as priority

Returns:

The constraints including the scanner name, bounds and the maximum sum of currents.

Return type:

dict

shimmingtoolbox.coils.coil.restrict_to_orders(shim_dict: dict, orders)

Select the keys according to the order specified

Parameters:
  • shim_dict (dict) -- Dictionary containing keys with the spherical harmonic orders

  • orders (list) -- List of all spherical harmonics orders to be used

Returns:

Dictionary with only the keys specified in orders

Return type:

dict

shimmingtoolbox.coils.spherical_harmonics.spherical_harmonics(orders, x, y, z)

Returns an array of spherical harmonic basis fields with the order/degree index along the 4th dimension.

Parameters:
  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers (np.array(range(0, 3)) yields harmonics up to (n-1)-th order). Must be non negative.

  • x (numpy.ndarray) -- 3-D arrays of grid coordinates

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x)

Returns:

4d basis set of spherical harmonics with order/degree ordered along 4th dimension

Return type:

numpy.ndarray

Examples

Initialize grid positions

>>> [x, y, z] = np.meshgrid(np.array(range(-10, 11)), np.array(range(-10, 11)), np.array(range(-10, 11)), indexing='ij')

0th-to-2nd order terms inclusive

>>> orders = np.array(range(0, 3))
>>> basis = spherical_harmonics(orders, x, y, z)

Notes

  • basis[:, :, :, 0] corresponds to the 0th-order constant term (globally=unity)
    • 0: c

  • basis[:, :, :, 1:4] to 1st-order linear terms
    • 1: y

    • 2: z

    • 3: x

  • basis[:, :, :, 4:8] to 2nd-order terms
    • 4: xy

    • 5: zy

    • 6: z2

    • 7: zx

    • 8: x^2 - y^2

  • basis[:, :, :, 8:15] to 3rd-order terms
    • 9: y(x^2 - y^2)

    • 10: xyz

    • 11: yz^2

    • 12: z^3

    • 13: xz^2

    • 14: z(x^2 - y^2)

    • 15: x(x^2 - y^2)

Based on
shimmingtoolbox.coils.spher_harm_basis.channels_per_order(order, manufacturer=None)

Return the number of channels per order for the specified manufacturer

Parameters:
  • order (int) -- Order of the spherical harmonics

  • manufacturer (str) -- Manufacturer of the scanner.

Returns:

shimmingtoolbox.coils.spher_harm_basis.convert_spher_harm_to_dict(spher_harm, orders)

Convert an array of spherical harmonics to a dictionary of 3D/4d arrays, where each key is the order of the

Parameters:
  • spher_harm (np.ndarray) -- Array of spherical harmonics

  • orders (tuple) -- Tuple containing the orders of the spherical harmonics in the array, sorted in ascending order

Returns:

Dictionary of 3D arrays, where each key is the order of the spherical harmonic

Return type:

dict

shimmingtoolbox.coils.spher_harm_basis.ge_basis(x, y, z, orders=(1, 2))

The function first wraps shimmingtoolbox.coils.spher_harm_basis.scaled_spher_harm to generate the specified order spherical harmonic basis fields at the grid positions given by arrays x,y,z. Following GE convention, basis is then:

  • Rescaled:

    • 1 XXXXX for X,Y,Z gradients (= Hz/mm)

    • Hz/mm^2 / 1 mA for the 2nd order terms (See details below for the different channels)

  • Reordered along the 4th dimension as X, Y, Z, XY, ZY, ZX, X2-Y2, Z2

The returned basis is thereby in the form of ideal "shim reference maps", ready for optimization.

Parameters:
  • x (numpy.ndarray) -- 3-D arrays of grid coordinates, "Left->Right" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Posterior->Anterior" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Inferior->Superior" grid coordinates in the patient coordinate system (i.e. NIfTI reference, units of mm)

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order, implemented 1st and 2nd order)

Returns:

4-D array of spherical harmonic basis fields

Return type:

numpy.ndarray

shimmingtoolbox.coils.spher_harm_basis.philips_basis(x, y, z, orders=(1, 2))

The function first wraps shimmingtoolbox.coils.spherical_harmonics to generate the specified order spherical harmonic basis fields at the grid positions given by arrays X,Y,Z. Following Philips convention, basis is then:

  • Rescaled to Hz/unit-shim, where "unit-shim" refers to:

    • 1 milli-T/m for X,Y,Z gradients (= 42.576 Hz/mm)

    • 1 milli-T/m^2 for 2nd order terms (= 0.042576 Hz/mm^2)

  • Reordered along the 4th dimension as X, Y, Z, Z2, ZX, ZY, X2-Y2, 2XY, Z3, Z2X, Z2Y, Z(X2-Y2), 2XYZ, X3, Y3

The returned basis is thereby in the form of ideal "shim reference maps", ready for optimization.

Parameters:
  • x (numpy.ndarray) -- 3-D arrays of grid coordinates, "Left->Right" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Posterior->Anterior" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Inferior->Superior" grid coordinates in the patient coordinate system (i.e. NIfTI reference, units of mm)

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order, implemented 1st and 2nd order)

Returns:

4-D array of spherical harmonic basis fields

Return type:

numpy.ndarray

Note

Philips coordinate system has its x in the AP direction and y axis in the RL direction. Therefore, channel 0 (x) changes along axis 1 and channel 1 (y) changes along axis 0.

shimmingtoolbox.coils.spher_harm_basis.reorder_to_manufacturer(spher_harm, manufacturer)

Reorder 1st - 2nd - 3rd order coefficients, if specified. From

Y, Z, X, XY, ZY, Z2, ZX, X2 - Y2, Y(X2 - Y2), XYZ, Z2Y, Z3, Z2X, Z(X2 - Y2), X(X2 - Y2) (output by shimmingtoolbox.coils.spherical_harmonics.spherical_harmonics), to

X, Y, Z, Z2, ZX, ZY, X2 - Y2, XY, Z3, Z2X, Z2Y, Z(X2 - Y2) (in line with Siemens shims) or

X, Y, Z, Z2, ZX, ZY, X2 - Y2, XY (in line with GE shims) or

X, Y, Z, Z2, ZX, ZY, X2 - Y2, XY, Z3, Z2X, Z2Y, Z(X2 - Y2), XYZ, X(X2 - Y2), Y(X2 - Y2) (in line with Philips shims)

Parameters:
  • spher_harm (dict) -- 3D array of spherical harmonics coefficients with key corresponding to the order

  • manufacturer (str) -- Manufacturer of the scanner

Returns:

Coefficients ordered following the manufacturer's convention

Return type:

dict

shimmingtoolbox.coils.spher_harm_basis.scaled_spher_harm(x, y, z, orders=(1, 2))

The function first wraps shimmingtoolbox.coils.spherical_harmonics to generate the specified orders spherical harmonic basis fields at the grid positions given by arrays X,Y,Z. It is then:

  • Rescaled to 1uT/m or 1uT/m^2 in units of Hz/mm or Hz/mm^2:

    • 1 micro-T/m for X,Y,Z gradients(= 0.042576 Hz/mm)

    • 1 micro-T/m^2 for 2nd order terms (= 0.000042576 Hz/mm^2)

    • 1 micro-T/m^3 for 3rd order terms (= 0.000000042576 Hz/mm^3)

  • Ordered: Y, Z, X, XY, ZY, Z2, ZX, X2 - Y2

Parameters:
  • x (numpy.ndarray) -- 3-D arrays of grid coordinates, "Left->Right" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Posterior->Anterior" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Inferior->Superior" grid coordinates in the patient coordinate system (i.e. NIfTI reference, units of mm)

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order, implemented 1st and 2nd order)

Returns:

dictionary of the basis set of spherical harmonics scaled

Return type:

dict

shimmingtoolbox.coils.spher_harm_basis.sh_basis(x, y, z, orders=(1, 2), shim_cs='RAS')

The function first wraps shimmingtoolbox.coils.spherical_harmonics to generate the specified order spherical harmonic basis fields at the grid positions given by arrays x,y,z. basis is then:

  • Rescaled to Hz/unit-shim, where "unit-shim" refers to:

    • 1 micro-T/m for X,Y,Z gradients (= 0.042576 Hz/mm)

    • 1 micro-T/m^2 for 2nd order terms (= 0.000042576 Hz/mm^2)

    • 1 micro-T/m^3 for 3rd order terms (= 0.000000042576 Hz/mm^3)

  • Reordered along the 4th dimension as X, Y, Z, Z2, ZX, ZY, X2 - Y2, XY, Z3, Z2X, Z2Y, Z(X2 - Y2), XYZ, X(X2 - Y2), Y(X2 - Y2)

The returned basis is thereby in the form of ideal "shim reference maps", ready for optimization.

Parameters:
  • x (numpy.ndarray) -- 3-D arrays of grid coordinates, "Left->Right" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Posterior->Anterior" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Inferior->Superior" grid coordinates in the patient coordinate system (i.e. NIfTI reference, units of mm)

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order)

  • shim_cs (str) -- Coordinate system of the shims. Letter 1 'R' or 'L', letter 2 'A' or 'P', letter 3 'S' or 'I'.

Returns:

4-D array of spherical harmonic basis fields

Return type:

numpy.ndarray

shimmingtoolbox.coils.spher_harm_basis.siemens_basis(x, y, z, orders=(1, 2))

The function first wraps shimmingtoolbox.coils.spherical_harmonics to generate the specified order spherical harmonic basis fields at the grid positions given by arrays x,y,z. Following Siemens convention, basis is then:

  • Rescaled to Hz/unit-shim, where "unit-shim" refers to the measure displayed in the Adjustments card of the Syngo console UI, namely:

    • 1 micro-T/m for X,Y,Z gradients (= 0.042576 Hz/mm)

    • 1 micro-T/m^2 for 2nd order terms (= 0.000042576 Hz/mm^2)

    • 1 micro-T/m^3 for 3rd order terms (= 0.000000042576 Hz/mm^3)

  • Reordered along the 4th dimension as Y, Z, X, XY, ZY, Z2, ZX, X2 - Y2, Y(X2 - Y2), XYZ, Z2Y, Z3

The returned basis is thereby in the form of ideal "shim reference maps", ready for optimization.

Parameters:
  • x (numpy.ndarray) -- 3-D arrays of grid coordinates, "Left->Right" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • y (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Posterior->Anterior" grid coordinates in the patient coordinate system (i.e. NIfTI reference (RAS), units of mm)

  • z (numpy.ndarray) -- 3-D arrays of grid coordinates (same shape as x). "Inferior->Superior" grid coordinates in the patient coordinate system (i.e. NIfTI reference, units of mm)

  • orders (tuple) -- Degrees of the desired terms in the series expansion, specified as a vector of non-negative integers ((0:1:n) yields harmonics up to n-th order, implemented 1st, 2nd and 3rd order)

Returns:

4-D array of spherical harmonic basis fields

Return type:

numpy.ndarray

shimmingtoolbox.coils.coordinates.generate_meshgrid(dim, affine)

Generate meshgrid of size dim, with coordinate system defined by affine. :param dim: x, y and z dimensions. :type dim: tuple :param affine: 4x4 affine matrix :type affine: numpy.ndarray

Returns:

List of numpy.ndarray containing meshgrid of coordinates

Return type:

list

shimmingtoolbox.coils.coordinates.get_main_orientation(cosines: list)

Returns the orientation of the slice axis by looking at the ImageOrientationPatientDICOM JSON tag

Parameters:
  • cosines (list) -- list of 6 elements. The first 3 represent the x, y, z cosines of the first row. The last 3

  • x (represent the)

  • y

  • it (z cosines of the first column. This can be found in ImageOrientationPatientDICOM so)

  • coordinates. (should be LPS)

Returns:

'SAG', 'COR' or 'TRA'

Return type:

str

shimmingtoolbox.coils.coordinates.phys_gradient(data, affine)

Calculate the gradient of data along physical coordinates defined by affine

Parameters:
  • data (numpy.ndarray) -- 3d array containing data to apply gradient

  • affine (numpy.ndarray) -- 4x4 array containing affine transformation

Returns

numpy.ndarray: 3D matrix containing the gradient along the x direction in the physical coordinate system numpy.ndarray: 3D matrix containing the gradient along the y direction in the physical coordinate system numpy.ndarray: 3D matrix containing the gradient along the z direction in the physical coordinate system

shimmingtoolbox.coils.coordinates.phys_to_vox_coefs(gx, gy, gz, affine)

Calculate the vector sum along the image coordinates defined by affine with coefficients in the patient coordinate system.

Parameters:
  • gx (numpy.ndarray) -- 3D matrix containing the coefs along the x direction in the patient coordinate system

  • gy (numpy.ndarray) -- 3D matrix containing the coefs along the y direction in the patient coordinate system

  • gz (numpy.ndarray) -- 3D matrix containing the coefs along the z direction in the patient coordinate system

  • affine (numpy.ndarray) -- 4x4 array containing affine transformation

Returns:

3D matrix containing the coefs along the x direction in the image coordinate system numpy.ndarray: 3D matrix containing the coefs along the y direction in the image coordinate system numpy.ndarray: 3D matrix containing the coefs along the z direction in the image coordinate system

Return type:

numpy.ndarray

shimmingtoolbox.coils.coordinates.resample_from_to(nii_from_img, nii_to_vox_map, order=2, mode='nearest', cval=0.0, out_class=<class 'nibabel.nifti1.Nifti1Image'>)

Wrapper to nibabel's resample_from_to function. Resample image from_img to mapped voxel space to_vox_map. The wrapper adds support for 2D input data (adds a singleton) and for 4D time series. For more info, refer to nibabel.processing.resample_from_to.

Parameters:
  • nii_from_img (nibabel.Nifti1Image) -- Nibabel object with 2D, 3D or 4D array. The 4d case will be treated as a timeseries.

  • nii_to_vox_map (nibabel.Nifti1Image) -- Nibabel object with

  • order (int) -- Refer to nibabel.processing.resample_from_to

  • mode (str) -- Refer to nibabel.processing.resample_from_to

  • cval (scalar) -- Refer to nibabel.processing.resample_from_to

  • out_class -- Refer to nibabel.processing.resample_from_to

Returns:

Return a Nibabel object with the resampled data. The 4d case will have an extra dimension

for the different time points.

Return type:

nibabel.Nifti1Image

shimmingtoolbox.coils.biot_savart.biot_savart(centers, normals, radii, segment_numbers, fov_min, fov_max, fov_n)

Creates coil profiles for arbitrary loops, for use in multichannel shim examples that do not match spherical harmonics :param centers: List of 3D float center points for each loop in mm :type centers: list :param normals: List of 3D float normal vectors for each loop in mm :type normals: list :param radii: List of float radii for each loop in mm :type radii: list :param segment_numbers: List of integer number of segments for each loop approximation :type segment_numbers: list :param fov_min: Low 3D float corner of coil profile field of view (x, y, z) in mm :type fov_min: tuple :param fov_max: Inclusive high 3D float corner of coil profile field of view (x, y, z) in mm :type fov_max: tuple :param fov_n: Integer number of points for each dimension (x, y, z) in mm :type fov_n: tuple

Returns:

(X, Y, Z, centers) coil profiles of magnetic field z-component in Hz/A -- (X, Y, Z, Channel)

Return type:

numpy.ndarray

shimmingtoolbox.coils.biot_savart.generate_coil_bfield(wire, xyz, grid_size)

Generates Bz field in the FOV

Parameters:
  • wire (list) -- 1D list of n_segments dictionaries with start and stop point of the segment

  • xyz (np.array) -- 2D array shape (n_points, 3) where n_points is the number of points in the whole FOV. Represents the (x, y, z) coordinates in mm of each point in the FOV

  • grid_size (tuple) -- Shape of the FOV

Returns:

Bz field shaped back to grid_size

Return type:

numpy.ndarray

Shim

Sequencer

class shimmingtoolbox.shim.sequencer.RealTimeSequencer(nif_fieldmap, nif_target, nif_static_mask, nif_riro_mask, slices, pmu: PmuResp, coils_static, coils_riro, method='least_squares', opt_criteria='mse', mask_dilation_kernel='sphere', mask_dilation_kernel_size=3, reg_factor=0, path_output=None, is_pmu_time_offset_auto=False)

Sequencer object that stores different nibabel object, and parameters. It's also doing real time optimization of the currents, and the evaluation of the shimming

nii_fieldmap

Nibabel object containing fieldmap data in 4d where the 4th dimension is the timeseries. Also contains an affine transformation.

Type:

nib.Nifti1Image

json_fmap

Dict of the json sidecar corresponding to the fieldmap data (Used to find the acquisition timestamps).

Type:

dict

nii_target

Nibabel object containing target image data in 3d.

Type:

nib.Nifti1Image

nii_static_mask

3D target mask used for the optimizer to shim the region for the static component.

Type:

nib.Nifti1Image

nii_riro_mask

3D target mask used for the optimizer to shim the region for the riro component.

Type:

nib.Nifti1Image

slices

1D array containing tuples of dim3 slices to shim according to the target where the shape of target: (dim1, dim2, dim3). Refer to shimmingtoolbox.shim.sequencer.define_slices().

Type:

list

pmu

PmuResp object containing the respiratory trace information.

Type:

PmuResp

coils

List of Coils containing the coil profiles. The coil profiles and the fieldmaps must have matching units (if fmap is in Hz, the coil profiles must be in hz/unit_shim). Refer to shimmingtoolbox.coils.coil.Coil. Make sure the extent of the coil profiles are larger than the extent of the fieldmap. This is especially true for dimensions with only 1 voxel(e.g. (50x50x1x10). Refer to shimmingtoolbox.shim.sequencer.extend_slice()/ shimmingtoolbox.shim.shim_utils.update_affine_for_ap_slices()

Type:

ListCoil

method

Supported optimizer: 'least_squares', 'pseudo_inverse', 'quad_prog. Note: refer to their specific implementation to know limits of the methods in: shimmingtoolbox.optimizer

Type:

str

opt_criteria

Criteria for the optimizer 'least_squares'. Supported: 'mse': mean squared error, 'mae': mean absolute error, 'std': standard deviation, 'rmse': root mean squared error.

Type:

str

reg_factor

Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred). Only relevant for 'least_squares' opt_method.

Type:

float

mask_dilation_kernel

Kernel used to dilate the mask. Allowed shapes are: 'sphere', 'cross', 'line' 'cube'. See shimmingtoolbox.masking.mask_utils.modify_binary_mask() for more details.

Type:

str

mask_dilation_kernel_size

Length of a side of the 3d kernel to dilate the mask. Must be odd. For example, a kernel of size 3 will dilate the mask by 1 pixel.

Type:

int

path_output

Path to the directory to output figures. Set logging level to debug to output debug artefacts.

Type:

str

optimizer

Object that contains everything needed for the optimization created from shimmingtoolbox.optimizer init method

Type:

object

optimizer_riro

Object that contains everything needed for the riro optimization created from shimmingtoolbox.optimizer init method

Type:

object

bounds

List of the bounds for the currents for the real time optimization

Type:

list

acq_pressures

1D array that contains the acquisitions pressures

Type:

np.ndarray

acq_timestamps

1D array that contains the acquisitions timestamps

Type:

np.ndarray

extended_fmap

True if the fieldmap was extended to be able to shim only 1 slice

Type:

bool

eval(coef_static, coef_riro, mean_p, pressure_rms)

Evaluate the real time shimming by plotting and saving results

Parameters:
  • coef_static (np.ndarray) -- coefficients got during the static optimization

  • coef_riro (np.ndarray) -- coefficients got during the real time optimization

  • mean_p (float) -- mean of the acquisitions pressures

  • pressure_rms (float) -- rms of the acquisitions pressures

get_acq_pressures()

Get the acquisition pressures at the times when the field map volumes and slices were acquired.

Returns:

Acquisition timestamps in ms (n_volumes x n_slices).

Return type:

numpy.ndarray

get_real_time_parameters()

Get real time parameters used for shimming

Returns:

tuple containing:
  • np.ndarray: 3D array containing the static data for the optimization

  • np.ndarray: 3D array containing the real time data for the optimization

  • float: Mean pressure of the respiratory trace.

  • float: Root mean squared of the pressure trace. This is provided to compare results between scans,

    multiply the riro coefficients by rms of the pressure to do so.

Return type:

(tuple)

optimize_riro(mask_target)
Parameters:

mask_target (np.ndarray) -- target mask on which the optimization will be made

Returns:

Riro coefficients of the coil profiles to shim (len(slices) x channels) [Hz/unit_pressure]

plot_currents(static, riro=None)

Plot evolution of currents through shim groups

Parameters:
  • static (np.ndarray) -- Array with the static currents

  • riro (np.ndarray) -- Array with the riro currents

plot_full_time_std(unshimmed, masked_shim_static_riro, mask_fmap_cs, mask)

Plot and save the std heatmap over time

Parameters:
  • unshimmed (np.ndarray) -- Original fieldmap not shimmed shaped (x, y, z, time)

  • masked_shim_static_riro (np.ndarray) -- Masked shimmed fieldmap shaped (x, y, z, time, slices)

  • mask_fmap_cs (np.ndarray) -- Field map mask indicating where delta B0 is not 0 in each slice -- shaped (x, y, z, slices)

  • mask (np.ndarray) -- Mask in the fieldmap space shaped (x, y, z)

plot_pressure_and_unshimmed_field(unshimmed_trace)

Plot respiratory trace, acquisition time pressure points and the B0 field RMSE

Parameters:

unshimmed_trace (np.ndarray) -- field in the ROI for each shim volume

plot_pressure_vs_field(unshimmed, mask_fm)

One graph per i_shim In each graph, one scatter and one line for each fmap slice in the ROI Each line should have pearson correlation coefficient

plot_shimmed_trace(unshimmed_trace, shim_trace_static, shim_trace_riro, shim_trace_static_riro)

Plot shimmed and unshimmed rmse over the roi for each shim

Parameters:
  • unshimmed_trace (np.ndarray) -- array with the trace of the nii_fieldmap data

  • shim_trace_static (np.ndarray) -- array with the trace of the nii_fieldmap data after the static shimming

  • shim_trace_riro (np.ndarray) -- array with the trace of the nii_fieldmap data after the riro shimming

  • shim_trace_static_riro (np.ndarray) -- array with the trace of the nii_fieldmap data after both shimming

print_rt_metrics(unshimmed, shimmed_static, shimmed_static_riro, shimmed_riro, mask)

Print to the console metrics about the realtime and static shim. These metrics isolate temporal and static components

Temporal: Compute the STD across time pixelwise, and then compute the mean across pixels. Static: Compute the MEAN across time pixelwise, and then compute the STD across pixels.

Parameters:
  • unshimmed (np.ndarray) -- Fieldmap not shimmed

  • shimmed_static (np.ndarray) -- Data of the nii_fieldmap after the static shimming

  • shimmed_static_riro (np.ndarray) -- Data of the nii_fieldmap after static and riro shimming

  • shimmed_riro (np.ndarray) -- Data of the nii_fieldmap after the riro shimming

  • mask (np.ndarray) -- Mask where the shimming was done

resample_mask_to_target(nii_target)

Resample the static and riro masks to the target coordinate system

Parameters:

nii_target (nib.Nifti1Image) -- 4d fieldmap

Returns:

tuple containing:
  • np.ndarray: Static mask resampled on the fieldmap

  • np.ndarray: Riro mask resampled on the original fieldmap

  • np.ndarray: Static mask resampled and dilated on the fieldmap

  • np.ndarray: Riro mask resampled and dilated on the original fieldmap

Return type:

(tuple)

resample_masks_to_target_per_shim(nii_fmap)

Resample the static and riro masks to the target coordinate system for each shim group

nii_target (nib.Nifti1Image): 4d fieldmap

Returns:

tuple containing:
  • np.ndarray: Static mask resampled on the fieldmap

  • np.ndarray: Riro mask resampled on the original fieldmap

  • np.ndarray: Static mask resampled and dilated on the fieldmap

  • np.ndarray: Riro mask resampled and dilated on the original fieldmap

Return type:

(tuple)

select_optimizer(unshimmed, affine, pmu: PmuResp | None = None, mean_p=None)

Select and initialize the optimizer

Parameters:
  • unshimmed (np.ndarray) -- 3D B0 map

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • pmu (PmuResp) -- PmuResp object containing the respiratory trace information. Required for method 'least_squares_rt'.

  • mean_p (float) -- Mean pressure of the respiratory trace. Required for methods 'XXX_rt'.

shim()

Performs realtime shimming using one of the supported optimizers and an external respiratory trace.

Returns:

tuple containing:
  • np.ndarray: Static coefficients of the coil profiles to shim (len(slices) x channels) e.g. [Hz]

  • np.ndarray: Riro coefficients of the coil profiles to shim (len(slices) x channels)

    e.g. [Hz/unit_pressure]

  • float: Mean pressure of the respiratory trace.

  • float: Root mean squared of the pressure.

    This is provided to compare results between scans, multiply the riro coefficients by rms of the pressure to do so.

Return type:

(tuple)

class shimmingtoolbox.shim.sequencer.Sequencer(slices, mask_dilation_kernel, mask_dilation_kernel_size, reg_factor, w_signal_loss=0, w_signal_loss_xy=0, epi_te=0, path_output=None)

General class for the sequencer

slices

1D array containing tuples of dim3 slices to shim according to the target, where the shape of target is: (dim1, dim2, dim3). Refer to shimmingtoolbox.shim.sequencer.define_slices().

Type:

list

mask_dilation_kernel

Kernel used to dilate the mask. Allowed shapes are: 'sphere', 'cross', 'line' 'cube'. See shimmingtoolbox.masking.mask_utils.modify_binary_mask() for more details.

Type:

str

mask_dilation_kernel_size

Length of a side of the 3d kernel to dilate the mask. Must be odd. For example, a kernel of size 3 will dilate the mask by 1 pixel.

Type:

int

reg_factor

Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred). Only relevant for 'least_squares' opt_method.

Type:

float

path_output

Path to the directory to output figures. Set logging level to debug to output debug

Type:

str

index_shimmed

Indexes of slices that have been shimmed

index_not_shimmed

Indexes of slices that have not been shimmed

optimize(masks_fmap)

Optimization of the currents for each shim group. Wraps shimmingtoolbox.shim.sequencer.Sequencer.opt().

Parameters:

masks_fmap (np.ndarray) -- 3D fieldmap mask used for the optimizer to shim in the region of interest (only consider voxels with non-zero values)

Returns:

Coefficients of the coil profiles to shim (len(slices) x n_channels)

Return type:

np.ndarray

class shimmingtoolbox.shim.sequencer.ShimSequencer(nif_fieldmap, nif_target, nif_mask_target, slices, coils, method='least_squares', opt_criteria='mse', mask_dilation_kernel='sphere', mask_dilation_kernel_size=3, reg_factor=0, w_signal_loss=None, w_signal_loss_xy=None, epi_te=None, path_output=None)

ShimSequencer object to perform optimization of shim parameters for static and dynamic shimming. This object can also evaluate the shimming performance.

nif_fieldmap

NiftiFieldMap object containing fieldmap data.

Type:

NiftiFieldMap

nif_target

NiftiFile object containing target image data.

Type:

NiftiTarget

nif_mask_target

3D target mask used for the optimizer to shim in the region of interest. (only consider voxels with non-zero values)

Type:

NiftiMask

coils

List of Coils containing the coil profiles. The coil profiles and the fieldmaps must have matching units (if fmap is in Hz, the coil profiles must be in hz/unit_shim). Refer to shimmingtoolbox.coils.coil.Coil. Make sure the extent of the coil profiles are larger than the extent of the fieldmap. This is especially true for dimensions with only 1 voxel(e.g. (50x50x1). Refer to shimmingtoolbox.shim.sequencer.extend_slice()/ shimmingtoolbox.shim.shim_utils.update_affine_for_ap_slices()

Type:

ListCoil

method

Supported optimizer: 'least_squares', 'pseudo_inverse', 'quad_prog', 'bfgs'. Note: refer to their specific implementation to know limits of the methods in: shimmingtoolbox.optimizer

Type:

str

opt_criteria

Criteria for the optimizer 'least_squares'. Supported: 'mse': mean squared error, 'mae': mean absolute error, 'std': standard deviation, 'ps_huber': pseudo huber cost function.

Type:

str

optimizer

Object that contains everything needed for the optimization.

Type:

Optimizer

masks_fmap

Resampled mask on the original fieldmap

Type:

np.ndarray

calc_shimmed_full_mask(unshimmed, correction)

Calculate the shimmed full mask

Parameters:
  • unshimmed (np.ndarray) -- Original fieldmap not shimmed

  • correction (np.ndarray) -- Corrections to apply to the fieldmap

Returns:

tuple containing:
  • np.ndarray: Masked shimmed fieldmap

  • np.ndarray: Mask in the fieldmap space

Return type:

(tuple)

calc_shimmed_gradient_full_mask(gradient)

Calculate the shimmed gradient full mask

Parameters:

gradient (np.ndarray) -- Gradient of each shimmed fieldmap slice

Returns:

tuple containing:
  • np.ndarray: Masked shimmed fieldmap

  • np.ndarray: Mask in the fieldmap space

Return type:

(tuple)

calc_shimmed_target_orient(coefs, list_shim_slice)

Calculate and save the shimmed target orient

Parameters:
  • coefs (np.ndarray) -- Coefficients of the coil profiles to shim (len(slices) x n_channels)

  • list_shim_slice (list) -- list of the index where there was a correction

display_shimmed_results(shimmed, unshimmed, coef)

Print the efficiency of the corrections according to the opt_criteria

Parameters:
  • shimmed (np.ndarray) -- Shimmed fieldmap

  • unshimmed (np.ndarray) -- Original fieldmap not shimmed

  • coef (np.ndarray) -- Coefficients of the coil profiles to shim (len(slices) x n_channels)

eval(coefs)

Calculate theoretical shimmed map and output figures.

Args :

coefs (np.ndarray): Coefficients of the coil profiles to shim (len(slices) x n_channels)

evaluate_shimming(unshimmed, coef, merged_coils)

Evaluate the shimming and print the efficiency of the corrections.

Parameters:
  • unshimmed (np.ndarray) -- Original fieldmap not shimmed

  • coef (np.ndarray) -- Coefficients of the coil profiles to shim (len(slices) x n_channels)

  • merged_coils (np.ndarray) -- Coils resampled on the original fieldmap

Returns:

tuple containing:
  • np.ndarray: Shimmed fieldmap

  • np.ndarray: Corrections to apply to the fieldmap

  • list: List containing the indexes of the shimmed slices

Return type:

(tuple)

get_resampled_masks()

This function resamples the mask on the fieldmap and on the dilated fieldmap

Returns:

tuple containing:
  • nib.Nifti1Image: Mask resampled and dilated on the fieldmap for the optimization

  • nib.Nifti1Image: Mask resampled on the original fieldmap.

Return type:

(tuple)

plot_currents(static)

Plot evolution of currents through shim groups

Parameters:

static (np.ndarray) -- Array with the static coefficients

plot_partial_mask(unshimmed, shimmed, slice)

This figure shows a single fieldmap slice for all shim groups. The shimmed and unshimmed fieldmaps are in the background and the correction is overlaid in color.

Parameters:
  • unshimmed (np.ndarray) -- Original fieldmap not shimmed

  • shimmed (np.ndarray) -- Shimmed fieldmap

  • slice (int) -- Slice to plot

select_optimizer()

Select and initialize the optimizer

Returns:

Initialized Optimizer object

Return type:

Optimizer

shim()

Performs shimming according to slices using one of the supported optimizers and coil profiles.

Returns:

Coefficients of the coil profiles to shim (len(slices) x n_channels)

Return type:

np.ndarray

shimmingtoolbox.shim.sequencer.define_slices(n_slices: int, factor=1, method='ascending', software_version=None)

Define the slices to shim according to the output convention. (list of tuples)

Parameters:
  • n_slices (int) -- Number of total slices.

  • factor (int) -- Number of slices per shim.

  • method (str) -- Defines how the slices should be sorted, supported methods include: 'interleaved', 'ascending', 'descending', 'volume'. See Examples for more details.

Returns:

1D list containing tuples of dim3 slices to shim. (dim1, dim2, dim3)

Return type:

list

Examples

::

slices = define_slices(10, 2, 'interleaved') print(slices) # [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9)] slices = define_slices(20, 5, 'ascending') print(slices) # [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)] slices = define_slices(20, method='volume') # 'volume' ignores the 'factor' option print(slices) # [(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)]

shimmingtoolbox.shim.sequencer.extend_fmap_to_kernel_size(nii_fmap_orig, dilation_kernel_size, path_output=None, ret_location=False)

Load the fmap and expand its dimensions to the kernel size

Parameters:
  • nii_fmap_orig (nib.Nifti1Image) -- 3d (dim1, dim2, dim3) or 4d (dim1, dim2, dim3, t) nii to be extended

  • dilation_kernel_size -- Size of the kernel

  • path_output (str) -- Path to save the debug output

  • ret_location (bool) -- If True, return the location of the original data in the new data

Returns:

Nibabel object of the loaded and extended fieldmap

Return type:

nib.Nifti1Image

shimmingtoolbox.shim.sequencer.new_bounds_from_currents(currents: dict, old_bounds: dict)

Uses the currents to determine the appropriate bounds for the next optimization. It assumes that "old_coef + next_bound < old_bound".

Parameters:
  • currents (dict) -- Dictionary with n_shims as keys each with a list of n_channels values.

  • old_bounds (dict) -- Dictionary with orders as keys containing (min, max) containing the merged bounds of the previous optimization.

Returns:

Modified bounds (same shape as old_bounds)

Return type:

dict

shimmingtoolbox.shim.sequencer.new_bounds_from_currents_static_to_riro(currents, old_bounds, coils_static=[], coils_riro=[])

Uses the currents to determine the appropriate bounds for the next optimization. It assumes that "old_coef + next_bound < old_bound".

Parameters:
  • currents (np.ndarray) -- 2D array (n_shims x n_channels). Direct output from _optimize().

  • old_bounds (list) -- 1d list (n_channels) of tuples (min, max) containing the merged bounds of the previous optimization.

Returns:

2d list (n_shim_groups x n_channels) of bounds (min, max) corresponding to each shim group and channel.

Return type:

list

shimmingtoolbox.shim.sequencer.parse_slices(fname_nifti)

Parse the BIDS sidecar associated with the input nifti file.

Parameters:

fname_nifti (str) -- Full path to a NIfTI file

Returns:

1D list containing tuples of dim3 slices to shim. (dim1, dim2, dim3)

Return type:

list

shimmingtoolbox.shim.sequencer.plot_full_mask(unshimmed, shimmed_masked, mask, path_output)

Plot and save the static full mask

Parameters:
  • unshimmed (np.ndarray) -- Original fieldmap not shimmed

  • shimmed_masked (np.ndarray) -- Masked shimmed fieldmap

  • mask (np.ndarray) -- Mask in the fieldmap space

  • path_output (str) -- Path to the output folder

shimmingtoolbox.shim.sequencer.shim_max_intensity(nii_input, nii_mask=None)
Find indexes of the 4th dimension of the input volume that has the highest signal intensity for each slice.

Based on: https://onlinelibrary.wiley.com/doi/10.1002/hbm.26018

Parameters:
  • nii_input (nib.Nifti1Image) -- 4d volume where 4th dimension was acquired with different shim values

  • nii_mask (nib.Nifti1Image) -- Mask defining the spatial region to shim. If None: consider all voxels of nii_input.

Returns:

1d array containing the index of the volume that maximizes signal intensity for each slice

Return type:

np.ndarray

Shim Utils

This file includes utility functions useful for the shimming module

class shimmingtoolbox.shim.shim_utils.ScannerShimSettings(nif_fmap, orders=None)

Class to handle the scanner shim settings from a NIfTI fieldmap file.

shimmingtoolbox.shim.shim_utils.calculate_metric_within_mask(array, mask, metric, axis=None)

Calculate a weighted metric within a region of interest (ROI) defined by a mask.

This function computes various metrics (mean, standard deviation, mean absolute error, mean squared error, root mean squared error) over a 3D array, considering only the non-zero elements within the mask. The mask contains values from 0 to 1, where 0 indicates the data is masked. For values between 0 and 1, the data is weighted accordingly.

Parameters:
  • array (np.ndarray) -- 3D array of numerical values to compute the metric on.

  • mask (np.ndarray) -- 3D array with the same shape as array, with values between 0 and 1 that define the region of interest (ROI).

  • metric (str) -- The metric to calculate. Options are: 'mean' (average), 'std' (standard deviation), 'mae' (mean absolute error), 'mse' (mean squared error), 'rmse' (root mean squared error).

  • axis (int or None) -- Axis to compute the metric.

Returns:

Array containing the output metrics, if axis is None, the output is a single value

Return type:

np.ndarray

shimmingtoolbox.shim.shim_utils.convert_to_dac_units(shim_settings_coefs_ui, scanner_constraints, scanner_constraints_dac)

Convert shim settings from ui units to DAC units

Parameters:
  • shim_settings_coefs_ui (list) -- List of coefficients in the ui units

  • scanner_constraints (list) -- List containing the constraints of the scanner for a specific order

  • scanner_constraints_dac (list) -- List containing the maximum DAC values for a specific order

Returns:

List of coefficients in the DAC units

Return type:

list

shimmingtoolbox.shim.shim_utils.dac_to_shim_units(manufacturer, manufacturers_model_name, device_serial_number, shim_settings)
Converts the ShimSettings tag from the json BIDS sidecar to the ui units.

(i.e. For the Prisma fit DAC --> uT/m, uT/m^2 (1st order, 2nd order))

Parameters:
  • manufacturer (str) -- Manufacturer of the scanner. "SIEMENS", "GE" or "PHILIPS".

  • manufacturers_model_name (str) -- Name of the model of the scanner. Found in the json BIDS sidecar under ManufacturersModelName'. Supported names: 'Prisma_fit'.

  • device_serial_number (str) -- Serial number of the scanner. Found in the json BIDS sidecar under DeviceSerialNumber.

  • shim_settings (dict) -- Dictionary with keys: '1', '2'. Found in the json BIDS sidecar under 'ShimSetting'. '2' is a list of 5 coefficients.

Returns:

Same dictionary as the shim_settings input with coefficients of the first, second and third order

converted according to the appropriate manufacturer model.

Return type:

dict

shimmingtoolbox.shim.shim_utils.extend_slice(nii_array, n_slices=1, axis=2, location=None)

Adds n_slices on each side of the selected axis. It uses the nearest slice and copies it to fill the values. Updates the affine of the matrix to keep the input array in the same location.

Parameters:
  • nii_array (nib.Nifti1Image) -- 3d or 4d array to extend the dimensions along an axis.

  • n_slices (int) -- Number of slices to add on each side of the selected axis.

  • axis (int) -- Axis along which to insert the slice(s), Allowed axis: 0, 1, 2.

  • location (np.array) -- Location where the original data is located in the new data.

Returns:

Array extended with the appropriate affine to conserve where the original pixels were located.

Return type:

nib.Nifti1Image

Examples

::

print(nii_array.get_fdata().shape) # (50, 50, 1, 10) nii_out = extend_slice(nii_array, n_slices=1, axis=2) print(nii_out.get_fdata().shape) # (50, 50, 3, 10)

shimmingtoolbox.shim.shim_utils.get_phase_encode_direction_sign(fname_nii)

Returns the phase encode direction sign

Parameters:

fname_nii (str) -- Filename to a NIfTI file with its corresponding json file.

Returns:

Returns whether the encoding direction is positive (True) or negative (False)

Return type:

bool

shimmingtoolbox.shim.shim_utils.phys_to_gradient_cs(coefs_x, coefs_y, coefs_z, fname_target)

Converts physical coefficients (x, y, z from RAS Coordinate System) to Siemens Gradient Coordinate System

Parameters:
  • coefs_x (numpy.ndarray) -- Array containing x coefficients in the physical coordinate system RAS

  • coefs_y (numpy.ndarray) -- Array containing y coefficients in the physical coordinate system RAS

  • coefs_z (numpy.ndarray) -- Array containing z coefficients in the physical coordinate system RAS

  • fname_target (str) -- Filename of the NIfTI file to convert the data to that Gradient CS

Returns:

tuple containing:
  • numpy.ndarray: Array containing the data in the gradient CS (frequency/readout)

  • numpy.ndarray: Array containing the data in the gradient CS (phase)

  • numpy.ndarray: Array containing the data in the gradient CS (slice)

Return type:

(tuple)

shimmingtoolbox.shim.shim_utils.phys_to_shim_cs(coefs, manufacturer, orders)

Convert a list of coefficients from RAS to the Shim Coordinate System

Parameters:
  • coefs (np.ndarray) -- Coefficients in the physical RAS coordinate system of the manufacturer. The first dimension represents the different channels. (indexes 0, 1, 2 --> x, y, z...). If there are more coefficients, they are of higher order and must correspond to the implementation of the manufacturer. i.e. Siemens: X, Y, Z, Z2, ZX, ZY, X2-Y2, XY

  • manufacturer (str) -- Name of the manufacturer

  • orders (tuple) -- Tuple containing the spherical harmonic orders

Returns:

Coefficients in the shim coordinate system of the manufacturer

Return type:

np.ndarray

shimmingtoolbox.shim.shim_utils.shim_to_phys_cs(coefs, manufacturer, orders)

Convert coefficients from the shim coordinate system to the physical RAS coordinate system

Parameters:
  • coefs (np.ndarray) -- 1D list of coefficients in the Shim Coordinate System of the manufacturer. The first dimension represents the different channels. Indexes 0, 1, 2 --> x, y, z... If there are more coefficients, they are of higher order and must correspond to the implementation of the manufacturer. Siemens: X, Y, Z, Z2, ZX, ZY, X2-Y2, XY

  • manufacturer (str) -- Name of the manufacturer

  • orders (tuple) -- Tuple containing the spherical harmonic orders

Returns:

Coefficients in the physical RAS coordinate system

Return type:

np.ndarray

shimmingtoolbox.shim.shim_utils.update_affine_for_ap_slices(affine, n_slices=1, axis=2)

Updates the input affine to reflect an insertion of n_slices on each side of the selected axis

Parameters:
  • affine (np.ndarray) -- 4x4 qform affine matrix representing the coordinates

  • n_slices (int) -- Number of pixels to add on each side of the selected axis

  • axis (int) -- Axis along which to insert the slice(s)

Returns:

4x4 updated affine matrix

Return type:

np.ndarray

B1 Shim

shimmingtoolbox.shim.b1shim.b1shim(b1, mask=None, algorithm=1, target=None, q_matrix=None, sar_factor=1.5)

Computes static optimized shim weights that minimize the B1+ field coefficient of variation over the masked region.

Parameters:
  • b1 (numpy.ndarray) -- 4D array corresponding to the measured B1+ field. (x, y, n_slices, n_channels)

  • mask (numpy.ndarray) -- 3D array corresponding to the region where shimming will be performed. (x, y, n_slices)

  • algorithm (int) -- Number from 1 to 4 specifying which algorithm to use for B1+ optimization: 1 - Reduce the coefficient of variation of the B1+ field. Favors high B1+ efficiency. 2 - Magnitude least square (MLS) optimization targeting a specific B1+ value. Target value required. 3 - Maximizes the SAR efficiency (B1+/sqrt(SAR)). Q matrices required. 4 - Phase-only shimming.

  • target (float) -- Target B1+ value used by algorithm 2 in nT/V.

  • q_matrix (numpy.ndarray) -- Matrix used to constrain local SAR. If no matrix is provided, unconstrained optimization is performed, which might result in SAR excess at the scanner (n_channels, n_channels, n_vop).

  • sar_factor (float) -- Factor (=> 1) to which the maximum local SAR after shimming can exceed the phase-only shimming maximum local SAR. Values between 1 and 1.5 should work with Siemens scanners. High factors allow more shimming liberty but are more likely to result in SAR excess at the scanner.

Returns:

Optimized and normalized 1D vector of complex shimming weights of length n_channels.

Return type:

numpy.ndarray

shimmingtoolbox.shim.b1shim.combine_maps(b1_maps, weights)

Combines the B1 field distribution of several channels into one map representing the total B1 field magnitude.

Parameters:
  • b1_maps (numpy.ndarray) -- Complex B1 field for different channels (x, y, n_slices, n_channels).

  • weights (numpy.ndarray) -- 1D complex array of length n_channels.

Returns:

B1 field distribution obtained when applying the provided shim weights.

Return type:

numpy.ndarray

shimmingtoolbox.shim.b1shim.complex_to_vector(weights)

Separates the real and imaginary components of a complex vector into a twice as long vector.

Parameters:

weights (numpy.ndarray) -- 1D complex array of length n_channels.

Returns:

1D array of length 2*n_channels. First/second half: real/imaginary.

Return type:

numpy.ndarray

shimmingtoolbox.shim.b1shim.load_siemens_vop(fname_sar_file)

Reads in a Matlab file in which the VOP matrices are stored and returns them as a numpy array.

Parameters:

fname_sar_file -- Path to the 'SarDataUser.mat' file containing the scanner's VOPs. This file should be available at the scanner in 'C:/Medcom/MriProduct/PhysConfig'.

Returns:

VOP matrices (n_coils, n_coils, n_VOPs)

Return type:

numpy.ndarray

shimmingtoolbox.shim.b1shim.max_sar(weights, q_matrix)

Returns the maximum local SAR corresponding to a set of shim weight and a set of Q matrices.

Parameters:
  • weights (numpy.ndarray) -- 1D vector of complex shim weights. (length: n_channel)

  • q_matrix (numpy.ndarray) -- Q matrices used to compute the local energy deposition in the tissues.

  • (n_channels

  • n_channels

  • n_voxel)

Returns:

maximum local SAR.

Return type:

float

shimmingtoolbox.shim.b1shim.phase_only_shimming(b1_maps, init_phases=None)

Performs a phase-only RF-shimming to find a set of phases that homogenizes the B1+ field.

Parameters:
  • b1_maps (numpy.ndarray) -- 4D array corresponding to the measured B1 field. (x, y, n_slices, n_channels)

  • init_phases (numpy.ndarray) -- 1D array of initial phase values used for optimization.

Returns:

Optimized and normalized 1D vector of complex shimming weights of length n_channels.

Return type:

numpy.ndarray

shimmingtoolbox.shim.b1shim.vector_to_complex(weights)

Combines real and imaginary values contained in a vector into a half long complex vector.

Parameters:

weights (numpy.ndarray) -- 1D array of length 2*n_channels. First/second half: real/imaginary.

Returns:

1D complex array of length n_channels.

Return type:

numpy.ndarray

Optimizer

class shimmingtoolbox.optimizer.basic_optimizer.Optimizer(coils: List[Coil], unshimmed, affine)

Optimizer object that stores coil profiles and optimizes an unshimmed volume given a mask. Use optimize(args) to optimize a given mask. For basic optimizer, uses unbounded pseudo-inverse.

coils

List of Coil objects containing the coil profiles and related constraints

Type:

ListCoil

unshimmed

3d array of unshimmed volume

Type:

np.ndarray

unshimmed_affine

4x4 array containing the qform affine transformation for the unshimmed array

Type:

np.ndarray

merged_coils

4d array containing all coil profiles resampled onto the target unshimmed array concatenated on the 4th dimension. See self.merge_coils() for more details

Type:

np.ndarray

merged_bounds

list of bounds corresponding to each merged coils: merged_bounds[3] is the (min, max) bound for merged_coils[..., 3]

Type:

list

mask_coefficients

1d array of coefficients corresponding to the mask used for optimization

Type:

np.ndarray

__init__(coils: List[Coil], unshimmed, affine)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.optimizer_utils.OptimizerUtils(coils: List[Coil], unshimmed, affine, initial_guess_method, reg_factor=0)

Bases: Optimizer

Optimizer object that stores different useful functions and parameter for different optimization

initial_guess_method

String indicating how to find the first guess for the optimization

Type:

string

initial_coefs

Initial guess that will be used in the optimization

Type:

np.ndarray

reg_vector

Vector used to make the regularization in the optimization

Type:

np.ndarray

__init__(coils: List[Coil], unshimmed, affine, initial_guess_method, reg_factor=0)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.lsq_optimizer.LsqOptimizer(coils: List[Coil], unshimmed, affine, opt_criteria='mse', initial_guess_method='zeros', reg_factor=0, w_signal_loss=None, w_signal_loss_xy=None, epi_te=None)

Bases: OptimizerUtils

Optimizer object that stores coil profiles and optimizes an unshimmed volume given a mask. Use optimize(args) to optimize a given mask. The algorithm uses a least squares solver to find the best shim. It supports bounds for each channel as well as a bound for the absolute sum of the channels.

__init__(coils: List[Coil], unshimmed, affine, opt_criteria='mse', initial_guess_method='zeros', reg_factor=0, w_signal_loss=None, w_signal_loss_xy=None, epi_te=None)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_quadratic_term_grad(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE signal recovery objective function used in the least squares and BFGS optimization methods.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Wrapper for the optimization function. This function prepares the data and calls the optimizer. Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.lsq_optimizer.PmuLsqOptimizer(coils, unshimmed, affine, opt_criteria, pmu: PmuResp, mean_p=0, reg_factor=0)

Bases: LsqOptimizer

Optimizer for the realtime component (riro) for this optimization: field(i_vox) = riro(i_vox) * (acq_pressures - mean_p) + static(i_vox) Unshimmed must be in units: [unit_shim/unit_pressure], ex: [Hz/unit_pressure]

This optimizer bounds the riro results to the coil bounds by taking the range of pressure that can be reached by the PMU.

__init__(coils, unshimmed, affine, opt_criteria, pmu: PmuResp, mean_p=0, reg_factor=0)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

define_rt_bounds()

Define bounds taking into account that the formula scales the coefficient by the acquired pressure.

riro_offset = riro * (acq_pressure - mean_p)

Since the pressure can vary up and down, there are 2 maximum and 2 minimum values that the currents can have. We select the lower and greater of the 2 values respectively.

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_quadratic_term_grad(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE signal recovery objective function used in the least squares and BFGS optimization methods.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Wrapper for the optimization function. This function prepares the data and calls the optimizer. Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.quadprog_optimizer.PmuQuadProgOpt(coils, unshimmed, affine, pmu: PmuResp, reg_factor=0)

Bases: QuadProgOpt

Optimizer for the realtime component (riro) for this optimization: field(i_vox) = riro(i_vox) * (acq_pressures - mean_p) + static(i_vox) Unshimmed must be in units: [unit_shim/unit_pressure], ex: [Hz/unit_pressure]

This optimizer bounds the riro results to the coil bounds by taking the range of pressure that can be reached by the PMU.

__init__(coils, unshimmed, affine, pmu: PmuResp, reg_factor=0)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • pmu (PmuResp) -- PmuResp object containing the respiratory trace information.

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_cost_matrices(currents_0, unshimmed_vec, coil_mat, factor)

Returns the cost matrix and the cost vector to minimize 1/2 x.T @ cost_matrix @ x - cost_vector.T @ x

Parameters:
  • currents_0 (np.ndarray) -- Initial guess for the function

  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vector)

  • factor (float) -- Divide the result by 'factor'. This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D Cost matrix

  • np.ndarray: Cost vector

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_stability_factor(coef, unshimmed_vec, coil_mat, factor)

Objective function to find the stability factor for the quadratic optimization

Parameters:
  • coef (np.ndarray) -- 1D array of channel coefficients

  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- Devise the result by 'factor'. This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

Residuals for quad_prog optimization

Return type:

float

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.quadprog_optimizer.QuadProgOpt(coils: List[Coil], unshimmed, affine, reg_factor=0, initial_guess_method='zeros')

Bases: OptimizerUtils

Optimizer object that stores coil profiles and optimizes an unshimmed volume given a mask. Use optimize(args) to optimize a given mask. The algorithm uses a quadprog solver to find the best shim. It supports bounds for each channel as well as a bound for the absolute sum of the channels.

__init__(coils: List[Coil], unshimmed, affine, reg_factor=0, initial_guess_method='zeros')

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

  • initial_guess_method (str) -- method to find the initial guess

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_cost_matrices(currents_0, unshimmed_vec, coil_mat, factor)

Returns the cost matrix and the cost vector to minimize 1/2 x.T @ cost_matrix @ x - cost_vector.T @ x

Parameters:
  • currents_0 (np.ndarray) -- Initial guess for the function

  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vector)

  • factor (float) -- Divide the result by 'factor'. This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D Cost matrix

  • np.ndarray: Cost vector

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_stability_factor(coef, unshimmed_vec, coil_mat, factor)

Objective function to find the stability factor for the quadratic optimization

Parameters:
  • coef (np.ndarray) -- 1D array of channel coefficients

  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- Devise the result by 'factor'. This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

Residuals for quad_prog optimization

Return type:

float

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.bfgs_optimizer.BFGSOpt(coils: List[Coil], unshimmed, affine, opt_criteria='mse', initial_guess_method='zeros', reg_factor=0, w_signal_loss=None, w_signal_loss_xy=None, epi_te=None)

Bases: LsqOptimizer

Optimizer object that stores coil profiles and optimizes an unshimmed volume given a mask. Use optimize (args) to optimize a given mask. The algorithm uses a gradient based solver (L-BFGS-B) to find the best shim. It supports bounds for each shim channel.

__init__(coils: List[Coil], unshimmed, affine, opt_criteria='mse', initial_guess_method='zeros', reg_factor=0, w_signal_loss=None, w_signal_loss_xy=None, epi_te=None)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_quadratic_term_grad(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE signal recovery objective function used in the least squares and BFGS optimization methods.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Wrapper for the optimization function. This function prepares the data and calls the optimizer. Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

class shimmingtoolbox.optimizer.bfgs_optimizer.PmuBFGSOpt(coils, unshimmed, affine, opt_criteria, pmu: PmuResp, mean_p=0, reg_factor=0)

Bases: PmuLsqOptimizer

Optimizer object that stores coil profiles and optimizes an unshimmed volume given a mask. Use optimize (args) to optimize a given mask. The algorithm uses a gradient based solver (L-BFGS-B) to find the best shim. It supports bounds for each shim channel.

__init__(coils, unshimmed, affine, opt_criteria, pmu: PmuResp, mean_p=0, reg_factor=0)

Initializes coils according to input list of Coil

Parameters:
  • coils (ListCoil) -- List of Coil objects containing the coil profiles and related constraints

  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

  • reg_factor (float) -- Regularization factor for the current when optimizing. A higher coefficient will penalize higher current values while a lower factor will lower the effect of the regularization. A negative value will favour high currents (not preferred).

define_rt_bounds()

Define bounds taking into account that the formula scales the coefficient by the acquired pressure.

riro_offset = riro * (acq_pressure - mean_p)

Since the pressure can vary up and down, there are 2 maximum and 2 minimum values that the currents can have. We select the lower and greater of the 2 values respectively.

get_coil_mat_and_unshimmed(mask)

Returns the coil matrix, and the unshimmed vector used for the optimization

Parameters:

mask (np.ndarray) -- 3d array marking volume for optimization. Must be the same shape as unshimmed

Returns:

tuple containing:
  • np.ndarray: 2D flattened array (masked_values, n_channels) of masked coils

    (axis 0 must align with unshimmed_vec)

  • np.ndarray: 1D flattened array (masked_values,) of the masked unshimmed map

Return type:

(tuple)

get_initial_guess()

Calculates the initial guess according to the self.initial_guess_method

Returns:

1d array (n_channels) containing the initial guess for the optimization

Return type:

np.ndarray

get_quadratic_term(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE objective function used in the least squares, quadprog and BFGS optimization methods. For more details, see PR#451.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

get_quadratic_term_grad(unshimmed_vec, coil_mat, factor)

Returns all the quadratic terms used in the MSE signal recovery objective function used in the least squares and BFGS optimization methods.

Parameters:
  • unshimmed_vec (np.ndarray) -- 1D flattened array (point) of the masked unshimmed map

  • coil_mat (np.ndarray) -- 2D flattened array (point, channel) of masked coils (axis 0 must align with unshimmed_vec)

  • factor (float) -- This allows to scale the output for the minimize function to avoid positive directional linesearch

Returns:

tuple containing:
  • np.ndarray: 2D array using for the optimization

  • np.ndarray: 1D flattened array used for the optimization

  • float : Float used for the least squares optimizer

Return type:

(tuple)

merge_bounds()

Merge the coil profile bounds into a single array.

Returns:

list of bounds corresponding to each merged coils

Return type:

list

merge_coils(unshimmed, affine)

Uses the list of coil profiles to return a resampled concatenated list of coil profiles matching the unshimmed image. Bounds are also concatenated and returned.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the affine transformation for the unshimmed array

optimize(mask)

Wrapper for the optimization function. This function prepares the data and calls the optimizer. Optimize unshimmed volume by varying current to each channel

Parameters:

mask (np.ndarray) -- 3D integer mask used for the optimizer (only consider voxels with non-zero values).

Returns:

Coefficients corresponding to the coil profiles that minimize the objective function.

The shape of the array returned has shape corresponding to the total number of channels

Return type:

np.ndarray

set_merged_bounds(merged_bounds)

Changes the default bounds set in the coil profile

Parameters:

merged_bounds -- Concatenated coil profile bounds

set_unshimmed(unshimmed, affine)

Set the unshimmed array to a new array. Resamples coil profiles accordingly.

Parameters:
  • unshimmed (np.ndarray) -- 3d array of unshimmed volume

  • affine (np.ndarray) -- 4x4 array containing the qform affine transformation for the unshimmed array

Nifti file handling

class shimmingtoolbox.files.NiftiFile.NiftiFile(fname_nii: str, json: dict | None = None, path_output: str | None = None, json_needed: bool = True)

Bases: object

Parent class for handling NIfTI files.

__init__(fname_nii: str, json: dict | None = None, path_output: str | None = None, json_needed: bool = True) None
get_filename()

Get the filename without the extension from the NIfTI file path. Verifies that the file has a valid NIfTI extension (.nii or .nii.gz). If the file does not have a valid extension, raises a ValueError.

Raises:

ValueError -- If the file does not have a valid NIfTI extension.

Returns:

The filename without the extension.

Return type:

str

get_frequency()

Get the imaging frequency from the JSON metadata.

Returns:

Imaging frequency in Hz, or None if not available.

Return type:

float

get_isocenter()

Get the isocenter location in RAS coordinates from the json file.

The patient position is used to infer the table position in the patient coordinate system. When the table is at (0,0,0), the origin is at the isocenter. We can therefore infer the isocenter as -table_position when the table_position is in RAS coordinates.

Parameters:

json_data (dict) -- Dictionary containing the BIDS sidecar information

Returns:

Isocenter location in RAS coordinates

Return type:

numpy.ndarray

get_json(json_needed: bool = True) str | None

Find the corresponding JSON file for the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

json_needed (bool) -- Specifies whether the JSON file is required.

Returns:

The path to the JSON file if found, otherwise None.

Return type:

str

get_json_info(key: str, required: bool = True) any

Get a specific key from the JSON file.

Parameters:
  • key (str) -- The key to retrieve from the JSON file.

  • required (bool) -- If True, raises KeyError when key not found. If False, returns None.

Returns:

The value associated with the key in the JSON file, or None if not found and required=False.

Return type:

any

Raises:

KeyError -- If the key is not found and required=True.

get_manufacturers_model_name() str

Get the manufacturer model from the JSON metadata.

Returns:

Manufacturer model name with spaces replaced by underscores, or None if not available.

Return type:

str

get_path_nii()

Gets the path_nii of the Nifti file

Returns:

path_nii of the file (absolute path)

Return type:

str

get_scanner_shim_settings(orders: list[int] = [0, 1, 2, 3]) dict
Get the scanner's shim settings using the BIDS tag ShimSetting and ImagingFrequency and returns it in a

dictionary. 'orders' is used to check if the different orders are available in the metadata.

Parameters:
  • self (NiftiFile) -- The NiftiFile object containing the BIDS metadata.

  • orders (list[int]) -- List of orders to check for shim settings. Default is [0, 1, 2, 3].

Returns:

Dictionary containing the following keys: '0', '1' '2', '3'. The different orders are

lists unless the different values could not be populated.

Return type:

dict

load_json(json_needed: bool = True) dict | None

Load the JSON file corresponding to the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

None

Returns:

The content of the JSON file if found, otherwise None.

Return type:

dict

load_nii()

Load a NIfTI file and return the NIfTI object and its data. :param fname_nii: Path to the NIfTI file. :type fname_nii: str

Raises:

ValueError -- If the provided path does not exist or is not a valid NIfTI file.

Returns:

The loaded NIfTI image object. numpy.ndarray: The data contained in the NIfTI file.

Return type:

nib.Nifti1Image

save(fname: str | None = None) None

Save the NIfTI file to a specified path. If no output path is provided, it saves the file in the same directory with a default name.

Parameters:

fname (str, optional) -- The path where the NIfTI file should be saved. If None, it saves the file in the same directory with a default name.

Raises:

ValueError -- If the output path is not a valid directory.

Returns:

The function saves the NIfTI file to the specified path.

Return type:

None

set_nii(nii: Nifti1Image) None

Set the NIfTI image object and its data.

Parameters:

nii (nib.Nifti1Image) -- The NIfTI image object to set.

Raises:

TypeError -- If the provided nii is not a nib.Nifti1Image object.

shimmingtoolbox.files.NiftiFile.safe_getter(default_value=None)

Decorator that catches errors in getter functions and returns a default value.

class shimmingtoolbox.files.NiftiFieldMap.NiftiFieldMap(fname_nii: str, dilation_kernel_size, json: dict | None = None, path_output: str | None = None, is_realtime: bool = False)

Bases: NiftiFile

NiftiFieldMap is a subclass of NiftiFile that represents a NIfTI field map file.

It inherits all methods and properties from NiftiFile and can be used to handle field map files specifically.

__init__(fname_nii: str, dilation_kernel_size, json: dict | None = None, path_output: str | None = None, is_realtime: bool = False) None
extend_field_map(dilation_kernel_size: int) None

Extend the field map to match the dilation kernel size. This method checks the dimensions of the field map and extends it if necessary. :param dilation_kernel_size: The size of the dilation kernel to extend the field map to. :type dilation_kernel_size: int

Raises:

ValueError -- If the field map is not 2D or 3D.

Returns:

The extended NIfTI image if the field map was extended, otherwise the original NIfTI image.

Return type:

numpy.array

extend_fmap_to_kernel_size(dilation_kernel_size, ret_location=False)

Load the fmap and expand its dimensions to the kernel size

Parameters:
  • dilation_kernel_size -- Size of the kernel

  • ret_location (bool) -- If True, return the location of the original data in the new data

Returns:

Nibabel object of the loaded and extended fieldmap

Return type:

nib.Nifti1Image

get_filename()

Get the filename without the extension from the NIfTI file path. Verifies that the file has a valid NIfTI extension (.nii or .nii.gz). If the file does not have a valid extension, raises a ValueError.

Raises:

ValueError -- If the file does not have a valid NIfTI extension.

Returns:

The filename without the extension.

Return type:

str

get_frequency()

Get the imaging frequency from the JSON metadata.

Returns:

Imaging frequency in Hz, or None if not available.

Return type:

float

get_isocenter()

Get the isocenter location in RAS coordinates from the json file.

The patient position is used to infer the table position in the patient coordinate system. When the table is at (0,0,0), the origin is at the isocenter. We can therefore infer the isocenter as -table_position when the table_position is in RAS coordinates.

Parameters:

json_data (dict) -- Dictionary containing the BIDS sidecar information

Returns:

Isocenter location in RAS coordinates

Return type:

numpy.ndarray

get_json(json_needed: bool = True) str | None

Find the corresponding JSON file for the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

json_needed (bool) -- Specifies whether the JSON file is required.

Returns:

The path to the JSON file if found, otherwise None.

Return type:

str

get_json_info(key: str, required: bool = True) any

Get a specific key from the JSON file.

Parameters:
  • key (str) -- The key to retrieve from the JSON file.

  • required (bool) -- If True, raises KeyError when key not found. If False, returns None.

Returns:

The value associated with the key in the JSON file, or None if not found and required=False.

Return type:

any

Raises:

KeyError -- If the key is not found and required=True.

get_manufacturers_model_name() str

Get the manufacturer model from the JSON metadata.

Returns:

Manufacturer model name with spaces replaced by underscores, or None if not available.

Return type:

str

get_path_nii()

Gets the path_nii of the Nifti file

Returns:

path_nii of the file (absolute path)

Return type:

str

get_scanner_shim_settings(orders: list[int] = [0, 1, 2, 3]) dict
Get the scanner's shim settings using the BIDS tag ShimSetting and ImagingFrequency and returns it in a

dictionary. 'orders' is used to check if the different orders are available in the metadata.

Parameters:
  • self (NiftiFile) -- The NiftiFile object containing the BIDS metadata.

  • orders (list[int]) -- List of orders to check for shim settings. Default is [0, 1, 2, 3].

Returns:

Dictionary containing the following keys: '0', '1' '2', '3'. The different orders are

lists unless the different values could not be populated.

Return type:

dict

load_json(json_needed: bool = True) dict | None

Load the JSON file corresponding to the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

None

Returns:

The content of the JSON file if found, otherwise None.

Return type:

dict

load_nii()

Load a NIfTI file and return the NIfTI object and its data. :param fname_nii: Path to the NIfTI file. :type fname_nii: str

Raises:

ValueError -- If the provided path does not exist or is not a valid NIfTI file.

Returns:

The loaded NIfTI image object. numpy.ndarray: The data contained in the NIfTI file.

Return type:

nib.Nifti1Image

save(fname: str | None = None) None

Save the NIfTI file to a specified path. If no output path is provided, it saves the file in the same directory with a default name.

Parameters:

fname (str, optional) -- The path where the NIfTI file should be saved. If None, it saves the file in the same directory with a default name.

Raises:

ValueError -- If the output path is not a valid directory.

Returns:

The function saves the NIfTI file to the specified path.

Return type:

None

set_nii(nii: Nifti1Image) None

Set the NIfTI image and update the data, affine, and shape attributes.

Parameters:

nii (nib.Nifti1Image) -- The NIfTI image to set.

class shimmingtoolbox.files.NiftiMask.NiftiMask(fname_nii: str, json: dict | None = None, path_output: str | None = None)

Bases: NiftiFile

NiftiMask is a subclass of NiftiFile that represents a NIfTI mask file.

It inherits all methods and properties from NiftiFile and can be used to handle mask files specifically.

__init__(fname_nii: str, json: dict | None = None, path_output: str | None = None) None
get_filename()

Get the filename without the extension from the NIfTI file path. Verifies that the file has a valid NIfTI extension (.nii or .nii.gz). If the file does not have a valid extension, raises a ValueError.

Raises:

ValueError -- If the file does not have a valid NIfTI extension.

Returns:

The filename without the extension.

Return type:

str

get_frequency()

Get the imaging frequency from the JSON metadata.

Returns:

Imaging frequency in Hz, or None if not available.

Return type:

float

get_isocenter()

Get the isocenter location in RAS coordinates from the json file.

The patient position is used to infer the table position in the patient coordinate system. When the table is at (0,0,0), the origin is at the isocenter. We can therefore infer the isocenter as -table_position when the table_position is in RAS coordinates.

Parameters:

json_data (dict) -- Dictionary containing the BIDS sidecar information

Returns:

Isocenter location in RAS coordinates

Return type:

numpy.ndarray

get_json(json_needed: bool = True) str | None

Find the corresponding JSON file for the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

json_needed (bool) -- Specifies whether the JSON file is required.

Returns:

The path to the JSON file if found, otherwise None.

Return type:

str

get_json_info(key: str, required: bool = True) any

Get a specific key from the JSON file.

Parameters:
  • key (str) -- The key to retrieve from the JSON file.

  • required (bool) -- If True, raises KeyError when key not found. If False, returns None.

Returns:

The value associated with the key in the JSON file, or None if not found and required=False.

Return type:

any

Raises:

KeyError -- If the key is not found and required=True.

get_manufacturers_model_name() str

Get the manufacturer model from the JSON metadata.

Returns:

Manufacturer model name with spaces replaced by underscores, or None if not available.

Return type:

str

get_path_nii()

Gets the path_nii of the Nifti file

Returns:

path_nii of the file (absolute path)

Return type:

str

get_scanner_shim_settings(orders: list[int] = [0, 1, 2, 3]) dict
Get the scanner's shim settings using the BIDS tag ShimSetting and ImagingFrequency and returns it in a

dictionary. 'orders' is used to check if the different orders are available in the metadata.

Parameters:
  • self (NiftiFile) -- The NiftiFile object containing the BIDS metadata.

  • orders (list[int]) -- List of orders to check for shim settings. Default is [0, 1, 2, 3].

Returns:

Dictionary containing the following keys: '0', '1' '2', '3'. The different orders are

lists unless the different values could not be populated.

Return type:

dict

load_json(json_needed: bool = True) dict | None

Load the JSON file corresponding to the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

None

Returns:

The content of the JSON file if found, otherwise None.

Return type:

dict

load_mask(nif_target: NiftiTarget)

Load a mask and resample it on the target image.

Parameters:

nif_target (NiftiTarget) -- The target image to resample the mask on.

Raises:

ValueError -- If the mask is not in 3D or 4D.

load_nii()

Load a NIfTI file and return the NIfTI object and its data. :param fname_nii: Path to the NIfTI file. :type fname_nii: str

Raises:

ValueError -- If the provided path does not exist or is not a valid NIfTI file.

Returns:

The loaded NIfTI image object. numpy.ndarray: The data contained in the NIfTI file.

Return type:

nib.Nifti1Image

save(fname: str | None = None) None

Save the NIfTI file to a specified path. If no output path is provided, it saves the file in the same directory with a default name.

Parameters:

fname (str, optional) -- The path where the NIfTI file should be saved. If None, it saves the file in the same directory with a default name.

Raises:

ValueError -- If the output path is not a valid directory.

Returns:

The function saves the NIfTI file to the specified path.

Return type:

None

set_nii(nii: Nifti1Image, nif_target: NiftiTarget) None

Set the NIfTI image and load the mask on the target image.

Parameters:
  • nii (nib.Nifti1Image) -- The NIfTI image to set, which should be a mask.

  • nif_target (NiftiTarget) -- The target image to resample the mask on.

class shimmingtoolbox.files.NiftiTarget.NiftiTarget(fname_nii: str, json: dict | None = None, path_output: str | None = None)

Bases: NiftiFile

NiftiTarget is a subclass of NiftiFile that represents a NIfTI target image file.

It inherits all methods and properties from NiftiFile and can be used to handle target image files specifically.

__init__(fname_nii: str, json: dict | None = None, path_output: str | None = None) None
get_fat_sat_option() bool

Check if the NIfTI file has a Fat Saturation pulse.

Returns:

True if Fat Saturation pulse is detected, False otherwise.

Return type:

bool

get_filename()

Get the filename without the extension from the NIfTI file path. Verifies that the file has a valid NIfTI extension (.nii or .nii.gz). If the file does not have a valid extension, raises a ValueError.

Raises:

ValueError -- If the file does not have a valid NIfTI extension.

Returns:

The filename without the extension.

Return type:

str

get_frequency()

Get the imaging frequency from the JSON metadata.

Returns:

Imaging frequency in Hz, or None if not available.

Return type:

float

get_isocenter()

Get the isocenter location in RAS coordinates from the json file.

The patient position is used to infer the table position in the patient coordinate system. When the table is at (0,0,0), the origin is at the isocenter. We can therefore infer the isocenter as -table_position when the table_position is in RAS coordinates.

Parameters:

json_data (dict) -- Dictionary containing the BIDS sidecar information

Returns:

Isocenter location in RAS coordinates

Return type:

numpy.ndarray

get_json(json_needed: bool = True) str | None

Find the corresponding JSON file for the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

json_needed (bool) -- Specifies whether the JSON file is required.

Returns:

The path to the JSON file if found, otherwise None.

Return type:

str

get_json_info(key: str, required: bool = True) any

Get a specific key from the JSON file.

Parameters:
  • key (str) -- The key to retrieve from the JSON file.

  • required (bool) -- If True, raises KeyError when key not found. If False, returns None.

Returns:

The value associated with the key in the JSON file, or None if not found and required=False.

Return type:

any

Raises:

KeyError -- If the key is not found and required=True.

get_manufacturers_model_name() str

Get the manufacturer model from the JSON metadata.

Returns:

Manufacturer model name with spaces replaced by underscores, or None if not available.

Return type:

str

get_path_nii()

Gets the path_nii of the Nifti file

Returns:

path_nii of the file (absolute path)

Return type:

str

get_scanner_shim_settings(orders: list[int] = [0, 1, 2, 3]) dict
Get the scanner's shim settings using the BIDS tag ShimSetting and ImagingFrequency and returns it in a

dictionary. 'orders' is used to check if the different orders are available in the metadata.

Parameters:
  • self (NiftiFile) -- The NiftiFile object containing the BIDS metadata.

  • orders (list[int]) -- List of orders to check for shim settings. Default is [0, 1, 2, 3].

Returns:

Dictionary containing the following keys: '0', '1' '2', '3'. The different orders are

lists unless the different values could not be populated.

Return type:

dict

load_json(json_needed: bool = True) dict | None

Load the JSON file corresponding to the NIfTI file. The JSON file is expected to be in the same directory as the NIfTI file and have the same base name.

Parameters:

None

Returns:

The content of the JSON file if found, otherwise None.

Return type:

dict

load_nii()

Load a NIfTI file and return the NIfTI object and its data. :param fname_nii: Path to the NIfTI file. :type fname_nii: str

Raises:

ValueError -- If the provided path does not exist or is not a valid NIfTI file.

Returns:

The loaded NIfTI image object. numpy.ndarray: The data contained in the NIfTI file.

Return type:

nib.Nifti1Image

save(fname: str | None = None) None

Save the NIfTI file to a specified path. If no output path is provided, it saves the file in the same directory with a default name.

Parameters:

fname (str, optional) -- The path where the NIfTI file should be saved. If None, it saves the file in the same directory with a default name.

Raises:

ValueError -- If the output path is not a valid directory.

Returns:

The function saves the NIfTI file to the specified path.

Return type:

None

set_nii(nii: Nifti1Image) None

Set the NIfTI image and update the data, affine, and shape attributes.

Parameters:

nii (nib.Nifti1Image) -- The NIfTI image to set.

Image manipulation

shimmingtoolbox.image.concat_data(list_nii: List[Nifti1Image], axis=3, pixdim=None)

Concatenate data

Parameters:
  • list_nii -- list of Nifti1Image

  • axis -- axis: 0, 1, 2, 3, 4.

  • pixdim -- pixel resolution to join to image header

Returns:

concatenated image

Return type:

ListNii

Numerical model

Create numerical model data for multi-echo B0 field mapping data

This module is for numerically simulating multi-echo B0 field mapping data. It considers features like: background B0 field, flip angle, echo time, and noise.

Typical usage example:

from shimmingtoolbox.simulate import *

b0_sim = NumericalModel(model="shepp-logan")

# Generate a background B0
b0_field = 13 # (Hz)
b0_sim.generate_deltaB0("linear", [0.0, b0_field])

# Simulate the signal data
FA = 15 # (degrees)
TE = [0.003, 0.015] # (seconds)
SNR = 50
b0_sim.simulate_measurement(FA, TE, SNR)

# Save simulation as NIfTI file (JSON sidecar also exported with parameters)
b0_sim.save('Phase', 'b0_mapping_data.nii', format='nifti')
class shimmingtoolbox.simulate.numerical_model.NumericalModel(model=None, num_vox=128, n_slices=1)

Multi-echo B0 field mapping data numerical simulator.

Simulate multi-echo B0 field mapping data in the presence of a B0 field. Can simulate data under ideal conditions or with noise. Export simulations in a NIfTI or .mat file formats.

gamma

Gyromagnetic ratio in rad * Hz / Tesla.

Type:

float

field_strength

Static field strength in Tesla.

Type:

float

handedness

Orientation of the cross-product for the Larmor equation. The value of this attribute is MRI vendor-dependent.

measurement

Simulated measurement data array.

proton_density

Default assumed brain proton density in %.

T2_star

Default assumed brain T2* values in seconds at 3T.

generate_deltaB0(field_type, params)

Generates a background B0 field.

Defines the starting volume. Sets the background B0 field to zeros.

Parameters:
  • field_type (str) -- Type of field to be generated. Available implementations are: 'x', 'y', 'z'.

  • params (list) -- List of parameters defining the field for the selected field type. If field_type = 'x' or 'y' or 'z', then params are [m b] where m (Hz/pixel) is the slope and b is the floor field (Hz).

save(data_type, file_name, format=None, manufacturer='Simulated')

Exports simulated data to a file with a JSON sidecar.

Resets the measurement class attribute to zero before simulating. Simulates the signal for each echo-time provided. If defined, adds noise to the complex simulated signal measurements using an SNR value.

Parameters:
  • data_type -- Export data type. "Magnitude", "Phase", "Real", or "Imaginary".

  • file_name -- Filename of exported file, with or without file extension.

  • format -- File format for exported data. If no value given, will attempt to extract format from filename file extension, otherwise default to NIfTI.

  • manufacturer (str) -- Manufacturer to be written in the Json sidecar. Defaults to simulated.

simulate_measurement(FA, TE, SNR=None)

Simulates a multi-echo measurement for field mapping

Resets the measurement class attribute to zero before simulating. Simulates the signal for each echo-time provided. If defined, adds noise to the complex simulated signal measurements using an SNR value.

Parameters:
  • FA -- Flip angle in degrees.

  • TE -- Echo-times in seconds. Can be either a single value, list, or array.

  • SNR -- Signal-to-noise ratio used to define noise. If not set, no noise is added to the measurements.

Miscellaneous

Dicom to Nifti

shimmingtoolbox.dicom_to_nifti.dicom_to_nifti(path_dicom, path_nifti, subject_id='sub-01', fname_config_dcm2bids='/home/docs/checkouts/readthedocs.org/user_builds/shimming-toolbox-py/envs/632/lib/python3.10/site-packages/shimmingtoolbox/config/dcm2bids.json', remove_tmp=False)

Converts dicom files into nifti files by calling dcm2bids

Parameters:
  • path_dicom (str) -- Path to the input DICOM folder.

  • path_nifti (str) -- Path to the output NIfTI folder.

  • subject_id (str) -- Name of the imaged subject.

  • fname_config_dcm2bids (str) -- Path to the dcm2bids config JSON file.

  • remove_tmp (bool) -- If True, removes the tmp folder containing the NIfTI files created by dcm2niix.

shimmingtoolbox.dicom_to_nifti.fix_tfl_b1(nii_b1, json_data)

Un-shuffles and rescales the magnitude and phase of complex B1+ maps acquired with Siemens' standard B1+ mapping sequence. Also computes a corrected affine matrix allowing the B1+ maps to be visualized in FSLeyes. :param nii_b1: Array of dimension (x, y, n_slices, 2*n_channels) as created by dcm2niix. :type nii_b1: numpy.ndarray :param json_data: Contains the different fields present in the json file corresponding to the nifti file. :type json_data: dict

Returns:

NIfTI object containing the complex rescaled B1+ maps (x, y, n_slices, n_channels).

Return type:

nib.Nifti1Image

Load Nifti

shimmingtoolbox.load_nifti.get_acquisition_times(nif_data, when='slice-middle')

Return the acquisition timestamps from a json sidecar. This assumes BIDS convention.

Parameters:
  • nif_data (NiftiFieldMap) -- NiftiFieldMap object containing the nifti data and json sidecar.

  • when (str) -- When to get the acquisition time. Can be within {POSSIBLE_TIMINGS}.

Returns:

Acquisition timestamps in ms (n_volumes x n_slices).

Return type:

numpy.ndarray

shimmingtoolbox.load_nifti.load_nifti(path_data, modality='phase')

Load data from a directory containing NIFTI type file with nibabel.

Parameters:
  • path_data (str) -- Path to the directory containing the file(s) to load

  • modality (str) -- Modality to read nifti (can be phase or magnitude)

Returns:

List containing headers for every Nifti file dict: List containing all information in JSON format from every Nifti image numpy.ndarray: 5D array of all acquisition in time (x, y, z, echo, volume)

Return type:

nibabel.Nifti1Image.Header

Note

If 'path' is a folder containing niftis, directly output niftis. It 'path' is a folder containing acquisitions, ask the user for which acquisition to use.

shimmingtoolbox.load_nifti.read_nii(fname_nifti, auto_scale=True)

Reads a nifti file and returns the corresponding image and info. Also returns the associated json data. :param fname_nifti: direct path to the .nii or .nii.gz file that is going to be read :type fname_nifti: str :param auto_scale: Tells if scaling is done before return :type auto_scale: bool, optional

Returns:

Objet containing various data about the nifti file (returned by nibabel.load) json_data (dict): Contains the different fields present in the json file corresponding to the nifti file image (numpy.ndarray): For B0-maps, image contained in the nifti. Siemens phase images are rescaled between 0 and 2pi.

Return type:

info (Nifti1Image)

Download

shimmingtoolbox.download.download_data(urls)

Download the binaries from a URL and return the destination filename Retry downloading if either server or connection errors occur on a SSL connection

Parameters:

urls -- list of several urls (mirror servers) or single url (string)

shimmingtoolbox.download.install_data(url, dest_folder, keep=False)

Download a data bundle from a URL and install in the destination folder.

Parameters:
  • url -- URL or sequence thereof (if mirrors).

  • dest_folder -- destination directory for the data (to be created).

  • keep -- whether to keep existing data in the destination folder.

Returns:

NoneType

Note

The function tries to be smart about the data contents.

Examples:

If the archive only contains a README.md, and the destination folder is ${dst}, ${dst}/README.md will be created. Note: an archive not containing a single folder is commonly known as a "tarbomb" because it puts files anywhere in the current working directory.

If the archive contains a ${dir}/README.md, and the destination folder is ${dst}, ${dst}/README.md will be created. Note: typically the package will be called ${basename}-${revision}.zip and contain a root folder named ${basename}-${revision}/ under which all the other files will be located. The right thing to do in this case is to take the files from there and install them in ${dst}.

  • Uses download_data() to retrieve the data.

  • Uses unzip() to extract the bundle.

shimmingtoolbox.download.unzip(compressed, dest_folder)

Extract compressed file to the dest_folder. Can handle .zip, .tar.gz. If none of this extension is found, simply copy the file in dest_folder.

Parameters:
  • compressed -- the compressed .zip or .tar.gz file

  • dest_folder -- the destination dir that expanded files are written to

PMU

class shimmingtoolbox.pmu.PmuResp(fname_pmu: str, time_offset=0)

PMU object containing the pressure values of a Siemens .resp file

fname

Filename of the Siemens .resp file

Type:

str

data

Pressure values ranging from 0 to 4095

Type:

numpy.ndarray

start_time_mdh

Start time in milliseconds past midnight (mdh clock is expected to be the closest to the image header)

Type:

int

stop_time_mdh

Stop time in milliseconds past midnight (mdh clock is expected to be the closest to the image header)

Type:

int

start_time_mpcu

Start time in milliseconds past midnight

Type:

int

stop_time_mpcu

Stop time in milliseconds past midnight

Type:

int

adjust_start_time(time_offset: int)

Offset the start and end time of the PMU data :param time_offset: Time offset in ms to what is read in the .resp file :type time_offset: int

get_all_times()

Get all the timepoints from the respiratory file (in ms).

Returns:

Array containing the timepoints in ms of each data

Return type:

np.ndarray

get_data()

Retrieves the data of the PMU object

get_mean_trigger_span()

Returns the mean time between triggers in ms

Returns:

Mean time between triggers in ms

Return type:

float

get_pressure_rms(start_time=None, stop_time=None)

Returns the RMS value of the resp trace between start_time and stop_time

Parameters:
  • start_time (int) -- Start time in milliseconds past midnight

  • stop_time (int) -- Stop time in milliseconds past midnight

Returns:

RMS value of the resp trace between start_time and stop_time

Return type:

float

get_resp_trace(start_time=None, stop_time=None)

Returns the resp trace between start_time and stop_time

Parameters:
  • start_time (int) -- Start time in milliseconds past midnight

  • stop_time (int) -- Stop time in milliseconds past midnight

Returns:

Array with the resp trace between start_time and stop_time

Return type:

numpy.ndarray

get_start_and_stop_times()

Retrieves the start and stop time of the PMU object

get_times(start_time=None, stop_time=None)

Get the times in ms at which the respiration took place.

start_time (int): Start time in milliseconds past midnight stop_time (int): Stop time in milliseconds past midnight

Returns:

Array containing the timepoints in ms of each data

Return type:

np.ndarray

get_trigger_times(start_time=None, stop_time=None)

Returns the trigger times in ms of the resp trace. These triggers estimate the beginning of a new respiratory cycle

Returns:

Array with the trigger times in ms of the resp trace

Return type:

numpy.ndarray

interp_resp_trace(acquisition_times)

Interpolates data to the specified acquisition_times

Parameters:

acquisition_times (numpy.ndarray) -- Array of the times in milliseconds past midnight of the desired times to interpolate the resp_trace. Times must be within self.__start_time_mdh and self.__stop_time_mdh

Returns:

Array with interpolated times with the same shape as acquisition_times

Return type:

numpy.ndarray

mean(start_time=None, stop_time=None)

Returns the mean value of the resp trace between start_time and stop_time

Parameters:
  • start_time (int) -- Start time in milliseconds past midnight

  • stop_time (int) -- Stop time in milliseconds past midnight

Returns:

Mean value of the resp trace between start_time and stop_time

Return type:

float

read_resp(fname_pmu)

Read a Siemens Physiological Log file. Returns a tuple with the logging data as numpy integer array and times in the form of milliseconds past midnight.

Parameters:

fname_pmu -- Filename of the Siemens .resp file

Returns:

A dict containing the fname_pmu infos. Contains the following keys:

  • fname

  • data

  • data_triggers

  • start_time_mdh

  • stop_time_mdh

  • start_time_mpcu

  • stop_time_mpcu

Return type:

dict

set_data(data)

Set the data of the PMU object

Parameters:

data (numpy.ndarray) -- Pressure values ranging from 0 to 4095

set_start_and_stop_times(start_time_mdh, stop_time_mdh)

Set the start and stop time of the PMU object

Parameters:
  • start_time_mdh (int) -- Start time in milliseconds past midnight (mdh clock is expected to be the closest to the image header)

  • stop_time_mdh (int) -- Stop time in milliseconds past midnight (mdh clock is expected to be the closest to the image header)

Shimming toolbox utils

shimmingtoolbox.utils.add_suffix(fname, suffix)

Add suffix between end of file name and extension.

Parameters:
  • fname -- absolute or relative file name. Example: t2.nii

  • suffix -- suffix. Example: _mean

Return:

file name string with suffix. Example: t2_mean.nii

Examples:

  • add_suffix(t2.nii, _mean) -> t2_mean.nii

  • add_suffix(t2.nii.gz, a) -> t2a.nii.gz

shimmingtoolbox.utils.check_exe(name)

Ensure that a program exists and can be executed

shimmingtoolbox.utils.create_fname_from_path(path, file_default)

Given a path, make sure it is not a directory, if it is add the default filename, if not, return the path

Parameters:
  • path (str) -- filename or path to add the file_default to.

  • file_default (str) -- Name of the file + ext (example.nii.gz) to add to the path if the path is a directory.

Returns:

Absolute path of a file

Return type:

str

shimmingtoolbox.utils.create_output_dir(path_output, is_file=False, output_folder_name='output')

Given a path, create the directory if it doesn't exist.

Parameters:
  • path_output (str) -- Full path to either a folder or a file.

  • is_file (bool) -- True if the path_output is for a file, else False.

  • output_folder_name (str) -- Name of sub-folder.

shimmingtoolbox.utils.fill(data, invalid=None)

Replace the value of invalid 'data' cells (indicated by 'invalid') by the value of the nearest valid data cell

Parameters:
  • data (numpy.ndarray)) -- array of any dimension

  • invalid (numpy.ndarray) -- a binary array of same shape as 'data'. True cells set where data value should be replaced. If None (default), use: invalid = np.isnan(data)

Returns:

Return a filled array.

Return type:

numpy.ndarray

shimmingtoolbox.utils.iso_times_to_ms(iso_times)

Convert dicom acquisition times to ms

Parameters:

iso_times (numpy.ndarray) -- 1D array of time strings from dicoms. Suported formats: "HHMMSS.mmmmmm" or "HH:MM:SS.mmmmmm"

Returns:

1D array of times in milliseconds

Return type:

numpy.ndarray

shimmingtoolbox.utils.montage(X)

Concatenates images stored in a 3D array :param X: 3D array with the last dimension being the one in which the images are concatenated. :type X: numpy.ndarray

Returns:

2D array of concatenated images.

Return type:

numpy.ndarray

shimmingtoolbox.utils.run_subprocess(cmd)

Wrapper for subprocess.run().

Parameters:

cmd (list) -- list of arguments to be passed to the command line

shimmingtoolbox.utils.save_nii_json(nii, json_data, fname_output)

Save the nii to a nifti file and dict to a json file.

Parameters:
  • nii (nib.Nifti1Image) -- Nibabel object containing data save.

  • json_data (dict) -- Dictionary containing the json sidecar associated with the nibabel object.

  • fname_output (str) -- Output filename, supported types : '.nii', '.nii.gz'

shimmingtoolbox.utils.set_all_loggers(verbose, list_exclude=('matplotlib', 'indexed_gzip'))

Set all loggers in the root manager to the verbosity level. Exclude any logger with the name in list_exclude

Parameters:
  • verbose (str) -- Verbosity level: 'info', 'debug', 'warning', 'critical', 'error'

  • list_exclude -- List of string to exclude from logging

shimmingtoolbox.utils.splitext(fname)

Split a fname (folder/file + ext) into a folder/file and extension.

Note: for .nii.gz the extension is understandably .nii.gz, not .gz (os.path.splitext() would want to do the latter, hence the special case).

shimmingtoolbox.utils.st_progress_bar(*args, **kwargs)

Thin wrapper around tqdm.tqdm which checks SCT_PROGRESS_BAR muffling the progress bar if the user sets it to no, off, or false (case insensitive).

shimmingtoolbox.utils.timeit(func)

Decorator to time a function. Decorate a function: @timeit on top of the function definition. The elapsed time will output in debug mode