public async Task <ModelResult> SegmentationResultAsync(string modelId, string segmentationId, IEnumerable <DicomFile> referenceDicomFiles, IEnumerable <TagReplacement> userReplacements) { await DelayAndThrowExceptionIfNotNull(SegmentationResultException).ConfigureAwait(false); if (RealSegmentation) { return(await _InnerEyeSegmentationClient.SegmentationResultAsync(modelId, segmentationId, referenceDicomFiles, userReplacements).ConfigureAwait(false)); } else if (SegmentationProgressResult != null) { return(SegmentationProgressResult); } else { var dicomFile = await DicomFile.OpenAsync(SegmentationResultFile, FileReadOption.ReadAll).ConfigureAwait(false); dicomFile.Dataset.AddOrUpdate(DicomTag.SoftwareVersions, $@"InnerEye AI Model: Test.Name\" + $@"InnerEye AI Model ID: Test.ID\" + $@"InnerEye Model Created: Test.CreatedDate\" + $@"InnerEye Version: Test.AssemblyVersion\"); dicomFile.Dataset.AddOrUpdate(DicomTag.SeriesDate, $"{DateTime.UtcNow.Year}{DateTime.UtcNow.Month:D2}{DateTime.UtcNow.Day:D2}"); var anonymized = DeanonymizeDicomFile( dicomFile, referenceDicomFiles, TopLevelReplacements, userReplacements, SegmentationAnonymisationProtocolId, SegmentationAnonymisationProtocol); return(new ModelResult(100, string.Empty, anonymized)); } }
/// <summary> /// Gets the segmentation result. /// </summary> /// <param name="downloadQueueItem">The download queue item.</param> /// <param name="retryDelay">The delay between getting segmentation progress.</param> /// <param name="timeout">The maximum time we will wait for a segmentation result.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The segmentation result Dicom file or null.</returns> private async Task <DicomFile> GetSegmentationResultAsync(DownloadQueueItem downloadQueueItem, TimeSpan retryDelay, TimeSpan timeout, CancellationToken cancellationToken) { var referenceDicomFiles = OpenDicomFiles(downloadQueueItem.ReferenceDicomFiles); // Attempting to download result LogInformation(LogEntry.Create(AssociationStatus.Downloading, downloadQueueItem: downloadQueueItem, downloadProgress: 0, downloadError: string.Empty)); var tagReplacements = JsonConvert.DeserializeObject <IEnumerable <TagReplacement> >(downloadQueueItem.TagReplacementJsonString); // Create a new token for the maximum time we will sit and wait for a result. // Note: We need to check both the passed cancellation token and this new token for cancellation requests using (var cancellationTokenSource = new CancellationTokenSource(timeout)) { while (!cancellationTokenSource.IsCancellationRequested && !cancellationToken.IsCancellationRequested) { var modelResult = await _innerEyeSegmentationClient.SegmentationResultAsync( modelId : downloadQueueItem.ModelId, segmentationId : downloadQueueItem.SegmentationID, referenceDicomFiles : referenceDicomFiles, userReplacements : tagReplacements); if (modelResult.Progress == 100 && modelResult.DicomResult != null) { return(modelResult.DicomResult); } else if (!string.IsNullOrEmpty(modelResult.Error)) { LogError(LogEntry.Create(AssociationStatus.Downloading, downloadQueueItem: downloadQueueItem, downloadProgress: modelResult.Progress, downloadError: modelResult.Error), new Exception("Failed to get a segmentation result.")); // We cannot recover from this error, so we log and continue. return(null); } else { LogInformation(LogEntry.Create(AssociationStatus.Downloading, downloadQueueItem: downloadQueueItem, downloadProgress: modelResult.Progress, downloadError: modelResult.Error)); } // Make sure you pass the cancellation token, not the timeout token, so the service can stop timely await Task.Delay(retryDelay, cancellationToken); } } return(null); }