public void AddSeriesDisplaySets(IImageSet imageSet, Series series) { var factory = GetDisplaySetFactory(series.Modality); if (factory == null) { factory = _defaultDisplaySetFactory; } else { var modalityDisplaySetExists = null != (from displaySet in imageSet.DisplaySets where displaySet.Descriptor is ModalityDisplaySetDescriptor && ((ModalityDisplaySetDescriptor) displaySet.Descriptor).Modality == series.Modality select displaySet).FirstOrDefault(); //Tell the factory whether we've created an "all images" display set containing //all the images in the entire study for the given modality. ((DisplaySetFactory)factory).ModalityDisplaySetExists = modalityDisplaySetExists; } //Add all the display sets derived from single series next. List<IDisplaySet> displaySets = factory.CreateDisplaySets(series); foreach (IDisplaySet displaySet in displaySets) imageSet.DisplaySets.Add(displaySet); }
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; } var overlayFrames = GetFrames(series.Sops); using (var fusionOverlayData = new FusionOverlayData(overlayFrames)) { 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); using (var sops = new DisposableList<Sop>(baseSeries.Sops.OfType<ImageSop>().Select(s => new ImageSop(new FusionSopDataSource(s.DataSource, _fusionType, overlayFrames))))) { foreach (var baseFrame in GetFrames(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; }
private IDisplaySet CreateSeriesDisplaySet(Series series) { IDisplaySet displaySet = null; List<IPresentationImage> images = new List<IPresentationImage>(); foreach (Sop sop in series.Sops) images.AddRange(PresentationImageFactory.CreateImages(sop)); if (images.Count > 0) { DisplaySetDescriptor descriptor = new SeriesDisplaySetDescriptor(series.GetIdentifier(), PresentationImageFactory); displaySet = new DisplaySet(descriptor); foreach (IPresentationImage image in images) displaySet.PresentationImages.Add(image); } return displaySet; }
/// <summary> /// Creates <see cref="IDisplaySet"/>s from the given <see cref="Series"/>. /// </summary> /// <param name="series">The series for which <see cref="IDisplaySet"/>s are to be created.</param> /// <returns>A list of created <see cref="IDisplaySet"/>s.</returns> public override List<IDisplaySet> CreateDisplaySets(Series series) { if (CreateSingleImageDisplaySets) return DoCreateSingleImageDisplaySets(series); var displaySets = new List<IDisplaySet>(); var displaySet = CreateSeriesDisplaySet(series); if (displaySet != null) { displaySet.PresentationImages.Sort(); displaySets.Add(displaySet); } return displaySets; }
private void MakeEchoSeries(Series series) { int i = 0; foreach (Sop sop in series.Sops) { TestDataSource dataSource = (TestDataSource)sop.DataSource; int echoNumber = (++i <= 5) ? 1 : 2; dataSource._file.DataSet[DicomTags.EchoNumbers].SetInt32(0, echoNumber); } }
private IEnumerable<Series> FindFuseableBaseSeries(Series petSeries) { var petStudy = petSeries.ParentStudy; if (petStudy == null) yield break; foreach (var series in petStudy.Series) { if (CanFuse(series, petSeries)) yield return series; } }
public override List<IDisplaySet> CreateDisplaySets(Series series) { var displaySets = new List<IDisplaySet>(); bool showOriginal = true; if (SplitMultiEchoSeries) { List<IDisplaySet> echoDisplaySets = _echoFactory.CreateDisplaySets(series); if (echoDisplaySets.Count > 0 && !ShowOriginalMREchoSeries) showOriginal = false; displaySets.AddRange(echoDisplaySets); } if (SplitMixedMultiframeSeries) { List<IDisplaySet> multiFrameDisplaySets = _mixedMultiFrameFactory.CreateDisplaySets(series); if (multiFrameDisplaySets.Count > 0 && !ShowOriginalMixedMultiframeSeries) showOriginal = false; displaySets.AddRange(multiFrameDisplaySets); } bool modalityDegenerateCase = CreateAllImagesDisplaySet && !ModalityDisplaySetExists; bool singleImageDegenerateCase = false; if (CreateSingleImageDisplaySets) { //The factory will only create single image display sets and will not create a series //display set for the degenerate case of one image in a series. In the case where //the user wants to see "single image" display sets, we actually create a series //display set (below) for the degenerate case, because that's technically more correct. _basicFactory.CreateSingleImageDisplaySets = true; var singleImageDisplaySets = new List<IDisplaySet>(); foreach (IDisplaySet displaySet in _basicFactory.CreateDisplaySets(series)) singleImageDisplaySets.Add(displaySet); displaySets.AddRange(singleImageDisplaySets); singleImageDegenerateCase = singleImageDisplaySets.Count == 0; } //Show the original if: // 1. A previous part of this method hasn't already disabled it. // 2. The user wants to see it, or // 3. It's a degenerate case showOriginal = showOriginal && (ShowOriginalSeries || modalityDegenerateCase || singleImageDegenerateCase); if (showOriginal) { //The factory will create series display sets only. _basicFactory.CreateSingleImageDisplaySets = false; foreach (IDisplaySet displaySet in _basicFactory.CreateDisplaySets(series)) displaySets.Add(displaySet); } bool anyDisplaySetsCreated = displaySets.Count > 0 || ModalityDisplaySetExists; if (!anyDisplaySetsCreated) displaySets.AddRange(_placeholderDisplaySetFactory.CreateDisplaySets(series)); foreach (var factory in _externalFactories) displaySets.AddRange(factory.CreateDisplaySets(series)); return displaySets; }
public override List<IDisplaySet> CreateDisplaySets(Series series) { throw new NotSupportedException(); }
/// <summary> /// Creates zero or more <see cref="IDisplaySet"/>s from the given <see cref="Series"/>. /// </summary> /// <remarks> /// When the input <see cref="Series"/> does not have multiple echoes, no <see cref="IDisplaySet"/>s will be returned. /// Otherwise, at least 2 <see cref="IDisplaySet"/>s will be returned. /// </remarks> public override List<IDisplaySet> CreateDisplaySets(Series series) { List<IDisplaySet> displaySets = new List<IDisplaySet>(); if (series.Modality == "MR") { SortedDictionary<int, List<Sop>> imagesByEchoNumber = SplitMREchos(series.Sops); if (imagesByEchoNumber.Count > 1) { foreach (KeyValuePair<int, List<Sop>> echoImages in imagesByEchoNumber) { List<IPresentationImage> images = new List<IPresentationImage>(); foreach (ImageSop sop in echoImages.Value) images.AddRange(PresentationImageFactory.CreateImages(sop)); if (images.Count > 0) { IDisplaySet displaySet = new DisplaySet(new MREchoDisplaySetDescriptor(series.GetIdentifier(), echoImages.Key, PresentationImageFactory)); foreach (IPresentationImage image in images) displaySet.PresentationImages.Add(image); displaySet.PresentationImages.Sort(); displaySets.Add(displaySet); } } } } return displaySets; }
public bool CheckBaseSeries(Series series, out string error) { if (!IsValidBaseSeries(series)) { error = SR.MessageInvalidSeries; return false; } var frames = GetFrames(series.Sops); if (!AssertSameSeriesFrameOfReference(frames)) { error = SR.MessageInconsistentFramesOfReference; return false; } foreach (Frame frame in frames) { if (frame.ImageOrientationPatient.IsNull) { error = SR.MessageMissingImageOrientation; return false; } //TODO (CR Sept 2010): ImagePositionPatient? if (frame.NormalizedPixelSpacing.IsNull) { error = SR.MessageMissingPixelSpacing; return false; } } error = null; return true; }
public bool IsValidBaseSeries(Series series) { switch (_fusionType) { case PETFusionType.CT: if (series.Modality != _fusionType.ToString()) return false; var frames = GetFrames(series.Sops); if (frames.Count < 5) return false; return true; } return false; }
private static DisplaySet CreateFusionErrorDisplaySet(Series baseSeries, Series fusionSeries, string error) { // create a basic descriptor that's templated from the real PET fusion display descriptor var baseDescriptor = new PETFusionDisplaySetDescriptor(baseSeries.GetIdentifier(), fusionSeries.GetIdentifier(), IsAttenuationCorrected(fusionSeries.Sops[0])); var descriptor = new BasicDisplaySetDescriptor {Description = baseDescriptor.Description, Name = baseDescriptor.Name, Number = baseDescriptor.Number, Uid = baseDescriptor.Uid}; var displaySet = new DisplaySet(descriptor); displaySet.PresentationImages.Add(new ErrorPresentationImage(SR.MessageFusionError + Environment.NewLine + string.Format(SR.FormatReason, error))); return displaySet; }
private void AddSeries(Sop sop) { Series series; if (_series.ContainsKey(sop.SeriesInstanceUid)) { series = _series[sop.SeriesInstanceUid]; } else { Study study = _studies[sop.StudyInstanceUid]; series = new Series(study); series.SetSop(sop); study.Series.Add(series); _series[series.SeriesInstanceUid] = series; } sop.ParentSeries = series; series.Sops.Add(sop); }
/// <summary> /// Creates zero or more <see cref="IDisplaySet"/>s from the given <see cref="Series"/>. /// </summary> /// <returns>Zero or more <see cref="IDisplaySet"/>s.</returns> public abstract List<IDisplaySet> CreateDisplaySets(Series series);
private List<IDisplaySet> DoCreateSingleImageDisplaySets(Series series) { List<IDisplaySet> displaySets = new List<IDisplaySet>(); int position = 0; foreach (Sop sop in series.Sops) { List<IPresentationImage> images = PresentationImageFactory.CreateImages(sop); if (images.Count == 0) continue; if (sop.IsImage) { ImageSop imageSop = (ImageSop)sop; DicomDisplaySetDescriptor descriptor; if (imageSop.NumberOfFrames == 1) descriptor = new SingleImageDisplaySetDescriptor(series.GetIdentifier(), imageSop, position++); else descriptor = new MultiframeDisplaySetDescriptor(series.GetIdentifier(), sop.SopInstanceUid, sop.InstanceNumber); DisplaySet displaySet = new DisplaySet(descriptor); foreach (IPresentationImage image in images) displaySet.PresentationImages.Add(image); displaySets.Add(displaySet); } else { //The sop is actually a container for other referenced sops, like key images. foreach (IPresentationImage image in images) { DisplaySetDescriptor descriptor = null; if (image is IImageSopProvider) { IImageSopProvider provider = (IImageSopProvider) image; if (provider.ImageSop.NumberOfFrames == 1) descriptor = new SingleImageDisplaySetDescriptor(series.GetIdentifier(), provider.ImageSop, position++); else descriptor = new SingleFrameDisplaySetDescriptor(series.GetIdentifier(), provider.Frame, position++); } else { //TODO (CR Jan 2010): this because the design here is funny... the factory here should actually know something about the key object series it is building for ISeriesIdentifier sourceSeries = series.GetIdentifier(); descriptor = new BasicDisplaySetDescriptor(); descriptor.Description = sourceSeries.SeriesDescription; descriptor.Name = string.Format("{0}: {1}", sourceSeries.SeriesNumber, sourceSeries.SeriesDescription); descriptor.Number = sourceSeries.SeriesNumber.GetValueOrDefault(0); descriptor.Uid = sourceSeries.SeriesInstanceUid; } DisplaySet displaySet = new DisplaySet(descriptor); displaySet.PresentationImages.Add(image); displaySets.Add(displaySet); } } } if (displaySets.Count == 1) { //Degenerate case; single image series, which we're not supposed to create. displaySets[0].Dispose(); displaySets.Clear(); } return displaySets; }
internal static IEnumerable<IDisplaySet> CreateSeriesDisplaySets(Series series, StudyTree studyTree) { BasicDisplaySetFactory factory = new BasicDisplaySetFactory(); factory.SetStudyTree(studyTree); return factory.CreateDisplaySets(series); }
public bool IsValidPETFusionSeries(Series series) { if (series.Modality != _petModality) return false; var frames = GetFrames(series.Sops); if (frames.Count < 5) return false; return true; }
/// <summary> /// Creates zero or more <see cref="IDisplaySet"/>s from the given <see cref="Series"/>. /// </summary> /// <remarks>When the input series does not contain a mixture of single and multiframe /// images, no <see cref="IDisplaySet"/>s will be returned.</remarks> public override List<IDisplaySet> CreateDisplaySets(Series series) { List<IDisplaySet> displaySets = new List<IDisplaySet>(); List<ImageSop> singleFrames = new List<ImageSop>(); List<ImageSop> multiFrames = new List<ImageSop>(); foreach (Sop sop in series.Sops) { if (sop.IsImage) { ImageSop imageSop = (ImageSop)sop; if (imageSop.NumberOfFrames > 1) multiFrames.Add(imageSop); else singleFrames.Add(imageSop); } } if (multiFrames.Count > 1 || (singleFrames.Count > 0 && multiFrames.Count > 0)) { if (singleFrames.Count > 0) { List<IPresentationImage> singleFrameImages = new List<IPresentationImage>(); foreach (ImageSop singleFrame in singleFrames) singleFrameImages.AddRange(PresentationImageFactory.CreateImages(singleFrame)); if (singleFrameImages.Count > 0) { var descriptor = new SingleImagesDisplaySetDescriptor(series.GetIdentifier(), PresentationImageFactory); var singleImagesDisplaySet = new DisplaySet(descriptor); foreach (IPresentationImage singleFrameImage in singleFrameImages) singleImagesDisplaySet.PresentationImages.Add(singleFrameImage); singleImagesDisplaySet.PresentationImages.Sort(); displaySets.Add(singleImagesDisplaySet); } } foreach (ImageSop multiFrame in multiFrames) { List<IPresentationImage> multiFrameImages = PresentationImageFactory.CreateImages(multiFrame); if (multiFrameImages.Count > 0) { MultiframeDisplaySetDescriptor descriptor = new MultiframeDisplaySetDescriptor(multiFrame.ParentSeries.GetIdentifier(), multiFrame.SopInstanceUid, multiFrame.InstanceNumber); DisplaySet displaySet = new DisplaySet(descriptor); foreach (IPresentationImage multiFrameImage in multiFrameImages) displaySet.PresentationImages.Add(multiFrameImage); displaySet.PresentationImages.Sort(); displaySets.Add(displaySet); } } } return displaySets; }
public bool CheckPETFusionSeries(Series series, out string error) { if (!IsValidPETFusionSeries(series)) { error = SR.MessageInvalidSeries; return false; } var frames = GetFrames(series.Sops); if (!AssertSameSeriesFrameOfReference(frames)) { error = SR.MessageInconsistentFramesOfReference; return false; } // ensure all frames have the same orientation ImageOrientationPatient orient = frames[0].ImageOrientationPatient; double minColumnSpacing = double.MaxValue, minRowSpacing = double.MaxValue; double maxColumnSpacing = double.MinValue, maxRowSpacing = double.MinValue; foreach (Frame frame in frames) { if (frame.ImageOrientationPatient.IsNull) { error = SR.MessageMissingImageOrientation; return false; } if (!frame.ImageOrientationPatient.EqualsWithinTolerance(orient, _orientationTolerance)) { error = SR.MessageInconsistentImageOrientation; return false; } PixelSpacing pixelSpacing = frame.NormalizedPixelSpacing; if (pixelSpacing.IsNull) { error = SR.MessageMissingPixelSpacing; return false; } minColumnSpacing = Math.Min(minColumnSpacing, pixelSpacing.Column); maxColumnSpacing = Math.Max(maxColumnSpacing, pixelSpacing.Column); minRowSpacing = Math.Min(minRowSpacing, pixelSpacing.Row); maxRowSpacing = Math.Max(maxRowSpacing, pixelSpacing.Row); } //Aren't many of these rules taken from MPR? If so, we should create a rule object. // ensure all frames have consistent pixel spacing if (maxColumnSpacing - minColumnSpacing > _sliceSpacingTolerance || maxRowSpacing - minRowSpacing > _sliceSpacingTolerance) { error = SR.MessageInconsistentPixelSpacing; return false; } // ensure all frames are sorted by slice location frames.Sort(new SliceLocationComparer().Compare); // ensure all frames are equally spaced float? nominalSpacing = null; for (int i = 1; i < frames.Count; i++) { float currentSpacing = CalcSpaceBetweenPlanes(frames[i], frames[i - 1]); if (currentSpacing < _minimumSliceSpacing) { error = SR.MessageInconsistentImageSpacing; return false; } if (!nominalSpacing.HasValue) nominalSpacing = currentSpacing; if (!FloatComparer.AreEqual(currentSpacing, nominalSpacing.Value, _sliceSpacingTolerance)) { error = SR.MessageInconsistentImageSpacing; return false; } } // 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!! { error = SR.MessageUnsupportedGantryTilt; return false; } error = null; return true; }
public override List<IDisplaySet> CreateDisplaySets(Series series) { var images = new List<IPresentationImage>(); foreach (var sop in series.Sops) { // TODO CR (Oct 11): To be reworked before next Community release, since we do want this to show // only create placeholders for any non-image, non-presentation state SOPs if (sop.IsImage || sop.SopClassUid == SopClass.EncapsulatedPdfStorageUid || sop.SopClassUid == SopClass.GrayscaleSoftcopyPresentationStateStorageSopClassUid || sop.SopClassUid == SopClass.ColorSoftcopyPresentationStateStorageSopClassUid || sop.SopClassUid == SopClass.PseudoColorSoftcopyPresentationStateStorageSopClassUid || sop.SopClassUid == SopClass.BlendingSoftcopyPresentationStateStorageSopClassUid) continue; images.Add(new PlaceholderPresentationImage(sop)); } if (images.Count > 0) { var displaySet = new DisplaySet(new SeriesDisplaySetDescriptor(series.GetIdentifier(), PresentationImageFactory)); foreach (var image in images) displaySet.PresentationImages.Add(image); return new List<IDisplaySet>(new[] { displaySet }); } return new List<IDisplaySet>(); }
public bool CanFuse(Series baseSeries, Series petSeries) { if (!IsValidBaseSeries(baseSeries)) return false; if (!IsValidPETFusionSeries(petSeries)) return false; var baseFrames = GetFrames(baseSeries.Sops); var petFrames = GetFrames(petSeries.Sops); if (baseFrames[0].StudyInstanceUid != petFrames[0].StudyInstanceUid) return false; return true; }