Skip to content

api.serialization

This module handles the serialization of siibra objects into pydantic models.

Processes import from this module will require siibra installed.

_common

mapindex_to_model(mapindex, **kwargs)

Serialize MapIndex instance

Parameters:

Name Type Description Default
mapindex MapIndex

instance to be serialized

required

Returns:

Type Description
MapIndexModel

MapIndexModel

Source code in api/serialization/_common.py
@serialize(MapIndex)
def mapindex_to_model(mapindex: MapIndex, **kwargs) -> MapIndexModel:
    """Serialize MapIndex instance

    Args:
        mapindex: instance to be serialized

    Returns:
        MapIndexModel
        """
    return MapIndexModel(
        volume=mapindex.volume or 0,
        label=mapindex.label,
        fragment=mapindex.fragment
    )

pddf_to_model(df, detail=False, **kwargs)

Serialize pandas dataframe

Parameters:

Name Type Description Default
df DataFrame

DataFrame instance to be serialized

required
detail str

defailt flag. If not set, data attribute will not be populated.

False

Returns:

Type Description
DataFrameModel

DataFrameModel

Source code in api/serialization/_common.py
@serialize(DataFrame)
def pddf_to_model(df: DataFrame, detail: str=False, **kwargs) -> DataFrameModel:
    """Serialize pandas dataframe

    Args:
        df: DataFrame instance to be serialized
        detail: defailt flag. If not set, data attribute will not be populated.

    Returns:
        DataFrameModel
    """
    return DataFrameModel(
        index=[instance_to_model(el) for el in df.index],
        columns=[instance_to_model(el) for el in df.columns],
        ndim=df.ndim,
        data=instance_to_model(df.values.tolist()) if detail else None,
    )

pdseries_to_model(series, **kwargs)

Serialize pandas series.

Parameters:

Name Type Description Default
series Series

Series instance to be serialized

required

Returns:

Type Description
SeriesModel

SeriesModel

Raises:

Type Description
AssertionError

if dtype is not serializable

Source code in api/serialization/_common.py
@serialize(Series)
def pdseries_to_model(series: Series, **kwargs) -> SeriesModel:
    """Serialize pandas series.

    Args:
        series: Series instance to be serialized

    Returns:
        SeriesModel

    Raises:
        AssertionError: if dtype is not serializable
    """

    assert series.dtype in serializable_dtype, f"series dtype {series.dtype}" + \
        "not in serializable type: {', '.join([v.__name__ for v in serializable_dtype])}"
    return SeriesModel(
        name=series.name,
        dtype=str(series.dtype),
        index=[instance_to_model(el) for el in series.index],
        data=series.values.tolist()
    )

_retrieval

datasets

ebrains_dataset_to_model(ds, **kwargs)

Serialize ebrains dataset

Parameters:

Name Type Description Default
ds EbrainsBaseDataset

instance of EbrainsBaseDataset

required

Returns:

Type Description
EbrainsDatasetModel

EbrainsDatasetModel

Source code in api/serialization/_retrieval/datasets.py
@serialize(EbrainsBaseDataset)
def ebrains_dataset_to_model(ds: EbrainsBaseDataset, **kwargs) -> EbrainsDatasetModel:
    """Serialize ebrains dataset

    Args:
        ds: instance of EbrainsBaseDataset

    Returns:
        EbrainsDatasetModel
    """
    return EbrainsDatasetModel(
        id=ds.id,
        name=ds.name,
        urls=[EbrainsDsUrl(**url) for url in ds.urls],
        description=ds.description,
        contributors=[EbrainsDsPerson(**person) for person in ds.contributors],
        ebrains_page=ds.ebrains_page,
        custodians=[EbrainsDsPerson(**person) for person in ds.custodians]
    )

generic_dataset_to_model(ds, **kwargs)

Serialize generic dataset

Source code in api/serialization/_retrieval/datasets.py
@serialize(GenericDataset)
def generic_dataset_to_model(ds: GenericDataset, **kwargs) -> EbrainsDatasetModel:
    """Serialize generic dataset"""
    return EbrainsDatasetModel(
        id=md5(ds.name.encode("utf-8")).hexdigest(),
        name=ds.name,
        urls=[EbrainsDsUrl(**url) for url in ds.urls],
        description=ds.description,
        contributors=[EbrainsDsPerson(id=person.get("name"),
                                      schema_shortname=person.get("name"),
                                      identifier=person.get("name"),
                                      shortName=person.get("name"),
                                      name=person.get("name"))
                      for person in ds.contributors],
        custodians=[],
    )

core

_concept

atlasconcept_to_model(concept)

Serialize base concept.

Parameters:

Name Type Description Default
concept AtlasConcept

AtlasConcept

required

Returns:

Type Description
SiibraAtlasConcept

SiibraAtlasConcept

Source code in api/serialization/core/_concept.py
@serialize(AtlasConcept)
def atlasconcept_to_model(concept: AtlasConcept) -> SiibraAtlasConcept:
    """Serialize base concept.

    Args:
        concept: AtlasConcept

    Returns:
        SiibraAtlasConcept
    """
    return SiibraAtlasConcept(
        id=concept.id,
        name=concept.name,
        shortname=concept.shortname,
        modality=concept.modality,
        description=concept.modality,
        publications=[SiibraPublication(**publication) for publication in concept.publications],
        datasets=[instance_to_model(ds) for ds in concept.datasets]
    )

atlas

atlas_to_model(atlas, *, detail=False, **kwargs)

Serializes an atlas into SiibraAtlasModel

Parameters:

Name Type Description Default
atlas Atlas

Atlas

required
detail bool

detail flag

False

Returns:

Type Description
SiibraAtlasModel

SiibraAtlasModel

Source code in api/serialization/core/atlas.py
@serialize(Atlas)
def atlas_to_model(atlas: Atlas, *, detail: bool=False, **kwargs) -> SiibraAtlasModel:
    """Serializes an atlas into SiibraAtlasModel

    Args:
        atlas: Atlas
        detail: detail flag

    Returns:
        SiibraAtlasModel
    """
    return SiibraAtlasModel(
        id=atlas.id,
        name=atlas.name,
        spaces=[SiibraAtIdModel(id=spc.id) for spc in atlas.spaces],
        parcellations=[SiibraAtIdModel(id=parc.id) for parc in atlas.parcellations],
        species=str(atlas.species),
    )

get_species_data(species_str)

Translating string to SpeciesModel

Parameters:

Name Type Description Default
species_str str

species string

required

Returns:

Type Description
SpeciesModel

SpeciesModel

Raises:

Type Description
ValueError

If string does not decode

Source code in api/serialization/core/atlas.py
def get_species_data(species_str: str) -> SpeciesModel:
    """Translating string to SpeciesModel

    Args:
        species_str: species string

    Returns:
        SpeciesModel

    Raises:
        ValueError: If string does not decode
    """
    if species_str == 'human':
        return SpeciesModel(
            type="https://openminds.ebrains.eu/controlledTerms/Species",
            name="Homo sapiens",
            kg_v1_id="https://nexus.humanbrainproject.org/v0/data/minds/core/species/v1.0.0/0ea4e6ba-2681-4f7d-9fa9-49b915caaac9",
            id="https://openminds.ebrains.eu/instances/species/homoSapiens",
            preferred_ontology_identifier="http://purl.obolibrary.org/obo/NCBITaxon_9606"
        )
    if species_str == 'rat':
        return SpeciesModel(
            type="https://openminds.ebrains.eu/controlledTerms/Species",
            name="Rattus norvegicus",
            kg_v1_id="https://nexus.humanbrainproject.org/v0/data/minds/core/species/v1.0.0/f3490d7f-8f7f-4b40-b238-963dcac84412",
            id="https://openminds.ebrains.eu/instances/species/rattusNorvegicus",
            preferred_ontology_identifier="http://purl.obolibrary.org/obo/NCBITaxon_10116"
        )
    if species_str == 'mouse':
        return SpeciesModel(
            type="https://openminds.ebrains.eu/controlledTerms/Species",
            name="Mus musculus",
            kg_v1_id="https://nexus.humanbrainproject.org/v0/data/minds/core/species/v1.0.0/cfc1656c-67d1-4d2c-a17e-efd7ce0df88c",
            id="https://openminds.ebrains.eu/instances/species/musMusculus",
            preferred_ontology_identifier="http://purl.obolibrary.org/obo/NCBITaxon_10090"
        )
    # TODO this may not be correct. Wait for feedback and get more accurate
    if species_str == 'monkey':
        return SpeciesModel(
            type="https://openminds.ebrains.eu/controlledTerms/Species",
            name="Macaca fascicularis",
            kg_v1_id="https://nexus.humanbrainproject.org/v0/data/minds/core/species/v1.0.0/c541401b-69f4-4809-b6eb-82594fc90551",
            id="https://openminds.ebrains.eu/instances/species/macacaFascicularis",
            preferred_ontology_identifier="http://purl.obolibrary.org/obo/NCBITaxon_9541"
        )
    raise ValueError(f'species with spec {species_str} cannot be decoded')

parcellation

parcellation_to_model(parc, *, min_flag=False, **kwargs)

Serialize Parcellation into SiibraParcellationModel

Parameters:

Name Type Description Default
parc Parcellation

Parcellation

required

Returns:

Type Description
SiibraParcellationModel

SiibraParcellationModel

Source code in api/serialization/core/parcellation.py
@serialize(Parcellation)
def parcellation_to_model(parc: Parcellation, *, min_flag=False, **kwargs) -> SiibraParcellationModel:
    """Serialize Parcellation into SiibraParcellationModel

    Args:
        parc: Parcellation

    Returns:
        SiibraParcellationModel
    """

    if min_flag:
        return SiibraParcellationModel(
            id=parc.id,
            name=parc.name,
            datasets=[],
            brainAtlasVersions=[],
        )
    return SiibraParcellationModel(
        id=parc.id,
        name=parc.name,
        modality=parc.modality,
        shortname=parc.shortname,
        datasets=instance_to_model(parc.datasets, **kwargs),
        brain_atlas_versions=[BrainAtlasVersionModel(
            id=get_brain_atlas_version_id(parc, spc),
            atlas_type={
                # TODO fix
                "@id": AtlasType.PROBABILISTIC_ATLAS
            },
            accessibility={
                # TODO fix
                "@id": ""
            },
            coordinate_space={
                "@id": spc.id
            },
            description=parc.description[:2000],
            full_documentation={
                # TODO fix
                "@id": ""
            },
            full_name=get_brain_atlas_version_name(parc, spc),
            has_terminology_version=HasTerminologyVersion(
                has_entity_version=[{
                    "@id": id
                } for id in set([r.id for r in parc]) ]
            ),
            license={
                # TODO fix
                "@id": ""
            },
            release_date=str(date(1970, 1, 1)),
            short_name=parc.name[:30],
            version_identifier=f"{parc.version} in {spc.name}",
            version_innovation="",
        ) for spc in parc.supported_spaces],
        version=instance_to_model(parc.version, **kwargs) if parc.version is not None else None
    )

parcversion_to_model(version, **kwargs)

Serialize ParcellationVersion into SiibraParcellationVersionModel

Parameters:

Name Type Description Default
version ParcellationVersion

ParcellationVersion

required

Returns:

Type Description
SiibraParcellationVersionModel

SiibraParcellationVersionModel

Source code in api/serialization/core/parcellation.py
@serialize(ParcellationVersion)
def parcversion_to_model(version: ParcellationVersion, **kwargs) -> SiibraParcellationVersionModel:
    """Serialize ParcellationVersion into SiibraParcellationVersionModel

    Args:
        version: ParcellationVersion

    Returns:
        SiibraParcellationVersionModel

    """
    return SiibraParcellationVersionModel(
        name=version.name,
        deprecated=version.deprecated,
        prev=SiibraAtIdModel(
            id=version.prev_id
        ) if version.prev_id is not None else None,
        next=SiibraAtIdModel(
            id=version.next_id
        ) if version.next_id is not None else None,
    )

region

region_to_model(region, *, min_flag=False, detail=False, space=None, **kwargs)

Serialize Region

Parameters:

Name Type Description Default
region Region

Region object

required
detail bool

detail flag

False
space Space

Space object

None

Returns:

Type Description
ParcellationEntityVersionModel

ParcellationEntityVersionModel

Raises:

Type Description
AssertionError

region.parent.__class__ has not been registered to be serialized

AssertionError

provided space is not of instance Space

Source code in api/serialization/core/region.py
@serialize(Region)
def region_to_model(region: Region, *, min_flag: bool=False, detail: bool=False, space: Space=None, **kwargs) -> ParcellationEntityVersionModel:
    """Serialize Region

    Args:
        region: Region object
        detail: detail flag
        space: Space object

    Returns:
        ParcellationEntityVersionModel

    Raises:
        AssertionError: `region.parent.__class__` has not been registered to be serialized
        AssertionError: provided space is not of instance Space


    """
    if detail:
        assert any([
            Cls in REGISTER for Cls in region.parent.__class__.__mro__
        ]), "one of Region.parent.__class__.__mro__ must be in REGISTER"

    if space:
        assert isinstance(space, Space), "space kwarg must be of instance Space"

    pev = ParcellationEntityVersionModel(
        id=get_region_model_id(region),
        has_parent=[{"@id": get_region_model_id(region.parent)}]
            if (region.parent is not None)
            else None,
        name=region.name,
        ontology_identifier=None,
        relation_assessment=None,
        version_identifier=f"{region.parcellation.name} - {region.name}",
        version_innovation=region.description
    )

    if min_flag:
        return pev

    centroid = None
    if space:
        centroids = region.compute_centroids(space)
        if centroids is not None and len(centroids) > 0:
            centroid = centroids[0]
            if len(centroids) > 1:
                logger.warn(f"region {region.name!r} returned multiple centroids in space {space.name!r}. Returning the first one.")

    pev.has_annotation = HasAnnotation(
        best_view_point=BestViewPoint(
            coordinate_space={
                "@id": space.id
            },
            coordinates=[Coordinates(value=pt) for pt in centroid]
        ) if centroid else None,
        internal_identifier="",
        criteria_quality_type={
            # TODO check criteriaQualityType
            "@id": "https://openminds.ebrains.eu/instances/criteriaQualityType/asserted"
        },
        display_color="#{0:02x}{1:02x}{2:02x}".format(*region.rgb)
        if region.rgb
        else None,
    )

    # monkey patch big brain ngid
    if region.parcellation and region.parcellation.id == jba_29_id:
        found_lbls=[(ngid, lblidx)
            for (ngid, r_lbl_dict) in bigbrain_jba29_ngid.items()
            for (rname, lblidx) in r_lbl_dict.items()
            if rname == region.name]

        if len(found_lbls) > 0:
            pev.has_annotation.inspired_by = [
                *(pev.has_annotation.inspired_by or []),
                *[{
                    "@id": f"bb_ngid_lbl://{ngid}#{str(lbl)}"
                } for (ngid, lbl) in found_lbls]
            ]

    return pev

space

space_to_model(space, **kwargs)

Serialize space object into CommonCoordinateSpaceModel

Parameters:

Name Type Description Default
space Space

space object to be serialized

required

Returns:

Type Description
CommonCoordinateSpaceModel

CommonCoordinateSpaceModel

Source code in api/serialization/core/space.py
@serialize(Space)
def space_to_model(space: Space, **kwargs) -> CommonCoordinateSpaceModel:
    """Serialize space object into CommonCoordinateSpaceModel

    Args:
        space: space object to be serialized

    Returns:
        CommonCoordinateSpaceModel"""
    return CommonCoordinateSpaceModel(
        id=space.id,
        anatomical_axes_orientation={
            "@id": "https://openminds.ebrains.eu/vocab/anatomicalAxesOrientation/XYZ"
        },
        axes_origin=[
            AxesOrigin(value=0),
            AxesOrigin(value=0),
            AxesOrigin(value=0),
        ],
        default_image=[instance_to_model(vol) for vol in space.volumes],
        full_name=space.name,
        native_unit={
            "@id": "https://openminds.ebrains.eu/controlledTerms/Terminology/unitOfMeasurement/um"
        },
        release_date=str(date(2015, 1, 1)),
        short_name=space.shortname,
        version_identifier=space.name,
        datasets=[instance_to_model(ds) for ds in (space.datasets or [])]
    )

features

_basetypes

cortical_profiles

cortical_profile_to_model(pr, detail=False, super_model_dict={}, **kwargs)

Serialize cortical profile into SiibraCorticalProfileModel.

As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of CorticalProfile (Tabular), and passed to this function as super_model_dict. User should not supply their own super_model_dict kwarg, as it will be ignored.

Parameters:

Name Type Description Default
pr CorticalProfile

instance of CorticalProfile to be serialized

required

Returns:

Type Description
SiibraCorticalProfileModel

SiibraCorticalProfileModel

Source code in api/serialization/features/_basetypes/cortical_profiles.py
@serialize(CorticalProfile, pass_super_model=True)
def cortical_profile_to_model(pr: CorticalProfile, detail=False, super_model_dict={}, **kwargs) -> SiibraCorticalProfileModel:
    """Serialize cortical profile into SiibraCorticalProfileModel.

    As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of CorticalProfile (Tabular),
    and passed to this function as super_model_dict. User **should** not supply their own `super_model_dict` kwarg, as it will be ignored.

    Args:
        pr: instance of CorticalProfile to be serialized

    Returns:
        SiibraCorticalProfileModel
    """

    return SiibraCorticalProfileModel(
        **super_model_dict,
        unit=pr.unit,
        boundary_positions={
            "-".join([str(bound) for bound in boundary]): val
            for boundary, val in pr.boundary_positions.items()
        },
        boundaries_mapped=pr.boundaries_mapped,
    )

feature

feature_to_model(feat, detail=False, **kwargs)

Fallback serialize siibra Feature instance

Parameters:

Name Type Description Default
feat Feature

instance of Feature

required
detail bool

require detail flag.

False

Returns:

Type Description
FeatureModel

FeatureModel

Source code in api/serialization/features/_basetypes/feature.py
@serialize(Feature)
def feature_to_model(feat: Feature, detail: bool=False, **kwargs) -> FeatureModel:
    """Fallback serialize siibra Feature instance

    Args:
        feat: instance of Feature
        detail: require detail flag.

    Returns:
        FeatureModel
    """
    return FeatureModel(
        id=feat.id,
        name=feat.name,
        category=feat.category or "Unknown category",
        modality=feat.modality,
        description=feat.description,
        anchor=instance_to_model(feat.anchor, **kwargs) if detail else None,
        datasets=[instance_to_model(ds, **kwargs) for ds in feat.datasets]
    )

regional_connectivity

regional_conn_to_model(conn, subject=None, detail=False, super_model_dict={}, **kwargs)

Serialize regional connectivity

As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of RegionalConnectivity (Feature), and passed to this function as super_model_dict. User should not supply their own super_model_dict kwarg, as it will be ignored.

Parameters:

Name Type Description Default
conn RegionalConnectivity

instance of RegionalConnnectivity

required
subject str

subject to be retrieved, passed directly to RegionalConnectivity.get_matrix. If not supplied, "_average" will be populated

None
detail bool

detail flag. If not supplied, matrices attribute will not be populated

False

Returns:

Type Description
SiibraRegionalConnectivityModel

SiibraRegionalConnectivityModel

Source code in api/serialization/features/_basetypes/regional_connectivity.py
@serialize(RegionalConnectivity, pass_super_model=True)
def regional_conn_to_model(conn: RegionalConnectivity, subject:str=None, detail:bool=False, super_model_dict={}, **kwargs) -> SiibraRegionalConnectivityModel:
    """Serialize regional connectivity

    As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of RegionalConnectivity (Feature),
    and passed to this function as super_model_dict. User **should** not supply their own `super_model_dict` kwarg, as it will be ignored.

    Args:
        conn: instance of RegionalConnnectivity
        subject: subject to be retrieved, passed directly to RegionalConnectivity.get_matrix. If not supplied, "_average" will be populated
        detail: detail flag. If not supplied, matrices attribute will not be populated

    Returns:
        SiibraRegionalConnectivityModel
    """
    return SiibraRegionalConnectivityModel(
        **super_model_dict,
        subjects=conn.subjects,
        cohort=conn.cohort,
        matrices={
            subject if subject else '_average': instance_to_model(conn.get_matrix(subject), detail=detail, **kwargs)
        } if detail else None
    )

tabular

tabular_to_model(tabular, detail=False, super_model_dict={}, **kwargs)

Fallback serialization of Tabular feature

As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of Tabular (Feature), and passed to this function as super_model_dict. User should not supply their own super_model_dict kwarg, as it will be ignored.

Parameters:

Name Type Description Default
tabular Tabular

instance of tabular data

required
detail str

detail flag. If unset, will not populate data attribute

False

Returns:

Type Description
SiibraTabularModel

SiibraTabularModel

Source code in api/serialization/features/_basetypes/tabular.py
@serialize(Tabular, pass_super_model=True)
def tabular_to_model(tabular: Tabular, detail: str=False, super_model_dict={}, **kwargs) -> SiibraTabularModel:
    """Fallback serialization of Tabular feature

    As serialize.pass_super_model is set to true, the instance will first be serialized according to its superclass of Tabular (Feature),
    and passed to this function as super_model_dict. User **should** not supply their own `super_model_dict` kwarg, as it will be ignored.

    Args:
        tabular: instance of tabular data
        detail: detail flag. If unset, will not populate `data` attribute

    Returns:
        SiibraTabularModel
    """
    return SiibraTabularModel(
        **super_model_dict,
        data=instance_to_model(tabular.data, detail=detail, **kwargs) if detail else None
    )

volume_of_interest

voi_to_model(feat, **kwargs)

Serialize siibra Image instance

Serializing Image instance turns out to be rather complex, so doing it manually.

Parameters:

Name Type Description Default
feat Image

instance of siibra Image

required

Returns:

Type Description
SiibraVoiModel

SiibraVoiModel

Source code in api/serialization/features/_basetypes/volume_of_interest.py
@serialize(Image, pass_super_model=False)
def voi_to_model(feat: Image, **kwargs) -> SiibraVoiModel:
    """Serialize siibra Image instance

    Serializing Image instance turns out to be rather complex, so doing it manually.

    Args:
        feat: instance of siibra Image

    Returns:
        SiibraVoiModel"""
    feature_super_model = instance_to_model(feat, use_class=Feature)
    volume_super_model = instance_to_model(feat, use_class=Volume)

    feature_dict = feature_super_model.dict()
    feature_dict.pop("@type", None)
    return SiibraVoiModel(
        **feature_dict,
        volume=volume_super_model,
        boundingbox=instance_to_model(feat.boundingbox),
    )

anchor

assignment_to_model(asgmt, detail=False, **kwargs)

Serialize AnatommicalAssignment instance

Parameters:

Name Type Description Default
asgmt AnatomicalAssignment

siibra AnatomicalAssignment instance

required
detail bool

detail flag.

False

Returns:

Type Description
SiibraAnatomicalAssignmentModel

SiibraAnatomicalAssignmentModel

Source code in api/serialization/features/anchor.py
@serialize(AnatomicalAssignment)
def assignment_to_model(asgmt: AnatomicalAssignment, detail: bool=False, **kwargs) -> SiibraAnatomicalAssignmentModel:
    """Serialize AnatommicalAssignment instance

    Args:
        asgmt: siibra AnatomicalAssignment instance
        detail: detail flag.

    Returns:
        SiibraAnatomicalAssignmentModel

    """
    return SiibraAnatomicalAssignmentModel(
        query_structure=instance_to_model(asgmt.query_structure, detail=detail, **kwargs),
        assigned_structure=instance_to_model(asgmt.assigned_structure, detail=detail, **kwargs),
        qualification=asgmt.qualification.name,
        explanation=asgmt.explanation,
    )

dataset

ebrains

ebrains_datafeature_to_model(feat, detail=False, super_model_dict={}, **kwargs)

Serialize instance of EbrainsDataFeature

Parameters:

Name Type Description Default
feat EbrainsDataFeature

instance of EbrainsDataFeature

required
detail str

detail flag. If unset, datasets attribute will be an empty array

False

Returns:

Type Description
SiibraEbrainsDataFeatureModel

SiibraEbrainsDataFeatureModel

Source code in api/serialization/features/dataset/ebrains.py
@serialize(EbrainsDataFeature, pass_super_model=True)
def ebrains_datafeature_to_model(feat: EbrainsDataFeature, detail: str=False, super_model_dict={}, **kwargs) -> SiibraEbrainsDataFeatureModel:
    """Serialize instance of EbrainsDataFeature

    Args:
        feat: instance of EbrainsDataFeature
        detail: detail flag. If unset, `datasets` attribute will be an empty array

    Returns:
        SiibraEbrainsDataFeatureModel
    """
    return SiibraEbrainsDataFeatureModel(**super_model_dict)

molecular

gene_expression

receptor_density_fingerprint

locations

boundingbox

boundingbox_to_model(bbox, super_model_dict={}, **kwargs)

Serialize BoundingBox instance

Parameters:

Name Type Description Default
bbox BoundingBox

instance of bounding box

required

Returns:

Type Description
BoundingBoxModel

BoundingBoxModel

Source code in api/serialization/locations/boundingbox.py
@serialize(BoundingBox, pass_super_model=True)
def boundingbox_to_model(bbox: BoundingBox, super_model_dict={}, **kwargs) -> BoundingBoxModel:
    """Serialize BoundingBox instance

    Args:
        bbox: instance of bounding box

    Returns:
        BoundingBoxModel
    """
    return BoundingBoxModel(
        **super_model_dict,
        id=bbox.id,
        center=instance_to_model(bbox.center, **kwargs),
        minpoint=instance_to_model(bbox.minpoint, **kwargs),
        maxpoint=instance_to_model(bbox.maxpoint, **kwargs),
        shape=bbox.shape,
        is_planar=bbox.is_planar,
    )

location

location_to_model(location, **kwargs)

Fallback serialization of Location instance

Parameters:

Name Type Description Default
location Location

location instance

required

Returns: LocationModel

Source code in api/serialization/locations/location.py
@serialize(Location)
def location_to_model(location: Location, **kwargs) -> LocationModel:
    """Fallback serialization of Location instance

    Args:
        location: location instance
    Returns:
        LocationModel
    """
    return LocationModel(
        space={ "@id": location.space.id }
    )

point

point_to_model(point, **kwargs)

Serialization of Point instance

Parameters:

Name Type Description Default
point Point

Point instance to be serialized

required

Returns:

Type Description
CoordinatePointModel

CoordinatePointModel

Raises:

Type Description
InvalidParameters

if point does not have space defined

Source code in api/serialization/locations/point.py
@serialize(Point)
def point_to_model(point: Point, **kwargs) -> CoordinatePointModel:
    """Serialization of Point instance

    Args:
        point: Point instance to be serialized

    Returns:
        CoordinatePointModel

    Raises:
        InvalidParameters: if point does not have space defined"""
    if point.space is None:
        raise InvalidParameters(
            "Point.to_model cannot be done on Location entity that does not have space defined!"
        )
    space_id = point.space.id

    return CoordinatePointModel(
        id=point.id,
        coordinate_space={"@id": space_id},
        coordinates=[QuantitativeValueModel(value=coord) for coord in point],
    )

util

instance_to_model(instance, *, use_class=None, skip_classes=[], **kwargs)

Serialize instance into model, according to register.

Parameters:

Name Type Description Default
instance Any

instance to be serialized

required
use_class Type

use registered method for this specific class for serialization

None
skip_classes List[Type]

skip registered method for these classes

[]
kwargs Dict[str, Any]

keyword arguements to be passed to downstream instance_to_model calls

{}
Return

Serialized intances

Raises:

Type Description
ClsNotRegisteredException

if use_class is provided and use_class is not registered

ClsNotRegisteredException

if no suitable serialization can be found for instance.__class__

NonStrKeyException

if instance contains a dictionary, which do not have str as keys

Source code in api/serialization/util/__init__.py
def instance_to_model(instance: Any, * , use_class: Type=None, skip_classes: List[Type]=[], **kwargs: Dict[str, Any]):
    """Serialize instance into model, according to register.

    Args:
        instance: instance to be serialized
        use_class: use registered method for this specific class for serialization
        skip_classes: skip registered method for these classes
        kwargs: keyword arguements to be passed to downstream instance_to_model calls

    Return:
        Serialized intances

    Raises:
        ClsNotRegisteredException: if `use_class` is provided and use_class is not registered
        ClsNotRegisteredException: if no suitable serialization can be found for `instance.__class__`
        NonStrKeyException: if instance contains a dictionary, which do not have str as keys
    """
    if is_generic_instance(instance):
        if use_class:
            assert use_class == instance.__orig_class__, f"instance {str(instance)} is a instance of generic type. use_class must == instance.__orig_class__"
        use_class = instance.__orig_class__
    if use_class:
        use_class = sanitize_cls(use_class)
        if use_class not in REGISTER:
            raise ClsNotRegisteredException(f"class {str(use_class)} not in register")
        return REGISTER[use_class](instance, **kwargs)

    if instance is None:
        return None
    if isinstance(instance, (str, int, float)):
        return instance
    if isinstance(instance, (list, tuple)):
        return [instance_to_model(item) for item in instance]
    if isinstance(instance, dict):
        if not all([isinstance(key, str) for key in instance]):
            raise NonStrKeyException(f"Attempting to serialize dict with non str keys! {instance}")
        return {
            key: instance_to_model(value)
            for key, value in instance.items()
        }
    for Cls in instance.__class__.__mro__:
        if Cls in REGISTER:
            if Cls in skip_classes or any(issubclass(Cls, SkipCls) for SkipCls in skip_classes):
                continue
            return REGISTER[Cls](instance, **kwargs)
    raise ClsNotRegisteredException(f"class {instance.__class__}  has not been registered to be serialized!")

serialize(Cls, pass_super_model=False, **kwargs)

Decorator function. Wrapping and registering serialization strategies.

Parameters:

Name Type Description Default
Cls Type[Any]

Class to be serialized

required
pass_super_model Dict[str, Any]

flag if the serialized super class should be provided via super_model_dict

False
Source code in api/serialization/util/__init__.py
def serialize(Cls: Type[Any], pass_super_model: Dict[str, Any]=False, **kwargs):
    """Decorator function. Wrapping and registering serialization strategies.

    Args:
        Cls: Class to be serialized
        pass_super_model: flag if the serialized super class should be provided via `super_model_dict`
    """
    Cls = sanitize_cls(Cls)
    def outer(func: Callable):
        # TODO need to arrange the iteration from most specific to most generic
        def _func(*args, **kwargs):
            super_model = instance_to_model(*args, **kwargs, skip_classes=(Cls,))

            super_model_dict = super_model.dict()
            super_model_dict.pop("@type", None)
            return func(*args, **kwargs, super_model_dict=super_model_dict)

        real_func = _func if pass_super_model else func

        REGISTER[Cls] = real_func

        @wraps(func)
        def inner(*args, **kwargs):
            return real_func(*args, **kwargs)
        return inner
    return outer

siibra

This module serves as the single import point of all siibra dependencies.

If siibra paths changes in the future, they only need to be updated here.

volumes

parcellationmap

map_to_model(map, super_model_dict={}, **kwargs)

Serialize map instance

Parameters:

Name Type Description Default
map Map

Map instance

required

Returns:

Type Description
MapModel

MapModel

Source code in api/serialization/volumes/parcellationmap.py
@serialize(Map, pass_super_model=True)
def map_to_model(map: Map, super_model_dict={}, **kwargs) -> MapModel:
    """Serialize map instance

    Args:
        map: Map instance

    Returns:
        MapModel
    """
    return MapModel(
        **super_model_dict,
        species=str(map.species),
        indices={
            regionname: instance_to_model(mapindex, **kwargs)
            for regionname, mapindex in map._indices.items()
        },
        volumes=[instance_to_model(v, **kwargs) for v in map.volumes],
        # affine=map.affine.tolist()
    )

volume

remap_provider(obj)

Mutate and remap providers.

n.b. will mutate provided dictionary. Use copy.copy to avoid unexpected behaviors

Parameters:

Name Type Description Default
obj Dict[str, Union[dict, str]]

provider dictionary to be mutated

required

Returns:

Type Description
None

None

Source code in api/serialization/volumes/volume.py
def remap_provider(obj: Dict[str, Union[dict, str]]) -> None:
    """Mutate and remap providers.

    n.b. will mutate provided dictionary. Use copy.copy to avoid unexpected behaviors

    Args:
        obj: provider dictionary to be mutated

    Returns:
        None
    """
    if len(SIIBRA_API_REMAP_PROVIDERS) == 0:
        return obj
    for key, value in obj.items():
        if isinstance(value, str):
            for from_host, to_host in SIIBRA_API_REMAP_PROVIDERS.items():
                obj[key] = value.replace(from_host, to_host)
        if isinstance(value, dict):
            remap_provider(value)

volume_to_model(vol, **kwargs)

Serialize Volume instance.

If SIIBRA_API_REMAP_PROVIDERS is provided in config, will remap the provider URLs accordingly.

Parameters:

Name Type Description Default
vol Volume

Volume instance

required

Returns:

Type Description
VolumeModel

VolumeModel

Source code in api/serialization/volumes/volume.py
@serialize(Volume)
def volume_to_model(vol: Volume, **kwargs) -> VolumeModel:
    """Serialize Volume instance.

    If `SIIBRA_API_REMAP_PROVIDERS` is provided in config, will remap the provider URLs accordingly.

    Args:
        vol: Volume instance

    Returns:
        VolumeModel
    """
    copied_prov = copy.copy(vol.providers)
    remap_provider(copied_prov)

    return VolumeModel(
        name=str(vol.name),
        formats=list(vol.formats),
        provides_mesh=vol.provides_mesh,
        provides_image=vol.provides_image,
        fragments=vol.fragments,
        variant=vol.variant,
        provided_volumes=copied_prov,
        space=SiibraAtIdModel(id=vol.space.id),
        datasets=instance_to_model(vol.datasets, **kwargs)
    )