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
""" 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
# 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
# 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
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]
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
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
"""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
"""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