public override PriorStudyFinderResult FindPriorStudies()
        {
            _cancel = false;
            var results = new Dictionary <string, StudyItem>();

            IPatientReconciliationStrategy reconciliationStrategy = new DefaultPatientReconciliationStrategy();

            reconciliationStrategy.SetStudyTree(Viewer.StudyTree);

            var patientIds = new Dictionary <string, string>();

            foreach (Patient patient in Viewer.StudyTree.Patients)
            {
                if (_cancel)
                {
                    break;
                }

                IPatientData reconciled = reconciliationStrategy.ReconcileSearchCriteria(patient);
                patientIds[reconciled.PatientId] = reconciled.PatientId;
            }

            int failedCount  = 0;
            int successCount = 0;

            foreach (var priorsServer in ServerDirectory.GetPriorsServers(true))
            {
                if (_cancel)
                {
                    break;
                }

                try
                {
                    using (var bridge = new StudyRootQueryBridge(priorsServer.GetService <IStudyRootQuery>()))
                    {
                        foreach (string patientId in patientIds.Keys)
                        {
                            //#10790: don't search for priors if patient id is empty
                            if (string.IsNullOrEmpty(patientId))
                            {
                                continue;
                            }

                            var identifier = new StudyRootStudyIdentifier {
                                PatientId = patientId
                            };

                            IList <StudyRootStudyIdentifier> studies = bridge.StudyQuery(identifier);

                            Platform.Log(LogLevel.Debug, "Found {0} prior studies on server '{1}'", studies.Count, priorsServer.Name);

                            foreach (StudyRootStudyIdentifier study in studies)
                            {
                                if (_cancel)
                                {
                                    break;
                                }

                                //Eliminate false positives right away.
                                IPatientData reconciled = reconciliationStrategy.ReconcilePatientInformation(study);
                                if (reconciled == null)
                                {
                                    continue;
                                }

                                StudyItem studyItem = ConvertToStudyItem(study);
                                if (studyItem == null || results.ContainsKey(studyItem.StudyInstanceUid))
                                {
                                    continue;
                                }

                                if (!results.ContainsKey(studyItem.StudyInstanceUid))
                                {
                                    results[studyItem.StudyInstanceUid] = studyItem;
                                }
                            }
                        }
                    }

                    ++successCount;
                }
                catch (Exception e)
                {
                    ++failedCount;
                    Platform.Log(LogLevel.Error, e, "Failed to query server: {0}", priorsServer.Name);
                }
            }

            if (_cancel)
            {
                //Just pretend the query never happened.
                return(new PriorStudyFinderResult(new StudyItemList(), true));
            }

            if (failedCount > 0)
            {
                PriorStudyLoaderExceptionPolicy.NotifyFailedQuery();

                if (successCount == 0)
                {
                    throw new Exception("The search for prior studies has failed.");
                }
            }
            else
            {
                //Even if success count is zero, we'll still consider it "successful".
                PriorStudyLoaderExceptionPolicy.NotifySuccessfulQuery();
            }

            Platform.Log(LogLevel.Debug, "Found {0} prior studies in total.", results.Count);

            return(new PriorStudyFinderResult(new StudyItemList(results.Values), failedCount == 0));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Figure out which studies have been deleted and/or updated.
        /// </summary>
        private void ProcessChangedStudiesAsync(out DateTime?queryStartTime, out List <string> deletedStudyUids, out List <StudyEntry> updatedStudies)
        {
            deletedStudyUids = new List <string>();
            updatedStudies   = new List <StudyEntry>();
            queryStartTime   = null;
            DateTime now = DateTime.Now;

            var fiveSeconds         = TimeSpan.FromSeconds(5);
            var rapidChangeInterval = TimeSpan.FromMilliseconds(300);

            lock (_syncLock)
            {
                if (_queryingForUpdates)
                {
                    return; //Already querying.
                }
                //Nothing to query for? Return.
                if (_setChangedStudies.Count == 0 || !_lastStudyChangeTime.HasValue)
                {
                    return;
                }

                bool studiesChanging = now - _lastStudyChangeTime.Value < rapidChangeInterval;
                if (studiesChanging)
                {
                    //Many DIFFERENT studies are changing in very rapid succession. Delay until it settles down, which usually isn't long.
                    Platform.Log(LogLevel.Debug, "Studies are still actively changing - delaying update.");
                    return;
                }

                if (!_hastenUpdateQuery)
                {
                    bool updatedRecently = _lastUpdateQueryEndTime.HasValue && now - _lastUpdateQueryEndTime < fiveSeconds;
                    if (updatedRecently)
                    {
                        //We just finished an update query less than 5 seconds ago.
                        Platform.Log(LogLevel.Debug, "Studies were updated within the last 5 seconds - delaying update.");
                        return;
                    }
                }

                //Reset this before the immediate query.
                _hastenUpdateQuery = false;

                //Add everything to the deleted list.
                deletedStudyUids.AddRange(_setChangedStudies.Keys);
                _setChangedStudies.Clear();

                //We are officially querying for updates.
                _queryingForUpdates = true;
            }

            queryStartTime = now;
            string studyUids = DicomStringHelper.GetDicomStringArray(deletedStudyUids);

            try
            {
                var clock = new CodeClock();
                clock.Start();

                var criteria = new StudyRootStudyIdentifier {
                    StudyInstanceUid = studyUids
                };
                var request = new GetStudyEntriesRequest {
                    Criteria = new StudyEntry {
                        Study = criteria
                    }
                };

                IList <StudyEntry> entries = null;

                //We're doing it this way here because it's local only.
                Platform.GetService <IStudyStoreQuery>(s => entries = s.GetStudyEntries(request).StudyEntries);

                foreach (var entry in entries)
                {
                    //If we got a result back, then it's not deleted.
                    deletedStudyUids.Remove(entry.Study.StudyInstanceUid);
                    updatedStudies.Add(entry);
                }

                clock.Stop();
                Platform.Log(LogLevel.Debug, "Study update query took {0}.", clock);
            }
            catch (Exception e)
            {
                Platform.Log(LogLevel.Error, e);
            }
            finally
            {
                lock (_syncLock)
                {
                    //Finished querying for updates.
                    _queryingForUpdates     = false;
                    _lastUpdateQueryEndTime = now;
                }
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Constructor.
 /// </summary>
 public Viewer(Guid identifier, StudyRootStudyIdentifier primaryStudyIdentifier)
 {
     Identifier             = identifier;
     PrimaryStudyIdentifier = primaryStudyIdentifier;
 }
Exemplo n.º 4
0
 internal static List <StudyEntry> TestGetStudyEntries(IDicomServiceNode server, StudyRootStudyIdentifier criteria)
 {
     return(GetStudyEntries(server, criteria));
 }
 public Viewer OpenViewer(StudyRootStudyIdentifier studyRootStudyIdentifier)
 {
     return(OpenViewer(new[] { studyRootStudyIdentifier }));
 }
Exemplo n.º 6
0
        private void TestSortingImageSetsByStudyDate(bool reverse, bool useSops, bool testLayoutManagerSort)
        {
            ImageSetCollection orderedCollection    = new ImageSetCollection();
            ImageSetCollection nonOrderedCollection = new ImageSetCollection();
            StudyTree          studyTree            = new StudyTree();

            for (int i = 0; i <= 20; ++i)
            {
                string   id       = i.ToString();
                ImageSet imageSet = new ImageSet();
                imageSet.Name = id;

                string studyDate;
                if (i == 0)
                {
                    studyDate = "";
                }
                else
                {
                    studyDate = String.Format("200801{0}", i.ToString("00"));
                }

                if (useSops)
                {
                    DisplaySet displaySet = new DisplaySet(id, id);
                    ImageSop   sop        = NewImageSop(id, id, i);
                    imageSet.Uid = sop.StudyInstanceUid;
                    studyTree.AddSop(sop);

                    IPresentationImage image       = new DicomGrayscalePresentationImage(sop.Frames[1]);
                    IImageSopProvider  sopProvider = (IImageSopProvider)image;

                    DicomMessageSopDataSource dataSource = ((DicomMessageSopDataSource)sopProvider.ImageSop.DataSource);
                    dataSource.SourceMessage.DataSet[DicomTags.StudyDate].SetString(0, studyDate);
                    imageSet.DisplaySets.Add(displaySet);
                    displaySet.PresentationImages.Add(image);
                }
                else
                {
                    StudyRootStudyIdentifier identifier = new StudyRootStudyIdentifier();
                    identifier.StudyDate        = studyDate;
                    identifier.StudyInstanceUid = id;
                    ImageSetDescriptor descriptor = new DicomImageSetDescriptor(identifier);
                    imageSet.Descriptor = descriptor;
                }

                orderedCollection.Add(imageSet);
            }

            if (reverse)
            {
                List <IImageSet> temp = new List <IImageSet>();
                temp.AddRange(orderedCollection);
                temp.Reverse();
                orderedCollection.Clear();
                foreach (IImageSet imageSet in temp)
                {
                    orderedCollection.Add(imageSet);
                }
            }

            Randomize(orderedCollection, nonOrderedCollection);

            Debug.WriteLine("Before Sort\n------------------------\n");
            CollectionUtils.ForEach(nonOrderedCollection,
                                    imageSet => Debug.WriteLine(String.Format("name: {0}, date: {1}", imageSet.Name,
                                                                              ((IImageSopProvider)(imageSet.DisplaySets[0].PresentationImages[0])).
                                                                              ImageSop.StudyDate)));

            if (testLayoutManagerSort)
            {
                LayoutManager.SortImageSets(nonOrderedCollection, GetStudies(orderedCollection, studyTree));
            }
            else
            {
                nonOrderedCollection.Sort(new StudyDateComparer(reverse));
            }

            Debug.WriteLine("\nAfter Sort\n------------------------\n");
            CollectionUtils.ForEach(nonOrderedCollection,
                                    imageSet => Debug.WriteLine(String.Format("name: {0}, date: {1}", imageSet.Name,
                                                                              ((IImageSopProvider)(imageSet.DisplaySets[0].PresentationImages[0])).
                                                                              ImageSop.StudyDate)));

            if (reverse)
            {
                nonOrderedCollection.RemoveAt(20);
            }
            else
            {
                nonOrderedCollection.RemoveAt(0);
            }

            int j = reverse ? 20 : 1;

            foreach (IImageSet set in nonOrderedCollection)
            {
                Assert.AreEqual(j.ToString(), set.Name);
                j += reverse ? -1 : 1;
            }

            foreach (IImageSet set in nonOrderedCollection)
            {
                set.Dispose();
            }
            foreach (IImageSet set in orderedCollection)
            {
                set.Dispose();
            }

            studyTree.Dispose();
        }
Exemplo n.º 7
0
 public IList <StudyEntry> GetStudyEntries(StudyRootStudyIdentifier criteria)
 {
     return(GetStudyEntries(new StudyEntry {
         Study = criteria
     }));
 }
Exemplo n.º 8
0
        public System.Collections.Generic.IList <StudyRootStudyIdentifier> StudyQuery(StudyRootStudyIdentifier queryCriteria)
        {
            var criteria = new StudyEntry {
                Study = queryCriteria
            };
            var result = Real.GetStudyEntries(new GetStudyEntriesRequest {
                Criteria = criteria
            });

            return(result.StudyEntries.Select(e => e.Study).ToList());
        }
Exemplo n.º 9
0
        private static IList <StudyRootStudyIdentifier> FindStudies(StartViewerApplicationRequest request)
        {
            bool invalidRequest = true;
            List <StudyRootStudyIdentifier> results = new List <StudyRootStudyIdentifier>();

            using (StudyRootQueryBridge bridge = new StudyRootQueryBridge(Platform.GetService <IStudyRootQuery>()))
            {
                if (request.StudyInstanceUid != null && request.StudyInstanceUid.Length > 0)
                {
                    foreach (string studyUid in request.StudyInstanceUid)
                    {
                        //TODO (CR May 2010): can actually trigger a query of all studies
                        if (!String.IsNullOrEmpty(studyUid))
                        {
                            invalidRequest = false;
                        }

                        //TODO (CR May 2010): if request.AeTitle is set, assign RetrieveAeTitle parameter in
                        // StudyRootStudyIndentifer to this value.  Update the query code to then only
                        // search this specified partition and remove the loop code below that looks
                        // for matching AeTitles.
                        StudyRootStudyIdentifier identifier = new StudyRootStudyIdentifier
                        {
                            StudyInstanceUid = studyUid
                        };
                        IList <StudyRootStudyIdentifier> studies = bridge.StudyQuery(identifier);

                        bool found = false;
                        foreach (StudyRootStudyIdentifier study in studies)
                        {
                            if (!string.IsNullOrEmpty(request.AeTitle) && !study.RetrieveAeTitle.Equals(request.AeTitle))
                            {
                                continue;
                            }

                            results.Add(study);
                            found = true;
                        }

                        if (!found)
                        {
                            throw new NotFoundLoadStudyException(studyUid);
                        }
                    }
                }
                if (request.PatientId != null && request.PatientId.Length > 0)
                {
                    foreach (string patientId in request.PatientId)
                    {
                        if (!String.IsNullOrEmpty(patientId))
                        {
                            invalidRequest = false;
                        }

                        StudyRootStudyIdentifier identifier = new StudyRootStudyIdentifier
                        {
                            PatientId = patientId
                        };

                        IList <StudyRootStudyIdentifier> studies = bridge.StudyQuery(identifier);
                        bool found = false;
                        foreach (StudyRootStudyIdentifier study in studies)
                        {
                            if (!string.IsNullOrEmpty(request.AeTitle) && !study.RetrieveAeTitle.Equals(request.AeTitle))
                            {
                                continue;
                            }

                            results.Add(study);
                            found = true;
                        }

                        if (!found)
                        {
                            throw new PatientStudiesNotFoundException(patientId);
                        }
                    }
                }
                if (request.AccessionNumber != null && request.AccessionNumber.Length > 0)
                {
                    foreach (string accession in request.AccessionNumber)
                    {
                        if (!String.IsNullOrEmpty(accession))
                        {
                            invalidRequest = false;
                        }

                        StudyRootStudyIdentifier identifier = new StudyRootStudyIdentifier
                        {
                            AccessionNumber = accession
                        };

                        IList <StudyRootStudyIdentifier> studies = bridge.StudyQuery(identifier);

                        bool found = false;
                        foreach (StudyRootStudyIdentifier study in studies)
                        {
                            if (!string.IsNullOrEmpty(request.AeTitle) && !study.RetrieveAeTitle.Equals(request.AeTitle))
                            {
                                continue;
                            }

                            results.Add(study);
                            found = true;
                        }

                        if (!found)
                        {
                            throw new AccessionStudiesNotFoundException(accession);
                        }
                    }
                }
            }

            if (invalidRequest)
            {
                throw new InvalidRequestException();
            }

            return(results);
        }
Exemplo n.º 10
0
        public IList <StudyRootStudyIdentifier> StudyQuery(StudyRootStudyIdentifier queryCriteria)
        {
            QueryDelegate <StudyRootStudyIdentifier> query = (criteria, studyRootQuery) => studyRootQuery.StudyQuery(criteria);

            return(new GenericQuery <StudyRootStudyIdentifier>(query, false).Query(queryCriteria));
        }
Exemplo n.º 11
0
 private IEnumerable <Study> GetStudies(StudyRootStudyIdentifier criteria)
 {
     return(GetStudies(new StudyEntry {
         Study = criteria
     }));
 }
Exemplo n.º 12
0
        public IList <StudyRootStudyIdentifier> StudyQuery(StudyRootStudyIdentifier criteria)
        {
            var entries = GetStudies(criteria);

            return(entries.Select(e => e.ToStoreEntry().Study).ToList());
        }
Exemplo n.º 13
0
 private static bool IdealMatchModalitiesInStudy(StudyRootStudyIdentifier s, StudyRootStudyIdentifier q)
 {
     return(q.ModalitiesInStudy.Any(string.IsNullOrEmpty) ||
            s.ModalitiesInStudy.Intersect(q.ModalitiesInStudy).Any());
 }
Exemplo n.º 14
0
 public SearchRequestedEventArgs(StudyRootStudyIdentifier queryCriteria)
 {
     this.QueryCriteria = queryCriteria;
 }
Exemplo n.º 15
0
 public int Compare(StudyRootStudyIdentifier x, StudyRootStudyIdentifier y)
 {
     return(Compare((StudyIdentifier)x, y));
 }
 public StudyBrowserComponent()
 {
     _dummyStudyTable   = new Table <StudyTableItem>();
     _searchResults     = new Dictionary <string, SearchResult>();
     _lastQueryCriteria = new StudyRootStudyIdentifier();
 }
Exemplo n.º 17
0
        public override PriorStudyFinderResult FindPriorStudies()
        {
            _cancel = false;

            var priorsServerQueries = new List <IStudyRootQuery>();

            foreach (ServerPartition partition in ServerPartitionMonitor.Instance)
            {
                using (IReadContext ctx = PersistentStoreRegistry.GetDefaultStore().OpenReadContext())
                {
                    IDeviceEntityBroker  broker   = ctx.GetBroker <IDeviceEntityBroker>();
                    DeviceSelectCriteria criteria = new DeviceSelectCriteria();
                    criteria.DeviceTypeEnum.EqualTo(DeviceTypeEnum.PriorsServer);
                    criteria.ServerPartitionKey.EqualTo(partition.Key);
                    IList <Device> list = broker.Find(criteria);
                    foreach (Device theDevice in list)
                    {
                        // Check the settings and log for debug purposes
                        if (!theDevice.Enabled)
                        {
                            Platform.Log(LogLevel.Debug, "Prior Server '{0}' on partition '{1}' is disabled in the device setting",
                                         theDevice.AeTitle, partition.AeTitle);
                            continue;
                        }

                        DicomStudyRootQuery remoteQuery = new DicomStudyRootQuery(partition.AeTitle, theDevice.AeTitle,
                                                                                  theDevice.IpAddress, theDevice.Port);
                        priorsServerQueries.Add(remoteQuery);
                    }
                }
            }

            // Log the prior servers for debug purpose
            if (Platform.IsLogLevelEnabled(LogLevel.Debug) && priorsServerQueries.Count > 0)
            {
                StringBuilder log = new StringBuilder();
                log.Append("Searching for priors on the following servers:");

                StringBuilder serverList = new StringBuilder();
                foreach (DicomStudyRootQuery server in priorsServerQueries)
                {
                    if (serverList.Length > 0)
                    {
                        serverList.Append(",");
                    }
                    serverList.AppendFormat("{0}", server);
                }

                log.Append(serverList.ToString());
                Platform.Log(LogLevel.Debug, log.ToString());
            }

            StudyItemList results = new StudyItemList();

            DefaultPatientReconciliationStrategy reconciliationStrategy = new DefaultPatientReconciliationStrategy();
            List <string> patientIds = new List <string>();

            foreach (Patient patient in Viewer.StudyTree.Patients)
            {
                if (_cancel)
                {
                    break;
                }

                IPatientData reconciled = reconciliationStrategy.ReconcileSearchCriteria(patient);
                if (!patientIds.Contains(reconciled.PatientId))
                {
                    patientIds.Add(reconciled.PatientId);
                }
            }

            //Note: we don't catch the exception for this one because it's just querying the other
            //partitions, so if it fails we want an outright failure to occur.  Besides, it should never happen
            //if the server is functioning correctly.
            using (StudyRootQueryBridge bridge = new StudyRootQueryBridge(Platform.GetService <IStudyRootQuery>()))
            {
                foreach (string patientId in patientIds)
                {
                    StudyRootStudyIdentifier identifier = new StudyRootStudyIdentifier {
                        PatientId = patientId
                    };

                    IList <StudyRootStudyIdentifier> studies = bridge.StudyQuery(identifier);
                    foreach (StudyRootStudyIdentifier study in studies)
                    {
                        if (_cancel)
                        {
                            break;
                        }

                        StudyItem studyItem = ConvertToStudyItem(study);
                        if (studyItem != null)
                        {
                            results.Add(studyItem);
                        }
                    }
                }
            }

            bool complete = true;

            foreach (IStudyRootQuery query in priorsServerQueries)
            {
                foreach (string patientId in patientIds)
                {
                    try
                    {
                        var identifier = new StudyRootStudyIdentifier
                        {
                            PatientId = patientId
                        };

                        IList <StudyRootStudyIdentifier> list = query.StudyQuery(identifier);
                        foreach (StudyRootStudyIdentifier i in list)
                        {
                            if (_cancel)
                            {
                                break;
                            }

                            StudyItem studyItem = ConvertToStudyItem(i);
                            if (studyItem != null)
                            {
                                results.Add(studyItem);
                            }
                        }
                    }
                    catch (FaultException <DataValidationFault> ex)
                    {
                        complete = false;
                        Platform.Log(LogLevel.Error, ex, "An error has occurred when searching for prior studies on server '{0}'", query.ToString());
                    }
                    catch (FaultException <QueryFailedFault> ex)
                    {
                        complete = false;
                        Platform.Log(LogLevel.Error, ex, "An error has occurred when searching for prior studies on server '{0}'", query.ToString());
                    }
                }
            }

            return(new PriorStudyFinderResult(results, complete));
        }