Example #1
0
            /// <summary>
            /// Validates and prepares the provided frames for the <see cref="VolumeBuilder"/>.
            /// </summary>
            /// <exception cref="CreateVolumeException">Thrown if something is wrong with the source frames.</exception>
            public static void PrepareFrames(List <IFrameReference> frames)
            {
                // ensure we have at least 3 frames
                if (frames.Count < 3)
                {
                    throw new InsufficientFramesException();
                }

                // ensure all frames have are from the same series, and have the same frame of reference
                string studyInstanceUid    = frames[0].Frame.StudyInstanceUid;
                string seriesInstanceUid   = frames[0].Frame.SeriesInstanceUid;
                string frameOfReferenceUid = frames[0].Frame.FrameOfReferenceUid;

                if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid))
                {
                    throw new NullSourceSeriesException();
                }
                if (string.IsNullOrEmpty(frameOfReferenceUid))
                {
                    throw new NullFrameOfReferenceException();
                }

                foreach (IFrameReference frame in frames)
                {
                    if (frame.Frame.StudyInstanceUid != studyInstanceUid)
                    {
                        throw new MultipleSourceSeriesException();
                    }
                    if (frame.Frame.SeriesInstanceUid != seriesInstanceUid)
                    {
                        throw new MultipleSourceSeriesException();
                    }
                    if (frame.Frame.FrameOfReferenceUid != frameOfReferenceUid)
                    {
                        throw new MultipleFramesOfReferenceException();
                    }
                }

                // ensure all frames are of the same supported format
                if (frames.Any(frame => frame.Frame.BitsAllocated != 16))
                {
                    throw new UnsupportedPixelFormatSourceImagesException();
                }

                // ensure all frames have the same rescale function units
                if (frames.Select(frame => frame.Frame.RescaleUnits).Distinct().Count() > 1)
                {
                    throw new InconsistentRescaleFunctionTypeException();
                }

                // ensure all frames have the same orientation
                var orient     = frames[0].Frame.ImageOrientationPatient;
                var laterality = frames[0].Frame.Laterality;

                foreach (IFrameReference frame in frames)
                {
                    if (frame.Frame.ImageOrientationPatient.IsNull)
                    {
                        throw new NullImageOrientationException();
                    }
                    if (!frame.Frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance))
                    {
                        throw new MultipleImageOrientationsException();
                    }
                    if (frame.Frame.PixelSpacing.IsNull)
                    {
                        throw new UncalibratedFramesException();
                    }
                    if (Math.Abs(frame.Frame.PixelSpacing.AspectRatio - 1) > _sliceSpacingTolerance)
                    {
                        throw new AnisotropicPixelAspectRatioException();
                    }
                    if (laterality != frame.Frame.Laterality)
                    {
                        throw new InconsistentImageLateralityException();
                    }
                }

                // ensure all frames are sorted by slice location
                SliceLocationComparer sliceLocationComparer = new SliceLocationComparer();

                frames.Sort((x, y) => sliceLocationComparer.Compare(x.Frame, y.Frame));

                // ensure all frames are evenly spaced
                var spacing = new float[frames.Count - 1];

                for (int i = 1; i < frames.Count; i++)
                {
                    float currentSpacing = CalcSpaceBetweenPlanes(frames[i].Frame, frames[i - 1].Frame);
                    if (currentSpacing < _minimumSliceSpacing)
                    {
                        throw new UnevenlySpacedFramesException();
                    }

                    spacing[i - 1] = currentSpacing;
                }
                if (spacing.Max() - spacing.Min() > 2 * _sliceSpacingTolerance)
                {
                    throw new UnevenlySpacedFramesException();
                }

                // ensure frames are not skewed about unsupported axis combinations (this volume builder only normalizes for skew between the Y-axis and XZ-plane in the source data)
                if (!IsSupportedSourceSkew(frames))
                {
                    throw new UnsupportedGantryTiltAxisException();
                }
            }
            /// <summary>
            /// Validates and prepares the provided frames for the <see cref="VolumeBuilder"/>.
            /// </summary>
            /// <exception cref="CreateVolumeException">Thrown if something is wrong with the source frames.</exception>
            public static void PrepareFrames(List <IFrameReference> _frames)
            {
                // ensure we have at least 3 frames
                if (_frames.Count < 3)
                {
                    throw new InsufficientFramesException();
                }

                // ensure all frames have are from the same series, and have the same frame of reference
                string studyInstanceUid    = _frames[0].Frame.StudyInstanceUid;
                string seriesInstanceUid   = _frames[0].Frame.SeriesInstanceUid;
                string frameOfReferenceUid = _frames[0].Frame.FrameOfReferenceUid;

                if (string.IsNullOrEmpty(studyInstanceUid) || string.IsNullOrEmpty(seriesInstanceUid))
                {
                    throw new NullSourceSeriesException();
                }
                if (string.IsNullOrEmpty(frameOfReferenceUid))
                {
                    throw new NullFrameOfReferenceException();
                }

                foreach (IFrameReference frame in _frames)
                {
                    if (frame.Frame.StudyInstanceUid != studyInstanceUid)
                    {
                        throw new MultipleSourceSeriesException();
                    }
                    if (frame.Frame.SeriesInstanceUid != seriesInstanceUid)
                    {
                        throw new MultipleSourceSeriesException();
                    }
                    if (frame.Frame.FrameOfReferenceUid != frameOfReferenceUid)
                    {
                        throw new MultipleFramesOfReferenceException();
                    }
                }

                // ensure all frames are of the same supported format
                foreach (IFrameReference frame in _frames)
                {
                    if (frame.Frame.BitsAllocated != 16)
                    {
                        throw new UnsupportedPixelFormatSourceImagesException();
                    }
                }

                // ensure all frames have the same orientation
                ImageOrientationPatient orient = _frames[0].Frame.ImageOrientationPatient;

                foreach (IFrameReference frame in _frames)
                {
                    if (frame.Frame.ImageOrientationPatient.IsNull)
                    {
                        if (frame.ImageSop.NumberOfFrames > 1)
                        {
                            throw new UnsupportedMultiFrameSourceImagesException(new NullImageOrientationException());
                        }
                        throw new NullImageOrientationException();
                    }
                    if (!frame.Frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance))
                    {
                        throw new MultipleImageOrientationsException();
                    }
                    if (frame.Frame.PixelSpacing.IsNull)
                    {
                        throw new UncalibratedFramesException();
                    }
                    if (Math.Abs(frame.Frame.PixelSpacing.AspectRatio - 1) > _minimumSliceSpacing)
                    {
                        throw new AnisotropicPixelAspectRatioException();
                    }
                }

                // ensure all frames are sorted by slice location
                SliceLocationComparer sliceLocationComparer = new SliceLocationComparer();

                _frames.Sort(delegate(IFrameReference x, IFrameReference y) { return(sliceLocationComparer.Compare(x.Frame, y.Frame)); });

                // ensure all frames are equally spaced
                float?nominalSpacing = null;

                for (int i = 1; i < _frames.Count; i++)
                {
                    float currentSpacing = CalcSpaceBetweenPlanes(_frames[i].Frame, _frames[i - 1].Frame);
                    if (currentSpacing < _minimumSliceSpacing)
                    {
                        if (_frames[i].ImageSop.NumberOfFrames > 1)
                        {
                            throw new UnsupportedMultiFrameSourceImagesException(new UnevenlySpacedFramesException());
                        }
                        throw new UnevenlySpacedFramesException();
                    }

                    if (!nominalSpacing.HasValue)
                    {
                        nominalSpacing = currentSpacing;
                    }
                    if (!FloatComparer.AreEqual(currentSpacing, nominalSpacing.Value, _sliceSpacingTolerance))
                    {
                        throw new UnevenlySpacedFramesException();
                    }
                }

                // ensure frames are not tilted about unsupposed axis combinations (the gantry correction algorithm only supports rotations about X)
                if (!IsSupportedGantryTilt(_frames))                 // suffices to check first one... they're all co-planar now!!
                {
                    throw new UnsupportedGantryTiltAxisException();
                }
            }