"""DICOM fields that belong to Study, Series and Instance levels

Notes
-----
The classes below determine which DICOM tags get saved for which db objects.
Changing the fields below will require in the classes in dicomindex.orm
"""


class InstanceLevel:
    """attributes can be returned if query_level=INSTANCE"""

    fields = {
        "SOPInstanceUID",
        "SOPClassUID",
        "Rows",
        "Columns",
        "NumberOfFrames",
        "BitsAllocated",
        "ContentDate",
        "ContentTime",
        "ObservationDateTime",
        "ConceptNameCodeSequence",
        "ContentLabel",
        "ContentDescription",
        "PresentationCreationDate",
        "PresentationCreationTime",
        "ContentCreatorName",
        "TransferSyntaxUID",
        "InstanceNumber",
        "Manufacturer",
        "StationName",
        "ManufacturerModelName",
        "DeviceSerialNumber",
        "InstitutionAddress",
        "CorrectedImage",
        "SoftwareVersions",
        "DateOfLastCalibration",
        "TimeOfLastCalibration",
        "PixelPaddingValue",
    }


class SeriesLevel:
    """attributes can be returned if query_level=SERIES, or query_level=INSTANCE"""

    fields = {
        "SeriesInstanceUID",
        "Modality",
        "SeriesDate",
        "SeriesTime",
        "SeriesDescription",
        "Laterality",
        "AnatomicRegionSequence",
        "BodyPartExamined",
        "FrameOfReferenceUID",
        "PerformedProcedureStepDescription",
        "ProtocolName",
        "PerformingPhysicianName",
        "PerformedProcedureStepStartDate",
        "PerformedProcedureStepStartTime",
        "OperatorsName",
        "PerformedProcedureStepStatus",
        "PresentationIntentType",
        "SeriesNumber",
        "SeriesType",
        "SmallestPixelValueInSeries",
        "SpatialResolution",
        "NumberOfSeriesRelatedInstances",
    }


class SeriesLevelPromotable:
    """Instance level attributes that may be returned even if query_level=SERIES

    These attributes are promotable from the Image-level to the Series-level metadata
    if the attribute value for all SOP instances in that series contain the same
    value. Therefore, these attributes may be returned in a query_level=SERIES query,
    but only when this condition is satisfied.

    Notes
    -----
    Including any of these attributes as return keys in a Series-level query will
    cause the full study metadata to be loaded from disk, even if the corresponding
    attribute was promoted to the study summary MINT metadata. This means there is an
    extra read from disk in addition to the database, so the performance of such
    queries may be slightly slower than queries for other Series-level attributes.
    """

    fields = {
        "Manufacturer",
        "ManufacturerModelName",
        "CorrectedImage",
        "DeviceSerialNumber",
        "InstitutionAddress",
        "SoftwareVersions",
        "StationName",
        "DateOfLastCalibration",
        "TimeOfLastCalibration",
    }


class StudyLevel:
    """All fields that can be returned for query_level=STUDY, SERIES or INSTANCE.

    Notes
    -----
    From manual:
    Note that if a specified attribute is not in the study, the attribute will not
    be returned. If the specified attribute is in the study but does not have a
    value, it will be returned without a value.
    """

    fields = {
        "PatientID",
        "IssuerOfPatientID",
        "IssuerOfPatientIDQualifiersSequence",
        "PatientName",
        "PatientSex",
        "PatientBirthDate",
        "PatientBirthTime",
        "StudyInstanceUID",
        "AccessionNumber",
        "IssuerOfAccessionNumberSequence",
        "StudyID",
        "StudyDate",
        "StudyTime",
        "ModalitiesInStudy",
        "ReferringPhysicianName",
        "RequestedProcedureID",
        "StudyDescription",
        "InstanceAvailability",
        "InstitutionName",
        "StudyStatusID",
        "ConfidentialityCode",
        "ProcedureCodeSequence",
        "ReasonForPerformedProcedureCodeSequence",
        "OtherPatientIDsSequence",
        "InstitutionalDepartmentName",
        "NumberOfStudyRelatedSeries",
        "NumberOfStudyRelatedInstances",
        "InstanceAvailability",
        "SOPClassesInStudy",
        "CurrentPatientLocation",
        "SourceApplicationEntityTitle",
    }
