/// <summary>
        /// Saves given instances to temp files and performs requested operation on each of the saved file.
        /// NOTE: The temp file must me manually deleted during post save operation or it will stay in the temp folder.
        /// <exception cref="AimManagerException">AimManagerException</exception> can be thrown if save of an annotation fails.
        /// </summary>
        /// <param name="aimAnnotationReferences">List of annotation containers to save</param>
        /// <param name="postSaveProcessor">Operation to perform on each saved temp file</param>
        public void WriteDicomAnnotationsToTempFiles(List <IAimObjectReference> aimAnnotationReferences, Action <string> postSaveProcessor)
        {
            if (aimAnnotationReferences == null)
            {
                return;
            }

            var aim3Annotations = aimAnnotationReferences.Where(aimObject => aimObject != null && aimObject.AimVersion == AimVersion.AimVersion3).ToList();

            if (aim3Annotations.Any())
            {
                using (var aim3NativeHelper = new Aim3.Aim3NativeDcmHelper())
                {
                    foreach (var aim3Annotation in aim3Annotations)
                    {
                        var tempFileName = aim3NativeHelper.WriteAnnotationToTempFile(aim3Annotation);
                        if (tempFileName != null && postSaveProcessor != null)
                        {
                            postSaveProcessor(tempFileName);
                        }
                        else if (tempFileName != null)
                        {
                            // TODO - delete temp file?
                        }
                    }
                }
            }
            var aim4Annotations = aimAnnotationReferences.Where(aimObject => aimObject != null && aimObject.AimVersion == AimVersion.AimVersion4).ToList();

            if (aim4Annotations.Any())
            {
                using (var aim4NativeHelper = new Aim4.Aim4NativeDcmHelper())
                {
                    foreach (var aim4Annotation in aim4Annotations)
                    {
                        var tempFileName = aim4NativeHelper.WriteAnnotationToTempFile(aim4Annotation);
                        if (tempFileName != null && postSaveProcessor != null)
                        {
                            postSaveProcessor(tempFileName);
                        }
                        else if (tempFileName != null)
                        {
                            // TODO - delete temp file?
                        }
                    }
                }
            }

            if (aim3Annotations.Count + aim4Annotations.Count != aimAnnotationReferences.Count)
            {
                Platform.Log(LogLevel.Error, "AimManager.WriteDicomAnnotationsToTempFiles: not all annotations can be saved to DICOM files.");
                throw new NotImplementedException("Cannot save some of the annotations to DICOM files. Unknown version of AIM was encountered?");
            }
        }
Exemplo n.º 2
0
        // Loads annotations from local storage
        private List <IAimDocumentInstance> LoadLocalAimDocumentsForStudy(string studyInstanceUid)
        {
            var seriesIdentifier = new SeriesIdentifier {
                StudyInstanceUid = studyInstanceUid, Modality = AimManager.AimModality
            };
            var seriesEntryRequest = new GetSeriesEntriesRequest {
                Criteria = new SeriesEntry {
                    Series = seriesIdentifier
                }
            };

            IList <SeriesEntry> entries = null;

            Platform.GetService <IStudyStoreQuery>(s => entries = s.GetSeriesEntries(seriesEntryRequest).SeriesEntries);

            var instanceToAimFileInfoMap = new Dictionary <string, AimFileInfo>();

            // Get all unique AE Titles for the study. Can study have more than one?
            // We only need to query each AETitle once, or there will be duplicates/errors.
            var studyAes = (from seriesEntry in entries where seriesEntry != null select seriesEntry.Series.RetrieveAE).GroupBy(ae => ae.AETitle).Select(ae1 => ae1.First()).OfType <IDicomServiceNode>().ToList();

            if (!studyAes.Any())
            {
                Platform.Log(LogLevel.Debug, "Study ({0}} has no SR (AIM Annotations) objects", studyInstanceUid);
                return(null);
            }
            foreach (var studyAe in studyAes)
            {
                IStudyLoader studyLoader;
                try
                {
                    studyLoader = studyAe.GetService <IStudyLoader>();
                }
                catch (Exception ex)
                {
                    throw new AimManagerException("Cannot get study loader", ex);
                }

                int numberOfSops = studyLoader.Start(new StudyLoaderArgs(studyInstanceUid, null, new StudyLoaderOptions(true)));
                for (int i = 0; i < numberOfSops; i++)
                {
                    using (var sop = studyLoader.LoadNextSop())
                    {
                        if (sop != null && sop.Modality == AimManager.AimModality)
                        {
                            var localSopDataSource = sop.DataSource as ILocalSopDataSource;
                            if (localSopDataSource != null)
                            {
                                var filePathName = localSopDataSource.Filename;
                                switch (AimManager.GetAimVersionFromSop(sop))
                                {
                                case AimVersion.AimVersion3:
                                    instanceToAimFileInfoMap.Add(filePathName,
                                                                 new AimFileInfo(AimVersion.AimVersion3, sop.StudyInstanceUid, sop.SeriesInstanceUid, sop.SopInstanceUid));
                                    break;

                                case AimVersion.AimVersion4:
                                    instanceToAimFileInfoMap.Add(filePathName,
                                                                 new AimFileInfo(AimVersion.AimVersion4, sop.StudyInstanceUid, sop.SeriesInstanceUid, sop.SopInstanceUid));
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if (instanceToAimFileInfoMap.Any())
            {
                var aimDocumentInstances = new List <IAimDocumentInstance>();
                var aim4Instances        = instanceToAimFileInfoMap.Where(instance => instance.Value.AimVersion == AimVersion.AimVersion4).ToList();
                if (aim4Instances.Any())
                {
                    using (var dcmHelper = new Aim4.Aim4NativeDcmHelper())
                    {
                        foreach (var instanceInfo in aim4Instances)
                        {
                            var aimDocumentInstance = ReadAimDocumentFromDicomFile(dcmHelper,
                                                                                   instanceInfo.Key, instanceInfo.Value.StudyInstanceUid,
                                                                                   instanceInfo.Value.SeriesInstanceUid, instanceInfo.Value.SopInstanceUid);
                            if (aimDocumentInstance != null)
                            {
                                aimDocumentInstances.Add(aimDocumentInstance);
                            }
                        }
                    }
                }

                return(aimDocumentInstances.Any() ? aimDocumentInstances : null);
            }

            return(null);
        }
        public static List <string> ConvertAnnotationsFromXmlToDicomFiles(AimVersion aimVersion, List <string> xmlAnnotationsFilePathNames, IBackgroundTaskContext context, out List <string> invalidFiles)
        {
            Platform.CheckForNullReference(xmlAnnotationsFilePathNames, "xmlAnnotationsFilePathNames");

            var convertedAnnotations = new List <string>();

            invalidFiles = new List <string>();

            switch (aimVersion)
            {
            case AimVersion.AimVersion3:
            {
                int cnt = 0;
                using (var aim3NativeXmlHelper = new Aim3.Aim3NativeXmlHelper())
                {
                    using (var aim3NativeDcmHelper = new Aim3.Aim3NativeDcmHelper())
                    {
                        foreach (string aimFile in xmlAnnotationsFilePathNames.Where(pathName => pathName != null))
                        {
                            // Read XML file
                            ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count, String.Format("Reading file {0}", Path.GetFileName(aimFile)));
                            var annotations = aim3NativeXmlHelper.ReadAnnotationsFromFile(aimFile);

                            if (annotations.IsNullOrEmpty())
                            {
                                Platform.Log(LogLevel.Info, "No annotation is read from file {0}", Path.GetFileName(aimFile));
                                invalidFiles.Add(Path.GetFileName(aimFile));
                            }
                            else
                            {
                                // Write to temp file
                                ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count,
                                                   String.Format("Read {0} annotations from file {1}", annotations.Count, Path.GetFileName(aimFile)));
                                int dcmFileCnt = 0;
                                foreach (var annotation in annotations)
                                {
                                    ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count,
                                                       String.Format("Writing converted annotation to temporary file [{0} of {1}]", ++dcmFileCnt, annotations.Count));

                                    var tempFileName = aim3NativeDcmHelper.WriteAnnotationToTempFile(annotation);
                                    convertedAnnotations.Add(tempFileName);

                                    ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count,
                                                       String.Format("Wrote converted annotation to file {0} [{1} of {2}]", tempFileName, dcmFileCnt, annotations.Count));
                                }
                            }
                            if (context != null && context.CancelRequested)
                            {
                                break;
                            }
                            cnt++;
                        }
                    }
                }
            }
            break;

            case AimVersion.AimVersion4:
            {
                int cnt = 0;
                using (var aim4NativeXmlHelper = new Aim4.Aim4NativeXmlHelper())
                {
                    using (var aim4NativeDcmHelper = new Aim4.Aim4NativeDcmHelper())
                    {
                        foreach (string aimFile in xmlAnnotationsFilePathNames.Where(pathName => pathName != null))
                        {
                            // Read XML file
                            ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count, String.Format("Reading file {0}", Path.GetFileName(aimFile)));
                            var annotation = aim4NativeXmlHelper.ReadAnnotationFromFile(aimFile);

                            if (annotation == null)
                            {
                                Platform.Log(LogLevel.Info, "No annotation is read from file {0}", Path.GetFileName(aimFile));
                                invalidFiles.Add(Path.GetFileName(aimFile));
                            }
                            else
                            {
                                // Write to temp file
                                ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count,
                                                   String.Format("Read annotation collection from file {0}", Path.GetFileName(aimFile)));

                                var tempFileName = aim4NativeDcmHelper.WriteAnnotationToTempFile(annotation);
                                convertedAnnotations.Add(tempFileName);

                                ReportTaskProgress(context, cnt, xmlAnnotationsFilePathNames.Count,
                                                   String.Format("Wrote converted annotation collection to file {0}", tempFileName));
                            }
                            if (context != null && context.CancelRequested)
                            {
                                break;
                            }
                            cnt++;
                        }
                    }
                }
            }
            break;

            default:
                Debug.Assert(false, "AimManager.ConvertAnnotationsFromXmlToDicomFiles: Unexpected AIM version");
                break;
            }

            return(convertedAnnotations);
        }
        // Loads annotations from local storage
        private List<IAimDocumentInstance> LoadLocalAimDocumentsForStudy(string studyInstanceUid)
        {
            var seriesIdentifier = new SeriesIdentifier { StudyInstanceUid = studyInstanceUid, Modality = AimManager.AimModality };
            var seriesEntryRequest = new GetSeriesEntriesRequest { Criteria = new SeriesEntry { Series = seriesIdentifier } };

            IList<SeriesEntry> entries = null;
            Platform.GetService<IStudyStoreQuery>(s => entries = s.GetSeriesEntries(seriesEntryRequest).SeriesEntries);

            var instanceToAimFileInfoMap = new Dictionary<string, AimFileInfo>();

            // Get all unique AE Titles for the study. Can study have more than one?
            // We only need to query each AETitle once, or there will be duplicates/errors.
            var studyAes = (from seriesEntry in entries where seriesEntry != null select seriesEntry.Series.RetrieveAE).GroupBy(ae => ae.AETitle).Select(ae1 => ae1.First()).OfType<IDicomServiceNode>().ToList();
            if (!studyAes.Any())
            {
                Platform.Log(LogLevel.Debug, "Study ({0}} has no SR (AIM Annotations) objects", studyInstanceUid);
                return null;
            }
            foreach (var studyAe in studyAes)
            {

                IStudyLoader studyLoader;
                try
                {
                    studyLoader = studyAe.GetService<IStudyLoader>();
                }
                catch (Exception ex)
                {
                    throw new AimManagerException("Cannot get study loader", ex);
                }

                int numberOfSops = studyLoader.Start(new StudyLoaderArgs(studyInstanceUid, null, new StudyLoaderOptions(true)));
                for (int i = 0; i < numberOfSops; i++)
                {
                    using (var sop = studyLoader.LoadNextSop())
                    {
                        if (sop != null && sop.Modality == AimManager.AimModality)
                        {
                            var localSopDataSource = sop.DataSource as ILocalSopDataSource;
                            if (localSopDataSource != null)
                            {
                                var filePathName = localSopDataSource.Filename;
                                switch (AimManager.GetAimVersionFromSop(sop))
                                {
                                    case AimVersion.AimVersion3:
                                        instanceToAimFileInfoMap.Add(filePathName,
                                                                     new AimFileInfo(AimVersion.AimVersion3, sop.StudyInstanceUid, sop.SeriesInstanceUid, sop.SopInstanceUid));
                                        break;
                                    case AimVersion.AimVersion4:
                                        instanceToAimFileInfoMap.Add(filePathName,
                                                                     new AimFileInfo(AimVersion.AimVersion4, sop.StudyInstanceUid, sop.SeriesInstanceUid, sop.SopInstanceUid));
                                        break;
                                }
                            }
                        }
                    }
                }
            }

            if (instanceToAimFileInfoMap.Any())
            {
                var aimDocumentInstances = new List<IAimDocumentInstance>();
                var aim4Instances = instanceToAimFileInfoMap.Where(instance => instance.Value.AimVersion == AimVersion.AimVersion4).ToList();
                if (aim4Instances.Any())
                {
                    using (var dcmHelper = new Aim4.Aim4NativeDcmHelper())
                    {
                        foreach (var instanceInfo in aim4Instances)
                        {
                            var aimDocumentInstance = ReadAimDocumentFromDicomFile(dcmHelper,
                                                                            instanceInfo.Key, instanceInfo.Value.StudyInstanceUid,
                                                                            instanceInfo.Value.SeriesInstanceUid, instanceInfo.Value.SopInstanceUid);
                            if (aimDocumentInstance != null)
                                aimDocumentInstances.Add(aimDocumentInstance);
                        }
                    }
                }

                return aimDocumentInstances.Any() ? aimDocumentInstances : null;
            }

            return null;
        }