backend/image_markuper/dicom/api/serializers.py

190 lines
5.9 KiB
Python
Raw Normal View History

2022-11-01 12:20:43 +03:00
from dicom.models import (
BaseShape,
Circle,
Coordinate,
Dicom,
FreeHand,
Project,
Roi,
Ruler,
)
from dicom.services import create_coordinate
2022-10-28 21:52:02 +03:00
from drf_spectacular.utils import extend_schema_field
2022-10-26 23:22:04 +03:00
from rest_framework import serializers
2022-10-28 21:52:02 +03:00
from rest_framework.generics import get_object_or_404
class CoordinateSerializer(serializers.ModelSerializer):
class Meta:
model = Coordinate
fields = ["x", "y"]
2022-10-26 23:22:04 +03:00
class ListDicomSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="get_update_delete_dicom", lookup_field="slug"
)
file = serializers.FileField()
class Meta:
model = Dicom
2022-10-28 22:17:29 +03:00
fields = ["file", "uploaded", "pathology_type", "url"]
2022-10-26 23:22:04 +03:00
def create(self, validated_data):
return Dicom.objects.create(**validated_data, user=self.context["request"].user)
2022-10-28 21:52:02 +03:00
class BaseShapeSerializer(serializers.Serializer):
2022-11-01 12:20:43 +03:00
model = BaseShape
type = serializers.ChoiceField(choices=["circle", "roi", "free_hand"])
2022-10-28 21:52:02 +03:00
image_number = serializers.IntegerField()
coordinates = CoordinateSerializer(many=True)
2022-11-01 12:20:43 +03:00
def create(self, validated_data):
if self.model.max_coordinates:
if len(validated_data["coordinates"]) > self.model.max_coordinates:
raise serializers.ValidationError
if self.model.min_coordinates:
if len(validated_data["coordinates"]) < self.model.min_coordinates:
raise serializers.ValidationError
dicom = get_object_or_404(
Dicom, slug=self.context["request"].parser_context["kwargs"]["slug"]
)
obj = self.model.objects.create(
dicom=dicom, image_number=validated_data["image_number"]
)
create_coordinate(validated_data["coordinates"], obj)
return obj
def update(self, obj, validated_data):
Coordinate.objects.filter(shape=obj).delete()
if self.model.max_coordinates:
if len(validated_data["coordinates"]) > self.model.max_coordinates:
raise serializers.ValidationError
if self.model.min_coordinates:
if len(validated_data["coordinates"]) < self.model.min_coordinates:
raise serializers.ValidationError
create_coordinate(validated_data["coordinates"], obj)
return obj
2022-10-28 21:52:02 +03:00
2022-10-30 16:40:46 +03:00
class BaseShapeLayerSerializer(serializers.Serializer):
2022-11-01 12:20:43 +03:00
type = serializers.ChoiceField(choices=["circle", "roi", "free_hand"])
2022-10-30 16:40:46 +03:00
radius = serializers.FloatField(required=False)
coordinates = CoordinateSerializer(many=True)
2022-10-26 23:22:04 +03:00
class DicomSerializer(serializers.ModelSerializer):
file = serializers.FileField()
2022-10-28 21:52:02 +03:00
shapes = serializers.SerializerMethodField("get_dicom_shapes")
@extend_schema_field(field=BaseShapeSerializer)
def get_dicom_shapes(self, obj):
return [x.serialize_self() for x in obj.shapes.all()]
2022-10-26 23:22:04 +03:00
class Meta:
model = Dicom
2022-10-28 22:17:29 +03:00
fields = ["file", "uploaded", "pathology_type", "shapes"]
2022-10-28 21:52:02 +03:00
2022-11-01 12:20:43 +03:00
class RoiSerializer(BaseShapeSerializer, serializers.ModelSerializer):
2022-10-28 21:52:02 +03:00
coordinates = CoordinateSerializer(many=True)
2022-11-01 12:20:43 +03:00
model = Roi
2022-10-28 21:52:02 +03:00
class Meta:
2022-10-30 00:12:13 +03:00
model = Roi
2022-10-28 21:52:02 +03:00
fields = ["id", "image_number", "coordinates"]
extra_kwargs = {"id": {"read_only": True}}
2022-11-01 12:20:43 +03:00
class FreeHandSerializer(BaseShapeSerializer, serializers.ModelSerializer):
coordinates = CoordinateSerializer(many=True)
model = FreeHand
class Meta:
model = FreeHand
fields = ["id", "image_number", "coordinates"]
extra_kwargs = {"id": {"read_only": True}}
2022-10-28 21:52:02 +03:00
2022-11-01 12:20:43 +03:00
class RulerSerializer(BaseShapeSerializer, serializers.ModelSerializer):
coordinates = CoordinateSerializer(many=True)
model = Ruler
class Meta:
model = FreeHand
fields = ["id", "image_number", "coordinates"]
extra_kwargs = {"id": {"read_only": True}}
2022-10-28 21:52:02 +03:00
class CircleSerializer(serializers.ModelSerializer):
coordinates = CoordinateSerializer(many=True)
class Meta:
model = Circle
fields = ["id", "image_number", "radius", "coordinates"]
extra_kwargs = {"id": {"read_only": True}}
def create(self, validated_data):
if (
"coordinates" not in validated_data
and len(validated_data["coordinates"]) > 1
):
raise serializers.ValidationError
dicom = get_object_or_404(
Dicom, slug=self.context["request"].parser_context["kwargs"]["slug"]
)
circle = Circle.objects.create(
dicom=dicom,
image_number=validated_data["image_number"],
radius=validated_data["radius"],
)
create_coordinate(validated_data["coordinates"], circle)
return circle
def update(self, obj: Circle, validated_data):
Coordinate.objects.filter(shape=obj).delete()
create_coordinate(validated_data["coordinates"], obj)
if "radius" in validated_data:
obj.radius = validated_data["radius"]
obj.save()
return obj
2022-10-29 22:46:19 +03:00
2022-10-30 00:12:13 +03:00
class SmartFileUploadSerializer(serializers.Serializer):
2022-10-29 22:46:19 +03:00
file = serializers.FileField()
2022-11-01 12:20:43 +03:00
class ListProjectSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name="get_update_delete_project", lookup_field="slug"
)
class Meta:
model = Project
2022-11-02 14:32:46 +03:00
fields = ["slug", "url", "created"]
2022-11-01 12:20:43 +03:00
extra_kwargs = {
2022-11-02 14:32:46 +03:00
"slug": {"read_only": True},
2022-11-01 12:20:43 +03:00
"created": {"read_only": True},
}
2022-11-02 14:32:46 +03:00
def create(self, validated_data):
return Project.objects.create(user=self.context["request"].user)
2022-11-01 12:20:43 +03:00
class ProjectSerializer(serializers.ModelSerializer):
files = ListDicomSerializer(many=True)
class Meta:
model = Project
2022-11-03 23:15:25 +03:00
fields = ["files", "slug", "created", "stl"]
2022-11-03 22:16:11 +03:00
class PatologyGenerateSerializer(serializers.Serializer):
project_slug = serializers.CharField()
points = serializers.ListField(child=CoordinateSerializer())
depth = serializers.ListField(child=serializers.IntegerField())