Ejemplo n.º 1
0
        /// <summary>
        /// Cloning constructor.
        /// </summary>
        /// <param name="source">The source object from which to clone.</param>
        /// <param name="context">The cloning context object.</param>
        protected FusionPresentationImage(FusionPresentationImage source, ICloningContext context) : base(source, context)
        {
            context.CloneFields(source, this);

            _baseFrameReference        = source._baseFrameReference.Clone();
            _overlayFrameDataReference = source._overlayFrameDataReference.Clone();
        }
        public override List <IDisplaySet> CreateDisplaySets(Series series)
        {
            List <IDisplaySet> displaySets = new List <IDisplaySet>();

            if (IsValidPETFusionSeries(series))
            {
                var fuseableBaseSeries = new List <Series>(FindFuseableBaseSeries(series));
                if (fuseableBaseSeries.Count > 0)
                {
                    string error;
                    if (!CheckPETFusionSeries(series, out error))
                    {
                        // if there is an error with the PET series, avoid trying to generate the volume entirely
                        // instead, generate a placeholder series for each base series
                        foreach (var baseSeries in fuseableBaseSeries)
                        {
                            displaySets.Add(CreateFusionErrorDisplaySet(baseSeries, series, error));
                        }
                        return(displaySets);
                    }

                    using (var fusionOverlayData = new FusionOverlayData(GetFrames(series.Sops)))
                    {
                        foreach (var baseSeries in fuseableBaseSeries)
                        {
                            if (!CheckBaseSeries(baseSeries, out error))
                            {
                                // if there is an error with a single base series, generate a placeholder series
                                displaySets.Add(CreateFusionErrorDisplaySet(baseSeries, series, error));
                                continue;
                            }

                            var descriptor = new PETFusionDisplaySetDescriptor(baseSeries.GetIdentifier(), series.GetIdentifier(), IsAttenuationCorrected(series.Sops[0]));
                            var displaySet = new DisplaySet(descriptor);
                            foreach (var baseFrame in GetFrames(baseSeries.Sops))
                            {
                                using (var fusionOverlaySlice = fusionOverlayData.CreateOverlaySlice(baseFrame))
                                {
                                    var fus = new FusionPresentationImage(baseFrame, fusionOverlaySlice);
                                    displaySet.PresentationImages.Add(fus);
                                }
                            }
                            displaySet.PresentationImages.Sort();
                            displaySets.Add(displaySet);
                        }
                    }
                }
            }
            return(displaySets);
        }
        /// <summary>
        /// Attempts to install an appropriate equivalent of the specified <paramref name="sourceVoiLut"/> to a fusion image. If the LUT is not linear, computes a dummy LUT.
        /// </summary>
        private static void InstallVoiLut(FusionPresentationImage fusionImage, IVoiLut sourceVoiLut, Frame sourceFrame, bool applyToOverlay)
        {
            IVoiLut newVoiLut;

            if (sourceVoiLut is MinMaxPixelCalculatedLinearLut)
            {
                if (applyToOverlay)
                {
                    // if the overlay source image is using a min/max calculated LUT, install a custom calculated LUT that delay-computes min/max from the fusion data
                    // we need to delay-compute this because the fusion image graphic is delay-generated, and thus not necessarily available until just before rendering!
                    var skipModalityLut = sourceFrame.ParentImageSop.Modality == @"PT" && sourceFrame.IsSubnormalRescale;
                    newVoiLut = new FusionOverlayMinMaxVoiLutLinear(fusionImage, !skipModalityLut);
                }
                else
                {
                    // if the base source image is using a min/max calculated LUT, install a similarly min/max calculated LUT for the base of the fusion image
                    newVoiLut = new MinMaxPixelCalculatedLinearLut(fusionImage.ImageGraphic.PixelData);
                }
            }
            else if (sourceVoiLut is IVoiLutLinear)
            {
                var voiLutLinear           = (IVoiLutLinear)sourceVoiLut;
                var normalizedVoiSlope     = 1.0;
                var normalizedVoiIntercept = 0.0;
                if (applyToOverlay && sourceFrame.ParentImageSop.Modality == @"PT" && sourceFrame.IsSubnormalRescale)
                {
                    // for subnormal PET rescale slope cases, the original VOI windows must be transformed through the same process as what MPR did to the pixel data
                    normalizedVoiSlope     = sourceFrame.RescaleSlope / fusionImage.OverlayFrameData.OverlayRescaleSlope;
                    normalizedVoiIntercept = (sourceFrame.RescaleIntercept - fusionImage.OverlayFrameData.OverlayRescaleIntercept) / fusionImage.OverlayFrameData.OverlayRescaleSlope;
                }
                newVoiLut = new BasicVoiLutLinear(voiLutLinear.WindowWidth * normalizedVoiSlope, voiLutLinear.WindowCenter * normalizedVoiSlope + normalizedVoiIntercept);
            }
            else
            {
                // if the source image is using some non-linear LUT, just install a default pass-through LUT
                newVoiLut = new IdentityVoiLinearLut();
            }

            if (applyToOverlay)
            {
                fusionImage.OverlayVoiLutManager.InstallVoiLut(newVoiLut);
            }
            else
            {
                fusionImage.BaseVoiLutManager.InstallVoiLut(newVoiLut);
            }
        }
 public FusionOverlayMinMaxVoiLutLinear(FusionPresentationImage fusionPresentationImage, bool useModalityLut)
 {
     Platform.CheckForNullReference(fusionPresentationImage, "fusionPresentationImage");
     _fusionPresentationImage = fusionPresentationImage;
     _useModalityLut          = useModalityLut;
 }