/// <summary> /// Validates the slice information. This method will check: /// 1. The dataset has a supported transfer syntax. /// 2. Does not have a 'ModalityLUTSequence' attribute in the dataset. /// 3. Has 16 bits allocated. /// 4. Has 'MONOCHROME2' as the photometric interpretation. /// 5. Only has 1 sample (channel) per pixel. /// 6. Validates the SOP class of the dataset is CT or MR and has the correct matching 'Modality' attribute. /// 7. Validates the 'BitsStored' attribute is 1 + the 'HighBit' attribute. /// </summary> /// <param name="dataset">The dataset to build the slice information from.</param> /// <param name="supportedTransferSyntaxes">The list of supported transfer syntaxes or empty if you do not wish to validate against this.</param> /// <exception cref="ArgumentNullException">The provided slice information was null.</exception> /// <exception cref="ArgumentException">The provided DICOM dataset did not have a required attribute or was not of the correct value.</exception> public static void ValidateSliceInformation( SliceInformation sliceInformation, IReadOnlyCollection <DicomTransferSyntax> supportedTransferSyntaxes = null) { sliceInformation = sliceInformation ?? throw new ArgumentNullException(nameof(sliceInformation)); var dataset = sliceInformation.DicomDataset; // 1. If supported transfer syntaxes have been provided, validate the dataset has one of these. if (supportedTransferSyntaxes != null && !supportedTransferSyntaxes.Contains(dataset.InternalTransferSyntax)) { throw new ArgumentException($"The DICOM dataset has an unsupported storage transfer syntax type {dataset.InternalTransferSyntax}. Expected: {string.Join("/ ", supportedTransferSyntaxes.Select(x => x.ToString()))}"); } // 2. A dataset should not have the 'ModalityLUTSequence' tag. if (dataset.Contains(DicomTag.ModalityLUTSequence)) { throw new ArgumentException("The DICOM dataset should not have the 'ModalityLUTSequence' attribute.", nameof(dataset)); } // 3. Check if the dataset has the 'BitsAllocated' tag and is set to 16. ThrowArgumentExeceptionIfNotEquals(ExpectedBitsAllocated, dataset.GetRequiredDicomAttribute <int>(DicomTag.BitsAllocated), "The DICOM dataset has an unsupported value for the 'BitsAllocated' attribute."); // 4. A dataset should have 'MONOCHROME2' for the photometric interpretation (i.e. is gray-scale). ThrowArgumentExeceptionIfNotEquals(ExpectedPhotometricInterpretation, DicomExtensions.DicomTrim(dataset.GetRequiredDicomAttribute <string>(DicomTag.PhotometricInterpretation)), "The DICOM dataset has an unsupported value for the 'PhotometricInterpretation' attribute."); // 5. A slice should only have one sample per pixel (1 channel at each pixel). ThrowArgumentExeceptionIfNotEquals(ExpectedSamplesPerPixel, dataset.GetRequiredDicomAttribute <int>(DicomTag.SamplesPerPixel), "The DICOM dataset has an unsupported value for the 'SamplesPerPixel' attribute."); // 6. Validate the SOP class of the slice is either MR/ CT and has the correct matching 'Modality' attribute. var modality = dataset.GetRequiredDicomAttribute <string>(DicomTag.Modality); if (sliceInformation.SopClass == DicomUID.CTImageStorage) { ThrowArgumentExeceptionIfNotEquals(DicomConstants.CTModality, modality, "The DICOM dataset has an 'CTImageStorage' SOP class but does not have CT for the 'Modality' attribute."); } if (sliceInformation.SopClass == DicomUID.MRImageStorage) { ThrowArgumentExeceptionIfNotEquals(DicomConstants.MRModality, modality, "The DICOM dataset has an 'MRImageStorage' SOP class but does not have MR for the 'Modality' attribute."); } // 7. Check the high bit against the bit stored. ThrowArgumentExeceptionIfNotEquals((int)sliceInformation.HighBit + 1, dataset.GetRequiredDicomAttribute <int>(DicomTag.BitsStored), $"The DICOM dataset has an unsupported value for the 'BitsStored' attribute. High bit value: {sliceInformation.HighBit}."); }
public void ToDicomTransferSyntaxArrayWithNullInput() { var result = DicomExtensions.ToDicomTransferSyntaxArray(null); Assert.Null(result); }