/// <summary> /// Blocks until the request is received so calling code doesn't have to deal with asynchrony (see the EventWaitHandle in TrySend). /// Only the timeout is applied no Throtelling, the client is unreleased on return /// </summary> /// <param name="client"></param> /// <param name="token"></param> #region SendRequest public void SendRequest(DicomClient client, CancellationToken token) { _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Sending request to " + _dicomConfiguration.RemoteAetTitle + " at " + _dicomConfiguration.RemoteAetUri.Host + ":" + _dicomConfiguration.RemoteAetUri.Port)); bool completed; try { completed = client.SendAsync(token) .Wait(_dicomConfiguration.TransferTimeOutInMilliseconds + 1000, token); } catch (Exception ex) { OnRequestException?.Invoke(ex); throw new Exception("Error when attempting to send DICOM request: " + ex.Message, ex); } if (completed) { OnRequestSucess?.Invoke(); } else { OnRequestTimeout?.Invoke(); } }
public async Task <bool?> MoveImagesAsync(string serverIp, int serverPort, string serverAET, string localAET, string destAET, string studyInstanceUid, string seriesInstanceUid = null) { bool?success = null; DicomCMoveRequest request = string.IsNullOrEmpty(seriesInstanceUid) ? RequestFactory.CreateCMoveByStudyUID(destAET, studyInstanceUid) : RequestFactory.CreateCMoveBySeriesUID(destAET, studyInstanceUid, seriesInstanceUid); request.OnResponseReceived += (req, res) => { if (res.Status.State == DicomState.Pending) { logger.Info("Sending is in progress. please wait: " + res.Remaining.ToString()); } else if (res.Status.State == DicomState.Success) { logger.Info("Sending successfully finished."); success = true; } else if (res.Status.State == DicomState.Failure) { logger.Info("Error sending datasets: " + res.Status.Description); success = false; } logger.Debug("C-MOVE response status. " + res.Status.Description); }; DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET); await client.AddRequestAsync(request); await client.SendAsync(); return(success); }
private static async Task <List <DicomDataset> > GetAllItemsFromWorklistAsync(string serverIP, int serverPort, string serverAET, string clientAET) { var worklistItems = new List <DicomDataset>(); var cfind = DicomCFindRequest.CreateWorklistQuery(); // no filter, so query all awailable entries cfind.OnResponseReceived = (DicomCFindRequest rq, DicomCFindResponse rp) => { if (rp.HasDataset) { Console.WriteLine("Study UID: {0}", rp.Dataset.GetSingleValue <string>(DicomTag.StudyInstanceUID)); worklistItems.Add(rp.Dataset); } else { Console.WriteLine(rp.Status.ToString()); } }; var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET); await client.AddRequestAsync(cfind); await client.SendAsync(); return(worklistItems); }
/// <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); }
public async Task <List <DicomDataset> > QueryStudiesByPatientAsync(string serverIp, int serverPort, string serverAET, string localAET, string patientId = null, string patientName = null, DicomDateRange studyDateTime = null) { List <DicomDataset> studyUids = new List <DicomDataset>(); DicomCFindRequest request = RequestFactory.CreateStudyQuery(patientId, patientName, studyDateTime); request.OnResponseReceived += (req, res) => { if (res.Status == DicomStatus.Success || res.Status == DicomStatus.Pending) { if (res.HasDataset) { studyUids.Add(res.Dataset); } else { logger.Error("Query studies response has no dataset."); } } else { logger.Error("Query Studies failure. Status - [{0}]", res.Status); } }; DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET); await client.AddRequestAsync(request); await client.SendAsync(); return(studyUids); }
private void HandleCStoreException(Exception ex, OutputJob job, DicomClient client) { var exception = ex; if (exception is AggregateException) { exception = exception.InnerException; } if (exception is DicomAssociationAbortedException abortEx) { job.Logger.LogError("Association aborted with reason {0}, exception {1}", abortEx.AbortReason, abortEx); } else if (exception is DicomAssociationRejectedException rejectEx) { job.Logger.LogError("Association rejected with reason {0}, exception {1}", rejectEx.RejectReason, rejectEx); } else if (exception is IOException && exception?.InnerException is System.Net.Sockets.SocketException socketException) { job.Logger.LogError("Association aborted with error {0}, exception {1}", socketException.Message, socketException); } else { job.Logger.LogError("Job failed with error {0}", exception); } }
private void GenerateRequests( OutputJob job, DicomClient client, CountdownEvent countDownEventHandle) { while (job.PendingDicomFiles.Count > 0) { try { var request = new DicomCStoreRequest(job.PendingDicomFiles.Dequeue()); request.OnResponseReceived += (req, response) => { if (response.Status != DicomStatus.Success) { job.FailedDicomFiles.Add(request.File, response.Status.ToString()); } else { job.ProcessedDicomFiles.Add(request.File); job.Logger.LogInformation("Instance {0} sent successfully", request.File.FileMetaInfo.MediaStorageSOPInstanceUID.UID); } countDownEventHandle.Signal(); }; client.AddRequestAsync(request).ConfigureAwait(false); } catch (Exception exception) { job.Logger.LogError("Error while adding DICOM C-STORE request: {0}", exception); } } }
public async Task <bool> PingDicomServer(StoredDicomServer s, DicomClient client) { bool result = false; logger.Trace("Sending ECHO to " + s.AETitle); DicomCEchoRequest r = new DicomCEchoRequest(); r.OnResponseReceived += (re, response) => { logger.Trace(s.AETitle + " C-Echo response = " + response); if (((DicomCEchoResponse)response).Status == DicomStatus.Success) { result = true; } else { result = false; } }; await client.AddRequestAsync(r); try { //client.Send(s.IPAddress, s.Port, false, LocalAETitle, s.AETitle, 5000); Task sendEcho = client.SendAsync(); await sendEcho; } catch (Exception ex) { logger.Error("Exception in echo to " + s.AETitle + " " + ex.Message); result = false; } return(result); }
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(); }
public async Task <List <DicomDataset> > QuerySeriesByStudyAsync(string serverIp, int serverPort, string serverAET, string localAET, string studyInstanceUid, string modality = null) { List <DicomDataset> seriesUids = new List <DicomDataset>(); DicomCFindRequest request = RequestFactory.CreateSeriesQuery(studyInstanceUid, modality); request.OnResponseReceived += (req, res) => { if (res.Status == DicomStatus.Success || res.Status == DicomStatus.Pending) { if (res.HasDataset) { seriesUids.Add(res.Dataset); } else { logger.Error("Query series response has no dataset."); } } else { logger.Error("Query Series failure. Status - [{0}]", res.Status); } }; DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET); await client.AddRequestAsync(request); await client.SendAsync(); return(seriesUids); }
public DicomBaseClient(string serverHost, int serverPort, string serverAeTitle, string clientAeTitle) { CreateClient = () => { var client = new DicomClient(serverHost, serverPort, false, clientAeTitle, serverAeTitle); client.NegotiateAsyncOps(); return(client); }; }
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); }
public PacsDataSender(IConfiguration configuration, DicomFileQueue dicomFileQueue) { _configuration = configuration; var host = _configuration.GetSection("Destination:Host").Value; var scpAeTitle = _configuration.GetSection("Destination:AeTitle").Value; var port = Int32.Parse(_configuration.GetSection("Destination:Port").Value); _clientSend = new Dicom.Network.Client.DicomClient(host, port, false, "SCU", scpAeTitle); _dicomFileQueue = dicomFileQueue; }
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); }
public async Task Print() { var dicomClient = new DicomClient(RemoteAddress, RemotePort, false, CallingAE, CalledAE); await dicomClient.AddRequestAsync( new DicomNCreateRequest(FilmSession.SOPClassUID, FilmSession.SOPInstanceUID) { Dataset = FilmSession }); foreach (var filmbox in FilmSession.BasicFilmBoxes) { var imageBoxRequests = new List <DicomNSetRequest>(); var filmBoxRequest = new DicomNCreateRequest(FilmBox.SOPClassUID, filmbox.SOPInstanceUID) { Dataset = filmbox }; filmBoxRequest.OnResponseReceived = (request, response) => { if (response.HasDataset) { var seq = response.Dataset.GetSequence(DicomTag.ReferencedImageBoxSequence); for (int i = 0; i < seq.Items.Count; i++) { var req = imageBoxRequests[i]; var imageBox = req.Dataset; var sopInstanceUid = seq.Items[i].GetSingleValue <string>(DicomTag.ReferencedSOPInstanceUID); imageBox.AddOrUpdate(DicomTag.SOPInstanceUID, sopInstanceUid); req.Command.AddOrUpdate(DicomTag.RequestedSOPInstanceUID, sopInstanceUid); } } }; await dicomClient.AddRequestAsync(filmBoxRequest); foreach (var image in filmbox.BasicImageBoxes) { var req = new DicomNSetRequest(image.SOPClassUID, image.SOPInstanceUID) { Dataset = image }; imageBoxRequests.Add(req); await dicomClient.AddRequestAsync(req); } } await dicomClient.AddRequestAsync(new DicomNActionRequest(FilmSession.SOPClassUID, FilmSession.SOPInstanceUID, 0x0001)); await dicomClient.SendAsync(); }
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); }
public void EchoTest() { var success = false; var client = new DicomClient("localhost", 11112, false, "me", "also_me"); client.AddRequestAsync(new DicomCEchoRequest { OnResponseReceived = (req, res) => { success = true; } } ).Wait(); client.SendAsync().Wait(); Assert.True(success, "No echo response from own PACS"); }
public void EchoTest(string host, int port) { var success = false; var client = new DicomClient(host, port, false, LocalAetTitle, RemoteAetTitle); client.AddRequestAsync(new DicomCEchoRequest { OnResponseReceived = (req, res) => { success = true; } } ).Wait(); client.SendAsync().Wait(); Assert.True(success, $"No echo response from PACS on {host}:{port}"); }
/// <summary> /// Throttle requests using W(O) = mO(t) + c where W is the wait period, O is the opertaion duration, m and c are positive constants /// Sends requests added to the client is unreleased at the end of this request send. /// </summary> /// #region ThrottleRequest public void ThrottleRequest(DicomClient client, CancellationToken cancellationToken) { var transferTimer = new Stopwatch(); transferTimer.Start(); SendRequest(client, cancellationToken); transferTimer.Stop(); //valuein mills var delay = _dicomConfiguration.RequestCooldownInMilliseconds; if (delay <= 0) { return; } _listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Requests sleeping for " + delay / 1000 + "seconds")); Task.Delay(delay, cancellationToken).Wait(cancellationToken); }
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); }
/// <summary> /// 参考 /// https://github.com/fo-dicom/fo-dicom-samples/blob/master/Desktop/Worklist%20SCU/Program.cs /// </summary> /// <param name="serverIp">Remote IP</param> /// <param name="serverPort">Remote Port</param> /// <param name="serverAET">Remote AET</param> /// <param name="localAET">Local AET</param> /// <param name="modality">Modality</param> /// <returns>Dataset</returns> public async Task <List <DicomDataset> > GetAllItemsFromWorklistAsync(string serverIp, int serverPort, string serverAET, string localAET, string modality = null) { List <DicomDataset> worklistItems = new List <DicomDataset>(); DicomCFindRequest worklistRequest = RequestFactory.CreateWorklistQuery(null, null, localAET, null, modality //, new DicomDateRange(DateTime.Today, DateTime.Today.AddHours(23).AddMinutes(59).AddSeconds(59)) // 时间限制:当天 00:00:00 ~ 23:59:59 ); worklistRequest.OnResponseReceived += (request, response) => { if (!response.HasDataset) { if (response.Status == DicomStatus.Success) { Logger.Debug("Worklist response END."); } else { Logger.Debug("Worklist response has [NO DATASET]."); } return; } if (response.Status != DicomStatus.Success && response.Status != DicomStatus.Pending && response.Status != DicomStatus.QueryRetrieveOptionalKeysNotSupported) { Logger.Error("Worklist response error - [{0}]", response.Status); return; } worklistItems.Add(response.Dataset); }; DicomClient client = new DicomClient(serverIp, serverPort, false, localAET, serverAET); await client.AddRequestAsync(worklistRequest); await client.SendAsync(); return(worklistItems); }
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); }
//建立连接并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(); } } }
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); }
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(); }
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); }
public override SMIDataChunk DoGetChunk(ICacheFetchRequest cacheRequest, IDataLoadEventListener listener, GracefulCancellationToken cancellationToken) { listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, $"CFindSource version is {typeof(CFindSource).Assembly.GetName().Version}. Assembly is {typeof(PACSSource).Assembly} ")); listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, $"Fo-Dicom version is {typeof(DicomClient).Assembly.GetName().Version}. Assembly is {typeof(DicomClient).Assembly} ")); var dicomConfiguration = GetConfiguration(); var requestSender = new DicomRequestSender(dicomConfiguration, listener); var dateFrom = Request.Start; var dateTo = Request.End; CachingSCP.LocalAet = LocalAETitle; CachingSCP.Listener = listener; if (PatientIdWhitelistColumnInfo != null && !IgnoreWhiteList) { GetWhitelist(listener); } //temp dir var cacheDir = new LoadDirectory(Request.CacheProgress.LoadProgress.LoadMetadata.LocationOfFlatFiles).Cache; var cacheLayout = new SMICacheLayout(cacheDir, new SMICachePathResolver(Modality)); Chunk = new SMIDataChunk(Request) { FetchDate = dateFrom, Modality = Modality, Layout = cacheLayout }; // Create filepath for the results of the C-Find var workingDirectory = cacheLayout.GetLoadCacheDirectory(listener); var filename = $"{dateFrom:yyyyMMddhhmmss}.csv"; var filepath = Path.Combine(workingDirectory.FullName, filename); var sw = new StreamWriter(filepath); var writer = new CsvWriter(sw, new CsvConfiguration(CultureInfo.CurrentCulture)); WriteHeaders(writer); DicomClient client = new DicomClient(dicomConfiguration.RemoteAetUri.Host, dicomConfiguration.RemoteAetUri.Port, false, dicomConfiguration.LocalAetTitle, dicomConfiguration.RemoteAetTitle); try { // Find a list of studies #region Query listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "Requesting Studies from " + dateFrom + " to " + dateTo)); int responses = 0; var request = CreateStudyRequestByDateRangeForModality(dateFrom, dateTo, Modality); request.OnResponseReceived += (req, response) => { if (Filter(Whitelist, response)) { Interlocked.Increment(ref responses); WriteResult(writer, response); } }; requestSender.ThrottleRequest(request, client, cancellationToken.AbortToken); listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Debug, "Total filtered studies for " + dateFrom + " to " + dateTo + " is " + responses)); #endregion } finally { writer.Dispose(); } return(Chunk); }
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; } }
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(); }
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'); }