Source code for src.imagedata.apps.diffusion

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

import numpy as np
import pandas as pd


[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 >>> img = Series('data', 'b', opts={'accept_duplicate_tag': 'True'}) >>> g = get_g_vectors(img) >>> 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 _slice = 0 _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 = img.DicomHeaderDict[_slice][tag][2] 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, tag=0): """Get diffusion b value Extracting diffusion b value has been tested on MRI data from some major vendors. Args: img (imagedata.Series): Series object. tag (int): Optional tag in Series object. Default: 0. Returns: float: b value. Returns NaN when no b value is present in dataset. """ 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 # Extract pydicom dataset for given slice and tag _slice = 0 _ds = img.DicomHeaderDict[_slice][tag][2] for _method in [get_DICOM_b_value, get_Siemens_b_value, get_GEMS_b_value]: try: return _method(_ds) except KeyError: pass return np.nan