예제 #1
0
        public async Task RetrieveAsync(DicomCGetRequest request, Func <DicomDataset, Task <bool> > storeHandler)
        {
            async Task <DicomCStoreResponse> cStoreHandler(DicomCStoreRequest cStoreRequest)
            {
                var success = await storeHandler(cStoreRequest.Dataset);

                return(new DicomCStoreResponse(cStoreRequest, success ? DicomStatus.Success : DicomStatus.QueryRetrieveUnableToPerformSuboperations));
            }

            var client = CreateClient();
            var presentationContexts = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(DicomStorageCategory.Image, DicomTransferSyntax.ExplicitVRLittleEndian,
                                                                                                              DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ImplicitVRBigEndian);

            client.AdditionalPresentationContexts.AddRange(presentationContexts);
            presentationContexts = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(DicomStorageCategory.Document, DicomTransferSyntax.ExplicitVRLittleEndian,
                                                                                                          DicomTransferSyntax.ImplicitVRLittleEndian, DicomTransferSyntax.ImplicitVRBigEndian);
            client.AdditionalPresentationContexts.AddRange(presentationContexts);
            try
            {
                client.OnCStoreRequest += cStoreHandler;
                await client.AddRequestAsync(request);

                await client.SendAsync();
            }
            finally
            {
                client.OnCStoreRequest -= cStoreHandler;
            }
        }
예제 #2
0
        private void CGetResponse(DicomCGetRequest request, DicomCGetResponse response)
        {
            RoutedItem ri = (RoutedItem)request.UserState;

            var taskInfo = $"id: {ri.id} messageID: {request.MessageID} connection: {Connection.name}";

            _logger.Log(LogLevel.Debug, $"{taskInfo} response: {response.Status}");

            try
            {
                //if(response.Status.ToString().Equals("Success") || response.Status.ToString().Equals("Pending")){

                if (response.HasDataset)
                {
                    foreach (var data in response.Dataset)
                    {
                        _logger.Log(LogLevel.Debug, $"{taskInfo} response.dataset.tag: {data}  ");
                    }
                    _logger.Log(LogLevel.Debug, $"{taskInfo} StudyID: {response.Dataset.GetValue<string>(DicomTag.StudyID, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} StudyInstanceUID: {response.Dataset.GetValue<string>(DicomTag.StudyInstanceUID, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} SOPInstanceUID: {response.Dataset.GetValue<string>(DicomTag.SOPInstanceUID, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} QueryRetrieveLevel: {response.Dataset.GetValue<string>(DicomTag.QueryRetrieveLevel, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} PatientName: {response.Dataset.GetValue<string>(DicomTag.PatientName, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} PatientBirthDate: {response.Dataset.GetValue<string>(DicomTag.PatientBirthDate, 0)} ");
                    _logger.Log(LogLevel.Debug, $"{taskInfo} StudyDate: {response.Dataset.GetValue<string>(DicomTag.StudyDate, 0)} ");
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }
예제 #3
0
        public IEnumerable <DicomCGetResponse> OnCGetRequest(DicomCGetRequest request)
        {
            IDicomImageFinderService finderService = QRServer.CreateFinderService;
            List <string>            matchingFiles = null;

            switch (request.Level)
            {
            case DicomQueryRetrieveLevel.Patient:
                matchingFiles = finderService.FindFilesByUID(request.Dataset.Get <string>(DicomTag.PatientID), string.Empty, string.Empty);
                break;

            case DicomQueryRetrieveLevel.Study:
                matchingFiles = finderService.FindFilesByUID(string.Empty, request.Dataset.Get <string>(DicomTag.StudyInstanceUID), string.Empty);
                break;

            case DicomQueryRetrieveLevel.Series:
                matchingFiles = finderService.FindFilesByUID(string.Empty, string.Empty, request.Dataset.Get <string>(DicomTag.SeriesInstanceUID));
                break;

            case DicomQueryRetrieveLevel.Image:
                yield return(new DicomCGetResponse(request, DicomStatus.QueryRetrieveUnableToPerformSuboperations));

                yield break;
            }

            foreach (var matchingFile in matchingFiles)
            {
                var storeRequest = new DicomCStoreRequest(matchingFile);
                SendRequest(storeRequest);
            }

            yield return(new DicomCGetResponse(request, DicomStatus.Success));
        }
예제 #4
0
        public static DicomCGetRequest CreateCGetBySOPInstanceUID(string studyInstanceUID, string seriesInstanceUID, string sopInstanceUID, DicomPriority priority = DicomPriority.Medium)
        {
            var request = new DicomCGetRequest(studyInstanceUID, seriesInstanceUID, sopInstanceUID, priority);

            // no more dicomtags have to be set
            return(request);
        }
예제 #5
0
        public IEnumerable <DicomCGetResponse> OnCGetRequest(DicomCGetRequest request)
        {
            List <string> matchingFiles = new List <string>();

            switch (request.Level)
            {
            case DicomQueryRetrieveLevel.Patient:
                break;

            case DicomQueryRetrieveLevel.Study:
                break;

            case DicomQueryRetrieveLevel.Series:
                break;

            case DicomQueryRetrieveLevel.Image:
                yield return(new DicomCGetResponse(request, DicomStatus.QueryRetrieveUnableToPerformSuboperations));

                yield break;
            }

            foreach (var matchingFile in matchingFiles)
            {
                var storeRequest = new DicomCStoreRequest(matchingFile);
                SendRequestAsync(storeRequest).Wait();
            }
            yield return(new DicomCGetResponse(request, DicomStatus.Success));
        }
예제 #6
0
        public static DicomCGetRequest CreateCGetBySeriesUID(string studyUID, string seriesUID)
        {
            var request = new DicomCGetRequest(studyUID, seriesUID);

            // no more dicomtags have to be set
            return(request);
        }
예제 #7
0
        public void AddSeveralUIDsToQuery()
        {
            var e = Record.Exception(() =>
            {
                var request = new DicomCGetRequest("1.2.3.456");
                request.Dataset.Add(DicomTag.SeriesInstanceUID, "1.2.3\\3.4.5");
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });

            Assert.Null(e);

            e = Record.Exception(() =>
            {
                var request = new DicomCGetRequest("1.2.3.456");
                request.Dataset.Add(DicomTag.SeriesInstanceUID, "1.2.3", "2.3.4");
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });
            Assert.Null(e);

            e = Record.Exception(() =>
            {
                var request = new DicomCGetRequest("1.2.3.456");
                request.Dataset.Add(new DicomUniqueIdentifier(DicomTag.SeriesInstanceUID, "1.2.3", "3.4.5"));
                Assert.Equal(2, request.Dataset.GetValueCount(DicomTag.SeriesInstanceUID));
            });
            Assert.Null(e);
        }
예제 #8
0
        public void Level_GetterOnRequestCreatedFromCommand_Throws()
        {
            var request   = new DicomCGetRequest(new DicomDataset());
            var exception = Record.Exception(() => request.Level);

            Assert.NotNull(exception);
        }
        public async Task OnCGetRequestAsync_Pending_ShouldRespond()
        {
            var port = Ports.GetNext();

            using (DicomServerFactory.Create <PendingAsyncDicomCGetProvider>(port, logger: _logger.IncludePrefix("DicomServer")))
            {
                var client = DicomClientFactory.Create("127.0.0.1", port, false, "SCU", "ANY-SCP");
                client.Logger = _logger.IncludePrefix(typeof(DicomClient).Name);

                var responses = new ConcurrentQueue <DicomCGetResponse>();
                DicomRequest.OnTimeoutEventArgs timeout = null;
                var studyInstanceUID = DicomUIDGenerator.GenerateDerivedFromUUID().ToString();
                var request          = new DicomCGetRequest(studyInstanceUID)
                {
                    OnResponseReceived = (req, res) => responses.Enqueue(res),
                    OnTimeout          = (sender, args) => timeout = args
                };

                await client.AddRequestAsync(request).ConfigureAwait(false);

                await client.SendAsync().ConfigureAwait(false);

                Assert.Collection(
                    responses,
                    response1 => Assert.Equal(DicomStatus.Pending, response1.Status),
                    response2 => Assert.Equal(DicomStatus.Pending, response2.Status),
                    response3 => Assert.Equal(DicomStatus.Success, response3.Status)
                    );
                Assert.Null(timeout);
            }
        }
        public async IAsyncEnumerable <DicomCGetResponse> OnCGetRequestAsync(DicomCGetRequest request)
        {
            yield return(new DicomCGetResponse(request, DicomStatus.Pending));

            yield return(new DicomCGetResponse(request, DicomStatus.Pending));

            yield return(new DicomCGetResponse(request, DicomStatus.Success));
        }
예제 #11
0
        public void CreateQueryWithInvalidUID()
        {
            var invalidStudyUID = "1.2.0004";
            var e = Record.Exception(() =>
            {
                var request = new DicomCGetRequest(invalidStudyUID, DicomPriority.Medium);
                Assert.Equal(invalidStudyUID, request.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID));
            });

            Assert.Null(e);
        }
예제 #12
0
        public void AddInvalidUIDToQuery()
        {
            var invalidStudyUID = "1.2.0004";
            var e = Record.Exception(() =>
            {
                var request = new DicomCGetRequest(invalidStudyUID, DicomPriority.Medium);
                request.Dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, invalidStudyUID);
                Assert.Equal(invalidStudyUID, request.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID));
            });

            Assert.Null(e);
        }
예제 #13
0
        internal DicomCGetRequest CreateCGetRquest_FramesByList(String SOPInstanceUID, int FrameIndex)
        {
            DicomDataset command = new DicomDataset();

            command.AddOrUpdate(DicomTag.CommandField, (ushort)DicomCommandField.CGetRequest);
            command.Add(DicomTag.AffectedSOPClassUID, DicomUID.CompositeInstanceRootRetrieveGET);
            command.AddOrUpdate(DicomTag.Priority, (ushort)DicomPriority.Medium);
            command.AddOrUpdate(DicomTag.MessageID, (ushort)1);
            command.AddOrUpdate(DicomTag.CommandDataSetType, (ushort)0x0202);
            command.AddOrUpdate(DicomTag.SimpleFrameList, FrameIndex.ToUInt32Array());
            command.AddOrUpdate(DicomTag.SOPInstanceUID, SOPInstanceUID);
            var cGetRequest = new DicomCGetRequest(command);

            cGetRequest.Dataset = new DicomDataset();
            cGetRequest.Dataset.Add(DicomTag.AffectedSOPClassUID, DicomUID.CompositeInstanceRootRetrieveGET);
            return(cGetRequest);
        }
예제 #14
0
        public async Task DicomCGetRequest_PickCTImagesInStudy_OnlyCTImagesRetrieved()
        {
            var client = DicomClientFactory.Create("localhost", 11112, false, "SCU", "COMMON");

            var pc = DicomPresentationContext.GetScpRolePresentationContext(DicomUID.CTImageStorage);

            client.AdditionalPresentationContexts.Add(pc);

            var counter = 0;
            var locker  = new object();

            client.OnCStoreRequest = request =>
            {
                lock (locker)
                {
                    ++counter;
                }

                return(Task.FromResult(new DicomCStoreResponse(request, DicomStatus.Success)));
            };

            var get = new DicomCGetRequest("1.2.840.113619.2.55.3.2609388324.145.1222836278.84");

            var handle = new ManualResetEventSlim();

            get.OnResponseReceived = (request, response) =>
            {
                if (response.Remaining == 0)
                {
                    handle.Set();
                }
            };
            await client.AddRequestAsync(get);

            await client.SendAsync().ConfigureAwait(false);

            handle.Wait();

            Assert.Equal(140, counter);
        }
예제 #15
0
        public async Task DicomCGetRequest_OneImageInSeries_Received()
        {
            var client = DicomClientFactory.Create("localhost", 11112, false, "SCU", "COMMON");

            var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                DicomStorageCategory.Image,
                DicomTransferSyntax.ExplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRBigEndian);

            client.AdditionalPresentationContexts.AddRange(pcs);

            DicomDataset dataset = null;

            client.OnCStoreRequest = request =>
            {
                dataset = request.Dataset;
                return(Task.FromResult(new DicomCStoreResponse(request, DicomStatus.Success)));
            };

            var get = new DicomCGetRequest(
                "1.2.840.113619.2.1.1.322987881.621.736170080.681",
                "1.2.840.113619.2.1.2411.1031152382.365.736169244");

            var handle = new ManualResetEventSlim();

            get.OnResponseReceived = (request, response) =>
            {
                handle.Set();
            };
            await client.AddRequestAsync(get);

            await client.SendAsync().ConfigureAwait(false);

            handle.Wait();

            Assert.Equal("RT ANKLE", dataset.GetString(DicomTag.StudyDescription));
        }
예제 #16
0
        public async Task <DicomDataset> GetImagesBySOPInstanceAsync(string serverIp, int serverPort, string serverAET, string localAET, string studyInstanceUid, string seriesInstanceUid, string sopInstanceUid)
        {
            DicomDataset imageDatasets = null;

            DicomCGetRequest request = RequestFactory.CreateCGetBySeriesUID(studyInstanceUid, seriesInstanceUid);
            DicomClient      client  = new DicomClient(serverIp, serverPort, false, localAET, serverAET);

            client.OnCStoreRequest += async(req) =>
            {
                if (req.HasDataset)
                {
                    imageDatasets = req.Dataset;
                    return(await Task.FromResult(new DicomCStoreResponse(req, DicomStatus.Success)));
                }
                else
                {
                    logger.Error("C-STORE request has no dataset.");
                    return(await Task.FromResult(new DicomCStoreResponse(req, DicomStatus.AttributeListError)));
                }
            };
            // the client has to accept storage of the images. We know that the requested images are of SOP class Secondary capture,
            // so we add the Secondary capture to the additional presentation context
            // a more general approach would be to mace a cfind-request on image level and to read a list of distinct SOP classes of all
            // the images. these SOP classes shall be added here.
            var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                DicomStorageCategory.Image,
                DicomTransferSyntax.ExplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRLittleEndian,
                DicomTransferSyntax.ImplicitVRBigEndian);

            client.AdditionalPresentationContexts.AddRange(pcs);
            await client.AddRequestAsync(request);

            await client.SendAsync();

            return(imageDatasets);
        }
예제 #17
0
        // Note: cGet is not working at this point
        public void CGet(RoutedItem routedItem, int taskID, DICOMConnection connection)
        {
            Connection = connection;
            //process any outstanding moves and return the results

            var taskInfo = $"task: {taskID} connection: {Connection.name}";

            List <string> movesToRemove = new List <string>();

            try
            {
                _logger.Log(LogLevel.Debug, $"{taskInfo} dicom.AddRequest: {routedItem.id} ");
                try
                {
                    var request = new DicomCGetRequest(routedItem.request)
                    {
                        UserState = routedItem
                    };

                    request.OnResponseReceived += CGetResponse;
                    // Fix if cGet is ever fixed                        dicomClient.AddRequest(request);
                }
                catch (TaskCanceledException)
                {
                    _logger.Log(LogLevel.Information, $"Task was canceled.");
                }
                catch (DicomDataException e)
                {
                    _logger.Log(LogLevel.Warning, $"{taskInfo} move: {routedItem.id} {e.Message} {e.StackTrace}");
                }
            }
            catch (Exception e)
            {
                _logger.LogFullException(e, taskInfo);
            }
        }
        public async Task <bool> DataQuery()
        {
            try
            {
                var host       = _configuration.GetSection("Source:Host").Value;
                var scpAeTitle = _configuration.GetSection("Source:AeTitle").Value;
                var port       = Int32.Parse(_configuration.GetSection("Source:Port").Value);

                clientQuery = new Dicom.Network.Client.DicomClient(host, port, false, "SCU", scpAeTitle);

                var cFindStudy = new DicomCFindRequest(DicomQueryRetrieveLevel.Study);

                cFindStudy.Dataset.AddOrUpdate(DicomTag.StudyInstanceUID, "");

                cFindStudy.OnResponseReceived = async(DicomCFindRequest rq, DicomCFindResponse rp) => {
                    if (null != rp.Dataset)
                    {
                        var    cFindSeries = new DicomCFindRequest(DicomQueryRetrieveLevel.Series, DicomPriority.Medium);
                        string studyUid    = rp.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID);
                        cFindSeries.Dataset.AddOrUpdate(DicomTag.StudyInstanceUID, studyUid);
                        cFindSeries.Dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, "");
                        cFindSeries.OnResponseReceived = async(DicomCFindRequest req, DicomCFindResponse rep) => {
                            if (null != rep.Dataset)
                            {
                                var cFindImage = new DicomCFindRequest(DicomQueryRetrieveLevel.Image, DicomPriority.Medium);
                                var seriesUid  = rep.Dataset.GetSingleValue <string>(DicomTag.SeriesInstanceUID);

                                cFindImage.Dataset.AddOrUpdate(DicomTag.StudyInstanceUID, studyUid);
                                cFindImage.Dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, seriesUid);
                                cFindImage.Dataset.AddOrUpdate(DicomTag.SOPInstanceUID, "");

                                cFindImage.OnResponseReceived = async(DicomCFindRequest reqi, DicomCFindResponse repi) =>
                                {
                                    if (null != repi.Dataset)
                                    {
                                        var imageUid   = repi.Dataset.GetString(DicomTag.SOPInstanceUID);
                                        var clientCGet = new Dicom.Network.Client.DicomClient(host, port, false, "SCU", scpAeTitle);

                                        clientCGet.OnCStoreRequest += (DicomCStoreRequest reqs) =>
                                        {
                                            _dicomFileQueue.Enqueue(reqs.Dataset);
                                            return(Task.FromResult(new DicomCStoreResponse(reqs, DicomStatus.Success)));
                                        };
                                        var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                                            DicomStorageCategory.Image,
                                            DicomTransferSyntax.ExplicitVRLittleEndian,
                                            DicomTransferSyntax.ImplicitVRLittleEndian,
                                            DicomTransferSyntax.ImplicitVRBigEndian);
                                        clientCGet.AdditionalPresentationContexts.AddRange(pcs);
                                        var cGetRequest = new DicomCGetRequest(studyUid, seriesUid, imageUid);
                                        await clientCGet.AddRequestAsync(cGetRequest);

                                        await clientCGet.SendAsync();
                                    }
                                };
                                await clientQuery.AddRequestAsync(cFindImage);

                                await clientQuery.SendAsync();
                            }
                        };
                        await clientQuery.AddRequestAsync(cFindSeries);

                        await clientQuery.SendAsync();
                    }
                };

                await clientQuery.AddRequestAsync(cFindStudy);

                await clientQuery.SendAsync();

                Thread.Sleep(Timeout.Infinite);
                return(true);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
예제 #19
0
        public void Level_Getter_ReturnsCorrectQueryRetrieveLevel(DicomCGetRequest request, DicomQueryRetrieveLevel expected)
        {
            var actual = request.Level;

            Assert.Equal(expected, actual);
        }
예제 #20
0
        public IEnumerable <DicomCGetResponse> OnCGetRequest(DicomCGetRequest request)
        {
            var queryLevel = request.Level;

            switch (queryLevel)
            {
            case DicomQueryRetrieveLevel.Patient:
            {
                IEnumerable <DicomDataset> resStudys = PacsServer.QueryService.FindStudies(request.Dataset, new QueryOptions());
                foreach (var resStudy in resStudys)
                {
                    var resSerices = PacsServer.QueryService.FindSeries(resStudy, new QueryOptions());
                    foreach (var resSerice in resSerices)
                    {
                        AddSearchRequestData(resSerice);
                        var resObjects = PacsServer.QueryService.FindObjectInstances(resSerice, new QueryOptions());
                        foreach (var resObject in resObjects)
                        {
                            var location     = RetrieveSopInstance(resObject);
                            var storeRequest = new DicomCStoreRequest(location.ID);
                            SendRequestAsync(storeRequest).Wait();
                        }
                    }
                }
            }
            break;

            case DicomQueryRetrieveLevel.Study:
            {
                IEnumerable <DicomDataset> resStudys = PacsServer.QueryService.FindStudies(request.Dataset, new QueryOptions());
                foreach (var resStudy in resStudys)
                {
                    var resSerices = PacsServer.QueryService.FindSeries(resStudy, new QueryOptions());
                    foreach (var resSerice in resSerices)
                    {
                        AddSearchRequestData(resSerice);
                        var resObjects = PacsServer.QueryService.FindObjectInstances(resSerice, new QueryOptions());
                        foreach (var resObject in resObjects)
                        {
                            var location     = RetrieveSopInstance(resObject);
                            var storeRequest = new DicomCStoreRequest(location.ID);
                            SendRequestAsync(storeRequest).Wait();
                        }
                    }
                }
            }
            break;

            case DicomQueryRetrieveLevel.Series:
            {
                var resSerices = PacsServer.QueryService.FindSeries(request.Dataset, new QueryOptions());
                foreach (var resSerice in resSerices)
                {
                    AddSearchRequestData(resSerice);
                    var resObjects = PacsServer.QueryService.FindObjectInstances(resSerice, new QueryOptions());
                    foreach (var resObject in resObjects)
                    {
                        var location     = RetrieveSopInstance(resObject);
                        var storeRequest = new DicomCStoreRequest(location.ID);
                        SendRequestAsync(storeRequest).Wait();
                    }
                }
            }
            break;

            case DicomQueryRetrieveLevel.Image:
            {
                AddSearchRequestData(request.Dataset);
                var resObjects = PacsServer.QueryService.FindObjectInstances(request.Dataset, new QueryOptions());
                foreach (var resObject in resObjects)
                {
                    var location     = RetrieveSopInstance(resObject);
                    var storeRequest = new DicomCStoreRequest(location.ID);
                    SendRequestAsync(storeRequest).Wait();
                }
            }
            break;
            }
            yield return(new DicomCGetResponse(request, DicomStatus.Success));
        }