def __rasterize(self, points, data_roi, voxel_size, dtype, settings, mask_array=None): '''Rasterize 'points' into an array with the given 'voxel_size''' mask = mask_array.data if mask_array is not None else None logger.debug("Rasterizing points in %s", points.spec.roi) # prepare output array rasterized_points = np.zeros(data_roi.get_shape(), dtype=dtype) # Fast rasterization currently only implemented for mode ball without # inner radius set use_fast_rasterization = ( settings.mode == 'ball' and settings.inner_radius_fraction is None ) if use_fast_rasterization: dims = len(rasterized_points.shape) # get structuring element for mode ball ball_kernel = create_ball_kernel(settings.radius, voxel_size) radius_voxel = Coordinate(np.array(ball_kernel.shape)/2) data_roi_base = Roi( offset=Coordinate((0,)*dims), shape=Coordinate(rasterized_points.shape)) kernel_roi_base = Roi( offset=Coordinate((0,)*dims), shape=Coordinate(ball_kernel.shape)) # Rasterize volume either with single voxel or with defined struct elememt for point in points.data.values(): # get the voxel coordinate, 'Coordinate' ensures integer v = Coordinate(point.location/voxel_size) # get the voxel coordinate relative to output array start v -= data_roi.get_begin() # skip points outside of mask if mask is not None and not mask[v]: continue logger.debug( "Rasterizing point %s at %s", point.location, point.location/voxel_size - data_roi.get_begin()) if use_fast_rasterization: # Calculate where to crop the kernel mask and the rasterized array shifted_kernel = kernel_roi_base.shift(v - radius_voxel) shifted_data = data_roi_base.shift(-(v - radius_voxel)) arr_crop = data_roi_base.intersect(shifted_kernel) kernel_crop = kernel_roi_base.intersect(shifted_data) arr_crop_ind = arr_crop.get_bounding_box() kernel_crop_ind = kernel_crop.get_bounding_box() rasterized_points[arr_crop_ind] = np.logical_or( ball_kernel[kernel_crop_ind], rasterized_points[arr_crop_ind]) else: rasterized_points[v] = 1 # grow points if not use_fast_rasterization: if settings.mode == 'ball': enlarge_binary_map( rasterized_points, settings.radius, voxel_size, 1.0 - settings.inner_radius_fraction, in_place=True) else: sigmas = settings.radius/voxel_size gaussian_filter( rasterized_points, sigmas, output=rasterized_points, mode='constant') # renormalize to have 1 be the highest value max_value = np.max(rasterized_points) if max_value > 0: rasterized_points /= max_value if mask_array is not None: # use more efficient bitwise operation when possible if settings.mode == 'ball': rasterized_points &= mask else: rasterized_points *= mask return rasterized_points
def __rasterize(self, graph, data_roi, voxel_size, dtype, settings, mask_array=None): '''Rasterize 'graph' into an array with the given 'voxel_size''' mask = mask_array.data if mask_array is not None else None logger.debug("Rasterizing graph in %s", graph.spec.roi) # prepare output array rasterized_graph = np.zeros(data_roi.get_shape(), dtype=dtype) # Fast rasterization currently only implemented for mode ball without # inner radius set use_fast_rasterization = ( settings.mode == "ball" and settings.inner_radius_fraction is None and len(list(graph.edges)) == 0 ) if use_fast_rasterization: dims = len(rasterized_graph.shape) # get structuring element for mode ball ball_kernel = create_ball_kernel(settings.radius, voxel_size) radius_voxel = Coordinate(np.array(ball_kernel.shape)/2) data_roi_base = Roi( offset=Coordinate((0,)*dims), shape=Coordinate(rasterized_graph.shape)) kernel_roi_base = Roi( offset=Coordinate((0,)*dims), shape=Coordinate(ball_kernel.shape)) # Rasterize volume either with single voxel or with defined struct elememt for node in graph.nodes: # get the voxel coordinate, 'Coordinate' ensures integer v = Coordinate(node.location/voxel_size) # get the voxel coordinate relative to output array start v -= data_roi.get_begin() # skip graph outside of mask if mask is not None and not mask[v]: continue logger.debug( "Rasterizing node %s at %s", node.location, node.location/voxel_size - data_roi.get_begin()) if use_fast_rasterization: # Calculate where to crop the kernel mask and the rasterized array shifted_kernel = kernel_roi_base.shift(v - radius_voxel) shifted_data = data_roi_base.shift(-(v - radius_voxel)) arr_crop = data_roi_base.intersect(shifted_kernel) kernel_crop = kernel_roi_base.intersect(shifted_data) arr_crop_ind = arr_crop.get_bounding_box() kernel_crop_ind = kernel_crop.get_bounding_box() rasterized_graph[arr_crop_ind] = np.logical_or( ball_kernel[kernel_crop_ind], rasterized_graph[arr_crop_ind] ) else: if settings.color_attr is not None: c = graph.nodes[node].get(settings.color_attr) if c is None: logger.debug(f"Skipping node: {node}") continue elif np.isclose(c, 1) and not np.isclose(settings.fg_value, 1): logger.warning( f"Node {node} is being colored with color {c} according to " f"attribute {settings.color_attr} " f"but color 1 will be replaced with fg_value: {settings.fg_value}" ) else: c = 1 rasterized_graph[v] = c if settings.edges: for e in graph.edges: if settings.color_attr is not None: c = graph.edges[e].get(settings.color_attr) if c is None: continue elif np.isclose(c, 1) and not np.isclose(settings.fg_value, 1): logger.warning( f"Edge {e} is being colored with color {c} according to " f"attribute {settings.color_attr} " f"but color 1 will be replaced with fg_value: {settings.fg_value}" ) u = graph.node(e.u) v = graph.node(e.v) u_coord = Coordinate(u.location / voxel_size) v_coord = Coordinate(v.location / voxel_size) line = draw.line_nd(u_coord, v_coord, endpoint=True) rasterized_graph[line] = 1 # grow graph if not use_fast_rasterization: if settings.mode == "ball": enlarge_binary_map( rasterized_graph, settings.radius, voxel_size, settings.inner_radius_fraction, in_place=True) else: sigmas = settings.radius/voxel_size gaussian_filter( rasterized_graph, sigmas, output=rasterized_graph, mode="constant" ) # renormalize to have 1 be the highest value max_value = np.max(rasterized_graph) if max_value > 0: rasterized_graph /= max_value if mask_array is not None: # use more efficient bitwise operation when possible if settings.mode == "ball": rasterized_graph &= mask else: rasterized_graph *= mask return rasterized_graph