Ejemplo n.º 1
0
def test_gene_exp():
    r = siibra.parcellations['2.9'].decode_region('fp1 left')
    args = (r, "gene")
    kwargs = {'gene': "MAOA", 'maptype': MapType.CONTINUOUS}
    features_higher = siibra.get_features(*args,
                                          threshold_continuous=0.9,
                                          **kwargs)
    features_lower = siibra.get_features(*args,
                                         threshold_continuous=0.2,
                                         **kwargs)

    # Using higher threshold == smaller number of features
    assert len(features_lower) > len(features_higher)
Ejemplo n.º 2
0
def get_global_features(atlas_id, parcellation_id, modality_id):
    if modality_id not in siibra.features.modalities:
        # if modality_id not in feature_classes:
        # modality_id not found in feature_classes
        raise HTTPException(status_code=400,
                            detail=f'{modality_id} is not a valid modality')

    #TODO check if still needed
    # if not issubclass(
    #         feature_classes[modality_id],
    #         feature_export.GlobalFeature):
    #     # modality_id is not a global feature, return empty array
    #     return []

    atlas = siibra.atlases[atlas_id]
    parcellation = atlas.get_parcellation(parcellation_id)

    got_features = siibra.get_features(parcellation, modality_id)
    if siibra.features.modalities[
            modality_id] == siibra.features.connectivity.ConnectivityMatrixQuery:
        return [
            {
                '@id': f.id,
                'src_name': f.name,
                'src_info': f.description,
                # 'column_names': f.column_names, TODO: Where to get column names
                'matrix': f.matrix.tolist(),
            } for f in got_features
        ]
    logger.info(f'feature {modality_id} has not yet been implemented')
    raise HTTPException(
        status_code=204,
        detail=f'feature {modality_id} has not yet been implemented')
Ejemplo n.º 3
0
 def test_check_layer_density_with_valid_range(self):
     features = siibra.get_features(region, siibra.modalities.CorticalCellDistribution)
     assert len(features) > 1
     feature = features[0]
     layer_density = feature.layer_density(1)
     assert layer_density is not None
     layer_density = feature.layer_density(6)
     assert layer_density is not None
Ejemplo n.º 4
0
def test_get_hoc1_left_density():
    atlas = siibra.atlases['human']
    region = atlas.get_region("hoc1 left", parcellation="2.9")
    features = siibra.get_features(region,
                                   siibra.modalities.ReceptorDistribution)
    assert len(
        features
    ) == 1, f"expect only 1 result from getting hoc1 left receptor, but got {len(features)}"
    expected_name = "Density measurements of different receptors for Area hOc1 (V1, 17, CalcS) [human, v1.0]"
    assert features[
        0].name == expected_name, f"name of fetched receptor does not match. Expected {expected_name}, got {features[0].name}"
Ejemplo n.º 5
0
def test_genes(region_spec: str, gene: str):
    parc = siibra.parcellations['2.9']
    region = parc.decode_region(region_spec)
    features = siibra.get_features(region, "gene", gene=gene)
    assert len(features) > 0, f"expecting at least 1 gene feature"
    assert all([isinstance(f, GeneExpression) for f in features
                ]), f"expecting all features to be of type GeneExpression"
    assert all(
        [
            hasattr(f, 'structure') and hasattr(f, "top_level_structure")
            for f in features
        ]
    ), f"expecting all features to have structure and top_level_structure attributes"
Ejemplo n.º 6
0
    def _retrieve_samples(self, regionspec, maptype: siibra.MapType,
                          threshold: float):
        """
        Retrieves and prepares gene expression samples for the given region
        definition.

        Parameters:
        -----------

        regionspec : str
            Identifier for a brain region in the selected atlas parcellation

        Returns: dictionary
            Gene expression data samples for the provided region
        """
        if maptype is None:
            raise Exception(f"maptype must be provided for _retrieve_samples")
        if maptype is siibra.MapType.CONTINUOUS and threshold is None:
            raise Exception(f"for continuous map, threshold must be provided!")
        region = self.parcellation.decode_region(regionspec)
        if region is None:
            logger.warn(
                "Region definition '{}' could not be matched in atlas.".format(
                    regionspec))
            return None
        samples = defaultdict(dict)
        for gene_name in self.genes:
            for f in siibra.get_features(region,
                                         "gene",
                                         gene=gene_name,
                                         maptype=maptype,
                                         threshold_continuous=threshold):
                key = tuple(list(f.location) + [regionspec])
                samples[key] = {**samples[key], **f.donor_info}
                samples[key]['mnicoord'] = tuple(f.location)
                samples[key]['region'] = region
                samples[key][gene_name] = np.mean(
                    winsorize(f.z_scores, limits=0.1))
        logger.info('{} samples found for region {}.'.format(
            len(samples), regionspec))
        return samples
Ejemplo n.º 7
0
def get_all_features_for_region(request: Request, atlas_id: str,
                                parcellation_id: str, region_id: str):
    """
    Returns all regional features for a region.
    """
    validate_and_return_atlas(atlas_id)
    parcellation = validate_and_return_parcellation(parcellation_id)
    region = validate_and_return_region(region_id, parcellation)

    result = {
        'features': [{
            m:
            '{}atlases/{}/parcellations/{}/regions/{}/features/{}'.format(
                get_base_url_from_request(request),
                atlas_id.replace('/', '%2F'),
                parcellation_id.replace('/', '%2F'),
                region_id.replace('/', '%2F'), m)
        } for m in siibra.get_features(region, 'all')]
    }

    return jsonable_encoder(result)
Ejemplo n.º 8
0
 def test_get_hoc1_cortical_cell_distribution(self):
     features = siibra.get_features(region, siibra.modalities.CorticalCellDistribution)
     assert len(features) > 1
Ejemplo n.º 9
0
def get_regional_feature(atlas_id,
                         parcellation_id,
                         region_id,
                         modality_id,
                         detail=True,
                         feature_id=None,
                         gene=None):
    if not siibra.modalities.provides(modality_id):  #feature_classes:
        # modality_id not found in feature_classes
        raise HTTPException(status_code=400,
                            detail=f'{modality_id} is not a valid modality')

    # TODO - check for subclass
    #     if not issubclass(
    #             feature_classes[modality_id],
    #             feature_export.RegionalFeature):
    #         # modality_id is not a global feature, return empty array
    #         return []

    atlas = validate_and_return_atlas(atlas_id)
    parcellation = validate_and_return_parcellation(parcellation_id)
    # region = atlas.get_region(region_id, parcellation)
    region = validate_and_return_region(region_id, parcellation)

    # TODO: validate region
    #     raise HTTPException(status_code=404,
    #                         detail=f'Region with id {region_id} not found!')
    try:
        got_features = siibra.get_features(region, modality_id)
    except:
        raise HTTPException(
            status_code=500,
            detail=f'Could not get features for region with id {region_id}')

    shaped_features = None
    if siibra.features.modalities[
            modality_id] == siibra.features.ebrains.EbrainsRegionalFeatureQuery:
        shaped_features = [{
            'summary': {
                '@id': kg_rf_f.id,
                'src_name': kg_rf_f.name,
            },
            'get_detail': lambda kg_rf_f: {
                '__detail': kg_rf_f.detail
            },
            'instance': kg_rf_f,
        } for kg_rf_f in got_features]
    if siibra.features.modalities[
            modality_id] == siibra.features.genes.AllenBrainAtlasQuery:
        shaped_features = [{
            'summary': {
                '@id': hashlib.md5(str(gene_feat).encode("utf-8")).hexdigest(),
            },
            'get_detail': lambda gene_feat: {
                '__donor_info': gene_feat.donor_info,
                '__gene': gene_feat.gene,
                '__probe_ids': gene_feat.probe_ids,
                '__mri_coord': gene_feat.mri_coord,
                '__z_scores': gene_feat.z_scores,
                '__expression_levels': gene_feat.expression_levels
            },
            'instance': gene_feat,
        } for gene_feat in got_features]
    if siibra.features.modalities[
            modality_id] == siibra.features.connectivity.ConnectivityProfileQuery:
        shaped_features = [
            {
                'summary': {
                    "@id": conn_pr._matrix.id,
                    "src_name": conn_pr.name,
                    "src_info": conn_pr.description,
                    "kgSchema": conn_pr._matrix.type_id,
                    "kgId": conn_pr._matrix.id,
                },
                'get_detail': lambda conn_pr: {
                    "__column_names": list(conn_pr.regionnames
                                           ),  #TODO: where to get the names?
                    "__profile": conn_pr.profile.tolist(),
                },
                'instance': conn_pr,
            } for conn_pr in got_features
        ]
    if siibra.features.modalities[
            modality_id] == siibra.features.receptors.ReceptorQuery:
        shaped_features = [
            {
                'summary': {
                    "@id":
                    receptor_pr.name,
                    "name":
                    receptor_pr.name,
                    "info":
                    receptor_pr.info,
                    "origin_datainfos": [{
                        'name': receptor_pr.name,
                        'description': receptor_pr.info,
                        'urls': [{
                            'doi': receptor_pr.url
                        }]
                    }]
                },
                'get_detail': lambda receptor_pr: {
                    "__receptor_symbols": siibra.features.receptors.
                    RECEPTOR_SYMBOLS,
                    "__files": [
                    ],  #receptor_pr.files, # TODO where  to get files
                    "__data": {
                        "__profiles": receptor_pr.profiles,
                        "__autoradiographs": {
                            key: {
                                "content_type":
                                "application/octet-stream",
                                "content_encoding":
                                "gzip; base64",
                                "x-width":
                                np.transpose(value, axes=[1, 0, 2]).shape[0],
                                "x-height":
                                np.transpose(value, axes=[1, 0, 2]).shape[1],
                                "x-channel":
                                np.transpose(value, axes=[1, 0, 2]).shape[2],
                                "content":
                                base64.b64encode(
                                    zlib.compress(
                                        np.transpose(value, axes=[1, 0, 2]).
                                        tobytes(order="F"))),
                            }
                            for key, value in receptor_pr.autoradiographs.
                            items()
                        },
                        "__fingerprint": receptor_pr.fingerprint,
                        # "__profile_unit": receptor_pr.profile_unit, TODO check where to get units
                    },
                },
                'instance': receptor_pr,
            } for receptor_pr in got_features
        ]
    if siibra.features.modalities[
            modality_id] == siibra.features.cells.RegionalCellDensityExtractor:
        shaped_features = [{
            'summary': {
                "@id": '...',
                'regionspec': conn_pr.regionspec,
                'species': conn_pr.species,
                'cells': conn_pr.cells.to_dict(),
                'section': conn_pr.section,
                'patch': conn_pr.patch
            },
            'get_detail': lambda conn_pr: {
                'regionspec': conn_pr.regionspec,
                'species': conn_pr.species,
                'cells': conn_pr.cells.to_dict(),
                'section': conn_pr.section,
                'patch': conn_pr.patch
            },
            'instance': conn_pr,
        } for conn_pr in got_features]

    if shaped_features is None:
        raise HTTPException(
            status_code=501,
            detail=f'feature {modality_id} has not yet been implmented')

    if feature_id is not None:
        shaped_features = [
            f for f in shaped_features if f['summary']['@id'] == feature_id
        ]
    return [{
        **f['summary'],
        **(f['get_detail'](f['instance']) if detail else {})
    } for f in shaped_features]
Ejemplo n.º 10
0
def get_spatial_features(atlas_id,
                         space_id,
                         modality_id,
                         feature_id=None,
                         detail=False,
                         parc_id=None,
                         region_id=None):

    if modality_id not in siibra.features.modalities:
        raise HTTPException(status_code=400,
                            detail=f'{modality_id} is not a valid modality')

    # TODO: Why only spatial features
    if not issubclass(
            # feature_classes[modality_id],
            # feature_export.SpatialFeature):
            siibra.features.modalities[modality_id]._FEATURETYPE,
            siibra.features.feature.SpatialFeature):
        # modality_id is not a global feature, return empty array
        return []

    atlas = validate_and_return_atlas(atlas_id)
    space_of_interest = validate_and_return_space(space_id, atlas)

    # TODO not working at the moment. Space_of_interest is never in atlas.spaces
    # if space_of_interest not in atlas.spaces:
    #     raise HTTPException(404, detail=f'space {space_id} not in atlas {atlas}')

    # TODO: No Selection of parcellation and region is needed - TODO: How to provide parcellation/region
    if parc_id is None:
        raise HTTPException(status_code=400, detail='Parc id is needed')

    parc = validate_and_return_parcellation(parc_id, atlas)
    roi = validate_and_return_region(region_id, parc)

    logger.debug(
        f'get_spatial_features: {str(atlas)}, {str(space_of_interest)}, {str(parc)}, {str(roi)}'
    )

    try:
        # spatial_features=atlas.get_features(modality_id)
        spatial_features = siibra.get_features(roi,
                                               modality_id,
                                               space=space_of_interest)
    except Exception as e:
        logger.warn(e, str(space_of_interest), space_id)
        raise HTTPException(404, detail=f'Could not get spatial features.')

    shaped_features = None
    if siibra.features.modalities[
            modality_id] == siibra.features.ieeg.IEEG_SessionQuery:
        shaped_features = [{
            'summary': {
                '@id': hashlib.md5(str(feat).encode("utf-8")).hexdigest(),
                'name': f'{feat.dataset.name} sub:{feat.sub_id}',
                'description': str(feat.dataset.description),
                'origin_datainfos': [{
                    'urls': feat.dataset.urls
                }]
            },
            'get_detail':
            lambda ft: get_ieeg_session_detail(ft,
                                               region=roi,
                                               parcellation=parc,
                                               space=space_of_interest,
                                               atlas=atlas),
            'instance':
            feat
        } for feat in spatial_features]

    if shaped_features is None:
        raise HTTPException(501, detail=f'{modality_id} not yet implemented')

    if feature_id is not None:
        shaped_features = [
            f for f in shaped_features if f['summary']['@id'] == feature_id
        ]

    return [{
        **f['summary'],
        **(f['get_detail'](f['instance']) if detail else {}),
    } for f in shaped_features]
Ejemplo n.º 11
0
EBRAINS regional datasets
~~~~~~~~~~~~~~~~~~~~~~~~~ 

The modalitity "EbrainsRegionalDataset' is different from the others.
It returns any datasets in the EBRAINS Knowledge Graph which could be linked to the given atlas concept, and provides access to their metadata, as well as the link to the EBRAINS Knowledge Graph. 
The returned features can thus actually have different modalities, and might include datasets which are also supported as one of the explicitly supported modalities shown in previous examples.
"""

# %%
# We query regional features for the secondary visual cortex V2.

import siibra

atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS
region = atlas.get_region("v2")
features = siibra.get_features(region,
                               siibra.modalities.EbrainsRegionalDataset)
for feature in features:
    print(f" - {feature.name}")

# %%
# Since these features represent EBRAINS datasets which are linked to brain regions,
# they are instances of both the "RegionalFeature" class and the "EbrainsDataset" class.
print(
    f"The last returned feature was of type '{feature.__class__.__name__}', "
    f"derived from {' and '.join(b.__name__ for b in feature.__class__.__bases__)}."
)

# %%
# Each EBRAINS feature provides access to the metadata from the EBRAINS Knowledge Graph.
# We view some of those for the last returned feature (which is accessible from the loop above).
# ``siibra`` implements a lazy loading mechanism here again:
Ejemplo n.º 12
0
 def test_to_model(self):
     features = siibra.get_features(region, siibra.modalities.CorticalCellDistribution)
     feature = features[0]
     model = feature.to_model(detail=False)
     assert isinstance(model, CorticalCellDistributionModel)
     assert getattr(model.metadata, 'short_name') is not None and model.metadata.short_name != ""
Ejemplo n.º 13
0
 def test_check_layer_density_with_invalid_range(self):
     features = siibra.get_features(region, siibra.modalities.CorticalCellDistribution)
     assert len(features) > 1
     feature = features[0]
     with self.assertRaises(AssertionError):
         feature.layer_density(10)
Ejemplo n.º 14
0
    def test_get_features_ebrains_features(self):

        region = self.atlas.get_region('hoc1 left')
        features = siibra.get_features(region, modalities.EbrainsRegionalDataset)
        assert(len(features) > 0)
`siibra` provides access to connectivity matrices from different sources containing averaged connectivity information for brain parcellations.
These matrices are modelled as ParcellationFeature types, so they match against a complete parcellation.
Several types of connectivity are supported. 
As of now, these include the feature modalities "StreamlineCounts", "StreamlineLengths", and "FunctionalConnectivity".
"""

# %%
# We start by selecting an atlas parcellation.
import siibra
atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS
jubrain = atlas.get_parcellation('julich 2.9')

# %%
# The matrices are queried as expected, using `siibra.get_features`, and passing the parcellation as a concept.
# Here, we query for structural connectivity matrices.
features = siibra.get_features(jubrain, siibra.modalities.StreamlineCounts)
print(f"Found {len(features)} streamline count matrices.")

# %%
# We fetch the first result and have a look at it.
# It is a specific `StreamlineCounts` object, but it is derived from the more general `ConnectivityMatrix` class.
# The `src_info` attribute contains more detailed metadata information about each matrix.
conn = features[0]
print(
    f"Matrix reflects {conn.modality()} for subject {conn.subject} of {conn.cohort}."
)
print("\n" + "; ".join(conn.authors))
print(conn.name)
print("Dataset id: " + conn.dataset_id)
print("\n" + conn.description)
Ejemplo n.º 16
0
    <https://github.com/FZJ-INM1-BDA/siibra-jugex>`_, which provides an
    implementation for differential gene expression analysis between two
    different brain regions as proposed by Bludau et al.
"""

# %%
# We start by selecting an atlas.
import siibra
atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS

# %%
# We select a brain region and query for expression levels of GABARAPL2.
region = atlas.get_region("V1")
features = siibra.get_features(
    region, siibra.modalities.GeneExpression,
    gene=siibra.features.gene_names.GABARAPL2,
    maptype=siibra.commons.MapType.CONTINUOUS,
    threshold_continuous=0.2)
print(features[0])

# %%
# Since gene expressions are spatial features,
# let's check the reference space of the results.
space = features[0].space
assert(all(f.space==space for f in features))

# %%
# Plot the locations of the probes that were found, together with the region
# mask of V1.
from nilearn import plotting
all_coords = [tuple(g.location) for g in features]
Cortical cell body distributions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Another regional data feature are cortical distributions of cell bodies. The distributions are measured crom cortical image patches that have been extracted from the original cell-body stained histological sections of the Bigbrain (Amunts et al., 2013), scanned at 1 micrometer resolution. These patches come together with manual annotations of cortical layers. The cell segmentations have been performed using the recently proposed Contour Proposal Networks (CPN; E. Upschulte et al.; https://arxiv.org/abs/2104.03393; https://github.com/FZJ-INM1-BDA/celldetection).
"""

# %%
# We start by selecting an atlas.
import siibra

atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS

# %%
# Find cell density features for V1
v1 = atlas.get_region("v1")
features = siibra.get_features(v1, siibra.modalities.CorticalCellDistribution)
print(f"{len(features)} found for region {v1.name}")

# %%
# Look at the default visualization the first of them.
# This will actually fetch the image and cell segmentation data.
features[0].plot()

# %%
# The segmented cells are stored in each feature as a numpy array with named columns.
# For example, to plot the 2D distribution of the cell locations colored by
# layers, we can do:
import matplotlib.pyplot as plt

c = features[0].cells
plt.scatter(c["x"], c["y"], c=c["layer"], s=0.1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

EBRAINS provides transmitter receptor density measurments linked to a selection of cytoarchitectonic brain regions in the human brain (Palomero-Gallagher, Amunts, Zilles et al.). These can be accessed by calling the ``siibra.get_features()`` method with the ``siibra.modalities.ReceptorDistribution`` modality (or the shorthand 'receptor'), and by specifying a cytoarchitectonic region. Receptor densities come as a structured datatype which includes a regional fingerprint with average densities for different transmitters, as well as often an additional cortical density profile and a sample autoradiograph patch. They bring their own `plot()` method to produce a quick illustration.
"""


# %%
# We start by selecting an atlas.
import siibra
atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS

# %%
# If we query this modality for the whole atlas instead of a particular
# brain region, all linked receptor density features
# will be returned.
all_features = siibra.get_features( atlas, siibra.modalities.ReceptorDistribution)
print("Receptor density features found for the following regions:")
print("\n".join(f.regionspec for f in all_features))

# %%
# When providing a particular region instead, the returned list is filtered accordingly. 
# So we can directly retrieve densities for the primary visual cortex:
v1_features = siibra.get_features(atlas.get_region('v1'), 'receptor')
for f in v1_features:
    fig = f.plot()

# %%
# Each feature includes a data structure for the fingerprint, with mean and
# standard values for different receptors. The following table thus gives
# us the same values as shown in the polar plot above:
fp = v1_features[0].fingerprint
Ejemplo n.º 19
0
 def test_check_average_density(self):
     features = siibra.get_features(region, siibra.modalities.CorticalCellDistribution)
     assert len(features) > 1
     feature = features[0]
     average_density = feature.average_density()
     assert average_density is not None
Ejemplo n.º 20
0
Parcellation maps can be colorized with a dictionary of values.
This is useful to visualize data features in 3D space.
Here we demonstrate it for average densities of the GABAA receptor.
"""

# %%
# We start by selecting an atlas and the Julich-Brain parcellation.
import siibra
atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS
jubrain = atlas.get_parcellation('julich 2.9')

# %%
# As in the previous example, we extract all receptor density features linked
# to Julich-Brain.
receptor_features = siibra.get_features(jubrain,
                                        siibra.modalities.ReceptorDistribution)

# %%
# Colorizing a map requires a dictionary that maps region objects to numbers.
# We build a dictionary mapping Julich-Brain regions to average receptor
# densities measured for GABAA.
receptor = 'GABAA'
mapping = {
    jubrain.decode_region(f.regionspec): f.fingerprint[receptor].mean
    for f in receptor_features if receptor in f.fingerprint.labels
}

# %%
# Now colorize the Julich-Brain maximum probability map and plot it.
colorized_map = jubrain.get_map(space='mni152').colorize(mapping)
from nilearn import plotting
Ejemplo n.º 21
0
# %%
# Available modalities are defined in the registry ``siibra.modalities``.
# Most of these represent specifically supported data modalities, and will
# be covered one by one in the next examples.
for m in siibra.modalities:
    print(m)

# %%
# Regional features
# ^^^^^^^^^^^^^^^^^
#
# As a first example, we use brain region V2 to query for "EbrainsRegionalDataset" features.
# See :ref:`ebrains_datasets` for more information about this modality.
atlas = siibra.atlases.MULTILEVEL_HUMAN_ATLAS
region = atlas.get_region("v2")
features = siibra.get_features(region,
                               siibra.modalities.EbrainsRegionalDataset)
for feature in features:
    print(f" - {feature.name}")

# %%
# Mappings to brain regions can have different precision:
# A feature may be associated with the exact region requested,
# but it may also be linked to a child region, similar region, or parent region.
# To understand the link between the query region and each requested feature,
# ``siibra`` adds some information about the match each time a query is executed. In particular,
#
#  - ``Feature.match_qualification`` returns a rating of the matching that was applied, and could be any of "exact", "approximate", "contained", "contains"
#  - ``Feature.match_description`` often contains a human-readable description about the matching
#
# Furthermore, if applicable,
#  - ``Feature.matched_region`` returns the region object to which the feature was last matched,