Source code for bsb.topology

"""
Topology module
"""

from ._layout import box_layout
from .partition import AllenStructure, Layer, NrrdVoxels, Partition
from .region import Region, RegionGroup, Stack


[docs] def create_topology(regions, ldc, mdc): """ Create a topology from group of regions. Will check for root regions, if there's not exactly 1 root region a :class:`~.topology.region.RegionGroup` will be created as new root. :param regions: Any iterable of regions. :type regions: Iterable :param ldc: Least dominant corner of the topology. Forms the suggested outer bounds of the topology together with the `mdc`. :param mdc: Most dominant corner of the topology. Forms the suggested outer bounds of the topology together with the `mdc`. """ regions = list(regions) if len(roots := get_root_regions(regions)) == 1: topology = roots[0] else: topology = RegionGroup(children=roots, name="topology") hint = box_layout(ldc, mdc) topology.do_layout(hint) return topology
[docs] def get_partitions(regions): """ Get all of the partitions belonging to the group of regions and their subregions. :param regions: Any iterable of regions. :type regions: Iterable """ def collect_deps(region, ignore): # get_dependencies can be overridden, so `list` it to avoid mutation of userdata deps = list(region.get_dependencies()) regions = [d for d in deps if not is_partition(d)] parts = set(p for p in deps if is_partition(p)) ignore.update(parts) for r in regions: # Only check unchecked regions if r not in ignore: ignore.add(r) parts.update(collect_deps(r, ignore)) return parts partitions = set() for region in regions: partitions.update(p := collect_deps(region, set())) return partitions
[docs] def is_partition(obj): """ Checks if an object is a partition. """ return ( hasattr(obj, "get_layout") and hasattr(obj, "to_chunks") and hasattr(obj, "chunk_to_voxels") )
[docs] def is_region(obj): """ Checks if an object is a region. """ return hasattr(obj, "get_layout") and hasattr(obj, "do_layout")
[docs] def get_root_regions(regions): """ Get all of the root regions, not belonging to any other region in the given group. :param regions: Any iterable of regions. :type regions: Iterable """ managed = set() def collect_deps(region, ignore): # get_dependencies can be overridden, so `list` it to avoid mutation of userdata deps = list(region.get_dependencies()).copy() for dep in deps: # Only check unchecked regions, ignore visited & partitions if dep not in ignore and is_region(dep): ignore.add(dep) extra_deps = collect_deps(dep, ignore) ignore.update(extra_deps) return deps # Give `managed` as the mutable ignore arg so that it is filled with all regionals # encountered as dependencies by the `collect_deps` recursive function. for region in regions: collect_deps(region, managed) return list(set(list(regions)) - managed)
__all__ = [ "box_layout", "create_topology", "get_partitions", "get_root_regions", "is_partition", "is_region", ]