Exemple #1
0
import gzip
from io import StringIO
import itertools
from pkg_resources import resource_filename
from nibabel.volumeutils import Recoder
import numpy as np
import pandas as pd
from abagen import io, utils
from abagen.datasets import _fetch_alleninf_coords

# AHBA structure IDs corresponding to different brain parts
ONTOLOGY = Recoder(
    (('4008', 'cerebral cortex', 'cortex'),
     ('4275', 'cerebral nuclei', 'subcortex'),
     ('4391', 'diencephalon', 'subcortex'),
     ('9001', 'mesencephalon', 'subcortex'),
     ('4696', 'cerebellum', 'cerebellum'),
     ('4833', 'metencephalon', 'cerebellum'),
     ('9512', 'myelencephalon', 'cerebellum')),
    fields=('id', 'name', 'structure')
)


def reannotate_probes(probes):
    """
    Replaces gene symbols in `probes` with reannotated data

    Uses annotations from [1]_ to replace probe annotations shipped with AHBA
    data. Any probes that were unable to be matched to a gene in reannotation
    procedure are not retained.

    Parameters
Exemple #2
0
"""

import os
from pkg_resources import resource_filename
from nibabel.volumeutils import Recoder
from nilearn.datasets.utils import _fetch_files
import pandas as pd
from sklearn.utils import Bunch
from abagen import io

WELL_KNOWN_IDS = Recoder((('9861', 'H0351.2001', '178238387', '157722636'),
                          ('10021', 'H0351.2002', '178238373', '157723301'),
                          ('12876', 'H0351.1009', '178238359', '157722290'),
                          ('15496', 'H0351.1015', '178238266', '162021642'),
                          ('14380', 'H0351.1012', '178238316', '157721937'),
                          ('15697', 'H0351.1016', '178236545', '157682966')),
                         fields=(
                             'subj',
                             'uid',
                             'url',
                             't1w',
                         ))

VALID_DONORS = sorted(
    WELL_KNOWN_IDS.value_set('subj') | WELL_KNOWN_IDS.value_set('uid'))


def _get_dataset_dir(dataset_name, data_dir=None, verbose=1):
    """
    Gets path to `dataset_name`

    Parameters
Exemple #3
0
# caveat: Note that it's ambiguous to get the code given the bytespervoxel
# caveat 2: Note that the bytespervox you get is in str ( not an int)
_dtdefs = (  # code, conversion function, dtype, bytes per voxel
    (0, 'uint8', '>u1', '1', 'MRI_UCHAR', np.uint8, np.dtype(np.uint8),
     np.dtype(np.uint8).newbyteorder('>')),
    (4, 'int16', '>i2', '2', 'MRI_SHORT', np.int16, np.dtype(np.int16),
     np.dtype(np.int16).newbyteorder('>')),
    (1, 'int32', '>i4', '4', 'MRI_INT', np.int32, np.dtype(np.int32),
     np.dtype(np.int32).newbyteorder('>')),
    (3, 'float', '>f4', '4', 'MRI_FLOAT', np.float32, np.dtype(np.float32),
     np.dtype(np.float32).newbyteorder('>')))

# make full code alias bank, including dtype column
data_type_codes = Recoder(_dtdefs,
                          fields=('code', 'label', 'dtype', 'bytespervox',
                                  'mritype', 'np_dtype1', 'np_dtype2',
                                  'numpy_dtype'))


class MGHError(Exception):
    """Exception for MGH format related problems.

    To be raised whenever MGH is not happy, or we are not happy with
    MGH.
    """
    pass


class MGHHeader(object):
    '''
    The header also consists of the footer data which MGH places after the data
Exemple #4
0
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
#   See COPYING file distributed along with the NiBabel package for the
#   copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##

from nibabel.volumeutils import Recoder
import numpy as np

xform_codes = Recoder(
    (  # code, label
        (0, 'unknown',
         "NIFTI_XFORM_UNKNOWN"),  # Code for transform unknown or absent
        (1, 'scanner', "NIFTI_XFORM_SCANNER_ANAT"),
        (2, 'aligned', "NIFTI_XFORM_ALIGNED_ANAT"),
        (3, 'talairach', "NIFTI_XFORM_TALAIRACH"),
        (4, 'mni', "NIFTI_XFORM_MNI_152")),
    fields=('code', 'label', 'niistring'))

try:
    _float128t = np.float128
except AttributeError:
    _float128t = np.void
try:
    _complex256t = np.complex256
except AttributeError:
    _complex256t = np.void

dtdefs = (  # code, label, dtype definition, niistring, XXX: format for store in txt
Exemple #5
0
def _get_unionization_from_experiment(experiment_id,
                                      structures=None,
                                      attributes=None,
                                      average=True,
                                      verbose=False):
    """
    Gets unionization data for provided experiment(s) `experiment_id`

    Parameters
    ----------
    experiment_id : int or list
        Numerical experiment ID. If multiple experiments are provided the
        requested `attributes` will be averaged across experiments
    structures : list, optional
        List of structures (id, acronym, or name) for which to get unionization
        information associated with provided `experiment_id`. If not specified
        uses structures documented in [1]_. Specifying either the id or name is
        recommended as acronyms are not unique to structures. Default: None
    attributes : str or list, optional
        Which attributes / information to obtain for the provided structure.
        See :func:`abagen.mouse.available_unionization_info` for list of
        available attributes to request. If not specified all available
        attributes will be returned. Default: None
    average : bool, optional
        Whether to average across experiments if `experiment_id` is provided as
        a list. Only experiments probing the same gene will be considered for
        averaging. Default: True
    verbose : bool, optional
        Whether to print status messages. Default: False

    Returns
    -------
    unionization : pandas.DataFrame
        Where columns are unionization attributes and the index corresponds to
        gene ids and strucuture ids

    References
    ----------
    .. [1] Rubinov, M., Ypma, R. J., Watson, C., & Bullmore, E. T. (2015).
       Wiring cost and topological participation of the mouse brain connectome.
       Proceedings of the National Academy of Sciences, 112(32), 10032-10037.
    """

    if isinstance(experiment_id, (str, int)):
        experiment_id = [experiment_id]

    if structures is None:
        # read default structure list (from Rubinov et al., 2015, PNAS)
        structures = fetch_rubinov2015_structures(entry_type='id')
    elif isinstance(structures, (str, int)):
        structures = [structures]

    # we need to coerce all provided structures to be integer ids, NOT strings
    # so fetch all available structures then recode them to ids
    if any(isinstance(f, str) for f in structures):
        structs = np.asarray(fetch_allenref_structures(verbose=False))
        structs = Recoder(structs.tolist(), fields=['acronym', 'id', 'name'])
        structures = list(set(structs.id.get(f) for f in structures))

    # determine which attributes to request; if we don't have to request all
    # of them then we can speed up the API call
    if attributes is None:
        attributes = ['expression_density']
    elif attributes == 'all':
        attributes = _UNIONIZATION_ATTRIBUTES
    elif isinstance(attributes, str):
        attributes = [attributes]

    includes = ['structure_unionizes', 'genes']
    criteria = [
        '[id$in{}]'.format(','.join([str(f) for f in experiment_id])),
        'products[id$eq1]',
        'structure_unionizes[structure_id$in{}]'.format(','.join(
            [str(f) for f in structures])),
    ]
    req_attributes = [
        'id', 'structure_unionizes', 'structure_unionizes.structure_id'
    ] + ['structure_unionizes.' + attr for attr in attributes]

    info = _make_api_query('SectionDataSet',
                           includes=includes,
                           criteria=criteria,
                           attributes=req_attributes,
                           verbose=verbose)

    for n, exp in enumerate(info):
        keep = exp['structure_unionizes']
        for struc in keep:
            struc['gene_id'] = exp['genes'][0]['id']
            struc['experiment_id'] = exp['id']
        info[n] = keep

    # construct data frame from requested unionization info
    info = pd.DataFrame(list(itertools.chain.from_iterable(info)))
    if average:
        info = info.groupby(['gene_id', 'structure_id']).mean()
    else:
        info = info.set_index(['gene_id', 'experiment_id', 'structure_id'])

    return info[attributes]
Exemple #6
0
def get_unionization_from_gene(id=None,
                               acronym=None,
                               name=None,
                               slicing_direction='sagittal',
                               structures=None,
                               attributes=None,
                               average=True,
                               verbose=False):
    """
    Gets unionization data for provided gene(s)

    One of `id`, `acronym`, or `name` must be provided.

    Parameters
    ----------
    id : int, optional
        Numerical gene ID
    acronym : str, optional
        Short-form gene acronym (case sensitive)
    name : str, optional
        Full gene name (case sensitive)
    slicing_direction : {'sagittal', 'coronal'}, optional
        Slicing direction of brain tissue
    structures : list, optional
        List of structures (id, acronym, or name) for which to get unionization
        information associated with provided `experiment_id`. If not specified
        uses structures documented in [1]_. Specifying either the id or name is
        recommended as acronyms are not unique to structures. Default: None
    attributes : str or list, optional
        Which attributes / information to obtain for the provided gene. See
        :func:`abagen.mouse.available_gene_info` for list of available
        attributes to request. If not specified then only 'expression_density'
        will be returned. Specifying 'all' will return all information.
        Default: None
    average : bool, optional
        Whether to average across experiments if there are multiple experiments
        corresponding to any provided gene(s). Only experiments probing the
        same gene will be considered for averaging, and distinct structures
        will be retained. Default: True
    verbose : bool, optional
        Whether to print status messages. Default: False

    Returns
    -------
    unionization : pandas.DataFrame
        Where columns are unionization attributes and the index corresponds to
        strucuture and gene ids (if `experiments` is provided as a list
        with multiple genes). If `average=False`, `experiments` will also be a
        level in index

    Examples
    --------
    >>> from abagen import mouse
    >>> mouse.get_unionization_from_gene(acronym='Pdyn', structures=[22, 31])
                          expression_density
    gene_id structure_id
    18376   22                      0.024840
            31                      0.017199

    >>> mouse.get_unionization_from_gene(acronym=['Ace', 'Cd99'], structures=[22, 31])
                          expression_density
    gene_id structure_id
    11210   22                      0.001283
            31                      0.001427
    163028  22                      0.067537
            31                      0.056442

    References
    ----------
    .. [1] Rubinov, M., Ypma, R. J., Watson, C., & Bullmore, E. T. (2015).
       Wiring cost and topological participation of the mouse brain connectome.
       Proceedings of the National Academy of Sciences, 112(32), 10032-10037.
    """  # noqa

    directions = ['sagittal', 'coronal']
    if slicing_direction not in directions:
        raise ValueError(
            'Slicing_direction {} is invalid. Must be in {}.'.format(
                slicing_direction, directions))

    if structures is None:
        # read default structure list (from Rubinov et al., 2015, PNAS)
        structures = fetch_rubinov2015_structures(entry_type='id')
    elif isinstance(structures, (str, int)):
        structures = [structures]

    # we need to coerce all provided structures to be integer ids, NOT strings
    # so fetch all available structures then recode them to ids
    if any(isinstance(f, str) for f in structures):
        structs = np.asarray(fetch_allenref_structures(verbose=False))
        structs = Recoder(structs.tolist(), fields=['acronym', 'id', 'name'])
        structures = list(set(structs.id.get(f) for f in structures))

    exp_ids = _get_experiments_from_gene(id=id,
                                         acronym=acronym,
                                         name=name,
                                         slicing_direction=slicing_direction,
                                         verbose=verbose)

    data = _get_unionization_from_experiment(exp_ids,
                                             structures=structures,
                                             attributes=attributes,
                                             average=average,
                                             verbose=verbose)

    return data
Exemple #7
0
from nibabel.volumeutils import Recoder
import numpy as np
import pandas as pd
from scipy.spatial.distance import cdist

from . import io, utils

# AHBA structure IDs corresponding to different brain parts
ONTOLOGY = Recoder(
    (('4008', 'cerebral cortex', 'cortex'),
     ('4275', 'cerebral nuclei', 'subcortex'),
     ('4391', 'diencephalon', 'subcortex'),
     ('9001', 'mesencephalon', 'subcortex'),
     ('4696', 'cerebellum', 'cerebellum'),
     ('9131', 'pons', 'brainstem'),
     ('9512', 'myelencephalon', 'brainstem'),
     ('9218', 'white matter', 'white matter'),
     ('9352', 'sulci & spaces', 'other'),
     ('4219', 'hippocampal formation', 'subcortex')),
    fields=('id', 'name', 'structure')
)


def update_mni_coords(annotation):
    """
    Replaces MNI coords in `annotation` with corrected coords from `alleninf`

    Parameters
    ----------
    annotation : str
Exemple #8
0
"""Read/write linear transforms."""
import numpy as np
from nibabel.volumeutils import Recoder
from nibabel.affines import voxel_sizes

from .base import BaseLinearTransformList, StringBasedStruct, TransformFileError


transform_codes = Recoder(
    (
        (0, "LINEAR_VOX_TO_VOX"),
        (1, "LINEAR_RAS_TO_RAS"),
        (2, "LINEAR_PHYSVOX_TO_PHYSVOX"),
        (14, "REGISTER_DAT"),
        (21, "LINEAR_COR_TO_COR"),
    ),
    fields=("code", "label"),
)


class VolumeGeometry(StringBasedStruct):
    """Data structure for regularly gridded images."""

    template_dtype = np.dtype(
        [
            ("valid", "i4"),  # Valid values: 0, 1
            ("volume", "i4", (3, 1)),  # width, height, depth
            ("voxelsize", "f4", (3, 1)),  # xsize, ysize, zsize
            ("xras", "f8", (3, 1)),  # x_r, x_a, x_s
            ("yras", "f8", (3, 1)),  # y_r, y_a, y_s
            ("zras", "f8", (3, 1)),  # z_r, z_a, z_s
Exemple #9
0
"""Read/write linear transforms."""
import numpy as np
from nibabel.volumeutils import Recoder
from nibabel.affines import voxel_sizes

from .base import BaseLinearTransformList, StringBasedStruct, TransformFileError


transform_codes = Recoder((
    (0, 'LINEAR_VOX_TO_VOX'),
    (1, 'LINEAR_RAS_TO_RAS'),
    (2, 'LINEAR_PHYSVOX_TO_PHYSVOX'),
    (14, 'REGISTER_DAT'),
    (21, 'LINEAR_COR_TO_COR')),
    fields=('code', 'label'))


class VolumeGeometry(StringBasedStruct):
    """Data structure for regularly gridded images."""

    template_dtype = np.dtype([
        ('valid', 'i4'),              # Valid values: 0, 1
        ('volume', 'i4', (3, 1)),     # width, height, depth
        ('voxelsize', 'f4', (3, 1)),  # xsize, ysize, zsize
        ('xras', 'f8', (3, 1)),       # x_r, x_a, x_s
        ('yras', 'f8', (3, 1)),       # y_r, y_a, y_s
        ('zras', 'f8', (3, 1)),       # z_r, z_a, z_s
        ('cras', 'f8', (3, 1)),       # c_r, c_a, c_s
        ('filename', 'U1024')])       # Not conformant (may be >1024 bytes)
    dtype = template_dtype