Source code for imagedata.apps.diffusion

"""Extract diffusion MRI parameters.
"""
# Copyright (c) 2013-2024 Erling Andersen, Haukeland University Hospital, Bergen, Norway

import numpy as np
import pandas as pd
from pydicom import Dataset
from typing import SupportsFloat
from ..series import Series

Number = type[SupportsFloat]


[docs] def get_g_vectors(img): """Get diffusion gradient vectors Extracting diffusion gradient vectors has been tested on MRI data from some major vendors. Args: img (imagedata.Series): Series object. Returns: pd.DataFrame: Diffusion gradient vectors, columns b, z, y, x. Raises: IndexError: when no gradient vector is present in dataset. Examples: >>> from imagedata import Series >>> from imagedata.apps.diffusion import get_g_vectors >>> im = Series('data', 'b', opts={'accept_duplicate_tag': 'True'}) >>> g = get_g_vectors(im) >>> print(g) b z y x 0 0 NaN NaN NaN 1 500 -0.706399 0.000000 0.707814 2 500 -0.706399 0.000000 -0.707814 3 500 -0.706399 -0.707814 0.000000 4 500 0.707814 -0.706399 0.000000 5 500 0.000000 -0.707107 0.707107 6 500 0.000000 -0.707107 -0.707107 7 1000 -0.706752 0.000000 0.707461 8 1000 -0.706752 0.000000 -0.707461 9 1000 -0.706753 -0.707460 0.000000 10 1000 0.707460 -0.706754 0.000000 11 1000 0.001414 -0.707106 0.707106 12 1000 0.001414 -0.707106 -0.707106 13 2500 -0.706824 0.000000 0.707390 """ def get_DICOM_g_vector(ds): # Attempt to address standard DICOM attributes return ds['DiffusionGradientOrientation'].value def get_Siemens_g_vector(ds): block = ds.private_block(0x0019, 'SIEMENS MR HEADER') return block[0x0e].value def get_GEMS_g_vector(ds): block = ds.private_block(0x0019, 'GEMS_ACQU_01') return [block[0xbb].value, block[0xbc].value, block[0xbd].value] _v = [] # Extract pydicom dataset for first slice and each tag _dwi_weighted = False for tag in range(img.shape[0]): _b = get_b_value(img, tag) _dwi_weighted = _dwi_weighted or not np.isnan(_b) _G = [np.nan, np.nan, np.nan] _ds: Dataset = img.dicomTemplate for _method in [get_DICOM_g_vector, get_Siemens_g_vector, get_GEMS_g_vector]: try: _G = _method(_ds) break except KeyError: pass _v.append({'b': _b, 'z': _G[2], 'y': _G[1], 'x': _G[0]}) if _dwi_weighted: return pd.DataFrame(_v) else: raise IndexError('No b values found in dataset')
[docs] def get_b_value(img: Series) -> float: """Get diffusion b value Extracting diffusion b value has been tested on MRI data from some major vendors. Args: img (imagedata.Series): Series object. Returns: float: b value. Returns NaN when no b value is present in dataset. """ # Extract pydicom dataset for given slice and tag _ds: Dataset = img.dicomTemplate return get_ds_b_value(_ds)
[docs] def get_ds_b_value(ds: Dataset) -> float: """Get diffusion b value from Dataset Setting diffusion b value has been tested on MRI data from some major vendors. Args: ds: Input dataset Returns: b value """ def get_DICOM_b_value(_ds): # Attempt to address standard DICOM attribute return _ds['DiffusionBValue'].value def get_Siemens_b_value(_ds): block = _ds.private_block(0x0019, 'SIEMENS MR HEADER') return block[0x0c].value def get_GEMS_b_value(_ds): block = _ds.private_block(0x0043, 'GEMS_PARM_01') return block[0x39].value for _method in [get_DICOM_b_value, get_Siemens_b_value, get_GEMS_b_value]: try: return float(_method(ds)) except (KeyError, IndexError): pass raise IndexError('Cannot get b value')
[docs] def set_ds_b_value(ds: Dataset, value: Number): """Set diffusion b value Setting diffusion b value has been tested on MRI data from some major vendors. Args: ds (pydicom.Dataset): Dataset value: b value """ def set_DICOM_b_value(_ds, _value): # Attempt to address standard DICOM attribute _ds.DiffusionBValue = _value def set_Siemens_b_value(_ds, _value): block = _ds.private_block(0x0019, 'SIEMENS MR HEADER') block[0x0c].value = _value def set_GEMS_b_value(_ds, _value): block = _ds.private_block(0x0043, 'GEMS_PARM_01') block[0x39].value = _value for _method in [set_DICOM_b_value, set_Siemens_b_value, set_GEMS_b_value]: try: _method(ds, value) return except (KeyError, IndexError): pass raise IndexError('Cannot set b value')