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)); }
/// <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; } } }
/// <summary> /// Constructor. /// </summary> public Viewer(Guid identifier, StudyRootStudyIdentifier primaryStudyIdentifier) { Identifier = identifier; PrimaryStudyIdentifier = primaryStudyIdentifier; }
internal static List <StudyEntry> TestGetStudyEntries(IDicomServiceNode server, StudyRootStudyIdentifier criteria) { return(GetStudyEntries(server, criteria)); }
public Viewer OpenViewer(StudyRootStudyIdentifier studyRootStudyIdentifier) { return(OpenViewer(new[] { studyRootStudyIdentifier })); }
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(); }
public IList <StudyEntry> GetStudyEntries(StudyRootStudyIdentifier criteria) { return(GetStudyEntries(new StudyEntry { Study = criteria })); }
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()); }
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); }
public IList <StudyRootStudyIdentifier> StudyQuery(StudyRootStudyIdentifier queryCriteria) { QueryDelegate <StudyRootStudyIdentifier> query = (criteria, studyRootQuery) => studyRootQuery.StudyQuery(criteria); return(new GenericQuery <StudyRootStudyIdentifier>(query, false).Query(queryCriteria)); }
private IEnumerable <Study> GetStudies(StudyRootStudyIdentifier criteria) { return(GetStudies(new StudyEntry { Study = criteria })); }
public IList <StudyRootStudyIdentifier> StudyQuery(StudyRootStudyIdentifier criteria) { var entries = GetStudies(criteria); return(entries.Select(e => e.ToStoreEntry().Study).ToList()); }
private static bool IdealMatchModalitiesInStudy(StudyRootStudyIdentifier s, StudyRootStudyIdentifier q) { return(q.ModalitiesInStudy.Any(string.IsNullOrEmpty) || s.ModalitiesInStudy.Intersect(q.ModalitiesInStudy).Any()); }
public SearchRequestedEventArgs(StudyRootStudyIdentifier queryCriteria) { this.QueryCriteria = queryCriteria; }
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(); }
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)); }