Exemplo n.º 1
0
        public async Task GenerateAndTestDeAnonymisedStructureSetFile()
        {
            var image      = @"Images\LargeSeriesWithContour";
            var tempFolder = CreateTemporaryDirectory();

            var segmentationClient = GetMockInnerEyeSegmentationClient();

            var configType   = AETConfigType.ModelWithResultDryRun;
            var dryRunFolder = DryRunFolders.GetFolder(configType);

            var testAETConfigModel = GetTestAETConfigModel();

            var newTestAETConfigModel = testAETConfigModel.With(
                aetConfig: new ClientAETConfig(
                    new AETConfig(
                        configType,
                        testAETConfigModel.AETConfig.Config.ModelsConfig),
                    testAETConfigModel.AETConfig.Destination,
                    false));

            var aetConfigProvider = new MockAETConfigProvider(newTestAETConfigModel);

            var receivePort = 160;

            using (var deleteService = CreateDeleteService())
                using (var pushService = CreatePushService(aetConfigProvider.AETConfigModels))
                    using (var downloadService = CreateDownloadService(segmentationClient))
                        using (var uploadService = CreateUploadService(segmentationClient, aetConfigProvider.AETConfigModels))
                            using (var receiveService = CreateReceiveService(receivePort, tempFolder))
                            {
                                deleteService.Start();
                                pushService.Start();
                                downloadService.Start();
                                uploadService.Start();
                                receiveService.Start();

                                DcmtkHelpers.SendFolderUsingDCMTK(
                                    image,
                                    receivePort,
                                    ScuProfile.LEExplicitCT,
                                    TestContext,
                                    applicationEntityTitle: newTestAETConfigModel.CallingAET,
                                    calledAETitle: newTestAETConfigModel.CalledAET);

                                SpinWait.SpinUntil(() => tempFolder.GetDirectories().FirstOrDefault(x => x.FullName.Contains(dryRunFolder)) != null);

                                var dryRunFolderDirectory = tempFolder.GetDirectories().First(x => x.FullName.Contains(dryRunFolder)).GetDirectories().First();

                                // Wait until we have all image files.
                                SpinWait.SpinUntil(() => dryRunFolderDirectory.GetFiles().Length == 1);

                                // Wait for all files to save.
                                await Task.Delay(1000);

                                var originalSlice = DicomFile.Open(new DirectoryInfo(image).GetFiles().First().FullName);

                                Assert.IsNotNull(originalSlice);

                                foreach (var file in dryRunFolderDirectory.GetFiles())
                                {
                                    var dicomFile = DicomFile.Open(file.FullName, FileReadOption.ReadAll);

                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.StudyDate), dicomFile.Dataset.GetSingleValue <string>(DicomTag.StudyDate));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.AccessionNumber), dicomFile.Dataset.GetSingleValue <string>(DicomTag.AccessionNumber));
                                    Assert.AreEqual("RTSTRUCT", dicomFile.Dataset.GetSingleValue <string>(DicomTag.Modality));
                                    Assert.AreEqual("Microsoft Corporation", dicomFile.Dataset.GetSingleValue <string>(DicomTag.Manufacturer));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.ReferringPhysicianName), dicomFile.Dataset.GetSingleValue <string>(DicomTag.ReferringPhysicianName));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty), dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.PatientName), dicomFile.Dataset.GetSingleValue <string>(DicomTag.PatientName));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.PatientID), dicomFile.Dataset.GetSingleValue <string>(DicomTag.PatientID));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.PatientBirthDate), dicomFile.Dataset.GetSingleValue <string>(DicomTag.PatientBirthDate));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID), dicomFile.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));
                                    Assert.AreEqual(originalSlice.Dataset.GetSingleValue <string>(DicomTag.StudyID), dicomFile.Dataset.GetSingleValue <string>(DicomTag.StudyID));

                                    Assert.IsTrue(dicomFile.Dataset.GetString(DicomTag.SoftwareVersions).StartsWith("Microsoft InnerEye Gateway:"));
                                    Assert.IsTrue(dicomFile.Dataset.GetValue <string>(DicomTag.SoftwareVersions, 1).StartsWith("InnerEye AI Model:"));
                                    Assert.IsTrue(dicomFile.Dataset.GetValue <string>(DicomTag.SoftwareVersions, 2).StartsWith("InnerEye AI Model ID:"));
                                    Assert.IsTrue(dicomFile.Dataset.GetValue <string>(DicomTag.SoftwareVersions, 3).StartsWith("InnerEye Model Created:"));
                                    Assert.IsTrue(dicomFile.Dataset.GetValue <string>(DicomTag.SoftwareVersions, 4).StartsWith("InnerEye Version:"));

                                    Assert.AreEqual("1.2.840.10008.5.1.4.1.1.481.3", dicomFile.Dataset.GetSingleValue <string>(DicomTag.SOPClassUID));
                                    Assert.AreEqual($"{DateTime.UtcNow.Year}{DateTime.UtcNow.Month.ToString("D2")}{DateTime.UtcNow.Day.ToString("D2")}", dicomFile.Dataset.GetSingleValue <string>(DicomTag.SeriesDate));
                                    Assert.IsTrue(dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, string.Empty).StartsWith("1.2.826.0.1.3680043.2"));
                                    Assert.AreEqual("511091532", dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, string.Empty));
                                    Assert.AreEqual("NOT FOR CLINICAL USE", dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty));
                                    Assert.IsTrue(dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty).StartsWith("1.2.826.0.1.3680043.2"));
                                    Assert.AreEqual("ANONYM", dicomFile.Dataset.GetSingleValueOrDefault(DicomTag.OperatorsName, string.Empty));

                                    VerifyDicomFile(file.FullName);
                                }
                            }
        }
Exemplo n.º 2
0
        public async Task GatewayLiveEndToEndTest()
        {
            var testAETConfigModel = GetTestAETConfigModel();

            var resultDirectory = CreateTemporaryDirectory();

            using (var dicomDataReceiver = new ListenerDataReceiver(new ListenerDicomSaver(resultDirectory.FullName)))
            {
                var eventCount = 0;
                var folderPath = string.Empty;

                dicomDataReceiver.DataReceived += (sender, e) =>
                {
                    folderPath = e.FolderPath;
                    Interlocked.Increment(ref eventCount);
                };

                StartDicomDataReceiver(dicomDataReceiver, testAETConfigModel.AETConfig.Destination.Port);

                var receivePort = 141;

                using (var segmentationClient = GetMockInnerEyeSegmentationClient())
                    using (var deleteService = CreateDeleteService())
                        using (var pushService = CreatePushService())
                            using (var downloadService = CreateDownloadService(segmentationClient))
                                using (var uploadService = CreateUploadService(segmentationClient))
                                    using (var receiveService = CreateReceiveService(receivePort))
                                    {
                                        deleteService.Start();
                                        pushService.Start();
                                        downloadService.Start();
                                        uploadService.Start();
                                        receiveService.Start();

                                        var dicomDataSender = new DicomDataSender();
                                        var echoResult      = await dicomDataSender.DicomEchoAsync(
                                            testAETConfigModel.CallingAET,
                                            testAETConfigModel.CalledAET,
                                            receivePort,
                                            "127.0.0.1").ConfigureAwait(false);

                                        Assert.IsTrue(echoResult == DicomOperationResult.Success);

                                        DcmtkHelpers.SendFolderUsingDCMTK(
                                            @"Images\1ValidSmall",
                                            receivePort,
                                            ScuProfile.LEExplicitCT,
                                            TestContext,
                                            applicationEntityTitle: testAETConfigModel.CallingAET,
                                            calledAETitle: testAETConfigModel.CalledAET);

                                        // Wait for all events to finish on the data received
                                        SpinWait.SpinUntil(() => eventCount >= 3, TimeSpan.FromMinutes(3));

#pragma warning disable CA1508 // Avoid dead conditional code
                                        Assert.IsFalse(string.IsNullOrWhiteSpace(folderPath));
#pragma warning restore CA1508 // Avoid dead conditional code

                                        var dicomFile = await DicomFile.OpenAsync(new DirectoryInfo(folderPath).GetFiles()[0].FullName).ConfigureAwait(false);

                                        Assert.IsNotNull(dicomFile);
                                    }
            }
        }
Exemplo n.º 3
0
        public async Task GenerateAndTestAnonymisedRTFile()
        {
            var tempFolder = CreateTemporaryDirectory();

            {
                var configType   = AETConfigType.ModelDryRun;
                var dryRunFolder = DryRunFolders.GetFolder(configType);

                var segmentationClient = GetMockInnerEyeSegmentationClient();

                var testAETConfigModel    = GetTestAETConfigModel();
                var newTestAETConfigModel = testAETConfigModel.With(
                    aetConfig: new ClientAETConfig(
                        new AETConfig(
                            configType,
                            null),
                        testAETConfigModel.AETConfig.Destination,
                        false));

                var aetConfigProvider = new MockAETConfigProvider(newTestAETConfigModel);

                var receivePort = 162;

                using (var deleteService = CreateDeleteService())
                    using (var pushService = CreatePushService(aetConfigProvider.AETConfigModels))
                        using (var downloadService = CreateDownloadService(segmentationClient))
                            using (var uploadService = CreateUploadService(segmentationClient, aetConfigProvider.AETConfigModels))
                                using (var receiveService = CreateReceiveService(receivePort, tempFolder))
                                {
                                    deleteService.Start();
                                    pushService.Start();
                                    downloadService.Start();
                                    uploadService.Start();
                                    receiveService.Start();

                                    DcmtkHelpers.SendFolderUsingDCMTK(
                                        @"Images\1ValidSmall",
                                        receivePort,
                                        ScuProfile.LEExplicitRTCT,
                                        TestContext,
                                        applicationEntityTitle: newTestAETConfigModel.CallingAET,
                                        calledAETitle: newTestAETConfigModel.CalledAET);

                                    SpinWait.SpinUntil(() => tempFolder.GetDirectories().FirstOrDefault(x => x.FullName.Contains(dryRunFolder)) != null);

                                    var dryRunFolderDirectory = tempFolder.GetDirectories().First(x => x.FullName.Contains(dryRunFolder)).GetDirectories().First();

                                    // Wait until we have all image files.
                                    SpinWait.SpinUntil(() => dryRunFolderDirectory.GetFiles().Length == 1);

                                    // Wait for all files to save.
                                    await Task.Delay(1000);

                                    var savedSampleFile = false;

                                    foreach (var file in dryRunFolderDirectory.GetFiles())
                                    {
                                        var dicomFile = DicomFile.Open(file.FullName);

                                        AssertDicomFileIsAnonymised(dicomFile);

                                        if (!savedSampleFile)
                                        {
                                            WriteDicomFileForBuildPackage("AnonymisedRT.dcm", dicomFile);
                                            savedSampleFile = true;
                                        }
                                    }
                                }
            }
        }
Exemplo n.º 4
0
        public async Task IntegrationTestEndToEnd()
        {
            var sourceDirectory = CreateTemporaryDirectory();
            var resultDirectory = CreateTemporaryDirectory();

            var random = new Random();

            // Get file names for all in directory
            var sourceDicomFileNames = new DirectoryInfo(@"Images\HN").GetFiles().ToArray();
            // Load all DICOM files
            var sourceDicomFiles = sourceDicomFileNames.Select(f => DicomFile.Open(f.FullName, FileReadOption.ReadAll)).ToArray();

            // Add/Update random tags for the source DICOM files.
            DicomAnonymisationTests.AddRandomTags(random, sourceDicomFiles);

            // Save them all to the sourceDirectory.
            var sourcePairs = sourceDicomFileNames.Zip(sourceDicomFiles, (f, d) => Tuple.Create(f, d)).ToArray();

            foreach (var sourcePair in sourcePairs)
            {
                var sourceImageFilePath = Path.Combine(sourceDirectory.FullName, sourcePair.Item1.Name);

                sourcePair.Item2.Save(sourceImageFilePath);
            }

            // Keep the first as a reference for deanonymization later.
            var originalSlice = sourceDicomFiles.First();

            var testAETConfigModel = GetTestAETConfigModel();

            var receivePort = 160;

            using (var dicomDataReceiver = new ListenerDataReceiver(new ListenerDicomSaver(resultDirectory.FullName)))
                using (var deleteService = CreateDeleteService())
                    using (var pushService = CreatePushService())
                        using (var downloadService = CreateDownloadService())
                            using (var uploadService = CreateUploadService())
                                using (var receiveService = CreateReceiveService(receivePort))
                                {
                                    // Start a DICOM receiver for the final DICOM-RT file
                                    var eventCount = new ConcurrentDictionary <DicomReceiveProgressCode, int>();
                                    var folderPath = string.Empty;

                                    dicomDataReceiver.DataReceived += (sender, e) =>
                                    {
                                        folderPath = e.FolderPath;
                                        eventCount.AddOrUpdate(e.ProgressCode, 1, (k, v) => v + 1);
                                    };

                                    StartDicomDataReceiver(dicomDataReceiver, testAETConfigModel.AETConfig.Destination.Port);

                                    // Start the services.
                                    deleteService.Start();
                                    pushService.Start();
                                    downloadService.Start();
                                    uploadService.Start();
                                    receiveService.Start();

                                    // Try a DICOM C-ECHO
                                    var dicomDataSender = new DicomDataSender();

                                    var echoResult = await dicomDataSender.DicomEchoAsync(
                                        testAETConfigModel.CallingAET,
                                        testAETConfigModel.CalledAET,
                                        receivePort,
                                        "127.0.0.1").ConfigureAwait(false);

                                    Assert.IsTrue(echoResult == DicomOperationResult.Success);

                                    // Send the image stack
                                    DcmtkHelpers.SendFolderUsingDCMTK(
                                        sourceDirectory.FullName,
                                        receivePort,
                                        ScuProfile.LEExplicitCT,
                                        TestContext,
                                        applicationEntityTitle: testAETConfigModel.CallingAET,
                                        calledAETitle: testAETConfigModel.CalledAET);

                                    // Wait for DICOM-RT file to be received.
                                    Func <DicomReceiveProgressCode, int, bool> TestEventCount = (progressCode, count) =>
                                                                                                eventCount.ContainsKey(progressCode) && eventCount[progressCode] == count;

                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.AssociationEstablished, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.FileReceived, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.AssociationReleased, 1));
                                    SpinWait.SpinUntil(() => TestEventCount(DicomReceiveProgressCode.ConnectionClosed, 1));

                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.AssociationEstablished] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.FileReceived] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.AssociationReleased] == 1);
                                    Assert.IsTrue(eventCount[DicomReceiveProgressCode.ConnectionClosed] == 1);

                                    var receivedFiles = new DirectoryInfo(folderPath).GetFiles();
                                    Assert.AreEqual(1, receivedFiles.Length);

                                    var receivedFilePath = receivedFiles.First().FullName;

                                    var dicomFile = await DicomFile.OpenAsync(receivedFilePath, FileReadOption.ReadAll).ConfigureAwait(false);

                                    Assert.IsNotNull(dicomFile);

                                    var matchedModel = ApplyAETModelConfigProvider.ApplyAETModelConfig(testAETConfigModel.AETConfig.Config.ModelsConfig, sourceDicomFiles);

                                    var segmentationClient = TestGatewayProcessorConfigProvider.CreateInnerEyeSegmentationClient().Invoke();

                                    DicomAnonymisationTests.AssertDeanonymizedFile(
                                        originalSlice,
                                        dicomFile,
                                        segmentationClient.TopLevelReplacements,
                                        matchedModel.Result.TagReplacements,
                                        false);

                                    AssertIsDicomRtFile(DateTime.UtcNow, dicomFile, matchedModel.Result.ModelId);
                                }
        }