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); }
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(); }
/// <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 <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); }
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 <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); }
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); }
/// <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 <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 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(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}"); }
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"); }
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 <bool> SendToPacs() { try { while (true) { var dataset = _dicomFileQueue.Dequeue(); var file = new DicomFile(dataset); ++dcmImagesSent; Console.WriteLine("Number of DCM images transferred : " + dcmImagesSent); // Send Data to Dicom Server await _clientSend.AddRequestAsync(new Dicom.Network.DicomCStoreRequest(file)); await _clientSend.SendAsync(); } return(true); } catch (Exception ex) { throw ex; } }
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 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; } }
private static async Task <(DicomUID affectedInstanceUid, string responseStatus, string responseMessage)> SendMppsInProgressAsync(string serverIP, int serverPort, string serverAET, string clientAET, DicomDataset worklistItem) { var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET); var dataset = new DicomDataset(); DicomSequence procedureStepSq = worklistItem.GetSequence(DicomTag.ScheduledProcedureStepSequence); // A worklistitem may have a list of scheduledprocedureSteps. // For each of them you have to send separate MPPS InProgress- and Completed-messages. // there in this example we will only send for the first procedure step var procedureStep = procedureStepSq.First(); DicomDataset content = new DicomDataset(); // get study instance UID from MWL query resault string studyInstanceUID = worklistItem.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, DicomUID.Generate().ToString()); // set Attribute Sequence data content.Add(DicomTag.StudyInstanceUID, studyInstanceUID); content.Add(DicomTag.ReferencedStudySequence, new DicomDataset()); content.Add(DicomTag.AccessionNumber, worklistItem.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty)); content.Add(DicomTag.RequestedProcedureID, worklistItem.GetSingleValueOrDefault(DicomTag.RequestedProcedureID, string.Empty)); content.Add(DicomTag.RequestedProcedureDescription, worklistItem.GetSingleValueOrDefault(DicomTag.RequestedProcedureDescription, string.Empty)); content.Add(DicomTag.ScheduledProcedureStepID, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty)); content.Add(DicomTag.ScheduledProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepDescription, string.Empty)); content.Add(DicomTag.ScheduledProtocolCodeSequence, new DicomDataset()); DicomSequence attr_Sequence = new DicomSequence(DicomTag.ScheduledStepAttributesSequence, content);//"Scheduled Step Attribute Sequence" dataset.Add(attr_Sequence); dataset.Add(DicomTag.PatientName, worklistItem.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty)); dataset.Add(DicomTag.PatientID, worklistItem.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty)); dataset.Add(DicomTag.PatientBirthDate, worklistItem.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty)); dataset.Add(DicomTag.PatientSex, worklistItem.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty)); dataset.Add(DicomTag.ReferencedPatientSequence, new DicomDataset()); dataset.Add(DicomTag.PerformedProcedureStepID, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty)); dataset.Add(DicomTag.PerformedStationAETitle, PerformedStationAETitle); dataset.Add(DicomTag.PerformedStationName, PerformedStationName); dataset.Add(DicomTag.PerformedLocation, string.Empty); dataset.Add(DicomTag.PerformedProcedureStepStartDate, DateTime.Now); dataset.Add(DicomTag.PerformedProcedureStepStartTime, DateTime.Now); // set status dataset.Add(DicomTag.PerformedProcedureStepStatus, "IN PROGRESS"); dataset.Add(DicomTag.PerformedProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty)); dataset.Add(DicomTag.PerformedProcedureTypeDescription, string.Empty); dataset.Add(DicomTag.PerformedProcedureStepEndDate, string.Empty); dataset.Add(DicomTag.PerformedProcedureStepEndTime, string.Empty); // get modality from MWL query resault dataset.Add(DicomTag.Modality, procedureStep.GetSingleValueOrDefault(DicomTag.Modality, string.Empty)); dataset.Add(DicomTag.StudyID, worklistItem.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty)); dataset.Add(DicomTag.PerformedProtocolCodeSequence, new DicomDataset()); // create an unique UID as the effectedinstamceUid, this id will be needed for the N-SET also DicomUID effectedinstamceUid = DicomUID.Generate(); var dicomStartRequest = new DicomNCreateRequest(DicomUID.ModalityPerformedProcedureStepSOPClass, effectedinstamceUid) { Dataset = dataset }; string responseStatus = string.Empty; string responseMessage = string.Empty; dicomStartRequest.OnResponseReceived += (req, response) => { if (response != null) { Console.WriteLine(response); responseStatus = response.Status.ToString(); responseMessage = response.ToString(); } }; await client.AddRequestAsync(dicomStartRequest); await client.SendAsync(); return(effectedinstamceUid, responseStatus, responseMessage); }
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'); }
private static async Task <(string responseStatus, string responseMessage)> SendMppsCompletedAsync(string serverIP, int serverPort, string serverAET, string clientAET, DicomUID affectedInstanceUid, DicomDataset worklistItem) { var client = new DicomClient(serverIP, serverPort, false, clientAET, serverAET); var dataset = new DicomDataset(); DicomSequence procedureStepSq = worklistItem.GetSequence(DicomTag.ScheduledProcedureStepSequence); // A worklistitem may have a list of scheduledprocedureSteps. // For each of them you have to send separate MPPS InProgress- and Completed-messages. // there in this example we will only send for the first procedure step var procedureStep = procedureStepSq.First(); // data dataset.Add(DicomTag.PerformedProcedureStepEndDate, DateTime.Now); dataset.Add(DicomTag.PerformedProcedureStepEndTime, DateTime.Now); dataset.Add(DicomTag.PerformedProcedureStepStatus, "COMPLETED"); dataset.Add(DicomTag.PerformedProcedureStepDescription, procedureStep.GetSingleValueOrDefault(DicomTag.ScheduledProcedureStepID, string.Empty)); dataset.Add(DicomTag.PerformedProcedureTypeDescription, string.Empty); dataset.Add(DicomTag.PerformedProtocolCodeSequence, new DicomDataset()); // dose and reports dataset.Add(DicomTag.ImageAndFluoroscopyAreaDoseProduct, 0.0m); // if there has bee sone dose while examination dataset.Add(DicomTag.CommentsOnRadiationDose, string.Empty); // a free text that contains all dose parameters // images created var performedSeriesSq = new DicomSequence(DicomTag.PerformedSeriesSequence); // iterate all Series that have been created while examination var serie = new DicomDataset { { DicomTag.RetrieveAETitle, string.Empty }, // the aetitle of the archive where the images have been sent to { DicomTag.SeriesDescription, "serie 1" }, { DicomTag.PerformingPhysicianName, string.Empty }, { DicomTag.OperatorsName, string.Empty }, { DicomTag.ProtocolName, string.Empty }, { DicomTag.SeriesInstanceUID, DicomUID.Generate() } }; var refImagesInSerie = new DicomSequence(DicomTag.ReferencedImageSequence); // iterate all images in the serie var image = new DicomDataset { { DicomTag.ReferencedSOPClassUID, DicomUID.SecondaryCaptureImageStorage }, { DicomTag.ReferencedSOPInstanceUID, DicomUID.Generate() } }; refImagesInSerie.Items.Add(image); serie.Add(refImagesInSerie); performedSeriesSq.Items.Add(serie); dataset.Add(performedSeriesSq); var dicomFinished = new DicomNSetRequest(DicomUID.ModalityPerformedProcedureStepSOPClass, affectedInstanceUid) { Dataset = dataset }; string responseStatus = string.Empty; string responseMessage = string.Empty; dicomFinished.OnResponseReceived += (req, response) => { if (response != null) { Console.WriteLine(response); responseStatus = response.Status.ToString(); responseMessage = response.ToString(); } }; await client.AddRequestAsync(dicomFinished); await client.SendAsync(); return(responseStatus, responseMessage); }
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); }
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(); }
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(); }
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)); }