def get_voi(atlas_id: str, space_id: str, boundingbox: Tuple[Tuple[float, float, float], Tuple[float, float, float]]): atlas = validate_and_return_atlas(atlas_id) space = validate_and_return_space(space_id, atlas) bbox = BoundingBox(boundingbox[0], boundingbox[1], space) def serialize_point(point): return [p for p in point] def serialize_voi(voi: VolumeOfInterest): return { "@id": voi.id, "name": voi.name, "description": voi.description, "url": voi.urls, "location": { "space": { "@id": voi.location.space.id }, "center": serialize_point(voi.location.center), "minpoint": serialize_point(voi.location.minpoint), "maxpoint": serialize_point(voi.location.maxpoint), }, "volumes": [vol_src_sans_space(vol) for vol in voi.volumes] } return [ serialize_voi(feat) for feat in all_voi_features if feat.location.space is space and bbox.intersection(feat.location) ]
def get_template_by_space_id(atlas_id: str, space_id: str): """ Returns a template for a given space id. """ atlas = validate_and_return_atlas(atlas_id) space = validate_and_return_space(space_id) template = atlas.get_template(space).fetch() # create file-object in memory # file_object = io.BytesIO() filename = get_file_from_nibabel(template, 'template', space) return FileResponse(filename, filename=filename)
def get_region_by_name(base_url: str, atlas_id: str, parcellation_id: str, region_id: str, space_id: str = None): """ Returns a specific region for a given id. """ atlas = siibra.atlases[atlas_id] parcellation = atlas.get_parcellation(parcellation_id) try: region = validate_and_return_region(region_id, parcellation) except ValueError: raise HTTPException(404, 'Region spec {region_id} cannot be decoded') if space_id: space = validate_and_return_space(space_id) region_json = region_encoder(region, space=space) region_json['props'] = get_region_props(space_id, atlas, region) region_json['hasRegionalMap'] = region.has_regional_map( space, siibra.commons.MapType.CONTINUOUS) region_json['_dataset_specs'] = [ spec for spec in region_json['_dataset_specs'] if spec.get('@type') != 'minds/core/dataset/v1.0.0' ] for ds in [ ds for ds in region.datasets if type(ds) == siibra.core.datasets.EbrainsDataset ]: region_json['_dataset_specs'].append( jsonable_encoder(ds, custom_encoder=siibra_custom_json_encoder)) else: region_json = region_encoder(region) single_region_root_url = '{}atlases/{}/parcellations/{}/regions/{}'.format( base_url, quote(atlas_id), quote(parcellation_id), quote(region_id)) region_json['links'] = { 'features': f'{single_region_root_url}/features', 'regional_map_info': f'{single_region_root_url}/regional_map/info?space_id={space_id}' if region_json.get('hasRegionalMap') else None, 'regional_map': f'{single_region_root_url}/regional_map/map?space_id={space_id}' if region_json.get('hasRegionalMap') else None, } return region_json
def get_all_regions_for_parcellation_id(atlas_id: str, parcellation_id: str, space_id: Optional[str] = None): """ Returns all regions for a given parcellation id. """ parcellation = validate_and_return_parcellation(parcellation_id) if not space_id is None: space = validate_and_return_space(space_id) else: space = None return [ region_encoder(region, space=space) for region in parcellation.regiontree.children ]
def get_parcellation_map_for_space(atlas_id: str, space_id: str): """ Returns all parcellation maps for a given space id. """ validate_and_return_atlas(atlas_id) space = validate_and_return_space(space_id) valid_parcs = [p for p in siibra.parcellations if p.supports_space(space)] if len(valid_parcs) == 1: maps = [valid_parcs[0].get_map(space)] filename = get_file_from_nibabel(maps[0], 'maps', space) return FileResponse(filename, filename=filename) else: raise HTTPException( status_code=501, detail= f'space with id {space_id} has multiple parc, not yet implemented') maps = [p.get_map(space) for p in valid_parcs] files = [] mem_zip = io.BytesIO() label_index = 0 for map in maps: files.append( get_file_from_nibabel(map, 'map-{}'.format(label_index), space)) label_index = label_index + 1 with zipfile.ZipFile(mem_zip, mode="w", compression=zipfile.ZIP_DEFLATED) as zf: for f in files: zf.write(f) print(zf.namelist()) mem_zip.seek(0) response = StreamingResponse(iter([mem_zip.getvalue()]), media_type="application/x-zip-compressed") response.headers[ "Content-Disposition"] = 'attachment; filename=maps-{}.zip'.format( space.name.replace(' ', '_')) return response raise HTTPException( status_code=404, detail='Maps for space with id: {} not found'.format(space_id))
def parse_region_selection(atlas_id: str, parcellation_id: str, region_id: str, space_id: str): if space_id is None: raise HTTPException( status_code=400, detail='space_id is required for this functionality') space_of_interest = validate_and_return_space(space_id) validate_and_return_atlas(atlas_id) parcellation = validate_and_return_parcellation(parcellation_id) region = validate_and_return_region(region_id, parcellation) if region is None: raise HTTPException(status_code=404, detail=f'cannot find region with spec {region_id}') # if len(region) > 1: # raise HTTPException( # status_code=400, # detail=f'found multiple region withs pec {region_id}') return region, space_of_interest
def get_spatial_feature_names(atlas_id: str, space_id: str, request: Request): """ Return all possible feature names and links to get more details """ validate_and_return_atlas(atlas_id) space = validate_and_return_space(space_id) # TODO: Getting all features with result takes to much time at the moment # features = siibra.get_features(space, 'all') return { 'features': [{ feature.modality(): '{}atlases/{}/spaces/{}/features/{}'.format( get_base_url_from_request(request), atlas_id.replace('/', '%2F'), space_id.replace('/', '%2F'), quote(feature.modality())) for feature in siibra.features.modalities if issubclass( feature._FEATURETYPE, siibra.features.feature.SpatialFeature) }] }
def get_one_space_by_id(atlas_id: str, space_id: str, request: Request): """ Returns one space for given id, with links to further resources """ validate_and_return_atlas(atlas_id) space = validate_and_return_space(space_id) if space: json_result = jsonable_encoder( space, custom_encoder=siibra_custom_json_encoder) # TODO: Error on first call json_result['availableParcellations'] = get_parcellations_for_space( space) json_result['links'] = { 'templates': { 'href': '{}atlases/{}/spaces/{}/templates'.format( get_base_url_from_request(request), atlas_id.replace('/', '%2F'), space.id.replace('/', '%2F')) }, 'parcellation_maps': { 'href': '{}atlases/{}/spaces/{}/parcellation_maps'.format( get_base_url_from_request(request), atlas_id.replace('/', '%2F'), space.id.replace('/', '%2F')) }, 'features': { 'href': '{}atlases/{}/spaces/{}/features'.format( get_base_url_from_request(request), atlas_id.replace('/', '%2F'), space.id.replace('/', '%2F')) } } if hasattr(space, 'origin_datainfos'): json_result['originDatainfos'] = [ origin_data_decoder(datainfo) for datainfo in space.origin_datainfos ] return json_result else: raise HTTPException( status_code=404, detail='space with id: {} not found'.format(space_id))
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]