Пример #1
0
        public async Task StoreImageAsync(string serverIp, int serverPort, string serverAET, string localAET, IEnumerable <CStoreItem> items)
        {
            DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET);

            client.NegotiateAsyncOps();

            foreach (CStoreItem item in items)
            {
                DicomCStoreRequest request = new DicomCStoreRequest(item.File)
                {
                    OnResponseReceived = (req, res) =>
                    {
                        if (res.Status != DicomStatus.Success)
                        {
                            Logger.Error("C-STORE send failed. Instance UID - [{0}]", req.SOPInstanceUID);
                            item.Status = CStoreItemStatus.Failed;
                        }
                        else
                        {
                            item.Status = CStoreItemStatus.Success;
                        }
                    }
                };

                await client.AddRequestAsync(request);
            }

            await client.SendAsync();
        }
Пример #2
0
        /// <summary>
        /// 测试请求
        /// </summary>
        /// <param name="serverIp">Server IP Addr</param>
        /// <param name="serverPort">Server Port</param>
        /// <param name="serverAET">Server AE Title</param>
        /// <param name="localAET">Client AE Title</param>
        /// <returns>true if success</returns>
        public async Task <bool> Echo(string serverIp, int serverPort, string serverAET, string localAET)
        {
            bool echoResult = false;

            DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET);

            client.NegotiateAsyncOps();

            DicomCEchoRequest request = new DicomCEchoRequest()
            {
                OnResponseReceived = (req, res) =>
                {
                    if (res.Status == DicomStatus.Success)
                    {
                        echoResult = true;
                    }
                }
            };

            await client.AddRequestAsync(request);

            try
            {
                await client.SendAsync();
            }
            catch (System.Exception ex)
            {
                loggerService.Error(ex);
                return(false);
            }

            return(echoResult);
        }
Пример #3
0
 public DicomBaseClient(string serverHost, int serverPort, string serverAeTitle, string clientAeTitle)
 {
     CreateClient = () =>
     {
         var client = new DicomClient(serverHost, serverPort, false, clientAeTitle, serverAeTitle);
         client.NegotiateAsyncOps();
         return(client);
     };
 }
Пример #4
0
        public async Task <List <TempDicomSeries> > GetDicomSeries(TempDicomStudy d)
        {
            var result  = new List <TempDicomSeries>();
            var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Series);

            #region seriesDataset
            request.Dataset.AddOrUpdate(DicomTag.Modality, "");
            request.Dataset.AddOrUpdate(DicomTag.SeriesNumber, "");
            request.Dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, "");
            request.Dataset.AddOrUpdate(DicomTag.SeriesDate, "");
            request.Dataset.AddOrUpdate(DicomTag.SeriesTime, "");
            request.Dataset.AddOrUpdate(DicomTag.SeriesDescription, "");
            request.Dataset.AddOrUpdate(DicomTag.StudyInstanceUID, d.StudyInstanceUID);
            #endregion

            request.OnResponseReceived += (re, response) =>
            {
                if ((response as DicomCFindResponse).Status == DicomStatus.Success)
                {
                    ;
                }
                logger.Trace(" C-Find response = " + response);
                try
                {
                    if ((response as DicomCFindResponse).HasDataset)
                    {
                        TempDicomSeries s = new TempDicomSeries((response as DicomCFindResponse).Dataset);
                        if (result.Where(x => x.SeriesInstanceUID == s.SeriesInstanceUID).Any() == false)
                        {
                            s.TempDicomStudy = d;
                            d.DicomSeries.Add(s);
                            result.Add(s);
                            //s.Debug();
                            logger.Trace("Picked up Series Instance UID " + (response as DicomCFindResponse).Dataset.GetString(DicomTag.SeriesInstanceUID));
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Warn(ex, "Exception in getting TempDicomSeries");
                }
            };

            foreach (StoredDicomServer s in DicomServers.Where(x => x.Online))
            {
                logger.Trace("Running series query on " + s.AETitle);
                DicomClient client = new DicomClient(s.IPAddress, s.Port, false, _preferences.AETitle, s.AETitle);
                client.AssociationRejected += Client_AssociationRejected;
                client.AssociationAccepted += Client_AssociationAccepted;
                client.NegotiateAsyncOps();
                await client.AddRequestAsync(request);

                await client.SendAsync();
            }
            return(result);
        }
Пример #5
0
        public async Task <List <TempDicomStudy> > GetDicomStudies(DateTime studyDate)
        {
            logger.Trace("GetDicomStudies(" + studyDate + ")");
            var Studies = new List <TempDicomStudy>();
            var request = new DicomCFindRequest(DicomQueryRetrieveLevel.Study);

            #region studyDataset
            request.Dataset.AddOrUpdate(DicomTag.PatientName, "");
            request.Dataset.AddOrUpdate(DicomTag.PatientID, "");
            request.Dataset.AddOrUpdate(DicomTag.StudyDate, studyDate.ToString("yyyyMMdd"));
            request.Dataset.AddOrUpdate(DicomTag.StudyInstanceUID, "");
            request.Dataset.AddOrUpdate(DicomTag.AccessionNumber, "");
            request.Dataset.AddOrUpdate(DicomTag.StudyDescription, "");
            request.Dataset.AddOrUpdate(DicomTag.ModalitiesInStudy, "");
            #endregion

            request.OnResponseReceived += (re, response) =>
            {
                logger.Trace(" C-Find response = " + response);
                try
                {
                    if ((response as DicomCFindResponse).HasDataset)
                    {
                        if (Studies.Where(x => x.StudyInstanceUID == (response as DicomCFindResponse).Dataset.GetString(DicomTag.StudyInstanceUID)).Any() == false)
                        {
                            Studies.Add(new TempDicomStudy((response as DicomCFindResponse).Dataset));
                            logger.Trace("Picked up Study Instance UID " + (response as DicomCFindResponse).Dataset.GetString(DicomTag.StudyInstanceUID));
                        }
                        else
                        {
                            logger.Trace("Already picked up Study Instance UID " + (response as DicomCFindResponse).Dataset.GetString(DicomTag.StudyInstanceUID));
                        }
                    }
                }
                catch (Exception ex)
                {
                    logger.Warn(ex, "Exception in getting studyUID");
                }
            };

            foreach (StoredDicomServer s in DicomServers.Where(x => x.Online))
            {
                logger.Trace("Running study level query on " + s.AETitle);
                DicomClient client = new DicomClient(s.IPAddress, s.Port, false, _preferences.AETitle, s.AETitle);
                client.AssociationRejected += Client_AssociationRejected;
                client.AssociationAccepted += Client_AssociationAccepted;
                client.NegotiateAsyncOps();
                await client.AddRequestAsync(request);

                await client.SendAsync();

                //client.Send(s.IPAddress, s.Port, false, LocalAETitle, s.AETitle, 5000);
            }
            return(Studies);
        }
Пример #6
0
        public async Task NewDicomClient_SendEchos()
        {
            var client = new Dicom.Network.Client.DicomClient("127.0.0.1", _server.Port, false, "SCU", "ANY-SCP");

            client.NegotiateAsyncOps(1, 1);
            client.AssociationLingerTimeoutInMs = 0;

            var requests = Enumerable.Range(0, 1000).Select(i => new DicomCEchoRequest());

            await client.AddRequestsAsync(requests).ConfigureAwait(false);

            await client.SendAsync().ConfigureAwait(false);
        }
Пример #7
0
        private async Task SendCStoreRequest(OutputJob job)
        {
            await DownloadFromPayloadsService(job);

            if (job.PendingDicomFiles.Count > 0)
            {
                var         countDownEventHandle = new CountdownEvent(job.PendingDicomFiles.Count);
                DicomClient client = null;
                try
                {
                    client = new DicomClient(
                        job.HostIp,
                        job.Port,
                        false,
                        _dicomAdapterConfiguration.Value.Dicom.Scu.AeTitle,
                        job.AeTitle);
                    client.AssociationAccepted += (sender, args) =>
                                                  job.Logger.LogInformation("Association accepted.");
                    client.AssociationRejected += (sender, args) =>
                                                  job.Logger.LogInformation("Association rejected.");
                    client.AssociationReleased += (sender, args) =>
                                                  job.Logger.LogInformation("Association release.");

                    client.Options = new DicomServiceOptions
                    {
                        LogDataPDUs      = _dicomAdapterConfiguration.Value.Dicom.Scu.LogDataPdus,
                        LogDimseDatasets = _dicomAdapterConfiguration.Value.Dicom.Scu.LogDimseDatasets
                    };
                    client.NegotiateAsyncOps();
                    GenerateRequests(job, client, countDownEventHandle);
                    job.Logger.LogInformation("Sending job to {0}@{1}:{2}", job.AeTitle, job.HostIp, job.Port);
                    await client.SendAsync(_token).ConfigureAwait(false);

                    countDownEventHandle.Wait(_token);
                    job.Logger.LogInformation("Job sent to {0} completed", job.AeTitle);
                }
                catch (Exception ex)
                {
                    HandleCStoreException(ex, job, client);
                }
            }
            job.LogFailedRequests();
            job.ReportStatus(_token);
        }
Пример #8
0
        protected override async Task <OutputJob> ExportDataBlockCallback(OutputJob outputJob, CancellationToken cancellationToken)
        {
            using var loggerScope = _logger.BeginScope(new LogginDataDictionary <string, object> { { "JobId", outputJob.JobId }, { "PayloadId", outputJob.PayloadId } });

            if (outputJob.PendingDicomFiles.Count > 0)
            {
                var         countDownEventHandle = new CountdownEvent(outputJob.PendingDicomFiles.Count);
                DicomClient client = null;
                try
                {
                    client = new DicomClient(
                        outputJob.HostIp,
                        outputJob.Port,
                        false,
                        _scuConfiguration.AeTitle,
                        outputJob.AeTitle);

                    client.AssociationAccepted += (sender, args) => _logger.LogInformation("Association accepted.");
                    client.AssociationRejected += (sender, args) => _logger.LogInformation("Association rejected.");
                    client.AssociationReleased += (sender, args) => _logger.LogInformation("Association release.");

                    client.Options = new DicomServiceOptions
                    {
                        LogDataPDUs      = _scuConfiguration.LogDataPdus,
                        LogDimseDatasets = _scuConfiguration.LogDimseDatasets
                    };
                    client.NegotiateAsyncOps();
                    GenerateRequests(outputJob, client, countDownEventHandle);
                    _logger.LogInformation("Sending job to {0}@{1}:{2}", outputJob.AeTitle, outputJob.HostIp, outputJob.Port);
                    await client.SendAsync(cancellationToken).ConfigureAwait(false);

                    countDownEventHandle.Wait(cancellationToken);
                    _logger.LogInformation("Job sent to {0} completed", outputJob.AeTitle);
                }
                catch (Exception ex)
                {
                    HandleCStoreException(ex, outputJob, client);
                }
            }

            return(outputJob);
        }
Пример #9
0
        //建立连接并Retrieve
        async public void DicomCRetrieveRequestFunct(ServerConfig OneServerConfig)
        {
            // 建立连接
            var client = new DicomClient(OneServerConfig.RemoteIp, OneServerConfig.RemotePort,
                                         false, OneServerConfig.LocalAeTitle, OneServerConfig.RemoteAeTitle);

            client.NegotiateAsyncOps();

            // 使用CMOVE抓取信息,发送到本机STORE服务
            // using ()
            {
                OneServerConfig.AddLogStr($"Run C-Store SCP server on port 104");
                foreach (var oneResult in Results)
                {
                    var  cMoveRequest     = new DicomCMoveRequest("SegAE", oneResult.StudyInstanceUid, oneResult.SeriesInstanceUid);
                    bool?moveSuccessfully = null;


                    cMoveRequest.OnResponseReceived += (DicomCMoveRequest requ, DicomCMoveResponse response) =>
                    {
                        if (response.Status.State == DicomState.Pending)
                        {
                            // Console.WriteLine("Sending is in progress. please wait: " + response.Remaining.ToString());
                        }
                        else if (response.Status.State == DicomState.Success)
                        {
                            OneServerConfig.AddLogStr($"{oneResult.PatientId} " +
                                                      $"{oneResult.SeriesInstanceUid}");
                            moveSuccessfully = true;
                        }
                        else if (response.Status.State == DicomState.Failure)
                        {
                            OneServerConfig.AddLogStr($"{response.Status.Description}");
                            moveSuccessfully = false;
                        }
                    };
                    await client.AddRequestAsync(cMoveRequest);

                    await client.SendAsync();
                }
            }
        }
Пример #10
0
        public async Task <List <DicomFile> > GetDicomFiles(string studyInstanceUID, string seriesInstanceUID)
        {
            ReceivedFiles.Clear();
            DicomCMoveRequest moveRequest = new DicomCMoveRequest(_preferences.AETitle, studyInstanceUID, seriesInstanceUID);

            moveRequest.OnResponseReceived += (DicomCMoveRequest requ, DicomCMoveResponse response) =>
            {
                if (response.Status.State == DicomState.Pending)
                {
                    //logger.Trace("PresentationContext: " + response.PresentationContext.AcceptedTransferSyntax.ToString());
                }
                else if (response.Status.State == DicomState.Success)
                {
                    logger.Trace("Sending successfully finished");
                }
                else if (response.Status.State == DicomState.Failure)
                {
                    logger.Error("Error sending datasets: " + response.Status.Description);
                }
            };
            logger.Debug("Move Request; AE Title: " + _preferences.AETitle + "; Level: " + moveRequest.Level + "; SOP Class UID: " + moveRequest.SOPClassUID);
            foreach (StoredDicomServer s in DicomServers)
            {
                logger.Trace("GetDicomFiles(" + studyInstanceUID + "," + seriesInstanceUID + ") on " + s.AETitle);


                var pcs = DicomPresentationContext.GetScpRolePresentationContextsFromStorageUids(
                    DicomStorageCategory.Image,
                    DicomTransferSyntax.ExplicitVRLittleEndian,
                    DicomTransferSyntax.ImplicitVRLittleEndian);
                DicomClient client = new DicomClient(s.IPAddress, s.Port, false, _preferences.AETitle, s.AETitle);
                client.AdditionalPresentationContexts.AddRange(pcs);
                client.AssociationRejected += Client_AssociationRejected;
                client.AssociationAccepted += Client_AssociationAccepted;
                client.NegotiateAsyncOps();
                await client.AddRequestAsync(moveRequest);

                await client.SendAsync();
            }

            return(ReceivedFiles);
        }
Пример #11
0
        private async void echoServer_Do()
        {
            // var server = new DicomServer<DicomCEchoProvider>();
            var client = new DicomClient(TheServerConfig.RemoteIp, TheServerConfig.RemotePort,
                                         false, TheServerConfig.LocalAeTitle, TheServerConfig.RemoteAeTitle);

            client.NegotiateAsyncOps();

            var request = new DicomCEchoRequest();

            request.OnResponseReceived += (DicomCEchoRequest req, DicomCEchoResponse response) =>
            {
                // Console.WriteLine("C-Echo Status: " + response.Status);
                TheServerConfig.LogInfo += ("ECHO: " + response.Status + Environment.NewLine);
            };

            await client.AddRequestAsync(request);

            await client.SendAsync();
        }
Пример #12
0
        public IEnumerable <DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
        {
            // the c-move request contains the DestinationAE. the data of this AE should be configured somewhere.
            if (request.DestinationAE != "STORESCP")
            {
                yield return(new DicomCMoveResponse(request, DicomStatus.QueryRetrieveMoveDestinationUnknown));

                yield return(new DicomCMoveResponse(request, DicomStatus.ProcessingFailure));

                yield break;
            }

            // this data should come from some data storage!
            var destinationPort = 11112;
            var destinationIP   = "localhost";

            IDicomImageFinderService finderService = QRServer.CreateFinderService;
            IEnumerable <string>     matchingFiles = Enumerable.Empty <string>();

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

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

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

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

                yield break;
            }

            var client = new DicomClient(destinationIP, destinationPort, false, QRServer.AETitle, request.DestinationAE);

            client.NegotiateAsyncOps();
            int storeTotal   = matchingFiles.Count();
            int storeDone    = 0; // this variable stores the number of instances that have already been sent
            int storeFailure = 0; // this variable stores the number of faulues returned in a OnResponseReceived

            foreach (string file in matchingFiles)
            {
                var storeRequest = new DicomCStoreRequest(file);
                // !!! there is a Bug in fo-dicom 3.0.2 that the OnResponseReceived handlers are invoked not until the DicomClient has already
                //     sent all the instances. So the counters are not increased image by image sent but only once in a bulk after all storage
                //     has been finished. This bug will be fixed hopefully soon.
                storeRequest.OnResponseReceived += (req, resp) =>
                {
                    if (resp.Status == DicomStatus.Success)
                    {
                        Logger.Info("Storage of image successfull");
                        storeDone++;
                    }
                    else
                    {
                        Logger.Error("Storage of image failed");
                        storeFailure++;
                    }
                };
                client.AddRequestAsync(storeRequest).Wait();
            }

            var sendTask = client.SendAsync();

            while (!sendTask.IsCompleted)
            {
                // while the send-task is runnin we inform the QR SCU every 2 seconds about the status and how many instances are remaining to send.
                yield return(new DicomCMoveResponse(request, DicomStatus.Pending)
                {
                    Remaining = storeTotal - storeDone - storeFailure, Completed = storeDone
                });

                Thread.Sleep(TimeSpan.FromSeconds(2));
            }

            Logger.Info("..finished");
            yield return(new DicomCMoveResponse(request, DicomStatus.Success));
        }
Пример #13
0
        private static async Task Main(string[] args)
        {
            try
            {
                // Initialize log manager.
                LogManager.SetImplementation(NLogManager.Instance);

                DicomException.OnException += delegate(object sender, DicomExceptionEventArgs ea)
                {
                    ConsoleColor old = Console.ForegroundColor;
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine(ea.Exception);
                    Console.ForegroundColor = old;
                };

                var config = new LoggingConfiguration();

                var target = new ColoredConsoleTarget
                {
                    Layout = @"${date:format=HH\:mm\:ss}  ${message}"
                };
                config.AddTarget("Console", target);
                config.LoggingRules.Add(new LoggingRule("*", NLog.LogLevel.Debug, target));

                NLog.LogManager.Configuration = config;

                var client = new DicomClient("127.0.0.1", 11112, false, "SCU", "STORESCP");
                client.NegotiateAsyncOps();
                for (int i = 0; i < 10; i++)
                {
                    await client.AddRequestAsync(new DicomCEchoRequest());
                }

                await client.AddRequestAsync(new DicomCStoreRequest(@"test1.dcm"));

                await client.AddRequestAsync(new DicomCStoreRequest(@"test2.dcm"));

                await client.SendAsync();

                foreach (DicomPresentationContext ctr in client.AdditionalPresentationContexts)
                {
                    Console.WriteLine("PresentationContext: " + ctr.AbstractSyntax + " Result: " + ctr.Result);
                }

                var samplesDir = Path.Combine(
                    Path.GetPathRoot(Environment.CurrentDirectory),
                    "Development",
                    "fo-dicom-samples");
                var testDir = Path.Combine(samplesDir, "Test");

                if (!Directory.Exists(testDir))
                {
                    Directory.CreateDirectory(testDir);
                }

                //var img = new DicomImage(samplesDir + @"\ClearCanvas\CRStudy\1.3.51.5145.5142.20010109.1105627.1.0.1.dcm");
                //img.RenderImage().Save(testDir + @"\test.jpg");

                //var df = DicomFile.Open(samplesDir + @"\User Submitted\overlays.dcm");

                //Console.WriteLine(df.FileMetaInfo.Get<DicomTransferSyntax>(DicomTag.TransferSyntaxUID).UID.Name);
                //Console.WriteLine(df.Dataset.Get<PlanarConfiguration>(DicomTag.PlanarConfiguration));

                //var img = new DicomImage(df.Dataset);
                //img.RenderImage().Save(testDir + @"\test.jpg");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.JPEGLSLossless);
                //df.Save(testDir + @"\test-jls.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.JPEG2000Lossless);
                //df.Save(testDir + @"\test-j2k.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14SV1);
                //df.Save(testDir + @"\test-jll.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.RLELossless);
                //df.Save(testDir + @"\test-rle.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRLittleEndian);
                //df.Save(testDir + @"\test-ele.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRBigEndian);
                //df.Save(testDir + @"\test-ebe.dcm");

                //df = df.ChangeTransferSyntax(DicomTransferSyntax.ImplicitVRLittleEndian);
                //df.Save(testDir + @"\test-ile.dcm");

                //Console.WriteLine("End...");
                //Console.ReadLine();

                //df.WriteToLog(LogManager.GetCurrentClassLogger(), LogLevel.Info);

                //Console.WriteLine(DicomValueMultiplicity.Parse("1"));
                //Console.WriteLine(DicomValueMultiplicity.Parse("3"));
                //Console.WriteLine(DicomValueMultiplicity.Parse("1-3"));
                //Console.WriteLine(DicomValueMultiplicity.Parse("1-n"));
                //Console.WriteLine(DicomValueMultiplicity.Parse("2-2n"));

                //Console.WriteLine(DicomTag.Parse("00200020"));
                //Console.WriteLine(DicomTag.Parse("0008,0040"));
                //Console.WriteLine(DicomTag.Parse("(3000,0012)"));
                //Console.WriteLine(DicomTag.Parse("2000,2000:TEST CREATOR"));
                //Console.WriteLine(DicomTag.Parse("(4000,4000:TEST_CREATOR:2)"));

                //Console.WriteLine(DicomMaskedTag.Parse("(30xx,xx90)"));
                //Console.WriteLine(DicomMaskedTag.Parse("(3000-3021,0016)"));

                //DicomRange<DateTime> r = new DicomRange<DateTime>(DateTime.Now.AddSeconds(-5), DateTime.Now.AddSeconds(5));
                //Console.WriteLine(r.Contains(DateTime.Now));
                //Console.WriteLine(r.Contains(DateTime.Today));
                //Console.WriteLine(r.Contains(DateTime.Now.AddSeconds(60)));

                //DicomDictionary dict = new DicomDictionary();
                //dict.Load(@"F:\Development\fo-dicom\DICOM\Dictionaries\dictionary.xml", DicomDictionaryFormat.XML);

                //string output = Dicom.Generators.DicomTagGenerator.Generate("Dicom", "DicomTag", dict);
                //File.WriteAllText(@"F:\Development\fo-dicom\DICOM\DicomTagGenerated.cs", output);

                //output = Dicom.Generators.DicomDictionaryGenerator.Generate("Dicom", "DicomDictionary", "LoadInternalDictionary", dict);
                //File.WriteAllText(@"F:\Development\fo-dicom\DICOM\DicomDictionaryGenerated.cs", output);

                //string output = Dicom.Generators.DicomUIDGenerator.Process(@"F:\Development\fo-dicom\DICOM\Dictionaries\dictionary.xml");
                //File.WriteAllText(@"F:\Development\fo-dicom\DICOM\DicomUIDGenerated.cs", output);
            }
            catch (Exception e)
            {
                if (!(e is DicomException))
                {
                    Console.WriteLine(e.ToString());
                }
            }

            Console.ReadLine();
        }
Пример #14
0
        public IEnumerable <DicomCMoveResponse> OnCMoveRequest(DicomCMoveRequest request)
        {
            //var cMoveAETitle = CADServer.DB.CMoveAETitles.Where(a => a.AETitle == request.DestinationAE).ToList();

            //// the c-move request contains the DestinationAE. the data of this AE should be configured somewhere.
            //if (cMoveAETitle.Count == 0)
            //{
            //    yield return new DicomCMoveResponse(request, DicomStatus.QueryRetrieveMoveDestinationUnknown);
            //    yield return new DicomCMoveResponse(request, DicomStatus.ProcessingFailure);
            //    yield break;
            //}

            //// this data should come from some data storage!
            //var destinationPort = cMoveAETitle[0].Port;
            //var destinationIP = cMoveAETitle[0].IP;
            var destinationPort = 11112;
            var destinationIP   = "127.0.0.1";

            IDbCommand selectCommand = PacsServer.DatabaseService.CreateCommand();

            selectCommand.Connection  = PacsServer.DatabaseService.CreateConnection();
            selectCommand.CommandText = string.Format(@"SELECT * From CMoveIPTable WHERE AEtitle = '{0}'", request.DestinationAE);

            selectCommand.Connection.Open();
            using (var reader = selectCommand.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleRow))
            {
                if (reader.Read())
                {
                    destinationPort = reader.GetInt32(2);
                    destinationIP   = reader.GetString(1);
                    Console.WriteLine("{0} {1} {2} {3}", reader.GetInt64(0), reader.GetString(1), reader.GetInt32(2), reader.GetString(3));
                }
                else
                {
                    yield return(new DicomCMoveResponse(request, DicomStatus.QueryRetrieveMoveDestinationUnknown));

                    yield return(new DicomCMoveResponse(request, DicomStatus.ProcessingFailure));

                    yield break;
                }
            }



            var queryLevel = request.Level;

            var matchingFiles = new List <IStorageLocation>();

            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)
                        {
                            matchingFiles.Add(RetrieveSopInstance(resObject));
                        }
                    }
                }
            }
            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)
                        {
                            matchingFiles.Add(RetrieveSopInstance(resObject));
                        }
                    }
                }
            }
            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)
                    {
                        matchingFiles.Add(RetrieveSopInstance(resObject));
                    }
                }
            }
            break;

            case DicomQueryRetrieveLevel.Image:
            {
                AddSearchRequestData(request.Dataset);
                var resObjects = PacsServer.QueryService.FindObjectInstances(request.Dataset, new QueryOptions());
                foreach (var resObject in resObjects)
                {
                    matchingFiles.Add(RetrieveSopInstance(resObject));
                }
            }
            break;
            }

            var client = new DicomClient(destinationIP, destinationPort, false, PacsServer.AETitle, request.DestinationAE);

            client.NegotiateAsyncOps();
            int storeTotal   = matchingFiles.Count();
            int storeDone    = 0; // this variable stores the number of instances that have already been sent
            int storeFailure = 0; // this variable stores the number of faulues returned in a OnResponseReceived

            foreach (IStorageLocation location in matchingFiles)
            {
                var storeRequest = new DicomCStoreRequest(location.ID);
                // !!! there is a Bug in fo-dicom 3.0.2 that the OnResponseReceived handlers are invoked not until the DicomClient has already
                //     sent all the instances. So the counters are not increased image by image sent but only once in a bulk after all storage
                //     has been finished. This bug will be fixed hopefully soon.
                storeRequest.OnResponseReceived += (req, resp) =>
                {
                    if (resp.Status == DicomStatus.Success)
                    {
                        Logger.Info("Storage of image successfull");
                        storeDone++;
                    }
                    else
                    {
                        Logger.Error("Storage of image failed");
                        storeFailure++;
                    }
                };
                client.AddRequestAsync(storeRequest).Wait();
            }

            var sendTask = client.SendAsync();

            while (!sendTask.IsCompleted)
            {
                // while the send-task is runnin we inform the QR SCU every 2 seconds about the status and how many instances are remaining to send.
                yield return(new DicomCMoveResponse(request, DicomStatus.Pending)
                {
                    Remaining = storeTotal - storeDone - storeFailure, Completed = storeDone
                });

                Thread.Sleep(TimeSpan.FromSeconds(2));
            }

            Logger.Info("..finished");
            yield return(new DicomCMoveResponse(request, DicomStatus.Success));
        }
Пример #15
0
        // 建立连接并查询
        async public void DicomCFindRequestFunct(ServerConfig OneServerConfig)
        {
            // 首先清空原来的查询结果
            Results.Clear();

            // 建立连接,查找病人下面的所有Study
            var client = new DicomClient(OneServerConfig.RemoteIp, OneServerConfig.RemotePort,
                                         false, OneServerConfig.LocalAeTitle, OneServerConfig.RemoteAeTitle);

            client.NegotiateAsyncOps();

            var patientRequest = DicomCFindRequest.CreateStudyQuery(
                patientId: ToQueryPatientId, patientName: ToQueryPatientName, studyDateTime: ToQueryStudyDateRange);

            // ATTENTION
            // 需要把DicomTag.StudyTime去除才能得到正确的查询结果,可能是fo-dicom程序的Bug
            // 注意这个StudyTime与查询里面的studyDateTime不是一个意思
            patientRequest.Dataset.Remove(DicomTag.StudyTime);

            var patientRequestResults = new List <ValuableResult>();

            patientRequest.OnResponseReceived += (req, response) =>
            {
                if (response.Status == DicomStatus.Pending)
                {
                    lock (patientRequestResults)
                    {
                        var patientId        = response.Dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty);
                        var studyInstanceUid = response.Dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);

                        if (!string.IsNullOrEmpty(patientId) && !string.IsNullOrEmpty(studyInstanceUid))
                        {
                            patientRequestResults.Add(new ValuableResult()
                            {
                                PatientId        = patientId,
                                StudyInstanceUid = studyInstanceUid
                            });

                            // 更新主界面显示
                            // OneServerConfig.AddLogStr($"Found {response.Dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty)} " +
                            //     $"{patientId} and the study instance id is {studyInstanceUid} which was created in " +
                            //     $"{response.Dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty)}");
                            // OneServerConfig.AddLogStr($"Found: {response.Dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty)} ");
                        }
                    }
                }
                if (response.Status == DicomStatus.Success)
                {
                    // Console.WriteLine(response.Status.ToString());
                    //OneServerConfig.LogInfo += response.Status.ToString() + Environment.NewLine;
                }
            };

            await client.AddRequestAsync(patientRequest);

            await client.SendAsync();

            // 病人层次的查询结束
            // 得到需要的病人ID和Study的ID

            // 查询对应的序列
            var seriesRequestResults = new List <ValuableResult>();

            foreach (var patientRequestResult in patientRequestResults)
            {
                var seriesRequest = DicomCFindRequest.CreateSeriesQuery(patientRequestResult.StudyInstanceUid);
                seriesRequest.OnResponseReceived += (req, response) =>
                {
                    if (response.Status == DicomStatus.Pending)
                    {
                        var seriesUid = response.Dataset?.GetSingleValue <string>(DicomTag.SeriesInstanceUID);
                        if (!string.IsNullOrEmpty(seriesUid))
                        {
                            string modality = response.Dataset?.GetSingleValue <string>(DicomTag.Modality);
                            if ((IsCtSave && modality.ToUpper().Trim() == "CT") ||
                                (IsMrSave && modality.ToUpper().Trim() == "MR") ||
                                (IsPetSave && modality.ToUpper().Trim() == "PT") ||
                                (IsRtsSave && modality.ToUpper().Trim() == "RTSTRUCT") ||
                                (IsRtpSave && modality.ToUpper().Trim() == "PTPLAN") ||
                                (IsRtDoseSave && modality.ToUpper().Trim() == "RTDOSE"))
                            {
                                seriesRequestResults.Add(new ValuableResult()
                                {
                                    PatientId         = patientRequestResult.PatientId,
                                    StudyInstanceUid  = patientRequestResult.StudyInstanceUid,
                                    SeriesInstanceUid = seriesUid
                                });

                                OneServerConfig.AddLogStr($"Found: {patientRequestResult.PatientId} {modality}");
                            }
                        }
                    }
                    if (response.Status == DicomStatus.Success)
                    {
                        // Console.WriteLine(response.Status.ToString());
                        //OneServerConfig.LogInfo += response.Status.ToString() + Environment.NewLine;
                    }

                    // serieUids.Add(response.Dataset?.GetSingleValue<string>(DicomTag.SeriesInstanceUID));
                };
                await client.AddRequestAsync(seriesRequest);

                await client.SendAsync();
            }

            Results.AddRange(seriesRequestResults);
        }
Пример #16
0
        static async Task Main(string[] args)
        {
            var client = new DicomClient(QRServerHost, QRServerPort, false, CallingAE, CalledAE);

            client.NegotiateAsyncOps();

            //// Find a list of Studies

            //var request = CreateStudyRequestByPatientName("Traxler^Y*");

            //var studyUids = new List<string>();
            //request.OnResponseReceived += (req, response) =>
            //{
            //    DebugStudyResponse(response);
            //    studyUids.Add(response.Dataset?.GetSingleValue<string>(DicomTag.StudyInstanceUID));
            //};
            //await client.AddRequestAsync(request);
            //await client.SendAsync();

            //// find all series from a study that previous was returned
            var studyUID = "111";

            //var studyUID = studyUids[0];
            //request = CreateSeriesRequestByStudyUID(studyUID);
            //var serieUids = new List<string>();
            //request.OnResponseReceived += (req, response) =>
            //{
            //    DebugSerieResponse(response);
            //    serieUids.Add(response.Dataset?.GetSingleValue<string>(DicomTag.SeriesInstanceUID));
            //};
            //await client.AddRequestAsync(request);
            //await client.SendAsync();

            // now get all the images of a serie with cGet in the same association

            client = new DicomClient(QRServerHost, QRServerPort, false, CallingAE, CalledAE);
            var cGetRequest = CreateCGetBySeriesUID(studyUID, "11");

            client.OnCStoreRequest += (DicomCStoreRequest req) =>
            {
                Console.WriteLine(DateTime.Now.ToString() + " recived");
                SaveImage(req.Dataset);
                return(Task.FromResult(new DicomCStoreResponse(req, DicomStatus.Success)));
            };
            // 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(cGetRequest);

            await client.SendAsync();

            // if the images shall be sent to an existing storescp and this storescp is configured on the QR SCP then a CMove could be performed:

            // here we want to see how a error case looks like - because the test QR Server does not know the node FODICOMSCP
            client = new DicomClient(QRServerHost, QRServerPort, false, CallingAE, CalledAE);
            var  cMoveRequest     = CreateCMoveByStudyUID("STORESCP", studyUID);
            bool?moveSuccessfully = null;

            cMoveRequest.OnResponseReceived += (DicomCMoveRequest requ, DicomCMoveResponse response) =>
            {
                if (response.Status.State == DicomState.Pending)
                {
                    Console.WriteLine("Sending is in progress. please wait: " + response.Remaining.ToString());
                }
                else if (response.Status.State == DicomState.Success)
                {
                    Console.WriteLine("Sending successfully finished");
                    moveSuccessfully = true;
                }
                else if (response.Status.State == DicomState.Failure)
                {
                    Console.WriteLine("Error sending datasets: " + response.Status.Description);
                    moveSuccessfully = false;
                }
                Console.WriteLine(response.Status);
            };
            await client.AddRequestAsync(cMoveRequest);

            await client.SendAsync();

            if (moveSuccessfully.GetValueOrDefault(false))
            {
                Console.WriteLine("images sent successfully");
                // images sent successfully from QR Server to the store scp
            }
            Console.ReadLine();
        }
Пример #17
0
        static async Task Main(string[] args)
        {
            var storeMore = "";

            StoreServerHost = GetServerHost();
            StoreServerPort = GetServerPort();

            Console.WriteLine("***************************************************");
            Console.WriteLine("Server AE Title: " + StoreServerAET);
            Console.WriteLine("Server Host Address: " + StoreServerHost);
            Console.WriteLine("Server Port: " + StoreServerPort);
            Console.WriteLine("Client AE Title: " + AET);
            Console.WriteLine("***************************************************");

            var client = new DicomClient(StoreServerHost, StoreServerPort, false, AET, StoreServerAET);

            client.NegotiateAsyncOps();

            do
            {
                try
                {
                    Console.WriteLine();
                    Console.WriteLine("Enter the path for a DICOM file:");
                    Console.Write(">>>");
                    string dicomFile = Console.ReadLine();

                    while (!File.Exists(dicomFile))
                    {
                        Console.WriteLine("Invalid file path, enter the path for a DICOM file or press Enter to Exit:");

                        dicomFile = Console.ReadLine();

                        if (string.IsNullOrWhiteSpace(dicomFile))
                        {
                            return;
                        }
                    }

                    var request = new DicomCStoreRequest(dicomFile);

                    request.OnResponseReceived += (req, response) =>
                    {
                        Console.WriteLine("C-Store Response Received, Status: " + response.Status);
                    };

                    await client.AddRequestAsync(request);

                    await client.SendAsync();
                }
                catch (Exception exception)
                {
                    Console.WriteLine();
                    Console.WriteLine("----------------------------------------------------");
                    Console.WriteLine("Error storing file. Exception Details:");
                    Console.WriteLine(exception.ToString());
                    Console.WriteLine("----------------------------------------------------");
                    Console.WriteLine();
                }

                Console.WriteLine("To store another file, enter \"y\"; Othersie, press enter to exit: ");
                Console.Write(">>>");
                storeMore = Console.ReadLine().Trim();
            } while (storeMore.Length > 0 && storeMore.ToLower()[0] == 'y');
        }
Пример #18
0
        static void Main(string[] args)
        {
            Directory.CreateDirectory(Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName) + "\\Log");

            var storeMore = "";
            int tCnt      = _thread;

            log.Info("***************************************************");
            log.Info("Server Host Address: " + _storeServerHost);
            log.Info("Server Port: " + _storeServerPort);
            log.Info("Server AE Title: " + _storeServerAET);
            log.Info("Client AE Title: " + _aet);
            log.Info("Test count: " + _count);
            log.Info("Test interval: " + _interval);
            log.Info("Test thread: " + _thread);
            log.Info("Test dicom: " + _testDICOMPath);
            log.Info("***************************************************");
            if (_manual == "Y")
            {
                tCnt = 1;
                log.Info("To start test, enter \"y\"; Othersie, press any key to exit: ");
                storeMore = Console.ReadLine().Trim();
                if (storeMore.Length > 0 && storeMore.ToLower()[0] == 'y')
                {
                }
                else
                {
                    Environment.Exit(0);
                }
            }

            Thread[] workerThreads = new Thread[tCnt];

            for (int i = 0; i < workerThreads.Length; i++)
            {
                int tNum = i;
                workerThreads[i] = new Thread(new ThreadStart(async() =>
                {
                    //var client = new DicomClient(_storeServerHost, _storeServerPort, false, _aet, _storeServerAET);
                    //Add a handler to be notified of any association rejections
                    //client.AssociationRejected += (sender, e) => {
                    //    log.Warn($"Association was rejected. Rejected Reason:{e.Reason}");
                    //};

                    //Add a handler to be notified of any association information on successful connections
                    //client.AssociationAccepted += (sender, e) =>
                    //{
                    //    log.Info(($"Association was accepted by:{e.Association.RemoteHost}");
                    //};

                    //Add a handler to be notified when association is successfully released - this can be triggered by the remote peer as well
                    //client.AssociationReleased += (sender, e) => {
                    //    log.Info("Association was released. BYE BYE!");
                    //};
                    //client.RequestTimedOut += (sender, e) =>
                    //{
                    //    log.Warn($"Send PACS error exception:{e.Request} {e.Timeout}");
                    //    throw new NotImplementedException();
                    //};
                    //client.NegotiateAsyncOps();

                    int count = 0;
                    while ((_manual == "Y" && storeMore.Length > 0 && storeMore.ToLower()[0] == 'y') || (_manual != "Y" && count < _count))
                    {
                        try
                        {
                            var client = new DicomClient(_storeServerHost, _storeServerPort, false, _aet, _storeServerAET);
                            client.NegotiateAsyncOps();

                            string dicomFile = _testDICOMPath;

                            if (_manual == "Y")
                            {
                                while (!File.Exists(dicomFile))
                                {
                                    log.Warn("Invalid file path, enter the path for a DICOM file or press Enter to Exit:");

                                    dicomFile = Console.ReadLine();

                                    if (string.IsNullOrWhiteSpace(dicomFile))
                                    {
                                        return;
                                    }
                                }
                            }
                            else
                            {
                                if (!File.Exists(dicomFile))
                                {
                                    log.Warn("Invalid file path, check test dicom file: " + _testDICOMPath);
                                    return;
                                }
                            }

                            if (_manual != "Y")
                            {
                                log.Info("Test " + tNum + "-[" + (count + 1) + "]");
                            }

                            var request = new DicomCStoreRequest(dicomFile);

                            request.OnResponseReceived += (req, response) =>
                            {
                                if (_manual == "Y")
                                {
                                    log.Info("C-Store Response Received, Status: " + response.Status);
                                    log.Info("To test again, enter \"y\"; Othersie, press any key to exit: ");
                                    storeMore = Console.ReadLine().Trim();
                                    if (storeMore.Length > 0 && storeMore.ToLower()[0] == 'y')
                                    {
                                    }
                                    else
                                    {
                                        Environment.Exit(0);
                                    }
                                }
                                else
                                {
                                    log.Info(tNum + "-[" + (count + 1) + "] " + "C-Store Response Received, Status: " + response.Status);
                                    if (count < (_count - 1))
                                    {
                                        int fortimerinterval = 0;
                                        if (_interval == "random")
                                        {
                                            fortimerinterval = rand.Next(_randomIntervalmin, _randomIntervalmax);
                                        }
                                        else
                                        {
                                            fortimerinterval = Int32.Parse(_interval);
                                        }
                                        log.Info(tNum + "-[" + (count + 1) + "] " + "Time interval " + fortimerinterval / 1000 + " seconds");
                                        count++;
                                        Thread.Sleep(fortimerinterval);
                                    }
                                    else
                                    {
                                        bool allDone = true;
                                        foreach (var workerThread in workerThreads)
                                        {
                                            if (workerThread.IsAlive)
                                            {
                                                allDone = false;
                                                break;
                                            }
                                        }
                                        if (allDone)
                                        {
                                            Thread.Sleep(15000);
                                            Environment.Exit(0);
                                        }
                                    }
                                }
                            };

                            await client.AddRequestAsync(request);
                            await client.SendAsync();
                        }
                        catch (DicomAssociationRejectedException assoRejectEx)
                        {
                            log.Warn("----------------------------------------------------");
                            log.Warn(tNum + "-[" + (count + 1) + "] " + assoRejectEx.Message);
                            log.Warn("----------------------------------------------------");
                        }
                        catch (Exception exception)
                        {
                            log.Error("----------------------------------------------------");
                            log.Error(tNum + "-[" + (count + 1) + "] " + exception.ToString());
                            log.Error("----------------------------------------------------");
                        }
                    }
                }
                                                              ))
                {
                    IsBackground = true,
                    Name         = $"SenderThread #{i}",
                    Priority     = ThreadPriority.AboveNormal
                };
                workerThreads[i].Start();
            }
            //  Await all background threads
            foreach (var workerThread in workerThreads)
            {
                workerThread.Join(600000);      //  10 minutes thread timeout
            }
            SpinWait.SpinUntil(() => false);
        }