private void InitializeNecessaryLuts(Luts luts)
		{
			if (luts >= Luts.Voi && LutComposer.VoiLut == null)
			{
				IVoiLut lut = null;
				
				if (_voiLutFactory != null)
					lut = _voiLutFactory.CreateVoiLut(this);

				if (lut == null)
					lut = new IdentityVoiLinearLut();

				InstallVoiLut(lut);
			}
		}
		/// <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);
		}
		private void InitializeNecessaryLuts(Luts luts)
		{
			if (luts >= Luts.Modality && LutComposer.ModalityLut == null)
			{
				IModalityLut modalityLut =
					this.LutFactory.GetModalityLutLinear(this.BitsStored, this.IsSigned, _rescaleSlope, _rescaleIntercept);

				this.LutComposer.ModalityLut = modalityLut;
			}

			if (luts >= Luts.Voi && LutComposer.VoiLut == null)
			{
				IVoiLut lut = null;

				if (_voiLutFactory != null)
					lut = _voiLutFactory.CreateVoiLut(this);

				if (lut == null)
					lut = new IdentityVoiLinearLut();

				(this as IVoiLutInstaller).InstallVoiLut(lut);
			}
		}
		private void InitializeNecessaryLuts(Luts luts)
		{
			if (luts >= Luts.Modality && LutComposer.ModalityLut == null)
			{
				var lut = LutFactory.GetModalityLutLinear(BitsStored, IsSigned, RescaleSlope, RescaleIntercept);

				LutComposer.ModalityLut = lut;
			}

			if (luts >= Luts.Voi && LutComposer.VoiLut == null)
			{
				var lut = new IdentityVoiLinearLut();

				(this as IVoiLutInstaller).InstallVoiLut(lut);
			}
		}