public void TestVolumeInformationCreateTest()
        {
            ushort highBit          = 16;
            var    expectedDimX     = 54;
            var    expectedDimY     = 64;
            var    expectedDimZ     = 50;
            var    expectedSpacingX = 3;
            var    expectedSpacingY = 5;
            var    expectedSpacingZ = 4;
            var    expectedOrigin   = new Point3D(1, 2, 3);

            var dicomDatasets = CreateValidDicomDatasetVolume(
                expectedDimX,
                expectedDimY,
                expectedDimZ,
                expectedSpacingX,
                expectedSpacingY,
                expectedSpacingZ,
                expectedOrigin,
                DicomUID.CTImageStorage,
                highBit);

            var volumeInformation = VolumeInformation.Create(dicomDatasets);

            Assert.AreEqual(expectedDimX, volumeInformation.Width);
            Assert.AreEqual(expectedDimY, volumeInformation.Height);
            Assert.AreEqual(expectedDimZ, volumeInformation.Depth);
            Assert.AreEqual(expectedSpacingX, volumeInformation.VoxelWidthInMillimeters);
            Assert.AreEqual(expectedSpacingY, volumeInformation.VoxelHeightInMillimeters);
            Assert.AreEqual(expectedSpacingZ, volumeInformation.VoxelDepthInMillimeters);
            Assert.AreEqual(0, volumeInformation.RescaleIntercept);
            Assert.AreEqual(1, volumeInformation.RescaleSlope);
            Assert.AreEqual(highBit, volumeInformation.HighBit);
            Assert.AreEqual(true, volumeInformation.SignedPixelRepresentation);
            Assert.AreEqual(expectedOrigin.X, volumeInformation.Origin.X);
            Assert.AreEqual(expectedOrigin.Y, volumeInformation.Origin.Y);
            Assert.AreEqual(expectedOrigin.Z, volumeInformation.Origin.Z);
            Assert.AreEqual(Matrix3.CreateIdentity(), volumeInformation.Direction);

            for (var i = 0; i < dicomDatasets.Length; i++)
            {
                Assert.AreEqual(i * expectedSpacingZ + expectedOrigin.Z, volumeInformation.GetSliceInformation(i).SlicePosition);
            }

            // Exception testing.
            dicomDatasets[dicomDatasets.Length - 1].AddOrUpdate(new DicomDecimalString(DicomTag.PixelSpacing, new decimal[] { 0, 0 }));
            Assert.Throws <ArgumentException>(() => VolumeInformation.Create(dicomDatasets.Take(1)));
            var sliceInformation = new SliceInformation[1];

            Assert.Throws <ArgumentException>(() => VolumeInformation.Create(sliceInformation));
            sliceInformation = null;
            Assert.Throws <ArgumentNullException>(() => VolumeInformation.Create(sliceInformation));
            dicomDatasets = null;
            Assert.Throws <ArgumentNullException>(() => VolumeInformation.Create(dicomDatasets));
        }
        /// <summary>
        /// Attempt to construct a 3-dimensional volume instance from the provided set of DICOM series files.
        /// </summary>
        /// <param name="dicomDatasets">The collection of DICOM datasets.</param>
        /// <param name="acceptanceTest">An implmentation of IVolumeGeometricAcceptanceTest expressing the geometric tollerances required by your application</param>
        /// <param name="supportLossyCodecs">true if it is appropriate for your application to support lossy pixel encodings</param>
        /// <returns>The created 3-dimensional volume.</returns>
        /// <exception cref="ArgumentNullException">The DICOM datasets or acceptance test is null.</exception>
        /// <exception cref="ArgumentException">A volume could not be formed from the provided DICOM series datasets.</exception>
        public static Volume3D <short> BuildVolume(
            IEnumerable <DicomDataset> dicomDatasets,
            IVolumeGeometricAcceptanceTest acceptanceTest,
            bool supportLossyCodecs)
        {
            dicomDatasets  = dicomDatasets ?? throw new ArgumentNullException(nameof(dicomDatasets));
            acceptanceTest = acceptanceTest ?? throw new ArgumentNullException(nameof(acceptanceTest));

            // 1. Construct the volume information: this requires a minimum set of DICOM tags in each dataset.
            var volumeInformation = VolumeInformation.Create(dicomDatasets);

            // 2. Now validate the volume based on the acceptance tests (will throw argument exception on failure).
            DicomSeriesInformationValidator.ValidateVolumeInformation(volumeInformation, acceptanceTest, supportLossyCodecs ? null : SupportedTransferSyntaxes);

            // 3. Now validated, lets extract the pixels as a short array.
            return(DicomSeriesImageReader.BuildVolume(volumeInformation));
        }
        public void TestVolumeInformationValidation()
        {
            var dicomDatasets  = CreateValidDicomDatasetVolume(5, 5, 5, 1, 1, 3, new Point3D(), DicomUID.CTImageStorage, 16);
            var acceptanceTest = new ModerateGeometricAcceptanceTest("Blah1", "Blah2");

            // Valid DICOM slice.
            DicomSeriesInformationValidator.ValidateVolumeInformation(
                VolumeInformation.Create(dicomDatasets),
                acceptanceTest,
                new[] { dicomDatasets[0].InternalTransferSyntax });

            // Inconsistent slice information.
            var dicomDatasets2 = CreateValidDicomDatasetVolume(5, 5, 5, 1, 1, 3, new Point3D(), DicomUID.CTImageStorage, 16);

            dicomDatasets2[dicomDatasets2.Length - 2].AddOrUpdate(new DicomUnsignedShort(DicomTag.Rows, 234));
            var exception = Assert.Throws <ArgumentException>(() => DicomSeriesInformationValidator.ValidateVolumeInformation(
                                                                  VolumeInformation.Create(dicomDatasets2),
                                                                  acceptanceTest));

            Assert.IsTrue(exception.Message.Contains("Slice at position '9' has an inconsistent height. Expected: '5', Actual: '234'."));

            // Invalid supported transfer syntax
            Assert.Throws <ArgumentException>(() => DicomSeriesInformationValidator.ValidateVolumeInformation(
                                                  VolumeInformation.Create(dicomDatasets),
                                                  acceptanceTest,
                                                  new[] { DicomTransferSyntax.DeflatedExplicitVRLittleEndian }));

            // Failing acceptance test
            Assert.Throws <ArgumentException>(() => DicomSeriesInformationValidator.ValidateVolumeInformation(
                                                  VolumeInformation.Create(dicomDatasets),
                                                  new FailingAcceptanceTest()));

            // Exception testing
            Assert.Throws <ArgumentNullException>(() => DicomSeriesInformationValidator.ValidateVolumeInformation(
                                                      VolumeInformation.Create(dicomDatasets),
                                                      null));

            Assert.Throws <ArgumentNullException>(() => DicomSeriesInformationValidator.ValidateVolumeInformation(
                                                      null,
                                                      acceptanceTest));
        }