コード例 #1
0
    def test_multiple_polygonsets_for_one_grader_distinct(self):
        grader = UserFactory()
        grader.groups.add(
            Group.objects.get(name=settings.RETINA_GRADERS_GROUP_NAME)
        )
        polygon_sets = [
            self.annotation_set.polygonset1,
            PolygonAnnotationSetFactory(
                grader=grader, image=self.annotation_set.polygonset1.image
            ),
            PolygonAnnotationSetFactory(
                grader=grader, image=self.annotation_set.polygonset1.image
            ),
        ]

        force_authenticate(self.request, user=self.retina_admin)
        response = self.view(self.request, **self.kwargs)

        graders = (
            get_user_model()
            .objects.filter(
                polygonannotationset__in=polygon_sets,
                groups__name=settings.RETINA_GRADERS_GROUP_NAME,
            )
            .distinct()
        )
        expected_response = UserSerializer(graders, many=True).data
        expected_response.sort(key=lambda k: k["id"])

        assert response.status_code == status.HTTP_200_OK
        response.data.sort(key=lambda k: k["id"])
        assert response.data == expected_response
コード例 #2
0
 def test_testsetretinapathologies_old(self):
     PolygonAnnotationSetFactory(name="No match")
     PolygonAnnotationSetFactory(name="retina::too_small")
     result = set_retina_pathologies(PolygonAnnotationSet.objects.all())
     assert result["pathology_set"] == 0
     assert result["old_annotation"] == 2
     assert len(result["non_matching_pathology"]) == 0
コード例 #3
0
def generate_two_polygon_annotation_sets(retina_grader=False):
    graders = (UserFactory(), UserFactory())

    if retina_grader:
        add_to_graders_group(graders)

    polygonsets = (
        PolygonAnnotationSetFactory(grader=graders[0]),
        PolygonAnnotationSetFactory(grader=graders[1]),
    )

    # Create child models for polygon annotation set
    singlepolygonbatches = (
        SinglePolygonAnnotationFactory.create_batch(
            10, annotation_set=polygonsets[0]
        ),
        SinglePolygonAnnotationFactory.create_batch(
            10, annotation_set=polygonsets[1]
        ),
    )

    return TwoPolygonAnnotationSets(
        grader1=graders[0],
        grader2=graders[1],
        polygonset1=polygonsets[0],
        polygonset2=polygonsets[1],
    )
コード例 #4
0
 def test_testmigratelesionnames_already_migrated(self):
     image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
     PolygonAnnotationSetFactory(name="retina::oct::macular::Drusen",
                                 image=image)
     PolygonAnnotationSetFactory(
         name="retina::enface::rf_present::Hard drusen")
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 0
     assert result["already_translated"] == 2
コード例 #5
0
 def test_testmigratelesionnames_correctly_migrated_case_insensitive(self):
     image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
     annotation_oct = PolygonAnnotationSetFactory(
         name="amd_present::DrUsEn AnD DrUsEn lIkE sTruCtUrEs::HARD dRuSeN",
         image=image,
     )
     annotation_enface = PolygonAnnotationSetFactory(
         name="DrUsEn AnD DrUsEn lIkE sTruCtUrEs::HARD dRuSeN")
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 2
     annotation_enface.refresh_from_db()
     assert (annotation_enface.name ==
             "retina::enface::rf_present::Hard drusen")
     annotation_oct.refresh_from_db()
     assert annotation_oct.name == "retina::oct::macular::Drusen"
コード例 #6
0
 def test_testmigratelesionnames_correctly_migrated(self):
     image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
     annotation_oct = PolygonAnnotationSetFactory(
         name="amd_present::Drusen and drusen like structures::Hard Drusen",
         image=image,
     )
     annotation_enface = PolygonAnnotationSetFactory(
         name="drusen and drusen like structures::hard drusen")
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 2
     annotation_enface.refresh_from_db()
     assert (annotation_enface.name ==
             "retina::enface::rf_present::Hard drusen")
     annotation_oct.refresh_from_db()
     assert annotation_oct.name == "retina::oct::macular::Drusen"
コード例 #7
0
 def test_testmigratelesionnames_no_match_enface(self):
     annotation = PolygonAnnotationSetFactory(
         name=
         "amd_present::Drusen and drusen like structures::Conical drusen")
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 0
     assert result["enface_no_match"] == [annotation.id]
コード例 #8
0
def generate_annotation_set(retina_grader=False):
    grader = UserFactory()

    if retina_grader:
        add_to_graders_group([grader])

    measurement = MeasurementAnnotationFactory(grader=grader)
    boolean = BooleanClassificationAnnotationFactory(grader=grader)
    integer = IntegerClassificationAnnotationFactory(grader=grader)
    polygon = PolygonAnnotationSetFactory(grader=grader)
    coordinatelist = CoordinateListAnnotationFactory(grader=grader)
    landmark = LandmarkAnnotationSetFactory(grader=grader)
    etdrs = ETDRSGridAnnotationFactory(grader=grader)

    # Create child models for polygon annotation set
    SinglePolygonAnnotationFactory.create_batch(10, annotation_set=polygon)

    # Create child models for landmark annotation set (3 per image)
    for i in range(5):
        image = ImageFactory()
        SingleLandmarkAnnotationFactory(annotation_set=landmark, image=image)

    return AnnotationSet(
        grader=grader,
        measurement=measurement,
        boolean=boolean,
        polygon=polygon,
        coordinatelist=coordinatelist,
        landmark=landmark,
        etdrs=etdrs,
        integer=integer,
    )
コード例 #9
0
    def test_multiple_graders_some_retina_grader(self):
        graders = (
            UserFactory(),
            UserFactory(),
            UserFactory(),
            UserFactory(),
            UserFactory(),
        )
        polygon_sets = [self.annotation_set.polygonset1]
        for index, grader in enumerate(graders):
            if index % 2 == 0:
                grader.groups.add(
                    Group.objects.get(name=settings.RETINA_GRADERS_GROUP_NAME)
                )
            polygon_sets.append(
                PolygonAnnotationSetFactory(
                    grader=grader, image=self.annotation_set.polygonset1.image
                )
            )

        force_authenticate(self.request, user=self.retina_admin)
        response = self.view(self.request, **self.kwargs)

        graders = get_user_model().objects.filter(
            polygonannotationset__in=polygon_sets,
            groups__name=settings.RETINA_GRADERS_GROUP_NAME,
        )
        expected_response = UserSerializer(graders, many=True).data
        expected_response.sort(key=lambda k: k["id"])

        assert response.status_code == status.HTTP_200_OK
        response.data.sort(key=lambda k: k["id"])
        assert response.data == expected_response
コード例 #10
0
    def test_update_view(self, TwoRetinaPolygonAnnotationSets, rf, user_type):
        model_serialized = SinglePolygonAnnotationSerializer(
            TwoRetinaPolygonAnnotationSets.polygonset1.singlepolygonannotation_set.first()
        ).data
        annotation_set = PolygonAnnotationSetFactory(
            grader=TwoRetinaPolygonAnnotationSets.grader1
        )
        model_serialized["annotation_set"] = str(annotation_set.id)
        model_json = json.dumps(model_serialized)

        response = view_test(
            "update",
            user_type,
            self.namespace,
            self.basename,
            TwoRetinaPolygonAnnotationSets.grader1,
            TwoRetinaPolygonAnnotationSets.polygonset1.singlepolygonannotation_set.first(),
            rf,
            SinglePolygonViewSet,
            model_json,
        )

        if user_type in ("retina_grader", "retina_admin"):
            response.data["annotation_set"] = str(
                response.data["annotation_set"]
            )
            assert response.data == model_serialized
コード例 #11
0
    def test_create_view(self, TwoRetinaPolygonAnnotationSets, rf, user_type):
        model_build = SinglePolygonAnnotationFactory.build()
        model_serialized = SinglePolygonAnnotationSerializer(model_build).data
        annotation_set = PolygonAnnotationSetFactory(
            grader=TwoRetinaPolygonAnnotationSets.grader1
        )
        model_serialized["annotation_set"] = str(annotation_set.id)
        model_json = json.dumps(model_serialized)

        response = view_test(
            "create",
            user_type,
            self.namespace,
            self.basename,
            TwoRetinaPolygonAnnotationSets.grader1,
            None,
            rf,
            SinglePolygonViewSet,
            model_json,
        )
        if user_type in ("retina_grader", "retina_admin"):
            model_serialized["id"] = response.data["id"]
            response.data["annotation_set"] = str(
                response.data["annotation_set"]
            )
            assert response.data == model_serialized
コード例 #12
0
 def test_testmigratelesionnames_no_match_oct_boolean(self):
     image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
     annotation = PolygonAnnotationSetFactory(
         name="other_present::Vascular::Branch retinal artery occlusion",
         image=image,
     )
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 0
     assert result["boolean_oct_no_match"] == [annotation.id]
コード例 #13
0
def create_load_data(data_type, ds, grader):
    if data_type == "Registration":
        model = LandmarkAnnotationSetFactory(grader=grader)
        SingleLandmarkAnnotationFactory(
            annotation_set=model, image=ds["image_cf"]
        ),
        if ds["archive"].name == "Australia":
            # Australia does not allow obs images so create a new cf image for Australia test
            img = ImageFactory(study=ds["study"])
            SingleLandmarkAnnotationFactory(annotation_set=model, image=img)
        else:
            SingleLandmarkAnnotationFactory(
                annotation_set=model, image=ds["image_obs"]
            ),
    elif data_type == "ETDRS":
        model = ETDRSGridAnnotationFactory(grader=grader, image=ds["image_cf"])
    elif data_type == "GA" or data_type == "kappa":
        model_macualar = PolygonAnnotationSetFactory(
            grader=grader, image=ds["image_cf"], name="macular"
        )
        SinglePolygonAnnotationFactory(annotation_set=model_macualar)
        SinglePolygonAnnotationFactory(annotation_set=model_macualar)
        SinglePolygonAnnotationFactory(annotation_set=model_macualar)

        model_peripapillary = PolygonAnnotationSetFactory(
            grader=grader, image=ds["image_cf"], name="peripapillary"
        )
        SinglePolygonAnnotationFactory(annotation_set=model_peripapillary)
        SinglePolygonAnnotationFactory(annotation_set=model_peripapillary)
        SinglePolygonAnnotationFactory(annotation_set=model_peripapillary)
        model = [model_macualar, model_peripapillary]
    elif data_type == "Measure":
        model = [
            MeasurementAnnotationFactory(grader=grader, image=ds["image_cf"]),
            MeasurementAnnotationFactory(grader=grader, image=ds["image_cf"]),
            MeasurementAnnotationFactory(grader=grader, image=ds["image_cf"]),
        ]
    elif data_type == "Fovea":
        model = BooleanClassificationAnnotationFactory(
            grader=grader, image=ds["image_cf"], name="fovea_affected"
        )

    return model
コード例 #14
0
 def test_testmigratelesionnames_no_match_oct(self):
     image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
     annotation = PolygonAnnotationSetFactory(
         name=
         "amd_present::Pigment changes & RPE degeneration::Increased pigmentation",
         image=image,
     )
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 0
     assert result["oct_no_match"] == [annotation.id]
コード例 #15
0
 def test_testmigratelesionnames_unique_violation_appends(self):
     annotation = PolygonAnnotationSetFactory(
         name="drusen and drusen like structures::hard drusen")
     SinglePolygonAnnotationFactory(annotation_set=annotation),
     SinglePolygonAnnotationFactory(annotation_set=annotation),
     annotation_dup = PolygonAnnotationSetFactory(
         name="retina::enface::rf_present::Hard drusen",
         grader=annotation.grader,
         image=annotation.image,
         created=annotation.created,
     )
     SinglePolygonAnnotationFactory(annotation_set=annotation_dup),
     SinglePolygonAnnotationFactory(annotation_set=annotation_dup),
     assert annotation_dup.singlepolygonannotation_set.count() == 2
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 1
     assert result["already_translated"] == 1
     assert PolygonAnnotationSet.objects.count() == 1
     annotation_dup.refresh_from_db()
     assert annotation_dup.singlepolygonannotation_set.count() == 4
コード例 #16
0
 def test_testsetretinapathologies_no_match(self):
     annotation = PolygonAnnotationSetFactory(
         name="retina::enface::non_matching_pathology::bla")
     result = set_retina_pathologies(PolygonAnnotationSet.objects.all())
     assert result["pathology_set"] == 0
     assert result["old_annotation"] == 0
     assert len(result["non_matching_pathology"]) == 1
     assert result["non_matching_pathology"] == [{
         "id": annotation.id,
         "name": annotation.name
     }]
コード例 #17
0
    def test_testmigratelesionnames_combined(self):
        image = ImageFactory(modality=ImagingModalityFactory(modality="OCT"))
        annotation_oct = PolygonAnnotationSetFactory(
            name="amd_present::Drusen and drusen like structures::Hard Drusen",
            image=image,
        )
        annotation_enface = PolygonAnnotationSetFactory(
            name="drusen and drusen like structures::hard drusen")
        PolygonAnnotationSetFactory(name="retina::oct::macular::Drusen",
                                    image=image)
        PolygonAnnotationSetFactory(
            name="retina::enface::rf_present::Hard drusen")
        PolygonAnnotationSetFactory(
            name="other_present::Vascular::Branch retinal artery occlusion", )
        annotation_oct_no_match_boolean = PolygonAnnotationSetFactory(
            name="other_present::Vascular::Branch retinal artery occlusion",
            image=image,
        )
        annotation_oct_no_match = PolygonAnnotationSetFactory(
            name=
            "amd_present::Pigment changes & RPE degeneration::Increased pigmentation",
            image=image,
        )
        annotation_enface_no_match = PolygonAnnotationSetFactory(
            name=
            "amd_present::Drusen and drusen like structures::Conical drusen")
        annotation_no_match = PolygonAnnotationSetFactory(name="No match")

        assert BooleanClassificationAnnotation.objects.count() == 0
        result = migrate_annotations(PolygonAnnotationSet.objects.all())
        assert result["translated"] == 3
        assert BooleanClassificationAnnotation.objects.count() == 1
        assert result["already_translated"] == 2
        assert result["boolean_oct_no_match"] == [
            annotation_oct_no_match_boolean.id
        ]
        assert result["oct_no_match"] == [annotation_oct_no_match.id]
        assert result["enface_no_match"] == [annotation_enface_no_match.id]
        assert result["no_match"] == [annotation_no_match.id]
        annotation_enface.refresh_from_db()
        assert (annotation_enface.name ==
                "retina::enface::rf_present::Hard drusen")
        annotation_oct.refresh_from_db()
        assert annotation_oct.name == "retina::oct::macular::Drusen"
コード例 #18
0
def generate_annotation_set(retina_grader=False, image=False):
    grader = UserFactory()

    if retina_grader:
        add_to_graders_group([grader])

    create_options = {"grader": grader}
    if image:
        create_options_with_image = {"image": image, **create_options}
    else:
        create_options_with_image = create_options

    measurement = MeasurementAnnotationFactory(**create_options_with_image)
    boolean = BooleanClassificationAnnotationFactory(
        **create_options_with_image
    )
    integer = IntegerClassificationAnnotationFactory(
        **create_options_with_image
    )
    polygon = PolygonAnnotationSetFactory(**create_options_with_image)
    coordinatelist = CoordinateListAnnotationFactory(
        **create_options_with_image
    )
    etdrs = ETDRSGridAnnotationFactory(**create_options_with_image)
    landmark = LandmarkAnnotationSetFactory(**create_options)

    # Create child models for polygon annotation set
    SinglePolygonAnnotationFactory.create_batch(10, annotation_set=polygon)

    # Create child models for landmark annotation set (3 per image)
    single_landmarks = []
    for i in range(5):
        if i > 0 or not image:
            image = ImageFactory()
        single_landmarks.append(
            SingleLandmarkAnnotationFactory(
                annotation_set=landmark, image=image
            )
        )

    return AnnotationSet(
        grader=grader,
        measurement=measurement,
        boolean=boolean,
        polygon=polygon,
        coordinatelist=coordinatelist,
        landmark=landmark,
        singlelandmarks=single_landmarks,
        etdrs=etdrs,
        integer=integer,
    )
コード例 #19
0
 def test_testsetretinapathologies_created(self):
     annotation = PolygonAnnotationSetFactory(
         name=f"retina::enface::{pathology_options_enface[0]}::bla")
     assert RetinaImagePathologyAnnotation.objects.all().count() == 0
     result = set_retina_pathologies(PolygonAnnotationSet.objects.all())
     assert result["pathology_set"] == 1
     assert result["old_annotation"] == 0
     assert len(result["non_matching_pathology"]) == 0
     assert RetinaImagePathologyAnnotation.objects.all().count() == 1
     pathology_annotation = RetinaImagePathologyAnnotation.objects.first()
     assert pathology_annotation.image == annotation.image
     assert pathology_annotation.grader == annotation.grader
     for v in pathology_options_enface:
         assert getattr(pathology_annotation,
                        v) == (v == pathology_options_enface[0])
コード例 #20
0
 def test_testmigratelesionnames_correctly_migrated_boolean(self):
     annotation_enface = PolygonAnnotationSetFactory(
         name="other_present::Vascular::Branch retinal artery occlusion")
     assert BooleanClassificationAnnotation.objects.count() == 0
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 1
     assert PolygonAnnotationSet.objects.count() == 0
     assert BooleanClassificationAnnotation.objects.count() == 1
     annotation = BooleanClassificationAnnotation.objects.first()
     assert (annotation.name ==
             "retina::enface::Branch retinal artery occlusion")
     assert annotation.value
     assert annotation.grader == annotation_enface.grader
     assert annotation.image == annotation_enface.image
     assert annotation.created == annotation_enface.created
コード例 #21
0
 def test_testsetretinapathologies_oct(self):
     annotation = PolygonAnnotationSetFactory(
         name=f"retina::oct::{pathology_options_oct[0]}::bla")
     assert OctRetinaImagePathologyAnnotation.objects.all().count() == 0
     result = set_retina_pathologies(PolygonAnnotationSet.objects.all())
     assert result["pathology_set"] == 1
     assert result["old_annotation"] == 0
     assert len(result["non_matching_pathology"]) == 0
     assert RetinaImagePathologyAnnotation.objects.all().count() == 0
     assert OctRetinaImagePathologyAnnotation.objects.all().count() == 1
     oct_pathology_annotation = (
         OctRetinaImagePathologyAnnotation.objects.first())
     assert oct_pathology_annotation.image == annotation.image
     assert oct_pathology_annotation.grader == annotation.grader
     assert (getattr(oct_pathology_annotation, pathology_options_oct[0]) is
             True)
コード例 #22
0
 def test_testsetretinapathologies_updated(self):
     annotation = PolygonAnnotationSetFactory(
         name=f"retina::enface::{pathology_options_enface[0]}::bla")
     pathology_annotation = RetinaImagePathologyAnnotationFactory(
         **{
             "image": annotation.image,
             "grader": annotation.grader,
             pathology_options_enface[0]: False,
         })
     assert RetinaImagePathologyAnnotation.objects.all().count() == 1
     result = set_retina_pathologies(PolygonAnnotationSet.objects.all())
     assert result["pathology_set"] == 1
     assert result["old_annotation"] == 0
     assert len(result["non_matching_pathology"]) == 0
     assert RetinaImagePathologyAnnotation.objects.all().count() == 1
     pathology_annotation.refresh_from_db()
     assert pathology_annotation.image == annotation.image
     assert pathology_annotation.grader == annotation.grader
     assert (getattr(pathology_annotation, pathology_options_enface[0]) is
             True)
コード例 #23
0
    def test_update_view_wrong_user_id(
        self, TwoRetinaPolygonAnnotationSets, rf, user_type
    ):
        model_serialized = SinglePolygonAnnotationSerializer(
            TwoRetinaPolygonAnnotationSets.polygonset1.singlepolygonannotation_set.first()
        ).data
        annotation_set = PolygonAnnotationSetFactory()
        model_serialized["annotation_set"] = str(annotation_set.id)
        model_json = json.dumps(model_serialized)

        response = view_test(
            "update",
            user_type,
            self.namespace,
            self.basename,
            TwoRetinaPolygonAnnotationSets.grader1,
            TwoRetinaPolygonAnnotationSets.polygonset1.singlepolygonannotation_set.first(),
            rf,
            SinglePolygonViewSet,
            model_json,
            check_response_status_code=False,
        )
        if user_type == "retina_admin":
            model_serialized["id"] = response.data["id"]
            response.data["annotation_set"] = str(
                response.data["annotation_set"]
            )
            assert response.data == model_serialized
        elif user_type == "retina_grader":
            assert response.status_code == status.HTTP_400_BAD_REQUEST
            assert (
                str(response.data["non_field_errors"][0])
                == "User is not allowed to create annotation for other grader"
            )
        else:
            assert response.status_code == status.HTTP_403_FORBIDDEN
コード例 #24
0
 def test_testmigratelesionnames_no_match(self):
     annotation = PolygonAnnotationSetFactory(name="No match")
     result = migrate_annotations(PolygonAnnotationSet.objects.all())
     assert result["translated"] == 0
     assert result["no_match"] == [annotation.id]