Beispiel #1
0
    def it_can_remap_negative_level_indices(self, level, expected_value,
                                            levels_prop):
        levels_prop.return_value = [0, 1, 2, 3, 4, 5, 6, 7, 8]

        slide = Slide("path", "processed")

        assert slide._remap_level(level) == expected_value
Beispiel #2
0
    def it_can_resample_itself(self, tmpdir, resampled_dims_):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")
        resampled_dims_.return_value = (100, 200, 300, 400)

        _resample = slide._resample(32)

        # image array assertions
        assert type(_resample[1]) == np.ndarray
        # ---The np array shape should be (new_h X new_w X channels),---
        # ---in this case (look at resampled_dims mock) the new_h is 400---
        # ---the new_w is 300 and the color channels of the image are 3---
        assert _resample[1].shape == (400, 300, 3)
        # ---Here we prove that the 3 channels are compliant with the color---
        # ---definition and that each channel is a np.array (400x300) filled---
        # ---with the related color expressed during the image creation---
        np.testing.assert_almost_equal(_resample[1][:, :, 0],
                                       np.full((400, 300), 155))
        np.testing.assert_almost_equal(_resample[1][:, :, 1],
                                       np.full((400, 300), 249))
        np.testing.assert_almost_equal(_resample[1][:, :, 2],
                                       np.full((400, 300), 240))
        # PIL image assertions
        assert type(_resample[0]) == PIL.Image.Image
        assert _resample[0].size == (300, 400)
        assert _resample[0].width == 300
        assert _resample[0].height == 400
        assert _resample[0].mode == "RGB"
Beispiel #3
0
    def it_knows_its_region_coordinates(self):
        region = Region(index=0, area=14, bbox=(0, 1, 1, 2), center=(0.5, 0.5))
        slide = Slide("a/b", "c/d")

        region_coords_ = slide._region_coordinates(region)

        assert region_coords_ == CoordinatePair(x_ul=1, y_ul=0, x_br=2, y_br=1)
Beispiel #4
0
    def it_knows_regions_from_binary_mask(self, request):
        binary_mask = np.array([[True, False], [True, True]])
        label = function_mock(request, "histolab.slide.label")
        regionprops = function_mock(request, "histolab.slide.regionprops")
        RegionProps = namedtuple("RegionProps", ("area", "bbox", "centroid"))
        regions_props = [
            RegionProps(3, (0, 0, 2, 2),
                        (0.6666666666666666, 0.3333333333333333))
        ]
        regionprops.return_value = regions_props
        label(binary_mask).return_value = [[0, 1], [1, 1]]
        slide = Slide("/a/b", "c/d")

        regions_from_binary_mask_ = slide._regions_from_binary_mask(
            binary_mask)

        regionprops.assert_called_once_with(label(binary_mask))
        assert type(regions_from_binary_mask_) == list
        assert len(regions_from_binary_mask_) == 1
        assert type(regions_from_binary_mask_[0]) == Region
        assert regions_from_binary_mask_ == [
            Region(
                index=0,
                area=regions_props[0].area,
                bbox=regions_props[0].bbox,
                center=regions_props[0].centroid,
            )
        ]
Beispiel #5
0
    def it_knows_its_scaled_image_path(self, resampled_dims_, slide_path,
                                       proc_path, slide_dims, expected_value):
        resampled_dims_.return_value = slide_dims
        slide = Slide(slide_path, proc_path)

        scaled_img_path = slide.scaled_image_path(scale_factor=22)

        assert scaled_img_path == expected_value
Beispiel #6
0
    def but_it_raises_error_when_it_doesnt_exist(self):
        slide = Slide("a/b", "processed")

        with pytest.raises(FileNotFoundError) as err:
            slide.show()

        assert (str(err.value) ==
                "Cannot display the slide thumbnail:[Errno 2] No such file or "
                "directory: 'processed/thumbnails/b.png'")
    def it_calculate_resampled_nparray_from_small_region_svs_image(self):
        slide = Slide(SVS.CMU_1_SMALL_REGION,
                      os.path.join(SVS.CMU_1_SMALL_REGION, "processed"))

        resampled_array = slide.resampled_array(scale_factor=32)

        expected_value = load_expectation(
            "svs-images/small-region-svs-resampled-array", type_="npy")
        np.testing.assert_almost_equal(resampled_array, expected_value)
Beispiel #8
0
    def it_can_show_its_thumbnail(self, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")

        slide.save_thumbnail()

        assert ImageShow.show(PIL.Image.open(slide.thumbnail_path))
Beispiel #9
0
    def but_it_raises_error_when_it_doesnt_exist(self):
        slide = Slide("a/b", "processed")

        with pytest.raises(FileNotFoundError) as err:
            slide.show()

        assert (
            str(err.value) ==
            "Cannot display the slide thumbnail: The wsi path resource doesn't "
            "exist: a/b")
Beispiel #10
0
    def it_knows_its_level_dimensions(self, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")

        level_dimensions = slide.level_dimensions(level=0)

        assert level_dimensions == (500, 500)
Beispiel #11
0
    def but_it_raises_an_error_when_n_is_not_between_1_and_number_of_regions(
            self, n):
        regions = [
            Region(i, i + 1, (0, 0, 2, 2), (0.5, 0.5)) for i in range(4)
        ]
        slide = Slide("a/b", "c/d")
        with pytest.raises(ValueError) as err:
            slide._biggest_regions(regions, n)

        assert str(
            err.value) == f"n should be between 1 and {len(regions)}, got {n}"
Beispiel #12
0
    def but_it_raises_error_when_it_doesnt_exist(self):
        slide = Slide("a/b", "processed")

        with pytest.raises(FileNotFoundError) as err:
            slide.show()

        assert (
            str(err.value) ==
            "Cannot display the slide thumbnail:[Errno 2] No such file or "
            f"directory: {repr(os.path.join('processed', 'thumbnails', 'b.png'))}"
        )
Beispiel #13
0
    def it_knows_its_scaled_image(self, tmpdir, resampled_dims_):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, os.path.join(tmp_path_, "processed"))
        resampled_dims_.return_value = (100, 200, 300, 400)

        scaled_image = slide.scaled_image(32)

        assert type(scaled_image) == PIL.Image.Image
Beispiel #14
0
    def it_knows_if_coords_are_valid(self, coords, expected_result, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")

        _are_valid = slide._has_valid_coords(coords)

        assert type(_are_valid) == bool
        assert _are_valid == expected_result
Beispiel #15
0
    def but_it_raises_expection_when_level_does_not_exist(self, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILImageMock.DIMS_500X500_RGBA_COLOR_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")
        with pytest.raises(ValueError) as err:
            slide.level_dimensions(level=3)

        assert str(err.value
                   ) == "Level 3 not available. Number of available levels: 1"
Beispiel #16
0
    def it_knows_its_resampled_array(self, tmpdir, resampled_dims_):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")
        resampled_dims_.return_value = (100, 200, 300, 400)

        resampled_array = slide.resampled_array(scale_factor=32)

        assert type(resampled_array) == np.ndarray
        assert resampled_array.shape == (400, 300, 3)
Beispiel #17
0
    def it_knows_its_biggest_regions(self):
        regions = [
            Region(index=0, area=14, bbox=(0, 0, 2, 2), center=(0.5, 0.5)),
            Region(index=1, area=2, bbox=(0, 0, 2, 2), center=(0.5, 0.5)),
            Region(index=2, area=5, bbox=(0, 0, 2, 2), center=(0.5, 0.5)),
            Region(index=3, area=10, bbox=(0, 0, 2, 2), center=(0.5, 0.5)),
        ]
        slide = Slide("a/b", "c/d")

        biggest_regions = slide._biggest_regions(regions, 2)

        assert biggest_regions == [regions[0], regions[3]]
Beispiel #18
0
    def it_locates_the_biggest_bbox(self, tmpdir, slide_fixture, tissue_mask,
                                    expectation):
        slide = Slide(slide_fixture, os.path.join(tmpdir, "processed"))

        expected_img = load_expectation(
            os.path.join("bbox-location-images", expectation),
            type_="png",
        )
        bbox_location_img = slide.locate_biggest_tissue_box(
            tissue_mask=tissue_mask, scale_factor=3)

        np.testing.assert_array_almost_equal(np.asarray(bbox_location_img),
                                             expected_img)
Beispiel #19
0
    def or_it_has_wrong_processed_path(self, request):
        """This test simulates a wrong user behaviour, using a None object instead of a
        str, or a path as processed_path param"""
        _resampled_dimensions = method_mock(request, Slide,
                                            "_resampled_dimensions")
        _resampled_dimensions.return_value = (1, 2, 3, 4)
        with pytest.raises(TypeError) as err:
            slide = Slide("path", None)
            slide.scaled_image_path(32)

        assert isinstance(err.value, TypeError)
        assert (str(err.value) ==
                "expected str, bytes or os.PathLike object, not NoneType")
Beispiel #20
0
    def it_can_save_thumbnail(self, tmpdir, resampled_dims_):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, os.path.join(tmp_path_, "processed"))
        resampled_dims_.return_value = (100, 200, 300, 400)

        slide.save_thumbnail()

        assert slide.thumbnail_path == os.path.join(tmp_path_, "processed",
                                                    "thumbnails", "mywsi.png")
        assert os.path.exists(os.path.join(tmp_path_, slide.thumbnail_path))
Beispiel #21
0
    def it_resamples_with_the_correct_scale_factor(self, tmpdir,
                                                   resampled_dims_):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, "processed")
        resampled_dims_.return_value = (500, 500, 15, 15)

        _resample = slide._resample(32)

        assert _resample[1].shape == (math.floor(500 / 32),
                                      math.floor(500 / 32), 3)
Beispiel #22
0
    def but_it_raises_zero_division_error_when_scalefactor_is_0(
            self, dimensions_):
        """Considering the teset above, this one prove that a wrong behaviour of the
        user can cause a zerodivision error. In this case the scale_factor=0 generates
        the ZeroDivision Exception
        """
        dimensions_.return_value = (300, 500)
        slide = Slide("/a/b/foo", "processed")
        with pytest.raises(ZeroDivisionError) as err:
            slide._resampled_dimensions(scale_factor=0)

        assert isinstance(err.value, ZeroDivisionError)
        assert str(err.value) == "division by zero"
Beispiel #23
0
    def it_locates_the_mask(self, request, tmpdir, slide_fixture, tissue_mask,
                            binary_mask, expectation):
        slide = Slide(slide_fixture, os.path.join(tmpdir, "processed"))
        expected_img = load_expectation(
            os.path.join("mask-location-images", expectation),
            type_="png",
        )

        mask_location_img = slide.locate_mask(binary_mask,
                                              tissue_mask=tissue_mask,
                                              scale_factor=3)

        np.testing.assert_array_almost_equal(np.asarray(mask_location_img),
                                             expected_img)
Beispiel #24
0
    def it_knows_its_thumbnails(self, request, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        thumbnail_ = property_mock(request, Slide, "thumbnail")
        slide1 = Slide("foo/bar", "proc")
        slide2 = Slide("foo/bar", "proc")

        slideset = SlideSet(tmp_path_, os.path.join(tmp_path_, "processed"),
                            [])
        slides = method_mock(request, SlideSet, "__iter__")
        slides.return_value = [slide1, slide2]

        slideset.thumbnails()

        assert thumbnail_.call_args_list == [call(), call()]
Beispiel #25
0
    def it_knows_its_resampled_dimensions(self, dimensions_):
        """This test prove that given the dimensions (mock object here), it does
        the correct maths operations:
            `large_w, large_h = self.dimensions`
            `new_w = math.floor(large_w / self._scale_factor)`
            `new_h = math.floor(large_h / self._scale_factor)`
            `return large_w, large_h, new_w, new_h`
        """
        dimensions_.return_value = (300, 500)
        slide = Slide("/a/b/foo", "processed")

        _resampled_dims = slide._resampled_dimensions(scale_factor=32)

        assert _resampled_dims == (300, 500, 9, 15)
    def it_knows_its_name(self):
        slide = Slide(SVS.CMU_1_SMALL_REGION,
                      os.path.join(SVS.CMU_1_SMALL_REGION, "processed"))

        name = slide.name

        assert name == ntpath.basename(SVS.CMU_1_SMALL_REGION).split(".")[0]
Beispiel #27
0
    def it_can_construct_tissue_mask(self, wsi, expected_array):
        slide = Slide(wsi, os.path.join(wsi, "processed"))
        expected_array = load_expectation(expected_array, type_="npy")
        tissue_mask = TissueMask()

        np.testing.assert_array_almost_equal(tissue_mask(slide),
                                             expected_array)
Beispiel #28
0
    def but_it_raises_error_with_negative_n_tiles_value(self, request, tmpdir):
        tmp_path_ = tmpdir.mkdir("myslide")
        image = PILIMG.RGBA_COLOR_500X500_155_249_240
        image.save(os.path.join(tmp_path_, "mywsi.png"), "PNG")
        slide_path = os.path.join(tmp_path_, "mywsi.png")
        slide = Slide(slide_path, os.path.join(tmp_path_, "processed"))
        _scores = method_mock(request, ScoreTiler, "_scores")
        coords = CP(0, 10, 0, 10)
        _scores.return_value = [
            (0.7, coords),
            (0.5, coords),
            (0.2, coords),
            (0.8, coords),
            (0.1, coords),
        ]
        _scorer = instance_mock(request, RandomScorer)
        score_tiler = ScoreTiler(_scorer, (10, 10), -1, 0)
        binary_mask = BiggestTissueBoxMask()

        with pytest.raises(ValueError) as err:
            score_tiler.extract(slide, binary_mask)

        assert isinstance(err.value, ValueError)
        assert str(err.value) == "'n_tiles' cannot be negative (-1)"
        _scores.assert_called_once_with(score_tiler, slide, binary_mask)
Beispiel #29
0
    def it_constructs_from_args(self, request, slide_path, processed_path):
        _init_ = initializer_mock(request, Slide)

        slide = Slide(slide_path, processed_path)

        _init_.assert_called_once_with(ANY, slide_path, processed_path)
        assert isinstance(slide, Slide)
Beispiel #30
0
    def but_it_raises_an_exception_if_file_not_found(self):
        with pytest.raises(FileNotFoundError) as err:
            slide = Slide("wrong/path/fake.wsi", "processed")
            slide._wsi

        assert isinstance(err.value, FileNotFoundError)
        assert str(err.value) == "The wsi path resource doesn't exist"