cellmap_flow.portable.carry =========================== .. py:module:: cellmap_flow.portable.carry .. autoapi-nested-parse:: The paint of one annotation volume carried onto another model's grid: the maths of ``carry_paint`` (``finetune/session/volume.py`` says what it is for), on arrays alone, so the server runs it on its zarrs and the browser on its paint store's chunks (``portable/calls.py``). Each new voxel takes the paint of the old voxels whose centres lie inside it (one for a grid as fine as the old, several for a coarser one), or, where none does (a finer grid), the old voxel its own centre lies in. A new voxel whose old voxels were painted different labels is left unpainted, on a boundary the coarser grid cannot draw; unpainted old voxels do not count against it, so a stroke thinner than the new voxel still lands, a voxel wide. Only the boxes of the old volume's painted chunks are visited. Classes ------- .. autoapisummary:: cellmap_flow.portable.carry.Grid Functions --------- .. autoapisummary:: cellmap_flow.portable.carry.axis_sources cellmap_flow.portable.carry.parts cellmap_flow.portable.carry.first_visit cellmap_flow.portable.carry.carry Module Contents --------------- .. py:class:: Grid An annotation volume's grid, z y x: voxel 0's lower corner in nm (not the OME translation, which is its centre: ``volume_corner_nm``), its voxel size in nm, and its shape and chunks in voxels. .. py:attribute:: corner_nm :type: tuple .. py:attribute:: voxel_nm :type: tuple .. py:attribute:: shape :type: tuple .. py:attribute:: chunks :type: tuple .. py:function:: axis_sources(old: Grid, new: Grid, axis: int) Per voxel of ``new`` along ``axis``, the voxels of ``old`` it takes, as ``(first, end)`` arrays (end <= first where none lies in the old volume): those whose centres lie inside it, or, when none does (a finer grid), the one its own centre lies in. .. py:function:: parts(chunks, lo, shape) -> Iterator[Tuple[tuple, tuple, tuple]] The chunks (of ``chunks`` voxels) the box ``lo`` + ``shape`` touches: each one's index, the box's part of it and the chunk's part of the box, both as slices. .. py:function:: first_visit(visited: dict, chunks, lo, shape) -> numpy.ndarray The voxels of the box ``lo`` + ``shape`` not visited before, marking them visited in ``visited`` (a mask per chunk index of ``chunks``). .. py:function:: carry(old: Grid, new: Grid, painted: Iterable[Tuple[tuple, numpy.ndarray]], read: Callable[[list, list], numpy.ndarray], dtype) -> Tuple[Dict[tuple, numpy.ndarray], dict] Carry the paint of the old volume's ``painted`` chunks (each its index and its labels, a whole chunk) onto the new grid. ``read(lo, hi)`` gives the old labels over a box in old voxels (several chunks' worth, for a coarser new grid); ``dtype`` is the new volume's (its labels capped at its maximum). Returns the new chunks that got paint, by index, each whole (0 where the old paint says nothing: the caller writes them over what is there where they are not 0), and the counts ``{"painted", "source", "conflicts", "chunks"}``: the new voxels painted, the old painted voxels they came from, the new voxels left unpainted where their old voxels disagreed, and the new chunks returned.