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);
        }
Exemple #3
0
        /// <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));
        }
Exemple #4
0
            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()));
        }
Exemple #7
0
        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);
 }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
 /// <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);
            }
        }