/// <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())); }
/// <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()); }