public PresentationStateReference(DicomSoftcopyPresentationState presentationState) : base(presentationState.DicomFile.DataSet[DicomTags.StudyInstanceUid].ToString(), presentationState.PresentationSeriesInstanceUid, presentationState.PresentationSopClassUid, presentationState.PresentationSopInstanceUid, presentationState.DicomFile.MetaInfo[DicomTags.SourceApplicationEntityTitle].ToString()) { }
protected virtual List <IPresentationImage> CreateImages(KeyImageContentItem item) { List <IPresentationImage> images = new List <IPresentationImage>(); ImageSop imageSop = FindReferencedImageSop(item.ReferencedImageSopInstanceUid, item.Source.GeneralStudy.StudyInstanceUid); if (imageSop != null) { int frameNumber = item.FrameNumber.GetValueOrDefault(-1); if (item.FrameNumber.HasValue) { // FramesCollection is a 1-based index!!! if (frameNumber > 0 && frameNumber <= imageSop.Frames.Count) { images.Add(Create(imageSop.Frames[frameNumber])); } else { Platform.Log(LogLevel.Error, "The referenced key image {0} does not have a frame {1} (referenced in Key Object Selection {2})", item.ReferencedImageSopInstanceUid, frameNumber, item.Source.SopCommon.SopInstanceUid); images.Add(new KeyObjectPlaceholderImage(SR.MessageReferencedKeyImageFrameNotFound)); } } else { foreach (Frame frame in imageSop.Frames) { images.Add(Create(frame)); } } Sop presentationStateSop = FindReferencedSop(item.PresentationStateSopInstanceUid, item.Source.GeneralStudy.StudyInstanceUid); if (presentationStateSop != null) { foreach (IPresentationImage image in images) { if (image is IPresentationStateProvider) { try { IPresentationStateProvider presentationStateProvider = (IPresentationStateProvider)image; presentationStateProvider.PresentationState = DicomSoftcopyPresentationState.Load(presentationStateSop.DataSource); } catch (Exception ex) { Platform.Log(LogLevel.Warn, ex, SR.MessagePresentationStateReadFailure); } } } } } else { Platform.Log(LogLevel.Warn, "The referenced key image {0} is not loaded as part of the current study (referenced in Key Object Selection {1})", item.ReferencedImageSopInstanceUid, item.Source.SopCommon.SopInstanceUid); images.Add(new KeyObjectPlaceholderImage(SR.MessageReferencedKeyImageFromOtherStudy)); } return(images); }
/// <remarks> /// The current implementation of <see cref="KeyImagePublisher"/> supports only locally stored images that are <see cref="IImageSopProvider"/>s and supports <see cref="DicomSoftcopyPresentationState"/>s. /// </remarks> public static bool IsSupportedImage(IPresentationImage image) { var imageSopProvider = image as IImageSopProvider; if (imageSopProvider == null) { return(false); } return(imageSopProvider.ImageSop.DataSource.IsStored && DicomSoftcopyPresentationState.IsSupported(image)); }
public void Add(DicomSoftcopyPresentationState state) { IDicomAttributeProvider dataset = state.DicomFile.DataSet; bool result = base.TryAddReference(dataset[DicomTags.StudyInstanceUid], state.PresentationSeriesInstanceUid, state.PresentationSopClassUid, state.PresentationSopInstanceUid); if (result && !_seriesInfo.ContainsKey(state.PresentationSeriesInstanceUid)) { SeriesInfo seriesInfo = new SeriesInfo(); seriesInfo.RetrieveAeTitle = dataset[DicomTags.RetrieveAeTitle].ToString(); seriesInfo.StorageMediaFileSetId = dataset[DicomTags.StorageMediaFileSetId].GetString(0, string.Empty); seriesInfo.StorageMediaFileSetUid = dataset[DicomTags.StorageMediaFileSetUid].GetString(0, string.Empty); _seriesInfo.Add(state.PresentationSeriesInstanceUid, seriesInfo); } }
public void TestKeyImages(int numberOfFrames, int numberOfMultiframeKeyImages, int numberOfSingleFrameKeyImages, bool doSplitting) { Assert.IsTrue(numberOfFrames == 0 || numberOfFrames > 1); Assert.IsTrue(numberOfMultiframeKeyImages <= numberOfFrames); const int numberOfSeries = 1; int instancesPerSeries = numberOfSingleFrameKeyImages + ((numberOfFrames > 0) ? 1 : 0); Assert.IsTrue(instancesPerSeries > 0); List <TestDataSource> dataSources = CreateMRStudyDataSources(numberOfSeries, instancesPerSeries, "1.2.3"); if (numberOfFrames > 0) { TestDataSource multiFrameDataSource = dataSources[0]; DicomAttributeCollection oldDataSet = multiFrameDataSource.File.DataSet; DicomAttributeCollection newDataSet = new DicomAttributeCollection(); DicomFile newFile = new DicomFile("", new DicomAttributeCollection(), newDataSet); //Yes this is the world's crappiest hack. base.SetupMultiframeXA(newDataSet, 512, 512, (uint)numberOfFrames); //because of an exception that gets thrown from the DateTimeParser newDataSet[DicomTags.StudyDate].SetNullValue(); newDataSet[DicomTags.StudyTime].SetNullValue(); newDataSet[DicomTags.SeriesDate].SetNullValue(); newDataSet[DicomTags.SeriesTime].SetNullValue(); newDataSet[DicomTags.ReferencedStudySequence].SetEmptyValue(); newDataSet[DicomTags.Modality].SetStringValue("MR"); newDataSet[DicomTags.StudyInstanceUid].SetStringValue(oldDataSet[DicomTags.StudyInstanceUid].ToString()); newDataSet[DicomTags.SeriesInstanceUid].SetStringValue(oldDataSet[DicomTags.SeriesInstanceUid].ToString()); dataSources[0] = new TestDataSource(newFile); } StudyTree studyTree = CreateStudyTree(ConvertToSops(dataSources)); KeyImageSerializer serializer = new KeyImageSerializer(); Patient patient = studyTree.Patients[0]; Study study = patient.Studies[0]; Series sourceSeries = study.Series[0]; List <IDisplaySet> allDisplaySets = new List <IDisplaySet>(); BasicDisplaySetFactory factory = new BasicDisplaySetFactory(); factory.SetStudyTree(studyTree); List <IDisplaySet> displaySets = factory.CreateDisplaySets(sourceSeries); allDisplaySets.AddRange(displaySets); List <DicomFile> presentationStates = new List <DicomFile>(); int numberOfMultiframeKeyImagesCreated = 0; foreach (IDisplaySet displaySet in displaySets) { foreach (IPresentationImage image in displaySet.PresentationImages) { Frame frame = ((IImageSopProvider)image).Frame; if (frame.ParentImageSop.NumberOfFrames > 1) { if (numberOfMultiframeKeyImagesCreated >= numberOfMultiframeKeyImages) { continue; } ++numberOfMultiframeKeyImagesCreated; } DicomSoftcopyPresentationState presentationState = DicomSoftcopyPresentationState.Create(image); //because of an exception that gets thrown from the DateTimeParser presentationState.DicomFile.DataSet[DicomTags.StudyDate].SetNullValue(); presentationState.DicomFile.DataSet[DicomTags.StudyTime].SetNullValue(); presentationState.DicomFile.DataSet[DicomTags.SeriesDate].SetNullValue(); presentationState.DicomFile.DataSet[DicomTags.SeriesTime].SetNullValue(); presentationStates.Add(presentationState.DicomFile); serializer.AddImage(frame, presentationState); } } List <DicomFile> files = serializer.Serialize(); List <TestDataSource> keyImageDataSources = ConvertToDataSources(files); List <Sop> keyImageSops = ConvertToSops(keyImageDataSources); keyImageSops.AddRange(ConvertToSops(ConvertToDataSources(presentationStates))); foreach (Sop sop in keyImageSops) { studyTree.AddSop(sop); } try { foreach (Series series in study.Series) { if (series.Modality != "KO") { continue; } List <IDisplaySet> keyImageDisplaySets; if (doSplitting) { factory.CreateSingleImageDisplaySets = true; keyImageDisplaySets = factory.CreateDisplaySets(series); if (keyImageDisplaySets.Count == 0) { factory.CreateSingleImageDisplaySets = false; keyImageDisplaySets = factory.CreateDisplaySets(series); } } else { keyImageDisplaySets = factory.CreateDisplaySets(series); } allDisplaySets.AddRange(keyImageDisplaySets); int numberOfKeyImages = numberOfMultiframeKeyImages + numberOfSingleFrameKeyImages; if (!doSplitting) { Assert.AreEqual(1, keyImageDisplaySets.Count, "There should be only one display set"); IDisplaySet keyImageDisplaySet = keyImageDisplaySets[0]; Assert.AreEqual(numberOfKeyImages, keyImageDisplaySet.PresentationImages.Count, "Expected {0} images", numberOfKeyImages); Assert.AreEqual(typeof(KOSelectionDocumentDisplaySetDescriptor), keyImageDisplaySet.Descriptor.GetType(), "Wrong display set descriptor type"); } else { Assert.AreEqual(numberOfKeyImages, keyImageDisplaySets.Count, "Expected {0} display sets", numberOfKeyImages); foreach (IDisplaySet keyImageDisplaySet in keyImageDisplaySets) { Assert.AreEqual(1, keyImageDisplaySet.PresentationImages.Count, "There should be only one presentation image"); IPresentationImage keyImage = keyImageDisplaySet.PresentationImages[0]; ImageSop sop = ((IImageSopProvider)keyImage).ImageSop; Assert.AreEqual(sourceSeries.SeriesInstanceUid, sop.SeriesInstanceUid, "Series Instance Uid is not that of the source series"); if (numberOfKeyImages == 1) { Assert.AreEqual(typeof(KOSelectionDocumentDisplaySetDescriptor), keyImageDisplaySet.Descriptor.GetType(), "Wrong display set descriptor type"); } else if (sop.NumberOfFrames > 1) { Assert.AreEqual(typeof(KOSelectionSingleFrameDisplaySetDescriptor), keyImageDisplaySet.Descriptor.GetType(), "Wrong display set descriptor type"); } else { Assert.AreEqual(typeof(KOSelectionSingleImageDisplaySetDescriptor), keyImageDisplaySet.Descriptor.GetType(), "Wrong display set descriptor type"); } } } } } finally { foreach (IDisplaySet displaySet in allDisplaySets) { displaySet.Dispose(); } studyTree.Dispose(); } }
/// <summary> /// Creates all the SOP instances associated with the key object selection and the content presentation states. /// </summary> public IDictionary <IStudySource, List <DicomFile> > CreateSopInstances(NextSeriesNumberDelegate nextSeriesNumberDelegate) { if (!HasChanges || !Items.Any()) { return(new Dictionary <IStudySource, List <DicomFile> >(0)); } // update the author field Author = GetUserName(); // the series index ensures consistent series level data because we only create one KO series and one PR series per study var studyIndex = new Dictionary <string, StudyInfo>(); var secondaryCaptureImageFactory = new SecondaryCaptureImageFactory(nextSeriesNumberDelegate); var framePresentationStates = new List <KeyValuePair <KeyImageReference, PresentationStateReference> >(); // create presentation states for the images in the clipboard var presentationStates = new List <DicomSoftcopyPresentationState>(); foreach (var item in Items.Where(i => i.Item is IPresentationImage)) { var image = (IPresentationImage)item.Item; // if the item is a placeholder image (e.g. because source study wasn't available), simply reserialize the original sop references if (image is KeyObjectPlaceholderImage) { // because source study wasn't available, we don't have enough information to create the identical KO for that study // and thus an entry in the study index table is not needed var ko = (KeyObjectPlaceholderImage)image; framePresentationStates.Add(new KeyValuePair <KeyImageReference, PresentationStateReference>(ko.KeyImageReference, ko.PresentationStateReference)); continue; } var provider = image as IImageSopProvider; if (provider == null) { continue; } StudyInfo studyInfo; var studyInstanceUid = provider.ImageSop.StudyInstanceUid; if (!studyIndex.TryGetValue(studyInstanceUid, out studyInfo)) { studyIndex.Add(studyInstanceUid, studyInfo = new StudyInfo(provider, nextSeriesNumberDelegate)); // keep the previous series number if the one we know about is the same study as this new document // otherwise, pre-allocate a series number for the KO now (ensures the number will be lower than any SC and PR series) if (_parentStudyInstanceUid == studyInstanceUid && _seriesNumber.HasValue) { studyInfo.KeyObjectSeriesNumber = _seriesNumber.Value; } else { studyInfo.AllocateKeyObjectSeriesNumber(); } } // if the item doesn't have changes and the presentation state is DICOM, simply reserialize the original sop references if (!item.HasChanges() && image is IDicomPresentationImage) { var dicomPresentationState = ((IDicomPresentationImage)image).PresentationState as DicomSoftcopyPresentationState; framePresentationStates.Add(new KeyValuePair <KeyImageReference, PresentationStateReference>(provider.Frame, dicomPresentationState)); continue; } // if the image is not a permanent stored instance (i.e. it was dynamically generated), create a secondary capture from it if (!provider.Sop.DataSource.IsStored) { image = secondaryCaptureImageFactory.CreateSecondaryCapture(image); provider = (IImageSopProvider)image; } var presentationState = DicomSoftcopyPresentationState.IsSupported(image) ? DicomSoftcopyPresentationState.Create (image, ps => { ps.PresentationSeriesInstanceUid = studyInfo.PresentationSeriesUid; ps.PresentationSeriesNumber = studyInfo.PresentationSeriesNumber; ps.PresentationSeriesDateTime = studyInfo.PresentationSeriesDateTime; ps.PresentationInstanceNumber = studyInfo.GetNextPresentationInstanceNumber(); ps.SourceAETitle = provider.ImageSop.DataSource[DicomTags.SourceApplicationEntityTitle].ToString(); }) : null; if (presentationState != null) { presentationStates.Add(presentationState); } framePresentationStates.Add(new KeyValuePair <KeyImageReference, PresentationStateReference>(provider.Frame, presentationState)); } // serialize the key image document var serializer = new KeyImageSerializer(); serializer.Author = Author; serializer.Description = Description; serializer.DocumentTitle = DocumentTitle; serializer.SeriesDescription = SeriesDescription; foreach (var presentationFrame in framePresentationStates) { serializer.AddImage(presentationFrame.Key, presentationFrame.Value); } // collect all the SOP instances that were created (SC, PR and KO) var documents = new List <DicomFile>(); documents.AddRange(serializer.Serialize(koSeries => { var uid = koSeries.StudyInstanceUid; if (studyIndex.ContainsKey(uid)) { koSeries.SeriesDateTime = studyIndex[uid].KeyObjectSeriesDateTime; koSeries.SeriesNumber = studyIndex[uid].KeyObjectSeriesNumber; koSeries.SeriesInstanceUid = studyIndex[uid].KeyObjectSeriesUid; return(studyIndex[uid].DataSource); } return(null); } )); documents.AddRange(secondaryCaptureImageFactory.Files); documents.AddRange(presentationStates.Select(ps => ps.DicomFile)); // return the created instances grouped by study (and thus study origin/source) return(documents.GroupBy(f => (IStudySource)studyIndex[f.DataSet[DicomTags.StudyInstanceUid].ToString()]).ToDictionary(g => g.Key, g => g.ToList())); }
public static void AddKeyImage(IPresentationImage image) { Platform.CheckForNullReference(image, "image"); Platform.CheckForNullReference(image.ImageViewer, "image.ImageViewer"); // TODO (CR Phoenix5 - Med): Clinical as well if (!PermissionsHelper.IsInRole(AuthorityTokens.KeyImages)) { throw new PolicyException(SR.ExceptionCreateKeyImagePermissionDenied); } var sopProvider = image as IImageSopProvider; if (sopProvider == null) { throw new ArgumentException("The image must be an IImageSopProvider.", "image"); } IDisplaySet displaySet = null; foreach (var set in image.ImageViewer.LogicalWorkspace.ImageSets) { if (set.Descriptor.Equals(image.ParentDisplaySet.ParentImageSet.Descriptor)) { foreach (var d in set.DisplaySets) { var displaySetDescriptor = d.Descriptor as KeyImageDisplaySetDescriptor; if (displaySetDescriptor != null && displaySetDescriptor.SourceStudy.StudyInstanceUid.Equals(sopProvider.Sop.StudyInstanceUid)) { displaySet = d; break; } } break; } } if (displaySet == null) { var displaySetDescriptor = new KeyImageDisplaySetDescriptor(new StudyIdentifier(sopProvider.ImageSop)); displaySet = new DisplaySet(displaySetDescriptor); bool displaySetAdded = false; foreach (var imageSet in image.ImageViewer.LogicalWorkspace.ImageSets) { if (imageSet.Descriptor.Equals(image.ParentDisplaySet.ParentImageSet.Descriptor)) { imageSet.DisplaySets.Add(displaySet); displaySetAdded = true; break; } } if (!displaySetAdded) { throw new ApplicationException(SR.MessageCreateKeyImageFailed); } } var presentationImage = image.CreateFreshCopy(); var presentationState = DicomSoftcopyPresentationState.Create(image); var basicImage = presentationImage as BasicPresentationImage; if (basicImage != null) { basicImage.PresentationState = presentationState; } displaySet.PresentationImages.Add(presentationImage); foreach (var imageBox in image.ImageViewer.PhysicalWorkspace.ImageBoxes) { if (imageBox.DisplaySet != null && imageBox.DisplaySet.Descriptor.Uid == displaySet.Descriptor.Uid) { var physicalImage = presentationImage.CreateFreshCopy(); presentationState = DicomSoftcopyPresentationState.Create(image); basicImage = physicalImage as BasicPresentationImage; if (basicImage != null) { basicImage.PresentationState = presentationState; } imageBox.DisplaySet.PresentationImages.Add(physicalImage); imageBox.Draw(); } } }
/// <summary> /// Adds a frame and associated presentation state to the serialization queue. /// </summary> public void AddImage(Frame frame, DicomSoftcopyPresentationState presentationState) { AddImage((KeyImageReference)frame, presentationState); }
/// <summary> /// Serializes the current contents into a number of key object selection document SOP instances. /// </summary> /// <param name="callback">A callback method to initialize the series-level attributes of the key object document.</param> public List <DicomFile> Serialize(InitializeKeyObjectDocumentSeriesCallback callback) { callback = callback ?? DefaultInitializeKeyObjectDocumentSeriesCallback; if (_framePresentationStates.Count == 0) { throw new InvalidOperationException("Key object selection cannot be empty."); } List <DicomFile> keyObjectDocuments = new List <DicomFile>(); List <IHierarchicalSopInstanceReferenceMacro> identicalDocuments = new List <IHierarchicalSopInstanceReferenceMacro>(); Dictionary <string, KeyObjectSelectionDocumentIod> koDocumentsByStudy = new Dictionary <string, KeyObjectSelectionDocumentIod>(); foreach (Frame frame in (IEnumerable <Frame>)_framePresentationStates) { string studyInstanceUid = frame.StudyInstanceUid; if (!koDocumentsByStudy.ContainsKey(studyInstanceUid)) { KeyObjectDocumentSeries seriesInfo = new KeyObjectDocumentSeries(frame.ParentImageSop.PatientId, studyInstanceUid); callback.Invoke(seriesInfo); DicomFile keyObjectDocument = new DicomFile(); keyObjectDocument.SourceApplicationEntityTitle = this.SourceAETitle; KeyObjectSelectionDocumentIod iod = CreatePrototypeDocument(frame.ParentImageSop.DataSource, keyObjectDocument.DataSet, SpecificCharacterSet); iod.GeneralEquipment.Manufacturer = this.Manufacturer ?? string.Empty; // this one is type 2 - all other GenEq attributes are type 3 iod.GeneralEquipment.ManufacturersModelName = string.IsNullOrEmpty(this.ManufacturersModelName) ? null : this.ManufacturersModelName; iod.GeneralEquipment.DeviceSerialNumber = string.IsNullOrEmpty(this.DeviceSerialNumber) ? null : this.DeviceSerialNumber; iod.GeneralEquipment.SoftwareVersions = string.IsNullOrEmpty(this.SoftwareVersions) ? null : this.SoftwareVersions; iod.GeneralEquipment.InstitutionName = string.IsNullOrEmpty(this.Institution.Name) ? null : this.Institution.Name; iod.GeneralEquipment.InstitutionAddress = string.IsNullOrEmpty(this.Institution.Address) ? null : this.Institution.Address; iod.GeneralEquipment.InstitutionalDepartmentName = string.IsNullOrEmpty(this.Institution.DepartmentName) ? null : this.Institution.DepartmentName; iod.GeneralEquipment.StationName = string.IsNullOrEmpty(this.StationName) ? null : this.StationName; string seriesDescription = _seriesDescription; if (!string.IsNullOrEmpty(_author)) { seriesDescription = string.Format("{0} ({1})", seriesDescription, _author); } iod.KeyObjectDocumentSeries.InitializeAttributes(); iod.KeyObjectDocumentSeries.Modality = Modality.KO; iod.KeyObjectDocumentSeries.SeriesDateTime = seriesInfo.SeriesDateTime; iod.KeyObjectDocumentSeries.SeriesDescription = seriesDescription; iod.KeyObjectDocumentSeries.SeriesInstanceUid = CreateUid(seriesInfo.SeriesInstanceUid); iod.KeyObjectDocumentSeries.SeriesNumber = seriesInfo.SeriesNumber ?? CalculateSeriesNumber(frame); iod.KeyObjectDocumentSeries.ReferencedPerformedProcedureStepSequence = null; iod.SopCommon.SopClass = SopClass.KeyObjectSelectionDocumentStorage; iod.SopCommon.SopInstanceUid = DicomUid.GenerateUid().UID; identicalDocuments.Add(iod.KeyObjectDocument.CreateIdenticalDocumentsSequence( studyInstanceUid, iod.KeyObjectDocumentSeries.SeriesInstanceUid, iod.SopCommon.SopClassUid, iod.SopCommon.SopInstanceUid)); koDocumentsByStudy.Add(studyInstanceUid, iod); keyObjectDocuments.Add(keyObjectDocument); } } foreach (KeyObjectSelectionDocumentIod iod in koDocumentsByStudy.Values) { iod.KeyObjectDocument.InitializeAttributes(); iod.KeyObjectDocument.InstanceNumber = 1; iod.KeyObjectDocument.ContentDateTime = _datetime; iod.KeyObjectDocument.ReferencedRequestSequence = null; iod.KeyObjectDocument.IdenticalDocumentsSequence = identicalDocuments.ToArray(); iod.SrDocumentContent.InitializeContainerAttributes(); iod.SrDocumentContent.ConceptNameCodeSequence = _docTitle; List <IContentSequence> contentList = new List <IContentSequence>(); EvidenceDictionary currentRequestedProcedureEvidenceList = new EvidenceDictionary(); Dictionary <ImageSop, List <int> > frameMap = new Dictionary <ImageSop, List <int> >(); foreach (KeyValuePair <Frame, DicomSoftcopyPresentationState> frameAndPresentationState in _framePresentationStates) { Frame frame = frameAndPresentationState.Key; ImageSop sop = frame.ParentImageSop; // build frame map by unique sop - used to make the evidence sequence less verbose if (!frameMap.ContainsKey(frame.ParentImageSop)) { frameMap.Add(frame.ParentImageSop, new List <int>()); } List <int> frames = frameMap[frame.ParentImageSop]; if (!frames.Contains(frame.FrameNumber)) { frames.Add(frame.FrameNumber); } // content sequence must still list all content as it was given, including any repeats IContentSequence content = iod.SrDocumentContent.CreateContentSequence(); { content.RelationshipType = RelationshipType.Contains; content.ReferencedContentItemIdentifier = new uint[] { 1 }; IImageReferenceMacro imageReferenceMacro = content.InitializeImageReferenceAttributes(); imageReferenceMacro.ReferencedSopSequence.InitializeAttributes(); imageReferenceMacro.ReferencedSopSequence.ReferencedSopClassUid = sop.SopClassUid; imageReferenceMacro.ReferencedSopSequence.ReferencedSopInstanceUid = sop.SopInstanceUid; if (sop.NumberOfFrames > 1) { imageReferenceMacro.ReferencedSopSequence.ReferencedFrameNumber = frame.FrameNumber.ToString(); } else { imageReferenceMacro.ReferencedSopSequence.ReferencedFrameNumber = null; } // save the presentation state if (frameAndPresentationState.Value != null) { DicomSoftcopyPresentationState presentationState = frameAndPresentationState.Value; imageReferenceMacro.ReferencedSopSequence.CreateReferencedSopSequence(); imageReferenceMacro.ReferencedSopSequence.ReferencedSopSequence.InitializeAttributes(); imageReferenceMacro.ReferencedSopSequence.ReferencedSopSequence.ReferencedSopClassUid = presentationState.PresentationSopClass.Uid; imageReferenceMacro.ReferencedSopSequence.ReferencedSopSequence.ReferencedSopInstanceUid = presentationState.PresentationSopInstanceUid; } } contentList.Add(content); } // add the description if (!string.IsNullOrEmpty(_description)) { IContentSequence koDescription = iod.SrDocumentContent.CreateContentSequence(); koDescription.InitializeAttributes(); koDescription.ConceptNameCodeSequence = KeyObjectSelectionCodeSequences.KeyObjectDescription; koDescription.TextValue = _description; koDescription.RelationshipType = RelationshipType.Contains; koDescription.ReferencedContentItemIdentifier = new uint[] { 1 }; contentList.Add(koDescription); } // add each unique sop to the evidence list using the map built earlier foreach (ImageSop sop in frameMap.Keys) { currentRequestedProcedureEvidenceList.Add(sop); } // add each referenced presentation state to the evidence list as well foreach (DicomSoftcopyPresentationState state in (IEnumerable <DicomSoftcopyPresentationState>)_framePresentationStates) { if (state == null) { continue; } currentRequestedProcedureEvidenceList.Add(state); } // set the content and the evidence sequences iod.SrDocumentContent.ContentSequence = contentList.ToArray(); iod.KeyObjectDocument.CurrentRequestedProcedureEvidenceSequence = currentRequestedProcedureEvidenceList.ToArray(); } // set meta for the files foreach (DicomFile keyObjectDocument in keyObjectDocuments) { keyObjectDocument.MediaStorageSopClassUid = keyObjectDocument.DataSet[DicomTags.SopClassUid].ToString(); keyObjectDocument.MediaStorageSopInstanceUid = keyObjectDocument.DataSet[DicomTags.SopInstanceUid].ToString(); } return(keyObjectDocuments); }
/// <summary> /// Adds a frame and associated presentation state to the serialization queue. /// </summary> public void AddImage(Frame frame, DicomSoftcopyPresentationState presentationState) { _framePresentationStates.Add(new KeyValuePair <Frame, DicomSoftcopyPresentationState>(frame, presentationState)); }
public IPresentationImage CreateSecondaryCapture(IPresentationImage image) { var imageSopProvider = image as IImageSopProvider; if (imageSopProvider == null) { const string msg = "image must implement IImageSopProvider"; throw new ArgumentException(msg, "image"); } SeriesInfo seriesInfo; var seriesKey = MakeSeriesKey(imageSopProvider.Frame.StudyInstanceUid, imageSopProvider.Sop.Modality); if (!_seriesInfo.TryGetValue(seriesKey, out seriesInfo)) { _seriesInfo[seriesKey] = seriesInfo = new SeriesInfo(_nextSeriesNumberDelegate.Invoke(imageSopProvider.Frame.StudyInstanceUid)); } var dcf = CreatePrototypeFile(imageSopProvider.Sop.DataSource); FillGeneralSeriesModule(dcf.DataSet, imageSopProvider.Frame, seriesInfo); FillScEquipmentModule(dcf.DataSet, Manufacturer, ManufacturersModelName, SoftwareVersions); FillFrameOfReferenceModule(dcf.DataSet, imageSopProvider.Frame); FillGeneralImageModule(dcf.DataSet, imageSopProvider.Frame, seriesInfo); FillScImageModule(dcf.DataSet, imageSopProvider.Frame); FillImagePlaneModule(dcf.DataSet, imageSopProvider.Frame); FillSopCommonModule(dcf.DataSet, SopClass.SecondaryCaptureImageStorageUid); FillAuxiliaryImageData(dcf.DataSet, imageSopProvider.Frame); if (image is GrayscalePresentationImage) { FillModalityLutModule(dcf.DataSet, imageSopProvider.Frame); FillVoiLutModule(dcf.DataSet, imageSopProvider.Frame); // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleGrayscale(dcf.DataSet, imageSopProvider.Frame); } else if (image is ColorPresentationImage) { // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleColor(dcf.DataSet, imageSopProvider.Frame); } else { // create image pixel last - this method may need to override some attributes set previously CreateImagePixelModuleRasterRgb(dcf.DataSet, image); } dcf.MediaStorageSopClassUid = dcf.DataSet[DicomTags.SopClassUid].ToString(); dcf.MediaStorageSopInstanceUid = dcf.DataSet[DicomTags.SopInstanceUid].ToString(); _files.Add(dcf); using (var sop = new ImageSop(new LocalSopDataSource(dcf))) { var secondaryCapture = PresentationImageFactory.Create(sop).Single(); try { var presentationState = DicomSoftcopyPresentationState.IsSupported(image) ? DicomSoftcopyPresentationState.Create(image) : null; if (presentationState != null) { presentationState.DeserializeOptions |= DicomSoftcopyPresentationStateDeserializeOptions.IgnoreImageRelationship; presentationState.Deserialize(secondaryCapture); // override the spatial transform of the secondary capture because the presentation state doesn't save exact parameters var sourceTransform = image as ISpatialTransformProvider; var targetTransform = secondaryCapture as ISpatialTransformProvider; if (sourceTransform != null && targetTransform != null) { targetTransform.SpatialTransform.CenterOfRotationXY = sourceTransform.SpatialTransform.CenterOfRotationXY; targetTransform.SpatialTransform.FlipX = sourceTransform.SpatialTransform.FlipX; targetTransform.SpatialTransform.FlipY = sourceTransform.SpatialTransform.FlipY; targetTransform.SpatialTransform.RotationXY = sourceTransform.SpatialTransform.RotationXY; targetTransform.SpatialTransform.Scale = sourceTransform.SpatialTransform.Scale; targetTransform.SpatialTransform.TranslationX = sourceTransform.SpatialTransform.TranslationX; targetTransform.SpatialTransform.TranslationY = sourceTransform.SpatialTransform.TranslationY; var sourceImageTransform = sourceTransform as IImageSpatialTransform; var targetImageTransform = targetTransform as IImageSpatialTransform; if (sourceImageTransform != null && targetImageTransform != null) { targetImageTransform.ScaleToFit = sourceImageTransform.ScaleToFit; } } } // force a render to update the client rectangle and scaling of the image secondaryCapture.RenderImage(image.ClientRectangle).Dispose(); } catch (Exception ex) { Platform.Log(LogLevel.Warn, ex, "An error has occurred while deserializing the image presentation state."); } return(secondaryCapture); } }