Example #1
0
    def from_file(self, request):
        """
        Creates a new scan instance from a file (currently only DICOM format files are accepted).
        
        Parameters
        ----------
        request : 
            A request from the client.
        
        Returns
        -------
        Response
            A response containing the serialized data or a message.
        """
        file_obj = request.data["file"]
        subject = get_subject_model().objects.get(
            id=request.data["subject_id"])

        if file_obj.name.endswith(".dcm"):
            scan, created = ImportScan(subject, file_obj).run()
            serializer = ScanSerializer(scan, context={"request": request})
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        elif file_obj.name.endswith(".zip"):
            content = ContentFile(file_obj.read())
            temp_file_name = default_storage.save("tmp.zip", content)
            temp_file_path = os.path.join(settings.MEDIA_ROOT, temp_file_name)
            LocalImport(subject, temp_file_path).run()
            os.remove(temp_file_path)
            return Response(
                {"message": "Successfully imported ZIP archive!"},
                status=status.HTTP_201_CREATED,
            )
Example #2
0
def session_post_save_receiver(sender: Model, instance: Session, created: bool,
                               **kwargs) -> None:
    """
    Creates a new subject automatically if a subject was not assigned and a
    DICOM series is accessible by extracting the
    :class:`~django_dicom.models.patient.Patient` information.

    Parameters
    ----------
    sender : ~django.db.models.Model
        The :class:`~django_mri.models.session.Session` model
    instance : ~django_mri.models.session.Session
        Session instance
    created : bool
        Whether the session instance was created or not
    """
    if not instance.subject:
        Subject = get_subject_model()
        scan = instance.scan_set.first()
        if scan and scan.dicom.patient:
            instance.subject, _ = Subject.objects.from_dicom_patient(
                scan.dicom.patient)
            instance.save()
Example #3
0
from typing import Tuple

from django.urls import reverse
from django_mri.models.irb_approval import IrbApproval
from django_mri.models.session import Session
from django_mri.serializers.irb_approval import IrbApprovalSerializer
from django_mri.serializers.utils import (
    MiniGroupSerializer,
    MiniMeasurementSerializer,
    MiniSubjectSerializer,
)
from django_mri.utils import get_measurement_model, get_subject_model
from rest_framework import serializers

Measurement = get_measurement_model()
Subject = get_subject_model()

SESSION_SERIALIZER_FIELDS: Tuple[str] = (
    "id",
    "subject",
    "comments",
    "time",
    "measurement",
    "irb",
)
SESSION_READ_FIELDS: Tuple[str] = (
    "dicom_zip",
    "nifti_zip",
    "n_scans",
    "study_groups",
)
Example #4
0
class Session(TimeStampedModel):
    """
    Represents a single MRI scanning session.
    """

    #: The associated `Subject` model (optional).
    subject = models.ForeignKey(
        get_subject_model(),
        on_delete=models.CASCADE,
        related_name="mri_session_set",
        blank=True,
        null=True,
    )

    #: Any other information about this scanning sequence.
    comments = models.TextField(
        max_length=1000,
        blank=True,
        null=True,
        help_text=help_text.SESSION_COMMENTS,
    )

    #: The associated `Measurement` model (optional).
    measurement = models.ForeignKey(
        get_measurement_model(),
        related_name="mri_session_set",
        blank=True,
        null=True,
        on_delete=models.PROTECT,
    )

    #: The date and time in which this scanning sequence began.
    time = models.DateTimeField()

    #: Associated IRB approval.
    irb = models.ForeignKey(
        "django_mri.IrbApproval",
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        verbose_name="IRB approval",
    )

    objects = SessionQuerySet.as_manager()

    class Meta:
        ordering = ("-time", )

    def __str__(self) -> str:
        """
        Returns the string representation of this instance.

        Returns
        -------
        str
            String representation
        """
        date = self.time.date()
        if self.subject:
            return f"Subject #{self.subject.id} MRI session from {date}"
        return f"Unclaimed MRI session from {date}"

    @property
    def study_groups(self) -> QuerySet:
        """
        The experimental groups with which scans in this session are
        associated. This property is only relevant if `STUDY_GROUP_MODEL` is
        set in the project's settings.

        Returns
        -------
        QuerySet
            The associated study groups
        """

        ids = self.scan_set.values_list("study_groups", flat=True)
        return Group.objects.filter(id__in=ids)

    @property
    def subject_age(self) -> float:
        """
        Returns the subject's age in years at the time of the session
        acquisition. If the subject's date of birth or the session's
        acquisition time are not available, returns `None`.

        Returns
        -------
        float
            Subject age in years at the time of the session's acquisition
        """

        conditions = self.time and self.subject and self.subject.date_of_birth
        if conditions:
            delta = self.time.date() - self.subject.date_of_birth
            return delta.total_seconds() / (60 * 60 * 24 * 365)