def test_paint_point(): # fmt: off img = Array5D(numpy.asarray([ [[100, 0, 0, 100], [ 0, 17, 0, 0], [ 0, 0, 17, 0], [ 0, 0, 0, 0]], [[200, 0, 0, 200], [ 0, 40, 0, 0], [ 0, 0, 40, 0], [ 0, 0, 0, 0]] ]), axiskeys="cyx") # fmt: on # fmt: off expected_painted = Array5D( numpy.asarray( [ [[107, 0, 0, 100], [0, 17, 0, 0], [0, 0, 17, 0], [0, 0, 0, 0]], [[200, 0, 0, 200], [0, 40, 123, 0], [0, 0, 40, 0], [0, 0, 0, 0]], ] ), axiskeys="cyx", ) # fmt: on img.paint_point(Point5D.zero(c=0, y=0, x=0), value=107) img.paint_point(Point5D.zero(c=1, y=1, x=2), value=123) assert img == expected_painted
def test_h5_datasource(): data_2d = Array5D(np.arange(100).reshape(10, 10), axiskeys="yx") h5_path = create_h5(data_2d, axiskeys_style="vigra", chunk_shape=Shape5D(x=3, y=3)) ds = H5DataSource(outer_path=h5_path, inner_path=PurePosixPath("/data"), filesystem=OsFs("/")) assert ds.shape == data_2d.shape assert ds.tile_shape == Shape5D(x=3, y=3) slc = ds.interval.updated(x=(0, 3), y=(0, 2)) assert (ds.retrieve(slc).raw("yx") == data_2d.cut(slc).raw("yx") ).all() #type: ignore data_3d = Array5D(np.arange(10 * 10 * 10).reshape(10, 10, 10), axiskeys="zyx") h5_path = create_h5(data_3d, axiskeys_style="vigra", chunk_shape=Shape5D(x=3, y=3)) ds = H5DataSource(outer_path=h5_path, inner_path=PurePosixPath("/data"), filesystem=OsFs("/")) assert ds.shape == data_3d.shape assert ds.tile_shape == Shape5D(x=3, y=3) slc = ds.interval.updated(x=(0, 3), y=(0, 2), z=3) assert (ds.retrieve(slc).raw("yxz") == data_3d.cut(slc).raw("yxz") ).all() #type: ignore
def test_color_filter(): # fmt: off arr = Array5D(numpy.asarray([ [[100, 20, 30, 100], [ 11, 21, 31, 41], [ 12, 22, 32, 42], [ 13, 23, 33, 43]], [[200, 24, 34, 200], [ 15, 25, 35, 45], [ 16, 26, 36, 46], [ 17, 27, 37, 47]] ]), axiskeys="cyx") color = Array5D(numpy.asarray([100, 200]), axiskeys="c") expected_color_filtered = Array5D(numpy.asarray([ [[100, 0, 0, 100], [ 0, 0, 0, 0], [ 0, 0, 0, 0], [ 0, 0, 0, 0]], [[200, 0, 0, 200], [ 0, 0, 0, 0], [ 0, 0, 0, 0], [ 0, 0, 0, 0]] ]), axiskeys="cyx") # fmt: on filtered = arr.color_filtered(color=color) assert filtered == expected_color_filtered
def test_connected_components(): # fmt: off arr = Array5D(numpy.asarray([ [7, 7, 0, 0, 0, 0], [7, 7, 0, 0, 0, 0], [7, 0, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0], [0, 0, 3, 3, 3, 0], [0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]), axiskeys="yx") expected = Array5D(numpy.asarray([ [1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [0, 0, 0, 2, 0, 0], [0, 0, 2, 2, 2, 0], [0, 0, 0, 2, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]), axiskeys="yx") # fmt: on labeled = arr.connected_components() assert (labeled.raw("yx") == expected.raw("yx")).all()
def test_sample_channels(): # fmt: off arr = Array5D( numpy.asarray([ [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]], [[-1, -2, -3, -4, -5], [-6, -7, -8, -9, -10], [-11, -12, -13, -14, -15], [-16, -17, -18, -19, -20]], [[10, 20, 30, 40, 50], [11, 21, 31, 41, 51], [12, 22, 32, 42, 52], [13, 23, 33, 43, 53]], ]), "cyx") mask = Array5D( numpy.asarray([ [1, 1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1, 1, 1], ]), "yx").as_mask() expected_raw_samples = numpy.asarray([[1, -1, 10], [2, -2, 20], [3, -3, 30], [8, -8, 31], [13, -13, 32], [18, -18, 33], [19, -19, 43], [20, -20, 53]]) # fmt: on samples = arr.sample_channels(mask) assert (samples.linear_raw() == expected_raw_samples).all()
def to_z_slice_pngs(self) -> Iterator[io.BytesIO]: for z_slice in self.split(self.shape.updated(z=1)): print(f"\nz_slice: {z_slice}") rendered_rgb = Array5D.allocate(z_slice.shape.updated(c=3), dtype=np.dtype("float32"), value=0) rendered_rgb_yxc = rendered_rgb.raw("yxc") for prediction_channel, color in zip( z_slice.split(z_slice.shape.updated(c=1)), self.channel_colors): print(f"\nprediction_channel: {prediction_channel}") class_rgb = Array5D(np.ones( prediction_channel.shape.updated(c=3).to_tuple("yxc")), axiskeys="yxc") class_rgb.raw("yxc")[...] *= np.asarray( [color.r, color.g, color.b]) * (color.a / 255) class_rgb.raw("cyx")[...] *= prediction_channel.raw("yx") rendered_rgb_yxc += class_rgb.raw("yxc") out_image = PIL.Image.fromarray( rendered_rgb.raw("yxc").astype(np.uint8)) # type: ignore out_file = io.BytesIO() out_image.save(out_file, "png") out_file.seek(0) yield out_file
def test_unique_colors(): # fmt: off img_c_as_first_axis = Array5D(numpy.asarray([ [[100, 0, 0, 100], [ 0, 17, 0, 0], [ 0, 0, 17, 0], [ 0, 0, 0, 0]], [[200, 0, 0, 200], [ 0, 40, 0, 0], [ 0, 0, 40, 0], [ 0, 0, 0, 0]] ]), axiskeys="cyx") img_c_as_last_axis = Array5D(numpy.asarray([ [[100, 200], [ 0, 0], [ 0, 0], [ 0, 0]], [[100, 200], [ 17, 40], [ 0, 0], [ 0, 0]] ]), axiskeys="yxc") # fmt: on for img in (img_c_as_first_axis, img_c_as_last_axis): unique_colors = [list(color) for color in img.unique_colors().linear_raw()] for expected_color in [[0, 0], [17, 40], [100, 200]]: unique_colors.pop(unique_colors.index(expected_color)) assert len(unique_colors) == 0
def test_combine(): # fmt: off arr = Array5D(numpy.asarray([ [7, 7, 0, 0, 0, 0], [7, 7, 0, 0, 0, 0], [7, 0, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0], [0, 0, 3, 3, 3, 0], [0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 5, 5, 0, 0]]), axiskeys="yx") piece1 = Array5D(numpy.asarray([ [7, 7,], [7, 7,], [7, 0,]]), axiskeys="yx", location=Point5D.zero()) piece2 = Array5D(numpy.asarray([ [0, 3, 0, 0], [3, 3, 3, 0], [0, 3, 0, 0]]), axiskeys="yx", location=Point5D.zero(y=3, x=2)) piece3 = Array5D(numpy.asarray([ [5, 5]]), axiskeys="yx", location=Point5D.zero(y=8, x=2)) # fmt: on combined = piece1.combine([piece2, piece3]) assert (combined.raw("yx") == arr.raw("yx")).all()
def test_allocation(): arr = Array5D.allocate(Slice5D.zero(x=slice(100, 200), y=slice(200, 300)), numpy.uint8) assert arr.shape == Shape5D(x=100, y=100) assert arr.location == Point5D.zero(x=100, y=200) arr = Array5D.allocate(Slice5D.zero(x=slice(-100, 200), y=slice(200, 300)), numpy.uint8) assert arr.shape == Shape5D(x=300, y=100) assert arr.location == Point5D.zero(x=-100, y=200)
def compute(self, roi: Tuple[DataRoi, ConnectedComponentsExtractor]) -> Array5D: """Outputs a Array5D where shape.x is the highest label extracted from the provided DataRoi. Channels are the stacked channels of the features in self.feature_names""" feature_map = self.get_timewise_feature_map(roi) timewise_features = [ Array5D.from_stack(list(frame_features.values()), stack_along="c") for frame_features in feature_map.values() ] return Array5D.from_stack(timewise_features, stack_along="t")
def test_unique_border_colors(): # fmt: off arr = Array5D(numpy.asarray([ [7, 7, 0, 0, 0, 0], [7, 7, 0, 0, 0, 0], [7, 0, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0], [0, 0, 3, 3, 3, 0], [0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 5, 5, 0, 0]]), axiskeys="yx") # fmt: on border_colors = arr.unique_border_colors() assert border_colors.shape == Shape5D(x=len([7, 5, 0])) raw_colors = border_colors.raw("x") assert 7 in raw_colors assert 5 in raw_colors assert 0 in raw_colors # fmt: off arr_zyx = Array5D(numpy.asarray([ [[7, 7, 0, 0, 0, 0], [7, 7, 0, 0, 0, 0], [7, 0, 0, 0, 0, 0], [0, 0, 0, 3, 0, 0], [0, 0, 3, 3, 3, 0], [0, 0, 0, 3, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 5, 5, 0, 0]], [[0, 0, 0, 2, 2, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 9, 0], [0, 0, 0, 0, 9, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]], ]), axiskeys="zyx") # fmt: on # import pydevd; pydevd.settrace() # get borders as if this was two separate plaes, as opposed to a single 3d block border_colors = arr_zyx.unique_border_colors(border_thickness=Shape5D.zero(x=1, y=1)) print("===>>>>>", border_colors.raw("x")) assert border_colors.shape == Shape5D(x=len([7, 5, 0, 2])) raw_colors = border_colors.raw("x") assert 7 in raw_colors assert 5 in raw_colors assert 0 in raw_colors assert 2 in border_colors._data
def test_setting_rois(): # fmt: off raw = numpy.asarray([ [[1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]], [[-1, -2, -3, -4, -5 ], [-6, -7, -8, -9, -10], [-11, -12, -13, -14, -15], [-16, -17, -18, -19, -20]], ]) piece = Array5D(numpy.asarray([ [100, 200], [300, 400] ]), "yx", location=Point5D.zero(x=2, y=1, c=1)) expected_cyx_raw_with_piece = numpy.asarray([ [[1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]], [[-1, -2, -3, -4, -5 ], [-6, -7, 100, 200, -10], [-11, -12, 300, 400, -15], [-16, -17, -18, -19, -20]], ]) extrapolating_piece = Array5D(numpy.asarray([ [111, 222, 333], [444, 555, 6661] ]), "yx", location=Point5D.zero(x=3, y=2, c=0)) expected_cyx_raw_with_extrapolating_piece = numpy.asarray([ [[1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10], [11, 12, 13, 111, 222], [16, 17, 18, 444, 555]], [[-1, -2, -3, -4, -5 ], [-6, -7, 100, 200, -10], [-11, -12, 300, 400, -15], [-16, -17, -18, -19, -20]], ]) # fmt: on arr = Array5D(raw, "cyx") arr.set(piece) assert (arr.raw("cyx") == expected_cyx_raw_with_piece).all() arr.set(extrapolating_piece, autocrop=True) assert (arr.raw("cyx") == expected_cyx_raw_with_extrapolating_piece).all()
def test_raw(): raw = numpy.random.rand(10, 20, 30) arr = Array5D(raw, "xyz") assert raw.shape == (10, 20, 30) assert (arr.raw("xyz") == raw).all() # fmt: off raw2 = numpy.asarray([[1, 2, 3], [4, 5, 6]]) expected_raw2_yx = numpy.asarray([[1, 4], [2, 5], [3, 6]]) raw3 = numpy.asarray([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]) expected_raw3_zxy = numpy.asarray([[[1, 4], [7, 10]], [[2, 5], [8, 11]], [[3, 6], [9, 12]]]) # fmt: on arr2 = Array5D(raw2, "xy") assert (arr2.raw("yx") == expected_raw2_yx).all() arr3 = Array5D(raw3, "xyz") zxy_raw = arr3.raw("zxy") assert (zxy_raw == expected_raw3_zxy).all() # fmt: off zcyx = Array5D(numpy.asarray([[[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]], [[12, 13, 14], [15, 16, 17], [18, 19, 20], [21, 22, 23]]], [[[24, 25, 26], [27, 28, 29], [30, 31, 32], [33, 34, 35]], [[36, 37, 38], [39, 40, 41], [42, 43, 44], [45, 46, 47]]], [[[48, 49, 50], [51, 52, 53], [54, 55, 56], [57, 58, 59]], [[60, 61, 62], [63, 64, 65], [66, 67, 68], [69, 70, 71]]]]), axiskeys="zcyx") expected_raw_xycz = numpy.asarray([[[[0, 24, 48], [12, 36, 60]], [[3, 27, 51], [15, 39, 63]], [[6, 30, 54], [18, 42, 66]], [[9, 33, 57], [21, 45, 69]]], [[[1, 25, 49], [13, 37, 61]], [[4, 28, 52], [16, 40, 64]], [[7, 31, 55], [19, 43, 67]], [[10, 34, 58], [22, 46, 70]]], [[[2, 26, 50], [14, 38, 62]], [[5, 29, 53], [17, 41, 65]], [[8, 32, 56], [20, 44, 68]], [[11, 35, 59], [23, 47, 71]]]]) # fmt: on assert (zcyx.raw("xycz") == expected_raw_xycz).all()
def test_from_stack(): stack = [ Array5D(numpy.asarray([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), axiskeys="yx"), Array5D(numpy.asarray([[7, 2, 2], [3, 1, 5], [2, 7, 3]]), axiskeys="yx"), Array5D(numpy.asarray([[4, 2, 1], [3, 4, 0], [2, 4, 1]]), axiskeys="yx"), ] z_stacked = Array5D.from_stack(stack, stack_along="z") for i in range(len(stack)): assert (z_stacked.cut(Slice5D(z=i)).raw("yx") == stack[i].raw("yx")).all() y_stacked = Array5D.from_stack(stack, stack_along="y") for i in range(len(stack)): stack_slc = Slice5D(y=slice(3 * i, 3 * (i + 1))) assert (y_stacked.cut(stack_slc).raw("yx") == stack[i].raw("yx")).all()
def test_get_borders(): # fmt: off arr = Array5D( numpy.asarray([ [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]], [[-1, -2, -3, -4, -5], [-6, -7, -8, -9, -10], [-11, -12, -13, -14, -15], [-16, -17, -18, -19, -20]], [[10, 20, 30, 40, 50], [11, 21, 31, 41, 51], [12, 22, 32, 42, 52], [13, 23, 33, 43, 53]], ]), "cyx") expected_thin_borders = { "left_border": Array5D( numpy.asarray([ [[1], [6], [11], [16]], [[-1], [-6], [-11], [-16]], [[10], [11], [12], [13]], ]), "cyx"), "top_border": Array5D( numpy.asarray([[[1, 2, 3, 4, 5]], [[-1, -2, -3, -4, -5]], [[10, 20, 30, 40, 50]]]), "cyx"), "right_border": Array5D( numpy.asarray([ [[5], [10], [15], [20]], [[-5], [-10], [-15], [-20]], [[50], [51], [52], [53]], ]), "cyx"), "bottom_border": Array5D( numpy.asarray([ [[16, 17, 18, 19, 20]], [[-16, -17, -18, -19, -20]], [[13, 23, 33, 43, 53]], ]), "cyx") } # fmt: on for border_data in arr.get_borders(thickness=Shape5D.zero(x=1, y=1)): for expected_border in expected_thin_borders.values(): if (border_data.raw("cyx") == expected_border.raw("cyx")).all(): break else: raise Exception( f"Could not find this border in the expected set:\n{border_data.raw('cyx')}" )
def interpolate_from_points(cls, color: Color, voxels: Sequence[Point5D], raw_data: DataSource): start = Point5D.min_coords(voxels) stop = Point5D.max_coords( voxels ) + 1 # +1 because slice.stop is exclusive, but max_point isinclusive scribbling_roi = Interval5D.create_from_start_stop(start=start, stop=stop) if scribbling_roi.shape.c != 1: raise ValueError( f"Annotations must not span multiple channels: {voxels}") scribblings = Array5D.allocate(scribbling_roi, dtype=np.dtype(bool), value=False) anchor = voxels[0] for voxel in voxels: for interp_voxel in anchor.interpolate_until(voxel): scribblings.paint_point(point=interp_voxel, value=True) anchor = voxel return cls(scribblings._data, axiskeys=scribblings.axiskeys, color=color, raw_data=raw_data, location=start)
def from_json_value(cls, data: JsonValue) -> "Annotation": data_dict = ensureJsonObject(data) raw_voxels = ensureJsonArray(data_dict.get("voxels")) voxels: Sequence[Point5D] = [ Point5D.from_json_value(raw_voxel) for raw_voxel in raw_voxels ] color = Color.from_json_data(data_dict.get("color")) raw_data = DataSource.from_json_value(data_dict.get("raw_data")) start = Point5D.min_coords(voxels) stop = Point5D.max_coords( voxels ) + 1 # +1 because slice.stop is exclusive, but max_point isinclusive scribbling_roi = Interval5D.create_from_start_stop(start=start, stop=stop) if scribbling_roi.shape.c != 1: raise ValueError( f"Annotations must not span multiple channels: {voxels}") scribblings = Array5D.allocate(scribbling_roi, dtype=np.dtype(bool), value=False) for voxel in voxels: scribblings.paint_point(point=voxel, value=True) return cls(scribblings._data, axiskeys=scribblings.axiskeys, color=color, raw_data=raw_data, location=start)
def create_h5(array: Array5D, axiskeys_style: str, chunk_shape: Optional[Shape5D] = None, axiskeys: str = "xyztc"): raw_chunk_shape = (chunk_shape or Shape5D() * 2).clamped( maximum=array.shape).to_tuple(axiskeys) path = tempfile.mkstemp()[1] + ".h5" f = h5py.File(path, "w") ds = f.create_dataset("data", chunks=raw_chunk_shape, data=array.raw(axiskeys)) if axiskeys_style == "dims": for key, dim in zip(axiskeys, ds.dims): # type: ignore dim.label = key elif axiskeys_style == "vigra": type_flags = {"x": 2, "y": 2, "z": 2, "t": 2, "c": 1} axistags = [{ "key": key, "typeflags": type_flags[key], "resolution": 0, "description": "" } for key in axiskeys] ds.attrs["axistags"] = json.dumps({"axes": axistags}) else: raise Exception(f"Bad axiskeys_style: {axiskeys_style}") return Path(path)
def test_writing_to_offset_precomputed_chunks(tmp_path: Path, data: Array5D): datasource = ArrayDataSource.from_array5d(data, tile_shape=Shape5D(x=10, y=10), location=Point5D(x=1000, y=1000)) scale = PrecomputedChunksScale.from_datasource(datasource=datasource, key=Path("my_test_data"), encoding=RawEncoder()) sink_path = Path("mytest.precomputed") filesystem = OsFs(tmp_path.as_posix()) info = PrecomputedChunksInfo( data_type=datasource.dtype, type_="image", num_channels=datasource.shape.c, scales=tuple([scale]), ) datasink = PrecomputedChunksSink.create( filesystem=filesystem, base_path=sink_path, info=info, ).scale_sinks[0] for tile in datasource.roi.get_datasource_tiles(): datasink.write(tile.retrieve()) precomp_datasource = PrecomputedChunksDataSource( path=sink_path, filesystem=filesystem, resolution=scale.resolution) reloaded_data = precomp_datasource.retrieve() assert (reloaded_data.raw("xyz") == data.raw("xyz")).all() # type: ignore
def _do_predict(self, roi: DataRoi) -> Predictions: feature_data = self.feature_extractor.compute(roi) predictions = Array5D.allocate( interval=self.get_expected_roi(roi), dtype=np.dtype('float32'), value=0, ) assert predictions.interval == self.get_expected_roi(roi) raw_linear_predictions: np.ndarray = predictions.linear_raw() def do_predict(forest: VigraRandomForest): return forest.predictProbabilities( feature_data.linear_raw()) * forest.treeCount() with ThreadPoolExecutor(max_workers=len(self.forests), thread_name_prefix="predictor") as executor: for forest_predictions in executor.map(do_predict, self.forests): raw_linear_predictions += forest_predictions raw_linear_predictions /= self.num_trees predictions.setflags(write=False) return Predictions( arr=predictions.raw(predictions.axiskeys), axiskeys=predictions.axiskeys, location=predictions.location, channel_colors=Color.sort(self.color_map.keys()), )
def test_cut(): # fmt: off raw = numpy.asarray([ [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], ]) expected_piece = numpy.asarray([ [2, 3], [7, 8], [12, 13], [17, 18] ]) expected_global_sub_piece = numpy.asarray([ [3], [8], [13], [18] ]) # fmt: on arr = Array5D(raw, "zy") piece = arr.cut(Slice5D(y=slice(1, 3))) assert (piece.raw("zy") == expected_piece).all() assert piece.location == Point5D.zero(y=1) global_sub_piece = piece.cut(Slice5D(y=2)) assert (global_sub_piece.raw("zy") == expected_global_sub_piece).all() local_sub_piece = piece.local_cut(Slice5D(y=1)) assert (local_sub_piece.raw("zy") == global_sub_piece.raw("zy")).all()
def test_h5_datasource(): data_2d = Array5D(np.arange(100).reshape(10, 10), axiskeys="yx") h5_path = create_h5(data_2d, axiskeys_style="vigra", chunk_shape=Shape5D(x=3, y=3)) ds = DataSource.create(h5_path) assert ds.shape == data_2d.shape assert ds.tile_shape == Shape5D(x=3, y=3) slc = Slice5D(x=slice(0, 3), y=slice(0, 2)) assert (ds.retrieve(slc).raw("yx") == data_2d.cut(slc).raw("yx")).all() data_3d = Array5D(np.arange(10 * 10 * 10).reshape(10, 10, 10), axiskeys="zyx") h5_path = create_h5(data_3d, axiskeys_style="vigra", chunk_shape=Shape5D(x=3, y=3)) ds = DataSource.create(h5_path) assert ds.shape == data_3d.shape assert ds.tile_shape == Shape5D(x=3, y=3) slc = Slice5D(x=slice(0, 3), y=slice(0, 2), z=3) assert (ds.retrieve(slc).raw("yxz") == data_3d.cut(slc).raw("yxz")).all()
def from_array5d(cls, arr: Array5D, *, tile_shape: Optional[Shape5D] = None, location: Point5D = Point5D.zero()): return cls(data=arr.raw(Point5D.LABELS), axiskeys=Point5D.LABELS, location=location, tile_shape=tile_shape)
def merge(annotations: Sequence["Annotation"], color_map: Optional[Dict[Color, np.uint8]] = None) -> Array5D: out_roi = Interval5D.enclosing(annot.interval for annot in annotations) out = Array5D.allocate(interval=out_roi, value=0, dtype=np.dtype('uint8')) color_map = color_map or Color.create_color_map( annot.color for annot in annotations) for annot in annotations: out.set(annot.colored(color_map[annot.color]), mask_value=0) return out
def _get_tile(self, tile: Slice5D) -> Array5D: slice_address = "_".join( f"{s.start}-{s.stop}" for s in tile.to_slices(self.scale.spatial_axiskeys)) path = self.scale.key + "/" + slice_address with self.filesystem.openbin(path) as f: raw_tile_bytes = f.read() raw_tile_c_shape = tile.shape.to_tuple(self.axiskeys) raw_tile = np.frombuffer(raw_tile_bytes, dtype=self.dtype).reshape(raw_tile_c_shape) tile_5d = Array5D(raw_tile, axiskeys=self.axiskeys) return tile_5d.translated(tile.start)
def test_n5_datasource(): # fmt: off data = Array5D(np.asarray([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]).astype(np.uint8), axiskeys="yx") # fmt: on path = Path(create_n5(data, chunk_size=Shape5D(x=2, y=2))) ds = N5DataSource(path=path / "data", filesystem=OsFs("/")) assert ds.shape == data.shape # fmt: off expected_raw_piece = Array5D(np.asarray([[1, 2, 3], [6, 7, 8]]).astype(np.uint8), axiskeys="yx") # fmt: on assert ds.retrieve(x=(0, 3), y=(0, 2)) == expected_raw_piece ds2 = pickle.loads(pickle.dumps(ds)) assert ds2.retrieve(x=(0, 3), y=(0, 2)) == expected_raw_piece
def compute(self, roi: DataRoi) -> FeatureData: features: List[FeatureData] = [] channel_offset: int = 0 for fx in self.extractors: result = fx.compute(roi).translated(Point5D.zero(c=channel_offset)) features.append(result) channel_offset += result.shape.c out = Array5D.combine(features) return FeatureData( arr=out.raw(out.axiskeys), axiskeys=out.axiskeys, location=out.location )
def test_neighboring_tiles(): # fmt: off arr = Array5D(np.asarray( [[10, 11, 12, 20, 21, 22, 30], [13, 14, 15, 23, 24, 25, 33], [16, 17, 18, 26, 27, 28, 36], [40, 41, 42, 50, 51, 52, 60], [43, 44, 45, 53, 54, 55, 63], [46, 47, 48, 56, 57, 58, 66], [70, 71, 72, 80, 81, 82, 90], [73, 74, 75, 83, 84, 85, 93], [76, 77, 78, 86, 87, 88, 96], [0, 1, 2, 3, 4, 5, 6]], dtype=np.uint8), axiskeys="yx") ds = DataSource.create(create_png(arr)) fifties_slice = DataSourceSlice(ds).clamped( Slice5D(x=slice(3, 6), y=slice(3, 6))) expected_fifties_slice = Array5D(np.asarray([[50, 51, 52], [53, 54, 55], [56, 57, 58]]), axiskeys="yx") # fmt: on top_slice = DataSourceSlice(ds, x=slice(3, 6), y=slice(0, 3)) bottom_slice = DataSourceSlice(ds, x=slice(3, 6), y=slice(6, 9)) right_slice = DataSourceSlice(ds, x=slice(6, 7), y=slice(3, 6)) left_slice = DataSourceSlice(ds, x=slice(0, 3), y=slice(3, 6)) # fmt: off fifties_neighbor_data = { top_slice: Array5D(np.asarray([[20, 21, 22], [23, 24, 25], [26, 27, 28]]), axiskeys="yx"), right_slice: Array5D(np.asarray([[60], [63], [66]]), axiskeys="yx"), bottom_slice: Array5D(np.asarray([[80, 81, 82], [83, 84, 85], [86, 87, 88]]), axiskeys="yx"), left_slice: Array5D(np.asarray([[40, 41, 42], [43, 44, 45], [46, 47, 48]]), axiskeys="yx"), } expected_fifties_neighbors = {} # fmt: on assert (fifties_slice.retrieve().raw("yx") == expected_fifties_slice.raw( "yx")).all() for neighbor in fifties_slice.get_neighboring_tiles( tile_shape=Shape5D(x=3, y=3)): try: expected_slice = fifties_neighbor_data.pop(neighbor) assert (expected_slice.raw("yx") == neighbor.retrieve().raw("yx") ).all() except KeyError: print(f"\nWas searching for ", neighbor, "\n") for k in fifties_neighbor_data.keys(): print("--->>> ", k) assert len(fifties_neighbor_data) == 0
def reshape_datablock_and_slicing_for_input( self, block: numpy.ndarray, slicing: List[slice], slot: OutputSlot, project: Project) -> Tuple[numpy.ndarray, List[slice]]: """Reshapes a block of data and its corresponding slicing into the slot's current shape, so as to be compatible with versions of ilastik that saved and loaded block slots in their original shape Checks for version 1.3.3 and 1.3.3post1 because those were the versions that saved labels in 5D """ current_axiskeys = self.get_input_image_current_axiskeys(slot) saved_data_axiskeys = self.get_saved_data_axiskeys(slot, project) fixed_slicing = Slice5D.zero(**dict(zip( saved_data_axiskeys, slicing))).to_slices(current_axiskeys) fixed_block = Array5D(block, saved_data_axiskeys).raw(current_axiskeys) return fixed_block, fixed_slicing
def reshape_datablock_and_slicing_for_output( self, block: numpy.ndarray, slicing: List[slice], slot: OutputSlot) -> Tuple[numpy.ndarray, List[slice]]: """Reshapes a block of data and its corresponding slicing into the slot's original shape, so as to be compatible with versions of ilastik that saved and loaded block slots in their original shape Always save using original shape to be backwards compatible with 1.3.2 """ original_axiskeys = self.get_input_image_original_axiskeys(slot) current_axiskeys = self.get_input_image_current_axiskeys(slot) fixed_block = Array5D(block, current_axiskeys).raw(original_axiskeys) fixed_slicing = Slice5D.zero(**dict(zip( current_axiskeys, slicing))).to_slices(original_axiskeys) return fixed_block, fixed_slicing