def get_bounds(vol, bounds, mip, bounds_mip=0, chunk_size=None): """Return bounds of vol at mip, or snap bounds at src_mip to chunk_size Args: vol (CloudVolume) bounds (Bbox-like object) mip (int): mip level of returned bounds bounds_mip (int): mip level of input bounds chunk_size (Vec-like object): if bounds are set, can set chunk_size for snapping Returns: Bbox for bounds """ if bounds is None: bounds = vol.meta.bounds(mip) else: bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=bounds_mip, to_mip=mip) if chunk_size is not None: bounds = bounds.expand_to_chunk_size(chunk_size, vol.meta.voxel_offset(mip)) bounds = Bbox.clamp(bounds, vol.meta.bounds(mip)) print("Volume Bounds: ", vol.meta.bounds(mip)) print("Selected ROI: ", bounds) return bounds
def crop(self, bbox): """ Crop away all vertices and edges that lie outside of the given bbox. The edge counts as inside. Returns: new PrecomputedSkeleton """ skeleton = self.clone() bbox = Bbox.create(bbox) if skeleton.empty(): return skeleton nodes_valid_mask = np.array( [bbox.contains(vtx) for vtx in skeleton.vertices], dtype=np.bool) nodes_valid_idx = np.where(nodes_valid_mask)[0] # Set invalid vertices to be duplicates # so they'll be removed during consolidation if nodes_valid_idx.shape[0] == 0: return PrecomputedSkeleton() first_node = nodes_valid_idx[0] skeleton.vertices[~nodes_valid_mask] = skeleton.vertices[first_node] edges_valid_mask = np.isin(skeleton.edges, nodes_valid_idx) edges_valid_idx = edges_valid_mask[:, 0] * edges_valid_mask[:, 1] skeleton.edges = skeleton.edges[edges_valid_idx, :] return skeleton.consolidate()
def create_blackout_tasks(cloudpath: str, bounds: Bbox, mip: int = 0, shape: ShapeType = (2048, 2048, 64), value: int = 0, non_aligned_writes: bool = False): vol = CloudVolume(cloudpath, mip=mip) shape = Vec(*shape) bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=0, to_mip=mip) if not non_aligned_writes: bounds = bounds.expand_to_chunk_size(vol.chunk_size, vol.voxel_offset) bounds = Bbox.clamp(bounds, vol.mip_bounds(mip)) class BlackoutTaskIterator(FinelyDividedTaskIterator): def task(self, shape, offset): bounded_shape = min2(shape, vol.bounds.maxpt - offset) return partial( igneous.tasks.BlackoutTask, cloudpath=cloudpath, mip=mip, shape=shape.clone(), offset=offset.clone(), value=value, non_aligned_writes=non_aligned_writes, ) def on_finish(self): vol.provenance.processing.append({ 'method': { 'task': 'BlackoutTask', 'cloudpath': cloudpath, 'mip': mip, 'non_aligned_writes': non_aligned_writes, 'value': value, 'shape': shape.tolist(), 'bounds': [ bounds.minpt.tolist(), bounds.maxpt.tolist(), ], }, 'by': operator_contact(), 'date': strftime('%Y-%m-%d %H:%M %Z'), }) return BlackoutTaskIterator(bounds, shape)
def create_blackout_tasks(cloudpath, bounds, mip=0, shape=(2048, 2048, 64), value=0, non_aligned_writes=False): vol = CloudVolume(cloudpath, mip=mip) shape = Vec(*shape) bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=0, to_mip=mip) bounds = Bbox.clamp(bounds, vol.mip_bounds(mip)) class BlackoutTaskIterator(): def __len__(self): return num_tasks(bounds, shape) def __iter__(self): for startpt in xyzrange(bounds.minpt, bounds.maxpt, shape): bounded_shape = min2(shape, vol.bounds.maxpt - startpt) yield igneous.tasks.BlackoutTask( cloudpath=cloudpath, mip=mip, shape=shape.clone(), offset=startpt.clone(), value=value, non_aligned_writes=non_aligned_writes, ) vol.provenance.processing.append({ 'method': { 'task': 'BlackoutTask', 'cloudpath': cloudpath, 'mip': mip, 'non_aligned_writes': non_aligned_writes, 'value': value, 'shape': shape.tolist(), 'bounds': [ bounds.minpt.tolist(), bounds.maxpt.tolist(), ], }, 'by': OPERATOR_CONTACT, 'date': strftime('%Y-%m-%d %H:%M %Z'), }) return BlackoutTaskIterator()
def create_touch_tasks(self, cloudpath, mip=0, shape=(2048, 2048, 64), bounds=None): vol = CloudVolume(cloudpath, mip=mip) shape = Vec(*shape) if bounds is None: bounds = vol.bounds.clone() bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=0, to_mip=mip) bounds = Bbox.clamp(bounds, vol.mip_bounds(mip)) class TouchTaskIterator(): def __len__(self): return num_tasks(bounds, shape) def __iter__(self): for startpt in xyzrange(bounds.minpt, bounds.maxpt, shape): bounded_shape = min2(shape, vol.bounds.maxpt - startpt) yield igneous.tasks.TouchTask( cloudpath=cloudpath, shape=bounded_shape.clone(), offset=startpt.clone(), mip=mip, ) vol.provenance.processing.append({ 'method': { 'task': 'TouchTask', 'mip': mip, 'shape': shape.tolist(), 'bounds': [ bounds.minpt.tolist(), bounds.maxpt.tolist(), ], }, 'by': OPERATOR_CONTACT, 'date': strftime('%Y-%m-%d %H:%M %Z'), }) vol.commit_provenance() return TouchTaskIterator()
def get_bounds(vol, bounds, shape, mip, chunk_size=None): if bounds is None: bounds = vol.bounds.clone() else: bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=0, to_mip=mip) if chunk_size is not None: bounds = bounds.expand_to_chunk_size(chunk_size, vol.mip_voxel_offset(mip)) bounds = Bbox.clamp(bounds, vol.mip_bounds(mip)) print("Volume Bounds: ", vol.mip_bounds(mip)) print("Selected ROI: ", bounds) return bounds
def create_touch_tasks( self, cloudpath, mip=0, shape=(2048, 2048, 64), bounds=None ): vol = CloudVolume(cloudpath, mip=mip) shape = Vec(*shape) if bounds is None: bounds = vol.bounds.clone() bounds = Bbox.create(bounds) bounds = vol.bbox_to_mip(bounds, mip=0, to_mip=mip) bounds = Bbox.clamp(bounds, vol.mip_bounds(mip)) class TouchTaskIterator(FinelyDividedTaskIterator): def task(self, shape, offset): bounded_shape = min2(shape, vol.bounds.maxpt - offset) return igneous.tasks.TouchTask( cloudpath=cloudpath, shape=bounded_shape.clone(), offset=offset.clone(), mip=mip, ) def on_finish(self): vol.provenance.processing.append({ 'method': { 'task': 'TouchTask', 'mip': mip, 'shape': shape.tolist(), 'bounds': [ bounds.minpt.tolist(), bounds.maxpt.tolist(), ], }, 'by': OPERATOR_CONTACT, 'date': strftime('%Y-%m-%d %H:%M %Z'), }) vol.commit_provenance() return TouchTaskIterator(bounds, shape)