def smooth_img(imgs, fwhm, **kwargs):
    """Smooth images by applying a Gaussian filter.
    Apply a Gaussian filter along the three first dimensions of arr.
    In all cases, non-finite values in input image are replaced by zeros.

    This is copied and slightly modified from nilearn:
    https://github.com/nilearn/nilearn/blob/master/nilearn/image/image.py
    Added the **kwargs argument.

    Parameters
    ==========
    imgs: Niimg-like object or iterable of Niimg-like objects
        See http://nilearn.github.io/manipulating_images/manipulating_images.html#niimg.
        Image(s) to smooth.
    fwhm: scalar, numpy.ndarray, 'fast' or None
        Smoothing strength, as a Full-Width at Half Maximum, in millimeters.
        If a scalar is given, width is identical on all three directions.
        A numpy.ndarray must have 3 elements, giving the FWHM along each axis.
        If fwhm == 'fast', a fast smoothing will be performed with
        a filter [0.2, 1, 0.2] in each direction and a normalisation
        to preserve the scale.
        If fwhm is None, no filtering is performed (useful when just removal
        of non-finite values is needed)
    Returns
    =======
    filtered_img: nibabel.Nifti1Image or list of.
        Input image, filtered. If imgs is an iterable, then filtered_img is a
        list.
    """

    # Use hasattr() instead of isinstance to workaround a Python 2.6/2.7 bug
    # See http://bugs.python.org/issue7624
    if hasattr(imgs, "__iter__") \
       and not isinstance(imgs, string_types):
        single_img = False
    else:
        single_img = True
        imgs = [imgs]

    ret = []
    for img in imgs:
        img = check_niimg(img)
        affine = img.get_affine()
        filtered = _smooth_array(img.get_data(), affine, fwhm=fwhm,
                                 ensure_finite=True, copy=True, **kwargs)
        ret.append(new_img_like(img, filtered, affine, copy_header=True))

    if single_img:
        return ret[0]
    else:
        return ret

def smooth_img ( imgs , fwhm , ** kwargs ) : if hasattr ( imgs , "__iter__" ) and not isinstance ( imgs , string_types ) : single_img = False else : single_img = True imgs = [ imgs ] ret = [ ] for img in imgs : img = check_niimg ( img ) affine = img . get_affine ( ) filtered = _smooth_array ( img . get_data ( ) , affine , fwhm = fwhm , ensure_finite = True , copy = True , ** kwargs ) ret . append ( new_img_like ( img , filtered , affine , copy_header = True ) ) if single_img : return ret [ 0 ] else : return ret

Smooth images by applying a Gaussian filter . Apply a Gaussian filter along the three first dimensions of arr . In all cases non - finite values in input image are replaced by zeros .


def signed_session(self, session=None):
        """Create requests session with any required auth headers
        applied.

        :rtype: requests.Session.
        """

        if session:
            session = super(ClientCertAuthentication, self).signed_session(session)
        else:
            session = super(ClientCertAuthentication, self).signed_session()

        if self.cert is not None:
            session.cert = self.cert
        if self.ca_cert is not None:
            session.verify = self.ca_cert
        if self.no_verify:
            session.verify = False

        return session

def signed_session ( self , session = None ) : if session : session = super ( ClientCertAuthentication , self ) . signed_session ( session ) else : session = super ( ClientCertAuthentication , self ) . signed_session ( ) if self . cert is not None : session . cert = self . cert if self . ca_cert is not None : session . verify = self . ca_cert if self . no_verify : session . verify = False return session

Create requests session with any required auth headers applied .


def signed_session(self, session=None):
        """Create requests session with AAD auth headers

        :rtype: requests.Session.
        """

        from sfctl.config import (aad_metadata, aad_cache)

        if session:
            session = super(AdalAuthentication, self).signed_session(session)
        else:
            session = super(AdalAuthentication, self).signed_session()

        if self.no_verify:
            session.verify = False

        authority_uri, cluster_id, client_id = aad_metadata()
        existing_token, existing_cache = aad_cache()
        context = adal.AuthenticationContext(authority_uri,
                                             cache=existing_cache)
        new_token = context.acquire_token(cluster_id,
                                          existing_token['userId'], client_id)
        header = "{} {}".format("Bearer", new_token['accessToken'])
        session.headers['Authorization'] = header
        return session

def
signed_session
(
self
,
session
=
)
:
from
sfctl
.
config
import
(
aad_metadata
,
aad_cache
)
if
session
:
session
=
super
(
AdalAuthentication
,
self
)
.
signed_session
(
session
)
else
:
session
=
super
(
AdalAuthentication
,
self
)
.
signed_session
(
)
if
self
.
no_verify
:
session
.
verify
=
False
authority_uri
,
cluster_id
,
client_id
=
aad_metadata
(
)
existing_token
,
existing_cache
=
aad_cache
(
)
context
=
adal
.
AuthenticationContext
(
authority_uri
,
cache
=
existing_cache
)
new_token
=
context
.
acquire_token
(
cluster_id
,
existing_token
[
'userId'
]
,
client_id
)
header
=
"{} {}"
.
format
(
"Bearer"
,
new_token
[
'accessToken'
]
)
session
.
headers
[
'Authorization'
]
=
header
return
session


def voxspace_to_mmspace(img):
    """ Return a grid with coordinates in 3D physical space for `img`."""
    shape, affine = img.shape[:3], img.affine
    coords = np.array(np.meshgrid(*(range(i) for i in shape), indexing='ij'))
    coords = np.rollaxis(coords, 0, len(shape) + 1)
    mm_coords = nib.affines.apply_affine(affine, coords)

    return mm_coords

def voxspace_to_mmspace ( img ) : shape , affine = img . shape [ : 3 ] , img . affine coords = np . array ( np . meshgrid ( * ( range ( i ) for i in shape ) , indexing = 'ij' ) ) coords = np . rollaxis ( coords , 0 , len ( shape ) + 1 ) mm_coords = nib . affines . apply_affine ( affine , coords ) return mm_coords

Return a grid with coordinates in 3D physical space for img .


def get_3D_coordmap(img):
    '''
    Gets a 3D CoordinateMap from img.

    Parameters
    ----------
    img: nib.Nifti1Image or nipy Image

    Returns
    -------
    nipy.core.reference.coordinate_map.CoordinateMap
    '''
    if isinstance(img, nib.Nifti1Image):
        img = nifti2nipy(img)

    if img.ndim == 4:
        from nipy.core.reference.coordinate_map import drop_io_dim
        cm = drop_io_dim(img.coordmap, 3)
    else:
        cm = img.coordmap

    return cm

def get_3D_coordmap ( img ) : if isinstance ( img , nib . Nifti1Image ) : img = nifti2nipy ( img ) if img . ndim == 4 : from nipy . core . reference . coordinate_map import drop_io_dim cm = drop_io_dim ( img . coordmap , 3 ) else : cm = img . coordmap return cm


def get_img_info(image):
    """Return the header and affine matrix from a Nifti file.

    Parameters
    ----------
    image: img-like object or str
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

    Returns
    -------
    hdr, aff
    """
    try:
        img = check_img(image)
    except Exception as exc:
        raise Exception('Error reading file {0}.'.format(repr_imgs(image))) from exc
    else:
        return img.get_header(), img.get_affine()

def
get_img_info
(
image
)
:
try
:
img
=
check_img
(
image
)
except
Exception
as
exc
:
raise
Exception
(
'Error reading file {0}.'
.
format
(
repr_imgs
(
image
)
)
)
from
exc
else
:
return
img
.
get_header
(
)
,
img
.
get_affine
(
)

Return the header and affine matrix from a Nifti file .


def get_img_data(image, copy=True):
    """Return the voxel matrix of the Nifti file.
    If safe_mode will make a copy of the img before returning the data, so the input image is not modified.

    Parameters
    ----------
    image: img-like object or str
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

    copy: bool
    If safe_mode will make a copy of the img before returning the data, so the input image is not modified.

    Returns
    -------
    array_like
    """
    try:
        img = check_img(image)
        if copy:
            return get_data(img)
        else:
            return img.get_data()
    except Exception as exc:
        raise Exception('Error when reading file {0}.'.format(repr_imgs(image))) from exc

def
get_img_data
(
image
,
copy
=
True
)
:
try
:
img
=
check_img
(
image
)
if
copy
:
return
get_data
(
img
)
else
:
return
img
.
get_data
(
)
except
Exception
as
exc
:
raise
Exception
(
'Error when reading file {0}.'
.
format
(
repr_imgs
(
image
)
)
)
from
exc

Return the voxel matrix of the Nifti file . If safe_mode will make a copy of the img before returning the data so the input image is not modified .


def load_nipy_img(nii_file):
    """Read a Nifti file and return as nipy.Image

    Parameters
    ----------
    param nii_file: str
        Nifti file path

    Returns
    -------
    nipy.Image
    """
    # delayed import because could not install nipy on Python 3 on OSX
    import nipy

    if not os.path.exists(nii_file):
        raise FileNotFound(nii_file)

    try:
        return nipy.load_image(nii_file)
    except Exception as exc:
        raise Exception('Reading file {0}.'.format(repr_imgs(nii_file))) from exc

def
load_nipy_img
(
nii_file
)
:
import
nipy
if
not
os
.
path
.
exists
(
nii_file
)
:
raise
FileNotFound
(
nii_file
)
try
:
return
nipy
.
load_image
(
nii_file
)
except
Exception
as
exc
:
raise
Exception
(
'Reading file {0}.'
.
format
(
repr_imgs
(
nii_file
)
)
)
from
exc

Read a Nifti file and return as nipy . Image


def niftilist_to_array(img_filelist, outdtype=None):
    """
    From the list of absolute paths to nifti files, creates a Numpy array
    with the data.

    Parameters
    ----------
    img_filelist:  list of str
        List of absolute file paths to nifti files. All nifti files must have
        the same shape.

    outdtype: dtype
        Type of the elements of the array, if not set will obtain the dtype from
        the first nifti file.

    Returns
    -------
    outmat: Numpy array with shape N x prod(vol.shape)
            containing the N files as flat vectors.

    vol_shape: Tuple with shape of the volumes, for reshaping.

    """
    try:
        first_img = img_filelist[0]
        vol       = get_img_data(first_img)
    except IndexError as ie:
        raise Exception('Error getting the first item of img_filelis: {}'.format(repr_imgs(img_filelist[0]))) from ie

    if not outdtype:
        outdtype = vol.dtype

    outmat = np.zeros((len(img_filelist), np.prod(vol.shape)), dtype=outdtype)

    try:
        for i, img_file in enumerate(img_filelist):
            vol = get_img_data(img_file)
            outmat[i, :] = vol.flatten()
    except Exception as exc:
        raise Exception('Error on reading file {0}.'.format(img_file)) from exc

    return outmat, vol.shape

From the list of absolute paths to nifti files creates a Numpy array with the data .


def _crop_img_to(image, slices, copy=True):
    """Crops image to a smaller size

    Crop img to size indicated by slices and modify the affine accordingly.

    Parameters
    ----------
    image: img-like object or str
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

        Image to be cropped.

    slices: list of slices
        Defines the range of the crop.
        E.g. [slice(20, 200), slice(40, 150), slice(0, 100)]
        defines a 3D cube

        If slices has less entries than image has dimensions,
        the slices will be applied to the first len(slices) dimensions.

    copy: boolean
        Specifies whether cropped data is to be copied or not.
        Default: True

    Returns
    -------
    cropped_img: img-like object
        Cropped version of the input image
    """

    img    = check_img(image)
    data   = img.get_data()
    affine = img.get_affine()

    cropped_data = data[slices]
    if copy:
        cropped_data   = cropped_data.copy()

    linear_part        = affine[:3, :3]
    old_origin         = affine[:3,  3]
    new_origin_voxel   = np.array([s.start for s in slices])
    new_origin         = old_origin + linear_part.dot(new_origin_voxel)

    new_affine         = np.eye(4)
    new_affine[:3, :3] = linear_part
    new_affine[:3,  3] = new_origin

    new_img = nib.Nifti1Image(cropped_data, new_affine)

    return new_img

def _crop_img_to ( image , slices , copy = True ) : img = check_img ( image ) data = img . get_data ( ) affine = img . get_affine ( ) cropped_data = data [ slices ] if copy : cropped_data = cropped_data . copy ( ) linear_part = affine [ : 3 , : 3 ] old_origin = affine [ : 3 , 3 ] new_origin_voxel = np . array ( [ s . start for s in slices ] ) new_origin = old_origin + linear_part . dot ( new_origin_voxel ) new_affine = np . eye ( 4 ) new_affine [ : 3 , : 3 ] = linear_part new_affine [ : 3 , 3 ] = new_origin new_img = nib . Nifti1Image ( cropped_data , new_affine ) return new_img


def crop_img(image, rtol=1e-8, copy=True):
    """Crops img as much as possible

    Will crop img, removing as many zero entries as possible
    without touching non-zero entries. Will leave one voxel of
    zero padding around the obtained non-zero area in order to
    avoid sampling issues later on.

    Parameters
    ----------
    image: img-like object or str
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

        Image to be cropped.

    rtol: float
        relative tolerance (with respect to maximal absolute
        value of the image), under which values are considered
        negligeable and thus croppable.

    copy: boolean
        Specifies whether cropped data is copied or not.

    Returns
    -------
    cropped_img: image
        Cropped version of the input image
    """

    img              = check_img(image)
    data             = img.get_data()
    infinity_norm    = max(-data.min(), data.max())
    passes_threshold = np.logical_or(data < -rtol * infinity_norm,
                                     data >  rtol * infinity_norm)

    if data.ndim == 4:
        passes_threshold = np.any(passes_threshold, axis=-1)

    coords = np.array(np.where(passes_threshold))
    start  = coords.min(axis=1)
    end    = coords.max(axis=1) + 1

    # pad with one voxel to avoid resampling problems
    start = np.maximum(start - 1, 0)
    end   = np.minimum(end   + 1, data.shape[:3])

    slices = [slice(s, e) for s, e in zip(start, end)]

    return _crop_img_to(img, slices, copy=copy)

def crop_img ( image , rtol = 1e-8 , copy = True ) : img = check_img ( image ) data = img . get_data ( ) infinity_norm = max ( - data . min ( ) , data . max ( ) ) passes_threshold = np . logical_or ( data < - rtol * infinity_norm , data > rtol * infinity_norm ) if data . ndim == 4 : passes_threshold = np . any ( passes_threshold , axis = - 1 ) coords = np . array ( np . where ( passes_threshold ) ) start = coords . min ( axis = 1 ) end = coords . max ( axis = 1 ) + 1 start = np . maximum ( start - 1 , 0 ) end = np . minimum ( end + 1 , data . shape [ : 3 ] ) slices = [ slice ( s , e ) for s , e in zip ( start , end ) ] return _crop_img_to ( img , slices , copy = copy )


def new_img_like(ref_niimg, data, affine=None, copy_header=False):
    """Create a new image of the same class as the reference image

    Parameters
    ----------
    ref_niimg: image
        Reference image. The new image will be of the same type.

    data: numpy array
        Data to be stored in the image

    affine: 4x4 numpy array, optional
        Transformation matrix

    copy_header: boolean, optional
        Indicated if the header of the reference image should be used to
        create the new image

    Returns
    -------
    new_img: image
        A loaded image with the same type (and header) as the reference image.
    """
    # Hand-written loading code to avoid too much memory consumption
    if not (hasattr(ref_niimg, 'get_data')
              and hasattr(ref_niimg,'get_affine')):
        if isinstance(ref_niimg, _basestring):
            ref_niimg = nib.load(ref_niimg)
        elif operator.isSequenceType(ref_niimg):
            ref_niimg = nib.load(ref_niimg[0])
        else:
            raise TypeError(('The reference image should be a niimg, %r '
                            'was passed') % ref_niimg )

    if affine is None:
        affine = ref_niimg.get_affine()
    if data.dtype == bool:
        default_dtype = np.int8
        if (LooseVersion(nib.__version__) >= LooseVersion('1.2.0') and
                isinstance(ref_niimg, nib.freesurfer.mghformat.MGHImage)):
            default_dtype = np.uint8
        data = as_ndarray(data, dtype=default_dtype)
    header = None
    if copy_header:
        header = copy.copy(ref_niimg.get_header())
        header['scl_slope'] = 0.
        header['scl_inter'] = 0.
        header['glmax'] = 0.
        header['cal_max'] = np.max(data) if data.size > 0 else 0.
        header['cal_max'] = np.min(data) if data.size > 0 else 0.
    return ref_niimg.__class__(data, affine, header=header)


def get_h5file(file_path, mode='r'):
    """ Return the h5py.File given its file path.

    Parameters
    ----------
    file_path: string
        HDF5 file path

    mode: string
        r   Readonly, file must exist
        r+  Read/write, file must exist
        w   Create file, truncate if exists
        w-  Create file, fail if exists
        a   Read/write if exists, create otherwise (default)

    Returns
    -------
    h5file: h5py.File
    """
    if not op.exists(file_path):
        raise IOError('Could not find file {}.'.format(file_path))

    try:
        h5file = h5py.File(file_path, mode=mode)
    except:
        raise
    else:
        return h5file

def
get_h5file
(
file_path
,
mode
=
'r'
)
:
if
not
op
.
exists
(
file_path
)
:
raise
IOError
(
'Could not find file {}.'
.
format
(
file_path
)
)
try
:
h5file
=
h5py
.
File
(
file_path
,
mode
=
mode
)
except
:
raise
else
:
return
h5file

Return the h5py . File given its file path .


def extract_datasets(h5file, h5path='/'):
    """ Return all dataset contents from h5path group in h5file in an OrderedDict.

    Parameters
    ----------
    h5file: h5py.File
        HDF5 file object

    h5path: str
        HDF5 group path to read datasets from

    Returns
    -------
    datasets: OrderedDict
        Dict with variables contained in file_path/h5path
    """
    if isinstance(h5file, str):
        _h5file = h5py.File(h5file, mode='r')
    else:
        _h5file = h5file

    _datasets = get_datasets(_h5file, h5path)
    datasets  = OrderedDict()
    try:
        for ds in _datasets:
            datasets[ds.name.split('/')[-1]] = ds[:]
    except:
        raise RuntimeError('Error reading datasets in {}/{}.'.format(_h5file.filename, h5path))
    finally:
        if isinstance(h5file, str):
            _h5file.close()

    return datasets

def
extract_datasets
(
h5file
,
h5path
=
'/'
)
:
if
isinstance
(
h5file
,
str
)
:
_h5file
=
h5py
.
File
(
h5file
,
mode
=
'r'
)
else
:
_h5file
=
h5file
_datasets
=
get_datasets
(
_h5file
,
h5path
)
datasets
=
OrderedDict
(
)
try
:
for
ds
in
_datasets
:
datasets
[
ds
.
name
.
split
(
'/'
)
[
1
]
]
=
ds
[
:
]
except
:
raise
RuntimeError
(
'Error reading datasets in {}/{}.'
.
format
(
_h5file
.
filename
,
h5path
)
)
finally
:
if
isinstance
(
h5file
,
str
)
:
_h5file
.
close
(
)
return
datasets

Return all dataset contents from h5path group in h5file in an OrderedDict .


def _get_node_names(h5file, h5path='/', node_type=h5py.Dataset):
    """Return the node of type node_type names within h5path of h5file.

    Parameters
    ----------
    h5file: h5py.File
        HDF5 file object

    h5path: str
        HDF5 group path to get the group names from

    node_type: h5py object type
        HDF5 object type

    Returns
    -------
    names: list of str
        List of names
    """
    if isinstance(h5file, str):
        _h5file = get_h5file(h5file, mode='r')
    else:
        _h5file = h5file

    if not h5path.startswith('/'):
        h5path = '/' + h5path

    names = []
    try:
        h5group = _h5file.require_group(h5path)

        for node in _hdf5_walk(h5group, node_type=node_type):
            names.append(node.name)
    except:
        raise RuntimeError('Error getting node names from {}/{}.'.format(_h5file.filename, h5path))
    finally:
        if isinstance(h5file, str):
            _h5file.close()

    return names

def
_get_node_names
(
h5file
,
h5path
=
'/'
,
node_type
=
h5py
.
Dataset
)
:
if
isinstance
(
h5file
,
str
)
:
_h5file
=
get_h5file
(
h5file
,
mode
=
'r'
)
else
:
_h5file
=
h5file
if
not
h5path
.
startswith
(
'/'
)
:
h5path
=
'/'
+
h5path
names
=
[
]
try
:
h5group
=
_h5file
.
require_group
(
h5path
)
for
node
in
_hdf5_walk
(
h5group
,
node_type
=
node_type
)
:
names
.
append
(
node
.
name
)
except
:
raise
RuntimeError
(
'Error getting node names from {}/{}.'
.
format
(
_h5file
.
filename
,
h5path
)
)
finally
:
if
isinstance
(
h5file
,
str
)
:
_h5file
.
close
(
)
return
names

Return the node of type node_type names within h5path of h5file .


def mask(self, image):
        """ self.mask setter

        Parameters
        ----------
        image: str or img-like object.
            See NeuroImage constructor docstring.
        """
        if image is None:
            self._mask = None

        try:
            mask = load_mask(image)
        except Exception as exc:
            raise Exception('Could not load mask image {}.'.format(image)) from exc
        else:
            self._mask = mask

def
mask
(
self
,
image
)
:
if
image
is
:
self
.
_mask
=
try
:
mask
=
load_mask
(
image
)
except
Exception
as
exc
:
raise
Exception
(
'Could not load mask image {}.'
.
format
(
image
)
)
from
exc
else
:
self
.
_mask
=
mask


def _load_images_and_labels(self, images, labels=None):
        """Read the images, load them into self.items and set the labels."""
        if not isinstance(images, (list, tuple)):
            raise ValueError('Expected an iterable (list or tuple) of strings or img-like objects. '
                             'Got a {}.'.format(type(images)))

        if not len(images) > 0:
            raise ValueError('Expected an iterable (list or tuple) of strings or img-like objects '
                             'of size higher than 0. Got {} items.'.format(len(images)))

        if labels is not None and len(labels) != len(images):
            raise ValueError('Expected the same length for image set ({}) and '
                             'labels list ({}).'.format(len(images), len(labels)))

        first_file = images[0]
        if first_file:
            first_img = NeuroImage(first_file)
        else:
            raise('Error reading image {}.'.format(repr_imgs(first_file)))

        for idx, image in enumerate(images):
            try:
                img = NeuroImage(image)
                self.check_compatibility(img, first_img)
            except:
                log.exception('Error reading image {}.'.format(repr_imgs(image)))
                raise
            else:
                self.items.append(img)

        self.set_labels(labels)

Read the images load them into self . items and set the labels .


def to_file(self, output_file, smooth_fwhm=0, outdtype=None):
        """Save the Numpy array created from to_matrix function to the output_file.

        Will save into the file: outmat, mask_indices, vol_shape and self.others (put here whatever you want)

            data: Numpy array with shape N x prod(vol.shape)
                  containing the N files as flat vectors.

            mask_indices: matrix with indices of the voxels in the mask

            vol_shape: Tuple with shape of the volumes, for reshaping.

        Parameters
        ----------
        output_file: str
            Path to the output file. The extension of the file will be taken into account for the file format.
            Choices of extensions: '.pyshelf' or '.shelf' (Python shelve)
                                   '.mat' (Matlab archive),
                                   '.hdf5' or '.h5' (HDF5 file)

        smooth_fwhm: int
            Integer indicating the size of the FWHM Gaussian smoothing kernel
            to smooth the subject volumes before creating the data matrix

        outdtype: dtype
            Type of the elements of the array, if None will obtain the dtype from
            the first nifti file.
        """
        outmat, mask_indices, mask_shape = self.to_matrix(smooth_fwhm, outdtype)

        exporter = ExportData()
        content = {'data':         outmat,
                   'labels':       self.labels,
                   'mask_indices': mask_indices,
                   'mask_shape':   mask_shape, }

        if self.others:
            content.update(self.others)

        log.debug('Creating content in file {}.'.format(output_file))
        try:
            exporter.save_variables(output_file, content)
        except Exception as exc:
            raise Exception('Error saving variables to file {}.'.format(output_file)) from exc

def
to_file
(
self
,
output_file
,
smooth_fwhm
=
0
,
outdtype
=
)
:
outmat
,
mask_indices
,
mask_shape
=
self
.
to_matrix
(
smooth_fwhm
,
outdtype
)
exporter
=
ExportData
(
)
content
=
{
'data'
:
outmat
,
'labels'
:
self
.
labels
,
'mask_indices'
:
mask_indices
,
'mask_shape'
:
mask_shape
,
}
if
self
.
others
:
content
.
update
(
self
.
others
)
log
.
debug
(
'Creating content in file {}.'
.
format
(
output_file
)
)
try
:
exporter
.
save_variables
(
output_file
,
content
)
except
Exception
as
exc
:
raise
Exception
(
'Error saving variables to file {}.'
.
format
(
output_file
)
)
from
exc

Save the Numpy array created from to_matrix function to the output_file .


def die(msg, code=-1):
    """Writes msg to stderr and exits with return code"""
    sys.stderr.write(msg + "\n")
    sys.exit(code)

def die ( msg , code = - 1 ) : sys . stderr . write ( msg + "\n" ) sys . exit ( code )


def check_call(cmd_args):
    """
    Calls the command

    Parameters
    ----------
    cmd_args: list of str
        Command name to call and its arguments in a list.

    Returns
    -------
    Command output
    """
    p = subprocess.Popen(cmd_args, stdout=subprocess.PIPE)
    (output, err) = p.communicate()
    return output

def check_call ( cmd_args ) : p = subprocess . Popen ( cmd_args , stdout = subprocess . PIPE ) ( output , err ) = p . communicate ( ) return output


def call_command(cmd_name, args_strings):
    """Call CLI command with arguments and returns its return value.

    Parameters
    ----------
    cmd_name: str
        Command name or full path to the binary file.

    arg_strings: list of str
        Argument strings list.

    Returns
    -------
    return_value
        Command return value.
    """
    if not op.isabs(cmd_name):
        cmd_fullpath = which(cmd_name)
    else:
        cmd_fullpath = cmd_name

    try:
        cmd_line = [cmd_fullpath] + args_strings

        log.info('Calling: {}.'.format(cmd_line))
        retval = subprocess.check_call(cmd_line)
    except CalledProcessError as ce:
        log.exception("Error calling command {} with arguments: "
                      "{} \n With return code: {}".format(cmd_name, args_strings,
                                                          ce.returncode))
        raise
    else:
        return retval

Call CLI command with arguments and returns its return value .


def condor_call(cmd, shell=True):
    """
    Tries to submit cmd to HTCondor, if it does not succeed, it will
    be called with subprocess.call.

    Parameters
    ----------
    cmd: string
        Command to be submitted

    Returns
    -------
    """
    log.info(cmd)
    ret = condor_submit(cmd)
    if ret != 0:
        subprocess.call(cmd, shell=shell)

def condor_call ( cmd , shell = True ) : log . info ( cmd ) ret = condor_submit ( cmd ) if ret != 0 : subprocess . call ( cmd , shell = shell )

Tries to submit cmd to HTCondor if it does not succeed it will be called with subprocess . call .


def condor_submit(cmd):
    """
    Submits cmd to HTCondor queue

    Parameters
    ----------
    cmd: string
        Command to be submitted

    Returns
    -------
    int
        returncode value from calling the submission command.
    """
    is_running = subprocess.call('condor_status', shell=True) == 0
    if not is_running:
        raise CalledProcessError('HTCondor is not running.')

    sub_cmd = 'condor_qsub -shell n -b y -r y -N ' \
              + cmd.split()[0] + ' -m n'

    log.info('Calling: ' + sub_cmd)

    return subprocess.call(sub_cmd + ' ' + cmd, shell=True)

def
condor_submit
(
cmd
)
:
is_running
=
subprocess
.
call
(
'condor_status'
,
shell
=
True
)
==
0
if
not
is_running
:
raise
CalledProcessError
(
'HTCondor is not running.'
)
sub_cmd
=
'condor_qsub -shell n -b y -r y -N '
+
cmd
.
split
(
)
[
0
]
+
' -m n'
log
.
info
(
'Calling: '
+
sub_cmd
)
return
subprocess
.
call
(
sub_cmd
+
' '
+
cmd
,
shell
=
True
)


def clean(ctx):
    """Clean previously built package artifacts.
    """
    ctx.run(f'python setup.py clean')
    dist = ROOT.joinpath('dist')
    print(f'removing {dist}')
    shutil.rmtree(str(dist))

def
clean
(
ctx
)
:
ctx
.
run
(
f'python setup.py clean'
)
dist
=
ROOT
.
joinpath
(
'dist'
)
print
(
f'removing {dist}'
)
shutil
.
rmtree
(
str
(
dist
)
)

Clean previously built package artifacts .


def upload(ctx, repo):
    """Upload the package to an index server.

    This implies cleaning and re-building the package.

    :param repo: Required. Name of the index server to upload to, as specifies
        in your .pypirc configuration file.
    """
    artifacts = ' '.join(
        shlex.quote(str(n))
        for n in ROOT.joinpath('dist').glob('pipfile[-_]cli-*')
    )
    ctx.run(f'twine upload --repository="{repo}" {artifacts}')


def load_command_table(self, args): #pylint: disable=too-many-statements
        """Load all Service Fabric commands"""

        # Need an empty client for the select and upload operations
        with CommandSuperGroup(__name__, self,
                               'rcctl.custom_cluster#{}') as super_group:
            with super_group.group('cluster') as group:
                group.command('select', 'select')

        with CommandSuperGroup(__name__, self, 'rcctl.custom_reliablecollections#{}',
                               client_factory=client_create) as super_group:
            with super_group.group('dictionary') as group:
                group.command('query', 'query_reliabledictionary')
                group.command('execute', 'execute_reliabledictionary')
                group.command('schema', 'get_reliabledictionary_schema')
                group.command('list', 'get_reliabledictionary_list')
                group.command('type-schema', 'get_reliabledictionary_type_schema')

        with ArgumentsContext(self, 'dictionary') as ac:
            ac.argument('application_name', options_list=['--application-name', '-a'])
            ac.argument('service_name', options_list=['--service-name', '-s'])
            ac.argument('dictionary_name', options_list=['--dictionary-name', '-d'])
            ac.argument('output_file', options_list=['--output-file', '-out'])
            ac.argument('input_file', options_list=['--input-file', '-in'])
            ac.argument('query_string', options_list=['--query-string', '-q'])
            ac.argument('type_name', options_list=['--type-name', '-t'])

        return OrderedDict(self.command_table)

def load_command_table ( self , args ) : with CommandSuperGroup ( __name__ , self , 'rcctl.custom_cluster#{}' ) as super_group : with super_group . group ( 'cluster' ) as group : group . command ( 'select' , 'select' ) with CommandSuperGroup ( __name__ , self , 'rcctl.custom_reliablecollections#{}' , client_factory = client_create ) as super_group : with super_group . group ( 'dictionary' ) as group : group . command ( 'query' , 'query_reliabledictionary' ) group . command ( 'execute' , 'execute_reliabledictionary' ) group . command ( 'schema' , 'get_reliabledictionary_schema' ) group . command ( 'list' , 'get_reliabledictionary_list' ) group . command ( 'type-schema' , 'get_reliabledictionary_type_schema' ) with ArgumentsContext ( self , 'dictionary' ) as ac : ac . argument ( 'application_name' , options_list = [ '--application-name' , '-a' ] ) ac . argument ( 'service_name' , options_list = [ '--service-name' , '-s' ] ) ac . argument ( 'dictionary_name' , options_list = [ '--dictionary-name' , '-d' ] ) ac . argument ( 'output_file' , options_list = [ '--output-file' , '-out' ] ) ac . argument ( 'input_file' , options_list = [ '--input-file' , '-in' ] ) ac . argument ( 'query_string' , options_list = [ '--query-string' , '-q' ] ) ac . argument ( 'type_name' , options_list = [ '--type-name' , '-t' ] ) return OrderedDict ( self . command_table )


def open_volume_file(filepath):
    """Open a volumetric file using the tools following the file extension.

    Parameters
    ----------
    filepath: str
        Path to a volume file

    Returns
    -------
    volume_data: np.ndarray
        Volume data

    pixdim: 1xN np.ndarray
        Vector with the description of the voxels physical size (usually in mm) for each volume dimension.

    Raises
    ------
    IOError
        In case the file is not found.
    """
    # check if the file exists
    if not op.exists(filepath):
        raise IOError('Could not find file {}.'.format(filepath))

    # define helper functions
    def open_nifti_file(filepath):
        return NiftiImage(filepath)

    def open_mhd_file(filepath):
        return MedicalImage(filepath)
        vol_data, hdr_data = load_raw_data_with_mhd(filepath)
        # TODO: convert vol_data and hdr_data into MedicalImage
        return vol_data, hdr_data

    def open_mha_file(filepath):
        raise NotImplementedError('This function has not been implemented yet.')

    # generic loader function
    def _load_file(filepath, loader):
        return loader(filepath)

    # file_extension -> file loader function
    filext_loader = {
                    'nii': open_nifti_file,
                    'mhd': open_mhd_file,
                    'mha': open_mha_file,
                    }

    # get extension of the `filepath`
    ext = get_extension(filepath)

    # find the loader from `ext`
    loader = None
    for e in filext_loader:
        if ext in e:
            loader = filext_loader[e]

    if loader is None:
        raise ValueError('Could not find a loader for file {}.'.format(filepath))

    return _load_file(filepath, loader)

Open a volumetric file using the tools following the file extension .


def rename_file_group_to_serial_nums(file_lst):
    """Will rename all files in file_lst to a padded serial
    number plus its extension

    :param file_lst: list of path.py paths
    """
    file_lst.sort()
    c = 1
    for f in file_lst:
        dirname = get_abspath(f.dirname())
        fdest = f.joinpath(dirname, "{0:04d}".format(c) +
                           OUTPUT_DICOM_EXTENSION)
        log.info('Renaming {0} to {1}'.format(f, fdest))
        f.rename(fdest)
        c += 1

def
rename_file_group_to_serial_nums
(
file_lst
)
:
file_lst
.
sort
(
)
c
=
1
for
f
in
file_lst
:
dirname
=
get_abspath
(
f
.
dirname
(
)
)
fdest
=
f
.
joinpath
(
dirname
,
"{0:04d}"
.
format
(
c
)
+
OUTPUT_DICOM_EXTENSION
)
log
.
info
(
'Renaming {0} to {1}'
.
format
(
f
,
fdest
)
)
f
.
rename
(
fdest
)
c
+=
1


def _store_dicom_paths(self, folders):
        """Search for dicoms in folders and save file paths into
        self.dicom_paths set.

        :param folders: str or list of str
        """
        if isinstance(folders, str):
            folders = [folders]

        for folder in folders:

            if not os.path.exists(folder):
                raise FolderNotFound(folder)

            self.items.extend(list(find_all_dicom_files(folder)))

def _store_dicom_paths ( self , folders ) : if isinstance ( folders , str ) : folders = [ folders ] for folder in folders : if not os . path . exists ( folder ) : raise FolderNotFound ( folder ) self . items . extend ( list ( find_all_dicom_files ( folder ) ) )

Search for dicoms in folders and save file paths into self . dicom_paths set .


def from_set(self, fileset, check_if_dicoms=True):
        """Overwrites self.items with the given set of files.
        Will filter the fileset and keep only Dicom files.

        Parameters
        ----------
        fileset: iterable of str
        Paths to files

        check_if_dicoms: bool
        Whether to check if the items in fileset are dicom file paths
        """
        if check_if_dicoms:
            self.items = []
            for f in fileset:
                if is_dicom_file(f):
                    self.items.append(f)
        else:
            self.items = fileset

def from_set ( self , fileset , check_if_dicoms = True ) : if check_if_dicoms : self . items = [ ] for f in fileset : if is_dicom_file ( f ) : self . items . append ( f ) else : self . items = fileset

Overwrites self . items with the given set of files . Will filter the fileset and keep only Dicom files .


def update(self, dicomset):
        """Update this set with the union of itself and dicomset.

        Parameters
        ----------
        dicomset: DicomFileSet
        """
        if not isinstance(dicomset, DicomFileSet):
            raise ValueError('Given dicomset is not a DicomFileSet.')

        self.items = list(set(self.items).update(dicomset))

def
update
(
self
,
dicomset
)
:
if
not
isinstance
(
dicomset
,
DicomFileSet
)
:
raise
ValueError
(
'Given dicomset is not a DicomFileSet.'
)
self
.
items
=
list
(
set
(
self
.
items
)
.
update
(
dicomset
)
)

Update this set with the union of itself and dicomset .


def copy_files_to_other_folder(self, output_folder, rename_files=True,
                                   mkdir=True, verbose=False):
        """
        Copies all files within this set to the output_folder

        Parameters
        ----------
        output_folder: str
        Path of the destination folder of the files

        rename_files: bool
        Whether or not rename the files to a sequential format

        mkdir: bool
        Whether to make the folder if it does not exist

        verbose: bool
        Whether to print to stdout the files that are beind copied
        """
        import shutil

        if not os.path.exists(output_folder):
            os.mkdir(output_folder)

        if not rename_files:
            for dcmf in self.items:
                outf = os.path.join(output_folder, os.path.basename(dcmf))
                if verbose:
                    print('{} -> {}'.format(dcmf, outf))
                shutil.copyfile(dcmf, outf)
        else:
            n_pad = len(self.items)+2
            for idx, dcmf in enumerate(self.items):
                outf = '{number:0{width}d}.dcm'.format(width=n_pad, number=idx)
                outf = os.path.join(output_folder, outf)
                if verbose:
                    print('{} -> {}'.format(dcmf, outf))
                shutil.copyfile(dcmf, outf)

def
copy_files_to_other_folder
(
self
,
output_folder
,
rename_files
=
True
,
mkdir
=
True
,
verbose
=
False
)
:
import
shutil
if
not
os
.
path
.
exists
(
output_folder
)
:
os
.
mkdir
(
output_folder
)
if
not
rename_files
:
for
dcmf
in
self
.
items
:
outf
=
os
.
path
.
join
(
output_folder
,
os
.
path
.
basename
(
dcmf
)
)
if
verbose
:
print
(
'{} -> {}'
.
format
(
dcmf
,
outf
)
)
shutil
.
copyfile
(
dcmf
,
outf
)
else
:
n_pad
=
len
(
self
.
items
)
+
2
for
idx
,
dcmf
in
enumerate
(
self
.
items
)
:
outf
=
'{number:0{width}d}.dcm'
.
format
(
width
=
n_pad
,
number
=
idx
)
outf
=
os
.
path
.
join
(
output_folder
,
outf
)
if
verbose
:
print
(
'{} -> {}'
.
format
(
dcmf
,
outf
)
)
shutil
.
copyfile
(
dcmf
,
outf
)


def get_dcm_reader(store_metadata=True, header_fields=None):
        """
        Creates a lambda function to read DICOM files.
        If store_store_metadata is False, will only return the file path.
        Else if you give header_fields, will return only the set of of
        header_fields within a DicomFile object or the whole DICOM file if
        None.

        :return: function
        This function has only one parameter: file_path
        """
        if not store_metadata:
            return lambda fpath: fpath

        if header_fields is None:
            build_dcm = lambda fpath: DicomFile(fpath)
        else:
            dicom_header = namedtuple('DicomHeader', header_fields)
            build_dcm = lambda fpath: dicom_header._make(DicomFile(fpath).get_attributes(header_fields))

        return build_dcm

def get_dcm_reader ( store_metadata = True , header_fields = None ) : if not store_metadata : return lambda fpath : fpath if header_fields is None : build_dcm = lambda fpath : DicomFile ( fpath ) else : dicom_header = namedtuple ( 'DicomHeader' , header_fields ) build_dcm = lambda fpath : dicom_header . _make ( DicomFile ( fpath ) . get_attributes ( header_fields ) ) return build_dcm

Creates a lambda function to read DICOM files . If store_store_metadata is False will only return the file path . Else if you give header_fields will return only the set of of header_fields within a DicomFile object or the whole DICOM file if None .


def scrape_all_files(self):
        """
        Generator that yields one by one the return value for self.read_dcm
        for each file within this set
        """
        try:
            for dcmf in self.items:
                yield self.read_dcm(dcmf)
        except IOError as ioe:
            raise IOError('Error reading DICOM file: {}.'.format(dcmf)) from ioe

def
scrape_all_files
(
self
)
:
try
:
for
dcmf
in
self
.
items
:
yield
self
.
read_dcm
(
dcmf
)
except
IOError
as
ioe
:
raise
IOError
(
'Error reading DICOM file: {}.'
.
format
(
dcmf
)
)
from
ioe

Generator that yields one by one the return value for self . read_dcm for each file within this set


def get_unique_field_values(dcm_file_list, field_name):
    """Return a set of unique field values from a list of DICOM files

    Parameters
    ----------
    dcm_file_list: iterable of DICOM file paths

    field_name: str
     Name of the field from where to get each value

    Returns
    -------
    Set of field values
    """
    field_values = set()

    for dcm in dcm_file_list:
        field_values.add(str(DicomFile(dcm).get_attributes(field_name)))

    return field_values

def get_unique_field_values ( dcm_file_list , field_name ) : field_values = set ( ) for dcm in dcm_file_list : field_values . add ( str ( DicomFile ( dcm ) . get_attributes ( field_name ) ) ) return field_values


def find_all_dicom_files(root_path):
    """
    Returns a list of the dicom files within root_path

    Parameters
    ----------
    root_path: str
    Path to the directory to be recursively searched for DICOM files.

    Returns
    -------
    dicoms: set
    Set of DICOM absolute file paths
    """
    dicoms = set()

    try:
        for fpath in get_all_files(root_path):
            if is_dicom_file(fpath):
                dicoms.add(fpath)
    except IOError as ioe:
        raise IOError('Error reading file {0}.'.format(fpath)) from ioe

    return dicoms

def
find_all_dicom_files
(
root_path
)
:
dicoms
=
set
(
)
try
:
for
fpath
in
get_all_files
(
root_path
)
:
if
is_dicom_file
(
fpath
)
:
dicoms
.
add
(
fpath
)
except
IOError
as
ioe
:
raise
IOError
(
'Error reading file {0}.'
.
format
(
fpath
)
)
from
ioe
return
dicoms


def is_dicom_file(filepath):
    """
    Tries to read the file using dicom.read_file,
    if the file exists and dicom.read_file does not raise
    and Exception returns True. False otherwise.

    :param filepath: str
     Path to DICOM file

    :return: bool
    """
    if not os.path.exists(filepath):
        raise IOError('File {} not found.'.format(filepath))

    filename = os.path.basename(filepath)
    if filename == 'DICOMDIR':
        return False

    try:
        _ = dicom.read_file(filepath)
    except Exception as exc:
        log.debug('Checking if {0} was a DICOM, but returned '
                  'False.'.format(filepath))
        return False

    return True

Tries to read the file using dicom . read_file if the file exists and dicom . read_file does not raise and Exception returns True . False otherwise .


def group_dicom_files(dicom_paths, hdr_field='PatientID'):
    """Group in a dictionary all the DICOM files in dicom_paths
    separated by the given `hdr_field` tag value.

    Parameters
    ----------
    dicom_paths: str
        Iterable of DICOM file paths.

    hdr_field: str
        Name of the DICOM tag whose values will be used as key for the group.

    Returns
    -------
    dicom_groups: dict of dicom_paths
    """
    dicom_groups = defaultdict(list)
    try:
        for dcm in dicom_paths:
            hdr = dicom.read_file(dcm)
            group_key = getattr(hdr, hdr_field)
            dicom_groups[group_key].append(dcm)
    except KeyError as ke:
        raise KeyError('Error reading field {} from file {}.'.format(hdr_field, dcm)) from ke

    return dicom_groups

def
group_dicom_files
(
dicom_paths
,
hdr_field
=
'PatientID'
)
:
dicom_groups
=
defaultdict
(
list
)
try
:
for
dcm
in
dicom_paths
:
hdr
=
dicom
.
read_file
(
dcm
)
group_key
=
getattr
(
hdr
,
hdr_field
)
dicom_groups
[
group_key
]
.
append
(
dcm
)
except
KeyError
as
ke
:
raise
KeyError
(
'Error reading field {} from file {}.'
.
format
(
hdr_field
,
dcm
)
)
from
ke
return
dicom_groups

Group in a dictionary all the DICOM files in dicom_paths separated by the given hdr_field tag value .


def get_attributes(self, attributes, default=''):
        """Return the attributes values from this DicomFile

        Parameters
        ----------
        attributes: str or list of str
         DICOM field names

        default: str
         Default value if the attribute does not exist.

        Returns
        -------
        Value of the field or list of values.
        """
        if isinstance(attributes, str):
            attributes = [attributes]

        attrs = [getattr(self, attr, default) for attr in attributes]

        if len(attrs) == 1:
            return attrs[0]

        return tuple(attrs)

def get_attributes ( self , attributes , default = '' ) : if isinstance ( attributes , str ) : attributes = [ attributes ] attrs = [ getattr ( self , attr , default ) for attr in attributes ] if len ( attrs ) == 1 : return attrs [ 0 ] return tuple ( attrs )


def merge_images(images, axis='t'):
    """ Concatenate `images` in the direction determined in `axis`.

    Parameters
    ----------
    images: list of str or img-like object.
        See NeuroImage constructor docstring.

    axis: str
      't' : concatenate images in time
      'x' : concatenate images in the x direction
      'y' : concatenate images in the y direction
      'z' : concatenate images in the z direction

    Returns
    -------
    merged: img-like object
    """
    # check if images is not empty
    if not images:
        return None

    # the given axis name to axis idx
    axis_dim = {'x': 0,
                'y': 1,
                'z': 2,
                't': 3,
                }

    # check if the given axis name is valid
    if axis not in axis_dim:
        raise ValueError('Expected `axis` to be one of ({}), got {}.'.format(set(axis_dim.keys()), axis))

    # check if all images are compatible with each other
    img1 = images[0]
    for img in images:
        check_img_compatibility(img1, img)

    # read the data of all the given images
    # TODO: optimize memory consumption by merging one by one.
    image_data = []
    for img in images:
        image_data.append(check_img(img).get_data())

    # if the work_axis is bigger than the number of axis of the images,
    # create a new axis for the images
    work_axis = axis_dim[axis]
    ndim = image_data[0].ndim
    if ndim - 1 < work_axis:
        image_data = [np.expand_dims(img, axis=work_axis) for img in image_data]

    # concatenate and return
    return np.concatenate(image_data, axis=work_axis)

Concatenate images in the direction determined in axis .


def nifti_out(f):
    """ Picks a function whose first argument is an `img`, processes its
    data and returns a numpy array. This decorator wraps this numpy array
    into a nibabel.Nifti1Image."""
    @wraps(f)
    def wrapped(*args, **kwargs):
        r = f(*args, **kwargs)

        img = read_img(args[0])
        return nib.Nifti1Image(r, affine=img.get_affine(), header=img.header)

    return wrapped

def nifti_out ( f ) : @ wraps ( f ) def wrapped ( * args , ** kwargs ) : r = f ( * args , ** kwargs ) img = read_img ( args [ 0 ] ) return nib . Nifti1Image ( r , affine = img . get_affine ( ) , header = img . header ) return wrapped

Picks a function whose first argument is an img processes its data and returns a numpy array . This decorator wraps this numpy array into a nibabel . Nifti1Image .


def div_img(img1, div2):
    """ Pixelwise division or divide by a number """
    if is_img(div2):
        return img1.get_data()/div2.get_data()
    elif isinstance(div2, (float, int)):
        return img1.get_data()/div2
    else:
        raise NotImplementedError('Cannot divide {}({}) by '
                                  '{}({})'.format(type(img1),
                                                  img1,
                                                  type(div2),
                                                  div2))

def
div_img
(
img1
,
div2
)
:
if
is_img
(
div2
)
:
return
img1
.
get_data
(
)
/
div2
.
get_data
(
)
elif
isinstance
(
div2
,
(
float
,
int
)
)
:
return
img1
.
get_data
(
)
/
div2
else
:
raise
NotImplementedError
(
'Cannot divide {}({}) by '
'{}({})'
.
format
(
type
(
img1
)
,
img1
,
type
(
div2
)
,
div2
)
)


def apply_mask(img, mask):
    """Return the image with the given `mask` applied."""
    from .mask import apply_mask

    vol, _ = apply_mask(img, mask)
    return vector_to_volume(vol, read_img(mask).get_data().astype(bool))

def apply_mask ( img , mask ) : from . mask import apply_mask vol , _ = apply_mask ( img , mask ) return vector_to_volume ( vol , read_img ( mask ) . get_data ( ) . astype ( bool ) )

Return the image with the given mask applied .


def abs_img(img):
    """ Return an image with the binarised version of the data of `img`."""
    bool_img = np.abs(read_img(img).get_data())
    return bool_img.astype(int)

def abs_img ( img ) : bool_img = np . abs ( read_img ( img ) . get_data ( ) ) return bool_img . astype ( int )

Return an image with the binarised version of the data of img .


def icc_img_to_zscore(icc, center_image=False):
    """ Return a z-scored version of `icc`.
    This function is based on GIFT `icatb_convertImageToZScores` function.
    """
    vol = read_img(icc).get_data()

    v2 = vol[vol != 0]
    if center_image:
        v2 = detrend(v2, axis=0)

    vstd = np.linalg.norm(v2, ord=2) / np.sqrt(np.prod(v2.shape) - 1)

    eps = np.finfo(vstd.dtype).eps
    vol /= (eps + vstd)

    return vol

def icc_img_to_zscore ( icc , center_image = False ) : vol = read_img ( icc ) . get_data ( ) v2 = vol [ vol != 0 ] if center_image : v2 = detrend ( v2 , axis = 0 ) vstd = np . linalg . norm ( v2 , ord = 2 ) / np . sqrt ( np . prod ( v2 . shape ) - 1 ) eps = np . finfo ( vstd . dtype ) . eps vol /= ( eps + vstd ) return vol

Return a z - scored version of icc . This function is based on GIFT icatb_convertImageToZScores function .


def spatial_map(icc, thr, mode='+'):
    """ Return the thresholded z-scored `icc`. """
    return thr_img(icc_img_to_zscore(icc), thr=thr, mode=mode).get_data()

def spatial_map ( icc , thr , mode = '+' ) : return thr_img ( icc_img_to_zscore ( icc ) , thr = thr , mode = mode ) . get_data ( )


def write_meta_header(filename, meta_dict):
    """ Write the content of the `meta_dict` into `filename`.

    Parameters
    ----------
    filename: str
        Path to the output file

    meta_dict: dict
        Dictionary with the fields of the metadata .mhd file
    """
    header = ''
    # do not use tags = meta_dict.keys() because the order of tags matters
    for tag in MHD_TAGS:
        if tag in meta_dict.keys():
            header += '{} = {}\n'.format(tag, meta_dict[tag])

    with open(filename, 'w') as f:
        f.write(header)

def
write_meta_header
(
filename
,
meta_dict
)
:
header
=
''
for
tag
in
MHD_TAGS
:
if
tag
in
meta_dict
.
keys
(
)
:
header
+=
'{} = {}\n'
.
format
(
tag
,
meta_dict
[
tag
]
)
with
open
(
filename
,
'w'
)
as
f
:
f
.
write
(
header
)

Write the content of the meta_dict into filename .


def dump_raw_data(filename, data):
    """ Write the data into a raw format file. Big endian is always used.

    Parameters
    ----------
    filename: str
        Path to the output file

    data: numpy.ndarray
        n-dimensional image data array.
    """
    if data.ndim == 3:
        # Begin 3D fix
        data = data.reshape([data.shape[0], data.shape[1]*data.shape[2]])
        # End 3D fix

    a = array.array('f')
    for o in data:
        a.fromlist(list(o.flatten()))

    # if is_little_endian():
    #     a.byteswap()

    with open(filename, 'wb') as rawf:
        a.tofile(rawf)

def dump_raw_data ( filename , data ) : if data . ndim == 3 : data = data . reshape ( [ data . shape [ 0 ] , data . shape [ 1 ] * data . shape [ 2 ] ] ) a = array . array ( 'f' ) for o in data : a . fromlist ( list ( o . flatten ( ) ) ) with open ( filename , 'wb' ) as rawf : a . tofile ( rawf )

Write the data into a raw format file . Big endian is always used .


def write_mhd_file(filename, data, shape=None, meta_dict=None):
    """ Write the `data` and `meta_dict` in two files with names
    that use `filename` as a prefix.

    Parameters
    ----------
    filename: str
        Path to the output file.
        This is going to be used as a preffix.
        Two files will be created, one with a '.mhd' extension
        and another with '.raw'. If `filename` has any of these already
        they will be taken into account to build the filenames.

    data: numpy.ndarray
        n-dimensional image data array.

    shape: tuple
        Tuple describing the shape of `data`
        Default: data.shape

    meta_dict: dict
        Dictionary with the fields of the metadata .mhd file
        Default: {}

    Returns
    -------
    mhd_filename: str
        Path to the .mhd file

    raw_filename: str
        Path to the .raw file
    """
    # check its extension
    ext = get_extension(filename)
    fname = op.basename(filename)
    if ext != '.mhd' or ext != '.raw':
        mhd_filename = fname + '.mhd'
        raw_filename = fname + '.raw'
    elif ext == '.mhd':
        mhd_filename = fname
        raw_filename = remove_ext(fname) + '.raw'
    elif ext == '.raw':
        mhd_filename = remove_ext(fname) + '.mhd'
        raw_filename = fname
    else:
        raise ValueError('`filename` extension {} from {} is not recognised. '
                         'Expected .mhd or .raw.'.format(ext, filename))

    # default values
    if meta_dict is None:
        meta_dict = {}

    if shape is None:
        shape = data.shape

    # prepare the default header
    meta_dict['ObjectType']             = meta_dict.get('ObjectType',             'Image')
    meta_dict['BinaryData']             = meta_dict.get('BinaryData',             'True' )
    meta_dict['BinaryDataByteOrderMSB'] = meta_dict.get('BinaryDataByteOrderMSB', 'False')
    meta_dict['ElementType']            = meta_dict.get('ElementType',            NUMPY_TO_MHD_TYPE[data.dtype.type])
    meta_dict['NDims']                  = meta_dict.get('NDims',                  str(len(shape)))
    meta_dict['DimSize']                = meta_dict.get('DimSize',                ' '.join([str(i) for i in shape]))
    meta_dict['ElementDataFile']        = meta_dict.get('ElementDataFile',        raw_filename)

    # target files
    mhd_filename = op.join(op.dirname(filename), mhd_filename)
    raw_filename = op.join(op.dirname(filename), raw_filename)

    # write the header
    write_meta_header(mhd_filename, meta_dict)

    # write the data
    dump_raw_data(raw_filename, data)

    return mhd_filename, raw_filename

Write the data and meta_dict in two files with names that use filename as a prefix .


def copy_mhd_and_raw(src, dst):
    """Copy .mhd and .raw files to dst.

    If dst is a folder, won't change the file, but if dst is another filepath,
    will modify the ElementDataFile field in the .mhd to point to the
    new renamed .raw file.

    Parameters
    ----------
    src: str
        Path to the .mhd file to be copied

    dst: str
        Path to the destination of the .mhd and .raw files.
        If a new file name is given, the extension will be ignored.

    Returns
    -------
    dst: str
    """
    # check if src exists
    if not op.exists(src):
        raise IOError('Could not find file {}.'.format(src))

    # check its extension
    ext = get_extension(src)
    if ext != '.mhd':
        msg = 'The src file path must be a .mhd file. Given: {}.'.format(src)
        raise ValueError(msg)

    # get the raw file for this src mhd file
    meta_src = _read_meta_header(src)

    # get the source raw file
    src_raw = meta_src['ElementDataFile']
    if not op.isabs(src_raw):
        src_raw = op.join(op.dirname(src), src_raw)

    # check if dst is dir
    if op.isdir(dst):
        # copy the mhd and raw file to its destiny
        shutil.copyfile(src, dst)
        shutil.copyfile(src_raw, dst)
        return dst

    # build raw file dst file name
    dst_raw = op.join(op.dirname(dst), remove_ext(op.basename(dst))) + '.raw'

    # add extension to the dst path
    if get_extension(dst) != '.mhd':
        dst += '.mhd'

    # copy the mhd and raw file to its destiny
    log.debug('cp: {} -> {}'.format(src,     dst))
    log.debug('cp: {} -> {}'.format(src_raw, dst_raw))
    shutil.copyfile(src, dst)
    shutil.copyfile(src_raw, dst_raw)

    # check if src file name is different than dst file name
    # if not the same file name, change the content of the ElementDataFile field
    if op.basename(dst) != op.basename(src):
        log.debug('modify {}: ElementDataFile: {} -> {}'.format(dst, src_raw,
                                                                op.basename(dst_raw)))
        meta_dst = _read_meta_header(dst)
        meta_dst['ElementDataFile'] = op.basename(dst_raw)
        write_meta_header(dst, meta_dst)

    return dst


def sav_to_pandas_rpy2(input_file):
    """
    SPSS .sav files to Pandas DataFrame through Rpy2

    :param input_file: string

    :return:
    """
    import pandas.rpy.common as com

    w = com.robj.r('foreign::read.spss("%s", to.data.frame=TRUE)' % input_file)
    return com.convert_robj(w)

SPSS . sav files to Pandas DataFrame through Rpy2


def sav_to_pandas_savreader(input_file):
    """
    SPSS .sav files to Pandas DataFrame through savreader module

    :param input_file: string

    :return:
    """
    from savReaderWriter import SavReader
    lines = []
    with SavReader(input_file, returnHeader=True) as reader:
        header = next(reader)
        for line in reader:
            lines.append(line)

    return pd.DataFrame(data=lines, columns=header)

def sav_to_pandas_savreader ( input_file ) : from savReaderWriter import SavReader lines = [ ] with SavReader ( input_file , returnHeader = True ) as reader : header = next ( reader ) for line in reader : lines . append ( line ) return pd . DataFrame ( data = lines , columns = header )

SPSS . sav files to Pandas DataFrame through savreader module


def save_varlist(filename, varnames, varlist):
        """
        Valid extensions '.pyshelf', '.mat', '.hdf5' or '.h5'

        @param filename: string

        @param varnames: list of strings
        Names of the variables

        @param varlist: list of objects
        The objects to be saved
        """
        variables = {}
        for i, vn in enumerate(varnames):
            variables[vn] = varlist[i]

        ExportData.save_variables(filename, variables)

def save_varlist ( filename , varnames , varlist ) : variables = { } for i , vn in enumerate ( varnames ) : variables [ vn ] = varlist [ i ] ExportData . save_variables ( filename , variables )

Valid extensions . pyshelf . mat . hdf5 or . h5


def cli():
    """Create CLI environment"""
    return VersionedCLI(cli_name=SF_CLI_NAME,
                        config_dir=SF_CLI_CONFIG_DIR,
                        config_env_var_prefix=SF_CLI_ENV_VAR_PREFIX,
                        commands_loader_cls=SFCommandLoader,
                        help_cls=SFCommandHelp)

def cli ( ) : return VersionedCLI ( cli_name = SF_CLI_NAME , config_dir = SF_CLI_CONFIG_DIR , config_env_var_prefix = SF_CLI_ENV_VAR_PREFIX , commands_loader_cls = SFCommandLoader , help_cls = SFCommandHelp )


def drain_rois(img):
    """Find all the ROIs in img and returns a similar volume with the ROIs
    emptied, keeping only their border voxels.

    This is useful for DTI tractography.

    Parameters
    ----------
    img: img-like object or str
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

    Returns
    -------
    np.ndarray
        an array of same shape as img_data
    """
    img_data = get_img_data(img)

    out = np.zeros(img_data.shape, dtype=img_data.dtype)

    krn_dim = [3] * img_data.ndim
    kernel  = np.ones(krn_dim, dtype=int)

    vals = np.unique(img_data)
    vals = vals[vals != 0]

    for i in vals:
        roi  = img_data == i
        hits = scn.binary_hit_or_miss(roi, kernel)
        roi[hits] = 0
        out[roi > 0] = i

    return out

def drain_rois ( img ) : img_data = get_img_data ( img ) out = np . zeros ( img_data . shape , dtype = img_data . dtype ) krn_dim = [ 3 ] * img_data . ndim kernel = np . ones ( krn_dim , dtype = int ) vals = np . unique ( img_data ) vals = vals [ vals != 0 ] for i in vals : roi = img_data == i hits = scn . binary_hit_or_miss ( roi , kernel ) roi [ hits ] = 0 out [ roi > 0 ] = i return out

Find all the ROIs in img and returns a similar volume with the ROIs emptied keeping only their border voxels .


def largest_connected_component(volume):
    """Return the largest connected component of a 3D array.

    Parameters
    -----------
    volume: numpy.array
        3D boolean array.

    Returns
    --------
    volume: numpy.array
        3D boolean array with only one connected component.
    """
    # We use asarray to be able to work with masked arrays.
    volume = np.asarray(volume)
    labels, num_labels = scn.label(volume)
    if not num_labels:
        raise ValueError('No non-zero values: no connected components found.')

    if num_labels == 1:
        return volume.astype(np.bool)

    label_count = np.bincount(labels.ravel().astype(np.int))
    # discard the 0 label
    label_count[0] = 0
    return labels == label_count.argmax()

Return the largest connected component of a 3D array .


def large_clusters_mask(volume, min_cluster_size):
    """ Return as mask for `volume` that includes only areas where
    the connected components have a size bigger than `min_cluster_size`
    in number of voxels.

    Parameters
    -----------
    volume: numpy.array
        3D boolean array.

    min_cluster_size: int
        Minimum size in voxels that the connected component must have.

    Returns
    --------
    volume: numpy.array
        3D int array with a mask excluding small connected components.
    """
    labels, num_labels = scn.label(volume)

    labels_to_keep = set([i for i in range(num_labels)
                         if np.sum(labels == i) >= min_cluster_size])

    clusters_mask = np.zeros_like(volume, dtype=int)
    for l in range(num_labels):
        if l in labels_to_keep:
            clusters_mask[labels == l] = 1

    return clusters_mask

def large_clusters_mask ( volume , min_cluster_size ) : labels , num_labels = scn . label ( volume ) labels_to_keep = set ( [ i for i in range ( num_labels ) if np . sum ( labels == i ) >= min_cluster_size ] ) clusters_mask = np . zeros_like ( volume , dtype = int ) for l in range ( num_labels ) : if l in labels_to_keep : clusters_mask [ labels == l ] = 1 return clusters_mask

Return as mask for volume that includes only areas where the connected components have a size bigger than min_cluster_size in number of voxels .


def create_rois_mask(roislist, filelist):
    """Look for the files in filelist containing the names in roislist, these files will be opened, binarised
    and merged in one mask.

    Parameters
    ----------
    roislist: list of strings
        Names of the ROIs, which will have to be in the names of the files in filelist.

    filelist: list of strings
        List of paths to the volume files containing the ROIs.

    Returns
    -------
    numpy.ndarray
        Mask volume
    """
    roifiles = []

    for roi in roislist:
        try:
            roi_file = search_list(roi, filelist)[0]
        except Exception as exc:
            raise Exception('Error creating list of roi files. \n {}'.format(str(exc)))
        else:
            roifiles.append(roi_file)

    return binarise(roifiles)

Look for the files in filelist containing the names in roislist these files will be opened binarised and merged in one mask .


def get_unique_nonzeros(arr):
    """ Return a sorted list of the non-zero unique values of arr.

    Parameters
    ----------
    arr: numpy.ndarray
        The data array

    Returns
    -------
    list of items of arr.
    """
    rois = np.unique(arr)
    rois = rois[np.nonzero(rois)]
    rois.sort()

    return rois

def get_unique_nonzeros ( arr ) : rois = np . unique ( arr ) rois = rois [ np . nonzero ( rois ) ] rois . sort ( ) return rois

Return a sorted list of the non - zero unique values of arr .


def get_rois_centers_of_mass(vol):
    """Get the center of mass for each ROI in the given volume.

    Parameters
    ----------
    vol: numpy ndarray
        Volume with different values for each ROI.

    Returns
    -------
    OrderedDict
        Each entry in the dict has the ROI value as key and the center_of_mass coordinate as value.
    """
    from scipy.ndimage.measurements import center_of_mass

    roisvals = np.unique(vol)
    roisvals = roisvals[roisvals != 0]

    rois_centers = OrderedDict()
    for r in roisvals:
        rois_centers[r] = center_of_mass(vol, vol, r)

    return rois_centers

def get_rois_centers_of_mass ( vol ) : from scipy . ndimage . measurements import center_of_mass roisvals = np . unique ( vol ) roisvals = roisvals [ roisvals != 0 ] rois_centers = OrderedDict ( ) for r in roisvals : rois_centers [ r ] = center_of_mass ( vol , vol , r ) return rois_centers

Get the center of mass for each ROI in the given volume .


def _partition_data(datavol, roivol, roivalue, maskvol=None, zeroe=True):
    """ Extracts the values in `datavol` that are in the ROI with value `roivalue` in `roivol`.
    The ROI can be masked by `maskvol`.

    Parameters
    ----------
    datavol: numpy.ndarray
        4D timeseries volume or a 3D volume to be partitioned

    roivol: numpy.ndarray
        3D ROIs volume

    roivalue: int or float
        A value from roivol that represents the ROI to be used for extraction.

    maskvol: numpy.ndarray
        3D mask volume

    zeroe: bool
        If true will remove the null timeseries voxels.  Only applied to timeseries (4D) data.

    Returns
    -------
    values: np.array
        An array of the values in the indicated ROI.
        A 2D matrix if `datavol` is 4D or a 1D vector if `datavol` is 3D.
    """
    if maskvol is not None:
        # get all masked time series within this roi r
        indices = (roivol == roivalue) * (maskvol > 0)
    else:
        # get all time series within this roi r
        indices = roivol == roivalue

    if datavol.ndim == 4:
        ts = datavol[indices, :]
    else:
        ts = datavol[indices]

    # remove zeroed time series
    if zeroe:
        if datavol.ndim == 4:
            ts = ts[ts.sum(axis=1) != 0, :]

    return ts

def _partition_data ( datavol , roivol , roivalue , maskvol = None , zeroe = True ) : if maskvol is not None : indices = ( roivol == roivalue ) * ( maskvol > 0 ) else : indices = roivol == roivalue if datavol . ndim == 4 : ts = datavol [ indices , : ] else : ts = datavol [ indices ] if zeroe : if datavol . ndim == 4 : ts = ts [ ts . sum ( axis = 1 ) != 0 , : ] return ts

Extracts the values in datavol that are in the ROI with value roivalue in roivol . The ROI can be masked by maskvol .


def get_3D_from_4D(image, vol_idx=0):
    """Pick one 3D volume from a 4D nifti image file

    Parameters
    ----------
    image: img-like object or str
        Volume defining different ROIs.
        Can either be:
        - a file path to a Nifti image
        - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
        If niimg is a string, consider it as a path to Nifti image and
        call nibabel.load on it. If it is an object, check if get_data()
        and get_affine() methods are present, raise TypeError otherwise.

    vol_idx: int
        Index of the 3D volume to be extracted from the 4D volume.

    Returns
    -------
    vol, hdr, aff
        The data array, the image header and the affine transform matrix.
    """
    img      = check_img(image)
    hdr, aff = get_img_info(img)

    if len(img.shape) != 4:
        raise AttributeError('Volume in {} does not have 4 dimensions.'.format(repr_imgs(img)))

    if not 0 <= vol_idx < img.shape[3]:
        raise IndexError('IndexError: 4th dimension in volume {} has {} volumes, '
                         'not {}.'.format(repr_imgs(img), img.shape[3], vol_idx))

    img_data = img.get_data()
    new_vol  = img_data[:, :, :, vol_idx].copy()

    hdr.set_data_shape(hdr.get_data_shape()[:3])

    return new_vol, hdr, aff


def get_dataset(self, ds_name, mode='r'):
        """
        Returns a h5py dataset given its registered name.

        :param ds_name: string
        Name of the dataset to be returned.

        :return:
        """
        if ds_name in self._datasets:
            return self._datasets[ds_name]
        else:
            return self.create_empty_dataset(ds_name)

def get_dataset ( self , ds_name , mode = 'r' ) : if ds_name in self . _datasets : return self . _datasets [ ds_name ] else : return self . create_empty_dataset ( ds_name )

Returns a h5py dataset given its registered name .


def create_empty_dataset(self, ds_name, dtype=np.float32):
        """
        Creates a Dataset with unknown size.
        Resize it before using.

        :param ds_name: string

        :param dtype: dtype
        Datatype of the dataset

        :return: h5py DataSet
        """
        if ds_name in self._datasets:
            return self._datasets[ds_name]

        ds = self._group.create_dataset(ds_name, (1, 1), maxshape=None,
                                        dtype=dtype)
        self._datasets[ds_name] = ds

        return ds

def create_empty_dataset ( self , ds_name , dtype = np . float32 ) : if ds_name in self . _datasets : return self . _datasets [ ds_name ] ds = self . _group . create_dataset ( ds_name , ( 1 , 1 ) , maxshape = None , dtype = dtype ) self . _datasets [ ds_name ] = ds return ds

Creates a Dataset with unknown size . Resize it before using .


def create_dataset(self, ds_name, data, attrs=None, dtype=None):
        """
        Saves a Numpy array in a dataset in the HDF file, registers it as
        ds_name and returns the h5py dataset.

        :param ds_name: string
        Registration name of the dataset to be registered.

        :param data: Numpy ndarray

        :param dtype: dtype
        Datatype of the dataset

        :return: h5py dataset
        """
        if ds_name in self._datasets:
            ds = self._datasets[ds_name]
            if ds.dtype != data.dtype:
                warnings.warn('Dataset and data dtype are different!')

        else:
            if dtype is None:
                dtype = data.dtype

            ds = self._group.create_dataset(ds_name, data.shape,
                                            dtype=dtype)

            if attrs is not None:
                for key in attrs:
                    setattr(ds.attrs, key, attrs[key])

        ds.read_direct(data)
        self._datasets[ds_name] = ds

        return ds

def
create_dataset
(
self
,
ds_name
,
data
,
attrs
=
,
dtype
=
)
:
if
ds_name
in
self
.
_datasets
:
ds
=
self
.
_datasets
[
ds_name
]
if
ds
.
dtype
!=
data
.
dtype
:
warnings
.
warn
(
'Dataset and data dtype are different!'
)
else
:
if
dtype
is
:
dtype
=
data
.
dtype
ds
=
self
.
_group
.
create_dataset
(
ds_name
,
data
.
shape
,
dtype
=
dtype
)
if
attrs
is
not
:
for
key
in
attrs
:
setattr
(
ds
.
attrs
,
key
,
attrs
[
key
]
)
ds
.
read_direct
(
data
)
self
.
_datasets
[
ds_name
]
=
ds
return
ds

Saves a Numpy array in a dataset in the HDF file registers it as ds_name and returns the h5py dataset .


def save(self, ds_name, data, dtype=None):
        """
        See create_dataset.
        """
        return self.create_dataset(ds_name, data, dtype)

def save ( self , ds_name , data , dtype = None ) : return self . create_dataset ( ds_name , data , dtype )


def _fill_missing_values(df, range_values, fill_value=0, fill_method=None):
        """
        Will get the names of the index colums of df, obtain their ranges from
        range_values dict and return a reindexed version of df with the given
        range values.

        :param df: pandas DataFrame

        :param range_values: dict or array-like
        Must contain for each index column of df an entry with all the values
        within the range of the column.

        :param fill_value: scalar or 'nearest', default 0
        Value to use for missing values. Defaults to 0, but can be any
        "compatible" value, e.g., NaN.
        The 'nearest' mode will fill the missing value with the nearest value in
         the column.

        :param fill_method:  {'backfill', 'bfill', 'pad', 'ffill', None}, default None
        Method to use for filling holes in reindexed DataFrame
        'pad' / 'ffill': propagate last valid observation forward to next valid
        'backfill' / 'bfill': use NEXT valid observation to fill gap

        :return: pandas Dataframe and used column ranges
        reindexed DataFrame and dict with index column ranges
        """
        idx_colnames  = df.index.names

        idx_colranges = [range_values[x] for x in idx_colnames]

        fullindex = pd.Index([p for p in product(*idx_colranges)],
                             name=tuple(idx_colnames))

        fulldf = df.reindex(index=fullindex, fill_value=fill_value,
                            method=fill_method)

        fulldf.index.names = idx_colnames

        return fulldf, idx_colranges

def _fill_missing_values ( df , range_values , fill_value = 0 , fill_method = None ) : idx_colnames = df . index . names idx_colranges = [ range_values [ x ] for x in idx_colnames ] fullindex = pd . Index ( [ p for p in product ( * idx_colranges ) ] , name = tuple ( idx_colnames ) ) fulldf = df . reindex ( index = fullindex , fill_value = fill_value , method = fill_method ) fulldf . index . names = idx_colnames return fulldf , idx_colranges

Will get the names of the index colums of df obtain their ranges from range_values dict and return a reindexed version of df with the given range values .


def get(self, key):
        """
        Retrieve pandas object or group of Numpy ndarrays
        stored in file

        Parameters
        ----------
        key : object

        Returns
        -------
        obj : type of object stored in file
        """
        node = self.get_node(key)
        if node is None:
            raise KeyError('No object named %s in the file' % key)

        if hasattr(node, 'attrs'):
            if 'pandas_type' in node.attrs:
                return self._read_group(node)

        return self._read_array(node)

def
get
(
self
,
key
)
:
node
=
self
.
get_node
(
key
)
if
node
is
:
raise
KeyError
(
'No object named %s in the file'
%
key
)
if
hasattr
(
node
,
'attrs'
)
:
if
'pandas_type'
in
node
.
attrs
:
return
self
.
_read_group
(
node
)
return
self
.
_read_array
(
node
)


def put(self, key, value, attrs=None, format=None, append=False, **kwargs):
        """
        Store object in HDFStore

        Parameters
        ----------
        key : str

        value : {Series, DataFrame, Panel, Numpy ndarray}

        format : 'fixed(f)|table(t)', default is 'fixed'
            fixed(f) : Fixed format
                Fast writing/reading. Not-appendable, nor searchable

            table(t) : Table format
                Write as a PyTables Table structure which may perform worse but allow more flexible operations
                like searching/selecting subsets of the data

        append : boolean, default False
            This will force Table format, append the input data to the
            existing.

        encoding : default None, provide an encoding for strings
        """
        if not isinstance(value, np.ndarray):
            super(NumpyHDFStore, self).put(key, value, format, append, **kwargs)
        else:
            group = self.get_node(key)

            # remove the node if we are not appending
            if group is not None and not append:
                self._handle.removeNode(group, recursive=True)
                group = None

            if group is None:
                paths = key.split('/')

                # recursively create the groups
                path = '/'
                for p in paths:
                    if not len(p):
                        continue
                    new_path = path
                    if not path.endswith('/'):
                        new_path += '/'
                    new_path += p
                    group = self.get_node(new_path)
                    if group is None:
                        group = self._handle.createGroup(path, p)
                    path = new_path

            ds_name = kwargs.get('ds_name', self._array_dsname)

            ds = self._handle.createArray(group, ds_name, value)
            if attrs is not None:
                for key in attrs:
                    setattr(ds.attrs, key, attrs[key])

            self._handle.flush()

            return ds

def put ( self , key , value , attrs = None , format = None , append = False , ** kwargs ) : if not isinstance ( value , np . ndarray ) : super ( NumpyHDFStore , self ) . put ( key , value , format , append , ** kwargs ) else : group = self . get_node ( key ) if group is not None and not append : self . _handle . removeNode ( group , recursive = True ) group = None if group is None : paths = key . split ( '/' ) path = '/' for p in paths : if not len ( p ) : continue new_path = path if not path . endswith ( '/' ) : new_path += '/' new_path += p group = self . get_node ( new_path ) if group is None : group = self . _handle . createGroup ( path , p ) path = new_path ds_name = kwargs . get ( 'ds_name' , self . _array_dsname ) ds = self . _handle . createArray ( group , ds_name , value ) if attrs is not None : for key in attrs : setattr ( ds . attrs , key , attrs [ key ] ) self . _handle . flush ( ) return ds


def put_df_as_ndarray(self, key, df, range_values, loop_multiindex=False,
                          unstack=False, fill_value=0, fill_method=None):
        """Returns a PyTables HDF Array from df in the shape given by its index columns range values.

        :param key: string object

        :param df: pandas DataFrame

        :param range_values: dict or array-like
        Must contain for each index column of df an entry with all the values
        within the range of the column.

        :param loop_multiindex: bool
        Will loop through the first index in a multiindex dataframe, extract a
        dataframe only for one value, complete and fill the missing values and
        store in the HDF.
        If this is True, it will not use unstack.
        This is as fast as unstacking.

        :param unstack: bool
        Unstack means that this will use the first index name to
        unfold the DataFrame, and will create a group with as many datasets
        as valus has this first index.
        Use this if you think the filled dataframe won't fit in your RAM memory.
        If set to False, this will transform the dataframe in memory first
        and only then save it.

        :param fill_value: scalar or 'nearest', default 0
        Value to use for missing values. Defaults to 0, but can be any
        "compatible" value, e.g., NaN.
        The 'nearest' mode will fill the missing value with the nearest value in
         the column.

        :param fill_method:  {'backfill', 'bfill', 'pad', 'ffill', None}, default None
        Method to use for filling holes in reindexed DataFrame
        'pad' / 'ffill': propagate last valid observation forward to next valid
        'backfill' / 'bfill': use NEXT valid observation to fill gap

        :return: PyTables data node
        """
        idx_colnames = df.index.names
        #idx_colranges = [range_values[x] for x in idx_colnames]

        #dataset group name if not given
        if key is None:
            key = idx_colnames[0]

        if loop_multiindex:
            idx_values = df.index.get_level_values(0).unique()

            for idx in idx_values:
                vals, _ = self._fill_missing_values(df.xs((idx,), level=idx_colnames[0]),
                                                    range_values,
                                                    fill_value=fill_value,
                                                    fill_method=fill_method)

                ds_name = str(idx) + '_' + '_'.join(vals.columns)

                self._push_dfblock(key, vals, ds_name, range_values)

            return self._handle.get_node('/' + str(key))

        #separate the dataframe into blocks, only with the first index
        else:
            if unstack:
                df = df.unstack(idx_colnames[0])
                for idx in df:
                    vals, _ = self._fill_missing_values(df[idx], range_values,
                                                        fill_value=fill_value,
                                                        fill_method=fill_method)
                    vals = np.nan_to_num(vals)

                    ds_name = '_'.join([str(x) for x in vals.name])

                    self._push_dfblock(key, vals, ds_name, range_values)

                return self._handle.get_node('/' + str(key))

        #not separate the data
        vals, _ = self._fill_missing_values(df, range_values,
                                            fill_value=fill_value,
                                            fill_method=fill_method)

        ds_name = self._array_dsname

        return self._push_dfblock(key, vals, ds_name, range_values)

def put_df_as_ndarray ( self , key , df , range_values , loop_multiindex = False , unstack = False , fill_value = 0 , fill_method = None ) : idx_colnames = df . index . names if key is None : key = idx_colnames [ 0 ] if loop_multiindex : idx_values = df . index . get_level_values ( 0 ) . unique ( ) for idx in idx_values : vals , _ = self . _fill_missing_values ( df . xs ( ( idx , ) , level = idx_colnames [ 0 ] ) , range_values , fill_value = fill_value , fill_method = fill_method ) ds_name = str ( idx ) + '_' + '_' . join ( vals . columns ) self . _push_dfblock ( key , vals , ds_name , range_values ) return self . _handle . get_node ( '/' + str ( key ) ) else : if unstack : df = df . unstack ( idx_colnames [ 0 ] ) for idx in df : vals , _ = self . _fill_missing_values ( df [ idx ] , range_values , fill_value = fill_value , fill_method = fill_method ) vals = np . nan_to_num ( vals ) ds_name = '_' . join ( [ str ( x ) for x in vals . name ] ) self . _push_dfblock ( key , vals , ds_name , range_values ) return self . _handle . get_node ( '/' + str ( key ) ) vals , _ = self . _fill_missing_values ( df , range_values , fill_value = fill_value , fill_method = fill_method ) ds_name = self . _array_dsname return self . _push_dfblock ( key , vals , ds_name , range_values )

Returns a PyTables HDF Array from df in the shape given by its index columns range values .


def smooth_fwhm(self, fwhm):
        """ Set a smoothing Gaussian kernel given its FWHM in mm.  """
        if fwhm != self._smooth_fwhm:
            self._is_data_smooth = False
        self._smooth_fwhm = fwhm

def smooth_fwhm ( self , fwhm ) : if fwhm != self . _smooth_fwhm : self . _is_data_smooth = False self . _smooth_fwhm = fwhm

Set a smoothing Gaussian kernel given its FWHM in mm .


def apply_mask(self, mask_img):
        """First set_mask and the get_masked_data.

        Parameters
        ----------
        mask_img:  nifti-like image, NeuroImage or str
            3D mask array: True where a voxel should be used.
            Can either be:
            - a file path to a Nifti image
            - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
            If niimg is a string, consider it as a path to Nifti image and
            call nibabel.load on it. If it is an object, check if get_data()
            and get_affine() methods are present, raise TypeError otherwise.

        Returns
        -------
        The masked data deepcopied
        """
        self.set_mask(mask_img)
        return self.get_data(masked=True, smoothed=True, safe_copy=True)

def apply_mask ( self , mask_img ) : self . set_mask ( mask_img ) return self . get_data ( masked = True , smoothed = True , safe_copy = True )

First set_mask and the get_masked_data .


def set_mask(self, mask_img):
        """Sets a mask img to this. So every operation to self, this mask will be taken into account.

        Parameters
        ----------
        mask_img: nifti-like image, NeuroImage or str
            3D mask array: True where a voxel should be used.
            Can either be:
            - a file path to a Nifti image
            - any object with get_data() and get_affine() methods, e.g., nibabel.Nifti1Image.
            If niimg is a string, consider it as a path to Nifti image and
            call nibabel.load on it. If it is an object, check if get_data()
            and get_affine() methods are present, raise TypeError otherwise.

        Note
        ----
        self.img and mask_file must have the same shape.

        Raises
        ------
        FileNotFound, NiftiFilesNotCompatible
        """
        mask = load_mask(mask_img, allow_empty=True)
        check_img_compatibility(self.img, mask, only_check_3d=True) # this will raise an exception if something is wrong
        self.mask = mask

def set_mask ( self , mask_img ) : mask = load_mask ( mask_img , allow_empty = True ) check_img_compatibility ( self . img , mask , only_check_3d = True ) self . mask = mask

Sets a mask img to this . So every operation to self this mask will be taken into account .


def _mask_data(self, data):
        """Return the data masked with self.mask

        Parameters
        ----------
        data: np.ndarray

        Returns
        -------
        masked np.ndarray

        Raises
        ------
        ValueError if the data and mask dimensions are not compatible.
        Other exceptions related to numpy computations.
        """
        self._check_for_mask()

        msk_data = self.mask.get_data()
        if self.ndim == 3:
            return data[msk_data], np.where(msk_data)
        elif self.ndim == 4:
            return _apply_mask_to_4d_data(data, self.mask)
        else:
            raise ValueError('Cannot mask {} with {} dimensions using mask {}.'.format(self, self.ndim, self.mask))


def apply_smoothing(self, smooth_fwhm):
        """Set self._smooth_fwhm and then smooths the data.
        See boyle.nifti.smooth.smooth_imgs.

        Returns
        -------
        the smoothed data deepcopied.

        """
        if smooth_fwhm <= 0:
            return

        old_smooth_fwhm   = self._smooth_fwhm
        self._smooth_fwhm = smooth_fwhm
        try:
            data = self.get_data(smoothed=True, masked=True, safe_copy=True)
        except ValueError as ve:
            self._smooth_fwhm = old_smooth_fwhm
            raise
        else:
            self._smooth_fwhm = smooth_fwhm
            return data

def apply_smoothing ( self , smooth_fwhm ) : if smooth_fwhm <= 0 : return old_smooth_fwhm = self . _smooth_fwhm self . _smooth_fwhm = smooth_fwhm try : data = self . get_data ( smoothed = True , masked = True , safe_copy = True ) except ValueError as ve : self . _smooth_fwhm = old_smooth_fwhm raise else : self . _smooth_fwhm = smooth_fwhm return data

Set self . _smooth_fwhm and then smooths the data . See boyle . nifti . smooth . smooth_imgs .


def mask_and_flatten(self):
        """Return a vector of the masked data.

        Returns
        -------
        np.ndarray, tuple of indices (np.ndarray), tuple of the mask shape
        """
        self._check_for_mask()

        return self.get_data(smoothed=True, masked=True, safe_copy=False)[self.get_mask_indices()],\
               self.get_mask_indices(), self.mask.shape

def mask_and_flatten ( self ) : self . _check_for_mask ( ) return self . get_data ( smoothed = True , masked = True , safe_copy = False ) [ self . get_mask_indices ( ) ] , self . get_mask_indices ( ) , self . mask . shape


def to_file(self, outpath):
        """Save this object instance in outpath.

        Parameters
        ----------
        outpath: str
            Output file path
        """
        if not self.has_mask() and not self.is_smoothed():
            save_niigz(outpath, self.img)
        else:
            save_niigz(outpath, self.get_data(masked=True, smoothed=True),
                       self.get_header(), self.get_affine())

def to_file ( self , outpath ) : if not self . has_mask ( ) and not self . is_smoothed ( ) : save_niigz ( outpath , self . img ) else : save_niigz ( outpath , self . get_data ( masked = True , smoothed = True ) , self . get_header ( ) , self . get_affine ( ) )


def setup_logging(log_config_file=op.join(op.dirname(__file__), 'logger.yml'),
                  log_default_level=LOG_LEVEL,
                  env_key=MODULE_NAME.upper() + '_LOG_CFG'):
    """Setup logging configuration."""
    path = log_config_file
    value = os.getenv(env_key, None)
    if value:
        path = value

    if op.exists(path):
        log_cfg = yaml.load(read(path).format(MODULE_NAME))
        logging.config.dictConfig(log_cfg)
        #print('Started logging using config file {0}.'.format(path))
    else:
        logging.basicConfig(level=log_default_level)
        #print('Started default logging. Could not find config file '
        #      'in {0}.'.format(path))
    log = logging.getLogger(__name__)
    log.debug('Start logging.')

def
setup_logging
(
log_config_file
=
op
.
join
(
op
.
dirname
(
__file__
)
,
'logger.yml'
)
,
log_default_level
=
LOG_LEVEL
,
env_key
=
MODULE_NAME
.
upper
(
)
+
'_LOG_CFG'
)
:
path
=
log_config_file
value
=
os
.
getenv
(
env_key
,
)
if
value
:
path
=
value
if
op
.
exists
(
path
)
:
log_cfg
=
yaml
.
load
(
read
(
path
)
.
format
(
MODULE_NAME
)
)
logging
.
config
.
dictConfig
(
log_cfg
)
else
:
logging
.
basicConfig
(
level
=
log_default_level
)
log
=
logging
.
getLogger
(
__name__
)
log
.
debug
(
'Start logging.'
)


def get_3D_from_4D(filename, vol_idx=0):
    """Return a 3D volume from a 4D nifti image file

    Parameters
    ----------
    filename: str
        Path to the 4D .mhd file

    vol_idx: int
        Index of the 3D volume to be extracted from the 4D volume.

    Returns
    -------
    vol, hdr
        The data array and the new 3D image header.
    """
    def remove_4th_element_from_hdr_string(hdr, fieldname):
        if fieldname in hdr:
            hdr[fieldname] = ' '.join(hdr[fieldname].split()[:3])

    vol, hdr = load_raw_data_with_mhd(filename)

    if vol.ndim != 4:
        raise ValueError('Volume in {} does not have 4 dimensions.'.format(op.join(op.dirname(filename),
                                                                                hdr['ElementDataFile'])))

    if not 0 <= vol_idx < vol.shape[3]:
        raise IndexError('IndexError: 4th dimension in volume {} has {} volumes, not {}.'.format(filename,
                                                                                vol.shape[3], vol_idx))

    new_vol = vol[:, :, :, vol_idx].copy()

    hdr['NDims'] = 3
    remove_4th_element_from_hdr_string(hdr, 'ElementSpacing')
    remove_4th_element_from_hdr_string(hdr, 'DimSize')

    return new_vol, hdr


def _safe_cache(memory, func, **kwargs):
    """ A wrapper for mem.cache that flushes the cache if the version
        number of nibabel has changed.
    """
    cachedir = memory.cachedir

    if cachedir is None or cachedir in __CACHE_CHECKED:
        return memory.cache(func, **kwargs)

    version_file = os.path.join(cachedir, 'module_versions.json')

    versions = dict()
    if os.path.exists(version_file):
        with open(version_file, 'r') as _version_file:
            versions = json.load(_version_file)

    modules = (nibabel, )
    # Keep only the major + minor version numbers
    my_versions = dict((m.__name__, LooseVersion(m.__version__).version[:2])
                       for m in modules)
    commons = set(versions.keys()).intersection(set(my_versions.keys()))
    collisions = [m for m in commons if versions[m] != my_versions[m]]

    # Flush cache if version collision
    if len(collisions) > 0:
        if nilearn.CHECK_CACHE_VERSION:
            warnings.warn("Incompatible cache in %s: "
                          "different version of nibabel. Deleting "
                          "the cache. Put nilearn.CHECK_CACHE_VERSION "
                          "to false to avoid this behavior."
                          % cachedir)
            try:
                tmp_dir = (os.path.split(cachedir)[:-1]
                           + ('old_%i' % os.getpid(), ))
                tmp_dir = os.path.join(*tmp_dir)
                # We use rename + unlink to be more robust to race
                # conditions
                os.rename(cachedir, tmp_dir)
                shutil.rmtree(tmp_dir)
            except OSError:
                # Another process could have removed this dir
                pass

            try:
                os.makedirs(cachedir)
            except OSError:
                # File exists?
                pass
        else:
            warnings.warn("Incompatible cache in %s: "
                          "old version of nibabel." % cachedir)

    # Write json files if configuration is different
    if versions != my_versions:
        with open(version_file, 'w') as _version_file:
            json.dump(my_versions, _version_file)

    __CACHE_CHECKED[cachedir] = True

    return memory.cache(func, **kwargs)

A wrapper for mem . cache that flushes the cache if the version number of nibabel has changed .


def spatialimg_to_hdfgroup(h5group, spatial_img):
    """Saves a Nifti1Image into an HDF5 group.

    Parameters
    ----------
    h5group: h5py Group
        Output HDF5 file path

    spatial_img: nibabel SpatialImage
        Image to be saved

    h5path: str
        HDF5 group path where the image data will be saved.
        Datasets will be created inside the given group path:
        'data', 'extra', 'affine', the header information will
        be set as attributes of the 'data' dataset.

    """
    try:
        h5group['data']   = spatial_img.get_data()
        h5group['affine'] = spatial_img.get_affine()

        if hasattr(h5group, 'get_extra'):
            h5group['extra'] = spatial_img.get_extra()

        hdr = spatial_img.get_header()
        for k in list(hdr.keys()):
            h5group['data'].attrs[k] = hdr[k]

    except ValueError as ve:
        raise Exception('Error creating group ' + h5group.name) from ve

def
spatialimg_to_hdfgroup
(
h5group
,
spatial_img
)
:
try
:
h5group
[
'data'
]
=
spatial_img
.
get_data
(
)
h5group
[
'affine'
]
=
spatial_img
.
get_affine
(
)
if
hasattr
(
h5group
,
'get_extra'
)
:
h5group
[
'extra'
]
=
spatial_img
.
get_extra
(
)
hdr
=
spatial_img
.
get_header
(
)
for
k
in
list
(
hdr
.
keys
(
)
)
:
h5group
[
'data'
]
.
attrs
[
k
]
=
hdr
[
k
]
except
ValueError
as
ve
:
raise
Exception
(
'Error creating group '
+
h5group
.
name
)
from
ve

Saves a Nifti1Image into an HDF5 group .